diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_q15.c
deleted file mode 100644
index 007db31..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_q15.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_lms_norm_q15.c
-*
-* Description: Q15 NLMS filter.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupFilters
- */
-
-/**
- * @addtogroup LMS_NORM
- * @{
- */
-
-/**
-* @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.
-*
-* Scaling and Overflow Behavior:
-* \par
-* The function is implemented using a 64-bit internal accumulator.
-* Both coefficients 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.
-*
-* \par
-* In this filter, filter coefficients are updated for each sample and the updation of filter cofficients are saturted.
-*
- */
-
-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)
-{
- q15_t *pState = S->pState; /* State pointer */
- q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
- q15_t *pStateCurnt; /* Points to the current sample of the state */
- q15_t *px, *pb; /* Temporary pointers for state and coefficient buffers */
- q15_t mu = S->mu; /* Adaptive factor */
- uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */
- uint32_t tapCnt, blkCnt; /* Loop counters */
- q31_t energy; /* Energy of the input */
- q63_t acc; /* Accumulator */
- q15_t e = 0, d = 0; /* error, reference data sample */
- q15_t w = 0, in; /* weight factor and state */
- q15_t x0; /* temporary variable to hold input sample */
- //uint32_t shift = (uint32_t) S->postShift + 1u; /* Shift to be applied to the output */
- q15_t errorXmu, oneByEnergy; /* Temporary variables to store error and mu product and reciprocal of energy */
- q15_t postShift; /* Post shift to be applied to weight after reciprocal calculation */
- q31_t coef; /* Teporary variable for coefficient */
- q31_t acc_l, acc_h;
- int32_t lShift = (15 - (int32_t) S->postShift); /* Post shift */
- int32_t uShift = (32 - lShift);
-
- energy = S->energy;
- x0 = S->x0;
-
- /* S->pState points to buffer which contains previous frame (numTaps - 1) samples */
- /* pStateCurnt points to the location where the new input data should be written */
- pStateCurnt = &(S->pState[(numTaps - 1u)]);
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- while(blkCnt > 0u)
- {
- /* Copy the new input sample into the state buffer */
- *pStateCurnt++ = *pSrc;
-
- /* Initialize pState pointer */
- px = pState;
-
- /* Initialize coeff pointer */
- pb = (pCoeffs);
-
- /* Read the sample from input buffer */
- in = *pSrc++;
-
- /* Update the energy calculation */
- energy -= (((q31_t) x0 * (x0)) >> 15);
- energy += (((q31_t) in * (in)) >> 15);
-
- /* Set the accumulator to zero */
- acc = 0;
-
- /* Loop unrolling. Process 4 taps at a time. */
- tapCnt = numTaps >> 2;
-
- while(tapCnt > 0u)
- {
-
- /* Perform the multiply-accumulate */
-#ifndef UNALIGNED_SUPPORT_DISABLE
-
- acc = __SMLALD(*__SIMD32(px)++, (*__SIMD32(pb)++), acc);
- acc = __SMLALD(*__SIMD32(px)++, (*__SIMD32(pb)++), acc);
-
-#else
-
- acc += (((q31_t) * px++ * (*pb++)));
- acc += (((q31_t) * px++ * (*pb++)));
- acc += (((q31_t) * px++ * (*pb++)));
- acc += (((q31_t) * px++ * (*pb++)));
-
-#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* If the filter length is not a multiple of 4, compute the remaining filter taps */
- tapCnt = numTaps % 0x4u;
-
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
- acc += (((q31_t) * px++ * (*pb++)));
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* Calc lower part of acc */
- acc_l = acc & 0xffffffff;
-
- /* Calc upper part of acc */
- acc_h = (acc >> 32) & 0xffffffff;
-
- /* Apply shift for lower part of acc and upper part of acc */
- acc = (uint32_t) acc_l >> lShift | acc_h << uShift;
-
- /* Converting the result to 1.15 format and saturate the output */
- acc = __SSAT(acc, 16u);
-
- /* Store the result from accumulator into the destination buffer. */
- *pOut++ = (q15_t) acc;
-
- /* Compute and store error */
- d = *pRef++;
- e = d - (q15_t) acc;
- *pErr++ = e;
-
- /* Calculation of 1/energy */
- postShift = arm_recip_q15((q15_t) energy + DELTA_Q15,
- &oneByEnergy, S->recipTable);
-
- /* Calculation of e * mu value */
- errorXmu = (q15_t) (((q31_t) e * mu) >> 15);
-
- /* Calculation of (e * mu) * (1/energy) value */
- acc = (((q31_t) errorXmu * oneByEnergy) >> (15 - postShift));
-
- /* Weighting factor for the normalized version */
- w = (q15_t) __SSAT((q31_t) acc, 16);
-
- /* Initialize pState pointer */
- px = pState;
-
- /* Initialize coeff pointer */
- pb = (pCoeffs);
-
- /* Loop unrolling. Process 4 taps at a time. */
- tapCnt = numTaps >> 2;
-
- /* Update filter coefficients */
- while(tapCnt > 0u)
- {
- coef = *pb + (((q31_t) w * (*px++)) >> 15);
- *pb++ = (q15_t) __SSAT((coef), 16);
- coef = *pb + (((q31_t) w * (*px++)) >> 15);
- *pb++ = (q15_t) __SSAT((coef), 16);
- coef = *pb + (((q31_t) w * (*px++)) >> 15);
- *pb++ = (q15_t) __SSAT((coef), 16);
- coef = *pb + (((q31_t) w * (*px++)) >> 15);
- *pb++ = (q15_t) __SSAT((coef), 16);
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* If the filter length is not a multiple of 4, compute the remaining filter taps */
- tapCnt = numTaps % 0x4u;
-
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
- coef = *pb + (((q31_t) w * (*px++)) >> 15);
- *pb++ = (q15_t) __SSAT((coef), 16);
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* Read the sample from state buffer */
- x0 = *pState;
-
- /* Advance state pointer by 1 for the next sample */
- pState = pState + 1u;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Save energy and x0 values for the next frame */
- S->energy = (q15_t) energy;
- S->x0 = x0;
-
- /* Processing is complete. Now copy the last numTaps - 1 samples to the
- satrt of the state buffer. This prepares the state buffer for the
- next function call. */
-
- /* Points to the start of the pState buffer */
- pStateCurnt = S->pState;
-
- /* Calculation of count for copying integer writes */
- tapCnt = (numTaps - 1u) >> 2;
-
- while(tapCnt > 0u)
- {
-
-#ifndef UNALIGNED_SUPPORT_DISABLE
-
- *__SIMD32(pStateCurnt)++ = *__SIMD32(pState)++;
- *__SIMD32(pStateCurnt)++ = *__SIMD32(pState)++;
-
-#else
-
- *pStateCurnt++ = *pState++;
- *pStateCurnt++ = *pState++;
- *pStateCurnt++ = *pState++;
- *pStateCurnt++ = *pState++;
-
-#endif
-
- tapCnt--;
-
- }
-
- /* Calculation of count for remaining q15_t data */
- tapCnt = (numTaps - 1u) % 0x4u;
-
- /* copy data */
- while(tapCnt > 0u)
- {
- *pStateCurnt++ = *pState++;
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- while(blkCnt > 0u)
- {
- /* Copy the new input sample into the state buffer */
- *pStateCurnt++ = *pSrc;
-
- /* Initialize pState pointer */
- px = pState;
-
- /* Initialize pCoeffs pointer */
- pb = pCoeffs;
-
- /* Read the sample from input buffer */
- in = *pSrc++;
-
- /* Update the energy calculation */
- energy -= (((q31_t) x0 * (x0)) >> 15);
- energy += (((q31_t) in * (in)) >> 15);
-
- /* Set the accumulator to zero */
- acc = 0;
-
- /* Loop over numTaps number of values */
- tapCnt = numTaps;
-
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
- acc += (((q31_t) * px++ * (*pb++)));
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* Calc lower part of acc */
- acc_l = acc & 0xffffffff;
-
- /* Calc upper part of acc */
- acc_h = (acc >> 32) & 0xffffffff;
-
- /* Apply shift for lower part of acc and upper part of acc */
- acc = (uint32_t) acc_l >> lShift | acc_h << uShift;
-
- /* Converting the result to 1.15 format and saturate the output */
- acc = __SSAT(acc, 16u);
-
- /* Converting the result to 1.15 format */
- //acc = __SSAT((acc >> (16u - shift)), 16u);
-
- /* Store the result from accumulator into the destination buffer. */
- *pOut++ = (q15_t) acc;
-
- /* Compute and store error */
- d = *pRef++;
- e = d - (q15_t) acc;
- *pErr++ = e;
-
- /* Calculation of 1/energy */
- postShift = arm_recip_q15((q15_t) energy + DELTA_Q15,
- &oneByEnergy, S->recipTable);
-
- /* Calculation of e * mu value */
- errorXmu = (q15_t) (((q31_t) e * mu) >> 15);
-
- /* Calculation of (e * mu) * (1/energy) value */
- acc = (((q31_t) errorXmu * oneByEnergy) >> (15 - postShift));
-
- /* Weighting factor for the normalized version */
- w = (q15_t) __SSAT((q31_t) acc, 16);
-
- /* Initialize pState pointer */
- px = pState;
-
- /* Initialize coeff pointer */
- pb = (pCoeffs);
-
- /* Loop over numTaps number of values */
- tapCnt = numTaps;
-
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
- coef = *pb + (((q31_t) w * (*px++)) >> 15);
- *pb++ = (q15_t) __SSAT((coef), 16);
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* Read the sample from state buffer */
- x0 = *pState;
-
- /* Advance state pointer by 1 for the next sample */
- pState = pState + 1u;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Save energy and x0 values for the next frame */
- S->energy = (q15_t) energy;
- S->x0 = x0;
-
- /* Processing is complete. Now copy the last numTaps - 1 samples to the
- satrt of the state buffer. This prepares the state buffer for the
- next function call. */
-
- /* Points to the start of the pState buffer */
- pStateCurnt = S->pState;
-
- /* copy (numTaps - 1u) data */
- tapCnt = (numTaps - 1u);
-
- /* copy data */
- while(tapCnt > 0u)
- {
- *pStateCurnt++ = *pState++;
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
-}
-
-
-/**
- * @} end of LMS_NORM group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_q31.c
deleted file mode 100644
index 20701fa..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_q31.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_lms_norm_q31.c
-*
-* Description: Processing function for the Q31 NLMS filter.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupFilters
- */
-
-/**
- * @addtogroup LMS_NORM
- * @{
- */
-
-/**
-* @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.
-*
-* 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
-* log2(numTaps) bits. The reference signal should not be scaled down.
-* After all multiply-accumulates are performed, the 2.62 accumulator is shifted
-* and saturated to 1.31 format to yield the final result.
-* The output signal and error signal are in 1.31 format.
-*
-* \par
-* In this filter, filter coefficients are updated for each sample and the
-* updation of filter cofficients are saturted.
-*
-*/
-
-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)
-{
- q31_t *pState = S->pState; /* State pointer */
- q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
- q31_t *pStateCurnt; /* Points to the current sample of the state */
- q31_t *px, *pb; /* Temporary pointers for state and coefficient buffers */
- q31_t mu = S->mu; /* Adaptive factor */
- uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */
- uint32_t tapCnt, blkCnt; /* Loop counters */
- q63_t energy; /* Energy of the input */
- q63_t acc; /* Accumulator */
- q31_t e = 0, d = 0; /* error, reference data sample */
- q31_t w = 0, in; /* weight factor and state */
- q31_t x0; /* temporary variable to hold input sample */
-// uint32_t shift = 32u - ((uint32_t) S->postShift + 1u); /* Shift to be applied to the output */
- q31_t errorXmu, oneByEnergy; /* Temporary variables to store error and mu product and reciprocal of energy */
- q31_t postShift; /* Post shift to be applied to weight after reciprocal calculation */
- q31_t coef; /* Temporary variable for coef */
- q31_t acc_l, acc_h; /* temporary input */
- uint32_t uShift = ((uint32_t) S->postShift + 1u);
- uint32_t lShift = 32u - uShift; /* Shift to be applied to the output */
-
- energy = S->energy;
- x0 = S->x0;
-
- /* S->pState points to buffer which contains previous frame (numTaps - 1) samples */
- /* pStateCurnt points to the location where the new input data should be written */
- pStateCurnt = &(S->pState[(numTaps - 1u)]);
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- while(blkCnt > 0u)
- {
-
- /* Copy the new input sample into the state buffer */
- *pStateCurnt++ = *pSrc;
-
- /* Initialize pState pointer */
- px = pState;
-
- /* Initialize coeff pointer */
- pb = (pCoeffs);
-
- /* Read the sample from input buffer */
- in = *pSrc++;
-
- /* Update the energy calculation */
- energy = (q31_t) ((((q63_t) energy << 32) -
- (((q63_t) x0 * x0) << 1)) >> 32);
- energy = (q31_t) (((((q63_t) in * in) << 1) + (energy << 32)) >> 32);
-
- /* Set the accumulator to zero */
- acc = 0;
-
- /* Loop unrolling. Process 4 taps at a time. */
- tapCnt = numTaps >> 2;
-
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
- acc += ((q63_t) (*px++)) * (*pb++);
- acc += ((q63_t) (*px++)) * (*pb++);
- acc += ((q63_t) (*px++)) * (*pb++);
- acc += ((q63_t) (*px++)) * (*pb++);
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* If the filter length is not a multiple of 4, compute the remaining filter taps */
- tapCnt = numTaps % 0x4u;
-
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
- acc += ((q63_t) (*px++)) * (*pb++);
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* Converting the result to 1.31 format */
- /* Calc lower part of acc */
- acc_l = acc & 0xffffffff;
-
- /* Calc upper part of acc */
- acc_h = (acc >> 32) & 0xffffffff;
-
- acc = (uint32_t) acc_l >> lShift | acc_h << uShift;
-
- /* Store the result from accumulator into the destination buffer. */
- *pOut++ = (q31_t) acc;
-
- /* Compute and store error */
- d = *pRef++;
- e = d - (q31_t) acc;
- *pErr++ = e;
-
- /* Calculates the reciprocal of energy */
- postShift = arm_recip_q31(energy + DELTA_Q31,
- &oneByEnergy, &S->recipTable[0]);
-
- /* Calculation of product of (e * mu) */
- errorXmu = (q31_t) (((q63_t) e * mu) >> 31);
-
- /* Weighting factor for the normalized version */
- w = clip_q63_to_q31(((q63_t) errorXmu * oneByEnergy) >> (31 - postShift));
-
- /* Initialize pState pointer */
- px = pState;
-
- /* Initialize coeff pointer */
- pb = (pCoeffs);
-
- /* Loop unrolling. Process 4 taps at a time. */
- tapCnt = numTaps >> 2;
-
- /* Update filter coefficients */
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
-
- /* coef is in 2.30 format */
- coef = (q31_t) (((q63_t) w * (*px++)) >> (32));
- /* get coef in 1.31 format by left shifting */
- *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
- /* update coefficient buffer to next coefficient */
- pb++;
-
- coef = (q31_t) (((q63_t) w * (*px++)) >> (32));
- *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
- pb++;
-
- coef = (q31_t) (((q63_t) w * (*px++)) >> (32));
- *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
- pb++;
-
- coef = (q31_t) (((q63_t) w * (*px++)) >> (32));
- *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
- pb++;
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* If the filter length is not a multiple of 4, compute the remaining filter taps */
- tapCnt = numTaps % 0x4u;
-
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
- coef = (q31_t) (((q63_t) w * (*px++)) >> (32));
- *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
- pb++;
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* Read the sample from state buffer */
- x0 = *pState;
-
- /* Advance state pointer by 1 for the next sample */
- pState = pState + 1;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Save energy and x0 values for the next frame */
- S->energy = (q31_t) energy;
- S->x0 = x0;
-
- /* Processing is complete. Now copy the last numTaps - 1 samples to the
- satrt of the state buffer. This prepares the state buffer for the
- next function call. */
-
- /* Points to the start of the pState buffer */
- pStateCurnt = S->pState;
-
- /* Loop unrolling for (numTaps - 1u) samples copy */
- tapCnt = (numTaps - 1u) >> 2u;
-
- /* copy data */
- while(tapCnt > 0u)
- {
- *pStateCurnt++ = *pState++;
- *pStateCurnt++ = *pState++;
- *pStateCurnt++ = *pState++;
- *pStateCurnt++ = *pState++;
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* Calculate remaining number of copies */
- tapCnt = (numTaps - 1u) % 0x4u;
-
- /* Copy the remaining q31_t data */
- while(tapCnt > 0u)
- {
- *pStateCurnt++ = *pState++;
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- while(blkCnt > 0u)
- {
-
- /* Copy the new input sample into the state buffer */
- *pStateCurnt++ = *pSrc;
-
- /* Initialize pState pointer */
- px = pState;
-
- /* Initialize pCoeffs pointer */
- pb = pCoeffs;
-
- /* Read the sample from input buffer */
- in = *pSrc++;
-
- /* Update the energy calculation */
- energy =
- (q31_t) ((((q63_t) energy << 32) - (((q63_t) x0 * x0) << 1)) >> 32);
- energy = (q31_t) (((((q63_t) in * in) << 1) + (energy << 32)) >> 32);
-
- /* Set the accumulator to zero */
- acc = 0;
-
- /* Loop over numTaps number of values */
- tapCnt = numTaps;
-
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
- acc += ((q63_t) (*px++)) * (*pb++);
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* Converting the result to 1.31 format */
- /* Converting the result to 1.31 format */
- /* Calc lower part of acc */
- acc_l = acc & 0xffffffff;
-
- /* Calc upper part of acc */
- acc_h = (acc >> 32) & 0xffffffff;
-
- acc = (uint32_t) acc_l >> lShift | acc_h << uShift;
-
-
- //acc = (q31_t) (acc >> shift);
-
- /* Store the result from accumulator into the destination buffer. */
- *pOut++ = (q31_t) acc;
-
- /* Compute and store error */
- d = *pRef++;
- e = d - (q31_t) acc;
- *pErr++ = e;
-
- /* Calculates the reciprocal of energy */
- postShift =
- arm_recip_q31(energy + DELTA_Q31, &oneByEnergy, &S->recipTable[0]);
-
- /* Calculation of product of (e * mu) */
- errorXmu = (q31_t) (((q63_t) e * mu) >> 31);
-
- /* Weighting factor for the normalized version */
- w = clip_q63_to_q31(((q63_t) errorXmu * oneByEnergy) >> (31 - postShift));
-
- /* Initialize pState pointer */
- px = pState;
-
- /* Initialize coeff pointer */
- pb = (pCoeffs);
-
- /* Loop over numTaps number of values */
- tapCnt = numTaps;
-
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
- /* coef is in 2.30 format */
- coef = (q31_t) (((q63_t) w * (*px++)) >> (32));
- /* get coef in 1.31 format by left shifting */
- *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
- /* update coefficient buffer to next coefficient */
- pb++;
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* Read the sample from state buffer */
- x0 = *pState;
-
- /* Advance state pointer by 1 for the next sample */
- pState = pState + 1;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Save energy and x0 values for the next frame */
- S->energy = (q31_t) energy;
- S->x0 = x0;
-
- /* Processing is complete. Now copy the last numTaps - 1 samples to the
- start of the state buffer. This prepares the state buffer for the
- next function call. */
-
- /* Points to the start of the pState buffer */
- pStateCurnt = S->pState;
-
- /* Loop for (numTaps - 1u) samples copy */
- tapCnt = (numTaps - 1u);
-
- /* Copy the remaining q31_t data */
- while(tapCnt > 0u)
- {
- *pStateCurnt++ = *pState++;
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
-}
-
-/**
- * @} end of LMS_NORM group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_q15.c
deleted file mode 100644
index 2f1b991..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_q15.c
+++ /dev/null
@@ -1,380 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_lms_q15.c
-*
-* Description: Processing function for the Q15 LMS filter.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-/**
- * @ingroup groupFilters
- */
-
-/**
- * @addtogroup LMS
- * @{
- */
-
- /**
- * @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.
- *
- * \par Scaling and Overflow Behavior:
- * The function is implemented using a 64-bit internal accumulator.
- * Both coefficients 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.
- *
- * \par
- * In this filter, filter coefficients are updated for each sample and the updation of filter cofficients are saturted.
- *
- */
-
-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)
-{
- q15_t *pState = S->pState; /* State pointer */
- uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */
- q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
- q15_t *pStateCurnt; /* Points to the current sample of the state */
- q15_t mu = S->mu; /* Adaptive factor */
- q15_t *px; /* Temporary pointer for state */
- q15_t *pb; /* Temporary pointer for coefficient buffer */
- uint32_t tapCnt, blkCnt; /* Loop counters */
- q63_t acc; /* Accumulator */
- q15_t e = 0; /* error of data sample */
- q15_t alpha; /* Intermediate constant for taps update */
- q31_t coef; /* Teporary variable for coefficient */
- q31_t acc_l, acc_h;
- int32_t lShift = (15 - (int32_t) S->postShift); /* Post shift */
- int32_t uShift = (32 - lShift);
-
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
-
- /* S->pState points to buffer which contains previous frame (numTaps - 1) samples */
- /* pStateCurnt points to the location where the new input data should be written */
- pStateCurnt = &(S->pState[(numTaps - 1u)]);
-
- /* Initializing blkCnt with blockSize */
- blkCnt = blockSize;
-
- while(blkCnt > 0u)
- {
- /* Copy the new input sample into the state buffer */
- *pStateCurnt++ = *pSrc++;
-
- /* Initialize state pointer */
- px = pState;
-
- /* Initialize coefficient pointer */
- pb = pCoeffs;
-
- /* Set the accumulator to zero */
- acc = 0;
-
- /* Loop unrolling. Process 4 taps at a time. */
- tapCnt = numTaps >> 2u;
-
- while(tapCnt > 0u)
- {
- /* acc += b[N] * x[n-N] + b[N-1] * x[n-N-1] */
- /* Perform the multiply-accumulate */
-#ifndef UNALIGNED_SUPPORT_DISABLE
-
- acc = __SMLALD(*__SIMD32(px)++, (*__SIMD32(pb)++), acc);
- acc = __SMLALD(*__SIMD32(px)++, (*__SIMD32(pb)++), acc);
-
-#else
-
- acc += (q63_t) (((q31_t) (*px++) * (*pb++)));
- acc += (q63_t) (((q31_t) (*px++) * (*pb++)));
- acc += (q63_t) (((q31_t) (*px++) * (*pb++)));
- acc += (q63_t) (((q31_t) (*px++) * (*pb++)));
-
-
-#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* If the filter length is not a multiple of 4, compute the remaining filter taps */
- tapCnt = numTaps % 0x4u;
-
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
- acc += (q63_t) (((q31_t) (*px++) * (*pb++)));
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* Calc lower part of acc */
- acc_l = acc & 0xffffffff;
-
- /* Calc upper part of acc */
- acc_h = (acc >> 32) & 0xffffffff;
-
- /* Apply shift for lower part of acc and upper part of acc */
- acc = (uint32_t) acc_l >> lShift | acc_h << uShift;
-
- /* Converting the result to 1.15 format and saturate the output */
- acc = __SSAT(acc, 16);
-
- /* Store the result from accumulator into the destination buffer. */
- *pOut++ = (q15_t) acc;
-
- /* Compute and store error */
- e = *pRef++ - (q15_t) acc;
-
- *pErr++ = (q15_t) e;
-
- /* Compute alpha i.e. intermediate constant for taps update */
- alpha = (q15_t) (((q31_t) e * (mu)) >> 15);
-
- /* Initialize state pointer */
- /* Advance state pointer by 1 for the next sample */
- px = pState++;
-
- /* Initialize coefficient pointer */
- pb = pCoeffs;
-
- /* Loop unrolling. Process 4 taps at a time. */
- tapCnt = numTaps >> 2u;
-
- /* Update filter coefficients */
- while(tapCnt > 0u)
- {
- coef = (q31_t) * pb + (((q31_t) alpha * (*px++)) >> 15);
- *pb++ = (q15_t) __SSAT((coef), 16);
- coef = (q31_t) * pb + (((q31_t) alpha * (*px++)) >> 15);
- *pb++ = (q15_t) __SSAT((coef), 16);
- coef = (q31_t) * pb + (((q31_t) alpha * (*px++)) >> 15);
- *pb++ = (q15_t) __SSAT((coef), 16);
- coef = (q31_t) * pb + (((q31_t) alpha * (*px++)) >> 15);
- *pb++ = (q15_t) __SSAT((coef), 16);
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* If the filter length is not a multiple of 4, compute the remaining filter taps */
- tapCnt = numTaps % 0x4u;
-
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
- coef = (q31_t) * pb + (((q31_t) alpha * (*px++)) >> 15);
- *pb++ = (q15_t) __SSAT((coef), 16);
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* Decrement the loop counter */
- blkCnt--;
-
- }
-
- /* Processing is complete. Now copy the last numTaps - 1 samples to the
- satrt of the state buffer. This prepares the state buffer for the
- next function call. */
-
- /* Points to the start of the pState buffer */
- pStateCurnt = S->pState;
-
- /* Calculation of count for copying integer writes */
- tapCnt = (numTaps - 1u) >> 2;
-
- while(tapCnt > 0u)
- {
-
-#ifndef UNALIGNED_SUPPORT_DISABLE
-
- *__SIMD32(pStateCurnt)++ = *__SIMD32(pState)++;
- *__SIMD32(pStateCurnt)++ = *__SIMD32(pState)++;
-#else
- *pStateCurnt++ = *pState++;
- *pStateCurnt++ = *pState++;
- *pStateCurnt++ = *pState++;
- *pStateCurnt++ = *pState++;
-#endif
-
- tapCnt--;
-
- }
-
- /* Calculation of count for remaining q15_t data */
- tapCnt = (numTaps - 1u) % 0x4u;
-
- /* copy data */
- while(tapCnt > 0u)
- {
- *pStateCurnt++ = *pState++;
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* S->pState points to buffer which contains previous frame (numTaps - 1) samples */
- /* pStateCurnt points to the location where the new input data should be written */
- pStateCurnt = &(S->pState[(numTaps - 1u)]);
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
- while(blkCnt > 0u)
- {
- /* Copy the new input sample into the state buffer */
- *pStateCurnt++ = *pSrc++;
-
- /* Initialize pState pointer */
- px = pState;
-
- /* Initialize pCoeffs pointer */
- pb = pCoeffs;
-
- /* Set the accumulator to zero */
- acc = 0;
-
- /* Loop over numTaps number of values */
- tapCnt = numTaps;
-
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
- acc += (q63_t) ((q31_t) (*px++) * (*pb++));
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* Calc lower part of acc */
- acc_l = acc & 0xffffffff;
-
- /* Calc upper part of acc */
- acc_h = (acc >> 32) & 0xffffffff;
-
- /* Apply shift for lower part of acc and upper part of acc */
- acc = (uint32_t) acc_l >> lShift | acc_h << uShift;
-
- /* Converting the result to 1.15 format and saturate the output */
- acc = __SSAT(acc, 16);
-
- /* Store the result from accumulator into the destination buffer. */
- *pOut++ = (q15_t) acc;
-
- /* Compute and store error */
- e = *pRef++ - (q15_t) acc;
-
- *pErr++ = (q15_t) e;
-
- /* Compute alpha i.e. intermediate constant for taps update */
- alpha = (q15_t) (((q31_t) e * (mu)) >> 15);
-
- /* Initialize pState pointer */
- /* Advance state pointer by 1 for the next sample */
- px = pState++;
-
- /* Initialize pCoeffs pointer */
- pb = pCoeffs;
-
- /* Loop over numTaps number of values */
- tapCnt = numTaps;
-
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
- coef = (q31_t) * pb + (((q31_t) alpha * (*px++)) >> 15);
- *pb++ = (q15_t) __SSAT((coef), 16);
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* Decrement the loop counter */
- blkCnt--;
-
- }
-
- /* Processing is complete. Now copy the last numTaps - 1 samples to the
- start of the state buffer. This prepares the state buffer for the
- next function call. */
-
- /* Points to the start of the pState buffer */
- pStateCurnt = S->pState;
-
- /* Copy (numTaps - 1u) samples */
- tapCnt = (numTaps - 1u);
-
- /* Copy the data */
- while(tapCnt > 0u)
- {
- *pStateCurnt++ = *pState++;
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
-}
-
-/**
- * @} end of LMS group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_q31.c
deleted file mode 100644
index 838e912..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_q31.c
+++ /dev/null
@@ -1,369 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_lms_q31.c
-*
-* Description: Processing function for the Q31 LMS filter.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-/**
- * @ingroup groupFilters
- */
-
-/**
- * @addtogroup LMS
- * @{
- */
-
- /**
- * @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.
- *
- * \par Scaling and Overflow Behavior:
- * 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 clips.
- * In order to avoid overflows completely the input signal must be scaled down by
- * log2(numTaps) bits.
- * The reference signal should not be scaled down.
- * After all multiply-accumulates are performed, the 2.62 accumulator is shifted
- * and saturated to 1.31 format to yield the final result.
- * The output signal and error signal are in 1.31 format.
- *
- * \par
- * In this filter, filter coefficients are updated for each sample and the updation of filter cofficients are saturted.
- */
-
-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)
-{
- q31_t *pState = S->pState; /* State pointer */
- uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */
- q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
- q31_t *pStateCurnt; /* Points to the current sample of the state */
- q31_t mu = S->mu; /* Adaptive factor */
- q31_t *px; /* Temporary pointer for state */
- q31_t *pb; /* Temporary pointer for coefficient buffer */
- uint32_t tapCnt, blkCnt; /* Loop counters */
- q63_t acc; /* Accumulator */
- q31_t e = 0; /* error of data sample */
- q31_t alpha; /* Intermediate constant for taps update */
- q31_t coef; /* Temporary variable for coef */
- q31_t acc_l, acc_h; /* temporary input */
- uint32_t uShift = ((uint32_t) S->postShift + 1u);
- uint32_t lShift = 32u - uShift; /* Shift to be applied to the output */
-
- /* S->pState points to buffer which contains previous frame (numTaps - 1) samples */
- /* pStateCurnt points to the location where the new input data should be written */
- pStateCurnt = &(S->pState[(numTaps - 1u)]);
-
- /* Initializing blkCnt with blockSize */
- blkCnt = blockSize;
-
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- while(blkCnt > 0u)
- {
- /* Copy the new input sample into the state buffer */
- *pStateCurnt++ = *pSrc++;
-
- /* Initialize state pointer */
- px = pState;
-
- /* Initialize coefficient pointer */
- pb = pCoeffs;
-
- /* Set the accumulator to zero */
- acc = 0;
-
- /* Loop unrolling. Process 4 taps at a time. */
- tapCnt = numTaps >> 2;
-
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
- /* acc += b[N] * x[n-N] */
- acc += ((q63_t) (*px++)) * (*pb++);
-
- /* acc += b[N-1] * x[n-N-1] */
- acc += ((q63_t) (*px++)) * (*pb++);
-
- /* acc += b[N-2] * x[n-N-2] */
- acc += ((q63_t) (*px++)) * (*pb++);
-
- /* acc += b[N-3] * x[n-N-3] */
- acc += ((q63_t) (*px++)) * (*pb++);
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* If the filter length is not a multiple of 4, compute the remaining filter taps */
- tapCnt = numTaps % 0x4u;
-
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
- acc += ((q63_t) (*px++)) * (*pb++);
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* Converting the result to 1.31 format */
- /* Calc lower part of acc */
- acc_l = acc & 0xffffffff;
-
- /* Calc upper part of acc */
- acc_h = (acc >> 32) & 0xffffffff;
-
- acc = (uint32_t) acc_l >> lShift | acc_h << uShift;
-
- /* Store the result from accumulator into the destination buffer. */
- *pOut++ = (q31_t) acc;
-
- /* Compute and store error */
- e = *pRef++ - (q31_t) acc;
-
- *pErr++ = (q31_t) e;
-
- /* Compute alpha i.e. intermediate constant for taps update */
- alpha = (q31_t) (((q63_t) e * mu) >> 31);
-
- /* Initialize state pointer */
- /* Advance state pointer by 1 for the next sample */
- px = pState++;
-
- /* Initialize coefficient pointer */
- pb = pCoeffs;
-
- /* Loop unrolling. Process 4 taps at a time. */
- tapCnt = numTaps >> 2;
-
- /* Update filter coefficients */
- while(tapCnt > 0u)
- {
- /* coef is in 2.30 format */
- coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32));
- /* get coef in 1.31 format by left shifting */
- *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
- /* update coefficient buffer to next coefficient */
- pb++;
-
- coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32));
- *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
- pb++;
-
- coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32));
- *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
- pb++;
-
- coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32));
- *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
- pb++;
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* If the filter length is not a multiple of 4, compute the remaining filter taps */
- tapCnt = numTaps % 0x4u;
-
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
- coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32));
- *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
- pb++;
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Processing is complete. Now copy the last numTaps - 1 samples to the
- satrt of the state buffer. This prepares the state buffer for the
- next function call. */
-
- /* Points to the start of the pState buffer */
- pStateCurnt = S->pState;
-
- /* Loop unrolling for (numTaps - 1u) samples copy */
- tapCnt = (numTaps - 1u) >> 2u;
-
- /* copy data */
- while(tapCnt > 0u)
- {
- *pStateCurnt++ = *pState++;
- *pStateCurnt++ = *pState++;
- *pStateCurnt++ = *pState++;
- *pStateCurnt++ = *pState++;
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* Calculate remaining number of copies */
- tapCnt = (numTaps - 1u) % 0x4u;
-
- /* Copy the remaining q31_t data */
- while(tapCnt > 0u)
- {
- *pStateCurnt++ = *pState++;
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- while(blkCnt > 0u)
- {
- /* Copy the new input sample into the state buffer */
- *pStateCurnt++ = *pSrc++;
-
- /* Initialize pState pointer */
- px = pState;
-
- /* Initialize pCoeffs pointer */
- pb = pCoeffs;
-
- /* Set the accumulator to zero */
- acc = 0;
-
- /* Loop over numTaps number of values */
- tapCnt = numTaps;
-
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
- acc += ((q63_t) (*px++)) * (*pb++);
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* Converting the result to 1.31 format */
- /* Store the result from accumulator into the destination buffer. */
- /* Calc lower part of acc */
- acc_l = acc & 0xffffffff;
-
- /* Calc upper part of acc */
- acc_h = (acc >> 32) & 0xffffffff;
-
- acc = (uint32_t) acc_l >> lShift | acc_h << uShift;
-
- *pOut++ = (q31_t) acc;
-
- /* Compute and store error */
- e = *pRef++ - (q31_t) acc;
-
- *pErr++ = (q31_t) e;
-
- /* Weighting factor for the LMS version */
- alpha = (q31_t) (((q63_t) e * mu) >> 31);
-
- /* Initialize pState pointer */
- /* Advance state pointer by 1 for the next sample */
- px = pState++;
-
- /* Initialize pCoeffs pointer */
- pb = pCoeffs;
-
- /* Loop over numTaps number of values */
- tapCnt = numTaps;
-
- while(tapCnt > 0u)
- {
- /* Perform the multiply-accumulate */
- coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32));
- *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
- pb++;
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Processing is complete. Now copy the last numTaps - 1 samples to the
- start of the state buffer. This prepares the state buffer for the
- next function call. */
-
- /* Points to the start of the pState buffer */
- pStateCurnt = S->pState;
-
- /* Copy (numTaps - 1u) samples */
- tapCnt = (numTaps - 1u);
-
- /* Copy the data */
- while(tapCnt > 0u)
- {
- *pStateCurnt++ = *pState++;
-
- /* Decrement the loop counter */
- tapCnt--;
- }
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
-}
-
-/**
- * @} end of LMS group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_add_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_add_f32.c
deleted file mode 100644
index e418492..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_add_f32.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/* ----------------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_add_f32.c
-*
-* Description: Floating-point matrix addition
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @defgroup MatrixAdd Matrix Addition
- *
- * Adds two matrices.
- * \image html MatrixAddition.gif "Addition of two 3 x 3 matrices"
- *
- * The functions check to make sure that
- * pSrcA
, pSrcB
, and pDst
have the same
- * number of rows and columns.
- */
-
-/**
- * @addtogroup MatrixAdd
- * @{
- */
-
-
-/**
- * @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)
-{
- float32_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
- float32_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
- float32_t *pOut = pDst->pData; /* output data matrix pointer */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- float32_t inA1, inA2, inB1, inB2, out1, out2; /* temporary variables */
-
-#endif // #ifndef ARM_MATH_CM0_FAMILY
-
- uint32_t numSamples; /* total number of elements in the matrix */
- uint32_t blkCnt; /* loop counters */
- arm_status status; /* status of matrix addition */
-
-#ifdef ARM_MATH_MATRIX_CHECK
- /* Check for matrix mismatch condition */
- if((pSrcA->numRows != pSrcB->numRows) ||
- (pSrcA->numCols != pSrcB->numCols) ||
- (pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif
- {
-
- /* Total number of samples in the input matrix */
- numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols;
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Loop unrolling */
- blkCnt = numSamples >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) + B(m,n) */
- /* Add and then store the results in the destination buffer. */
- /* Read values from source A */
- inA1 = pIn1[0];
-
- /* Read values from source B */
- inB1 = pIn2[0];
-
- /* Read values from source A */
- inA2 = pIn1[1];
-
- /* out = sourceA + sourceB */
- out1 = inA1 + inB1;
-
- /* Read values from source B */
- inB2 = pIn2[1];
-
- /* Read values from source A */
- inA1 = pIn1[2];
-
- /* out = sourceA + sourceB */
- out2 = inA2 + inB2;
-
- /* Read values from source B */
- inB1 = pIn2[2];
-
- /* Store result in destination */
- pOut[0] = out1;
- pOut[1] = out2;
-
- /* Read values from source A */
- inA2 = pIn1[3];
-
- /* Read values from source B */
- inB2 = pIn2[3];
-
- /* out = sourceA + sourceB */
- out1 = inA1 + inB1;
-
- /* out = sourceA + sourceB */
- out2 = inA2 + inB2;
-
- /* Store result in destination */
- pOut[2] = out1;
-
- /* Store result in destination */
- pOut[3] = out2;
-
-
- /* update pointers to process next sampels */
- pIn1 += 4u;
- pIn2 += 4u;
- pOut += 4u;
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the numSamples is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = numSamples % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Initialize blkCnt with number of samples */
- blkCnt = numSamples;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) + B(m,n) */
- /* Add and then store the results in the destination buffer. */
- *pOut++ = (*pIn1++) + (*pIn2++);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
-
- }
-
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixAdd group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_add_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_add_q15.c
deleted file mode 100644
index 45d1837..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_add_q15.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_add_q15.c
-*
-* Description: Q15 matrix addition
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @addtogroup MatrixAdd
- * @{
- */
-
-/**
- * @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.
- *
- * Scaling and Overflow Behavior:
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
- */
-
-arm_status arm_mat_add_q15(
- const arm_matrix_instance_q15 * pSrcA,
- const arm_matrix_instance_q15 * pSrcB,
- arm_matrix_instance_q15 * pDst)
-{
- q15_t *pInA = pSrcA->pData; /* input data matrix pointer A */
- q15_t *pInB = pSrcB->pData; /* input data matrix pointer B */
- q15_t *pOut = pDst->pData; /* output data matrix pointer */
- uint16_t numSamples; /* total number of elements in the matrix */
- uint32_t blkCnt; /* loop counters */
- arm_status status; /* status of matrix addition */
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
-
- /* Check for matrix mismatch condition */
- if((pSrcA->numRows != pSrcB->numRows) ||
- (pSrcA->numCols != pSrcB->numCols) ||
- (pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
-
- {
- /* Total number of samples in the input matrix */
- numSamples = (uint16_t) (pSrcA->numRows * pSrcA->numCols);
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /* Loop unrolling */
- blkCnt = (uint32_t) numSamples >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) + B(m,n) */
- /* Add, Saturate and then store the results in the destination buffer. */
- *__SIMD32(pOut)++ = __QADD16(*__SIMD32(pInA)++, *__SIMD32(pInB)++);
- *__SIMD32(pOut)++ = __QADD16(*__SIMD32(pInA)++, *__SIMD32(pInB)++);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = (uint32_t) numSamples % 0x4u;
-
- /* q15 pointers of input and output are initialized */
-
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) + B(m,n) */
- /* Add, Saturate and then store the results in the destination buffer. */
- *pOut++ = (q15_t) __QADD16(*pInA++, *pInB++);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Initialize blkCnt with number of samples */
- blkCnt = (uint32_t) numSamples;
-
-
- /* q15 pointers of input and output are initialized */
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) + B(m,n) */
- /* Add, Saturate and then store the results in the destination buffer. */
- *pOut++ = (q15_t) __SSAT(((q31_t) * pInA++ + *pInB++), 16);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- /* set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
-
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixAdd group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_add_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_add_q31.c
deleted file mode 100644
index b6ccddb..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_add_q31.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_add_q31.c
-*
-* Description: Q31 matrix addition
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @addtogroup MatrixAdd
- * @{
- */
-
-/**
- * @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.
- *
- * Scaling and Overflow Behavior:
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] will be saturated.
- */
-
-arm_status arm_mat_add_q31(
- const arm_matrix_instance_q31 * pSrcA,
- const arm_matrix_instance_q31 * pSrcB,
- arm_matrix_instance_q31 * pDst)
-{
- q31_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
- q31_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
- q31_t *pOut = pDst->pData; /* output data matrix pointer */
- q31_t inA1, inB1; /* temporary variables */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- q31_t inA2, inB2; /* temporary variables */
- q31_t out1, out2; /* temporary variables */
-
-#endif // #ifndef ARM_MATH_CM0_FAMILY
-
- uint32_t numSamples; /* total number of elements in the matrix */
- uint32_t blkCnt; /* loop counters */
- arm_status status; /* status of matrix addition */
-
-#ifdef ARM_MATH_MATRIX_CHECK
- /* Check for matrix mismatch condition */
- if((pSrcA->numRows != pSrcB->numRows) ||
- (pSrcA->numCols != pSrcB->numCols) ||
- (pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif
- {
- /* Total number of samples in the input matrix */
- numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols;
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /* Loop Unrolling */
- blkCnt = numSamples >> 2u;
-
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) + B(m,n) */
- /* Add, saturate and then store the results in the destination buffer. */
- /* Read values from source A */
- inA1 = pIn1[0];
-
- /* Read values from source B */
- inB1 = pIn2[0];
-
- /* Read values from source A */
- inA2 = pIn1[1];
-
- /* Add and saturate */
- out1 = __QADD(inA1, inB1);
-
- /* Read values from source B */
- inB2 = pIn2[1];
-
- /* Read values from source A */
- inA1 = pIn1[2];
-
- /* Add and saturate */
- out2 = __QADD(inA2, inB2);
-
- /* Read values from source B */
- inB1 = pIn2[2];
-
- /* Store result in destination */
- pOut[0] = out1;
- pOut[1] = out2;
-
- /* Read values from source A */
- inA2 = pIn1[3];
-
- /* Read values from source B */
- inB2 = pIn2[3];
-
- /* Add and saturate */
- out1 = __QADD(inA1, inB1);
- out2 = __QADD(inA2, inB2);
-
- /* Store result in destination */
- pOut[2] = out1;
- pOut[3] = out2;
-
- /* update pointers to process next sampels */
- pIn1 += 4u;
- pIn2 += 4u;
- pOut += 4u;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the numSamples is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = numSamples % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Initialize blkCnt with number of samples */
- blkCnt = numSamples;
-
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) + B(m,n) */
- /* Add, saturate and then store the results in the destination buffer. */
- inA1 = *pIn1++;
- inB1 = *pIn2++;
-
- inA1 = __QADD(inA1, inB1);
-
- /* Decrement the loop counter */
- blkCnt--;
-
- *pOut++ = inA1;
-
- }
-
- /* set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
-
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixAdd group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_f32.c
deleted file mode 100644
index d9d3388..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_f32.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_cmplx_mult_f32.c
-*
-* Description: Floating-point matrix multiplication.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @defgroup CmplxMatrixMult Complex Matrix Multiplication
- *
- * Complex Matrix multiplication is only defined if the number of columns of the
- * first matrix equals the number of rows of the second matrix.
- * Multiplying an M x N
matrix with an N x P
matrix results
- * in an M x P
matrix.
- * When matrix size checking is enabled, the functions check: (1) that the inner dimensions of
- * pSrcA
and pSrcB
are equal; and (2) that the size of the output
- * matrix equals the outer dimensions of pSrcA
and pSrcB
.
- */
-
-
-/**
- * @addtogroup CmplxMatrixMult
- * @{
- */
-
-/**
- * @brief Floating-point Complex matrix multiplication.
- * @param[in] *pSrcA points to the first input complex matrix structure
- * @param[in] *pSrcB points to the second input complex matrix structure
- * @param[out] *pDst points to output complex 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_cmplx_mult_f32(
- const arm_matrix_instance_f32 * pSrcA,
- const arm_matrix_instance_f32 * pSrcB,
- arm_matrix_instance_f32 * pDst)
-{
- float32_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
- float32_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
- float32_t *pInA = pSrcA->pData; /* input data matrix pointer A */
- float32_t *pOut = pDst->pData; /* output data matrix pointer */
- float32_t *px; /* Temporary output data matrix pointer */
- uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
- uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
- uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
- float32_t sumReal1, sumImag1; /* accumulator */
- float32_t a0, b0, c0, d0;
- float32_t a1, b1, c1, d1;
- float32_t sumReal2, sumImag2; /* accumulator */
-
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- uint16_t col, i = 0u, j, row = numRowsA, colCnt; /* loop counters */
- arm_status status; /* status of matrix multiplication */
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
-
- /* Check for matrix mismatch condition */
- if((pSrcA->numCols != pSrcB->numRows) ||
- (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
- {
-
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
-
- {
- /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
- /* row loop */
- do
- {
- /* Output pointer is set to starting address of the row being processed */
- px = pOut + 2 * i;
-
- /* For every row wise process, the column loop counter is to be initiated */
- col = numColsB;
-
- /* For every row wise process, the pIn2 pointer is set
- ** to the starting address of the pSrcB data */
- pIn2 = pSrcB->pData;
-
- j = 0u;
-
- /* column loop */
- do
- {
- /* Set the variable sum, that acts as accumulator, to zero */
- sumReal1 = 0.0f;
- sumImag1 = 0.0f;
-
- sumReal2 = 0.0f;
- sumImag2 = 0.0f;
-
- /* Initiate the pointer pIn1 to point to the starting address of the column being processed */
- pIn1 = pInA;
-
- /* Apply loop unrolling and compute 4 MACs simultaneously. */
- colCnt = numColsA >> 2;
-
- /* matrix multiplication */
- while(colCnt > 0u)
- {
-
- /* Reading real part of complex matrix A */
- a0 = *pIn1;
-
- /* Reading real part of complex matrix B */
- c0 = *pIn2;
-
- /* Reading imaginary part of complex matrix A */
- b0 = *(pIn1 + 1u);
-
- /* Reading imaginary part of complex matrix B */
- d0 = *(pIn2 + 1u);
-
- sumReal1 += a0 * c0;
- sumImag1 += b0 * c0;
-
- pIn1 += 2u;
- pIn2 += 2 * numColsB;
-
- sumReal2 -= b0 * d0;
- sumImag2 += a0 * d0;
-
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
-
- a1 = *pIn1;
- c1 = *pIn2;
-
- b1 = *(pIn1 + 1u);
- d1 = *(pIn2 + 1u);
-
- sumReal1 += a1 * c1;
- sumImag1 += b1 * c1;
-
- pIn1 += 2u;
- pIn2 += 2 * numColsB;
-
- sumReal2 -= b1 * d1;
- sumImag2 += a1 * d1;
-
- a0 = *pIn1;
- c0 = *pIn2;
-
- b0 = *(pIn1 + 1u);
- d0 = *(pIn2 + 1u);
-
- sumReal1 += a0 * c0;
- sumImag1 += b0 * c0;
-
- pIn1 += 2u;
- pIn2 += 2 * numColsB;
-
- sumReal2 -= b0 * d0;
- sumImag2 += a0 * d0;
-
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
-
- a1 = *pIn1;
- c1 = *pIn2;
-
- b1 = *(pIn1 + 1u);
- d1 = *(pIn2 + 1u);
-
- sumReal1 += a1 * c1;
- sumImag1 += b1 * c1;
-
- pIn1 += 2u;
- pIn2 += 2 * numColsB;
-
- sumReal2 -= b1 * d1;
- sumImag2 += a1 * d1;
-
- /* Decrement the loop count */
- colCnt--;
- }
-
- /* If the columns of pSrcA is not a multiple of 4, compute any remaining MACs here.
- ** No loop unrolling is used. */
- colCnt = numColsA % 0x4u;
-
- while(colCnt > 0u)
- {
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
- a1 = *pIn1;
- c1 = *pIn2;
-
- b1 = *(pIn1 + 1u);
- d1 = *(pIn2 + 1u);
-
- sumReal1 += a1 * c1;
- sumImag1 += b1 * c1;
-
- pIn1 += 2u;
- pIn2 += 2 * numColsB;
-
- sumReal2 -= b1 * d1;
- sumImag2 += a1 * d1;
-
- /* Decrement the loop counter */
- colCnt--;
- }
-
- sumReal1 += sumReal2;
- sumImag1 += sumImag2;
-
- /* Store the result in the destination buffer */
- *px++ = sumReal1;
- *px++ = sumImag1;
-
- /* Update the pointer pIn2 to point to the starting address of the next column */
- j++;
- pIn2 = pSrcB->pData + 2u * j;
-
- /* Decrement the column loop counter */
- col--;
-
- } while(col > 0u);
-
- /* Update the pointer pInA to point to the starting address of the next row */
- i = i + numColsB;
- pInA = pInA + 2 * numColsA;
-
- /* Decrement the row loop counter */
- row--;
-
- } while(row > 0u);
-
- /* Set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
-
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixMult group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_q15.c
deleted file mode 100644
index 46122ab..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_q15.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_cmplx_mat_mult_q15.c
-*
-* Description: Q15 complex matrix multiplication.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @addtogroup CmplxMatrixMult
- * @{
- */
-
-
-/**
- * @brief Q15 Complex matrix multiplication
- * @param[in] *pSrcA points to the first input complex matrix structure
- * @param[in] *pSrcB points to the second input complex matrix structure
- * @param[out] *pDst points to output complex matrix structure
- * @param[in] *pScratch 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.
- *
- * \par Conditions for optimum performance
- * Input, output and state buffers should be aligned by 32-bit
- *
- * \par Restrictions
- * If the silicon does not support unaligned memory access enable the macro UNALIGNED_SUPPORT_DISABLE
- * In this case input, output, scratch buffers should be aligned by 32-bit
- *
- * @details
- * Scaling and Overflow Behavior:
- *
- * \par
- * The function is implemented using a 64-bit internal accumulator. The inputs to the
- * multiplications are 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. This approach
- * provides 33 guard bits and there is no risk of overflow. The 34.30 result is then
- * truncated to 34.15 format by discarding the low 15 bits and then saturated to
- * 1.15 format.
- *
- * \par
- * Refer to arm_mat_mult_fast_q15()
for a faster but less precise version of this function.
- *
- */
-
-
-
-
-arm_status arm_mat_cmplx_mult_q15(
- const arm_matrix_instance_q15 * pSrcA,
- const arm_matrix_instance_q15 * pSrcB,
- arm_matrix_instance_q15 * pDst,
- q15_t * pScratch)
-{
- /* accumulator */
- q15_t *pSrcBT = pScratch; /* input data matrix pointer for transpose */
- q15_t *pInA = pSrcA->pData; /* input data matrix pointer A of Q15 type */
- q15_t *pInB = pSrcB->pData; /* input data matrix pointer B of Q15 type */
- q15_t *px; /* Temporary output data matrix pointer */
- uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
- uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
- uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
- uint16_t numRowsB = pSrcB->numRows; /* number of rows of input matrix A */
- uint16_t col, i = 0u, row = numRowsB, colCnt; /* loop counters */
- arm_status status; /* status of matrix multiplication */
- q63_t sumReal, sumImag;
-
-#ifdef UNALIGNED_SUPPORT_DISABLE
- q15_t in; /* Temporary variable to hold the input value */
- q15_t a, b, c, d;
-#else
- q31_t in; /* Temporary variable to hold the input value */
- q31_t prod1, prod2;
- q31_t pSourceA, pSourceB;
-#endif
-
-#ifdef ARM_MATH_MATRIX_CHECK
- /* Check for matrix mismatch condition */
- if((pSrcA->numCols != pSrcB->numRows) ||
- (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif
- {
- /* Matrix transpose */
- do
- {
- /* Apply loop unrolling and exchange the columns with row elements */
- col = numColsB >> 2;
-
- /* The pointer px is set to starting address of the column being processed */
- px = pSrcBT + i;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(col > 0u)
- {
-#ifdef UNALIGNED_SUPPORT_DISABLE
- /* Read two elements from the row */
- in = *pInB++;
- *px = in;
- in = *pInB++;
- px[1] = in;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB * 2;
-
- /* Read two elements from the row */
- in = *pInB++;
- *px = in;
- in = *pInB++;
- px[1] = in;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB * 2;
-
- /* Read two elements from the row */
- in = *pInB++;
- *px = in;
- in = *pInB++;
- px[1] = in;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB * 2;
-
- /* Read two elements from the row */
- in = *pInB++;
- *px = in;
- in = *pInB++;
- px[1] = in;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB * 2;
-
- /* Decrement the column loop counter */
- col--;
- }
-
- /* If the columns of pSrcB is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- col = numColsB % 0x4u;
-
- while(col > 0u)
- {
- /* Read two elements from the row */
- in = *pInB++;
- *px = in;
- in = *pInB++;
- px[1] = in;
-#else
-
- /* Read two elements from the row */
- in = *__SIMD32(pInB)++;
-
- *__SIMD32(px) = in;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB * 2;
-
-
- /* Read two elements from the row */
- in = *__SIMD32(pInB)++;
-
- *__SIMD32(px) = in;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB * 2;
-
- /* Read two elements from the row */
- in = *__SIMD32(pInB)++;
-
- *__SIMD32(px) = in;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB * 2;
-
- /* Read two elements from the row */
- in = *__SIMD32(pInB)++;
-
- *__SIMD32(px) = in;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB * 2;
-
- /* Decrement the column loop counter */
- col--;
- }
-
- /* If the columns of pSrcB is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- col = numColsB % 0x4u;
-
- while(col > 0u)
- {
- /* Read two elements from the row */
- in = *__SIMD32(pInB)++;
-
- *__SIMD32(px) = in;
-#endif
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB * 2;
-
- /* Decrement the column loop counter */
- col--;
- }
-
- i = i + 2u;
-
- /* Decrement the row loop counter */
- row--;
-
- } while(row > 0u);
-
- /* Reset the variables for the usage in the following multiplication process */
- row = numRowsA;
- i = 0u;
- px = pDst->pData;
-
- /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
- /* row loop */
- do
- {
- /* For every row wise process, the column loop counter is to be initiated */
- col = numColsB;
-
- /* For every row wise process, the pIn2 pointer is set
- ** to the starting address of the transposed pSrcB data */
- pInB = pSrcBT;
-
- /* column loop */
- do
- {
- /* Set the variable sum, that acts as accumulator, to zero */
- sumReal = 0;
- sumImag = 0;
-
- /* Apply loop unrolling and compute 2 MACs simultaneously. */
- colCnt = numColsA >> 1;
-
- /* Initiate the pointer pIn1 to point to the starting address of the column being processed */
- pInA = pSrcA->pData + i * 2;
-
-
- /* matrix multiplication */
- while(colCnt > 0u)
- {
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
-
-#ifdef UNALIGNED_SUPPORT_DISABLE
-
- /* read real and imag values from pSrcA buffer */
- a = *pInA;
- b = *(pInA + 1u);
- /* read real and imag values from pSrcB buffer */
- c = *pInB;
- d = *(pInB + 1u);
-
- /* Multiply and Accumlates */
- sumReal += (q31_t) a *c;
- sumImag += (q31_t) a *d;
- sumReal -= (q31_t) b *d;
- sumImag += (q31_t) b *c;
-
- /* read next real and imag values from pSrcA buffer */
- a = *(pInA + 2u);
- b = *(pInA + 3u);
- /* read next real and imag values from pSrcB buffer */
- c = *(pInB + 2u);
- d = *(pInB + 3u);
-
- /* update pointer */
- pInA += 4u;
-
- /* Multiply and Accumlates */
- sumReal += (q31_t) a *c;
- sumImag += (q31_t) a *d;
- sumReal -= (q31_t) b *d;
- sumImag += (q31_t) b *c;
- /* update pointer */
- pInB += 4u;
-#else
- /* read real and imag values from pSrcA and pSrcB buffer */
- pSourceA = *__SIMD32(pInA)++;
- pSourceB = *__SIMD32(pInB)++;
-
- /* Multiply and Accumlates */
-#ifdef ARM_MATH_BIG_ENDIAN
- prod1 = -__SMUSD(pSourceA, pSourceB);
-#else
- prod1 = __SMUSD(pSourceA, pSourceB);
-#endif
- prod2 = __SMUADX(pSourceA, pSourceB);
- sumReal += (q63_t) prod1;
- sumImag += (q63_t) prod2;
-
- /* read real and imag values from pSrcA and pSrcB buffer */
- pSourceA = *__SIMD32(pInA)++;
- pSourceB = *__SIMD32(pInB)++;
-
- /* Multiply and Accumlates */
-#ifdef ARM_MATH_BIG_ENDIAN
- prod1 = -__SMUSD(pSourceA, pSourceB);
-#else
- prod1 = __SMUSD(pSourceA, pSourceB);
-#endif
- prod2 = __SMUADX(pSourceA, pSourceB);
- sumReal += (q63_t) prod1;
- sumImag += (q63_t) prod2;
-
-#endif /* #ifdef UNALIGNED_SUPPORT_DISABLE */
-
- /* Decrement the loop counter */
- colCnt--;
- }
-
- /* process odd column samples */
- if((numColsA & 0x1u) > 0u)
- {
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
-
-#ifdef UNALIGNED_SUPPORT_DISABLE
-
- /* read real and imag values from pSrcA and pSrcB buffer */
- a = *pInA++;
- b = *pInA++;
- c = *pInB++;
- d = *pInB++;
-
- /* Multiply and Accumlates */
- sumReal += (q31_t) a *c;
- sumImag += (q31_t) a *d;
- sumReal -= (q31_t) b *d;
- sumImag += (q31_t) b *c;
-
-#else
- /* read real and imag values from pSrcA and pSrcB buffer */
- pSourceA = *__SIMD32(pInA)++;
- pSourceB = *__SIMD32(pInB)++;
-
- /* Multiply and Accumlates */
-#ifdef ARM_MATH_BIG_ENDIAN
- prod1 = -__SMUSD(pSourceA, pSourceB);
-#else
- prod1 = __SMUSD(pSourceA, pSourceB);
-#endif
- prod2 = __SMUADX(pSourceA, pSourceB);
- sumReal += (q63_t) prod1;
- sumImag += (q63_t) prod2;
-
-#endif /* #ifdef UNALIGNED_SUPPORT_DISABLE */
-
- }
-
- /* Saturate and store the result in the destination buffer */
-
- *px++ = (q15_t) (__SSAT(sumReal >> 15, 16));
- *px++ = (q15_t) (__SSAT(sumImag >> 15, 16));
-
- /* Decrement the column loop counter */
- col--;
-
- } while(col > 0u);
-
- i = i + numColsA;
-
- /* Decrement the row loop counter */
- row--;
-
- } while(row > 0u);
-
- /* set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
-
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixMult group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_q31.c
deleted file mode 100644
index 4053554..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_q31.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_cmplx_mult_q31.c
-*
-* Description: Floating-point matrix multiplication.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @addtogroup CmplxMatrixMult
- * @{
- */
-
-/**
- * @brief Q31 Complex matrix multiplication
- * @param[in] *pSrcA points to the first input complex matrix structure
- * @param[in] *pSrcB points to the second input complex matrix structure
- * @param[out] *pDst points to output complex matrix structure
- * @return The function returns either
- * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
- *
- * @details
- * 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. There is no saturation
- * on intermediate additions. Thus, if the accumulator overflows it wraps around and
- * distorts the result. The input signals should be scaled down to avoid intermediate
- * overflows. The input is thus scaled down by log2(numColsA) bits
- * to avoid overflows, as a total of numColsA additions are performed internally.
- * The 2.62 accumulator is right shifted by 31 bits and saturated to 1.31 format to yield the final result.
- *
- *
- */
-
-arm_status arm_mat_cmplx_mult_q31(
- const arm_matrix_instance_q31 * pSrcA,
- const arm_matrix_instance_q31 * pSrcB,
- arm_matrix_instance_q31 * pDst)
-{
- q31_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
- q31_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
- q31_t *pInA = pSrcA->pData; /* input data matrix pointer A */
- q31_t *pOut = pDst->pData; /* output data matrix pointer */
- q31_t *px; /* Temporary output data matrix pointer */
- uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
- uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
- uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
- q63_t sumReal1, sumImag1; /* accumulator */
- q31_t a0, b0, c0, d0;
- q31_t a1, b1, c1, d1;
-
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- uint16_t col, i = 0u, j, row = numRowsA, colCnt; /* loop counters */
- arm_status status; /* status of matrix multiplication */
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
-
- /* Check for matrix mismatch condition */
- if((pSrcA->numCols != pSrcB->numRows) ||
- (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
- {
-
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
-
- {
- /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
- /* row loop */
- do
- {
- /* Output pointer is set to starting address of the row being processed */
- px = pOut + 2 * i;
-
- /* For every row wise process, the column loop counter is to be initiated */
- col = numColsB;
-
- /* For every row wise process, the pIn2 pointer is set
- ** to the starting address of the pSrcB data */
- pIn2 = pSrcB->pData;
-
- j = 0u;
-
- /* column loop */
- do
- {
- /* Set the variable sum, that acts as accumulator, to zero */
- sumReal1 = 0.0;
- sumImag1 = 0.0;
-
- /* Initiate the pointer pIn1 to point to the starting address of the column being processed */
- pIn1 = pInA;
-
- /* Apply loop unrolling and compute 4 MACs simultaneously. */
- colCnt = numColsA >> 2;
-
- /* matrix multiplication */
- while(colCnt > 0u)
- {
-
- /* Reading real part of complex matrix A */
- a0 = *pIn1;
-
- /* Reading real part of complex matrix B */
- c0 = *pIn2;
-
- /* Reading imaginary part of complex matrix A */
- b0 = *(pIn1 + 1u);
-
- /* Reading imaginary part of complex matrix B */
- d0 = *(pIn2 + 1u);
-
- /* Multiply and Accumlates */
- sumReal1 += (q63_t) a0 *c0;
- sumImag1 += (q63_t) b0 *c0;
-
- /* update pointers */
- pIn1 += 2u;
- pIn2 += 2 * numColsB;
-
- /* Multiply and Accumlates */
- sumReal1 -= (q63_t) b0 *d0;
- sumImag1 += (q63_t) a0 *d0;
-
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
-
- /* read real and imag values from pSrcA and pSrcB buffer */
- a1 = *pIn1;
- c1 = *pIn2;
- b1 = *(pIn1 + 1u);
- d1 = *(pIn2 + 1u);
-
- /* Multiply and Accumlates */
- sumReal1 += (q63_t) a1 *c1;
- sumImag1 += (q63_t) b1 *c1;
-
- /* update pointers */
- pIn1 += 2u;
- pIn2 += 2 * numColsB;
-
- /* Multiply and Accumlates */
- sumReal1 -= (q63_t) b1 *d1;
- sumImag1 += (q63_t) a1 *d1;
-
- a0 = *pIn1;
- c0 = *pIn2;
-
- b0 = *(pIn1 + 1u);
- d0 = *(pIn2 + 1u);
-
- /* Multiply and Accumlates */
- sumReal1 += (q63_t) a0 *c0;
- sumImag1 += (q63_t) b0 *c0;
-
- /* update pointers */
- pIn1 += 2u;
- pIn2 += 2 * numColsB;
-
- /* Multiply and Accumlates */
- sumReal1 -= (q63_t) b0 *d0;
- sumImag1 += (q63_t) a0 *d0;
-
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
-
- a1 = *pIn1;
- c1 = *pIn2;
-
- b1 = *(pIn1 + 1u);
- d1 = *(pIn2 + 1u);
-
- /* Multiply and Accumlates */
- sumReal1 += (q63_t) a1 *c1;
- sumImag1 += (q63_t) b1 *c1;
-
- /* update pointers */
- pIn1 += 2u;
- pIn2 += 2 * numColsB;
-
- /* Multiply and Accumlates */
- sumReal1 -= (q63_t) b1 *d1;
- sumImag1 += (q63_t) a1 *d1;
-
- /* Decrement the loop count */
- colCnt--;
- }
-
- /* If the columns of pSrcA is not a multiple of 4, compute any remaining MACs here.
- ** No loop unrolling is used. */
- colCnt = numColsA % 0x4u;
-
- while(colCnt > 0u)
- {
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
- a1 = *pIn1;
- c1 = *pIn2;
-
- b1 = *(pIn1 + 1u);
- d1 = *(pIn2 + 1u);
-
- /* Multiply and Accumlates */
- sumReal1 += (q63_t) a1 *c1;
- sumImag1 += (q63_t) b1 *c1;
-
- /* update pointers */
- pIn1 += 2u;
- pIn2 += 2 * numColsB;
-
- /* Multiply and Accumlates */
- sumReal1 -= (q63_t) b1 *d1;
- sumImag1 += (q63_t) a1 *d1;
-
- /* Decrement the loop counter */
- colCnt--;
- }
-
- /* Store the result in the destination buffer */
- *px++ = (q31_t) clip_q63_to_q31(sumReal1 >> 31);
- *px++ = (q31_t) clip_q63_to_q31(sumImag1 >> 31);
-
- /* Update the pointer pIn2 to point to the starting address of the next column */
- j++;
- pIn2 = pSrcB->pData + 2u * j;
-
- /* Decrement the column loop counter */
- col--;
-
- } while(col > 0u);
-
- /* Update the pointer pInA to point to the starting address of the next row */
- i = i + numColsB;
- pInA = pInA + 2 * numColsA;
-
- /* Decrement the row loop counter */
- row--;
-
- } while(row > 0u);
-
- /* Set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
-
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixMult group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_init_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_init_f32.c
deleted file mode 100644
index 2a670b3..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_init_f32.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/* ----------------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_init_f32.c
-*
-* Description: Floating-point matrix initialization.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @defgroup MatrixInit Matrix Initialization
- *
- * Initializes the underlying matrix data structure.
- * The functions set the numRows
,
- * numCols
, and pData
fields
- * of the matrix data structure.
- */
-
-/**
- * @addtogroup MatrixInit
- * @{
- */
-
-/**
- * @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)
-{
- /* Assign Number of Rows */
- S->numRows = nRows;
-
- /* Assign Number of Columns */
- S->numCols = nColumns;
-
- /* Assign Data pointer */
- S->pData = pData;
-}
-
-/**
- * @} end of MatrixInit group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_init_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_init_q31.c
deleted file mode 100644
index 3fefda4..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_init_q31.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_init_q31.c
-*
-* Description: Q31 matrix initialization.
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @defgroup MatrixInit Matrix Initialization
- *
- */
-
-/**
- * @addtogroup MatrixInit
- * @{
- */
-
- /**
- * @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)
-{
- /* Assign Number of Rows */
- S->numRows = nRows;
-
- /* Assign Number of Columns */
- S->numCols = nColumns;
-
- /* Assign Data pointer */
- S->pData = pData;
-}
-
-/**
- * @} end of MatrixInit group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_inverse_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_inverse_f32.c
deleted file mode 100644
index f6fb9da..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_inverse_f32.c
+++ /dev/null
@@ -1,703 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_inverse_f32.c
-*
-* Description: Floating-point matrix inverse.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @defgroup MatrixInv Matrix Inverse
- *
- * Computes the inverse of a matrix.
- *
- * The inverse is defined only if the input matrix is square and non-singular (the determinant
- * is non-zero). The function checks that the input and output matrices are square and of the
- * same size.
- *
- * Matrix inversion is numerically sensitive and the CMSIS DSP library only supports matrix
- * inversion of floating-point matrices.
- *
- * \par Algorithm
- * The Gauss-Jordan method is used to find the inverse.
- * The algorithm performs a sequence of elementary row-operations until it
- * reduces the input matrix to an identity matrix. Applying the same sequence
- * of elementary row-operations to an identity matrix yields the inverse matrix.
- * If the input matrix is singular, then the algorithm terminates and returns error status
- * ARM_MATH_SINGULAR
.
- * \image html MatrixInverse.gif "Matrix Inverse of a 3 x 3 matrix using Gauss-Jordan Method"
- */
-
-/**
- * @addtogroup MatrixInv
- * @{
- */
-
-/**
- * @brief Floating-point matrix inverse.
- * @param[in] *pSrc points to input matrix structure
- * @param[out] *pDst points to output matrix structure
- * @return The function returns
- * ARM_MATH_SIZE_MISMATCH
if the input matrix is not square or if the size
- * of the output matrix does not match the size of the input matrix.
- * If the input matrix is found to be singular (non-invertible), then the function returns
- * ARM_MATH_SINGULAR
. Otherwise, the function returns ARM_MATH_SUCCESS
.
- */
-
-arm_status arm_mat_inverse_f32(
- const arm_matrix_instance_f32 * pSrc,
- arm_matrix_instance_f32 * pDst)
-{
- float32_t *pIn = pSrc->pData; /* input data matrix pointer */
- float32_t *pOut = pDst->pData; /* output data matrix pointer */
- float32_t *pInT1, *pInT2; /* Temporary input data matrix pointer */
- float32_t *pOutT1, *pOutT2; /* Temporary output data matrix pointer */
- float32_t *pPivotRowIn, *pPRT_in, *pPivotRowDst, *pPRT_pDst; /* Temporary input and output data matrix pointer */
- uint32_t numRows = pSrc->numRows; /* Number of rows in the matrix */
- uint32_t numCols = pSrc->numCols; /* Number of Cols in the matrix */
-
-#ifndef ARM_MATH_CM0_FAMILY
- float32_t maxC; /* maximum value in the column */
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- float32_t Xchg, in = 0.0f, in1; /* Temporary input values */
- uint32_t i, rowCnt, flag = 0u, j, loopCnt, k, l; /* loop counters */
- arm_status status; /* status of matrix inverse */
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
-
- /* Check for matrix mismatch condition */
- if((pSrc->numRows != pSrc->numCols) || (pDst->numRows != pDst->numCols)
- || (pSrc->numRows != pDst->numRows))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
-
- {
-
- /*--------------------------------------------------------------------------------------------------------------
- * Matrix Inverse can be solved using elementary row operations.
- *
- * Gauss-Jordan Method:
- *
- * 1. First combine the identity matrix and the input matrix separated by a bar to form an
- * augmented matrix as follows:
- * _ _ _ _
- * | a11 a12 | 1 0 | | X11 X12 |
- * | | | = | |
- * |_ a21 a22 | 0 1 _| |_ X21 X21 _|
- *
- * 2. In our implementation, pDst Matrix is used as identity matrix.
- *
- * 3. Begin with the first row. Let i = 1.
- *
- * 4. Check to see if the pivot for column i is the greatest of the column.
- * The pivot is the element of the main diagonal that is on the current row.
- * For instance, if working with row i, then the pivot element is aii.
- * If the pivot is not the most significant of the columns, exchange that row with a row
- * below it that does contain the most significant value in column i. If the most
- * significant value of the column is zero, then an inverse to that matrix does not exist.
- * The most significant value of the column is the absolute maximum.
- *
- * 5. Divide every element of row i by the pivot.
- *
- * 6. For every row below and row i, replace that row with the sum of that row and
- * a multiple of row i so that each new element in column i below row i is zero.
- *
- * 7. Move to the next row and column and repeat steps 2 through 5 until you have zeros
- * for every element below and above the main diagonal.
- *
- * 8. Now an identical matrix is formed to the left of the bar(input matrix, pSrc).
- * Therefore, the matrix to the right of the bar is our solution(pDst matrix, pDst).
- *----------------------------------------------------------------------------------------------------------------*/
-
- /* Working pointer for destination matrix */
- pOutT1 = pOut;
-
- /* Loop over the number of rows */
- rowCnt = numRows;
-
- /* Making the destination matrix as identity matrix */
- while(rowCnt > 0u)
- {
- /* Writing all zeroes in lower triangle of the destination matrix */
- j = numRows - rowCnt;
- while(j > 0u)
- {
- *pOutT1++ = 0.0f;
- j--;
- }
-
- /* Writing all ones in the diagonal of the destination matrix */
- *pOutT1++ = 1.0f;
-
- /* Writing all zeroes in upper triangle of the destination matrix */
- j = rowCnt - 1u;
- while(j > 0u)
- {
- *pOutT1++ = 0.0f;
- j--;
- }
-
- /* Decrement the loop counter */
- rowCnt--;
- }
-
- /* Loop over the number of columns of the input matrix.
- All the elements in each column are processed by the row operations */
- loopCnt = numCols;
-
- /* Index modifier to navigate through the columns */
- l = 0u;
-
- while(loopCnt > 0u)
- {
- /* Check if the pivot element is zero..
- * If it is zero then interchange the row with non zero row below.
- * If there is no non zero element to replace in the rows below,
- * then the matrix is Singular. */
-
- /* Working pointer for the input matrix that points
- * to the pivot element of the particular row */
- pInT1 = pIn + (l * numCols);
-
- /* Working pointer for the destination matrix that points
- * to the pivot element of the particular row */
- pOutT1 = pOut + (l * numCols);
-
- /* Temporary variable to hold the pivot value */
- in = *pInT1;
-
- /* Grab the most significant value from column l */
- maxC = 0;
- for (i = l; i < numRows; i++)
- {
- maxC = *pInT1 > 0 ? (*pInT1 > maxC ? *pInT1 : maxC) : (-*pInT1 > maxC ? -*pInT1 : maxC);
- pInT1 += numCols;
- }
-
- /* Update the status if the matrix is singular */
- if(maxC == 0.0f)
- {
- return ARM_MATH_SINGULAR;
- }
-
- /* Restore pInT1 */
- pInT1 = pIn;
-
- /* Destination pointer modifier */
- k = 1u;
-
- /* Check if the pivot element is the most significant of the column */
- if( (in > 0.0f ? in : -in) != maxC)
- {
- /* Loop over the number rows present below */
- i = numRows - (l + 1u);
-
- while(i > 0u)
- {
- /* Update the input and destination pointers */
- pInT2 = pInT1 + (numCols * l);
- pOutT2 = pOutT1 + (numCols * k);
-
- /* Look for the most significant element to
- * replace in the rows below */
- if((*pInT2 > 0.0f ? *pInT2: -*pInT2) == maxC)
- {
- /* Loop over number of columns
- * to the right of the pilot element */
- j = numCols - l;
-
- while(j > 0u)
- {
- /* Exchange the row elements of the input matrix */
- Xchg = *pInT2;
- *pInT2++ = *pInT1;
- *pInT1++ = Xchg;
-
- /* Decrement the loop counter */
- j--;
- }
-
- /* Loop over number of columns of the destination matrix */
- j = numCols;
-
- while(j > 0u)
- {
- /* Exchange the row elements of the destination matrix */
- Xchg = *pOutT2;
- *pOutT2++ = *pOutT1;
- *pOutT1++ = Xchg;
-
- /* Decrement the loop counter */
- j--;
- }
-
- /* Flag to indicate whether exchange is done or not */
- flag = 1u;
-
- /* Break after exchange is done */
- break;
- }
-
- /* Update the destination pointer modifier */
- k++;
-
- /* Decrement the loop counter */
- i--;
- }
- }
-
- /* Update the status if the matrix is singular */
- if((flag != 1u) && (in == 0.0f))
- {
- return ARM_MATH_SINGULAR;
- }
-
- /* Points to the pivot row of input and destination matrices */
- pPivotRowIn = pIn + (l * numCols);
- pPivotRowDst = pOut + (l * numCols);
-
- /* Temporary pointers to the pivot row pointers */
- pInT1 = pPivotRowIn;
- pInT2 = pPivotRowDst;
-
- /* Pivot element of the row */
- in = *pPivotRowIn;
-
- /* Loop over number of columns
- * to the right of the pilot element */
- j = (numCols - l);
-
- while(j > 0u)
- {
- /* Divide each element of the row of the input matrix
- * by the pivot element */
- in1 = *pInT1;
- *pInT1++ = in1 / in;
-
- /* Decrement the loop counter */
- j--;
- }
-
- /* Loop over number of columns of the destination matrix */
- j = numCols;
-
- while(j > 0u)
- {
- /* Divide each element of the row of the destination matrix
- * by the pivot element */
- in1 = *pInT2;
- *pInT2++ = in1 / in;
-
- /* Decrement the loop counter */
- j--;
- }
-
- /* Replace the rows with the sum of that row and a multiple of row i
- * so that each new element in column i above row i is zero.*/
-
- /* Temporary pointers for input and destination matrices */
- pInT1 = pIn;
- pInT2 = pOut;
-
- /* index used to check for pivot element */
- i = 0u;
-
- /* Loop over number of rows */
- /* to be replaced by the sum of that row and a multiple of row i */
- k = numRows;
-
- while(k > 0u)
- {
- /* Check for the pivot element */
- if(i == l)
- {
- /* If the processing element is the pivot element,
- only the columns to the right are to be processed */
- pInT1 += numCols - l;
-
- pInT2 += numCols;
- }
- else
- {
- /* Element of the reference row */
- in = *pInT1;
-
- /* Working pointers for input and destination pivot rows */
- pPRT_in = pPivotRowIn;
- pPRT_pDst = pPivotRowDst;
-
- /* Loop over the number of columns to the right of the pivot element,
- to replace the elements in the input matrix */
- j = (numCols - l);
-
- while(j > 0u)
- {
- /* Replace the element by the sum of that row
- and a multiple of the reference row */
- in1 = *pInT1;
- *pInT1++ = in1 - (in * *pPRT_in++);
-
- /* Decrement the loop counter */
- j--;
- }
-
- /* Loop over the number of columns to
- replace the elements in the destination matrix */
- j = numCols;
-
- while(j > 0u)
- {
- /* Replace the element by the sum of that row
- and a multiple of the reference row */
- in1 = *pInT2;
- *pInT2++ = in1 - (in * *pPRT_pDst++);
-
- /* Decrement the loop counter */
- j--;
- }
-
- }
-
- /* Increment the temporary input pointer */
- pInT1 = pInT1 + l;
-
- /* Decrement the loop counter */
- k--;
-
- /* Increment the pivot index */
- i++;
- }
-
- /* Increment the input pointer */
- pIn++;
-
- /* Decrement the loop counter */
- loopCnt--;
-
- /* Increment the index modifier */
- l++;
- }
-
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- float32_t Xchg, in = 0.0f; /* Temporary input values */
- uint32_t i, rowCnt, flag = 0u, j, loopCnt, k, l; /* loop counters */
- arm_status status; /* status of matrix inverse */
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
- /* Check for matrix mismatch condition */
- if((pSrc->numRows != pSrc->numCols) || (pDst->numRows != pDst->numCols)
- || (pSrc->numRows != pDst->numRows))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
- {
-
- /*--------------------------------------------------------------------------------------------------------------
- * Matrix Inverse can be solved using elementary row operations.
- *
- * Gauss-Jordan Method:
- *
- * 1. First combine the identity matrix and the input matrix separated by a bar to form an
- * augmented matrix as follows:
- * _ _ _ _ _ _ _ _
- * | | a11 a12 | | | 1 0 | | | X11 X12 |
- * | | | | | | | = | |
- * |_ |_ a21 a22 _| | |_0 1 _| _| |_ X21 X21 _|
- *
- * 2. In our implementation, pDst Matrix is used as identity matrix.
- *
- * 3. Begin with the first row. Let i = 1.
- *
- * 4. Check to see if the pivot for row i is zero.
- * The pivot is the element of the main diagonal that is on the current row.
- * For instance, if working with row i, then the pivot element is aii.
- * If the pivot is zero, exchange that row with a row below it that does not
- * contain a zero in column i. If this is not possible, then an inverse
- * to that matrix does not exist.
- *
- * 5. Divide every element of row i by the pivot.
- *
- * 6. For every row below and row i, replace that row with the sum of that row and
- * a multiple of row i so that each new element in column i below row i is zero.
- *
- * 7. Move to the next row and column and repeat steps 2 through 5 until you have zeros
- * for every element below and above the main diagonal.
- *
- * 8. Now an identical matrix is formed to the left of the bar(input matrix, src).
- * Therefore, the matrix to the right of the bar is our solution(dst matrix, dst).
- *----------------------------------------------------------------------------------------------------------------*/
-
- /* Working pointer for destination matrix */
- pOutT1 = pOut;
-
- /* Loop over the number of rows */
- rowCnt = numRows;
-
- /* Making the destination matrix as identity matrix */
- while(rowCnt > 0u)
- {
- /* Writing all zeroes in lower triangle of the destination matrix */
- j = numRows - rowCnt;
- while(j > 0u)
- {
- *pOutT1++ = 0.0f;
- j--;
- }
-
- /* Writing all ones in the diagonal of the destination matrix */
- *pOutT1++ = 1.0f;
-
- /* Writing all zeroes in upper triangle of the destination matrix */
- j = rowCnt - 1u;
- while(j > 0u)
- {
- *pOutT1++ = 0.0f;
- j--;
- }
-
- /* Decrement the loop counter */
- rowCnt--;
- }
-
- /* Loop over the number of columns of the input matrix.
- All the elements in each column are processed by the row operations */
- loopCnt = numCols;
-
- /* Index modifier to navigate through the columns */
- l = 0u;
- //for(loopCnt = 0u; loopCnt < numCols; loopCnt++)
- while(loopCnt > 0u)
- {
- /* Check if the pivot element is zero..
- * If it is zero then interchange the row with non zero row below.
- * If there is no non zero element to replace in the rows below,
- * then the matrix is Singular. */
-
- /* Working pointer for the input matrix that points
- * to the pivot element of the particular row */
- pInT1 = pIn + (l * numCols);
-
- /* Working pointer for the destination matrix that points
- * to the pivot element of the particular row */
- pOutT1 = pOut + (l * numCols);
-
- /* Temporary variable to hold the pivot value */
- in = *pInT1;
-
- /* Destination pointer modifier */
- k = 1u;
-
- /* Check if the pivot element is zero */
- if(*pInT1 == 0.0f)
- {
- /* Loop over the number rows present below */
- for (i = (l + 1u); i < numRows; i++)
- {
- /* Update the input and destination pointers */
- pInT2 = pInT1 + (numCols * l);
- pOutT2 = pOutT1 + (numCols * k);
-
- /* Check if there is a non zero pivot element to
- * replace in the rows below */
- if(*pInT2 != 0.0f)
- {
- /* Loop over number of columns
- * to the right of the pilot element */
- for (j = 0u; j < (numCols - l); j++)
- {
- /* Exchange the row elements of the input matrix */
- Xchg = *pInT2;
- *pInT2++ = *pInT1;
- *pInT1++ = Xchg;
- }
-
- for (j = 0u; j < numCols; j++)
- {
- Xchg = *pOutT2;
- *pOutT2++ = *pOutT1;
- *pOutT1++ = Xchg;
- }
-
- /* Flag to indicate whether exchange is done or not */
- flag = 1u;
-
- /* Break after exchange is done */
- break;
- }
-
- /* Update the destination pointer modifier */
- k++;
- }
- }
-
- /* Update the status if the matrix is singular */
- if((flag != 1u) && (in == 0.0f))
- {
- return ARM_MATH_SINGULAR;
- }
-
- /* Points to the pivot row of input and destination matrices */
- pPivotRowIn = pIn + (l * numCols);
- pPivotRowDst = pOut + (l * numCols);
-
- /* Temporary pointers to the pivot row pointers */
- pInT1 = pPivotRowIn;
- pOutT1 = pPivotRowDst;
-
- /* Pivot element of the row */
- in = *(pIn + (l * numCols));
-
- /* Loop over number of columns
- * to the right of the pilot element */
- for (j = 0u; j < (numCols - l); j++)
- {
- /* Divide each element of the row of the input matrix
- * by the pivot element */
- *pInT1 = *pInT1 / in;
- pInT1++;
- }
- for (j = 0u; j < numCols; j++)
- {
- /* Divide each element of the row of the destination matrix
- * by the pivot element */
- *pOutT1 = *pOutT1 / in;
- pOutT1++;
- }
-
- /* Replace the rows with the sum of that row and a multiple of row i
- * so that each new element in column i above row i is zero.*/
-
- /* Temporary pointers for input and destination matrices */
- pInT1 = pIn;
- pOutT1 = pOut;
-
- for (i = 0u; i < numRows; i++)
- {
- /* Check for the pivot element */
- if(i == l)
- {
- /* If the processing element is the pivot element,
- only the columns to the right are to be processed */
- pInT1 += numCols - l;
- pOutT1 += numCols;
- }
- else
- {
- /* Element of the reference row */
- in = *pInT1;
-
- /* Working pointers for input and destination pivot rows */
- pPRT_in = pPivotRowIn;
- pPRT_pDst = pPivotRowDst;
-
- /* Loop over the number of columns to the right of the pivot element,
- to replace the elements in the input matrix */
- for (j = 0u; j < (numCols - l); j++)
- {
- /* Replace the element by the sum of that row
- and a multiple of the reference row */
- *pInT1 = *pInT1 - (in * *pPRT_in++);
- pInT1++;
- }
- /* Loop over the number of columns to
- replace the elements in the destination matrix */
- for (j = 0u; j < numCols; j++)
- {
- /* Replace the element by the sum of that row
- and a multiple of the reference row */
- *pOutT1 = *pOutT1 - (in * *pPRT_pDst++);
- pOutT1++;
- }
-
- }
- /* Increment the temporary input pointer */
- pInT1 = pInT1 + l;
- }
- /* Increment the input pointer */
- pIn++;
-
- /* Decrement the loop counter */
- loopCnt--;
- /* Increment the index modifier */
- l++;
- }
-
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- /* Set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
-
- if((flag != 1u) && (in == 0.0f))
- {
- pIn = pSrc->pData;
- for (i = 0; i < numRows * numCols; i++)
- {
- if (pIn[i] != 0.0f)
- break;
- }
-
- if (i == numRows * numCols)
- status = ARM_MATH_SINGULAR;
- }
- }
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixInv group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_inverse_f64.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_inverse_f64.c
deleted file mode 100644
index 5fe42d4..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_inverse_f64.c
+++ /dev/null
@@ -1,703 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_inverse_f64.c
-*
-* Description: Floating-point matrix inverse.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @defgroup MatrixInv Matrix Inverse
- *
- * Computes the inverse of a matrix.
- *
- * The inverse is defined only if the input matrix is square and non-singular (the determinant
- * is non-zero). The function checks that the input and output matrices are square and of the
- * same size.
- *
- * Matrix inversion is numerically sensitive and the CMSIS DSP library only supports matrix
- * inversion of floating-point matrices.
- *
- * \par Algorithm
- * The Gauss-Jordan method is used to find the inverse.
- * The algorithm performs a sequence of elementary row-operations until it
- * reduces the input matrix to an identity matrix. Applying the same sequence
- * of elementary row-operations to an identity matrix yields the inverse matrix.
- * If the input matrix is singular, then the algorithm terminates and returns error status
- * ARM_MATH_SINGULAR
.
- * \image html MatrixInverse.gif "Matrix Inverse of a 3 x 3 matrix using Gauss-Jordan Method"
- */
-
-/**
- * @addtogroup MatrixInv
- * @{
- */
-
-/**
- * @brief Floating-point matrix inverse.
- * @param[in] *pSrc points to input matrix structure
- * @param[out] *pDst points to output matrix structure
- * @return The function returns
- * ARM_MATH_SIZE_MISMATCH
if the input matrix is not square or if the size
- * of the output matrix does not match the size of the input matrix.
- * If the input matrix is found to be singular (non-invertible), then the function returns
- * ARM_MATH_SINGULAR
. Otherwise, the function returns ARM_MATH_SUCCESS
.
- */
-
-arm_status arm_mat_inverse_f64(
- const arm_matrix_instance_f64 * pSrc,
- arm_matrix_instance_f64 * pDst)
-{
- float64_t *pIn = pSrc->pData; /* input data matrix pointer */
- float64_t *pOut = pDst->pData; /* output data matrix pointer */
- float64_t *pInT1, *pInT2; /* Temporary input data matrix pointer */
- float64_t *pOutT1, *pOutT2; /* Temporary output data matrix pointer */
- float64_t *pPivotRowIn, *pPRT_in, *pPivotRowDst, *pPRT_pDst; /* Temporary input and output data matrix pointer */
- uint32_t numRows = pSrc->numRows; /* Number of rows in the matrix */
- uint32_t numCols = pSrc->numCols; /* Number of Cols in the matrix */
-
-#ifndef ARM_MATH_CM0_FAMILY
- float64_t maxC; /* maximum value in the column */
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- float64_t Xchg, in = 0.0f, in1; /* Temporary input values */
- uint32_t i, rowCnt, flag = 0u, j, loopCnt, k, l; /* loop counters */
- arm_status status; /* status of matrix inverse */
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
-
- /* Check for matrix mismatch condition */
- if((pSrc->numRows != pSrc->numCols) || (pDst->numRows != pDst->numCols)
- || (pSrc->numRows != pDst->numRows))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
-
- {
-
- /*--------------------------------------------------------------------------------------------------------------
- * Matrix Inverse can be solved using elementary row operations.
- *
- * Gauss-Jordan Method:
- *
- * 1. First combine the identity matrix and the input matrix separated by a bar to form an
- * augmented matrix as follows:
- * _ _ _ _
- * | a11 a12 | 1 0 | | X11 X12 |
- * | | | = | |
- * |_ a21 a22 | 0 1 _| |_ X21 X21 _|
- *
- * 2. In our implementation, pDst Matrix is used as identity matrix.
- *
- * 3. Begin with the first row. Let i = 1.
- *
- * 4. Check to see if the pivot for column i is the greatest of the column.
- * The pivot is the element of the main diagonal that is on the current row.
- * For instance, if working with row i, then the pivot element is aii.
- * If the pivot is not the most significant of the columns, exchange that row with a row
- * below it that does contain the most significant value in column i. If the most
- * significant value of the column is zero, then an inverse to that matrix does not exist.
- * The most significant value of the column is the absolute maximum.
- *
- * 5. Divide every element of row i by the pivot.
- *
- * 6. For every row below and row i, replace that row with the sum of that row and
- * a multiple of row i so that each new element in column i below row i is zero.
- *
- * 7. Move to the next row and column and repeat steps 2 through 5 until you have zeros
- * for every element below and above the main diagonal.
- *
- * 8. Now an identical matrix is formed to the left of the bar(input matrix, pSrc).
- * Therefore, the matrix to the right of the bar is our solution(pDst matrix, pDst).
- *----------------------------------------------------------------------------------------------------------------*/
-
- /* Working pointer for destination matrix */
- pOutT1 = pOut;
-
- /* Loop over the number of rows */
- rowCnt = numRows;
-
- /* Making the destination matrix as identity matrix */
- while(rowCnt > 0u)
- {
- /* Writing all zeroes in lower triangle of the destination matrix */
- j = numRows - rowCnt;
- while(j > 0u)
- {
- *pOutT1++ = 0.0f;
- j--;
- }
-
- /* Writing all ones in the diagonal of the destination matrix */
- *pOutT1++ = 1.0f;
-
- /* Writing all zeroes in upper triangle of the destination matrix */
- j = rowCnt - 1u;
- while(j > 0u)
- {
- *pOutT1++ = 0.0f;
- j--;
- }
-
- /* Decrement the loop counter */
- rowCnt--;
- }
-
- /* Loop over the number of columns of the input matrix.
- All the elements in each column are processed by the row operations */
- loopCnt = numCols;
-
- /* Index modifier to navigate through the columns */
- l = 0u;
-
- while(loopCnt > 0u)
- {
- /* Check if the pivot element is zero..
- * If it is zero then interchange the row with non zero row below.
- * If there is no non zero element to replace in the rows below,
- * then the matrix is Singular. */
-
- /* Working pointer for the input matrix that points
- * to the pivot element of the particular row */
- pInT1 = pIn + (l * numCols);
-
- /* Working pointer for the destination matrix that points
- * to the pivot element of the particular row */
- pOutT1 = pOut + (l * numCols);
-
- /* Temporary variable to hold the pivot value */
- in = *pInT1;
-
- /* Grab the most significant value from column l */
- maxC = 0;
- for (i = l; i < numRows; i++)
- {
- maxC = *pInT1 > 0 ? (*pInT1 > maxC ? *pInT1 : maxC) : (-*pInT1 > maxC ? -*pInT1 : maxC);
- pInT1 += numCols;
- }
-
- /* Update the status if the matrix is singular */
- if(maxC == 0.0f)
- {
- return ARM_MATH_SINGULAR;
- }
-
- /* Restore pInT1 */
- pInT1 = pIn;
-
- /* Destination pointer modifier */
- k = 1u;
-
- /* Check if the pivot element is the most significant of the column */
- if( (in > 0.0f ? in : -in) != maxC)
- {
- /* Loop over the number rows present below */
- i = numRows - (l + 1u);
-
- while(i > 0u)
- {
- /* Update the input and destination pointers */
- pInT2 = pInT1 + (numCols * l);
- pOutT2 = pOutT1 + (numCols * k);
-
- /* Look for the most significant element to
- * replace in the rows below */
- if((*pInT2 > 0.0f ? *pInT2: -*pInT2) == maxC)
- {
- /* Loop over number of columns
- * to the right of the pilot element */
- j = numCols - l;
-
- while(j > 0u)
- {
- /* Exchange the row elements of the input matrix */
- Xchg = *pInT2;
- *pInT2++ = *pInT1;
- *pInT1++ = Xchg;
-
- /* Decrement the loop counter */
- j--;
- }
-
- /* Loop over number of columns of the destination matrix */
- j = numCols;
-
- while(j > 0u)
- {
- /* Exchange the row elements of the destination matrix */
- Xchg = *pOutT2;
- *pOutT2++ = *pOutT1;
- *pOutT1++ = Xchg;
-
- /* Decrement the loop counter */
- j--;
- }
-
- /* Flag to indicate whether exchange is done or not */
- flag = 1u;
-
- /* Break after exchange is done */
- break;
- }
-
- /* Update the destination pointer modifier */
- k++;
-
- /* Decrement the loop counter */
- i--;
- }
- }
-
- /* Update the status if the matrix is singular */
- if((flag != 1u) && (in == 0.0f))
- {
- return ARM_MATH_SINGULAR;
- }
-
- /* Points to the pivot row of input and destination matrices */
- pPivotRowIn = pIn + (l * numCols);
- pPivotRowDst = pOut + (l * numCols);
-
- /* Temporary pointers to the pivot row pointers */
- pInT1 = pPivotRowIn;
- pInT2 = pPivotRowDst;
-
- /* Pivot element of the row */
- in = *pPivotRowIn;
-
- /* Loop over number of columns
- * to the right of the pilot element */
- j = (numCols - l);
-
- while(j > 0u)
- {
- /* Divide each element of the row of the input matrix
- * by the pivot element */
- in1 = *pInT1;
- *pInT1++ = in1 / in;
-
- /* Decrement the loop counter */
- j--;
- }
-
- /* Loop over number of columns of the destination matrix */
- j = numCols;
-
- while(j > 0u)
- {
- /* Divide each element of the row of the destination matrix
- * by the pivot element */
- in1 = *pInT2;
- *pInT2++ = in1 / in;
-
- /* Decrement the loop counter */
- j--;
- }
-
- /* Replace the rows with the sum of that row and a multiple of row i
- * so that each new element in column i above row i is zero.*/
-
- /* Temporary pointers for input and destination matrices */
- pInT1 = pIn;
- pInT2 = pOut;
-
- /* index used to check for pivot element */
- i = 0u;
-
- /* Loop over number of rows */
- /* to be replaced by the sum of that row and a multiple of row i */
- k = numRows;
-
- while(k > 0u)
- {
- /* Check for the pivot element */
- if(i == l)
- {
- /* If the processing element is the pivot element,
- only the columns to the right are to be processed */
- pInT1 += numCols - l;
-
- pInT2 += numCols;
- }
- else
- {
- /* Element of the reference row */
- in = *pInT1;
-
- /* Working pointers for input and destination pivot rows */
- pPRT_in = pPivotRowIn;
- pPRT_pDst = pPivotRowDst;
-
- /* Loop over the number of columns to the right of the pivot element,
- to replace the elements in the input matrix */
- j = (numCols - l);
-
- while(j > 0u)
- {
- /* Replace the element by the sum of that row
- and a multiple of the reference row */
- in1 = *pInT1;
- *pInT1++ = in1 - (in * *pPRT_in++);
-
- /* Decrement the loop counter */
- j--;
- }
-
- /* Loop over the number of columns to
- replace the elements in the destination matrix */
- j = numCols;
-
- while(j > 0u)
- {
- /* Replace the element by the sum of that row
- and a multiple of the reference row */
- in1 = *pInT2;
- *pInT2++ = in1 - (in * *pPRT_pDst++);
-
- /* Decrement the loop counter */
- j--;
- }
-
- }
-
- /* Increment the temporary input pointer */
- pInT1 = pInT1 + l;
-
- /* Decrement the loop counter */
- k--;
-
- /* Increment the pivot index */
- i++;
- }
-
- /* Increment the input pointer */
- pIn++;
-
- /* Decrement the loop counter */
- loopCnt--;
-
- /* Increment the index modifier */
- l++;
- }
-
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- float64_t Xchg, in = 0.0f; /* Temporary input values */
- uint32_t i, rowCnt, flag = 0u, j, loopCnt, k, l; /* loop counters */
- arm_status status; /* status of matrix inverse */
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
- /* Check for matrix mismatch condition */
- if((pSrc->numRows != pSrc->numCols) || (pDst->numRows != pDst->numCols)
- || (pSrc->numRows != pDst->numRows))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
- {
-
- /*--------------------------------------------------------------------------------------------------------------
- * Matrix Inverse can be solved using elementary row operations.
- *
- * Gauss-Jordan Method:
- *
- * 1. First combine the identity matrix and the input matrix separated by a bar to form an
- * augmented matrix as follows:
- * _ _ _ _ _ _ _ _
- * | | a11 a12 | | | 1 0 | | | X11 X12 |
- * | | | | | | | = | |
- * |_ |_ a21 a22 _| | |_0 1 _| _| |_ X21 X21 _|
- *
- * 2. In our implementation, pDst Matrix is used as identity matrix.
- *
- * 3. Begin with the first row. Let i = 1.
- *
- * 4. Check to see if the pivot for row i is zero.
- * The pivot is the element of the main diagonal that is on the current row.
- * For instance, if working with row i, then the pivot element is aii.
- * If the pivot is zero, exchange that row with a row below it that does not
- * contain a zero in column i. If this is not possible, then an inverse
- * to that matrix does not exist.
- *
- * 5. Divide every element of row i by the pivot.
- *
- * 6. For every row below and row i, replace that row with the sum of that row and
- * a multiple of row i so that each new element in column i below row i is zero.
- *
- * 7. Move to the next row and column and repeat steps 2 through 5 until you have zeros
- * for every element below and above the main diagonal.
- *
- * 8. Now an identical matrix is formed to the left of the bar(input matrix, src).
- * Therefore, the matrix to the right of the bar is our solution(dst matrix, dst).
- *----------------------------------------------------------------------------------------------------------------*/
-
- /* Working pointer for destination matrix */
- pOutT1 = pOut;
-
- /* Loop over the number of rows */
- rowCnt = numRows;
-
- /* Making the destination matrix as identity matrix */
- while(rowCnt > 0u)
- {
- /* Writing all zeroes in lower triangle of the destination matrix */
- j = numRows - rowCnt;
- while(j > 0u)
- {
- *pOutT1++ = 0.0f;
- j--;
- }
-
- /* Writing all ones in the diagonal of the destination matrix */
- *pOutT1++ = 1.0f;
-
- /* Writing all zeroes in upper triangle of the destination matrix */
- j = rowCnt - 1u;
- while(j > 0u)
- {
- *pOutT1++ = 0.0f;
- j--;
- }
-
- /* Decrement the loop counter */
- rowCnt--;
- }
-
- /* Loop over the number of columns of the input matrix.
- All the elements in each column are processed by the row operations */
- loopCnt = numCols;
-
- /* Index modifier to navigate through the columns */
- l = 0u;
- //for(loopCnt = 0u; loopCnt < numCols; loopCnt++)
- while(loopCnt > 0u)
- {
- /* Check if the pivot element is zero..
- * If it is zero then interchange the row with non zero row below.
- * If there is no non zero element to replace in the rows below,
- * then the matrix is Singular. */
-
- /* Working pointer for the input matrix that points
- * to the pivot element of the particular row */
- pInT1 = pIn + (l * numCols);
-
- /* Working pointer for the destination matrix that points
- * to the pivot element of the particular row */
- pOutT1 = pOut + (l * numCols);
-
- /* Temporary variable to hold the pivot value */
- in = *pInT1;
-
- /* Destination pointer modifier */
- k = 1u;
-
- /* Check if the pivot element is zero */
- if(*pInT1 == 0.0f)
- {
- /* Loop over the number rows present below */
- for (i = (l + 1u); i < numRows; i++)
- {
- /* Update the input and destination pointers */
- pInT2 = pInT1 + (numCols * l);
- pOutT2 = pOutT1 + (numCols * k);
-
- /* Check if there is a non zero pivot element to
- * replace in the rows below */
- if(*pInT2 != 0.0f)
- {
- /* Loop over number of columns
- * to the right of the pilot element */
- for (j = 0u; j < (numCols - l); j++)
- {
- /* Exchange the row elements of the input matrix */
- Xchg = *pInT2;
- *pInT2++ = *pInT1;
- *pInT1++ = Xchg;
- }
-
- for (j = 0u; j < numCols; j++)
- {
- Xchg = *pOutT2;
- *pOutT2++ = *pOutT1;
- *pOutT1++ = Xchg;
- }
-
- /* Flag to indicate whether exchange is done or not */
- flag = 1u;
-
- /* Break after exchange is done */
- break;
- }
-
- /* Update the destination pointer modifier */
- k++;
- }
- }
-
- /* Update the status if the matrix is singular */
- if((flag != 1u) && (in == 0.0f))
- {
- return ARM_MATH_SINGULAR;
- }
-
- /* Points to the pivot row of input and destination matrices */
- pPivotRowIn = pIn + (l * numCols);
- pPivotRowDst = pOut + (l * numCols);
-
- /* Temporary pointers to the pivot row pointers */
- pInT1 = pPivotRowIn;
- pOutT1 = pPivotRowDst;
-
- /* Pivot element of the row */
- in = *(pIn + (l * numCols));
-
- /* Loop over number of columns
- * to the right of the pilot element */
- for (j = 0u; j < (numCols - l); j++)
- {
- /* Divide each element of the row of the input matrix
- * by the pivot element */
- *pInT1 = *pInT1 / in;
- pInT1++;
- }
- for (j = 0u; j < numCols; j++)
- {
- /* Divide each element of the row of the destination matrix
- * by the pivot element */
- *pOutT1 = *pOutT1 / in;
- pOutT1++;
- }
-
- /* Replace the rows with the sum of that row and a multiple of row i
- * so that each new element in column i above row i is zero.*/
-
- /* Temporary pointers for input and destination matrices */
- pInT1 = pIn;
- pOutT1 = pOut;
-
- for (i = 0u; i < numRows; i++)
- {
- /* Check for the pivot element */
- if(i == l)
- {
- /* If the processing element is the pivot element,
- only the columns to the right are to be processed */
- pInT1 += numCols - l;
- pOutT1 += numCols;
- }
- else
- {
- /* Element of the reference row */
- in = *pInT1;
-
- /* Working pointers for input and destination pivot rows */
- pPRT_in = pPivotRowIn;
- pPRT_pDst = pPivotRowDst;
-
- /* Loop over the number of columns to the right of the pivot element,
- to replace the elements in the input matrix */
- for (j = 0u; j < (numCols - l); j++)
- {
- /* Replace the element by the sum of that row
- and a multiple of the reference row */
- *pInT1 = *pInT1 - (in * *pPRT_in++);
- pInT1++;
- }
- /* Loop over the number of columns to
- replace the elements in the destination matrix */
- for (j = 0u; j < numCols; j++)
- {
- /* Replace the element by the sum of that row
- and a multiple of the reference row */
- *pOutT1 = *pOutT1 - (in * *pPRT_pDst++);
- pOutT1++;
- }
-
- }
- /* Increment the temporary input pointer */
- pInT1 = pInT1 + l;
- }
- /* Increment the input pointer */
- pIn++;
-
- /* Decrement the loop counter */
- loopCnt--;
- /* Increment the index modifier */
- l++;
- }
-
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- /* Set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
-
- if((flag != 1u) && (in == 0.0f))
- {
- pIn = pSrc->pData;
- for (i = 0; i < numRows * numCols; i++)
- {
- if (pIn[i] != 0.0f)
- break;
- }
-
- if (i == numRows * numCols)
- status = ARM_MATH_SINGULAR;
- }
- }
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixInv group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_f32.c
deleted file mode 100644
index 2a63d66..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_f32.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_mult_f32.c
-*
-* Description: Floating-point matrix multiplication.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @defgroup MatrixMult Matrix Multiplication
- *
- * Multiplies two matrices.
- *
- * \image html MatrixMultiplication.gif "Multiplication of two 3 x 3 matrices"
-
- * Matrix multiplication is only defined if the number of columns of the
- * first matrix equals the number of rows of the second matrix.
- * Multiplying an M x N
matrix with an N x P
matrix results
- * in an M x P
matrix.
- * When matrix size checking is enabled, the functions check: (1) that the inner dimensions of
- * pSrcA
and pSrcB
are equal; and (2) that the size of the output
- * matrix equals the outer dimensions of pSrcA
and pSrcB
.
- */
-
-
-/**
- * @addtogroup MatrixMult
- * @{
- */
-
-/**
- * @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)
-{
- float32_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
- float32_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
- float32_t *pInA = pSrcA->pData; /* input data matrix pointer A */
- float32_t *pOut = pDst->pData; /* output data matrix pointer */
- float32_t *px; /* Temporary output data matrix pointer */
- float32_t sum; /* Accumulator */
- uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
- uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
- uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- float32_t in1, in2, in3, in4;
- uint16_t col, i = 0u, j, row = numRowsA, colCnt; /* loop counters */
- arm_status status; /* status of matrix multiplication */
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
-
- /* Check for matrix mismatch condition */
- if((pSrcA->numCols != pSrcB->numRows) ||
- (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
- {
-
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
-
- {
- /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
- /* row loop */
- do
- {
- /* Output pointer is set to starting address of the row being processed */
- px = pOut + i;
-
- /* For every row wise process, the column loop counter is to be initiated */
- col = numColsB;
-
- /* For every row wise process, the pIn2 pointer is set
- ** to the starting address of the pSrcB data */
- pIn2 = pSrcB->pData;
-
- j = 0u;
-
- /* column loop */
- do
- {
- /* Set the variable sum, that acts as accumulator, to zero */
- sum = 0.0f;
-
- /* Initiate the pointer pIn1 to point to the starting address of the column being processed */
- pIn1 = pInA;
-
- /* Apply loop unrolling and compute 4 MACs simultaneously. */
- colCnt = numColsA >> 2u;
-
- /* matrix multiplication */
- while(colCnt > 0u)
- {
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
- in3 = *pIn2;
- pIn2 += numColsB;
- in1 = pIn1[0];
- in2 = pIn1[1];
- sum += in1 * in3;
- in4 = *pIn2;
- pIn2 += numColsB;
- sum += in2 * in4;
-
- in3 = *pIn2;
- pIn2 += numColsB;
- in1 = pIn1[2];
- in2 = pIn1[3];
- sum += in1 * in3;
- in4 = *pIn2;
- pIn2 += numColsB;
- sum += in2 * in4;
- pIn1 += 4u;
-
- /* Decrement the loop count */
- colCnt--;
- }
-
- /* If the columns of pSrcA is not a multiple of 4, compute any remaining MACs here.
- ** No loop unrolling is used. */
- colCnt = numColsA % 0x4u;
-
- while(colCnt > 0u)
- {
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
- sum += *pIn1++ * (*pIn2);
- pIn2 += numColsB;
-
- /* Decrement the loop counter */
- colCnt--;
- }
-
- /* Store the result in the destination buffer */
- *px++ = sum;
-
- /* Update the pointer pIn2 to point to the starting address of the next column */
- j++;
- pIn2 = pSrcB->pData + j;
-
- /* Decrement the column loop counter */
- col--;
-
- } while(col > 0u);
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- float32_t *pInB = pSrcB->pData; /* input data matrix pointer B */
- uint16_t col, i = 0u, row = numRowsA, colCnt; /* loop counters */
- arm_status status; /* status of matrix multiplication */
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
- /* Check for matrix mismatch condition */
- if((pSrcA->numCols != pSrcB->numRows) ||
- (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
- {
-
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
-
- {
- /* The following loop performs the dot-product of each row in pInA with each column in pInB */
- /* row loop */
- do
- {
- /* Output pointer is set to starting address of the row being processed */
- px = pOut + i;
-
- /* For every row wise process, the column loop counter is to be initiated */
- col = numColsB;
-
- /* For every row wise process, the pIn2 pointer is set
- ** to the starting address of the pSrcB data */
- pIn2 = pSrcB->pData;
-
- /* column loop */
- do
- {
- /* Set the variable sum, that acts as accumulator, to zero */
- sum = 0.0f;
-
- /* Initialize the pointer pIn1 to point to the starting address of the row being processed */
- pIn1 = pInA;
-
- /* Matrix A columns number of MAC operations are to be performed */
- colCnt = numColsA;
-
- while(colCnt > 0u)
- {
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
- sum += *pIn1++ * (*pIn2);
- pIn2 += numColsB;
-
- /* Decrement the loop counter */
- colCnt--;
- }
-
- /* Store the result in the destination buffer */
- *px++ = sum;
-
- /* Decrement the column loop counter */
- col--;
-
- /* Update the pointer pIn2 to point to the starting address of the next column */
- pIn2 = pInB + (numColsB - col);
-
- } while(col > 0u);
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- /* Update the pointer pInA to point to the starting address of the next row */
- i = i + numColsB;
- pInA = pInA + numColsA;
-
- /* Decrement the row loop counter */
- row--;
-
- } while(row > 0u);
- /* Set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
-
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixMult group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_fast_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_fast_q15.c
deleted file mode 100644
index b3c7aa0..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_fast_q15.c
+++ /dev/null
@@ -1,369 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_mult_fast_q15.c
-*
-* Description: Q15 matrix multiplication (fast variant)
-*
-* Target Processor: Cortex-M4/Cortex-M3
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @addtogroup MatrixMult
- * @{
- */
-
-
-/**
- * @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.
- *
- * @details
- * Scaling and Overflow Behavior:
- *
- * \par
- * The difference between the function arm_mat_mult_q15() and this fast variant is that
- * the fast variant use a 32-bit rather than a 64-bit accumulator.
- * The result of each 1.15 x 1.15 multiplication is truncated to
- * 2.30 format. These intermediate results are accumulated in a 32-bit register in 2.30
- * format. Finally, the accumulator is saturated and converted to a 1.15 result.
- *
- * \par
- * The fast version has the same overflow behavior as the standard version but provides
- * less precision since it discards the low 16 bits of each multiplication result.
- * In order to avoid overflows completely the input signals must be scaled down.
- * Scale down one of the input matrices by log2(numColsA) bits to
- * avoid overflows, as a total of numColsA additions are computed internally for each
- * output element.
- *
- * \par
- * See arm_mat_mult_q15()
for a slower implementation of this function
- * which uses 64-bit accumulation to provide higher precision.
- */
-
-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)
-{
- q31_t sum; /* accumulator */
- q15_t *pSrcBT = pState; /* input data matrix pointer for transpose */
- q15_t *pInA = pSrcA->pData; /* input data matrix pointer A of Q15 type */
- q15_t *pInB = pSrcB->pData; /* input data matrix pointer B of Q15 type */
- q15_t *px; /* Temporary output data matrix pointer */
- uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
- uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
- uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
- uint16_t numRowsB = pSrcB->numRows; /* number of rows of input matrix A */
- uint16_t col, i = 0u, row = numRowsB, colCnt; /* loop counters */
- arm_status status; /* status of matrix multiplication */
-
-#ifndef UNALIGNED_SUPPORT_DISABLE
-
- q31_t in; /* Temporary variable to hold the input value */
- q31_t inA1, inA2, inB1, inB2;
-
-#else
-
- q15_t in; /* Temporary variable to hold the input value */
- q15_t inA1, inA2, inB1, inB2;
-
-#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
-
-#ifdef ARM_MATH_MATRIX_CHECK
- /* Check for matrix mismatch condition */
- if((pSrcA->numCols != pSrcB->numRows) ||
- (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif
- {
- /* Matrix transpose */
- do
- {
- /* Apply loop unrolling and exchange the columns with row elements */
- col = numColsB >> 2;
-
- /* The pointer px is set to starting address of the column being processed */
- px = pSrcBT + i;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(col > 0u)
- {
-#ifndef UNALIGNED_SUPPORT_DISABLE
- /* Read two elements from the row */
- in = *__SIMD32(pInB)++;
-
- /* Unpack and store one element in the destination */
-#ifndef ARM_MATH_BIG_ENDIAN
-
- *px = (q15_t) in;
-
-#else
-
- *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB;
-
- /* Unpack and store the second element in the destination */
-#ifndef ARM_MATH_BIG_ENDIAN
-
- *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
-
-#else
-
- *px = (q15_t) in;
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB;
-
- /* Read two elements from the row */
- in = *__SIMD32(pInB)++;
-
- /* Unpack and store one element in the destination */
-#ifndef ARM_MATH_BIG_ENDIAN
-
- *px = (q15_t) in;
-
-#else
-
- *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB;
-
- /* Unpack and store the second element in the destination */
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
-
-#else
-
- *px = (q15_t) in;
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
-#else
-
- /* Read one element from the row */
- in = *pInB++;
-
- /* Store one element in the destination */
- *px = in;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB;
-
- /* Read one element from the row */
- in = *pInB++;
-
- /* Store one element in the destination */
- *px = in;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB;
-
- /* Read one element from the row */
- in = *pInB++;
-
- /* Store one element in the destination */
- *px = in;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB;
-
- /* Read one element from the row */
- in = *pInB++;
-
- /* Store one element in the destination */
- *px = in;
-
-#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB;
-
- /* Decrement the column loop counter */
- col--;
- }
-
- /* If the columns of pSrcB is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- col = numColsB % 0x4u;
-
- while(col > 0u)
- {
- /* Read and store the input element in the destination */
- *px = *pInB++;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB;
-
- /* Decrement the column loop counter */
- col--;
- }
-
- i++;
-
- /* Decrement the row loop counter */
- row--;
-
- } while(row > 0u);
-
- /* Reset the variables for the usage in the following multiplication process */
- row = numRowsA;
- i = 0u;
- px = pDst->pData;
-
- /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
- /* row loop */
- do
- {
- /* For every row wise process, the column loop counter is to be initiated */
- col = numColsB;
-
- /* For every row wise process, the pIn2 pointer is set
- ** to the starting address of the transposed pSrcB data */
- pInB = pSrcBT;
-
- /* column loop */
- do
- {
- /* Set the variable sum, that acts as accumulator, to zero */
- sum = 0;
-
- /* Apply loop unrolling and compute 2 MACs simultaneously. */
- colCnt = numColsA >> 2;
-
- /* Initiate the pointer pIn1 to point to the starting address of the column being processed */
- pInA = pSrcA->pData + i;
-
- /* matrix multiplication */
- while(colCnt > 0u)
- {
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
-#ifndef UNALIGNED_SUPPORT_DISABLE
-
- inA1 = *__SIMD32(pInA)++;
- inB1 = *__SIMD32(pInB)++;
- inA2 = *__SIMD32(pInA)++;
- inB2 = *__SIMD32(pInB)++;
-
- sum = __SMLAD(inA1, inB1, sum);
- sum = __SMLAD(inA2, inB2, sum);
-
-#else
-
- inA1 = *pInA++;
- inB1 = *pInB++;
- inA2 = *pInA++;
- sum += inA1 * inB1;
- inB2 = *pInB++;
-
- inA1 = *pInA++;
- inB1 = *pInB++;
- sum += inA2 * inB2;
- inA2 = *pInA++;
- inB2 = *pInB++;
-
- sum += inA1 * inB1;
- sum += inA2 * inB2;
-
-#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
-
- /* Decrement the loop counter */
- colCnt--;
- }
-
- /* process odd column samples */
- colCnt = numColsA % 0x4u;
-
- while(colCnt > 0u)
- {
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
- sum += (q31_t) (*pInA++) * (*pInB++);
-
- colCnt--;
- }
-
- /* Saturate and store the result in the destination buffer */
- *px = (q15_t) (sum >> 15);
- px++;
-
- /* Decrement the column loop counter */
- col--;
-
- } while(col > 0u);
-
- i = i + numColsA;
-
- /* Decrement the row loop counter */
- row--;
-
- } while(row > 0u);
-
- /* set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
-
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixMult group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_fast_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_fast_q31.c
deleted file mode 100644
index c11958f..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_fast_q31.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_mult_fast_q31.c
-*
-* Description: Q31 matrix multiplication (fast variant).
-*
-* Target Processor: Cortex-M4/Cortex-M3
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @addtogroup MatrixMult
- * @{
- */
-
-/**
- * @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.
- *
- * @details
- * Scaling and Overflow Behavior:
- *
- * \par
- * The difference between the function arm_mat_mult_q31() and this fast variant is that
- * the fast variant use a 32-bit rather than a 64-bit accumulator.
- * The result of each 1.31 x 1.31 multiplication is truncated to
- * 2.30 format. These intermediate results are accumulated in a 32-bit register in 2.30
- * format. Finally, the accumulator is saturated and converted to a 1.31 result.
- *
- * \par
- * The fast version has the same overflow behavior as the standard version but provides
- * less precision since it discards the low 32 bits of each multiplication result.
- * In order to avoid overflows completely the input signals must be scaled down.
- * Scale down one of the input matrices by log2(numColsA) bits to
- * avoid overflows, as a total of numColsA additions are computed internally for each
- * output element.
- *
- * \par
- * See arm_mat_mult_q31()
for a slower implementation of this function
- * which uses 64-bit accumulation to provide higher precision.
- */
-
-arm_status arm_mat_mult_fast_q31(
- const arm_matrix_instance_q31 * pSrcA,
- const arm_matrix_instance_q31 * pSrcB,
- arm_matrix_instance_q31 * pDst)
-{
- q31_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
- q31_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
- q31_t *pInA = pSrcA->pData; /* input data matrix pointer A */
-// q31_t *pSrcB = pSrcB->pData; /* input data matrix pointer B */
- q31_t *pOut = pDst->pData; /* output data matrix pointer */
- q31_t *px; /* Temporary output data matrix pointer */
- q31_t sum; /* Accumulator */
- uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
- uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
- uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
- uint16_t col, i = 0u, j, row = numRowsA, colCnt; /* loop counters */
- arm_status status; /* status of matrix multiplication */
- q31_t inA1, inA2, inA3, inA4, inB1, inB2, inB3, inB4;
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
-
- /* Check for matrix mismatch condition */
- if((pSrcA->numCols != pSrcB->numRows) ||
- (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
-
- {
- /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
- /* row loop */
- do
- {
- /* Output pointer is set to starting address of the row being processed */
- px = pOut + i;
-
- /* For every row wise process, the column loop counter is to be initiated */
- col = numColsB;
-
- /* For every row wise process, the pIn2 pointer is set
- ** to the starting address of the pSrcB data */
- pIn2 = pSrcB->pData;
-
- j = 0u;
-
- /* column loop */
- do
- {
- /* Set the variable sum, that acts as accumulator, to zero */
- sum = 0;
-
- /* Initiate the pointer pIn1 to point to the starting address of pInA */
- pIn1 = pInA;
-
- /* Apply loop unrolling and compute 4 MACs simultaneously. */
- colCnt = numColsA >> 2;
-
-
- /* matrix multiplication */
- while(colCnt > 0u)
- {
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
- /* Perform the multiply-accumulates */
- inB1 = *pIn2;
- pIn2 += numColsB;
-
- inA1 = pIn1[0];
- inA2 = pIn1[1];
-
- inB2 = *pIn2;
- pIn2 += numColsB;
-
- inB3 = *pIn2;
- pIn2 += numColsB;
-
- sum = (q31_t) ((((q63_t) sum << 32) + ((q63_t) inA1 * inB1)) >> 32);
- sum = (q31_t) ((((q63_t) sum << 32) + ((q63_t) inA2 * inB2)) >> 32);
-
- inA3 = pIn1[2];
- inA4 = pIn1[3];
-
- inB4 = *pIn2;
- pIn2 += numColsB;
-
- sum = (q31_t) ((((q63_t) sum << 32) + ((q63_t) inA3 * inB3)) >> 32);
- sum = (q31_t) ((((q63_t) sum << 32) + ((q63_t) inA4 * inB4)) >> 32);
-
- pIn1 += 4u;
-
- /* Decrement the loop counter */
- colCnt--;
- }
-
- /* If the columns of pSrcA is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- colCnt = numColsA % 0x4u;
-
- while(colCnt > 0u)
- {
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
- /* Perform the multiply-accumulates */
- sum = (q31_t) ((((q63_t) sum << 32) +
- ((q63_t) * pIn1++ * (*pIn2))) >> 32);
- pIn2 += numColsB;
-
- /* Decrement the loop counter */
- colCnt--;
- }
-
- /* Convert the result from 2.30 to 1.31 format and store in destination buffer */
- *px++ = sum << 1;
-
- /* Update the pointer pIn2 to point to the starting address of the next column */
- j++;
- pIn2 = pSrcB->pData + j;
-
- /* Decrement the column loop counter */
- col--;
-
- } while(col > 0u);
-
- /* Update the pointer pInA to point to the starting address of the next row */
- i = i + numColsB;
- pInA = pInA + numColsA;
-
- /* Decrement the row loop counter */
- row--;
-
- } while(row > 0u);
-
- /* set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixMult group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_q15.c
deleted file mode 100644
index 702ee83..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_q15.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_mult_q15.c
-*
-* Description: Q15 matrix multiplication.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @addtogroup MatrixMult
- * @{
- */
-
-
-/**
- * @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
- * @param[in] *pState points to the array for storing intermediate results (Unused)
- * @return The function returns either
- * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
- *
- * @details
- * Scaling and Overflow Behavior:
- *
- * \par
- * The function is implemented using a 64-bit internal accumulator. The inputs to the
- * multiplications are 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. This approach
- * provides 33 guard bits and there is no risk of overflow. The 34.30 result is then
- * truncated to 34.15 format by discarding the low 15 bits and then saturated to
- * 1.15 format.
- *
- * \par
- * Refer to arm_mat_mult_fast_q15()
for a faster but less precise version of this function for Cortex-M3 and Cortex-M4.
- *
- */
-
-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 CMSIS_UNUSED)
-{
- q63_t sum; /* accumulator */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- q15_t *pSrcBT = pState; /* input data matrix pointer for transpose */
- q15_t *pInA = pSrcA->pData; /* input data matrix pointer A of Q15 type */
- q15_t *pInB = pSrcB->pData; /* input data matrix pointer B of Q15 type */
- q15_t *px; /* Temporary output data matrix pointer */
- uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
- uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
- uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
- uint16_t numRowsB = pSrcB->numRows; /* number of rows of input matrix A */
- uint16_t col, i = 0u, row = numRowsB, colCnt; /* loop counters */
- arm_status status; /* status of matrix multiplication */
-
-#ifndef UNALIGNED_SUPPORT_DISABLE
-
- q31_t in; /* Temporary variable to hold the input value */
- q31_t pSourceA1, pSourceB1, pSourceA2, pSourceB2;
-
-#else
-
- q15_t in; /* Temporary variable to hold the input value */
- q15_t inA1, inB1, inA2, inB2;
-
-#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
-
-#ifdef ARM_MATH_MATRIX_CHECK
- /* Check for matrix mismatch condition */
- if((pSrcA->numCols != pSrcB->numRows) ||
- (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
- {
- /* Matrix transpose */
- do
- {
- /* Apply loop unrolling and exchange the columns with row elements */
- col = numColsB >> 2;
-
- /* The pointer px is set to starting address of the column being processed */
- px = pSrcBT + i;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(col > 0u)
- {
-#ifndef UNALIGNED_SUPPORT_DISABLE
-
- /* Read two elements from the row */
- in = *__SIMD32(pInB)++;
-
- /* Unpack and store one element in the destination */
-#ifndef ARM_MATH_BIG_ENDIAN
-
- *px = (q15_t) in;
-
-#else
-
- *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB;
-
- /* Unpack and store the second element in the destination */
-#ifndef ARM_MATH_BIG_ENDIAN
-
- *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
-
-#else
-
- *px = (q15_t) in;
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB;
-
- /* Read two elements from the row */
- in = *__SIMD32(pInB)++;
-
- /* Unpack and store one element in the destination */
-#ifndef ARM_MATH_BIG_ENDIAN
-
- *px = (q15_t) in;
-
-#else
-
- *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB;
-
- /* Unpack and store the second element in the destination */
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
-
-#else
-
- *px = (q15_t) in;
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB;
-
-#else
-
- /* Read one element from the row */
- in = *pInB++;
-
- /* Store one element in the destination */
- *px = in;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB;
-
- /* Read one element from the row */
- in = *pInB++;
-
- /* Store one element in the destination */
- *px = in;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB;
-
- /* Read one element from the row */
- in = *pInB++;
-
- /* Store one element in the destination */
- *px = in;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB;
-
- /* Read one element from the row */
- in = *pInB++;
-
- /* Store one element in the destination */
- *px = in;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB;
-
-#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
-
- /* Decrement the column loop counter */
- col--;
- }
-
- /* If the columns of pSrcB is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- col = numColsB % 0x4u;
-
- while(col > 0u)
- {
- /* Read and store the input element in the destination */
- *px = *pInB++;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += numRowsB;
-
- /* Decrement the column loop counter */
- col--;
- }
-
- i++;
-
- /* Decrement the row loop counter */
- row--;
-
- } while(row > 0u);
-
- /* Reset the variables for the usage in the following multiplication process */
- row = numRowsA;
- i = 0u;
- px = pDst->pData;
-
- /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
- /* row loop */
- do
- {
- /* For every row wise process, the column loop counter is to be initiated */
- col = numColsB;
-
- /* For every row wise process, the pIn2 pointer is set
- ** to the starting address of the transposed pSrcB data */
- pInB = pSrcBT;
-
- /* column loop */
- do
- {
- /* Set the variable sum, that acts as accumulator, to zero */
- sum = 0;
-
- /* Apply loop unrolling and compute 2 MACs simultaneously. */
- colCnt = numColsA >> 2;
-
- /* Initiate the pointer pIn1 to point to the starting address of the column being processed */
- pInA = pSrcA->pData + i;
-
-
- /* matrix multiplication */
- while(colCnt > 0u)
- {
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
-#ifndef UNALIGNED_SUPPORT_DISABLE
-
- /* read real and imag values from pSrcA and pSrcB buffer */
- pSourceA1 = *__SIMD32(pInA)++;
- pSourceB1 = *__SIMD32(pInB)++;
-
- pSourceA2 = *__SIMD32(pInA)++;
- pSourceB2 = *__SIMD32(pInB)++;
-
- /* Multiply and Accumlates */
- sum = __SMLALD(pSourceA1, pSourceB1, sum);
- sum = __SMLALD(pSourceA2, pSourceB2, sum);
-
-#else
- /* read real and imag values from pSrcA and pSrcB buffer */
- inA1 = *pInA++;
- inB1 = *pInB++;
- inA2 = *pInA++;
- /* Multiply and Accumlates */
- sum += inA1 * inB1;
- inB2 = *pInB++;
-
- inA1 = *pInA++;
- inB1 = *pInB++;
- /* Multiply and Accumlates */
- sum += inA2 * inB2;
- inA2 = *pInA++;
- inB2 = *pInB++;
-
- /* Multiply and Accumlates */
- sum += inA1 * inB1;
- sum += inA2 * inB2;
-
-#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
-
- /* Decrement the loop counter */
- colCnt--;
- }
-
- /* process remaining column samples */
- colCnt = numColsA & 3u;
-
- while(colCnt > 0u)
- {
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
- sum += *pInA++ * *pInB++;
-
- /* Decrement the loop counter */
- colCnt--;
- }
-
- /* Saturate and store the result in the destination buffer */
- *px = (q15_t) (__SSAT((sum >> 15), 16));
- px++;
-
- /* Decrement the column loop counter */
- col--;
-
- } while(col > 0u);
-
- i = i + numColsA;
-
- /* Decrement the row loop counter */
- row--;
-
- } while(row > 0u);
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- q15_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
- q15_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
- q15_t *pInA = pSrcA->pData; /* input data matrix pointer A of Q15 type */
- q15_t *pInB = pSrcB->pData; /* input data matrix pointer B of Q15 type */
- q15_t *pOut = pDst->pData; /* output data matrix pointer */
- q15_t *px; /* Temporary output data matrix pointer */
- uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
- uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
- uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
- uint16_t col, i = 0u, row = numRowsA, colCnt; /* loop counters */
- arm_status status; /* status of matrix multiplication */
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
- /* Check for matrix mismatch condition */
- if((pSrcA->numCols != pSrcB->numRows) ||
- (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
-
- {
- /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
- /* row loop */
- do
- {
- /* Output pointer is set to starting address of the row being processed */
- px = pOut + i;
-
- /* For every row wise process, the column loop counter is to be initiated */
- col = numColsB;
-
- /* For every row wise process, the pIn2 pointer is set
- ** to the starting address of the pSrcB data */
- pIn2 = pSrcB->pData;
-
- /* column loop */
- do
- {
- /* Set the variable sum, that acts as accumulator, to zero */
- sum = 0;
-
- /* Initiate the pointer pIn1 to point to the starting address of pSrcA */
- pIn1 = pInA;
-
- /* Matrix A columns number of MAC operations are to be performed */
- colCnt = numColsA;
-
- /* matrix multiplication */
- while(colCnt > 0u)
- {
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
- /* Perform the multiply-accumulates */
- sum += (q31_t) * pIn1++ * *pIn2;
- pIn2 += numColsB;
-
- /* Decrement the loop counter */
- colCnt--;
- }
-
- /* Convert the result from 34.30 to 1.15 format and store the saturated value in destination buffer */
- /* Saturate and store the result in the destination buffer */
- *px++ = (q15_t) __SSAT((sum >> 15), 16);
-
- /* Decrement the column loop counter */
- col--;
-
- /* Update the pointer pIn2 to point to the starting address of the next column */
- pIn2 = pInB + (numColsB - col);
-
- } while(col > 0u);
-
- /* Update the pointer pSrcA to point to the starting address of the next row */
- i = i + numColsB;
- pInA = pInA + numColsA;
-
- /* Decrement the row loop counter */
- row--;
-
- } while(row > 0u);
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
- /* set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
-
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixMult group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_q31.c
deleted file mode 100644
index 5d22522..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_q31.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_mult_q31.c
-*
-* Description: Q31 matrix multiplication.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @addtogroup MatrixMult
- * @{
- */
-
-/**
- * @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.
- *
- * @details
- * 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. There is no saturation
- * on intermediate additions. Thus, if the accumulator overflows it wraps around and
- * distorts the result. The input signals should be scaled down to avoid intermediate
- * overflows. The input is thus scaled down by log2(numColsA) bits
- * to avoid overflows, as a total of numColsA additions are performed internally.
- * The 2.62 accumulator is right shifted by 31 bits and saturated to 1.31 format to yield the final result.
- *
- * \par
- * See arm_mat_mult_fast_q31()
for a faster but less precise implementation of this function for Cortex-M3 and Cortex-M4.
- *
- */
-
-arm_status arm_mat_mult_q31(
- const arm_matrix_instance_q31 * pSrcA,
- const arm_matrix_instance_q31 * pSrcB,
- arm_matrix_instance_q31 * pDst)
-{
- q31_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
- q31_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
- q31_t *pInA = pSrcA->pData; /* input data matrix pointer A */
- q31_t *pOut = pDst->pData; /* output data matrix pointer */
- q31_t *px; /* Temporary output data matrix pointer */
- q63_t sum; /* Accumulator */
- uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
- uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
- uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- uint16_t col, i = 0u, j, row = numRowsA, colCnt; /* loop counters */
- arm_status status; /* status of matrix multiplication */
- q31_t a0, a1, a2, a3, b0, b1, b2, b3;
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
-
- /* Check for matrix mismatch condition */
- if((pSrcA->numCols != pSrcB->numRows) ||
- (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
-
- {
- /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
- /* row loop */
- do
- {
- /* Output pointer is set to starting address of the row being processed */
- px = pOut + i;
-
- /* For every row wise process, the column loop counter is to be initiated */
- col = numColsB;
-
- /* For every row wise process, the pIn2 pointer is set
- ** to the starting address of the pSrcB data */
- pIn2 = pSrcB->pData;
-
- j = 0u;
-
- /* column loop */
- do
- {
- /* Set the variable sum, that acts as accumulator, to zero */
- sum = 0;
-
- /* Initiate the pointer pIn1 to point to the starting address of pInA */
- pIn1 = pInA;
-
- /* Apply loop unrolling and compute 4 MACs simultaneously. */
- colCnt = numColsA >> 2;
-
-
- /* matrix multiplication */
- while(colCnt > 0u)
- {
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
- /* Perform the multiply-accumulates */
- b0 = *pIn2;
- pIn2 += numColsB;
-
- a0 = *pIn1++;
- a1 = *pIn1++;
-
- b1 = *pIn2;
- pIn2 += numColsB;
- b2 = *pIn2;
- pIn2 += numColsB;
-
- sum += (q63_t) a0 *b0;
- sum += (q63_t) a1 *b1;
-
- a2 = *pIn1++;
- a3 = *pIn1++;
-
- b3 = *pIn2;
- pIn2 += numColsB;
-
- sum += (q63_t) a2 *b2;
- sum += (q63_t) a3 *b3;
-
- /* Decrement the loop counter */
- colCnt--;
- }
-
- /* If the columns of pSrcA is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- colCnt = numColsA % 0x4u;
-
- while(colCnt > 0u)
- {
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
- /* Perform the multiply-accumulates */
- sum += (q63_t) * pIn1++ * *pIn2;
- pIn2 += numColsB;
-
- /* Decrement the loop counter */
- colCnt--;
- }
-
- /* Convert the result from 2.62 to 1.31 format and store in destination buffer */
- *px++ = (q31_t) (sum >> 31);
-
- /* Update the pointer pIn2 to point to the starting address of the next column */
- j++;
- pIn2 = (pSrcB->pData) + j;
-
- /* Decrement the column loop counter */
- col--;
-
- } while(col > 0u);
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- q31_t *pInB = pSrcB->pData; /* input data matrix pointer B */
- uint16_t col, i = 0u, row = numRowsA, colCnt; /* loop counters */
- arm_status status; /* status of matrix multiplication */
-
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
- /* Check for matrix mismatch condition */
- if((pSrcA->numCols != pSrcB->numRows) ||
- (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
-
- {
- /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
- /* row loop */
- do
- {
- /* Output pointer is set to starting address of the row being processed */
- px = pOut + i;
-
- /* For every row wise process, the column loop counter is to be initiated */
- col = numColsB;
-
- /* For every row wise process, the pIn2 pointer is set
- ** to the starting address of the pSrcB data */
- pIn2 = pSrcB->pData;
-
- /* column loop */
- do
- {
- /* Set the variable sum, that acts as accumulator, to zero */
- sum = 0;
-
- /* Initiate the pointer pIn1 to point to the starting address of pInA */
- pIn1 = pInA;
-
- /* Matrix A columns number of MAC operations are to be performed */
- colCnt = numColsA;
-
- /* matrix multiplication */
- while(colCnt > 0u)
- {
- /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
- /* Perform the multiply-accumulates */
- sum += (q63_t) * pIn1++ * *pIn2;
- pIn2 += numColsB;
-
- /* Decrement the loop counter */
- colCnt--;
- }
-
- /* Convert the result from 2.62 to 1.31 format and store in destination buffer */
- *px++ = (q31_t) clip_q63_to_q31(sum >> 31);
-
- /* Decrement the column loop counter */
- col--;
-
- /* Update the pointer pIn2 to point to the starting address of the next column */
- pIn2 = pInB + (numColsB - col);
-
- } while(col > 0u);
-
-#endif
-
- /* Update the pointer pInA to point to the starting address of the next row */
- i = i + numColsB;
- pInA = pInA + numColsA;
-
- /* Decrement the row loop counter */
- row--;
-
- } while(row > 0u);
-
- /* set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixMult group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_f32.c
deleted file mode 100644
index 37defa3..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_f32.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_scale_f32.c
-*
-* Description: Multiplies a floating-point matrix by a scalar.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @defgroup MatrixScale Matrix Scale
- *
- * Multiplies a matrix by a scalar. This is accomplished by multiplying each element in the
- * matrix by the scalar. For example:
- * \image html MatrixScale.gif "Matrix Scaling of a 3 x 3 matrix"
- *
- * The function checks to make sure that the input and output matrices are of the same size.
- *
- * In the fixed-point Q15 and Q31 functions, scale
is represented by
- * a fractional multiplication scaleFract
and an arithmetic shift shift
.
- * The shift allows the gain of the scaling operation to exceed 1.0.
- * The overall scale factor applied to the fixed-point data is
- *
- * scale = scaleFract * 2^shift.
- *
- */
-
-/**
- * @addtogroup MatrixScale
- * @{
- */
-
-/**
- * @brief Floating-point matrix scaling.
- * @param[in] *pSrc points to input matrix structure
- * @param[in] scale scale factor to be applied
- * @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_f32(
- const arm_matrix_instance_f32 * pSrc,
- float32_t scale,
- arm_matrix_instance_f32 * pDst)
-{
- float32_t *pIn = pSrc->pData; /* input data matrix pointer */
- float32_t *pOut = pDst->pData; /* output data matrix pointer */
- uint32_t numSamples; /* total number of elements in the matrix */
- uint32_t blkCnt; /* loop counters */
- arm_status status; /* status of matrix scaling */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- float32_t in1, in2, in3, in4; /* temporary variables */
- float32_t out1, out2, out3, out4; /* temporary variables */
-
-#endif // #ifndef ARM_MATH_CM0_FAMILY
-
-#ifdef ARM_MATH_MATRIX_CHECK
- /* Check for matrix mismatch condition */
- if((pSrc->numRows != pDst->numRows) || (pSrc->numCols != pDst->numCols))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
- {
- /* Total number of samples in the input matrix */
- numSamples = (uint32_t) pSrc->numRows * pSrc->numCols;
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /* Loop Unrolling */
- blkCnt = numSamples >> 2;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) * scale */
- /* Scaling and results are stored in the destination buffer. */
- in1 = pIn[0];
- in2 = pIn[1];
- in3 = pIn[2];
- in4 = pIn[3];
-
- out1 = in1 * scale;
- out2 = in2 * scale;
- out3 = in3 * scale;
- out4 = in4 * scale;
-
-
- pOut[0] = out1;
- pOut[1] = out2;
- pOut[2] = out3;
- pOut[3] = out4;
-
- /* update pointers to process next sampels */
- pIn += 4u;
- pOut += 4u;
-
- /* Decrement the numSamples loop counter */
- blkCnt--;
- }
-
- /* If the numSamples is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = numSamples % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Initialize blkCnt with number of samples */
- blkCnt = numSamples;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) * scale */
- /* The results are stored in the destination buffer. */
- *pOut++ = (*pIn++) * scale;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
-
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixScale group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_q15.c
deleted file mode 100644
index 5b1af16..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_q15.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_scale_q15.c
-*
-* Description: Multiplies a Q15 matrix by a scalar.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @addtogroup MatrixScale
- * @{
- */
-
-/**
- * @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 structure
- * @return The function returns either
- * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
- *
- * @details
- * Scaling and Overflow Behavior:
- * \par
- * The input data *pSrc
and scaleFract
are in 1.15 format.
- * These are multiplied to yield a 2.30 intermediate result and this is shifted with saturation to 1.15 format.
- */
-
-arm_status arm_mat_scale_q15(
- const arm_matrix_instance_q15 * pSrc,
- q15_t scaleFract,
- int32_t shift,
- arm_matrix_instance_q15 * pDst)
-{
- q15_t *pIn = pSrc->pData; /* input data matrix pointer */
- q15_t *pOut = pDst->pData; /* output data matrix pointer */
- uint32_t numSamples; /* total number of elements in the matrix */
- int32_t totShift = 15 - shift; /* total shift to apply after scaling */
- uint32_t blkCnt; /* loop counters */
- arm_status status; /* status of matrix scaling */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- q15_t in1, in2, in3, in4;
- q31_t out1, out2, out3, out4;
- q31_t inA1, inA2;
-
-#endif // #ifndef ARM_MATH_CM0_FAMILY
-
-#ifdef ARM_MATH_MATRIX_CHECK
- /* Check for matrix mismatch */
- if((pSrc->numRows != pDst->numRows) || (pSrc->numCols != pDst->numCols))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif // #ifdef ARM_MATH_MATRIX_CHECK
- {
- /* Total number of samples in the input matrix */
- numSamples = (uint32_t) pSrc->numRows * pSrc->numCols;
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- /* Loop Unrolling */
- blkCnt = numSamples >> 2;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) * k */
- /* Scale, saturate and then store the results in the destination buffer. */
- /* Reading 2 inputs from memory */
- inA1 = _SIMD32_OFFSET(pIn);
- inA2 = _SIMD32_OFFSET(pIn + 2);
-
- /* C = A * scale */
- /* Scale the inputs and then store the 2 results in the destination buffer
- * in single cycle by packing the outputs */
- out1 = (q31_t) ((q15_t) (inA1 >> 16) * scaleFract);
- out2 = (q31_t) ((q15_t) inA1 * scaleFract);
- out3 = (q31_t) ((q15_t) (inA2 >> 16) * scaleFract);
- out4 = (q31_t) ((q15_t) inA2 * scaleFract);
-
- out1 = out1 >> totShift;
- inA1 = _SIMD32_OFFSET(pIn + 4);
- out2 = out2 >> totShift;
- inA2 = _SIMD32_OFFSET(pIn + 6);
- out3 = out3 >> totShift;
- out4 = out4 >> totShift;
-
- in1 = (q15_t) (__SSAT(out1, 16));
- in2 = (q15_t) (__SSAT(out2, 16));
- in3 = (q15_t) (__SSAT(out3, 16));
- in4 = (q15_t) (__SSAT(out4, 16));
-
- _SIMD32_OFFSET(pOut) = __PKHBT(in2, in1, 16);
- _SIMD32_OFFSET(pOut + 2) = __PKHBT(in4, in3, 16);
-
- /* update pointers to process next sampels */
- pIn += 4u;
- pOut += 4u;
-
-
- /* Decrement the numSamples loop counter */
- blkCnt--;
- }
-
- /* If the numSamples is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = numSamples % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Initialize blkCnt with number of samples */
- blkCnt = numSamples;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) * k */
- /* Scale, saturate and then store the results in the destination buffer. */
- *pOut++ =
- (q15_t) (__SSAT(((q31_t) (*pIn++) * scaleFract) >> totShift, 16));
-
- /* Decrement the numSamples loop counter */
- blkCnt--;
- }
- /* Set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
-
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixScale group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_q31.c
deleted file mode 100644
index 5c88e41..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_q31.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_scale_q31.c
-*
-* Description: Multiplies a Q31 matrix by a scalar.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @addtogroup MatrixScale
- * @{
- */
-
-/**
- * @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.
- *
- * @details
- * Scaling and Overflow Behavior:
- * \par
- * The input data *pSrc
and scaleFract
are in 1.31 format.
- * These are multiplied to yield a 2.62 intermediate result and this is shifted with saturation to 1.31 format.
- */
-
-arm_status arm_mat_scale_q31(
- const arm_matrix_instance_q31 * pSrc,
- q31_t scaleFract,
- int32_t shift,
- arm_matrix_instance_q31 * pDst)
-{
- q31_t *pIn = pSrc->pData; /* input data matrix pointer */
- q31_t *pOut = pDst->pData; /* output data matrix pointer */
- uint32_t numSamples; /* total number of elements in the matrix */
- int32_t totShift = shift + 1; /* shift to apply after scaling */
- uint32_t blkCnt; /* loop counters */
- arm_status status; /* status of matrix scaling */
- q31_t in1, in2, out1; /* temporary variabels */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- q31_t in3, in4, out2, out3, out4; /* temporary variables */
-
-#endif // #ifndef ARM_MAT_CM0
-
-#ifdef ARM_MATH_MATRIX_CHECK
- /* Check for matrix mismatch */
- if((pSrc->numRows != pDst->numRows) || (pSrc->numCols != pDst->numCols))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif // #ifdef ARM_MATH_MATRIX_CHECK
- {
- /* Total number of samples in the input matrix */
- numSamples = (uint32_t) pSrc->numRows * pSrc->numCols;
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /* Loop Unrolling */
- blkCnt = numSamples >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) * k */
- /* Read values from input */
- in1 = *pIn;
- in2 = *(pIn + 1);
- in3 = *(pIn + 2);
- in4 = *(pIn + 3);
-
- /* multiply input with scaler value */
- in1 = ((q63_t) in1 * scaleFract) >> 32;
- in2 = ((q63_t) in2 * scaleFract) >> 32;
- in3 = ((q63_t) in3 * scaleFract) >> 32;
- in4 = ((q63_t) in4 * scaleFract) >> 32;
-
- /* apply shifting */
- out1 = in1 << totShift;
- out2 = in2 << totShift;
-
- /* saturate the results. */
- if(in1 != (out1 >> totShift))
- out1 = 0x7FFFFFFF ^ (in1 >> 31);
-
- if(in2 != (out2 >> totShift))
- out2 = 0x7FFFFFFF ^ (in2 >> 31);
-
- out3 = in3 << totShift;
- out4 = in4 << totShift;
-
- *pOut = out1;
- *(pOut + 1) = out2;
-
- if(in3 != (out3 >> totShift))
- out3 = 0x7FFFFFFF ^ (in3 >> 31);
-
- if(in4 != (out4 >> totShift))
- out4 = 0x7FFFFFFF ^ (in4 >> 31);
-
-
- *(pOut + 2) = out3;
- *(pOut + 3) = out4;
-
- /* update pointers to process next sampels */
- pIn += 4u;
- pOut += 4u;
-
-
- /* Decrement the numSamples loop counter */
- blkCnt--;
- }
-
- /* If the numSamples is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = numSamples % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Initialize blkCnt with number of samples */
- blkCnt = numSamples;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) * k */
- /* Scale, saturate and then store the results in the destination buffer. */
- in1 = *pIn++;
-
- in2 = ((q63_t) in1 * scaleFract) >> 32;
-
- out1 = in2 << totShift;
-
- if(in2 != (out1 >> totShift))
- out1 = 0x7FFFFFFF ^ (in2 >> 31);
-
- *pOut++ = out1;
-
- /* Decrement the numSamples loop counter */
- blkCnt--;
- }
-
- /* Set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
-
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixScale group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_f32.c
deleted file mode 100644
index f07bbe0..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_f32.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_sub_f32.c
-*
-* Description: Floating-point matrix subtraction.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @defgroup MatrixSub Matrix Subtraction
- *
- * Subtract two matrices.
- * \image html MatrixSubtraction.gif "Subraction of two 3 x 3 matrices"
- *
- * The functions check to make sure that
- * pSrcA
, pSrcB
, and pDst
have the same
- * number of rows and columns.
- */
-
-/**
- * @addtogroup MatrixSub
- * @{
- */
-
-/**
- * @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)
-{
- float32_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
- float32_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
- float32_t *pOut = pDst->pData; /* output data matrix pointer */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- float32_t inA1, inA2, inB1, inB2, out1, out2; /* temporary variables */
-
-#endif // #ifndef ARM_MATH_CM0_FAMILY
-
- uint32_t numSamples; /* total number of elements in the matrix */
- uint32_t blkCnt; /* loop counters */
- arm_status status; /* status of matrix subtraction */
-
-#ifdef ARM_MATH_MATRIX_CHECK
- /* Check for matrix mismatch condition */
- if((pSrcA->numRows != pSrcB->numRows) ||
- (pSrcA->numCols != pSrcB->numCols) ||
- (pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
- {
- /* Total number of samples in the input matrix */
- numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols;
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /* Loop Unrolling */
- blkCnt = numSamples >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) - B(m,n) */
- /* Subtract and then store the results in the destination buffer. */
- /* Read values from source A */
- inA1 = pIn1[0];
-
- /* Read values from source B */
- inB1 = pIn2[0];
-
- /* Read values from source A */
- inA2 = pIn1[1];
-
- /* out = sourceA - sourceB */
- out1 = inA1 - inB1;
-
- /* Read values from source B */
- inB2 = pIn2[1];
-
- /* Read values from source A */
- inA1 = pIn1[2];
-
- /* out = sourceA - sourceB */
- out2 = inA2 - inB2;
-
- /* Read values from source B */
- inB1 = pIn2[2];
-
- /* Store result in destination */
- pOut[0] = out1;
- pOut[1] = out2;
-
- /* Read values from source A */
- inA2 = pIn1[3];
-
- /* Read values from source B */
- inB2 = pIn2[3];
-
- /* out = sourceA - sourceB */
- out1 = inA1 - inB1;
-
-
- /* out = sourceA - sourceB */
- out2 = inA2 - inB2;
-
- /* Store result in destination */
- pOut[2] = out1;
-
- /* Store result in destination */
- pOut[3] = out2;
-
-
- /* update pointers to process next sampels */
- pIn1 += 4u;
- pIn2 += 4u;
- pOut += 4u;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the numSamples is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = numSamples % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Initialize blkCnt with number of samples */
- blkCnt = numSamples;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) - B(m,n) */
- /* Subtract and then store the results in the destination buffer. */
- *pOut++ = (*pIn1++) - (*pIn2++);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
-
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixSub group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_q15.c
deleted file mode 100644
index fd7b29c..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_q15.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_sub_q15.c
-*
-* Description: Q15 Matrix subtraction
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @addtogroup MatrixSub
- * @{
- */
-
-/**
- * @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.
- *
- * Scaling and Overflow Behavior:
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
- */
-
-arm_status arm_mat_sub_q15(
- const arm_matrix_instance_q15 * pSrcA,
- const arm_matrix_instance_q15 * pSrcB,
- arm_matrix_instance_q15 * pDst)
-{
- q15_t *pInA = pSrcA->pData; /* input data matrix pointer A */
- q15_t *pInB = pSrcB->pData; /* input data matrix pointer B */
- q15_t *pOut = pDst->pData; /* output data matrix pointer */
- uint32_t numSamples; /* total number of elements in the matrix */
- uint32_t blkCnt; /* loop counters */
- arm_status status; /* status of matrix subtraction */
-
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
-
- /* Check for matrix mismatch condition */
- if((pSrcA->numRows != pSrcB->numRows) ||
- (pSrcA->numCols != pSrcB->numCols) ||
- (pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
-
- {
- /* Total number of samples in the input matrix */
- numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols;
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /* Apply loop unrolling */
- blkCnt = numSamples >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) - B(m,n) */
- /* Subtract, Saturate and then store the results in the destination buffer. */
- *__SIMD32(pOut)++ = __QSUB16(*__SIMD32(pInA)++, *__SIMD32(pInB)++);
- *__SIMD32(pOut)++ = __QSUB16(*__SIMD32(pInA)++, *__SIMD32(pInB)++);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = numSamples % 0x4u;
-
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) - B(m,n) */
- /* Subtract and then store the results in the destination buffer. */
- *pOut++ = (q15_t) __QSUB16(*pInA++, *pInB++);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Initialize blkCnt with number of samples */
- blkCnt = numSamples;
-
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) - B(m,n) */
- /* Subtract and then store the results in the destination buffer. */
- *pOut++ = (q15_t) __SSAT(((q31_t) * pInA++ - *pInB++), 16);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- /* Set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
-
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixSub group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_q31.c
deleted file mode 100644
index d2f2f98..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_q31.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_sub_q31.c
-*
-* Description: Q31 matrix subtraction
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @addtogroup MatrixSub
- * @{
- */
-
-/**
- * @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.
- *
- * Scaling and Overflow Behavior:
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] will be saturated.
- */
-
-
-arm_status arm_mat_sub_q31(
- const arm_matrix_instance_q31 * pSrcA,
- const arm_matrix_instance_q31 * pSrcB,
- arm_matrix_instance_q31 * pDst)
-{
- q31_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
- q31_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
- q31_t *pOut = pDst->pData; /* output data matrix pointer */
- q31_t inA1, inB1; /* temporary variables */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- q31_t inA2, inB2; /* temporary variables */
- q31_t out1, out2; /* temporary variables */
-
-#endif // #ifndef ARM_MATH_CM0_FAMILY
-
- uint32_t numSamples; /* total number of elements in the matrix */
- uint32_t blkCnt; /* loop counters */
- arm_status status; /* status of matrix subtraction */
-
-
-#ifdef ARM_MATH_MATRIX_CHECK
- /* Check for matrix mismatch condition */
- if((pSrcA->numRows != pSrcB->numRows) ||
- (pSrcA->numCols != pSrcB->numCols) ||
- (pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif
- {
- /* Total number of samples in the input matrix */
- numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols;
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /* Loop Unrolling */
- blkCnt = numSamples >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) - B(m,n) */
- /* Subtract, saturate and then store the results in the destination buffer. */
- /* Read values from source A */
- inA1 = pIn1[0];
-
- /* Read values from source B */
- inB1 = pIn2[0];
-
- /* Read values from source A */
- inA2 = pIn1[1];
-
- /* Subtract and saturate */
- out1 = __QSUB(inA1, inB1);
-
- /* Read values from source B */
- inB2 = pIn2[1];
-
- /* Read values from source A */
- inA1 = pIn1[2];
-
- /* Subtract and saturate */
- out2 = __QSUB(inA2, inB2);
-
- /* Read values from source B */
- inB1 = pIn2[2];
-
- /* Store result in destination */
- pOut[0] = out1;
- pOut[1] = out2;
-
- /* Read values from source A */
- inA2 = pIn1[3];
-
- /* Read values from source B */
- inB2 = pIn2[3];
-
- /* Subtract and saturate */
- out1 = __QSUB(inA1, inB1);
-
- /* Subtract and saturate */
- out2 = __QSUB(inA2, inB2);
-
- /* Store result in destination */
- pOut[2] = out1;
- pOut[3] = out2;
-
- /* update pointers to process next samples */
- pIn1 += 4u;
- pIn2 += 4u;
- pOut += 4u;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the numSamples is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = numSamples % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Initialize blkCnt with number of samples */
- blkCnt = numSamples;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C(m,n) = A(m,n) - B(m,n) */
- /* Subtract, saturate and then store the results in the destination buffer. */
- inA1 = *pIn1++;
- inB1 = *pIn2++;
-
- inA1 = __QSUB(inA1, inB1);
-
- *pOut++ = inA1;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
-
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixSub group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_f32.c
deleted file mode 100644
index 84c08ec..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_f32.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_trans_f32.c
-*
-* Description: Floating-point matrix transpose.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 MatrixTrans Matrix Transpose
- *
- * Tranposes a matrix.
- * Transposing an M x N
matrix flips it around the center diagonal and results in an N x M
matrix.
- * \image html MatrixTranspose.gif "Transpose of a 3 x 3 matrix"
- */
-
-#include "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @addtogroup MatrixTrans
- * @{
- */
-
-/**
- * @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)
-{
- float32_t *pIn = pSrc->pData; /* input data matrix pointer */
- float32_t *pOut = pDst->pData; /* output data matrix pointer */
- float32_t *px; /* Temporary output data matrix pointer */
- uint16_t nRows = pSrc->numRows; /* number of rows */
- uint16_t nColumns = pSrc->numCols; /* number of columns */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- uint16_t blkCnt, i = 0u, row = nRows; /* loop counters */
- arm_status status; /* status of matrix transpose */
-
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
-
- /* Check for matrix mismatch condition */
- if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
-
- {
- /* Matrix transpose by exchanging the rows with columns */
- /* row loop */
- do
- {
- /* Loop Unrolling */
- blkCnt = nColumns >> 2;
-
- /* The pointer px is set to starting address of the column being processed */
- px = pOut + i;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u) /* column loop */
- {
- /* Read and store the input element in the destination */
- *px = *pIn++;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += nRows;
-
- /* Read and store the input element in the destination */
- *px = *pIn++;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += nRows;
-
- /* Read and store the input element in the destination */
- *px = *pIn++;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += nRows;
-
- /* Read and store the input element in the destination */
- *px = *pIn++;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += nRows;
-
- /* Decrement the column loop counter */
- blkCnt--;
- }
-
- /* Perform matrix transpose for last 3 samples here. */
- blkCnt = nColumns % 0x4u;
-
- while(blkCnt > 0u)
- {
- /* Read and store the input element in the destination */
- *px = *pIn++;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += nRows;
-
- /* Decrement the column loop counter */
- blkCnt--;
- }
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- uint16_t col, i = 0u, row = nRows; /* loop counters */
- arm_status status; /* status of matrix transpose */
-
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
- /* Check for matrix mismatch condition */
- if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
-
- {
- /* Matrix transpose by exchanging the rows with columns */
- /* row loop */
- do
- {
- /* The pointer px is set to starting address of the column being processed */
- px = pOut + i;
-
- /* Initialize column loop counter */
- col = nColumns;
-
- while(col > 0u)
- {
- /* Read and store the input element in the destination */
- *px = *pIn++;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += nRows;
-
- /* Decrement the column loop counter */
- col--;
- }
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- i++;
-
- /* Decrement the row loop counter */
- row--;
-
- } while(row > 0u); /* row loop end */
-
- /* Set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
-
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixTrans group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_q15.c
deleted file mode 100644
index 4e0fb82..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_q15.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_trans_q15.c
-*
-* Description: Q15 matrix transpose.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @addtogroup MatrixTrans
- * @{
- */
-
-/*
- * @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)
-{
- q15_t *pSrcA = pSrc->pData; /* input data matrix pointer */
- q15_t *pOut = pDst->pData; /* output data matrix pointer */
- uint16_t nRows = pSrc->numRows; /* number of nRows */
- uint16_t nColumns = pSrc->numCols; /* number of nColumns */
- uint16_t col, row = nRows, i = 0u; /* row and column loop counters */
- arm_status status; /* status of matrix transpose */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-#ifndef UNALIGNED_SUPPORT_DISABLE
-
- q31_t in; /* variable to hold temporary output */
-
-#else
-
- q15_t in;
-
-#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
-
- /* Check for matrix mismatch condition */
- if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
-
- {
- /* Matrix transpose by exchanging the rows with columns */
- /* row loop */
- do
- {
-
- /* Apply loop unrolling and exchange the columns with row elements */
- col = nColumns >> 2u;
-
- /* The pointer pOut is set to starting address of the column being processed */
- pOut = pDst->pData + i;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(col > 0u)
- {
-#ifndef UNALIGNED_SUPPORT_DISABLE
-
- /* Read two elements from the row */
- in = *__SIMD32(pSrcA)++;
-
- /* Unpack and store one element in the destination */
-#ifndef ARM_MATH_BIG_ENDIAN
-
- *pOut = (q15_t) in;
-
-#else
-
- *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
- /* Update the pointer pOut to point to the next row of the transposed matrix */
- pOut += nRows;
-
- /* Unpack and store the second element in the destination */
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
-
-#else
-
- *pOut = (q15_t) in;
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
- /* Update the pointer pOut to point to the next row of the transposed matrix */
- pOut += nRows;
-
- /* Read two elements from the row */
-#ifndef ARM_MATH_BIG_ENDIAN
-
- in = *__SIMD32(pSrcA)++;
-
-#else
-
- in = *__SIMD32(pSrcA)++;
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
- /* Unpack and store one element in the destination */
-#ifndef ARM_MATH_BIG_ENDIAN
-
- *pOut = (q15_t) in;
-
-#else
-
- *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
- /* Update the pointer pOut to point to the next row of the transposed matrix */
- pOut += nRows;
-
- /* Unpack and store the second element in the destination */
-#ifndef ARM_MATH_BIG_ENDIAN
-
- *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
-
-#else
-
- *pOut = (q15_t) in;
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
-#else
- /* Read one element from the row */
- in = *pSrcA++;
-
- /* Store one element in the destination */
- *pOut = in;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- pOut += nRows;
-
- /* Read one element from the row */
- in = *pSrcA++;
-
- /* Store one element in the destination */
- *pOut = in;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- pOut += nRows;
-
- /* Read one element from the row */
- in = *pSrcA++;
-
- /* Store one element in the destination */
- *pOut = in;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- pOut += nRows;
-
- /* Read one element from the row */
- in = *pSrcA++;
-
- /* Store one element in the destination */
- *pOut = in;
-
-#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
-
- /* Update the pointer pOut to point to the next row of the transposed matrix */
- pOut += nRows;
-
- /* Decrement the column loop counter */
- col--;
- }
-
- /* Perform matrix transpose for last 3 samples here. */
- col = nColumns % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
- /* Check for matrix mismatch condition */
- if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
-
- {
- /* Matrix transpose by exchanging the rows with columns */
- /* row loop */
- do
- {
- /* The pointer pOut is set to starting address of the column being processed */
- pOut = pDst->pData + i;
-
- /* Initialize column loop counter */
- col = nColumns;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(col > 0u)
- {
- /* Read and store the input element in the destination */
- *pOut = *pSrcA++;
-
- /* Update the pointer pOut to point to the next row of the transposed matrix */
- pOut += nRows;
-
- /* Decrement the column loop counter */
- col--;
- }
-
- i++;
-
- /* Decrement the row loop counter */
- row--;
-
- } while(row > 0u);
-
- /* set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixTrans group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_q31.c
deleted file mode 100644
index ec92582..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_q31.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mat_trans_q31.c
-*
-* Description: Q31 matrix transpose.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupMatrix
- */
-
-/**
- * @addtogroup MatrixTrans
- * @{
- */
-
-/*
- * @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)
-{
- q31_t *pIn = pSrc->pData; /* input data matrix pointer */
- q31_t *pOut = pDst->pData; /* output data matrix pointer */
- q31_t *px; /* Temporary output data matrix pointer */
- uint16_t nRows = pSrc->numRows; /* number of nRows */
- uint16_t nColumns = pSrc->numCols; /* number of nColumns */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- uint16_t blkCnt, i = 0u, row = nRows; /* loop counters */
- arm_status status; /* status of matrix transpose */
-
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
-
- /* Check for matrix mismatch condition */
- if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
-
- {
- /* Matrix transpose by exchanging the rows with columns */
- /* row loop */
- do
- {
- /* Apply loop unrolling and exchange the columns with row elements */
- blkCnt = nColumns >> 2u;
-
- /* The pointer px is set to starting address of the column being processed */
- px = pOut + i;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* Read and store the input element in the destination */
- *px = *pIn++;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += nRows;
-
- /* Read and store the input element in the destination */
- *px = *pIn++;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += nRows;
-
- /* Read and store the input element in the destination */
- *px = *pIn++;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += nRows;
-
- /* Read and store the input element in the destination */
- *px = *pIn++;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += nRows;
-
- /* Decrement the column loop counter */
- blkCnt--;
- }
-
- /* Perform matrix transpose for last 3 samples here. */
- blkCnt = nColumns % 0x4u;
-
- while(blkCnt > 0u)
- {
- /* Read and store the input element in the destination */
- *px = *pIn++;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += nRows;
-
- /* Decrement the column loop counter */
- blkCnt--;
- }
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- uint16_t col, i = 0u, row = nRows; /* loop counters */
- arm_status status; /* status of matrix transpose */
-
-
-#ifdef ARM_MATH_MATRIX_CHECK
-
- /* Check for matrix mismatch condition */
- if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows))
- {
- /* Set status as ARM_MATH_SIZE_MISMATCH */
- status = ARM_MATH_SIZE_MISMATCH;
- }
- else
-#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
-
- {
- /* Matrix transpose by exchanging the rows with columns */
- /* row loop */
- do
- {
- /* The pointer px is set to starting address of the column being processed */
- px = pOut + i;
-
- /* Initialize column loop counter */
- col = nColumns;
-
- while(col > 0u)
- {
- /* Read and store the input element in the destination */
- *px = *pIn++;
-
- /* Update the pointer px to point to the next row of the transposed matrix */
- px += nRows;
-
- /* Decrement the column loop counter */
- col--;
- }
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- i++;
-
- /* Decrement the row loop counter */
- row--;
-
- }
- while(row > 0u); /* row loop end */
-
- /* set status as ARM_MATH_SUCCESS */
- status = ARM_MATH_SUCCESS;
- }
-
- /* Return to application */
- return (status);
-}
-
-/**
- * @} end of MatrixTrans group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_f32.c
deleted file mode 100644
index 2326646..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_f32.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_max_f32.c
-*
-* Description: Maximum value of a floating-point vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @defgroup Max Maximum
- *
- * Computes the maximum value of an array of data.
- * The function returns both the maximum value and its position within the array.
- * There are separate functions for floating-point, Q31, Q15, and Q7 data types.
- */
-
-/**
- * @addtogroup Max
- * @{
- */
-
-
-/**
- * @brief Maximum value of a floating-point vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult maximum value returned here
- * @param[out] *pIndex index of maximum value returned here
- * @return none.
- */
-
-void arm_max_f32(
- float32_t * pSrc,
- uint32_t blockSize,
- float32_t * pResult,
- uint32_t * pIndex)
-{
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- float32_t maxVal1, maxVal2, out; /* Temporary variables to store the output value. */
- uint32_t blkCnt, outIndex, count; /* loop counter */
-
- /* Initialise the count value. */
- count = 0u;
- /* Initialise the index value to zero. */
- outIndex = 0u;
- /* Load first input value that act as reference value for comparision */
- out = *pSrc++;
-
- /* Loop unrolling */
- blkCnt = (blockSize - 1u) >> 2u;
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- while(blkCnt > 0u)
- {
- /* Initialize maxVal to the next consecutive values one by one */
- maxVal1 = *pSrc++;
-
- maxVal2 = *pSrc++;
-
- /* compare for the maximum value */
- if(out < maxVal1)
- {
- /* Update the maximum value and its index */
- out = maxVal1;
- outIndex = count + 1u;
- }
-
- maxVal1 = *pSrc++;
-
- /* compare for the maximum value */
- if(out < maxVal2)
- {
- /* Update the maximum value and its index */
- out = maxVal2;
- outIndex = count + 2u;
- }
-
- maxVal2 = *pSrc++;
-
- /* compare for the maximum value */
- if(out < maxVal1)
- {
- /* Update the maximum value and its index */
- out = maxVal1;
- outIndex = count + 3u;
- }
-
- /* compare for the maximum value */
- if(out < maxVal2)
- {
- /* Update the maximum value and its index */
- out = maxVal2;
- outIndex = count + 4u;
- }
-
- count += 4u;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* if (blockSize - 1u) is not multiple of 4 */
- blkCnt = (blockSize - 1u) % 4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
- float32_t maxVal1, out; /* Temporary variables to store the output value. */
- uint32_t blkCnt, outIndex; /* loop counter */
-
- /* Initialise the index value to zero. */
- outIndex = 0u;
- /* Load first input value that act as reference value for comparision */
- out = *pSrc++;
-
- blkCnt = (blockSize - 1u);
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* Initialize maxVal to the next consecutive values one by one */
- maxVal1 = *pSrc++;
-
- /* compare for the maximum value */
- if(out < maxVal1)
- {
- /* Update the maximum value and it's index */
- out = maxVal1;
- outIndex = blockSize - blkCnt;
- }
-
-
- /* Decrement the loop counter */
- blkCnt--;
-
- }
-
- /* Store the maximum value and it's index into destination pointers */
- *pResult = out;
- *pIndex = outIndex;
-}
-
-/**
- * @} end of Max group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_q15.c
deleted file mode 100644
index 20375c2..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_q15.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_max_q15.c
-*
-* Description: Maximum value of a Q15 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @addtogroup Max
- * @{
- */
-
-
-/**
- * @brief Maximum value of a Q15 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult maximum value returned here
- * @param[out] *pIndex index of maximum value returned here
- * @return none.
- */
-
-void arm_max_q15(
- q15_t * pSrc,
- uint32_t blockSize,
- q15_t * pResult,
- uint32_t * pIndex)
-{
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- q15_t maxVal1, maxVal2, out; /* Temporary variables to store the output value. */
- uint32_t blkCnt, outIndex, count; /* loop counter */
-
- /* Initialise the count value. */
- count = 0u;
- /* Initialise the index value to zero. */
- outIndex = 0u;
- /* Load first input value that act as reference value for comparision */
- out = *pSrc++;
-
- /* Loop unrolling */
- blkCnt = (blockSize - 1u) >> 2u;
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- while(blkCnt > 0u)
- {
- /* Initialize maxVal to the next consecutive values one by one */
- maxVal1 = *pSrc++;
-
- maxVal2 = *pSrc++;
-
- /* compare for the maximum value */
- if(out < maxVal1)
- {
- /* Update the maximum value and its index */
- out = maxVal1;
- outIndex = count + 1u;
- }
-
- maxVal1 = *pSrc++;
-
- /* compare for the maximum value */
- if(out < maxVal2)
- {
- /* Update the maximum value and its index */
- out = maxVal2;
- outIndex = count + 2u;
- }
-
- maxVal2 = *pSrc++;
-
- /* compare for the maximum value */
- if(out < maxVal1)
- {
- /* Update the maximum value and its index */
- out = maxVal1;
- outIndex = count + 3u;
- }
-
- /* compare for the maximum value */
- if(out < maxVal2)
- {
- /* Update the maximum value and its index */
- out = maxVal2;
- outIndex = count + 4u;
- }
-
- count += 4u;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* if (blockSize - 1u) is not multiple of 4 */
- blkCnt = (blockSize - 1u) % 4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
- q15_t maxVal1, out; /* Temporary variables to store the output value. */
- uint32_t blkCnt, outIndex; /* loop counter */
-
- blkCnt = (blockSize - 1u);
-
- /* Initialise the index value to zero. */
- outIndex = 0u;
- /* Load first input value that act as reference value for comparision */
- out = *pSrc++;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* Initialize maxVal to the next consecutive values one by one */
- maxVal1 = *pSrc++;
-
- /* compare for the maximum value */
- if(out < maxVal1)
- {
- /* Update the maximum value and it's index */
- out = maxVal1;
- outIndex = blockSize - blkCnt;
- }
- /* Decrement the loop counter */
- blkCnt--;
-
- }
-
- /* Store the maximum value and its index into destination pointers */
- *pResult = out;
- *pIndex = outIndex;
-}
-
-/**
- * @} end of Max group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_q31.c
deleted file mode 100644
index c687e79..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_q31.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_max_q31.c
-*
-* Description: Maximum value of a Q31 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @addtogroup Max
- * @{
- */
-
-
-/**
- * @brief Maximum value of a Q31 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult maximum value returned here
- * @param[out] *pIndex index of maximum value returned here
- * @return none.
- */
-
-void arm_max_q31(
- q31_t * pSrc,
- uint32_t blockSize,
- q31_t * pResult,
- uint32_t * pIndex)
-{
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t maxVal1, maxVal2, out; /* Temporary variables to store the output value. */
- uint32_t blkCnt, outIndex, count; /* loop counter */
-
- /* Initialise the count value. */
- count = 0u;
- /* Initialise the index value to zero. */
- outIndex = 0u;
- /* Load first input value that act as reference value for comparision */
- out = *pSrc++;
-
- /* Loop unrolling */
- blkCnt = (blockSize - 1u) >> 2u;
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- while(blkCnt > 0u)
- {
- /* Initialize maxVal to the next consecutive values one by one */
- maxVal1 = *pSrc++;
-
- maxVal2 = *pSrc++;
-
- /* compare for the maximum value */
- if(out < maxVal1)
- {
- /* Update the maximum value and its index */
- out = maxVal1;
- outIndex = count + 1u;
- }
-
- maxVal1 = *pSrc++;
-
- /* compare for the maximum value */
- if(out < maxVal2)
- {
- /* Update the maximum value and its index */
- out = maxVal2;
- outIndex = count + 2u;
- }
-
- maxVal2 = *pSrc++;
-
- /* compare for the maximum value */
- if(out < maxVal1)
- {
- /* Update the maximum value and its index */
- out = maxVal1;
- outIndex = count + 3u;
- }
-
- /* compare for the maximum value */
- if(out < maxVal2)
- {
- /* Update the maximum value and its index */
- out = maxVal2;
- outIndex = count + 4u;
- }
-
- count += 4u;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* if (blockSize - 1u) is not multiple of 4 */
- blkCnt = (blockSize - 1u) % 4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
- q31_t maxVal1, out; /* Temporary variables to store the output value. */
- uint32_t blkCnt, outIndex; /* loop counter */
-
- /* Initialise the index value to zero. */
- outIndex = 0u;
- /* Load first input value that act as reference value for comparision */
- out = *pSrc++;
-
- blkCnt = (blockSize - 1u);
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* Initialize maxVal to the next consecutive values one by one */
- maxVal1 = *pSrc++;
-
- /* compare for the maximum value */
- if(out < maxVal1)
- {
- /* Update the maximum value and it's index */
- out = maxVal1;
- outIndex = blockSize - blkCnt;
- }
-
- /* Decrement the loop counter */
- blkCnt--;
-
- }
-
- /* Store the maximum value and its index into destination pointers */
- *pResult = out;
- *pIndex = outIndex;
-}
-
-/**
- * @} end of Max group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_q7.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_q7.c
deleted file mode 100644
index 0e0cc2d..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_q7.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_max_q7.c
-*
-* Description: Maximum value of a Q7 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @addtogroup Max
- * @{
- */
-
-
-/**
- * @brief Maximum value of a Q7 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult maximum value returned here
- * @param[out] *pIndex index of maximum value returned here
- * @return none.
- */
-
-void arm_max_q7(
- q7_t * pSrc,
- uint32_t blockSize,
- q7_t * pResult,
- uint32_t * pIndex)
-{
-#ifndef ARM_MATH_CM0_FAMILY
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- q7_t maxVal1, maxVal2, out; /* Temporary variables to store the output value. */
- uint32_t blkCnt, outIndex, count; /* loop counter */
-
- /* Initialise the count value. */
- count = 0u;
- /* Initialise the index value to zero. */
- outIndex = 0u;
- /* Load first input value that act as reference value for comparision */
- out = *pSrc++;
-
- /* Loop unrolling */
- blkCnt = (blockSize - 1u) >> 2u;
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- while(blkCnt > 0u)
- {
- /* Initialize maxVal to the next consecutive values one by one */
- maxVal1 = *pSrc++;
-
- maxVal2 = *pSrc++;
-
- /* compare for the maximum value */
- if(out < maxVal1)
- {
- /* Update the maximum value and its index */
- out = maxVal1;
- outIndex = count + 1u;
- }
-
- maxVal1 = *pSrc++;
-
- /* compare for the maximum value */
- if(out < maxVal2)
- {
- /* Update the maximum value and its index */
- out = maxVal2;
- outIndex = count + 2u;
- }
-
- maxVal2 = *pSrc++;
-
- /* compare for the maximum value */
- if(out < maxVal1)
- {
- /* Update the maximum value and its index */
- out = maxVal1;
- outIndex = count + 3u;
- }
-
- /* compare for the maximum value */
- if(out < maxVal2)
- {
- /* Update the maximum value and its index */
- out = maxVal2;
- outIndex = count + 4u;
- }
-
- count += 4u;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* if (blockSize - 1u) is not multiple of 4 */
- blkCnt = (blockSize - 1u) % 4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
- q7_t maxVal1, out; /* Temporary variables to store the output value. */
- uint32_t blkCnt, outIndex; /* loop counter */
-
- /* Initialise the index value to zero. */
- outIndex = 0u;
- /* Load first input value that act as reference value for comparision */
- out = *pSrc++;
-
- blkCnt = (blockSize - 1u);
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* Initialize maxVal to the next consecutive values one by one */
- maxVal1 = *pSrc++;
-
- /* compare for the maximum value */
- if(out < maxVal1)
- {
- /* Update the maximum value and it's index */
- out = maxVal1;
- outIndex = blockSize - blkCnt;
- }
- /* Decrement the loop counter */
- blkCnt--;
-
- }
-
- /* Store the maximum value and its index into destination pointers */
- *pResult = out;
- *pIndex = outIndex;
-
-}
-
-/**
- * @} end of Max group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_f32.c
deleted file mode 100644
index bc054b2..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_f32.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mean_f32.c
-*
-* Description: Mean value of a floating-point vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @defgroup mean Mean
- *
- * Calculates the mean of the input vector. Mean is defined as the average of the elements in the vector.
- * The underlying algorithm is used:
- *
- *
- * Result = (pSrc[0] + pSrc[1] + pSrc[2] + ... + pSrc[blockSize-1]) / blockSize;
- *
- *
- * There are separate functions for floating-point, Q31, Q15, and Q7 data types.
- */
-
-/**
- * @addtogroup mean
- * @{
- */
-
-
-/**
- * @brief Mean value of a floating-point vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult mean value returned here
- * @return none.
- */
-
-
-void arm_mean_f32(
- float32_t * pSrc,
- uint32_t blockSize,
- float32_t * pResult)
-{
- float32_t sum = 0.0f; /* Temporary result storage */
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- float32_t in1, in2, in3, in4;
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
- in1 = *pSrc++;
- in2 = *pSrc++;
- in3 = *pSrc++;
- in4 = *pSrc++;
-
- sum += in1;
- sum += in2;
- sum += in3;
- sum += in4;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
- sum += *pSrc++;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */
- /* Store the result to the destination */
- *pResult = sum / (float32_t) blockSize;
-}
-
-/**
- * @} end of mean group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_q15.c
deleted file mode 100644
index ff5d64b..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_q15.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mean_q15.c
-*
-* Description: Mean value of a Q15 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @addtogroup mean
- * @{
- */
-
-/**
- * @brief Mean value of a Q15 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult mean value returned here
- * @return none.
- *
- * @details
- * Scaling and Overflow Behavior:
- * \par
- * The function is implemented using a 32-bit internal accumulator.
- * The input is represented in 1.15 format and is accumulated in a 32-bit
- * accumulator in 17.15 format.
- * There is no risk of internal overflow with this approach, and the
- * full precision of intermediate result is preserved.
- * Finally, the accumulator is saturated and truncated to yield a result of 1.15 format.
- *
- */
-
-
-void arm_mean_q15(
- q15_t * pSrc,
- uint32_t blockSize,
- q15_t * pResult)
-{
- q31_t sum = 0; /* Temporary result storage */
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t in;
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
- in = *__SIMD32(pSrc)++;
- sum += ((in << 16) >> 16);
- sum += (in >> 16);
- in = *__SIMD32(pSrc)++;
- sum += ((in << 16) >> 16);
- sum += (in >> 16);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
- sum += *pSrc++;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */
- /* Store the result to the destination */
- *pResult = (q15_t) (sum / (q31_t)blockSize);
-}
-
-/**
- * @} end of mean group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_q31.c
deleted file mode 100644
index afd62b3..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_q31.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mean_q31.c
-*
-* Description: Mean value of a Q31 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @addtogroup mean
- * @{
- */
-
-/**
- * @brief Mean value of a Q31 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult mean value returned here
- * @return none.
- *
- * @details
- * Scaling and Overflow Behavior:
- *\par
- * The function is implemented using a 64-bit internal accumulator.
- * The input is represented in 1.31 format and is accumulated in a 64-bit
- * accumulator in 33.31 format.
- * There is no risk of internal overflow with this approach, and the
- * full precision of intermediate result is preserved.
- * Finally, the accumulator is truncated to yield a result of 1.31 format.
- *
- */
-
-
-void arm_mean_q31(
- q31_t * pSrc,
- uint32_t blockSize,
- q31_t * pResult)
-{
- q63_t sum = 0; /* Temporary result storage */
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t in1, in2, in3, in4;
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
- in1 = *pSrc++;
- in2 = *pSrc++;
- in3 = *pSrc++;
- in4 = *pSrc++;
-
- sum += in1;
- sum += in2;
- sum += in3;
- sum += in4;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
- sum += *pSrc++;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */
- /* Store the result to the destination */
- *pResult = (q31_t) (sum / (int32_t) blockSize);
-}
-
-/**
- * @} end of mean group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_q7.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_q7.c
deleted file mode 100644
index 522e3d4..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_q7.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_mean_q7.c
-*
-* Description: Mean value of a Q7 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @addtogroup mean
- * @{
- */
-
-/**
- * @brief Mean value of a Q7 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult mean value returned here
- * @return none.
- *
- * @details
- * Scaling and Overflow Behavior:
- * \par
- * The function is implemented using a 32-bit internal accumulator.
- * The input is represented in 1.7 format and is accumulated in a 32-bit
- * accumulator in 25.7 format.
- * There is no risk of internal overflow with this approach, and the
- * full precision of intermediate result is preserved.
- * Finally, the accumulator is truncated to yield a result of 1.7 format.
- *
- */
-
-
-void arm_mean_q7(
- q7_t * pSrc,
- uint32_t blockSize,
- q7_t * pResult)
-{
- q31_t sum = 0; /* Temporary result storage */
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t in;
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
- in = *__SIMD32(pSrc)++;
-
- sum += ((in << 24) >> 24);
- sum += ((in << 16) >> 24);
- sum += ((in << 8) >> 24);
- sum += (in >> 24);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
- sum += *pSrc++;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */
- /* Store the result to the destination */
- *pResult = (q7_t) (sum / (int32_t) blockSize);
-}
-
-/**
- * @} end of mean group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_f32.c
deleted file mode 100644
index 22f057a..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_f32.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_min_f32.c
-*
-* Description: Minimum value of a floating-point vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @defgroup Min Minimum
- *
- * Computes the minimum value of an array of data.
- * The function returns both the minimum value and its position within the array.
- * There are separate functions for floating-point, Q31, Q15, and Q7 data types.
- */
-
-/**
- * @addtogroup Min
- * @{
- */
-
-
-/**
- * @brief Minimum value of a floating-point vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult minimum value returned here
- * @param[out] *pIndex index of minimum value returned here
- * @return none.
- *
- */
-
-void arm_min_f32(
- float32_t * pSrc,
- uint32_t blockSize,
- float32_t * pResult,
- uint32_t * pIndex)
-{
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- float32_t minVal1, minVal2, out; /* Temporary variables to store the output value. */
- uint32_t blkCnt, outIndex, count; /* loop counter */
-
- /* Initialise the count value. */
- count = 0u;
- /* Initialise the index value to zero. */
- outIndex = 0u;
- /* Load first input value that act as reference value for comparision */
- out = *pSrc++;
-
- /* Loop unrolling */
- blkCnt = (blockSize - 1u) >> 2u;
-
- while(blkCnt > 0)
- {
- /* Initialize minVal to the next consecutive values one by one */
- minVal1 = *pSrc++;
- minVal2 = *pSrc++;
-
- /* compare for the minimum value */
- if(out > minVal1)
- {
- /* Update the minimum value and its index */
- out = minVal1;
- outIndex = count + 1u;
- }
-
- minVal1 = *pSrc++;
-
- /* compare for the minimum value */
- if(out > minVal2)
- {
- /* Update the minimum value and its index */
- out = minVal2;
- outIndex = count + 2u;
- }
-
- minVal2 = *pSrc++;
-
- /* compare for the minimum value */
- if(out > minVal1)
- {
- /* Update the minimum value and its index */
- out = minVal1;
- outIndex = count + 3u;
- }
-
- /* compare for the minimum value */
- if(out > minVal2)
- {
- /* Update the minimum value and its index */
- out = minVal2;
- outIndex = count + 4u;
- }
-
- count += 4u;
-
- blkCnt--;
- }
-
- /* if (blockSize - 1u ) is not multiple of 4 */
- blkCnt = (blockSize - 1u) % 4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
- float32_t minVal1, out; /* Temporary variables to store the output value. */
- uint32_t blkCnt, outIndex; /* loop counter */
-
- /* Initialise the index value to zero. */
- outIndex = 0u;
- /* Load first input value that act as reference value for comparision */
- out = *pSrc++;
-
- blkCnt = (blockSize - 1u);
-
-#endif // #ifndef ARM_MATH_CM0_FAMILY
-
- while(blkCnt > 0)
- {
- /* Initialize minVal to the next consecutive values one by one */
- minVal1 = *pSrc++;
-
- /* compare for the minimum value */
- if(out > minVal1)
- {
- /* Update the minimum value and it's index */
- out = minVal1;
- outIndex = blockSize - blkCnt;
- }
-
- blkCnt--;
-
- }
-
- /* Store the minimum value and it's index into destination pointers */
- *pResult = out;
- *pIndex = outIndex;
-}
-
-/**
- * @} end of Min group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_q15.c
deleted file mode 100644
index 05c13dd..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_q15.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_min_q15.c
-*
-* Description: Minimum value of a Q15 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-
-/**
- * @addtogroup Min
- * @{
- */
-
-
-/**
- * @brief Minimum value of a Q15 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult minimum value returned here
- * @param[out] *pIndex index of minimum value returned here
- * @return none.
- *
- */
-
-void arm_min_q15(
- q15_t * pSrc,
- uint32_t blockSize,
- q15_t * pResult,
- uint32_t * pIndex)
-{
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- q15_t minVal1, minVal2, out; /* Temporary variables to store the output value. */
- uint32_t blkCnt, outIndex, count; /* loop counter */
-
- /* Initialise the count value. */
- count = 0u;
- /* Initialise the index value to zero. */
- outIndex = 0u;
- /* Load first input value that act as reference value for comparision */
- out = *pSrc++;
-
- /* Loop unrolling */
- blkCnt = (blockSize - 1u) >> 2u;
-
- while(blkCnt > 0)
- {
- /* Initialize minVal to the next consecutive values one by one */
- minVal1 = *pSrc++;
- minVal2 = *pSrc++;
-
- /* compare for the minimum value */
- if(out > minVal1)
- {
- /* Update the minimum value and its index */
- out = minVal1;
- outIndex = count + 1u;
- }
-
- minVal1 = *pSrc++;
-
- /* compare for the minimum value */
- if(out > minVal2)
- {
- /* Update the minimum value and its index */
- out = minVal2;
- outIndex = count + 2u;
- }
-
- minVal2 = *pSrc++;
-
- /* compare for the minimum value */
- if(out > minVal1)
- {
- /* Update the minimum value and its index */
- out = minVal1;
- outIndex = count + 3u;
- }
-
- /* compare for the minimum value */
- if(out > minVal2)
- {
- /* Update the minimum value and its index */
- out = minVal2;
- outIndex = count + 4u;
- }
-
- count += 4u;
-
- blkCnt--;
- }
-
- /* if (blockSize - 1u ) is not multiple of 4 */
- blkCnt = (blockSize - 1u) % 4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
- q15_t minVal1, out; /* Temporary variables to store the output value. */
- uint32_t blkCnt, outIndex; /* loop counter */
-
- blkCnt = (blockSize - 1u);
-
- /* Initialise the index value to zero. */
- outIndex = 0u;
- /* Load first input value that act as reference value for comparision */
- out = *pSrc++;
-
-#endif // #ifndef ARM_MATH_CM0_FAMILY
-
- while(blkCnt > 0)
- {
- /* Initialize minVal to the next consecutive values one by one */
- minVal1 = *pSrc++;
-
- /* compare for the minimum value */
- if(out > minVal1)
- {
- /* Update the minimum value and it's index */
- out = minVal1;
- outIndex = blockSize - blkCnt;
- }
-
- blkCnt--;
-
- }
-
-
-
- /* Store the minimum value and its index into destination pointers */
- *pResult = out;
- *pIndex = outIndex;
-}
-
-/**
- * @} end of Min group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_q31.c
deleted file mode 100644
index 97431db..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_q31.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_min_q31.c
-*
-* Description: Minimum value of a Q31 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-
-/**
- * @addtogroup Min
- * @{
- */
-
-
-/**
- * @brief Minimum value of a Q31 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult minimum value returned here
- * @param[out] *pIndex index of minimum value returned here
- * @return none.
- *
- */
-
-void arm_min_q31(
- q31_t * pSrc,
- uint32_t blockSize,
- q31_t * pResult,
- uint32_t * pIndex)
-{
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t minVal1, minVal2, out; /* Temporary variables to store the output value. */
- uint32_t blkCnt, outIndex, count; /* loop counter */
-
- /* Initialise the count value. */
- count = 0u;
- /* Initialise the index value to zero. */
- outIndex = 0u;
- /* Load first input value that act as reference value for comparision */
- out = *pSrc++;
-
-
- /* Loop unrolling */
- blkCnt = (blockSize - 1u) >> 2u;
-
- while(blkCnt > 0)
- {
- /* Initialize minVal to the next consecutive values one by one */
- minVal1 = *pSrc++;
- minVal2 = *pSrc++;
-
- /* compare for the minimum value */
- if(out > minVal1)
- {
- /* Update the minimum value and its index */
- out = minVal1;
- outIndex = count + 1u;
- }
-
- minVal1 = *pSrc++;
-
- /* compare for the minimum value */
- if(out > minVal2)
- {
- /* Update the minimum value and its index */
- out = minVal2;
- outIndex = count + 2u;
- }
-
- minVal2 = *pSrc++;
-
- /* compare for the minimum value */
- if(out > minVal1)
- {
- /* Update the minimum value and its index */
- out = minVal1;
- outIndex = count + 3u;
- }
-
- /* compare for the minimum value */
- if(out > minVal2)
- {
- /* Update the minimum value and its index */
- out = minVal2;
- outIndex = count + 4u;
- }
-
- count += 4u;
-
- blkCnt--;
- }
-
- /* if (blockSize - 1u ) is not multiple of 4 */
- blkCnt = (blockSize - 1u) % 4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
- q31_t minVal1, out; /* Temporary variables to store the output value. */
- uint32_t blkCnt, outIndex; /* loop counter */
-
- blkCnt = (blockSize - 1u);
-
- /* Initialise the index value to zero. */
- outIndex = 0u;
- /* Load first input value that act as reference value for comparision */
- out = *pSrc++;
-
-#endif // #ifndef ARM_MATH_CM0_FAMILY
-
- while(blkCnt > 0)
- {
- /* Initialize minVal to the next consecutive values one by one */
- minVal1 = *pSrc++;
-
- /* compare for the minimum value */
- if(out > minVal1)
- {
- /* Update the minimum value and it's index */
- out = minVal1;
- outIndex = blockSize - blkCnt;
- }
-
- blkCnt--;
-
- }
-
- /* Store the minimum value and its index into destination pointers */
- *pResult = out;
- *pIndex = outIndex;
-}
-
-/**
- * @} end of Min group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_q7.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_q7.c
deleted file mode 100644
index b6d0950..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_q7.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_min_q7.c
-*
-* Description: Minimum value of a Q7 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @addtogroup Min
- * @{
- */
-
-
-/**
- * @brief Minimum value of a Q7 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult minimum value returned here
- * @param[out] *pIndex index of minimum value returned here
- * @return none.
- *
- */
-
-void arm_min_q7(
- q7_t * pSrc,
- uint32_t blockSize,
- q7_t * pResult,
- uint32_t * pIndex)
-{
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- q7_t minVal1, minVal2, out; /* Temporary variables to store the output value. */
- uint32_t blkCnt, outIndex, count; /* loop counter */
-
- /* Initialise the count value. */
- count = 0u;
- /* Initialise the index value to zero. */
- outIndex = 0u;
- /* Load first input value that act as reference value for comparision */
- out = *pSrc++;
-
- /* Loop unrolling */
- blkCnt = (blockSize - 1u) >> 2u;
-
- while(blkCnt > 0)
- {
- /* Initialize minVal to the next consecutive values one by one */
- minVal1 = *pSrc++;
- minVal2 = *pSrc++;
-
- /* compare for the minimum value */
- if(out > minVal1)
- {
- /* Update the minimum value and its index */
- out = minVal1;
- outIndex = count + 1u;
- }
-
- minVal1 = *pSrc++;
-
- /* compare for the minimum value */
- if(out > minVal2)
- {
- /* Update the minimum value and its index */
- out = minVal2;
- outIndex = count + 2u;
- }
-
- minVal2 = *pSrc++;
-
- /* compare for the minimum value */
- if(out > minVal1)
- {
- /* Update the minimum value and its index */
- out = minVal1;
- outIndex = count + 3u;
- }
-
- /* compare for the minimum value */
- if(out > minVal2)
- {
- /* Update the minimum value and its index */
- out = minVal2;
- outIndex = count + 4u;
- }
-
- count += 4u;
-
- blkCnt--;
- }
-
- /* if (blockSize - 1u ) is not multiple of 4 */
- blkCnt = (blockSize - 1u) % 4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- q7_t minVal1, out; /* Temporary variables to store the output value. */
- uint32_t blkCnt, outIndex; /* loop counter */
-
- /* Initialise the index value to zero. */
- outIndex = 0u;
- /* Load first input value that act as reference value for comparision */
- out = *pSrc++;
-
- blkCnt = (blockSize - 1u);
-
-#endif // #ifndef ARM_MATH_CM0_FAMILY
-
- while(blkCnt > 0)
- {
- /* Initialize minVal to the next consecutive values one by one */
- minVal1 = *pSrc++;
-
- /* compare for the minimum value */
- if(out > minVal1)
- {
- /* Update the minimum value and it's index */
- out = minVal1;
- outIndex = blockSize - blkCnt;
- }
-
- blkCnt--;
-
- }
-
- /* Store the minimum value and its index into destination pointers */
- *pResult = out;
- *pIndex = outIndex;
-
-
-}
-
-/**
- * @} end of Min group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_f32.c
deleted file mode 100644
index 831c5b0..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_f32.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_power_f32.c
-*
-* Description: Sum of the squares of the elements of a floating-point vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @defgroup power Power
- *
- * Calculates the sum of the squares of the elements in the input vector.
- * The underlying algorithm is used:
- *
- *
- * Result = pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + pSrc[2] * pSrc[2] + ... + pSrc[blockSize-1] * pSrc[blockSize-1];
- *
- *
- * There are separate functions for floating point, Q31, Q15, and Q7 data types.
- */
-
-/**
- * @addtogroup power
- * @{
- */
-
-
-/**
- * @brief Sum of the squares of the elements of a floating-point vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult sum of the squares value returned here
- * @return none.
- *
- */
-
-
-void arm_power_f32(
- float32_t * pSrc,
- uint32_t blockSize,
- float32_t * pResult)
-{
- float32_t sum = 0.0f; /* accumulator */
- float32_t in; /* Temporary variable to store input value */
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
- /* Compute Power and then store the result in a temporary variable, sum. */
- in = *pSrc++;
- sum += in * in;
- in = *pSrc++;
- sum += in * in;
- in = *pSrc++;
- sum += in * in;
- in = *pSrc++;
- sum += in * in;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
-
- while(blkCnt > 0u)
- {
- /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
- /* compute power and then store the result in a temporary variable, sum. */
- in = *pSrc++;
- sum += in * in;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Store the result to the destination */
- *pResult = sum;
-}
-
-/**
- * @} end of power group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_q15.c
deleted file mode 100644
index 6e7034a..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_q15.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_power_q15.c
-*
-* Description: Sum of the squares of the elements of a Q15 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @addtogroup power
- * @{
- */
-
-/**
- * @brief Sum of the squares of the elements of a Q15 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult sum of the squares value returned here
- * @return none.
- *
- * @details
- * Scaling and Overflow Behavior:
- *
- * \par
- * The function is implemented using a 64-bit internal accumulator.
- * The input is represented in 1.15 format.
- * Intermediate multiplication yields a 2.30 format, and this
- * result is added without saturation to a 64-bit accumulator in 34.30 format.
- * With 33 guard bits in the accumulator, there is no risk of overflow, and the
- * full precision of the intermediate multiplication is preserved.
- * Finally, the return result is in 34.30 format.
- *
- */
-
-void arm_power_q15(
- q15_t * pSrc,
- uint32_t blockSize,
- q63_t * pResult)
-{
- q63_t sum = 0; /* Temporary result storage */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- q31_t in32; /* Temporary variable to store input value */
- q15_t in16; /* Temporary variable to store input value */
- uint32_t blkCnt; /* loop counter */
-
-
- /* loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
- /* Compute Power and then store the result in a temporary variable, sum. */
- in32 = *__SIMD32(pSrc)++;
- sum = __SMLALD(in32, in32, sum);
- in32 = *__SIMD32(pSrc)++;
- sum = __SMLALD(in32, in32, sum);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
- while(blkCnt > 0u)
- {
- /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
- /* Compute Power and then store the result in a temporary variable, sum. */
- in16 = *pSrc++;
- sum = __SMLALD(in16, in16, sum);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- q15_t in; /* Temporary variable to store input value */
- uint32_t blkCnt; /* loop counter */
-
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
- while(blkCnt > 0u)
- {
- /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
- /* Compute Power and then store the result in a temporary variable, sum. */
- in = *pSrc++;
- sum += ((q31_t) in * in);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- /* Store the results in 34.30 format */
- *pResult = sum;
-}
-
-/**
- * @} end of power group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_q31.c
deleted file mode 100644
index 2f7976a..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_q31.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_power_q31.c
-*
-* Description: Sum of the squares of the elements of a Q31 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @addtogroup power
- * @{
- */
-
-/**
- * @brief Sum of the squares of the elements of a Q31 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult sum of the squares value returned here
- * @return none.
- *
- * @details
- * Scaling and Overflow Behavior:
- *
- * \par
- * The function is implemented using a 64-bit internal accumulator.
- * The input is represented in 1.31 format.
- * Intermediate multiplication yields a 2.62 format, and this
- * result is truncated to 2.48 format by discarding the lower 14 bits.
- * The 2.48 result is then added without saturation to a 64-bit accumulator in 16.48 format.
- * With 15 guard bits in the accumulator, there is no risk of overflow, and the
- * full precision of the intermediate multiplication is preserved.
- * Finally, the return result is in 16.48 format.
- *
- */
-
-void arm_power_q31(
- q31_t * pSrc,
- uint32_t blockSize,
- q63_t * pResult)
-{
- q63_t sum = 0; /* Temporary result storage */
- q31_t in;
- uint32_t blkCnt; /* loop counter */
-
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
- /* Compute Power then shift intermediate results by 14 bits to maintain 16.48 format and then store the result in a temporary variable sum, providing 15 guard bits. */
- in = *pSrc++;
- sum += ((q63_t) in * in) >> 14u;
-
- in = *pSrc++;
- sum += ((q63_t) in * in) >> 14u;
-
- in = *pSrc++;
- sum += ((q63_t) in * in) >> 14u;
-
- in = *pSrc++;
- sum += ((q63_t) in * in) >> 14u;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
- /* Compute Power and then store the result in a temporary variable, sum. */
- in = *pSrc++;
- sum += ((q63_t) in * in) >> 14u;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Store the results in 16.48 format */
- *pResult = sum;
-}
-
-/**
- * @} end of power group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_q7.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_q7.c
deleted file mode 100644
index 3e97f91..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_q7.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_power_q7.c
-*
-* Description: Sum of the squares of the elements of a Q7 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @addtogroup power
- * @{
- */
-
-/**
- * @brief Sum of the squares of the elements of a Q7 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult sum of the squares value returned here
- * @return none.
- *
- * @details
- * Scaling and Overflow Behavior:
- *
- * \par
- * The function is implemented using a 32-bit internal accumulator.
- * The input is represented in 1.7 format.
- * Intermediate multiplication yields a 2.14 format, and this
- * result is added without saturation to an accumulator in 18.14 format.
- * With 17 guard bits in the accumulator, there is no risk of overflow, and the
- * full precision of the intermediate multiplication is preserved.
- * Finally, the return result is in 18.14 format.
- *
- */
-
-void arm_power_q7(
- q7_t * pSrc,
- uint32_t blockSize,
- q31_t * pResult)
-{
- q31_t sum = 0; /* Temporary result storage */
- q7_t in; /* Temporary variable to store input */
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- q31_t input1; /* Temporary variable to store packed input */
- q31_t in1, in2; /* Temporary variables to store input */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* Reading two inputs of pSrc vector and packing */
- input1 = *__SIMD32(pSrc)++;
-
- in1 = __SXTB16(__ROR(input1, 8));
- in2 = __SXTB16(input1);
-
- /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
- /* calculate power and accumulate to accumulator */
- sum = __SMLAD(in1, in1, sum);
- sum = __SMLAD(in2, in2, sum);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
- /* Compute Power and then store the result in a temporary variable, sum. */
- in = *pSrc++;
- sum += ((q15_t) in * in);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Store the result in 18.14 format */
- *pResult = sum;
-}
-
-/**
- * @} end of power group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_f32.c
deleted file mode 100644
index 466d17b..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_f32.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_rms_f32.c
-*
-* Description: Root mean square value of an array of F32 type
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @defgroup RMS Root mean square (RMS)
- *
- *
- * Calculates the Root Mean Sqaure of the elements in the input vector.
- * The underlying algorithm is used:
- *
- *
- * Result = sqrt(((pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] * pSrc[blockSize-1]) / blockSize));
- *
- *
- * There are separate functions for floating point, Q31, and Q15 data types.
- */
-
-/**
- * @addtogroup RMS
- * @{
- */
-
-
-/**
- * @brief Root Mean Square of the elements of a floating-point vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult rms value returned here
- * @return none.
- *
- */
-
-void arm_rms_f32(
- float32_t * pSrc,
- uint32_t blockSize,
- float32_t * pResult)
-{
- float32_t sum = 0.0f; /* Accumulator */
- float32_t in; /* Tempoprary variable to store input value */
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /* loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
- /* Compute sum of the squares and then store the result in a temporary variable, sum */
- in = *pSrc++;
- sum += in * in;
- in = *pSrc++;
- sum += in * in;
- in = *pSrc++;
- sum += in * in;
- in = *pSrc++;
- sum += in * in;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
- /* Compute sum of the squares and then store the results in a temporary variable, sum */
- in = *pSrc++;
- sum += in * in;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Compute Rms and store the result in the destination */
- arm_sqrt_f32(sum / (float32_t) blockSize, pResult);
-}
-
-/**
- * @} end of RMS group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_q15.c
deleted file mode 100644
index 74372be..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_q15.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_rms_q15.c
-*
-* Description: Root Mean Square of the elements of a Q15 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @addtogroup RMS
- * @{
- */
-
-/**
- * @brief Root Mean Square of the elements of a Q15 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult rms value returned here
- * @return none.
- *
- * @details
- * Scaling and Overflow Behavior:
- *
- * \par
- * The function is implemented using a 64-bit internal accumulator.
- * The input is represented in 1.15 format.
- * Intermediate multiplication yields a 2.30 format, and this
- * result is added without saturation to a 64-bit accumulator in 34.30 format.
- * With 33 guard bits in the accumulator, there is no risk of overflow, and the
- * full precision of the intermediate multiplication is preserved.
- * Finally, the 34.30 result is truncated to 34.15 format by discarding the lower
- * 15 bits, and then saturated to yield a result in 1.15 format.
- *
- */
-
-void arm_rms_q15(
- q15_t * pSrc,
- uint32_t blockSize,
- q15_t * pResult)
-{
- q63_t sum = 0; /* accumulator */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- q31_t in; /* temporary variable to store the input value */
- q15_t in1; /* temporary variable to store the input value */
- uint32_t blkCnt; /* loop counter */
-
- /* loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute sum of the squares and then store the results in a temporary variable, sum */
- in = *__SIMD32(pSrc)++;
- sum = __SMLALD(in, in, sum);
- in = *__SIMD32(pSrc)++;
- sum = __SMLALD(in, in, sum);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute sum of the squares and then store the results in a temporary variable, sum */
- in1 = *pSrc++;
- sum = __SMLALD(in1, in1, sum);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Truncating and saturating the accumulator to 1.15 format */
- /* Store the result in the destination */
- arm_sqrt_q15(__SSAT((sum / (q63_t)blockSize) >> 15, 16), pResult);
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- q15_t in; /* temporary variable to store the input value */
- uint32_t blkCnt; /* loop counter */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute sum of the squares and then store the results in a temporary variable, sum */
- in = *pSrc++;
- sum += ((q31_t) in * in);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Truncating and saturating the accumulator to 1.15 format */
- /* Store the result in the destination */
- arm_sqrt_q15(__SSAT((sum / (q63_t)blockSize) >> 15, 16), pResult);
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
-}
-
-/**
- * @} end of RMS group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_q31.c
deleted file mode 100644
index 7072e19..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_q31.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_rms_q31.c
-*
-* Description: Root Mean Square of the elements of a Q31 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @addtogroup RMS
- * @{
- */
-
-
-/**
- * @brief Root Mean Square of the elements of a Q31 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult rms value returned here
- * @return none.
- *
- * @details
- * Scaling and Overflow Behavior:
- *
- *\par
- * The function is implemented using an internal 64-bit accumulator.
- * The input is represented in 1.31 format, and intermediate multiplication
- * yields a 2.62 format.
- * The accumulator maintains full precision of the intermediate multiplication results,
- * but provides only a single guard bit.
- * There is no saturation on intermediate additions.
- * If the accumulator overflows, it wraps around and distorts the result.
- * In order to avoid overflows completely, the input signal must be scaled down by
- * log2(blockSize) bits, as a total of blockSize additions are performed internally.
- * Finally, the 2.62 accumulator is right shifted by 31 bits to yield a 1.31 format value.
- *
- */
-
-void arm_rms_q31(
- q31_t * pSrc,
- uint32_t blockSize,
- q31_t * pResult)
-{
- q63_t sum = 0; /* accumulator */
- q31_t in; /* Temporary variable to store the input */
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- q31_t in1, in2, in3, in4; /* Temporary input variables */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 8 outputs at a time.
- ** a second loop below computes the remaining 1 to 7 samples. */
- while(blkCnt > 0u)
- {
- /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
- /* Compute sum of the squares and then store the result in a temporary variable, sum */
- /* read two samples from source buffer */
- in1 = pSrc[0];
- in2 = pSrc[1];
-
- /* calculate power and accumulate to accumulator */
- sum += (q63_t) in1 *in1;
- sum += (q63_t) in2 *in2;
-
- /* read two samples from source buffer */
- in3 = pSrc[2];
- in4 = pSrc[3];
-
- /* calculate power and accumulate to accumulator */
- sum += (q63_t) in3 *in3;
- sum += (q63_t) in4 *in4;
-
-
- /* update source buffer to process next samples */
- pSrc += 4u;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 8, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
- /* Compute sum of the squares and then store the results in a temporary variable, sum */
- in = *pSrc++;
- sum += (q63_t) in *in;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Convert data in 2.62 to 1.31 by 31 right shifts and saturate */
- /* Compute Rms and store the result in the destination vector */
- arm_sqrt_q31(clip_q63_to_q31((sum / (q63_t) blockSize) >> 31), pResult);
-}
-
-/**
- * @} end of RMS group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_f32.c
deleted file mode 100644
index 2483ada..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_f32.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_std_f32.c
-*
-* Description: Standard deviation of the elements of a floating-point vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @defgroup STD Standard deviation
- *
- * Calculates the standard deviation of the elements in the input vector.
- * The underlying algorithm is used:
- *
- *
- * Result = sqrt((sumOfSquares - sum2 / blockSize) / (blockSize - 1))
- *
- * where, sumOfSquares = pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] * pSrc[blockSize-1]
- *
- * sum = pSrc[0] + pSrc[1] + pSrc[2] + ... + pSrc[blockSize-1]
- *
- *
- * There are separate functions for floating point, Q31, and Q15 data types.
- */
-
-/**
- * @addtogroup STD
- * @{
- */
-
-
-/**
- * @brief Standard deviation of the elements of a floating-point vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult standard deviation value returned here
- * @return none.
- *
- */
-
-
-void arm_std_f32(
- float32_t * pSrc,
- uint32_t blockSize,
- float32_t * pResult)
-{
- float32_t sum = 0.0f; /* Temporary result storage */
- float32_t sumOfSquares = 0.0f; /* Sum of squares */
- float32_t in; /* input value */
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- float32_t meanOfSquares, mean, squareOfMean;
-
- if(blockSize == 1)
- {
- *pResult = 0;
- return;
- }
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute Sum of squares of the input samples
- * and then store the result in a temporary variable, sum. */
- in = *pSrc++;
- sum += in;
- sumOfSquares += in * in;
- in = *pSrc++;
- sum += in;
- sumOfSquares += in * in;
- in = *pSrc++;
- sum += in;
- sumOfSquares += in * in;
- in = *pSrc++;
- sum += in;
- sumOfSquares += in * in;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute Sum of squares of the input samples
- * and then store the result in a temporary variable, sum. */
- in = *pSrc++;
- sum += in;
- sumOfSquares += in * in;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Compute Mean of squares of the input samples
- * and then store the result in a temporary variable, meanOfSquares. */
- meanOfSquares = sumOfSquares / ((float32_t) blockSize - 1.0f);
-
- /* Compute mean of all input values */
- mean = sum / (float32_t) blockSize;
-
- /* Compute square of mean */
- squareOfMean = (mean * mean) * (((float32_t) blockSize) /
- ((float32_t) blockSize - 1.0f));
-
- /* Compute standard deviation and then store the result to the destination */
- arm_sqrt_f32((meanOfSquares - squareOfMean), pResult);
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- float32_t squareOfSum; /* Square of Sum */
- float32_t var; /* Temporary varaince storage */
-
- if(blockSize == 1)
- {
- *pResult = 0;
- return;
- }
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute Sum of squares of the input samples
- * and then store the result in a temporary variable, sumOfSquares. */
- in = *pSrc++;
- sumOfSquares += in * in;
-
- /* C = (A[0] + A[1] + ... + A[blockSize-1]) */
- /* Compute Sum of the input samples
- * and then store the result in a temporary variable, sum. */
- sum += in;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Compute the square of sum */
- squareOfSum = ((sum * sum) / (float32_t) blockSize);
-
- /* Compute the variance */
- var = ((sumOfSquares - squareOfSum) / (float32_t) (blockSize - 1.0f));
-
- /* Compute standard deviation and then store the result to the destination */
- arm_sqrt_f32(var, pResult);
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
-}
-
-/**
- * @} end of STD group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_q15.c
deleted file mode 100644
index f113099..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_q15.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_std_q15.c
-*
-* Description: Standard deviation of an array of Q15 type.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @addtogroup STD
- * @{
- */
-
-/**
- * @brief Standard deviation of the elements of a Q15 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult standard deviation value returned here
- * @return none.
- *
- * @details
- * Scaling and Overflow Behavior:
- *
- * \par
- * The function is implemented using a 64-bit internal accumulator.
- * The input is represented in 1.15 format.
- * Intermediate multiplication yields a 2.30 format, and this
- * result is added without saturation to a 64-bit accumulator in 34.30 format.
- * With 33 guard bits in the accumulator, there is no risk of overflow, and the
- * full precision of the intermediate multiplication is preserved.
- * Finally, the 34.30 result is truncated to 34.15 format by discarding the lower
- * 15 bits, and then saturated to yield a result in 1.15 format.
- */
-
-void arm_std_q15(
- q15_t * pSrc,
- uint32_t blockSize,
- q15_t * pResult)
-{
- q31_t sum = 0; /* Accumulator */
- q31_t meanOfSquares, squareOfMean; /* square of mean and mean of square */
- uint32_t blkCnt; /* loop counter */
- q63_t sumOfSquares = 0; /* Accumulator */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- q31_t in; /* input value */
- q15_t in1; /* input value */
-
- if(blockSize == 1)
- {
- *pResult = 0;
- return;
- }
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute Sum of squares of the input samples
- * and then store the result in a temporary variable, sum. */
- in = *__SIMD32(pSrc)++;
- sum += ((in << 16) >> 16);
- sum += (in >> 16);
- sumOfSquares = __SMLALD(in, in, sumOfSquares);
- in = *__SIMD32(pSrc)++;
- sum += ((in << 16) >> 16);
- sum += (in >> 16);
- sumOfSquares = __SMLALD(in, in, sumOfSquares);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute Sum of squares of the input samples
- * and then store the result in a temporary variable, sum. */
- in1 = *pSrc++;
- sumOfSquares = __SMLALD(in1, in1, sumOfSquares);
- sum += in1;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Compute Mean of squares of the input samples
- * and then store the result in a temporary variable, meanOfSquares. */
- meanOfSquares = (q31_t)(sumOfSquares / (q63_t)(blockSize - 1));
-
- /* Compute square of mean */
- squareOfMean = (q31_t) ((q63_t)sum * sum / (q63_t)(blockSize * (blockSize - 1)));
-
- /* mean of the squares minus the square of the mean. */
- /* Compute standard deviation and store the result to the destination */
- arm_sqrt_q15(__SSAT((meanOfSquares - squareOfMean) >> 15, 16u), pResult);
-
-#else
-
- /* Run the below code for Cortex-M0 */
- q15_t in; /* input value */
-
- if(blockSize == 1)
- {
- *pResult = 0;
- return;
- }
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute Sum of squares of the input samples
- * and then store the result in a temporary variable, sumOfSquares. */
- in = *pSrc++;
- sumOfSquares += (in * in);
-
- /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
- /* Compute sum of all input values and then store the result in a temporary variable, sum. */
- sum += in;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Compute Mean of squares of the input samples
- * and then store the result in a temporary variable, meanOfSquares. */
- meanOfSquares = (q31_t)(sumOfSquares / (q63_t)(blockSize - 1));
-
- /* Compute square of mean */
- squareOfMean = (q31_t) ((q63_t)sum * sum / (q63_t)(blockSize * (blockSize - 1)));
-
- /* mean of the squares minus the square of the mean. */
- /* Compute standard deviation and store the result to the destination */
- arm_sqrt_q15(__SSAT((meanOfSquares - squareOfMean) >> 15, 16u), pResult);
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
-
-}
-
-/**
- * @} end of STD group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_q31.c
deleted file mode 100644
index f2518c5..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_q31.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_std_q31.c
-*
-* Description: Standard deviation of an array of Q31 type.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @addtogroup STD
- * @{
- */
-
-
-/**
- * @brief Standard deviation of the elements of a Q31 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult standard deviation value returned here
- * @return none.
- * @details
- * Scaling and Overflow Behavior:
- *
- *\par
- * The function is implemented using an internal 64-bit accumulator.
- * The input is represented in 1.31 format, which is then downshifted by 8 bits
- * which yields 1.23, and intermediate multiplication yields a 2.46 format.
- * The accumulator maintains full precision of the intermediate multiplication results,
- * but provides only a 16 guard bits.
- * There is no saturation on intermediate additions.
- * If the accumulator overflows it wraps around and distorts the result.
- * In order to avoid overflows completely the input signal must be scaled down by
- * log2(blockSize)-8 bits, as a total of blockSize additions are performed internally.
- * After division, internal variables should be Q18.46
- * Finally, the 18.46 accumulator is right shifted by 15 bits to yield a 1.31 format value.
- *
- */
-
-
-void arm_std_q31(
- q31_t * pSrc,
- uint32_t blockSize,
- q31_t * pResult)
-{
- q63_t sum = 0; /* Accumulator */
- q63_t meanOfSquares, squareOfMean; /* square of mean and mean of square */
- q31_t in; /* input value */
- uint32_t blkCnt; /* loop counter */
- q63_t sumOfSquares = 0; /* Accumulator */
-
- if(blockSize == 1)
- {
- *pResult = 0;
- return;
- }
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute Sum of squares of the input samples
- * and then store the result in a temporary variable, sum. */
- in = *pSrc++ >> 8;
- sum += in;
- sumOfSquares += ((q63_t) (in) * (in));
- in = *pSrc++ >> 8;
- sum += in;
- sumOfSquares += ((q63_t) (in) * (in));
- in = *pSrc++ >> 8;
- sum += in;
- sumOfSquares += ((q63_t) (in) * (in));
- in = *pSrc++ >> 8;
- sum += in;
- sumOfSquares += ((q63_t) (in) * (in));
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute Sum of squares of the input samples
- * and then store the result in a temporary variable, sum. */
- in = *pSrc++ >> 8;
- sum += in;
- sumOfSquares += ((q63_t) (in) * (in));
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Compute Mean of squares of the input samples
- * and then store the result in a temporary variable, meanOfSquares. */
- meanOfSquares = sumOfSquares / (q63_t)(blockSize - 1);
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute Sum of squares of the input samples
- * and then store the result in a temporary variable, sumOfSquares. */
- in = *pSrc++ >> 8;
- sumOfSquares += ((q63_t) (in) * (in));
-
- /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
- /* Compute sum of all input values and then store the result in a temporary variable, sum. */
- sum += in;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Compute Mean of squares of the input samples
- * and then store the result in a temporary variable, meanOfSquares. */
- meanOfSquares = sumOfSquares / (q63_t)(blockSize - 1);
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- /* Compute square of mean */
- squareOfMean = sum * sum / (q63_t)(blockSize * (blockSize - 1u));
-
- /* Compute standard deviation and then store the result to the destination */
- arm_sqrt_q31((meanOfSquares - squareOfMean) >> 15, pResult);
-
-}
-
-/**
- * @} end of STD group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_var_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_var_f32.c
deleted file mode 100644
index aff478d..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_var_f32.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_var_f32.c
-*
-* Description: Variance of the elements of a floating-point vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @defgroup variance Variance
- *
- * Calculates the variance of the elements in the input vector.
- * The underlying algorithm is used:
- *
- *
- * Result = (sumOfSquares - sum2 / blockSize) / (blockSize - 1)
- *
- * where, sumOfSquares = pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] * pSrc[blockSize-1]
- *
- * sum = pSrc[0] + pSrc[1] + pSrc[2] + ... + pSrc[blockSize-1]
- *
- *
- * There are separate functions for floating point, Q31, and Q15 data types.
- */
-
-/**
- * @addtogroup variance
- * @{
- */
-
-
-/**
- * @brief Variance of the elements of a floating-point vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult variance value returned here
- * @return none.
- *
- */
-
-
-void arm_var_f32(
- float32_t * pSrc,
- uint32_t blockSize,
- float32_t * pResult)
-{
-
- float32_t sum = 0.0f; /* Temporary result storage */
- float32_t sumOfSquares = 0.0f; /* Sum of squares */
- float32_t in; /* input value */
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- float32_t meanOfSquares, mean, squareOfMean; /* Temporary variables */
-
- if(blockSize == 1)
- {
- *pResult = 0;
- return;
- }
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute Sum of squares of the input samples
- * and then store the result in a temporary variable, sum. */
- in = *pSrc++;
- sum += in;
- sumOfSquares += in * in;
- in = *pSrc++;
- sum += in;
- sumOfSquares += in * in;
- in = *pSrc++;
- sum += in;
- sumOfSquares += in * in;
- in = *pSrc++;
- sum += in;
- sumOfSquares += in * in;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute Sum of squares of the input samples
- * and then store the result in a temporary variable, sum. */
- in = *pSrc++;
- sum += in;
- sumOfSquares += in * in;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Compute Mean of squares of the input samples
- * and then store the result in a temporary variable, meanOfSquares. */
- meanOfSquares = sumOfSquares / ((float32_t) blockSize - 1.0f);
-
- /* Compute mean of all input values */
- mean = sum / (float32_t) blockSize;
-
- /* Compute square of mean */
- squareOfMean = (mean * mean) * (((float32_t) blockSize) /
- ((float32_t) blockSize - 1.0f));
-
- /* Compute variance and then store the result to the destination */
- *pResult = meanOfSquares - squareOfMean;
-
-#else
-
- /* Run the below code for Cortex-M0 */
- float32_t squareOfSum; /* Square of Sum */
-
- if(blockSize == 1)
- {
- *pResult = 0;
- return;
- }
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute Sum of squares of the input samples
- * and then store the result in a temporary variable, sumOfSquares. */
- in = *pSrc++;
- sumOfSquares += in * in;
-
- /* C = (A[0] + A[1] + ... + A[blockSize-1]) */
- /* Compute Sum of the input samples
- * and then store the result in a temporary variable, sum. */
- sum += in;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Compute the square of sum */
- squareOfSum = ((sum * sum) / (float32_t) blockSize);
-
- /* Compute the variance */
- *pResult = ((sumOfSquares - squareOfSum) / (float32_t) (blockSize - 1.0f));
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
-}
-
-/**
- * @} end of variance group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_var_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_var_q15.c
deleted file mode 100644
index d304cfb..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_var_q15.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_var_q15.c
-*
-* Description: Variance of an array of Q15 type.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @addtogroup variance
- * @{
- */
-
-/**
- * @brief Variance of the elements of a Q15 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult variance value returned here
- * @return none.
- *
- * @details
- * Scaling and Overflow Behavior:
- *
- * \par
- * The function is implemented using a 64-bit internal accumulator.
- * The input is represented in 1.15 format.
- * Intermediate multiplication yields a 2.30 format, and this
- * result is added without saturation to a 64-bit accumulator in 34.30 format.
- * With 33 guard bits in the accumulator, there is no risk of overflow, and the
- * full precision of the intermediate multiplication is preserved.
- * Finally, the 34.30 result is truncated to 34.15 format by discarding the lower
- * 15 bits, and then saturated to yield a result in 1.15 format.
- *
- */
-
-
-void arm_var_q15(
- q15_t * pSrc,
- uint32_t blockSize,
- q15_t * pResult)
-{
-
- q31_t sum = 0; /* Accumulator */
- q31_t meanOfSquares, squareOfMean; /* square of mean and mean of square */
- uint32_t blkCnt; /* loop counter */
- q63_t sumOfSquares = 0; /* Accumulator */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- q31_t in; /* input value */
- q15_t in1; /* input value */
-
- if(blockSize == 1)
- {
- *pResult = 0;
- return;
- }
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute Sum of squares of the input samples
- * and then store the result in a temporary variable, sum. */
- in = *__SIMD32(pSrc)++;
- sum += ((in << 16) >> 16);
- sum += (in >> 16);
- sumOfSquares = __SMLALD(in, in, sumOfSquares);
- in = *__SIMD32(pSrc)++;
- sum += ((in << 16) >> 16);
- sum += (in >> 16);
- sumOfSquares = __SMLALD(in, in, sumOfSquares);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute Sum of squares of the input samples
- * and then store the result in a temporary variable, sum. */
- in1 = *pSrc++;
- sumOfSquares = __SMLALD(in1, in1, sumOfSquares);
- sum += in1;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Compute Mean of squares of the input samples
- * and then store the result in a temporary variable, meanOfSquares. */
- meanOfSquares = (q31_t) (sumOfSquares / (q63_t)(blockSize - 1));
-
- /* Compute square of mean */
- squareOfMean = (q31_t)((q63_t)sum * sum / (q63_t)(blockSize * (blockSize - 1)));
-
- /* mean of the squares minus the square of the mean. */
- *pResult = (meanOfSquares - squareOfMean) >> 15;
-
-#else
-
- /* Run the below code for Cortex-M0 */
- q15_t in; /* input value */
-
- if(blockSize == 1)
- {
- *pResult = 0;
- return;
- }
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute Sum of squares of the input samples
- * and then store the result in a temporary variable, sumOfSquares. */
- in = *pSrc++;
- sumOfSquares += (in * in);
-
- /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
- /* Compute sum of all input values and then store the result in a temporary variable, sum. */
- sum += in;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Compute Mean of squares of the input samples
- * and then store the result in a temporary variable, meanOfSquares. */
- meanOfSquares = (q31_t) (sumOfSquares / (q63_t)(blockSize - 1));
-
- /* Compute square of mean */
- squareOfMean = (q31_t)((q63_t)sum * sum / (q63_t)(blockSize * (blockSize - 1)));
-
- /* mean of the squares minus the square of the mean. */
- *pResult = (meanOfSquares - squareOfMean) >> 15;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
-}
-
-/**
- * @} end of variance group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_var_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_var_q31.c
deleted file mode 100644
index 6bd0de8..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_var_q31.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_var_q31.c
-*
-* Description: Variance of an array of Q31 type.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupStats
- */
-
-/**
- * @addtogroup variance
- * @{
- */
-
-/**
- * @brief Variance of the elements of a Q31 vector.
- * @param[in] *pSrc points to the input vector
- * @param[in] blockSize length of the input vector
- * @param[out] *pResult variance value returned here
- * @return none.
- *
- * @details
- * Scaling and Overflow Behavior:
- *
- *\par
- * The function is implemented using an internal 64-bit accumulator.
- * The input is represented in 1.31 format, which is then downshifted by 8 bits
- * which yields 1.23, and intermediate multiplication yields a 2.46 format.
- * The accumulator maintains full precision of the intermediate multiplication results,
- * but provides only a 16 guard bits.
- * There is no saturation on intermediate additions.
- * If the accumulator overflows it wraps around and distorts the result.
- * In order to avoid overflows completely the input signal must be scaled down by
- * log2(blockSize)-8 bits, as a total of blockSize additions are performed internally.
- * After division, internal variables should be Q18.46
- * Finally, the 18.46 accumulator is right shifted by 15 bits to yield a 1.31 format value.
- *
- */
-
-
-void arm_var_q31(
- q31_t * pSrc,
- uint32_t blockSize,
- q31_t * pResult)
-{
- q63_t sum = 0; /* Accumulator */
- q63_t meanOfSquares, squareOfMean; /* square of mean and mean of square */
- q31_t in; /* input value */
- uint32_t blkCnt; /* loop counter */
- q63_t sumOfSquares = 0; /* Accumulator */
-
- if(blockSize == 1)
- {
- *pResult = 0;
- return;
- }
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute Sum of squares of the input samples
- * and then store the result in a temporary variable, sum. */
- in = *pSrc++ >> 8;
- sum += in;
- sumOfSquares += ((q63_t) (in) * (in));
- in = *pSrc++ >> 8;
- sum += in;
- sumOfSquares += ((q63_t) (in) * (in));
- in = *pSrc++ >> 8;
- sum += in;
- sumOfSquares += ((q63_t) (in) * (in));
- in = *pSrc++ >> 8;
- sum += in;
- sumOfSquares += ((q63_t) (in) * (in));
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute Sum of squares of the input samples
- * and then store the result in a temporary variable, sum. */
- in = *pSrc++ >> 8;
- sum += in;
- sumOfSquares += ((q63_t) (in) * (in));
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Compute Mean of squares of the input samples
- * and then store the result in a temporary variable, meanOfSquares. */
- meanOfSquares = sumOfSquares / (q63_t)(blockSize - 1);
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
- while(blkCnt > 0u)
- {
- /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
- /* Compute Sum of squares of the input samples
- * and then store the result in a temporary variable, sumOfSquares. */
- in = *pSrc++ >> 8;
- sumOfSquares += ((q63_t) (in) * (in));
-
- /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
- /* Compute sum of all input values and then store the result in a temporary variable, sum. */
- sum += in;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* Compute Mean of squares of the input samples
- * and then store the result in a temporary variable, meanOfSquares. */
- meanOfSquares = sumOfSquares / (q63_t)(blockSize - 1);
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- /* Compute square of mean */
- squareOfMean = sum * sum / (q63_t)(blockSize * (blockSize - 1u));
-
-
- /* Compute standard deviation and then store the result to the destination */
- *pResult = (meanOfSquares - squareOfMean) >> 15;
-
-}
-
-/**
- * @} end of variance group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_f32.c
deleted file mode 100644
index bdbdff5..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_f32.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/* ----------------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_copy_f32.c
-*
-* Description: Copies the elements of a floating-point vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @defgroup copy Vector Copy
- *
- * Copies sample by sample from source vector to destination vector.
- *
- *
- * pDst[n] = pSrc[n]; 0 <= n < blockSize.
- *
- *
- * There are separate functions for floating point, Q31, Q15, and Q7 data types.
- */
-
-/**
- * @addtogroup copy
- * @{
- */
-
-/**
- * @brief Copies the elements of a floating-point vector.
- * @param[in] *pSrc points to input vector
- * @param[out] *pDst points to output vector
- * @param[in] blockSize length of the input vector
- * @return none.
- *
- */
-
-
-void arm_copy_f32(
- float32_t * pSrc,
- float32_t * pDst,
- uint32_t blockSize)
-{
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- float32_t in1, in2, in3, in4;
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = A */
- /* Copy and then store the results in the destination buffer */
- in1 = *pSrc++;
- in2 = *pSrc++;
- in3 = *pSrc++;
- in4 = *pSrc++;
-
- *pDst++ = in1;
- *pDst++ = in2;
- *pDst++ = in3;
- *pDst++ = in4;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = A */
- /* Copy and then store the results in the destination buffer */
- *pDst++ = *pSrc++;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-}
-
-/**
- * @} end of BasicCopy group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_q15.c
deleted file mode 100644
index 2d152c0..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_q15.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_copy_q15.c
-*
-* Description: Copies the elements of a Q15 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @addtogroup copy
- * @{
- */
-/**
- * @brief Copies the elements of a Q15 vector.
- * @param[in] *pSrc points to input vector
- * @param[out] *pDst points to output vector
- * @param[in] blockSize length of the input vector
- * @return none.
- *
- */
-
-void arm_copy_q15(
- q15_t * pSrc,
- q15_t * pDst,
- uint32_t blockSize)
-{
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = A */
- /* Read two inputs */
- *__SIMD32(pDst)++ = *__SIMD32(pSrc)++;
- *__SIMD32(pDst)++ = *__SIMD32(pSrc)++;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = A */
- /* Copy and then store the value in the destination buffer */
- *pDst++ = *pSrc++;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-}
-
-/**
- * @} end of BasicCopy group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_q31.c
deleted file mode 100644
index 7dec928..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_q31.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_copy_q31.c
-*
-* Description: Copies the elements of a Q31 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @addtogroup copy
- * @{
- */
-
-/**
- * @brief Copies the elements of a Q31 vector.
- * @param[in] *pSrc points to input vector
- * @param[out] *pDst points to output vector
- * @param[in] blockSize length of the input vector
- * @return none.
- *
- */
-
-void arm_copy_q31(
- q31_t * pSrc,
- q31_t * pDst,
- uint32_t blockSize)
-{
- uint32_t blkCnt; /* loop counter */
-
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t in1, in2, in3, in4;
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = A */
- /* Copy and then store the values in the destination buffer */
- in1 = *pSrc++;
- in2 = *pSrc++;
- in3 = *pSrc++;
- in4 = *pSrc++;
-
- *pDst++ = in1;
- *pDst++ = in2;
- *pDst++ = in3;
- *pDst++ = in4;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = A */
- /* Copy and then store the value in the destination buffer */
- *pDst++ = *pSrc++;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-}
-
-/**
- * @} end of BasicCopy group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_q7.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_q7.c
deleted file mode 100644
index 69c42cb..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_q7.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_copy_q7.c
-*
-* Description: Copies the elements of a Q7 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @addtogroup copy
- * @{
- */
-
-/**
- * @brief Copies the elements of a Q7 vector.
- * @param[in] *pSrc points to input vector
- * @param[out] *pDst points to output vector
- * @param[in] blockSize length of the input vector
- * @return none.
- *
- */
-
-void arm_copy_q7(
- q7_t * pSrc,
- q7_t * pDst,
- uint32_t blockSize)
-{
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = A */
- /* Copy and then store the results in the destination buffer */
- /* 4 samples are copied and stored at a time using SIMD */
- *__SIMD32(pDst)++ = *__SIMD32(pSrc)++;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
-
- while(blkCnt > 0u)
- {
- /* C = A */
- /* Copy and then store the results in the destination buffer */
- *pDst++ = *pSrc++;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-}
-
-/**
- * @} end of BasicCopy group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_f32.c
deleted file mode 100644
index a284f88..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_f32.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_fill_f32.c
-*
-* Description: Fills a constant value into a floating-point vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @defgroup Fill Vector Fill
- *
- * Fills the destination vector with a constant value.
- *
- *
- * pDst[n] = value; 0 <= n < blockSize.
- *
- *
- * There are separate functions for floating point, Q31, Q15, and Q7 data types.
- */
-
-/**
- * @addtogroup Fill
- * @{
- */
-
-/**
- * @brief Fills a constant value into a floating-point vector.
- * @param[in] value input value to be filled
- * @param[out] *pDst points to output vector
- * @param[in] blockSize length of the output vector
- * @return none.
- *
- */
-
-
-void arm_fill_f32(
- float32_t value,
- float32_t * pDst,
- uint32_t blockSize)
-{
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- float32_t in1 = value;
- float32_t in2 = value;
- float32_t in3 = value;
- float32_t in4 = value;
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = value */
- /* Fill the value in the destination buffer */
- *pDst++ = in1;
- *pDst++ = in2;
- *pDst++ = in3;
- *pDst++ = in4;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
-
- while(blkCnt > 0u)
- {
- /* C = value */
- /* Fill the value in the destination buffer */
- *pDst++ = value;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-}
-
-/**
- * @} end of Fill group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_q15.c
deleted file mode 100644
index 817b127..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_q15.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_fill_q15.c
-*
-* Description: Fills a constant value into a Q15 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @addtogroup Fill
- * @{
- */
-
-/**
- * @brief Fills a constant value into a Q15 vector.
- * @param[in] value input value to be filled
- * @param[out] *pDst points to output vector
- * @param[in] blockSize length of the output vector
- * @return none.
- *
- */
-
-void arm_fill_q15(
- q15_t value,
- q15_t * pDst,
- uint32_t blockSize)
-{
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- q31_t packedValue; /* value packed to 32 bits */
-
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* Packing two 16 bit values to 32 bit value in order to use SIMD */
- packedValue = __PKHBT(value, value, 16u);
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = value */
- /* Fill the value in the destination buffer */
- *__SIMD32(pDst)++ = packedValue;
- *__SIMD32(pDst)++ = packedValue;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = value */
- /* Fill the value in the destination buffer */
- *pDst++ = value;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-}
-
-/**
- * @} end of Fill group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_q31.c
deleted file mode 100644
index 0b773c9..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_q31.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_fill_q31.c
-*
-* Description: Fills a constant value into a Q31 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @addtogroup Fill
- * @{
- */
-
-/**
- * @brief Fills a constant value into a Q31 vector.
- * @param[in] value input value to be filled
- * @param[out] *pDst points to output vector
- * @param[in] blockSize length of the output vector
- * @return none.
- *
- */
-
-void arm_fill_q31(
- q31_t value,
- q31_t * pDst,
- uint32_t blockSize)
-{
- uint32_t blkCnt; /* loop counter */
-
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t in1 = value;
- q31_t in2 = value;
- q31_t in3 = value;
- q31_t in4 = value;
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = value */
- /* Fill the value in the destination buffer */
- *pDst++ = in1;
- *pDst++ = in2;
- *pDst++ = in3;
- *pDst++ = in4;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = value */
- /* Fill the value in the destination buffer */
- *pDst++ = value;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-}
-
-/**
- * @} end of Fill group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_q7.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_q7.c
deleted file mode 100644
index 0dde606..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_q7.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_fill_q7.c
-*
-* Description: Fills a constant value into a Q7 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @addtogroup Fill
- * @{
- */
-
-/**
- * @brief Fills a constant value into a Q7 vector.
- * @param[in] value input value to be filled
- * @param[out] *pDst points to output vector
- * @param[in] blockSize length of the output vector
- * @return none.
- *
- */
-
-void arm_fill_q7(
- q7_t value,
- q7_t * pDst,
- uint32_t blockSize)
-{
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- q31_t packedValue; /* value packed to 32 bits */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* Packing four 8 bit values to 32 bit value in order to use SIMD */
- packedValue = __PACKq7(value, value, value, value);
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = value */
- /* Fill the value in the destination buffer */
- *__SIMD32(pDst)++ = packedValue;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = value */
- /* Fill the value in the destination buffer */
- *pDst++ = value;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-}
-
-/**
- * @} end of Fill group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_float_to_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_float_to_q15.c
deleted file mode 100644
index cdc53a5..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_float_to_q15.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/* ----------------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_float_to_q15.c
-*
-* Description: Converts the elements of the floating-point vector to Q15 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @addtogroup float_to_x
- * @{
- */
-
-/**
- * @brief Converts the elements of the floating-point vector to Q15 vector.
- * @param[in] *pSrc points to the floating-point input vector
- * @param[out] *pDst points to the Q15 output vector
- * @param[in] blockSize length of the input vector
- * @return none.
- *
- * \par Description:
- * \par
- * The equation used for the conversion process is:
- *
- * pDst[n] = (q15_t)(pSrc[n] * 32768); 0 <= n < blockSize.
- *
- * \par Scaling and Overflow Behavior:
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
- * \note
- * In order to apply rounding, the library should be rebuilt with the ROUNDING macro
- * defined in the preprocessor section of project options.
- *
- */
-
-
-void arm_float_to_q15(
- float32_t * pSrc,
- q15_t * pDst,
- uint32_t blockSize)
-{
- float32_t *pIn = pSrc; /* Src pointer */
- uint32_t blkCnt; /* loop counter */
-
-#ifdef ARM_MATH_ROUNDING
-
- float32_t in;
-
-#endif /* #ifdef ARM_MATH_ROUNDING */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
-
-#ifdef ARM_MATH_ROUNDING
- /* C = A * 32768 */
- /* convert from float to q15 and then store the results in the destination buffer */
- in = *pIn++;
- in = (in * 32768.0f);
- in += in > 0.0f ? 0.5f : -0.5f;
- *pDst++ = (q15_t) (__SSAT((q31_t) (in), 16));
-
- in = *pIn++;
- in = (in * 32768.0f);
- in += in > 0.0f ? 0.5f : -0.5f;
- *pDst++ = (q15_t) (__SSAT((q31_t) (in), 16));
-
- in = *pIn++;
- in = (in * 32768.0f);
- in += in > 0.0f ? 0.5f : -0.5f;
- *pDst++ = (q15_t) (__SSAT((q31_t) (in), 16));
-
- in = *pIn++;
- in = (in * 32768.0f);
- in += in > 0.0f ? 0.5f : -0.5f;
- *pDst++ = (q15_t) (__SSAT((q31_t) (in), 16));
-
-#else
-
- /* C = A * 32768 */
- /* convert from float to q15 and then store the results in the destination buffer */
- *pDst++ = (q15_t) __SSAT((q31_t) (*pIn++ * 32768.0f), 16);
- *pDst++ = (q15_t) __SSAT((q31_t) (*pIn++ * 32768.0f), 16);
- *pDst++ = (q15_t) __SSAT((q31_t) (*pIn++ * 32768.0f), 16);
- *pDst++ = (q15_t) __SSAT((q31_t) (*pIn++ * 32768.0f), 16);
-
-#endif /* #ifdef ARM_MATH_ROUNDING */
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
- while(blkCnt > 0u)
- {
-
-#ifdef ARM_MATH_ROUNDING
- /* C = A * 32768 */
- /* convert from float to q15 and then store the results in the destination buffer */
- in = *pIn++;
- in = (in * 32768.0f);
- in += in > 0.0f ? 0.5f : -0.5f;
- *pDst++ = (q15_t) (__SSAT((q31_t) (in), 16));
-
-#else
-
- /* C = A * 32768 */
- /* convert from float to q15 and then store the results in the destination buffer */
- *pDst++ = (q15_t) __SSAT((q31_t) (*pIn++ * 32768.0f), 16);
-
-#endif /* #ifdef ARM_MATH_ROUNDING */
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
- while(blkCnt > 0u)
- {
-
-#ifdef ARM_MATH_ROUNDING
- /* C = A * 32768 */
- /* convert from float to q15 and then store the results in the destination buffer */
- in = *pIn++;
- in = (in * 32768.0f);
- in += in > 0 ? 0.5f : -0.5f;
- *pDst++ = (q15_t) (__SSAT((q31_t) (in), 16));
-
-#else
-
- /* C = A * 32768 */
- /* convert from float to q15 and then store the results in the destination buffer */
- *pDst++ = (q15_t) __SSAT((q31_t) (*pIn++ * 32768.0f), 16);
-
-#endif /* #ifdef ARM_MATH_ROUNDING */
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
-}
-
-/**
- * @} end of float_to_x group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_float_to_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_float_to_q31.c
deleted file mode 100644
index a2bf3f5..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_float_to_q31.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/* ----------------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_float_to_q31.c
-*
-* Description: Converts the elements of the floating-point vector to Q31 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @defgroup float_to_x Convert 32-bit floating point value
- */
-
-/**
- * @addtogroup float_to_x
- * @{
- */
-
-/**
- * @brief Converts the elements of the floating-point vector to Q31 vector.
- * @param[in] *pSrc points to the floating-point input vector
- * @param[out] *pDst points to the Q31 output vector
- * @param[in] blockSize length of the input vector
- * @return none.
- *
- *\par Description:
- * \par
- * The equation used for the conversion process is:
- *
- *
- * pDst[n] = (q31_t)(pSrc[n] * 2147483648); 0 <= n < blockSize.
- *
- * Scaling and Overflow Behavior:
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q31 range[0x80000000 0x7FFFFFFF] will be saturated.
- *
- * \note In order to apply rounding, the library should be rebuilt with the ROUNDING macro
- * defined in the preprocessor section of project options.
- */
-
-
-void arm_float_to_q31(
- float32_t * pSrc,
- q31_t * pDst,
- uint32_t blockSize)
-{
- float32_t *pIn = pSrc; /* Src pointer */
- uint32_t blkCnt; /* loop counter */
-
-#ifdef ARM_MATH_ROUNDING
-
- float32_t in;
-
-#endif /* #ifdef ARM_MATH_ROUNDING */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
-
-#ifdef ARM_MATH_ROUNDING
-
- /* C = A * 32768 */
- /* convert from float to Q31 and then store the results in the destination buffer */
- in = *pIn++;
- in = (in * 2147483648.0f);
- in += in > 0.0f ? 0.5f : -0.5f;
- *pDst++ = clip_q63_to_q31((q63_t) (in));
-
- in = *pIn++;
- in = (in * 2147483648.0f);
- in += in > 0.0f ? 0.5f : -0.5f;
- *pDst++ = clip_q63_to_q31((q63_t) (in));
-
- in = *pIn++;
- in = (in * 2147483648.0f);
- in += in > 0.0f ? 0.5f : -0.5f;
- *pDst++ = clip_q63_to_q31((q63_t) (in));
-
- in = *pIn++;
- in = (in * 2147483648.0f);
- in += in > 0.0f ? 0.5f : -0.5f;
- *pDst++ = clip_q63_to_q31((q63_t) (in));
-
-#else
-
- /* C = A * 2147483648 */
- /* convert from float to Q31 and then store the results in the destination buffer */
- *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0f));
- *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0f));
- *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0f));
- *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0f));
-
-#endif /* #ifdef ARM_MATH_ROUNDING */
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
- while(blkCnt > 0u)
- {
-
-#ifdef ARM_MATH_ROUNDING
-
- /* C = A * 2147483648 */
- /* convert from float to Q31 and then store the results in the destination buffer */
- in = *pIn++;
- in = (in * 2147483648.0f);
- in += in > 0.0f ? 0.5f : -0.5f;
- *pDst++ = clip_q63_to_q31((q63_t) (in));
-
-#else
-
- /* C = A * 2147483648 */
- /* convert from float to Q31 and then store the results in the destination buffer */
- *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0f));
-
-#endif /* #ifdef ARM_MATH_ROUNDING */
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
- while(blkCnt > 0u)
- {
-
-#ifdef ARM_MATH_ROUNDING
-
- /* C = A * 2147483648 */
- /* convert from float to Q31 and then store the results in the destination buffer */
- in = *pIn++;
- in = (in * 2147483648.0f);
- in += in > 0 ? 0.5f : -0.5f;
- *pDst++ = clip_q63_to_q31((q63_t) (in));
-
-#else
-
- /* C = A * 2147483648 */
- /* convert from float to Q31 and then store the results in the destination buffer */
- *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0f));
-
-#endif /* #ifdef ARM_MATH_ROUNDING */
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
-}
-
-/**
- * @} end of float_to_x group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_float_to_q7.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_float_to_q7.c
deleted file mode 100644
index 0497e2b..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_float_to_q7.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/* ----------------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_float_to_q7.c
-*
-* Description: Converts the elements of the floating-point vector to Q7 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @addtogroup float_to_x
- * @{
- */
-
-/**
- * @brief Converts the elements of the floating-point vector to Q7 vector.
- * @param[in] *pSrc points to the floating-point input vector
- * @param[out] *pDst points to the Q7 output vector
- * @param[in] blockSize length of the input vector
- * @return none.
- *
- *\par Description:
- * \par
- * The equation used for the conversion process is:
- *
- * pDst[n] = (q7_t)(pSrc[n] * 128); 0 <= n < blockSize.
- *
- * \par Scaling and Overflow Behavior:
- * \par
- * The function uses saturating arithmetic.
- * Results outside of the allowable Q7 range [0x80 0x7F] will be saturated.
- * \note
- * In order to apply rounding, the library should be rebuilt with the ROUNDING macro
- * defined in the preprocessor section of project options.
- */
-
-
-void arm_float_to_q7(
- float32_t * pSrc,
- q7_t * pDst,
- uint32_t blockSize)
-{
- float32_t *pIn = pSrc; /* Src pointer */
- uint32_t blkCnt; /* loop counter */
-
-#ifdef ARM_MATH_ROUNDING
-
- float32_t in;
-
-#endif /* #ifdef ARM_MATH_ROUNDING */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
-
-#ifdef ARM_MATH_ROUNDING
- /* C = A * 128 */
- /* convert from float to q7 and then store the results in the destination buffer */
- in = *pIn++;
- in = (in * 128);
- in += in > 0.0f ? 0.5f : -0.5f;
- *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8));
-
- in = *pIn++;
- in = (in * 128);
- in += in > 0.0f ? 0.5f : -0.5f;
- *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8));
-
- in = *pIn++;
- in = (in * 128);
- in += in > 0.0f ? 0.5f : -0.5f;
- *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8));
-
- in = *pIn++;
- in = (in * 128);
- in += in > 0.0f ? 0.5f : -0.5f;
- *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8));
-
-#else
-
- /* C = A * 128 */
- /* convert from float to q7 and then store the results in the destination buffer */
- *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8);
- *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8);
- *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8);
- *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8);
-
-#endif /* #ifdef ARM_MATH_ROUNDING */
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
- while(blkCnt > 0u)
- {
-
-#ifdef ARM_MATH_ROUNDING
- /* C = A * 128 */
- /* convert from float to q7 and then store the results in the destination buffer */
- in = *pIn++;
- in = (in * 128);
- in += in > 0.0f ? 0.5f : -0.5f;
- *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8));
-
-#else
-
- /* C = A * 128 */
- /* convert from float to q7 and then store the results in the destination buffer */
- *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8);
-
-#endif /* #ifdef ARM_MATH_ROUNDING */
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
- while(blkCnt > 0u)
- {
-#ifdef ARM_MATH_ROUNDING
- /* C = A * 128 */
- /* convert from float to q7 and then store the results in the destination buffer */
- in = *pIn++;
- in = (in * 128.0f);
- in += in > 0 ? 0.5f : -0.5f;
- *pDst++ = (q7_t) (__SSAT((q31_t) (in), 8));
-
-#else
-
- /* C = A * 128 */
- /* convert from float to q7 and then store the results in the destination buffer */
- *pDst++ = (q7_t) __SSAT((q31_t) (*pIn++ * 128.0f), 8);
-
-#endif /* #ifdef ARM_MATH_ROUNDING */
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
-}
-
-/**
- * @} end of float_to_x group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q15_to_float.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q15_to_float.c
deleted file mode 100644
index 2e9624a..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q15_to_float.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/* ----------------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_q15_to_float.c
-*
-* Description: Converts the elements of the Q15 vector to floating-point vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @defgroup q15_to_x Convert 16-bit Integer value
- */
-
-/**
- * @addtogroup q15_to_x
- * @{
- */
-
-
-
-
-/**
- * @brief Converts the elements of the Q15 vector to floating-point vector.
- * @param[in] *pSrc points to the Q15 input vector
- * @param[out] *pDst points to the floating-point output vector
- * @param[in] blockSize length of the input vector
- * @return none.
- *
- * \par Description:
- *
- * The equation used for the conversion process is:
- *
- *
- * pDst[n] = (float32_t) pSrc[n] / 32768; 0 <= n < blockSize.
- *
- *
- */
-
-
-void arm_q15_to_float(
- q15_t * pSrc,
- float32_t * pDst,
- uint32_t blockSize)
-{
- q15_t *pIn = pSrc; /* Src pointer */
- uint32_t blkCnt; /* loop counter */
-
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (float32_t) A / 32768 */
- /* convert from q15 to float and then store the results in the destination buffer */
- *pDst++ = ((float32_t) * pIn++ / 32768.0f);
- *pDst++ = ((float32_t) * pIn++ / 32768.0f);
- *pDst++ = ((float32_t) * pIn++ / 32768.0f);
- *pDst++ = ((float32_t) * pIn++ / 32768.0f);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = (float32_t) A / 32768 */
- /* convert from q15 to float and then store the results in the destination buffer */
- *pDst++ = ((float32_t) * pIn++ / 32768.0f);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-}
-
-/**
- * @} end of q15_to_x group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q15_to_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q15_to_q31.c
deleted file mode 100644
index 5a34279..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q15_to_q31.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/* ----------------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_q15_to_q31.c
-*
-* Description: Converts the elements of the Q15 vector to Q31 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @addtogroup q15_to_x
- * @{
- */
-
-/**
- * @brief Converts the elements of the Q15 vector to Q31 vector.
- * @param[in] *pSrc points to the Q15 input vector
- * @param[out] *pDst points to the Q31 output vector
- * @param[in] blockSize length of the input vector
- * @return none.
- *
- * \par Description:
- *
- * The equation used for the conversion process is:
- *
- *
- * pDst[n] = (q31_t) pSrc[n] << 16; 0 <= n < blockSize.
- *
- *
- */
-
-
-void arm_q15_to_q31(
- q15_t * pSrc,
- q31_t * pDst,
- uint32_t blockSize)
-{
- q15_t *pIn = pSrc; /* Src pointer */
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t in1, in2;
- q31_t out1, out2, out3, out4;
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (q31_t)A << 16 */
- /* convert from q15 to q31 and then store the results in the destination buffer */
- in1 = *__SIMD32(pIn)++;
- in2 = *__SIMD32(pIn)++;
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- /* extract lower 16 bits to 32 bit result */
- out1 = in1 << 16u;
- /* extract upper 16 bits to 32 bit result */
- out2 = in1 & 0xFFFF0000;
- /* extract lower 16 bits to 32 bit result */
- out3 = in2 << 16u;
- /* extract upper 16 bits to 32 bit result */
- out4 = in2 & 0xFFFF0000;
-
-#else
-
- /* extract upper 16 bits to 32 bit result */
- out1 = in1 & 0xFFFF0000;
- /* extract lower 16 bits to 32 bit result */
- out2 = in1 << 16u;
- /* extract upper 16 bits to 32 bit result */
- out3 = in2 & 0xFFFF0000;
- /* extract lower 16 bits to 32 bit result */
- out4 = in2 << 16u;
-
-#endif // #ifndef ARM_MATH_BIG_ENDIAN
-
- *pDst++ = out1;
- *pDst++ = out2;
- *pDst++ = out3;
- *pDst++ = out4;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = (q31_t)A << 16 */
- /* convert from q15 to q31 and then store the results in the destination buffer */
- *pDst++ = (q31_t) * pIn++ << 16;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
-}
-
-/**
- * @} end of q15_to_x group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q15_to_q7.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q15_to_q7.c
deleted file mode 100644
index 9b029a0..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q15_to_q7.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/* ----------------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_q15_to_q7.c
-*
-* Description: Converts the elements of the Q15 vector to Q7 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @addtogroup q15_to_x
- * @{
- */
-
-
-/**
- * @brief Converts the elements of the Q15 vector to Q7 vector.
- * @param[in] *pSrc points to the Q15 input vector
- * @param[out] *pDst points to the Q7 output vector
- * @param[in] blockSize length of the input vector
- * @return none.
- *
- * \par Description:
- *
- * The equation used for the conversion process is:
- *
- *
- * pDst[n] = (q7_t) pSrc[n] >> 8; 0 <= n < blockSize.
- *
- *
- */
-
-
-void arm_q15_to_q7(
- q15_t * pSrc,
- q7_t * pDst,
- uint32_t blockSize)
-{
- q15_t *pIn = pSrc; /* Src pointer */
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t in1, in2;
- q31_t out1, out2;
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (q7_t) A >> 8 */
- /* convert from q15 to q7 and then store the results in the destination buffer */
- in1 = *__SIMD32(pIn)++;
- in2 = *__SIMD32(pIn)++;
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- out1 = __PKHTB(in2, in1, 16);
- out2 = __PKHBT(in2, in1, 16);
-
-#else
-
- out1 = __PKHTB(in1, in2, 16);
- out2 = __PKHBT(in1, in2, 16);
-
-#endif // #ifndef ARM_MATH_BIG_ENDIAN
-
- /* rotate packed value by 24 */
- out2 = ((uint32_t) out2 << 8) | ((uint32_t) out2 >> 24);
-
- /* anding with 0xff00ff00 to get two 8 bit values */
- out1 = out1 & 0xFF00FF00;
- /* anding with 0x00ff00ff to get two 8 bit values */
- out2 = out2 & 0x00FF00FF;
-
- /* oring two values(contains two 8 bit values) to get four packed 8 bit values */
- out1 = out1 | out2;
-
- /* store 4 samples at a time to destiantion buffer */
- *__SIMD32(pDst)++ = out1;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = (q7_t) A >> 8 */
- /* convert from q15 to q7 and then store the results in the destination buffer */
- *pDst++ = (q7_t) (*pIn++ >> 8);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
-}
-
-/**
- * @} end of q15_to_x group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q31_to_float.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q31_to_float.c
deleted file mode 100644
index 4ea5c26..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q31_to_float.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* ----------------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_q31_to_float.c
-*
-* Description: Converts the elements of the Q31 vector to floating-point vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @defgroup q31_to_x Convert 32-bit Integer value
- */
-
-/**
- * @addtogroup q31_to_x
- * @{
- */
-
-/**
- * @brief Converts the elements of the Q31 vector to floating-point vector.
- * @param[in] *pSrc points to the Q31 input vector
- * @param[out] *pDst points to the floating-point output vector
- * @param[in] blockSize length of the input vector
- * @return none.
- *
- * \par Description:
- *
- * The equation used for the conversion process is:
- *
- *
- * pDst[n] = (float32_t) pSrc[n] / 2147483648; 0 <= n < blockSize.
- *
- *
- */
-
-
-void arm_q31_to_float(
- q31_t * pSrc,
- float32_t * pDst,
- uint32_t blockSize)
-{
- q31_t *pIn = pSrc; /* Src pointer */
- uint32_t blkCnt; /* loop counter */
-
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (float32_t) A / 2147483648 */
- /* convert from q31 to float and then store the results in the destination buffer */
- *pDst++ = ((float32_t) * pIn++ / 2147483648.0f);
- *pDst++ = ((float32_t) * pIn++ / 2147483648.0f);
- *pDst++ = ((float32_t) * pIn++ / 2147483648.0f);
- *pDst++ = ((float32_t) * pIn++ / 2147483648.0f);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = (float32_t) A / 2147483648 */
- /* convert from q31 to float and then store the results in the destination buffer */
- *pDst++ = ((float32_t) * pIn++ / 2147483648.0f);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-}
-
-/**
- * @} end of q31_to_x group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q31_to_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q31_to_q15.c
deleted file mode 100644
index 053c6ba..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q31_to_q15.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/* ----------------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_q31_to_q15.c
-*
-* Description: Converts the elements of the Q31 vector to Q15 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @addtogroup q31_to_x
- * @{
- */
-
-/**
- * @brief Converts the elements of the Q31 vector to Q15 vector.
- * @param[in] *pSrc points to the Q31 input vector
- * @param[out] *pDst points to the Q15 output vector
- * @param[in] blockSize length of the input vector
- * @return none.
- *
- * \par Description:
- *
- * The equation used for the conversion process is:
- *
- *
- * pDst[n] = (q15_t) pSrc[n] >> 16; 0 <= n < blockSize.
- *
- *
- */
-
-
-void arm_q31_to_q15(
- q31_t * pSrc,
- q15_t * pDst,
- uint32_t blockSize)
-{
- q31_t *pIn = pSrc; /* Src pointer */
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t in1, in2, in3, in4;
- q31_t out1, out2;
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (q15_t) A >> 16 */
- /* convert from q31 to q15 and then store the results in the destination buffer */
- in1 = *pIn++;
- in2 = *pIn++;
- in3 = *pIn++;
- in4 = *pIn++;
-
- /* pack two higher 16-bit values from two 32-bit values */
-#ifndef ARM_MATH_BIG_ENDIAN
-
- out1 = __PKHTB(in2, in1, 16);
- out2 = __PKHTB(in4, in3, 16);
-
-#else
-
- out1 = __PKHTB(in1, in2, 16);
- out2 = __PKHTB(in3, in4, 16);
-
-#endif // #ifdef ARM_MATH_BIG_ENDIAN
-
- *__SIMD32(pDst)++ = out1;
- *__SIMD32(pDst)++ = out2;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = (q15_t) A >> 16 */
- /* convert from q31 to q15 and then store the results in the destination buffer */
- *pDst++ = (q15_t) (*pIn++ >> 16);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
-}
-
-/**
- * @} end of q31_to_x group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q31_to_q7.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q31_to_q7.c
deleted file mode 100644
index 26bfd32..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q31_to_q7.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/* ----------------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_q31_to_q7.c
-*
-* Description: Converts the elements of the Q31 vector to Q7 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @addtogroup q31_to_x
- * @{
- */
-
-/**
- * @brief Converts the elements of the Q31 vector to Q7 vector.
- * @param[in] *pSrc points to the Q31 input vector
- * @param[out] *pDst points to the Q7 output vector
- * @param[in] blockSize length of the input vector
- * @return none.
- *
- * \par Description:
- *
- * The equation used for the conversion process is:
- *
- *
- * pDst[n] = (q7_t) pSrc[n] >> 24; 0 <= n < blockSize.
- *
- *
- */
-
-
-void arm_q31_to_q7(
- q31_t * pSrc,
- q7_t * pDst,
- uint32_t blockSize)
-{
- q31_t *pIn = pSrc; /* Src pointer */
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- q31_t in1, in2, in3, in4;
- q7_t out1, out2, out3, out4;
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (q7_t) A >> 24 */
- /* convert from q31 to q7 and then store the results in the destination buffer */
- in1 = *pIn++;
- in2 = *pIn++;
- in3 = *pIn++;
- in4 = *pIn++;
-
- out1 = (q7_t) (in1 >> 24);
- out2 = (q7_t) (in2 >> 24);
- out3 = (q7_t) (in3 >> 24);
- out4 = (q7_t) (in4 >> 24);
-
- *__SIMD32(pDst)++ = __PACKq7(out1, out2, out3, out4);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = (q7_t) A >> 24 */
- /* convert from q31 to q7 and then store the results in the destination buffer */
- *pDst++ = (q7_t) (*pIn++ >> 24);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
-}
-
-/**
- * @} end of q31_to_x group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q7_to_float.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q7_to_float.c
deleted file mode 100644
index c9dff9c..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q7_to_float.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* ----------------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_q7_to_float.c
-*
-* Description: Converts the elements of the Q7 vector to floating-point vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @defgroup q7_to_x Convert 8-bit Integer value
- */
-
-/**
- * @addtogroup q7_to_x
- * @{
- */
-
-/**
- * @brief Converts the elements of the Q7 vector to floating-point vector.
- * @param[in] *pSrc points to the Q7 input vector
- * @param[out] *pDst points to the floating-point output vector
- * @param[in] blockSize length of the input vector
- * @return none.
- *
- * \par Description:
- *
- * The equation used for the conversion process is:
- *
- *
- * pDst[n] = (float32_t) pSrc[n] / 128; 0 <= n < blockSize.
- *
- *
- */
-
-
-void arm_q7_to_float(
- q7_t * pSrc,
- float32_t * pDst,
- uint32_t blockSize)
-{
- q7_t *pIn = pSrc; /* Src pointer */
- uint32_t blkCnt; /* loop counter */
-
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (float32_t) A / 128 */
- /* convert from q7 to float and then store the results in the destination buffer */
- *pDst++ = ((float32_t) * pIn++ / 128.0f);
- *pDst++ = ((float32_t) * pIn++ / 128.0f);
- *pDst++ = ((float32_t) * pIn++ / 128.0f);
- *pDst++ = ((float32_t) * pIn++ / 128.0f);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = (float32_t) A / 128 */
- /* convert from q7 to float and then store the results in the destination buffer */
- *pDst++ = ((float32_t) * pIn++ / 128.0f);
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-}
-
-/**
- * @} end of q7_to_x group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q7_to_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q7_to_q15.c
deleted file mode 100644
index 5b93546..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q7_to_q15.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/* ----------------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_q7_to_q15.c
-*
-* Description: Converts the elements of the Q7 vector to Q15 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @addtogroup q7_to_x
- * @{
- */
-
-
-
-
-/**
- * @brief Converts the elements of the Q7 vector to Q15 vector.
- * @param[in] *pSrc points to the Q7 input vector
- * @param[out] *pDst points to the Q15 output vector
- * @param[in] blockSize length of the input vector
- * @return none.
- *
- * \par Description:
- *
- * The equation used for the conversion process is:
- *
- *
- * pDst[n] = (q15_t) pSrc[n] << 8; 0 <= n < blockSize.
- *
- *
- */
-
-
-void arm_q7_to_q15(
- q7_t * pSrc,
- q15_t * pDst,
- uint32_t blockSize)
-{
- q7_t *pIn = pSrc; /* Src pointer */
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
- q31_t in;
- q31_t in1, in2;
- q31_t out1, out2;
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (q15_t) A << 8 */
- /* convert from q7 to q15 and then store the results in the destination buffer */
- in = *__SIMD32(pIn)++;
-
- /* rotatate in by 8 and extend two q7_t values to q15_t values */
- in1 = __SXTB16(__ROR(in, 8));
-
- /* extend remainig two q7_t values to q15_t values */
- in2 = __SXTB16(in);
-
- in1 = in1 << 8u;
- in2 = in2 << 8u;
-
- in1 = in1 & 0xFF00FF00;
- in2 = in2 & 0xFF00FF00;
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- out2 = __PKHTB(in1, in2, 16);
- out1 = __PKHBT(in2, in1, 16);
-
-#else
-
- out1 = __PKHTB(in1, in2, 16);
- out2 = __PKHBT(in2, in1, 16);
-
-#endif
-
- *__SIMD32(pDst)++ = out1;
- *__SIMD32(pDst)++ = out2;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = (q15_t) A << 8 */
- /* convert from q7 to q15 and then store the results in the destination buffer */
- *pDst++ = (q15_t) * pIn++ << 8;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
-}
-
-/**
- * @} end of q7_to_x group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q7_to_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q7_to_q31.c
deleted file mode 100644
index 84e47a3..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q7_to_q31.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/* ----------------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_q7_to_q31.c
-*
-* Description: Converts the elements of the Q7 vector to Q31 vector.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupSupport
- */
-
-/**
- * @addtogroup q7_to_x
- * @{
- */
-
-/**
- * @brief Converts the elements of the Q7 vector to Q31 vector.
- * @param[in] *pSrc points to the Q7 input vector
- * @param[out] *pDst points to the Q31 output vector
- * @param[in] blockSize length of the input vector
- * @return none.
- *
- * \par Description:
- *
- * The equation used for the conversion process is:
- *
- *
- * pDst[n] = (q31_t) pSrc[n] << 24; 0 <= n < blockSize.
- *
- *
- */
-
-
-void arm_q7_to_q31(
- q7_t * pSrc,
- q31_t * pDst,
- uint32_t blockSize)
-{
- q7_t *pIn = pSrc; /* Src pointer */
- uint32_t blkCnt; /* loop counter */
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- q31_t in;
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /*loop Unrolling */
- blkCnt = blockSize >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- while(blkCnt > 0u)
- {
- /* C = (q31_t) A << 24 */
- /* convert from q7 to q31 and then store the results in the destination buffer */
- in = *__SIMD32(pIn)++;
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- *pDst++ = (__ROR(in, 8)) & 0xFF000000;
- *pDst++ = (__ROR(in, 16)) & 0xFF000000;
- *pDst++ = (__ROR(in, 24)) & 0xFF000000;
- *pDst++ = (in & 0xFF000000);
-
-#else
-
- *pDst++ = (in & 0xFF000000);
- *pDst++ = (__ROR(in, 24)) & 0xFF000000;
- *pDst++ = (__ROR(in, 16)) & 0xFF000000;
- *pDst++ = (__ROR(in, 8)) & 0xFF000000;
-
-#endif // #ifndef ARM_MATH_BIG_ENDIAN
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = blockSize % 0x4u;
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Loop over blockSize number of values */
- blkCnt = blockSize;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
- while(blkCnt > 0u)
- {
- /* C = (q31_t) A << 24 */
- /* convert from q7 to q31 and then store the results in the destination buffer */
- *pDst++ = (q31_t) * pIn++ << 24;
-
- /* Decrement the loop counter */
- blkCnt--;
- }
-
-}
-
-/**
- * @} end of q7_to_x group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_bitreversal.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_bitreversal.c
deleted file mode 100644
index dc62e63..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_bitreversal.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_bitreversal.c
-*
-* Description: This file has common tables like Bitreverse, reciprocal etc which are used across different functions
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-#include "arm_common_tables.h"
-
-/*
-* @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)
-{
- uint16_t fftLenBy2, fftLenBy2p1;
- uint16_t i, j;
- float32_t in;
-
- /* Initializations */
- j = 0u;
- fftLenBy2 = fftSize >> 1u;
- fftLenBy2p1 = (fftSize >> 1u) + 1u;
-
- /* Bit Reversal Implementation */
- for (i = 0u; i <= (fftLenBy2 - 2u); i += 2u)
- {
- if(i < j)
- {
- /* pSrc[i] <-> pSrc[j]; */
- in = pSrc[2u * i];
- pSrc[2u * i] = pSrc[2u * j];
- pSrc[2u * j] = in;
-
- /* pSrc[i+1u] <-> pSrc[j+1u] */
- in = pSrc[(2u * i) + 1u];
- pSrc[(2u * i) + 1u] = pSrc[(2u * j) + 1u];
- pSrc[(2u * j) + 1u] = in;
-
- /* pSrc[i+fftLenBy2p1] <-> pSrc[j+fftLenBy2p1] */
- in = pSrc[2u * (i + fftLenBy2p1)];
- pSrc[2u * (i + fftLenBy2p1)] = pSrc[2u * (j + fftLenBy2p1)];
- pSrc[2u * (j + fftLenBy2p1)] = in;
-
- /* pSrc[i+fftLenBy2p1+1u] <-> pSrc[j+fftLenBy2p1+1u] */
- in = pSrc[(2u * (i + fftLenBy2p1)) + 1u];
- pSrc[(2u * (i + fftLenBy2p1)) + 1u] =
- pSrc[(2u * (j + fftLenBy2p1)) + 1u];
- pSrc[(2u * (j + fftLenBy2p1)) + 1u] = in;
-
- }
-
- /* pSrc[i+1u] <-> pSrc[j+1u] */
- in = pSrc[2u * (i + 1u)];
- pSrc[2u * (i + 1u)] = pSrc[2u * (j + fftLenBy2)];
- pSrc[2u * (j + fftLenBy2)] = in;
-
- /* pSrc[i+2u] <-> pSrc[j+2u] */
- in = pSrc[(2u * (i + 1u)) + 1u];
- pSrc[(2u * (i + 1u)) + 1u] = pSrc[(2u * (j + fftLenBy2)) + 1u];
- pSrc[(2u * (j + fftLenBy2)) + 1u] = in;
-
- /* Reading the index for the bit reversal */
- j = *pBitRevTab;
-
- /* Updating the bit reversal index depending on the fft length */
- pBitRevTab += bitRevFactor;
- }
-}
-
-
-
-/*
-* @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 * pBitRevTable)
-{
- uint32_t fftLenBy2, fftLenBy2p1, i, j;
- q31_t in;
-
- /* Initializations */
- j = 0u;
- fftLenBy2 = fftLen / 2u;
- fftLenBy2p1 = (fftLen / 2u) + 1u;
-
- /* Bit Reversal Implementation */
- for (i = 0u; i <= (fftLenBy2 - 2u); i += 2u)
- {
- if(i < j)
- {
- /* pSrc[i] <-> pSrc[j]; */
- in = pSrc[2u * i];
- pSrc[2u * i] = pSrc[2u * j];
- pSrc[2u * j] = in;
-
- /* pSrc[i+1u] <-> pSrc[j+1u] */
- in = pSrc[(2u * i) + 1u];
- pSrc[(2u * i) + 1u] = pSrc[(2u * j) + 1u];
- pSrc[(2u * j) + 1u] = in;
-
- /* pSrc[i+fftLenBy2p1] <-> pSrc[j+fftLenBy2p1] */
- in = pSrc[2u * (i + fftLenBy2p1)];
- pSrc[2u * (i + fftLenBy2p1)] = pSrc[2u * (j + fftLenBy2p1)];
- pSrc[2u * (j + fftLenBy2p1)] = in;
-
- /* pSrc[i+fftLenBy2p1+1u] <-> pSrc[j+fftLenBy2p1+1u] */
- in = pSrc[(2u * (i + fftLenBy2p1)) + 1u];
- pSrc[(2u * (i + fftLenBy2p1)) + 1u] =
- pSrc[(2u * (j + fftLenBy2p1)) + 1u];
- pSrc[(2u * (j + fftLenBy2p1)) + 1u] = in;
-
- }
-
- /* pSrc[i+1u] <-> pSrc[j+1u] */
- in = pSrc[2u * (i + 1u)];
- pSrc[2u * (i + 1u)] = pSrc[2u * (j + fftLenBy2)];
- pSrc[2u * (j + fftLenBy2)] = in;
-
- /* pSrc[i+2u] <-> pSrc[j+2u] */
- in = pSrc[(2u * (i + 1u)) + 1u];
- pSrc[(2u * (i + 1u)) + 1u] = pSrc[(2u * (j + fftLenBy2)) + 1u];
- pSrc[(2u * (j + fftLenBy2)) + 1u] = in;
-
- /* Reading the index for the bit reversal */
- j = *pBitRevTable;
-
- /* Updating the bit reversal index depending on the fft length */
- pBitRevTable += bitRevFactor;
- }
-}
-
-
-
-/*
- * @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 * pSrc16,
-uint32_t fftLen,
-uint16_t bitRevFactor,
-uint16_t * pBitRevTab)
-{
- q31_t *pSrc = (q31_t *) pSrc16;
- q31_t in;
- uint32_t fftLenBy2, fftLenBy2p1;
- uint32_t i, j;
-
- /* Initializations */
- j = 0u;
- fftLenBy2 = fftLen / 2u;
- fftLenBy2p1 = (fftLen / 2u) + 1u;
-
- /* Bit Reversal Implementation */
- for (i = 0u; i <= (fftLenBy2 - 2u); i += 2u)
- {
- if(i < j)
- {
- /* pSrc[i] <-> pSrc[j]; */
- /* pSrc[i+1u] <-> pSrc[j+1u] */
- in = pSrc[i];
- pSrc[i] = pSrc[j];
- pSrc[j] = in;
-
- /* pSrc[i + fftLenBy2p1] <-> pSrc[j + fftLenBy2p1]; */
- /* pSrc[i + fftLenBy2p1+1u] <-> pSrc[j + fftLenBy2p1+1u] */
- in = pSrc[i + fftLenBy2p1];
- pSrc[i + fftLenBy2p1] = pSrc[j + fftLenBy2p1];
- pSrc[j + fftLenBy2p1] = in;
- }
-
- /* pSrc[i+1u] <-> pSrc[j+fftLenBy2]; */
- /* pSrc[i+2] <-> pSrc[j+fftLenBy2+1u] */
- in = pSrc[i + 1u];
- pSrc[i + 1u] = pSrc[j + fftLenBy2];
- pSrc[j + fftLenBy2] = in;
-
- /* Reading the index for the bit reversal */
- j = *pBitRevTab;
-
- /* Updating the bit reversal index depending on the fft length */
- pBitRevTab += bitRevFactor;
- }
-}
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_f32.c
deleted file mode 100644
index c287bb9..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_f32.c
+++ /dev/null
@@ -1,632 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_cfft_f32.c
-*
-* Description: Combined Radix Decimation in Frequency CFFT Floating point processing function
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-#include "arm_common_tables.h"
-
-extern void arm_radix8_butterfly_f32(
- float32_t * pSrc,
- uint16_t fftLen,
- const float32_t * pCoef,
- uint16_t twidCoefModifier);
-
-extern void arm_bitreversal_32(
- uint32_t * pSrc,
- const uint16_t bitRevLen,
- const uint16_t * pBitRevTable);
-
-/**
-* @ingroup groupTransforms
-*/
-
-/**
-* @defgroup ComplexFFT Complex FFT Functions
-*
-* \par
-* The Fast Fourier Transform (FFT) is an efficient algorithm for computing the
-* Discrete Fourier Transform (DFT). The FFT can be orders of magnitude faster
-* than the DFT, especially for long lengths.
-* The algorithms described in this section
-* operate on complex data. A separate set of functions is devoted to handling
-* of real sequences.
-* \par
-* There are separate algorithms for handling floating-point, Q15, and Q31 data
-* types. The algorithms available for each data type are described next.
-* \par
-* The FFT functions operate in-place. That is, the array holding the input data
-* will also be used to hold the corresponding result. The input data is complex
-* and contains 2*fftLen
interleaved values as shown below.
-* {real[0], imag[0], real[1], imag[1],..}
-* The FFT result will be contained in the same array and the frequency domain
-* values will have the same interleaving.
-*
-* \par Floating-point
-* The floating-point complex FFT uses a mixed-radix algorithm. Multiple radix-8
-* stages are performed along with a single radix-2 or radix-4 stage, as needed.
-* The algorithm supports lengths of [16, 32, 64, ..., 4096] and each length uses
-* a different twiddle factor table.
-* \par
-* The function uses the standard FFT definition and output values may grow by a
-* factor of fftLen
when computing the forward transform. The
-* inverse transform includes a scale of 1/fftLen
as part of the
-* calculation and this matches the textbook definition of the inverse FFT.
-* \par
-* Pre-initialized data structures containing twiddle factors and bit reversal
-* tables are provided and defined in arm_const_structs.h
. Include
-* this header in your function and then pass one of the constant structures as
-* an argument to arm_cfft_f32. For example:
-* \par
-* arm_cfft_f32(arm_cfft_sR_f32_len64, pSrc, 1, 1)
-* \par
-* computes a 64-point inverse complex FFT including bit reversal.
-* The data structures are treated as constant data and not modified during the
-* calculation. The same data structure can be reused for multiple transforms
-* including mixing forward and inverse transforms.
-* \par
-* Earlier releases of the library provided separate radix-2 and radix-4
-* algorithms that operated on floating-point data. These functions are still
-* provided but are deprecated. The older functions are slower and less general
-* than the new functions.
-* \par
-* An example of initialization of the constants for the arm_cfft_f32 function follows:
-* \code
-* const static arm_cfft_instance_f32 *S;
-* ...
-* switch (length) {
-* case 16:
-* S = &arm_cfft_sR_f32_len16;
-* break;
-* case 32:
-* S = &arm_cfft_sR_f32_len32;
-* break;
-* case 64:
-* S = &arm_cfft_sR_f32_len64;
-* break;
-* case 128:
-* S = &arm_cfft_sR_f32_len128;
-* break;
-* case 256:
-* S = &arm_cfft_sR_f32_len256;
-* break;
-* case 512:
-* S = &arm_cfft_sR_f32_len512;
-* break;
-* case 1024:
-* S = &arm_cfft_sR_f32_len1024;
-* break;
-* case 2048:
-* S = &arm_cfft_sR_f32_len2048;
-* break;
-* case 4096:
-* S = &arm_cfft_sR_f32_len4096;
-* break;
-* }
-* \endcode
-* \par Q15 and Q31
-* The floating-point complex FFT uses a mixed-radix algorithm. Multiple radix-4
-* stages are performed along with a single radix-2 stage, as needed.
-* The algorithm supports lengths of [16, 32, 64, ..., 4096] and each length uses
-* a different twiddle factor table.
-* \par
-* The function uses the standard FFT definition and output values may grow by a
-* factor of fftLen
when computing the forward transform. The
-* inverse transform includes a scale of 1/fftLen
as part of the
-* calculation and this matches the textbook definition of the inverse FFT.
-* \par
-* Pre-initialized data structures containing twiddle factors and bit reversal
-* tables are provided and defined in arm_const_structs.h
. Include
-* this header in your function and then pass one of the constant structures as
-* an argument to arm_cfft_q31. For example:
-* \par
-* arm_cfft_q31(arm_cfft_sR_q31_len64, pSrc, 1, 1)
-* \par
-* computes a 64-point inverse complex FFT including bit reversal.
-* The data structures are treated as constant data and not modified during the
-* calculation. The same data structure can be reused for multiple transforms
-* including mixing forward and inverse transforms.
-* \par
-* Earlier releases of the library provided separate radix-2 and radix-4
-* algorithms that operated on floating-point data. These functions are still
-* provided but are deprecated. The older functions are slower and less general
-* than the new functions.
-* \par
-* An example of initialization of the constants for the arm_cfft_q31 function follows:
-* \code
-* const static arm_cfft_instance_q31 *S;
-* ...
-* switch (length) {
-* case 16:
-* S = &arm_cfft_sR_q31_len16;
-* break;
-* case 32:
-* S = &arm_cfft_sR_q31_len32;
-* break;
-* case 64:
-* S = &arm_cfft_sR_q31_len64;
-* break;
-* case 128:
-* S = &arm_cfft_sR_q31_len128;
-* break;
-* case 256:
-* S = &arm_cfft_sR_q31_len256;
-* break;
-* case 512:
-* S = &arm_cfft_sR_q31_len512;
-* break;
-* case 1024:
-* S = &arm_cfft_sR_q31_len1024;
-* break;
-* case 2048:
-* S = &arm_cfft_sR_q31_len2048;
-* break;
-* case 4096:
-* S = &arm_cfft_sR_q31_len4096;
-* break;
-* }
-* \endcode
-*
-*/
-
-void arm_cfft_radix8by2_f32( arm_cfft_instance_f32 * S, float32_t * p1)
-{
- uint32_t L = S->fftLen;
- float32_t * pCol1, * pCol2, * pMid1, * pMid2;
- float32_t * p2 = p1 + L;
- const float32_t * tw = (float32_t *) S->pTwiddle;
- float32_t t1[4], t2[4], t3[4], t4[4], twR, twI;
- float32_t m0, m1, m2, m3;
- uint32_t l;
-
- pCol1 = p1;
- pCol2 = p2;
-
- // Define new length
- L >>= 1;
- // Initialize mid pointers
- pMid1 = p1 + L;
- pMid2 = p2 + L;
-
- // do two dot Fourier transform
- for ( l = L >> 2; l > 0; l-- )
- {
- t1[0] = p1[0];
- t1[1] = p1[1];
- t1[2] = p1[2];
- t1[3] = p1[3];
-
- t2[0] = p2[0];
- t2[1] = p2[1];
- t2[2] = p2[2];
- t2[3] = p2[3];
-
- t3[0] = pMid1[0];
- t3[1] = pMid1[1];
- t3[2] = pMid1[2];
- t3[3] = pMid1[3];
-
- t4[0] = pMid2[0];
- t4[1] = pMid2[1];
- t4[2] = pMid2[2];
- t4[3] = pMid2[3];
-
- *p1++ = t1[0] + t2[0];
- *p1++ = t1[1] + t2[1];
- *p1++ = t1[2] + t2[2];
- *p1++ = t1[3] + t2[3]; // col 1
-
- t2[0] = t1[0] - t2[0];
- t2[1] = t1[1] - t2[1];
- t2[2] = t1[2] - t2[2];
- t2[3] = t1[3] - t2[3]; // for col 2
-
- *pMid1++ = t3[0] + t4[0];
- *pMid1++ = t3[1] + t4[1];
- *pMid1++ = t3[2] + t4[2];
- *pMid1++ = t3[3] + t4[3]; // col 1
-
- t4[0] = t4[0] - t3[0];
- t4[1] = t4[1] - t3[1];
- t4[2] = t4[2] - t3[2];
- t4[3] = t4[3] - t3[3]; // for col 2
-
- twR = *tw++;
- twI = *tw++;
-
- // multiply by twiddle factors
- m0 = t2[0] * twR;
- m1 = t2[1] * twI;
- m2 = t2[1] * twR;
- m3 = t2[0] * twI;
-
- // R = R * Tr - I * Ti
- *p2++ = m0 + m1;
- // I = I * Tr + R * Ti
- *p2++ = m2 - m3;
-
- // use vertical symmetry
- // 0.9988 - 0.0491i <==> -0.0491 - 0.9988i
- m0 = t4[0] * twI;
- m1 = t4[1] * twR;
- m2 = t4[1] * twI;
- m3 = t4[0] * twR;
-
- *pMid2++ = m0 - m1;
- *pMid2++ = m2 + m3;
-
- twR = *tw++;
- twI = *tw++;
-
- m0 = t2[2] * twR;
- m1 = t2[3] * twI;
- m2 = t2[3] * twR;
- m3 = t2[2] * twI;
-
- *p2++ = m0 + m1;
- *p2++ = m2 - m3;
-
- m0 = t4[2] * twI;
- m1 = t4[3] * twR;
- m2 = t4[3] * twI;
- m3 = t4[2] * twR;
-
- *pMid2++ = m0 - m1;
- *pMid2++ = m2 + m3;
- }
-
- // first col
- arm_radix8_butterfly_f32( pCol1, L, (float32_t *) S->pTwiddle, 2u);
- // second col
- arm_radix8_butterfly_f32( pCol2, L, (float32_t *) S->pTwiddle, 2u);
-}
-
-void arm_cfft_radix8by4_f32( arm_cfft_instance_f32 * S, float32_t * p1)
-{
- uint32_t L = S->fftLen >> 1;
- float32_t * pCol1, *pCol2, *pCol3, *pCol4, *pEnd1, *pEnd2, *pEnd3, *pEnd4;
- const float32_t *tw2, *tw3, *tw4;
- float32_t * p2 = p1 + L;
- float32_t * p3 = p2 + L;
- float32_t * p4 = p3 + L;
- float32_t t2[4], t3[4], t4[4], twR, twI;
- float32_t p1ap3_0, p1sp3_0, p1ap3_1, p1sp3_1;
- float32_t m0, m1, m2, m3;
- uint32_t l, twMod2, twMod3, twMod4;
-
- pCol1 = p1; // points to real values by default
- pCol2 = p2;
- pCol3 = p3;
- pCol4 = p4;
- pEnd1 = p2 - 1; // points to imaginary values by default
- pEnd2 = p3 - 1;
- pEnd3 = p4 - 1;
- pEnd4 = pEnd3 + L;
-
- tw2 = tw3 = tw4 = (float32_t *) S->pTwiddle;
-
- L >>= 1;
-
- // do four dot Fourier transform
-
- twMod2 = 2;
- twMod3 = 4;
- twMod4 = 6;
-
- // TOP
- p1ap3_0 = p1[0] + p3[0];
- p1sp3_0 = p1[0] - p3[0];
- p1ap3_1 = p1[1] + p3[1];
- p1sp3_1 = p1[1] - p3[1];
-
- // col 2
- t2[0] = p1sp3_0 + p2[1] - p4[1];
- t2[1] = p1sp3_1 - p2[0] + p4[0];
- // col 3
- t3[0] = p1ap3_0 - p2[0] - p4[0];
- t3[1] = p1ap3_1 - p2[1] - p4[1];
- // col 4
- t4[0] = p1sp3_0 - p2[1] + p4[1];
- t4[1] = p1sp3_1 + p2[0] - p4[0];
- // col 1
- *p1++ = p1ap3_0 + p2[0] + p4[0];
- *p1++ = p1ap3_1 + p2[1] + p4[1];
-
- // Twiddle factors are ones
- *p2++ = t2[0];
- *p2++ = t2[1];
- *p3++ = t3[0];
- *p3++ = t3[1];
- *p4++ = t4[0];
- *p4++ = t4[1];
-
- tw2 += twMod2;
- tw3 += twMod3;
- tw4 += twMod4;
-
- for (l = (L - 2) >> 1; l > 0; l-- )
- {
- // TOP
- p1ap3_0 = p1[0] + p3[0];
- p1sp3_0 = p1[0] - p3[0];
- p1ap3_1 = p1[1] + p3[1];
- p1sp3_1 = p1[1] - p3[1];
- // col 2
- t2[0] = p1sp3_0 + p2[1] - p4[1];
- t2[1] = p1sp3_1 - p2[0] + p4[0];
- // col 3
- t3[0] = p1ap3_0 - p2[0] - p4[0];
- t3[1] = p1ap3_1 - p2[1] - p4[1];
- // col 4
- t4[0] = p1sp3_0 - p2[1] + p4[1];
- t4[1] = p1sp3_1 + p2[0] - p4[0];
- // col 1 - top
- *p1++ = p1ap3_0 + p2[0] + p4[0];
- *p1++ = p1ap3_1 + p2[1] + p4[1];
-
- // BOTTOM
- p1ap3_1 = pEnd1[-1] + pEnd3[-1];
- p1sp3_1 = pEnd1[-1] - pEnd3[-1];
- p1ap3_0 = pEnd1[0] + pEnd3[0];
- p1sp3_0 = pEnd1[0] - pEnd3[0];
- // col 2
- t2[2] = pEnd2[0] - pEnd4[0] + p1sp3_1;
- t2[3] = pEnd1[0] - pEnd3[0] - pEnd2[-1] + pEnd4[-1];
- // col 3
- t3[2] = p1ap3_1 - pEnd2[-1] - pEnd4[-1];
- t3[3] = p1ap3_0 - pEnd2[0] - pEnd4[0];
- // col 4
- t4[2] = pEnd2[0] - pEnd4[0] - p1sp3_1;
- t4[3] = pEnd4[-1] - pEnd2[-1] - p1sp3_0;
- // col 1 - Bottom
- *pEnd1-- = p1ap3_0 + pEnd2[0] + pEnd4[0];
- *pEnd1-- = p1ap3_1 + pEnd2[-1] + pEnd4[-1];
-
- // COL 2
- // read twiddle factors
- twR = *tw2++;
- twI = *tw2++;
- // multiply by twiddle factors
- // let Z1 = a + i(b), Z2 = c + i(d)
- // => Z1 * Z2 = (a*c - b*d) + i(b*c + a*d)
-
- // Top
- m0 = t2[0] * twR;
- m1 = t2[1] * twI;
- m2 = t2[1] * twR;
- m3 = t2[0] * twI;
-
- *p2++ = m0 + m1;
- *p2++ = m2 - m3;
- // use vertical symmetry col 2
- // 0.9997 - 0.0245i <==> 0.0245 - 0.9997i
- // Bottom
- m0 = t2[3] * twI;
- m1 = t2[2] * twR;
- m2 = t2[2] * twI;
- m3 = t2[3] * twR;
-
- *pEnd2-- = m0 - m1;
- *pEnd2-- = m2 + m3;
-
- // COL 3
- twR = tw3[0];
- twI = tw3[1];
- tw3 += twMod3;
- // Top
- m0 = t3[0] * twR;
- m1 = t3[1] * twI;
- m2 = t3[1] * twR;
- m3 = t3[0] * twI;
-
- *p3++ = m0 + m1;
- *p3++ = m2 - m3;
- // use vertical symmetry col 3
- // 0.9988 - 0.0491i <==> -0.9988 - 0.0491i
- // Bottom
- m0 = -t3[3] * twR;
- m1 = t3[2] * twI;
- m2 = t3[2] * twR;
- m3 = t3[3] * twI;
-
- *pEnd3-- = m0 - m1;
- *pEnd3-- = m3 - m2;
-
- // COL 4
- twR = tw4[0];
- twI = tw4[1];
- tw4 += twMod4;
- // Top
- m0 = t4[0] * twR;
- m1 = t4[1] * twI;
- m2 = t4[1] * twR;
- m3 = t4[0] * twI;
-
- *p4++ = m0 + m1;
- *p4++ = m2 - m3;
- // use vertical symmetry col 4
- // 0.9973 - 0.0736i <==> -0.0736 + 0.9973i
- // Bottom
- m0 = t4[3] * twI;
- m1 = t4[2] * twR;
- m2 = t4[2] * twI;
- m3 = t4[3] * twR;
-
- *pEnd4-- = m0 - m1;
- *pEnd4-- = m2 + m3;
- }
-
- //MIDDLE
- // Twiddle factors are
- // 1.0000 0.7071-0.7071i -1.0000i -0.7071-0.7071i
- p1ap3_0 = p1[0] + p3[0];
- p1sp3_0 = p1[0] - p3[0];
- p1ap3_1 = p1[1] + p3[1];
- p1sp3_1 = p1[1] - p3[1];
-
- // col 2
- t2[0] = p1sp3_0 + p2[1] - p4[1];
- t2[1] = p1sp3_1 - p2[0] + p4[0];
- // col 3
- t3[0] = p1ap3_0 - p2[0] - p4[0];
- t3[1] = p1ap3_1 - p2[1] - p4[1];
- // col 4
- t4[0] = p1sp3_0 - p2[1] + p4[1];
- t4[1] = p1sp3_1 + p2[0] - p4[0];
- // col 1 - Top
- *p1++ = p1ap3_0 + p2[0] + p4[0];
- *p1++ = p1ap3_1 + p2[1] + p4[1];
-
- // COL 2
- twR = tw2[0];
- twI = tw2[1];
-
- m0 = t2[0] * twR;
- m1 = t2[1] * twI;
- m2 = t2[1] * twR;
- m3 = t2[0] * twI;
-
- *p2++ = m0 + m1;
- *p2++ = m2 - m3;
- // COL 3
- twR = tw3[0];
- twI = tw3[1];
-
- m0 = t3[0] * twR;
- m1 = t3[1] * twI;
- m2 = t3[1] * twR;
- m3 = t3[0] * twI;
-
- *p3++ = m0 + m1;
- *p3++ = m2 - m3;
- // COL 4
- twR = tw4[0];
- twI = tw4[1];
-
- m0 = t4[0] * twR;
- m1 = t4[1] * twI;
- m2 = t4[1] * twR;
- m3 = t4[0] * twI;
-
- *p4++ = m0 + m1;
- *p4++ = m2 - m3;
-
- // first col
- arm_radix8_butterfly_f32( pCol1, L, (float32_t *) S->pTwiddle, 4u);
- // second col
- arm_radix8_butterfly_f32( pCol2, L, (float32_t *) S->pTwiddle, 4u);
- // third col
- arm_radix8_butterfly_f32( pCol3, L, (float32_t *) S->pTwiddle, 4u);
- // fourth col
- arm_radix8_butterfly_f32( pCol4, L, (float32_t *) S->pTwiddle, 4u);
-}
-
-/**
-* @addtogroup ComplexFFT
-* @{
-*/
-
-/**
-* @details
-* @brief Processing function for the floating-point complex FFT.
-* @param[in] *S points to an instance of the floating-point CFFT structure.
-* @param[in, out] *p1 points to the complex data buffer of size 2*fftLen
. Processing occurs in-place.
-* @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 none.
-*/
-
-void arm_cfft_f32(
- const arm_cfft_instance_f32 * S,
- float32_t * p1,
- uint8_t ifftFlag,
- uint8_t bitReverseFlag)
-{
- uint32_t L = S->fftLen, l;
- float32_t invL, * pSrc;
-
- if(ifftFlag == 1u)
- {
- /* Conjugate input data */
- pSrc = p1 + 1;
- for(l=0; lpTwiddle, 1);
- break;
- }
-
- if( bitReverseFlag )
- arm_bitreversal_32((uint32_t*)p1,S->bitRevLength,S->pBitRevTable);
-
- if(ifftFlag == 1u)
- {
- invL = 1.0f/(float32_t)L;
- /* Conjugate and scale output data */
- pSrc = p1;
- for(l=0; l2*fftLen. Processing occurs in-place.
-* @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 none.
-*/
-
-void arm_cfft_q15(
- const arm_cfft_instance_q15 * S,
- q15_t * p1,
- uint8_t ifftFlag,
- uint8_t bitReverseFlag)
-{
- uint32_t L = S->fftLen;
-
- if(ifftFlag == 1u)
- {
- switch (L)
- {
- case 16:
- case 64:
- case 256:
- case 1024:
- case 4096:
- arm_radix4_butterfly_inverse_q15 ( p1, L, (q15_t*)S->pTwiddle, 1 );
- break;
-
- case 32:
- case 128:
- case 512:
- case 2048:
- arm_cfft_radix4by2_inverse_q15 ( p1, L, S->pTwiddle );
- break;
- }
- }
- else
- {
- switch (L)
- {
- case 16:
- case 64:
- case 256:
- case 1024:
- case 4096:
- arm_radix4_butterfly_q15 ( p1, L, (q15_t*)S->pTwiddle, 1 );
- break;
-
- case 32:
- case 128:
- case 512:
- case 2048:
- arm_cfft_radix4by2_q15 ( p1, L, S->pTwiddle );
- break;
- }
- }
-
- if( bitReverseFlag )
- arm_bitreversal_16((uint16_t*)p1,S->bitRevLength,S->pBitRevTable);
-}
-
-/**
-* @} end of ComplexFFT group
-*/
-
-void arm_cfft_radix4by2_q15(
- q15_t * pSrc,
- uint32_t fftLen,
- const q15_t * pCoef)
-{
- uint32_t i;
- uint32_t n2;
- q15_t p0, p1, p2, p3;
-#ifndef ARM_MATH_CM0_FAMILY
- q31_t T, S, R;
- q31_t coeff, out1, out2;
- const q15_t *pC = pCoef;
- q15_t *pSi = pSrc;
- q15_t *pSl = pSrc + fftLen;
-#else
- uint32_t ia, l;
- q15_t xt, yt, cosVal, sinVal;
-#endif
-
- n2 = fftLen >> 1;
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- for (i = n2; i > 0; i--)
- {
- coeff = _SIMD32_OFFSET(pC);
- pC += 2;
-
- T = _SIMD32_OFFSET(pSi);
- T = __SHADD16(T, 0); // this is just a SIMD arithmetic shift right by 1
-
- S = _SIMD32_OFFSET(pSl);
- S = __SHADD16(S, 0); // this is just a SIMD arithmetic shift right by 1
-
- R = __QSUB16(T, S);
-
- _SIMD32_OFFSET(pSi) = __SHADD16(T, S);
- pSi += 2;
-
- #ifndef ARM_MATH_BIG_ENDIAN
-
- out1 = __SMUAD(coeff, R) >> 16;
- out2 = __SMUSDX(coeff, R);
-
- #else
-
- out1 = __SMUSDX(R, coeff) >> 16u;
- out2 = __SMUAD(coeff, R);
-
- #endif // #ifndef ARM_MATH_BIG_ENDIAN
-
- _SIMD32_OFFSET(pSl) =
- (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
- pSl += 2;
- }
-
-#else // #ifndef ARM_MATH_CM0_FAMILY
-
- ia = 0;
- for (i = 0; i < n2; i++)
- {
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
- ia++;
-
- l = i + n2;
-
- xt = (pSrc[2 * i] >> 1u) - (pSrc[2 * l] >> 1u);
- pSrc[2 * i] = ((pSrc[2 * i] >> 1u) + (pSrc[2 * l] >> 1u)) >> 1u;
-
- yt = (pSrc[2 * i + 1] >> 1u) - (pSrc[2 * l + 1] >> 1u);
- pSrc[2 * i + 1] =
- ((pSrc[2 * l + 1] >> 1u) + (pSrc[2 * i + 1] >> 1u)) >> 1u;
-
- pSrc[2u * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) +
- ((int16_t) (((q31_t) yt * sinVal) >> 16)));
-
- pSrc[2u * l + 1u] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) -
- ((int16_t) (((q31_t) xt * sinVal) >> 16)));
- }
-
-#endif // #ifndef ARM_MATH_CM0_FAMILY
-
- // first col
- arm_radix4_butterfly_q15( pSrc, n2, (q15_t*)pCoef, 2u);
- // second col
- arm_radix4_butterfly_q15( pSrc + fftLen, n2, (q15_t*)pCoef, 2u);
-
- for (i = 0; i < fftLen >> 1; i++)
- {
- p0 = pSrc[4*i+0];
- p1 = pSrc[4*i+1];
- p2 = pSrc[4*i+2];
- p3 = pSrc[4*i+3];
-
- p0 <<= 1;
- p1 <<= 1;
- p2 <<= 1;
- p3 <<= 1;
-
- pSrc[4*i+0] = p0;
- pSrc[4*i+1] = p1;
- pSrc[4*i+2] = p2;
- pSrc[4*i+3] = p3;
- }
-}
-
-void arm_cfft_radix4by2_inverse_q15(
- q15_t * pSrc,
- uint32_t fftLen,
- const q15_t * pCoef)
-{
- uint32_t i;
- uint32_t n2;
- q15_t p0, p1, p2, p3;
-#ifndef ARM_MATH_CM0_FAMILY
- q31_t T, S, R;
- q31_t coeff, out1, out2;
- const q15_t *pC = pCoef;
- q15_t *pSi = pSrc;
- q15_t *pSl = pSrc + fftLen;
-#else
- uint32_t ia, l;
- q15_t xt, yt, cosVal, sinVal;
-#endif
-
- n2 = fftLen >> 1;
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- for (i = n2; i > 0; i--)
- {
- coeff = _SIMD32_OFFSET(pC);
- pC += 2;
-
- T = _SIMD32_OFFSET(pSi);
- T = __SHADD16(T, 0); // this is just a SIMD arithmetic shift right by 1
-
- S = _SIMD32_OFFSET(pSl);
- S = __SHADD16(S, 0); // this is just a SIMD arithmetic shift right by 1
-
- R = __QSUB16(T, S);
-
- _SIMD32_OFFSET(pSi) = __SHADD16(T, S);
- pSi += 2;
-
- #ifndef ARM_MATH_BIG_ENDIAN
-
- out1 = __SMUSD(coeff, R) >> 16;
- out2 = __SMUADX(coeff, R);
- #else
-
- out1 = __SMUADX(R, coeff) >> 16u;
- out2 = __SMUSD(__QSUB(0, coeff), R);
-
- #endif // #ifndef ARM_MATH_BIG_ENDIAN
-
- _SIMD32_OFFSET(pSl) =
- (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
- pSl += 2;
- }
-
-#else // #ifndef ARM_MATH_CM0_FAMILY
-
- ia = 0;
- for (i = 0; i < n2; i++)
- {
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
- ia++;
-
- l = i + n2;
- xt = (pSrc[2 * i] >> 1u) - (pSrc[2 * l] >> 1u);
- pSrc[2 * i] = ((pSrc[2 * i] >> 1u) + (pSrc[2 * l] >> 1u)) >> 1u;
-
- yt = (pSrc[2 * i + 1] >> 1u) - (pSrc[2 * l + 1] >> 1u);
- pSrc[2 * i + 1] =
- ((pSrc[2 * l + 1] >> 1u) + (pSrc[2 * i + 1] >> 1u)) >> 1u;
-
- pSrc[2u * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) -
- ((int16_t) (((q31_t) yt * sinVal) >> 16)));
-
- pSrc[2u * l + 1u] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) +
- ((int16_t) (((q31_t) xt * sinVal) >> 16)));
- }
-
-#endif // #ifndef ARM_MATH_CM0_FAMILY
-
- // first col
- arm_radix4_butterfly_inverse_q15( pSrc, n2, (q15_t*)pCoef, 2u);
- // second col
- arm_radix4_butterfly_inverse_q15( pSrc + fftLen, n2, (q15_t*)pCoef, 2u);
-
- for (i = 0; i < fftLen >> 1; i++)
- {
- p0 = pSrc[4*i+0];
- p1 = pSrc[4*i+1];
- p2 = pSrc[4*i+2];
- p3 = pSrc[4*i+3];
-
- p0 <<= 1;
- p1 <<= 1;
- p2 <<= 1;
- p3 <<= 1;
-
- pSrc[4*i+0] = p0;
- pSrc[4*i+1] = p1;
- pSrc[4*i+2] = p2;
- pSrc[4*i+3] = p3;
- }
-}
-
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_q31.c
deleted file mode 100644
index 401825b..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_q31.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_cfft_q31.c
-*
-* Description: Combined Radix Decimation in Frequency CFFT fixed point processing function
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-extern void arm_radix4_butterfly_q31(
- q31_t * pSrc,
- uint32_t fftLen,
- q31_t * pCoef,
- uint32_t twidCoefModifier);
-
-extern void arm_radix4_butterfly_inverse_q31(
- q31_t * pSrc,
- uint32_t fftLen,
- q31_t * pCoef,
- uint32_t twidCoefModifier);
-
-extern void arm_bitreversal_32(
- uint32_t * pSrc,
- const uint16_t bitRevLen,
- const uint16_t * pBitRevTable);
-
-void arm_cfft_radix4by2_q31(
- q31_t * pSrc,
- uint32_t fftLen,
- const q31_t * pCoef);
-
-void arm_cfft_radix4by2_inverse_q31(
- q31_t * pSrc,
- uint32_t fftLen,
- const q31_t * pCoef);
-
-/**
-* @ingroup groupTransforms
-*/
-
-/**
-* @addtogroup ComplexFFT
-* @{
-*/
-
-/**
-* @details
-* @brief Processing function for the fixed-point complex FFT in Q31 format.
-* @param[in] *S points to an instance of the fixed-point CFFT structure.
-* @param[in, out] *p1 points to the complex data buffer of size 2*fftLen
. Processing occurs in-place.
-* @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 none.
-*/
-
-void arm_cfft_q31(
- const arm_cfft_instance_q31 * S,
- q31_t * p1,
- uint8_t ifftFlag,
- uint8_t bitReverseFlag)
-{
- uint32_t L = S->fftLen;
-
- if(ifftFlag == 1u)
- {
- switch (L)
- {
- case 16:
- case 64:
- case 256:
- case 1024:
- case 4096:
- arm_radix4_butterfly_inverse_q31 ( p1, L, (q31_t*)S->pTwiddle, 1 );
- break;
-
- case 32:
- case 128:
- case 512:
- case 2048:
- arm_cfft_radix4by2_inverse_q31 ( p1, L, S->pTwiddle );
- break;
- }
- }
- else
- {
- switch (L)
- {
- case 16:
- case 64:
- case 256:
- case 1024:
- case 4096:
- arm_radix4_butterfly_q31 ( p1, L, (q31_t*)S->pTwiddle, 1 );
- break;
-
- case 32:
- case 128:
- case 512:
- case 2048:
- arm_cfft_radix4by2_q31 ( p1, L, S->pTwiddle );
- break;
- }
- }
-
- if( bitReverseFlag )
- arm_bitreversal_32((uint32_t*)p1,S->bitRevLength,S->pBitRevTable);
-}
-
-/**
-* @} end of ComplexFFT group
-*/
-
-void arm_cfft_radix4by2_q31(
- q31_t * pSrc,
- uint32_t fftLen,
- const q31_t * pCoef)
-{
- uint32_t i, l;
- uint32_t n2, ia;
- q31_t xt, yt, cosVal, sinVal;
- q31_t p0, p1;
-
- n2 = fftLen >> 1;
- ia = 0;
- for (i = 0; i < n2; i++)
- {
- cosVal = pCoef[2*ia];
- sinVal = pCoef[2*ia + 1];
- ia++;
-
- l = i + n2;
- xt = (pSrc[2 * i] >> 2) - (pSrc[2 * l] >> 2);
- pSrc[2 * i] = (pSrc[2 * i] >> 2) + (pSrc[2 * l] >> 2);
-
- yt = (pSrc[2 * i + 1] >> 2) - (pSrc[2 * l + 1] >> 2);
- pSrc[2 * i + 1] = (pSrc[2 * l + 1] >> 2) + (pSrc[2 * i + 1] >> 2);
-
- mult_32x32_keep32_R(p0, xt, cosVal);
- mult_32x32_keep32_R(p1, yt, cosVal);
- multAcc_32x32_keep32_R(p0, yt, sinVal);
- multSub_32x32_keep32_R(p1, xt, sinVal);
-
- pSrc[2u * l] = p0 << 1;
- pSrc[2u * l + 1u] = p1 << 1;
-
- }
-
- // first col
- arm_radix4_butterfly_q31( pSrc, n2, (q31_t*)pCoef, 2u);
- // second col
- arm_radix4_butterfly_q31( pSrc + fftLen, n2, (q31_t*)pCoef, 2u);
-
- for (i = 0; i < fftLen >> 1; i++)
- {
- p0 = pSrc[4*i+0];
- p1 = pSrc[4*i+1];
- xt = pSrc[4*i+2];
- yt = pSrc[4*i+3];
-
- p0 <<= 1;
- p1 <<= 1;
- xt <<= 1;
- yt <<= 1;
-
- pSrc[4*i+0] = p0;
- pSrc[4*i+1] = p1;
- pSrc[4*i+2] = xt;
- pSrc[4*i+3] = yt;
- }
-
-}
-
-void arm_cfft_radix4by2_inverse_q31(
- q31_t * pSrc,
- uint32_t fftLen,
- const q31_t * pCoef)
-{
- uint32_t i, l;
- uint32_t n2, ia;
- q31_t xt, yt, cosVal, sinVal;
- q31_t p0, p1;
-
- n2 = fftLen >> 1;
- ia = 0;
- for (i = 0; i < n2; i++)
- {
- cosVal = pCoef[2*ia];
- sinVal = pCoef[2*ia + 1];
- ia++;
-
- l = i + n2;
- xt = (pSrc[2 * i] >> 2) - (pSrc[2 * l] >> 2);
- pSrc[2 * i] = (pSrc[2 * i] >> 2) + (pSrc[2 * l] >> 2);
-
- yt = (pSrc[2 * i + 1] >> 2) - (pSrc[2 * l + 1] >> 2);
- pSrc[2 * i + 1] = (pSrc[2 * l + 1] >> 2) + (pSrc[2 * i + 1] >> 2);
-
- mult_32x32_keep32_R(p0, xt, cosVal);
- mult_32x32_keep32_R(p1, yt, cosVal);
- multSub_32x32_keep32_R(p0, yt, sinVal);
- multAcc_32x32_keep32_R(p1, xt, sinVal);
-
- pSrc[2u * l] = p0 << 1;
- pSrc[2u * l + 1u] = p1 << 1;
-
- }
-
- // first col
- arm_radix4_butterfly_inverse_q31( pSrc, n2, (q31_t*)pCoef, 2u);
- // second col
- arm_radix4_butterfly_inverse_q31( pSrc + fftLen, n2, (q31_t*)pCoef, 2u);
-
- for (i = 0; i < fftLen >> 1; i++)
- {
- p0 = pSrc[4*i+0];
- p1 = pSrc[4*i+1];
- xt = pSrc[4*i+2];
- yt = pSrc[4*i+3];
-
- p0 <<= 1;
- p1 <<= 1;
- xt <<= 1;
- yt <<= 1;
-
- pSrc[4*i+0] = p0;
- pSrc[4*i+1] = p1;
- pSrc[4*i+2] = xt;
- pSrc[4*i+3] = yt;
- }
-}
-
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_f32.c
deleted file mode 100644
index b0632ac..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_f32.c
+++ /dev/null
@@ -1,485 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_cfft_radix2_f32.c
-*
-* Description: Radix-2 Decimation in Frequency CFFT & CIFFT Floating point processing function
-*
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-void arm_radix2_butterfly_f32(
- float32_t * pSrc,
- uint32_t fftLen,
- float32_t * pCoef,
- uint16_t twidCoefModifier);
-
-void arm_radix2_butterfly_inverse_f32(
- float32_t * pSrc,
- uint32_t fftLen,
- float32_t * pCoef,
- uint16_t twidCoefModifier,
- float32_t onebyfftLen);
-
-extern void arm_bitreversal_f32(
- float32_t * pSrc,
- uint16_t fftSize,
- uint16_t bitRevFactor,
- uint16_t * pBitRevTab);
-
-/**
-* @ingroup groupTransforms
-*/
-
-/**
-* @addtogroup ComplexFFT
-* @{
-*/
-
-/**
-* @details
-* @brief Radix-2 CFFT/CIFFT.
-* @deprecated Do not use this function. It has been superseded by \ref arm_cfft_f32 and will be removed
-* in the future.
-* @param[in] *S points to an instance of the floating-point Radix-2 CFFT/CIFFT structure.
-* @param[in, out] *pSrc points to the complex data buffer of size 2*fftLen
. Processing occurs in-place.
-* @return none.
-*/
-
-void arm_cfft_radix2_f32(
-const arm_cfft_radix2_instance_f32 * S,
-float32_t * pSrc)
-{
-
- if(S->ifftFlag == 1u)
- {
- /* Complex IFFT radix-2 */
- arm_radix2_butterfly_inverse_f32(pSrc, S->fftLen, S->pTwiddle,
- S->twidCoefModifier, S->onebyfftLen);
- }
- else
- {
- /* Complex FFT radix-2 */
- arm_radix2_butterfly_f32(pSrc, S->fftLen, S->pTwiddle,
- S->twidCoefModifier);
- }
-
- if(S->bitReverseFlag == 1u)
- {
- /* Bit Reversal */
- arm_bitreversal_f32(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
- }
-
-}
-
-
-/**
-* @} end of ComplexFFT group
-*/
-
-
-
-/* ----------------------------------------------------------------------
-** Internal helper function used by the FFTs
-** ------------------------------------------------------------------- */
-
-/*
-* @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_radix2_butterfly_f32(
-float32_t * pSrc,
-uint32_t fftLen,
-float32_t * pCoef,
-uint16_t twidCoefModifier)
-{
-
- uint32_t i, j, k, l;
- uint32_t n1, n2, ia;
- float32_t xt, yt, cosVal, sinVal;
- float32_t p0, p1, p2, p3;
- float32_t a0, a1;
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Initializations for the first stage */
- n2 = fftLen >> 1;
- ia = 0;
- i = 0;
-
- // loop for groups
- for (k = n2; k > 0; k--)
- {
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
-
- /* Twiddle coefficients index modifier */
- ia += twidCoefModifier;
-
- /* index calculation for the input as, */
- /* pSrc[i + 0], pSrc[i + fftLen/1] */
- l = i + n2;
-
- /* Butterfly implementation */
- a0 = pSrc[2 * i] + pSrc[2 * l];
- xt = pSrc[2 * i] - pSrc[2 * l];
-
- yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
- a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
-
- p0 = xt * cosVal;
- p1 = yt * sinVal;
- p2 = yt * cosVal;
- p3 = xt * sinVal;
-
- pSrc[2 * i] = a0;
- pSrc[2 * i + 1] = a1;
-
- pSrc[2 * l] = p0 + p1;
- pSrc[2 * l + 1] = p2 - p3;
-
- i++;
- } // groups loop end
-
- twidCoefModifier <<= 1u;
-
- // loop for stage
- for (k = n2; k > 2; k = k >> 1)
- {
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- // loop for groups
- j = 0;
- do
- {
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
- ia += twidCoefModifier;
-
- // loop for butterfly
- i = j;
- do
- {
- l = i + n2;
- a0 = pSrc[2 * i] + pSrc[2 * l];
- xt = pSrc[2 * i] - pSrc[2 * l];
-
- yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
- a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
-
- p0 = xt * cosVal;
- p1 = yt * sinVal;
- p2 = yt * cosVal;
- p3 = xt * sinVal;
-
- pSrc[2 * i] = a0;
- pSrc[2 * i + 1] = a1;
-
- pSrc[2 * l] = p0 + p1;
- pSrc[2 * l + 1] = p2 - p3;
-
- i += n1;
- } while( i < fftLen ); // butterfly loop end
- j++;
- } while( j < n2); // groups loop end
- twidCoefModifier <<= 1u;
- } // stages loop end
-
- // loop for butterfly
- for (i = 0; i < fftLen; i += 2)
- {
- a0 = pSrc[2 * i] + pSrc[2 * i + 2];
- xt = pSrc[2 * i] - pSrc[2 * i + 2];
-
- yt = pSrc[2 * i + 1] - pSrc[2 * i + 3];
- a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1];
-
- pSrc[2 * i] = a0;
- pSrc[2 * i + 1] = a1;
- pSrc[2 * i + 2] = xt;
- pSrc[2 * i + 3] = yt;
- } // groups loop end
-
-#else
-
- n2 = fftLen;
-
- // loop for stage
- for (k = fftLen; k > 1; k = k >> 1)
- {
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- // loop for groups
- j = 0;
- do
- {
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
- ia += twidCoefModifier;
-
- // loop for butterfly
- i = j;
- do
- {
- l = i + n2;
- a0 = pSrc[2 * i] + pSrc[2 * l];
- xt = pSrc[2 * i] - pSrc[2 * l];
-
- yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
- a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
-
- p0 = xt * cosVal;
- p1 = yt * sinVal;
- p2 = yt * cosVal;
- p3 = xt * sinVal;
-
- pSrc[2 * i] = a0;
- pSrc[2 * i + 1] = a1;
-
- pSrc[2 * l] = p0 + p1;
- pSrc[2 * l + 1] = p2 - p3;
-
- i += n1;
- } while(i < fftLen);
- j++;
- } while(j < n2);
- twidCoefModifier <<= 1u;
- }
-
-#endif // #ifndef ARM_MATH_CM0_FAMILY
-
-}
-
-
-void arm_radix2_butterfly_inverse_f32(
-float32_t * pSrc,
-uint32_t fftLen,
-float32_t * pCoef,
-uint16_t twidCoefModifier,
-float32_t onebyfftLen)
-{
-
- uint32_t i, j, k, l;
- uint32_t n1, n2, ia;
- float32_t xt, yt, cosVal, sinVal;
- float32_t p0, p1, p2, p3;
- float32_t a0, a1;
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- n2 = fftLen >> 1;
- ia = 0;
-
- // loop for groups
- for (i = 0; i < n2; i++)
- {
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
- ia += twidCoefModifier;
-
- l = i + n2;
- a0 = pSrc[2 * i] + pSrc[2 * l];
- xt = pSrc[2 * i] - pSrc[2 * l];
-
- yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
- a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
-
- p0 = xt * cosVal;
- p1 = yt * sinVal;
- p2 = yt * cosVal;
- p3 = xt * sinVal;
-
- pSrc[2 * i] = a0;
- pSrc[2 * i + 1] = a1;
-
- pSrc[2 * l] = p0 - p1;
- pSrc[2 * l + 1] = p2 + p3;
- } // groups loop end
-
- twidCoefModifier <<= 1u;
-
- // loop for stage
- for (k = fftLen / 2; k > 2; k = k >> 1)
- {
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- // loop for groups
- j = 0;
- do
- {
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
- ia += twidCoefModifier;
-
- // loop for butterfly
- i = j;
- do
- {
- l = i + n2;
- a0 = pSrc[2 * i] + pSrc[2 * l];
- xt = pSrc[2 * i] - pSrc[2 * l];
-
- yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
- a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
-
- p0 = xt * cosVal;
- p1 = yt * sinVal;
- p2 = yt * cosVal;
- p3 = xt * sinVal;
-
- pSrc[2 * i] = a0;
- pSrc[2 * i + 1] = a1;
-
- pSrc[2 * l] = p0 - p1;
- pSrc[2 * l + 1] = p2 + p3;
-
- i += n1;
- } while( i < fftLen ); // butterfly loop end
- j++;
- } while(j < n2); // groups loop end
-
- twidCoefModifier <<= 1u;
- } // stages loop end
-
- // loop for butterfly
- for (i = 0; i < fftLen; i += 2)
- {
- a0 = pSrc[2 * i] + pSrc[2 * i + 2];
- xt = pSrc[2 * i] - pSrc[2 * i + 2];
-
- a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1];
- yt = pSrc[2 * i + 1] - pSrc[2 * i + 3];
-
- p0 = a0 * onebyfftLen;
- p2 = xt * onebyfftLen;
- p1 = a1 * onebyfftLen;
- p3 = yt * onebyfftLen;
-
- pSrc[2 * i] = p0;
- pSrc[2 * i + 1] = p1;
- pSrc[2 * i + 2] = p2;
- pSrc[2 * i + 3] = p3;
- } // butterfly loop end
-
-#else
-
- n2 = fftLen;
-
- // loop for stage
- for (k = fftLen; k > 2; k = k >> 1)
- {
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- // loop for groups
- j = 0;
- do
- {
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
- ia = ia + twidCoefModifier;
-
- // loop for butterfly
- i = j;
- do
- {
- l = i + n2;
- a0 = pSrc[2 * i] + pSrc[2 * l];
- xt = pSrc[2 * i] - pSrc[2 * l];
-
- yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
- a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
-
- p0 = xt * cosVal;
- p1 = yt * sinVal;
- p2 = yt * cosVal;
- p3 = xt * sinVal;
-
- pSrc[2 * i] = a0;
- pSrc[2 * i + 1] = a1;
-
- pSrc[2 * l] = p0 - p1;
- pSrc[2 * l + 1] = p2 + p3;
-
- i += n1;
- } while( i < fftLen ); // butterfly loop end
- j++;
- } while( j < n2 ); // groups loop end
-
- twidCoefModifier = twidCoefModifier << 1u;
- } // stages loop end
-
- n1 = n2;
- n2 = n2 >> 1;
-
- // loop for butterfly
- for (i = 0; i < fftLen; i += n1)
- {
- l = i + n2;
-
- a0 = pSrc[2 * i] + pSrc[2 * l];
- xt = pSrc[2 * i] - pSrc[2 * l];
-
- a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
- yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
-
- p0 = a0 * onebyfftLen;
- p2 = xt * onebyfftLen;
- p1 = a1 * onebyfftLen;
- p3 = yt * onebyfftLen;
-
- pSrc[2 * i] = p0;
- pSrc[2u * l] = p2;
-
- pSrc[2 * i + 1] = p1;
- pSrc[2u * l + 1u] = p3;
- } // butterfly loop end
-
-#endif // #ifndef ARM_MATH_CM0_FAMILY
-
-}
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_f32.c
deleted file mode 100644
index 64fd956..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_f32.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_cfft_radix4_init_f32.c
-*
-* Description: Radix-4 Decimation in Frequency Floating-point CFFT & CIFFT Initialization function
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-#include "arm_common_tables.h"
-
-/**
- * @ingroup groupTransforms
- */
-
-/**
- * @addtogroup ComplexFFT
- * @{
- */
-
-/**
-* @brief Initialization function for the floating-point CFFT/CIFFT.
-* @deprecated Do not use this function. It has been superseded by \ref arm_cfft_f32 and will be removed
-* in the future.
-* @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.
-*
-* \par Description:
-* \par
-* The parameter ifftFlag
controls whether a forward or inverse transform is computed.
-* Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated
-* \par
-* The parameter bitReverseFlag
controls whether output is in normal order or bit reversed order.
-* Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order.
-* \par
-* The parameter fftLen
Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024.
-* \par
-* This Function also initializes Twiddle factor table pointer and Bit reversal table pointer.
-*/
-arm_status arm_cfft_radix2_init_f32(
- arm_cfft_radix2_instance_f32 * S,
- uint16_t fftLen,
- uint8_t ifftFlag,
- uint8_t bitReverseFlag)
-{
- /* Initialise the default arm status */
- arm_status status = ARM_MATH_SUCCESS;
-
- /* Initialise the FFT length */
- S->fftLen = fftLen;
-
- /* Initialise the Twiddle coefficient pointer */
- S->pTwiddle = (float32_t *) twiddleCoef;
-
- /* Initialise the Flag for selection of CFFT or CIFFT */
- S->ifftFlag = ifftFlag;
-
- /* Initialise the Flag for calculation Bit reversal or not */
- S->bitReverseFlag = bitReverseFlag;
-
- /* Initializations of structure parameters depending on the FFT length */
- switch (S->fftLen)
- {
-
- case 4096u:
- /* Initializations of structure parameters for 4096 point FFT */
-
- /* Initialise the twiddle coef modifier value */
- S->twidCoefModifier = 1u;
- /* Initialise the bit reversal table modifier */
- S->bitRevFactor = 1u;
- /* Initialise the bit reversal table pointer */
- S->pBitRevTable = (uint16_t *) armBitRevTable;
- /* Initialise the 1/fftLen Value */
- S->onebyfftLen = 0.000244140625;
- break;
-
- case 2048u:
- /* Initializations of structure parameters for 2048 point FFT */
-
- /* Initialise the twiddle coef modifier value */
- S->twidCoefModifier = 2u;
- /* Initialise the bit reversal table modifier */
- S->bitRevFactor = 2u;
- /* Initialise the bit reversal table pointer */
- S->pBitRevTable = (uint16_t *) & armBitRevTable[1];
- /* Initialise the 1/fftLen Value */
- S->onebyfftLen = 0.00048828125;
- break;
-
- case 1024u:
- /* Initializations of structure parameters for 1024 point FFT */
-
- /* Initialise the twiddle coef modifier value */
- S->twidCoefModifier = 4u;
- /* Initialise the bit reversal table modifier */
- S->bitRevFactor = 4u;
- /* Initialise the bit reversal table pointer */
- S->pBitRevTable = (uint16_t *) & armBitRevTable[3];
- /* Initialise the 1/fftLen Value */
- S->onebyfftLen = 0.0009765625f;
- break;
-
- case 512u:
- /* Initializations of structure parameters for 512 point FFT */
-
- /* Initialise the twiddle coef modifier value */
- S->twidCoefModifier = 8u;
- /* Initialise the bit reversal table modifier */
- S->bitRevFactor = 8u;
- /* Initialise the bit reversal table pointer */
- S->pBitRevTable = (uint16_t *) & armBitRevTable[7];
- /* Initialise the 1/fftLen Value */
- S->onebyfftLen = 0.001953125;
- break;
-
- case 256u:
- /* Initializations of structure parameters for 256 point FFT */
- S->twidCoefModifier = 16u;
- S->bitRevFactor = 16u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[15];
- S->onebyfftLen = 0.00390625f;
- break;
-
- case 128u:
- /* Initializations of structure parameters for 128 point FFT */
- S->twidCoefModifier = 32u;
- S->bitRevFactor = 32u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[31];
- S->onebyfftLen = 0.0078125;
- break;
-
- case 64u:
- /* Initializations of structure parameters for 64 point FFT */
- S->twidCoefModifier = 64u;
- S->bitRevFactor = 64u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[63];
- S->onebyfftLen = 0.015625f;
- break;
-
- case 32u:
- /* Initializations of structure parameters for 64 point FFT */
- S->twidCoefModifier = 128u;
- S->bitRevFactor = 128u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[127];
- S->onebyfftLen = 0.03125;
- break;
-
- case 16u:
- /* Initializations of structure parameters for 16 point FFT */
- S->twidCoefModifier = 256u;
- S->bitRevFactor = 256u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[255];
- S->onebyfftLen = 0.0625f;
- break;
-
-
- default:
- /* Reporting argument error if fftSize is not valid value */
- status = ARM_MATH_ARGUMENT_ERROR;
- break;
- }
-
- return (status);
-}
-
-/**
- * @} end of ComplexFFT group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_q15.c
deleted file mode 100644
index 1577c5e..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_q15.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_cfft_radix2_init_q15.c
-*
-* Description: Radix-2 Decimation in Frequency Q15 FFT & IFFT initialization function
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-#include "arm_common_tables.h"
-
-/**
- * @ingroup groupTransforms
- */
-
-
-/**
- * @addtogroup ComplexFFT
- * @{
- */
-
-/**
-* @brief Initialization function for the Q15 CFFT/CIFFT.
-* @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q15 and will be removed
-* @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 The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen
is not a supported value.
-*
-* \par Description:
-* \par
-* The parameter ifftFlag
controls whether a forward or inverse transform is computed.
-* Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated
-* \par
-* The parameter bitReverseFlag
controls whether output is in normal order or bit reversed order.
-* Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order.
-* \par
-* The parameter fftLen
Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024.
-* \par
-* This Function also initializes Twiddle factor table pointer and Bit reversal table pointer.
-*/
-
-arm_status arm_cfft_radix2_init_q15(
- arm_cfft_radix2_instance_q15 * S,
- uint16_t fftLen,
- uint8_t ifftFlag,
- uint8_t bitReverseFlag)
-{
- /* Initialise the default arm status */
- arm_status status = ARM_MATH_SUCCESS;
-
- /* Initialise the FFT length */
- S->fftLen = fftLen;
-
- /* Initialise the Twiddle coefficient pointer */
- S->pTwiddle = (q15_t *) twiddleCoef_4096_q15;
- /* Initialise the Flag for selection of CFFT or CIFFT */
- S->ifftFlag = ifftFlag;
- /* Initialise the Flag for calculation Bit reversal or not */
- S->bitReverseFlag = bitReverseFlag;
-
- /* Initializations of structure parameters depending on the FFT length */
- switch (S->fftLen)
- {
- case 4096u:
- /* Initializations of structure parameters for 4096 point FFT */
-
- /* Initialise the twiddle coef modifier value */
- S->twidCoefModifier = 1u;
- /* Initialise the bit reversal table modifier */
- S->bitRevFactor = 1u;
- /* Initialise the bit reversal table pointer */
- S->pBitRevTable = (uint16_t *) armBitRevTable;
-
- break;
-
- case 2048u:
- /* Initializations of structure parameters for 2048 point FFT */
-
- /* Initialise the twiddle coef modifier value */
- S->twidCoefModifier = 2u;
- /* Initialise the bit reversal table modifier */
- S->bitRevFactor = 2u;
- /* Initialise the bit reversal table pointer */
- S->pBitRevTable = (uint16_t *) & armBitRevTable[1];
-
- break;
-
- case 1024u:
- /* Initializations of structure parameters for 1024 point FFT */
- S->twidCoefModifier = 4u;
- S->bitRevFactor = 4u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[3];
-
- break;
-
- case 512u:
- /* Initializations of structure parameters for 512 point FFT */
- S->twidCoefModifier = 8u;
- S->bitRevFactor = 8u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[7];
-
- break;
-
- case 256u:
- /* Initializations of structure parameters for 256 point FFT */
- S->twidCoefModifier = 16u;
- S->bitRevFactor = 16u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[15];
-
- break;
-
- case 128u:
- /* Initializations of structure parameters for 128 point FFT */
- S->twidCoefModifier = 32u;
- S->bitRevFactor = 32u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[31];
-
- break;
-
- case 64u:
- /* Initializations of structure parameters for 64 point FFT */
- S->twidCoefModifier = 64u;
- S->bitRevFactor = 64u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[63];
-
- break;
-
- case 32u:
- /* Initializations of structure parameters for 32 point FFT */
- S->twidCoefModifier = 128u;
- S->bitRevFactor = 128u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[127];
-
- break;
-
- case 16u:
- /* Initializations of structure parameters for 16 point FFT */
- S->twidCoefModifier = 256u;
- S->bitRevFactor = 256u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[255];
-
- break;
-
- default:
- /* Reporting argument error if fftSize is not valid value */
- status = ARM_MATH_ARGUMENT_ERROR;
- break;
- }
-
- return (status);
-}
-
-/**
- * @} end of ComplexFFT group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_q31.c
deleted file mode 100644
index 61ebaad..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_q31.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_cfft_radix2_init_q31.c
-*
-* Description: Radix-2 Decimation in Frequency Fixed-point CFFT & CIFFT Initialization function
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-#include "arm_common_tables.h"
-
-/**
- * @ingroup groupTransforms
- */
-
-/**
- * @addtogroup ComplexFFT
- * @{
- */
-
-
-/**
-*
-* @brief Initialization function for the Q31 CFFT/CIFFT.
-* @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q31 and will be removed
-* @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 The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen
is not a supported value.
-*
-* \par Description:
-* \par
-* The parameter ifftFlag
controls whether a forward or inverse transform is computed.
-* Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated
-* \par
-* The parameter bitReverseFlag
controls whether output is in normal order or bit reversed order.
-* Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order.
-* \par
-* The parameter fftLen
Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024.
-* \par
-* This Function also initializes Twiddle factor table pointer and Bit reversal table pointer.
-*/
-
-arm_status arm_cfft_radix2_init_q31(
- arm_cfft_radix2_instance_q31 * S,
- uint16_t fftLen,
- uint8_t ifftFlag,
- uint8_t bitReverseFlag)
-{
- /* Initialise the default arm status */
- arm_status status = ARM_MATH_SUCCESS;
-
- /* Initialise the FFT length */
- S->fftLen = fftLen;
-
- /* Initialise the Twiddle coefficient pointer */
- S->pTwiddle = (q31_t *) twiddleCoef_4096_q31;
- /* Initialise the Flag for selection of CFFT or CIFFT */
- S->ifftFlag = ifftFlag;
- /* Initialise the Flag for calculation Bit reversal or not */
- S->bitReverseFlag = bitReverseFlag;
-
- /* Initializations of Instance structure depending on the FFT length */
- switch (S->fftLen)
- {
- /* Initializations of structure parameters for 4096 point FFT */
- case 4096u:
- /* Initialise the twiddle coef modifier value */
- S->twidCoefModifier = 1u;
- /* Initialise the bit reversal table modifier */
- S->bitRevFactor = 1u;
- /* Initialise the bit reversal table pointer */
- S->pBitRevTable = (uint16_t *) armBitRevTable;
- break;
-
- /* Initializations of structure parameters for 2048 point FFT */
- case 2048u:
- /* Initialise the twiddle coef modifier value */
- S->twidCoefModifier = 2u;
- /* Initialise the bit reversal table modifier */
- S->bitRevFactor = 2u;
- /* Initialise the bit reversal table pointer */
- S->pBitRevTable = (uint16_t *) & armBitRevTable[1];
- break;
-
- /* Initializations of structure parameters for 1024 point FFT */
- case 1024u:
- /* Initialise the twiddle coef modifier value */
- S->twidCoefModifier = 4u;
- /* Initialise the bit reversal table modifier */
- S->bitRevFactor = 4u;
- /* Initialise the bit reversal table pointer */
- S->pBitRevTable = (uint16_t *) & armBitRevTable[3];
- break;
-
- /* Initializations of structure parameters for 512 point FFT */
- case 512u:
- /* Initialise the twiddle coef modifier value */
- S->twidCoefModifier = 8u;
- /* Initialise the bit reversal table modifier */
- S->bitRevFactor = 8u;
- /* Initialise the bit reversal table pointer */
- S->pBitRevTable = (uint16_t *) & armBitRevTable[7];
- break;
-
- case 256u:
- /* Initializations of structure parameters for 256 point FFT */
- S->twidCoefModifier = 16u;
- S->bitRevFactor = 16u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[15];
- break;
-
- case 128u:
- /* Initializations of structure parameters for 128 point FFT */
- S->twidCoefModifier = 32u;
- S->bitRevFactor = 32u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[31];
- break;
-
- case 64u:
- /* Initializations of structure parameters for 64 point FFT */
- S->twidCoefModifier = 64u;
- S->bitRevFactor = 64u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[63];
- break;
-
- case 32u:
- /* Initializations of structure parameters for 32 point FFT */
- S->twidCoefModifier = 128u;
- S->bitRevFactor = 128u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[127];
- break;
-
- case 16u:
- /* Initializations of structure parameters for 16 point FFT */
- S->twidCoefModifier = 256u;
- S->bitRevFactor = 256u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[255];
- break;
-
-
- default:
- /* Reporting argument error if fftSize is not valid value */
- status = ARM_MATH_ARGUMENT_ERROR;
- break;
- }
-
- return (status);
-}
-
-/**
- * @} end of ComplexFFT group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_q15.c
deleted file mode 100644
index ad05e1e..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_q15.c
+++ /dev/null
@@ -1,742 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_cfft_radix2_q15.c
-*
-* Description: Radix-2 Decimation in Frequency CFFT & CIFFT Fixed point processing function
-*
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-void arm_radix2_butterfly_q15(
- q15_t * pSrc,
- uint32_t fftLen,
- q15_t * pCoef,
- uint16_t twidCoefModifier);
-
-void arm_radix2_butterfly_inverse_q15(
- q15_t * pSrc,
- uint32_t fftLen,
- q15_t * pCoef,
- uint16_t twidCoefModifier);
-
-void arm_bitreversal_q15(
- q15_t * pSrc,
- uint32_t fftLen,
- uint16_t bitRevFactor,
- uint16_t * pBitRevTab);
-
-/**
- * @ingroup groupTransforms
- */
-
-/**
- * @addtogroup ComplexFFT
- * @{
- */
-
-/**
- * @details
- * @brief Processing function for the fixed-point CFFT/CIFFT.
- * @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q15 and will be removed
- * @param[in] *S points to an instance of the fixed-point CFFT/CIFFT structure.
- * @param[in, out] *pSrc points to the complex data buffer of size 2*fftLen
. Processing occurs in-place.
- * @return none.
- */
-
-void arm_cfft_radix2_q15(
- const arm_cfft_radix2_instance_q15 * S,
- q15_t * pSrc)
-{
-
- if(S->ifftFlag == 1u)
- {
- arm_radix2_butterfly_inverse_q15(pSrc, S->fftLen,
- S->pTwiddle, S->twidCoefModifier);
- }
- else
- {
- arm_radix2_butterfly_q15(pSrc, S->fftLen,
- S->pTwiddle, S->twidCoefModifier);
- }
-
- arm_bitreversal_q15(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
-}
-
-/**
- * @} end of ComplexFFT group
- */
-
-void arm_radix2_butterfly_q15(
- q15_t * pSrc,
- uint32_t fftLen,
- q15_t * pCoef,
- uint16_t twidCoefModifier)
-{
-#ifndef ARM_MATH_CM0_FAMILY
-
- unsigned i, j, k, l;
- unsigned n1, n2, ia;
- q15_t in;
- q31_t T, S, R;
- q31_t coeff, out1, out2;
-
- //N = fftLen;
- n2 = fftLen;
-
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- // loop for groups
- for (i = 0; i < n2; i++)
- {
- coeff = _SIMD32_OFFSET(pCoef + (ia * 2u));
-
- ia = ia + twidCoefModifier;
-
- l = i + n2;
-
- T = _SIMD32_OFFSET(pSrc + (2 * i));
- in = ((int16_t) (T & 0xFFFF)) >> 1;
- T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF);
-
- S = _SIMD32_OFFSET(pSrc + (2 * l));
- in = ((int16_t) (S & 0xFFFF)) >> 1;
- S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF);
-
- R = __QSUB16(T, S);
-
- _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- out1 = __SMUAD(coeff, R) >> 16;
- out2 = __SMUSDX(coeff, R);
-
-#else
-
- out1 = __SMUSDX(R, coeff) >> 16u;
- out2 = __SMUAD(coeff, R);
-
-#endif // #ifndef ARM_MATH_BIG_ENDIAN
-
- _SIMD32_OFFSET(pSrc + (2u * l)) =
- (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
-
- coeff = _SIMD32_OFFSET(pCoef + (ia * 2u));
-
- ia = ia + twidCoefModifier;
-
- // loop for butterfly
- i++;
- l++;
-
- T = _SIMD32_OFFSET(pSrc + (2 * i));
- in = ((int16_t) (T & 0xFFFF)) >> 1;
- T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF);
-
- S = _SIMD32_OFFSET(pSrc + (2 * l));
- in = ((int16_t) (S & 0xFFFF)) >> 1;
- S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF);
-
- R = __QSUB16(T, S);
-
- _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- out1 = __SMUAD(coeff, R) >> 16;
- out2 = __SMUSDX(coeff, R);
-
-#else
-
- out1 = __SMUSDX(R, coeff) >> 16u;
- out2 = __SMUAD(coeff, R);
-
-#endif // #ifndef ARM_MATH_BIG_ENDIAN
-
- _SIMD32_OFFSET(pSrc + (2u * l)) =
- (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
-
- } // groups loop end
-
- twidCoefModifier = twidCoefModifier << 1u;
-
- // loop for stage
- for (k = fftLen / 2; k > 2; k = k >> 1)
- {
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- // loop for groups
- for (j = 0; j < n2; j++)
- {
- coeff = _SIMD32_OFFSET(pCoef + (ia * 2u));
-
- ia = ia + twidCoefModifier;
-
- // loop for butterfly
- for (i = j; i < fftLen; i += n1)
- {
- l = i + n2;
-
- T = _SIMD32_OFFSET(pSrc + (2 * i));
-
- S = _SIMD32_OFFSET(pSrc + (2 * l));
-
- R = __QSUB16(T, S);
-
- _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- out1 = __SMUAD(coeff, R) >> 16;
- out2 = __SMUSDX(coeff, R);
-
-#else
-
- out1 = __SMUSDX(R, coeff) >> 16u;
- out2 = __SMUAD(coeff, R);
-
-#endif // #ifndef ARM_MATH_BIG_ENDIAN
-
- _SIMD32_OFFSET(pSrc + (2u * l)) =
- (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
-
- i += n1;
-
- l = i + n2;
-
- T = _SIMD32_OFFSET(pSrc + (2 * i));
-
- S = _SIMD32_OFFSET(pSrc + (2 * l));
-
- R = __QSUB16(T, S);
-
- _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- out1 = __SMUAD(coeff, R) >> 16;
- out2 = __SMUSDX(coeff, R);
-
-#else
-
- out1 = __SMUSDX(R, coeff) >> 16u;
- out2 = __SMUAD(coeff, R);
-
-#endif // #ifndef ARM_MATH_BIG_ENDIAN
-
- _SIMD32_OFFSET(pSrc + (2u * l)) =
- (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
-
- } // butterfly loop end
-
- } // groups loop end
-
- twidCoefModifier = twidCoefModifier << 1u;
- } // stages loop end
-
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- coeff = _SIMD32_OFFSET(pCoef + (ia * 2u));
-
- ia = ia + twidCoefModifier;
-
- // loop for butterfly
- for (i = 0; i < fftLen; i += n1)
- {
- l = i + n2;
-
- T = _SIMD32_OFFSET(pSrc + (2 * i));
-
- S = _SIMD32_OFFSET(pSrc + (2 * l));
-
- R = __QSUB16(T, S);
-
- _SIMD32_OFFSET(pSrc + (2 * i)) = __QADD16(T, S);
-
- _SIMD32_OFFSET(pSrc + (2u * l)) = R;
-
- i += n1;
- l = i + n2;
-
- T = _SIMD32_OFFSET(pSrc + (2 * i));
-
- S = _SIMD32_OFFSET(pSrc + (2 * l));
-
- R = __QSUB16(T, S);
-
- _SIMD32_OFFSET(pSrc + (2 * i)) = __QADD16(T, S);
-
- _SIMD32_OFFSET(pSrc + (2u * l)) = R;
-
- } // groups loop end
-
-
-#else
-
- unsigned i, j, k, l;
- unsigned n1, n2, ia;
- q15_t xt, yt, cosVal, sinVal;
-
-
- //N = fftLen;
- n2 = fftLen;
-
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- // loop for groups
- for (j = 0; j < n2; j++)
- {
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
- ia = ia + twidCoefModifier;
-
- // loop for butterfly
- for (i = j; i < fftLen; i += n1)
- {
- l = i + n2;
- xt = (pSrc[2 * i] >> 1u) - (pSrc[2 * l] >> 1u);
- pSrc[2 * i] = ((pSrc[2 * i] >> 1u) + (pSrc[2 * l] >> 1u)) >> 1u;
-
- yt = (pSrc[2 * i + 1] >> 1u) - (pSrc[2 * l + 1] >> 1u);
- pSrc[2 * i + 1] =
- ((pSrc[2 * l + 1] >> 1u) + (pSrc[2 * i + 1] >> 1u)) >> 1u;
-
- pSrc[2u * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) +
- ((int16_t) (((q31_t) yt * sinVal) >> 16)));
-
- pSrc[2u * l + 1u] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) -
- ((int16_t) (((q31_t) xt * sinVal) >> 16)));
-
- } // butterfly loop end
-
- } // groups loop end
-
- twidCoefModifier = twidCoefModifier << 1u;
-
- // loop for stage
- for (k = fftLen / 2; k > 2; k = k >> 1)
- {
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- // loop for groups
- for (j = 0; j < n2; j++)
- {
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
- ia = ia + twidCoefModifier;
-
- // loop for butterfly
- for (i = j; i < fftLen; i += n1)
- {
- l = i + n2;
- xt = pSrc[2 * i] - pSrc[2 * l];
- pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1u;
-
- yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
- pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1u;
-
- pSrc[2u * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) +
- ((int16_t) (((q31_t) yt * sinVal) >> 16)));
-
- pSrc[2u * l + 1u] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) -
- ((int16_t) (((q31_t) xt * sinVal) >> 16)));
-
- } // butterfly loop end
-
- } // groups loop end
-
- twidCoefModifier = twidCoefModifier << 1u;
- } // stages loop end
-
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- // loop for groups
- for (j = 0; j < n2; j++)
- {
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
-
- ia = ia + twidCoefModifier;
-
- // loop for butterfly
- for (i = j; i < fftLen; i += n1)
- {
- l = i + n2;
- xt = pSrc[2 * i] - pSrc[2 * l];
- pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
-
- yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
- pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
-
- pSrc[2u * l] = xt;
-
- pSrc[2u * l + 1u] = yt;
-
- } // butterfly loop end
-
- } // groups loop end
-
- twidCoefModifier = twidCoefModifier << 1u;
-
-#endif // #ifndef ARM_MATH_CM0_FAMILY
-
-}
-
-
-void arm_radix2_butterfly_inverse_q15(
- q15_t * pSrc,
- uint32_t fftLen,
- q15_t * pCoef,
- uint16_t twidCoefModifier)
-{
-#ifndef ARM_MATH_CM0_FAMILY
-
- unsigned i, j, k, l;
- unsigned n1, n2, ia;
- q15_t in;
- q31_t T, S, R;
- q31_t coeff, out1, out2;
-
- //N = fftLen;
- n2 = fftLen;
-
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- // loop for groups
- for (i = 0; i < n2; i++)
- {
- coeff = _SIMD32_OFFSET(pCoef + (ia * 2u));
-
- ia = ia + twidCoefModifier;
-
- l = i + n2;
-
- T = _SIMD32_OFFSET(pSrc + (2 * i));
- in = ((int16_t) (T & 0xFFFF)) >> 1;
- T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF);
-
- S = _SIMD32_OFFSET(pSrc + (2 * l));
- in = ((int16_t) (S & 0xFFFF)) >> 1;
- S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF);
-
- R = __QSUB16(T, S);
-
- _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- out1 = __SMUSD(coeff, R) >> 16;
- out2 = __SMUADX(coeff, R);
-#else
-
- out1 = __SMUADX(R, coeff) >> 16u;
- out2 = __SMUSD(__QSUB(0, coeff), R);
-
-#endif // #ifndef ARM_MATH_BIG_ENDIAN
-
- _SIMD32_OFFSET(pSrc + (2u * l)) =
- (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
-
- coeff = _SIMD32_OFFSET(pCoef + (ia * 2u));
-
- ia = ia + twidCoefModifier;
-
- // loop for butterfly
- i++;
- l++;
-
- T = _SIMD32_OFFSET(pSrc + (2 * i));
- in = ((int16_t) (T & 0xFFFF)) >> 1;
- T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF);
-
- S = _SIMD32_OFFSET(pSrc + (2 * l));
- in = ((int16_t) (S & 0xFFFF)) >> 1;
- S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF);
-
- R = __QSUB16(T, S);
-
- _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- out1 = __SMUSD(coeff, R) >> 16;
- out2 = __SMUADX(coeff, R);
-#else
-
- out1 = __SMUADX(R, coeff) >> 16u;
- out2 = __SMUSD(__QSUB(0, coeff), R);
-
-#endif // #ifndef ARM_MATH_BIG_ENDIAN
-
- _SIMD32_OFFSET(pSrc + (2u * l)) =
- (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
-
- } // groups loop end
-
- twidCoefModifier = twidCoefModifier << 1u;
-
- // loop for stage
- for (k = fftLen / 2; k > 2; k = k >> 1)
- {
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- // loop for groups
- for (j = 0; j < n2; j++)
- {
- coeff = _SIMD32_OFFSET(pCoef + (ia * 2u));
-
- ia = ia + twidCoefModifier;
-
- // loop for butterfly
- for (i = j; i < fftLen; i += n1)
- {
- l = i + n2;
-
- T = _SIMD32_OFFSET(pSrc + (2 * i));
-
- S = _SIMD32_OFFSET(pSrc + (2 * l));
-
- R = __QSUB16(T, S);
-
- _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- out1 = __SMUSD(coeff, R) >> 16;
- out2 = __SMUADX(coeff, R);
-
-#else
-
- out1 = __SMUADX(R, coeff) >> 16u;
- out2 = __SMUSD(__QSUB(0, coeff), R);
-
-#endif // #ifndef ARM_MATH_BIG_ENDIAN
-
- _SIMD32_OFFSET(pSrc + (2u * l)) =
- (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
-
- i += n1;
-
- l = i + n2;
-
- T = _SIMD32_OFFSET(pSrc + (2 * i));
-
- S = _SIMD32_OFFSET(pSrc + (2 * l));
-
- R = __QSUB16(T, S);
-
- _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- out1 = __SMUSD(coeff, R) >> 16;
- out2 = __SMUADX(coeff, R);
-#else
-
- out1 = __SMUADX(R, coeff) >> 16u;
- out2 = __SMUSD(__QSUB(0, coeff), R);
-
-#endif // #ifndef ARM_MATH_BIG_ENDIAN
-
- _SIMD32_OFFSET(pSrc + (2u * l)) =
- (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
-
- } // butterfly loop end
-
- } // groups loop end
-
- twidCoefModifier = twidCoefModifier << 1u;
- } // stages loop end
-
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- // loop for groups
- for (j = 0; j < n2; j++)
- {
- coeff = _SIMD32_OFFSET(pCoef + (ia * 2u));
-
- ia = ia + twidCoefModifier;
-
- // loop for butterfly
- for (i = j; i < fftLen; i += n1)
- {
- l = i + n2;
-
- T = _SIMD32_OFFSET(pSrc + (2 * i));
-
- S = _SIMD32_OFFSET(pSrc + (2 * l));
-
- R = __QSUB16(T, S);
-
- _SIMD32_OFFSET(pSrc + (2 * i)) = __QADD16(T, S);
-
- _SIMD32_OFFSET(pSrc + (2u * l)) = R;
-
- } // butterfly loop end
-
- } // groups loop end
-
- twidCoefModifier = twidCoefModifier << 1u;
-
-#else
-
-
- unsigned i, j, k, l;
- unsigned n1, n2, ia;
- q15_t xt, yt, cosVal, sinVal;
-
- //N = fftLen;
- n2 = fftLen;
-
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- // loop for groups
- for (j = 0; j < n2; j++)
- {
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
- ia = ia + twidCoefModifier;
-
- // loop for butterfly
- for (i = j; i < fftLen; i += n1)
- {
- l = i + n2;
- xt = (pSrc[2 * i] >> 1u) - (pSrc[2 * l] >> 1u);
- pSrc[2 * i] = ((pSrc[2 * i] >> 1u) + (pSrc[2 * l] >> 1u)) >> 1u;
-
- yt = (pSrc[2 * i + 1] >> 1u) - (pSrc[2 * l + 1] >> 1u);
- pSrc[2 * i + 1] =
- ((pSrc[2 * l + 1] >> 1u) + (pSrc[2 * i + 1] >> 1u)) >> 1u;
-
- pSrc[2u * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) -
- ((int16_t) (((q31_t) yt * sinVal) >> 16)));
-
- pSrc[2u * l + 1u] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) +
- ((int16_t) (((q31_t) xt * sinVal) >> 16)));
-
- } // butterfly loop end
-
- } // groups loop end
-
- twidCoefModifier = twidCoefModifier << 1u;
-
- // loop for stage
- for (k = fftLen / 2; k > 2; k = k >> 1)
- {
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- // loop for groups
- for (j = 0; j < n2; j++)
- {
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
- ia = ia + twidCoefModifier;
-
- // loop for butterfly
- for (i = j; i < fftLen; i += n1)
- {
- l = i + n2;
- xt = pSrc[2 * i] - pSrc[2 * l];
- pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1u;
-
- yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
- pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1u;
-
- pSrc[2u * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) -
- ((int16_t) (((q31_t) yt * sinVal) >> 16)));
-
- pSrc[2u * l + 1u] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) +
- ((int16_t) (((q31_t) xt * sinVal) >> 16)));
-
- } // butterfly loop end
-
- } // groups loop end
-
- twidCoefModifier = twidCoefModifier << 1u;
- } // stages loop end
-
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
-
- ia = ia + twidCoefModifier;
-
- // loop for butterfly
- for (i = 0; i < fftLen; i += n1)
- {
- l = i + n2;
- xt = pSrc[2 * i] - pSrc[2 * l];
- pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
-
- yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
- pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
-
- pSrc[2u * l] = xt;
-
- pSrc[2u * l + 1u] = yt;
-
- } // groups loop end
-
-
-#endif // #ifndef ARM_MATH_CM0_FAMILY
-
-}
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_q31.c
deleted file mode 100644
index e72408f..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_q31.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_cfft_radix2_q31.c
-*
-* Description: Radix-2 Decimation in Frequency CFFT & CIFFT Fixed point processing function
-*
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-void arm_radix2_butterfly_q31(
- q31_t * pSrc,
- uint32_t fftLen,
- q31_t * pCoef,
- uint16_t twidCoefModifier);
-
-void arm_radix2_butterfly_inverse_q31(
- q31_t * pSrc,
- uint32_t fftLen,
- q31_t * pCoef,
- uint16_t twidCoefModifier);
-
-void arm_bitreversal_q31(
- q31_t * pSrc,
- uint32_t fftLen,
- uint16_t bitRevFactor,
- uint16_t * pBitRevTab);
-
-/**
-* @ingroup groupTransforms
-*/
-
-/**
-* @addtogroup ComplexFFT
-* @{
-*/
-
-/**
-* @details
-* @brief Processing function for the fixed-point CFFT/CIFFT.
-* @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q31 and will be removed
-* @param[in] *S points to an instance of the fixed-point CFFT/CIFFT structure.
-* @param[in, out] *pSrc points to the complex data buffer of size 2*fftLen
. Processing occurs in-place.
-* @return none.
-*/
-
-void arm_cfft_radix2_q31(
-const arm_cfft_radix2_instance_q31 * S,
-q31_t * pSrc)
-{
-
- if(S->ifftFlag == 1u)
- {
- arm_radix2_butterfly_inverse_q31(pSrc, S->fftLen,
- S->pTwiddle, S->twidCoefModifier);
- }
- else
- {
- arm_radix2_butterfly_q31(pSrc, S->fftLen,
- S->pTwiddle, S->twidCoefModifier);
- }
-
- arm_bitreversal_q31(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
-}
-
-/**
-* @} end of ComplexFFT group
-*/
-
-void arm_radix2_butterfly_q31(
-q31_t * pSrc,
-uint32_t fftLen,
-q31_t * pCoef,
-uint16_t twidCoefModifier)
-{
-
- unsigned i, j, k, l, m;
- unsigned n1, n2, ia;
- q31_t xt, yt, cosVal, sinVal;
- q31_t p0, p1;
-
- //N = fftLen;
- n2 = fftLen;
-
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- // loop for groups
- for (i = 0; i < n2; i++)
- {
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
- ia = ia + twidCoefModifier;
-
- l = i + n2;
- xt = (pSrc[2 * i] >> 1u) - (pSrc[2 * l] >> 1u);
- pSrc[2 * i] = ((pSrc[2 * i] >> 1u) + (pSrc[2 * l] >> 1u)) >> 1u;
-
- yt = (pSrc[2 * i + 1] >> 1u) - (pSrc[2 * l + 1] >> 1u);
- pSrc[2 * i + 1] =
- ((pSrc[2 * l + 1] >> 1u) + (pSrc[2 * i + 1] >> 1u)) >> 1u;
-
- mult_32x32_keep32_R(p0, xt, cosVal);
- mult_32x32_keep32_R(p1, yt, cosVal);
- multAcc_32x32_keep32_R(p0, yt, sinVal);
- multSub_32x32_keep32_R(p1, xt, sinVal);
-
- pSrc[2u * l] = p0;
- pSrc[2u * l + 1u] = p1;
-
- } // groups loop end
-
- twidCoefModifier <<= 1u;
-
- // loop for stage
- for (k = fftLen / 2; k > 2; k = k >> 1)
- {
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- // loop for groups
- for (j = 0; j < n2; j++)
- {
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
- ia = ia + twidCoefModifier;
-
- // loop for butterfly
- i = j;
- m = fftLen / n1;
- do
- {
- l = i + n2;
- xt = pSrc[2 * i] - pSrc[2 * l];
- pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1u;
-
- yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
- pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1u;
-
- mult_32x32_keep32_R(p0, xt, cosVal);
- mult_32x32_keep32_R(p1, yt, cosVal);
- multAcc_32x32_keep32_R(p0, yt, sinVal);
- multSub_32x32_keep32_R(p1, xt, sinVal);
-
- pSrc[2u * l] = p0;
- pSrc[2u * l + 1u] = p1;
- i += n1;
- m--;
- } while( m > 0); // butterfly loop end
-
- } // groups loop end
-
- twidCoefModifier <<= 1u;
- } // stages loop end
-
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
- ia = ia + twidCoefModifier;
-
- // loop for butterfly
- for (i = 0; i < fftLen; i += n1)
- {
- l = i + n2;
- xt = pSrc[2 * i] - pSrc[2 * l];
- pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
-
- yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
- pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
-
- pSrc[2u * l] = xt;
-
- pSrc[2u * l + 1u] = yt;
-
- i += n1;
- l = i + n2;
-
- xt = pSrc[2 * i] - pSrc[2 * l];
- pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
-
- yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
- pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
-
- pSrc[2u * l] = xt;
-
- pSrc[2u * l + 1u] = yt;
-
- } // butterfly loop end
-
-}
-
-
-void arm_radix2_butterfly_inverse_q31(
-q31_t * pSrc,
-uint32_t fftLen,
-q31_t * pCoef,
-uint16_t twidCoefModifier)
-{
-
- unsigned i, j, k, l;
- unsigned n1, n2, ia;
- q31_t xt, yt, cosVal, sinVal;
- q31_t p0, p1;
-
- //N = fftLen;
- n2 = fftLen;
-
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- // loop for groups
- for (i = 0; i < n2; i++)
- {
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
- ia = ia + twidCoefModifier;
-
- l = i + n2;
- xt = (pSrc[2 * i] >> 1u) - (pSrc[2 * l] >> 1u);
- pSrc[2 * i] = ((pSrc[2 * i] >> 1u) + (pSrc[2 * l] >> 1u)) >> 1u;
-
- yt = (pSrc[2 * i + 1] >> 1u) - (pSrc[2 * l + 1] >> 1u);
- pSrc[2 * i + 1] =
- ((pSrc[2 * l + 1] >> 1u) + (pSrc[2 * i + 1] >> 1u)) >> 1u;
-
- mult_32x32_keep32_R(p0, xt, cosVal);
- mult_32x32_keep32_R(p1, yt, cosVal);
- multSub_32x32_keep32_R(p0, yt, sinVal);
- multAcc_32x32_keep32_R(p1, xt, sinVal);
-
- pSrc[2u * l] = p0;
- pSrc[2u * l + 1u] = p1;
- } // groups loop end
-
- twidCoefModifier = twidCoefModifier << 1u;
-
- // loop for stage
- for (k = fftLen / 2; k > 2; k = k >> 1)
- {
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- // loop for groups
- for (j = 0; j < n2; j++)
- {
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
- ia = ia + twidCoefModifier;
-
- // loop for butterfly
- for (i = j; i < fftLen; i += n1)
- {
- l = i + n2;
- xt = pSrc[2 * i] - pSrc[2 * l];
- pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1u;
-
- yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
- pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1u;
-
- mult_32x32_keep32_R(p0, xt, cosVal);
- mult_32x32_keep32_R(p1, yt, cosVal);
- multSub_32x32_keep32_R(p0, yt, sinVal);
- multAcc_32x32_keep32_R(p1, xt, sinVal);
-
- pSrc[2u * l] = p0;
- pSrc[2u * l + 1u] = p1;
- } // butterfly loop end
-
- } // groups loop end
-
- twidCoefModifier = twidCoefModifier << 1u;
- } // stages loop end
-
- n1 = n2;
- n2 = n2 >> 1;
- ia = 0;
-
- cosVal = pCoef[ia * 2];
- sinVal = pCoef[(ia * 2) + 1];
- ia = ia + twidCoefModifier;
-
- // loop for butterfly
- for (i = 0; i < fftLen; i += n1)
- {
- l = i + n2;
- xt = pSrc[2 * i] - pSrc[2 * l];
- pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
-
- yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
- pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
-
- pSrc[2u * l] = xt;
-
- pSrc[2u * l + 1u] = yt;
-
- i += n1;
- l = i + n2;
-
- xt = pSrc[2 * i] - pSrc[2 * l];
- pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
-
- yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
- pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
-
- pSrc[2u * l] = xt;
-
- pSrc[2u * l + 1u] = yt;
-
- } // butterfly loop end
-
-}
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_f32.c
deleted file mode 100644
index b0f0a94..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_f32.c
+++ /dev/null
@@ -1,1210 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_cfft_radix4_f32.c
-*
-* Description: Radix-4 Decimation in Frequency CFFT & CIFFT Floating point processing function
-*
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-extern void arm_bitreversal_f32(
-float32_t * pSrc,
-uint16_t fftSize,
-uint16_t bitRevFactor,
-uint16_t * pBitRevTab);
-
-/**
-* @ingroup groupTransforms
-*/
-
-/* ----------------------------------------------------------------------
-** Internal helper function used by the FFTs
-** ------------------------------------------------------------------- */
-
-/*
-* @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)
-{
-
- float32_t co1, co2, co3, si1, si2, si3;
- uint32_t ia1, ia2, ia3;
- uint32_t i0, i1, i2, i3;
- uint32_t n1, n2, j, k;
-
-#ifndef ARM_MATH_CM0_FAMILY_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- float32_t xaIn, yaIn, xbIn, ybIn, xcIn, ycIn, xdIn, ydIn;
- float32_t Xaplusc, Xbplusd, Yaplusc, Ybplusd, Xaminusc, Xbminusd, Yaminusc,
- Ybminusd;
- float32_t Xb12C_out, Yb12C_out, Xc12C_out, Yc12C_out, Xd12C_out, Yd12C_out;
- float32_t Xb12_out, Yb12_out, Xc12_out, Yc12_out, Xd12_out, Yd12_out;
- float32_t *ptr1;
- float32_t p0,p1,p2,p3,p4,p5;
- float32_t a0,a1,a2,a3,a4,a5,a6,a7;
-
- /* Initializations for the first stage */
- n2 = fftLen;
- n1 = n2;
-
- /* n2 = fftLen/4 */
- n2 >>= 2u;
- i0 = 0u;
- ia1 = 0u;
-
- j = n2;
-
- /* Calculation of first stage */
- do
- {
- /* index calculation for the input as, */
- /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
- i1 = i0 + n2;
- i2 = i1 + n2;
- i3 = i2 + n2;
-
- xaIn = pSrc[(2u * i0)];
- yaIn = pSrc[(2u * i0) + 1u];
-
- xbIn = pSrc[(2u * i1)];
- ybIn = pSrc[(2u * i1) + 1u];
-
- xcIn = pSrc[(2u * i2)];
- ycIn = pSrc[(2u * i2) + 1u];
-
- xdIn = pSrc[(2u * i3)];
- ydIn = pSrc[(2u * i3) + 1u];
-
- /* xa + xc */
- Xaplusc = xaIn + xcIn;
- /* xb + xd */
- Xbplusd = xbIn + xdIn;
- /* ya + yc */
- Yaplusc = yaIn + ycIn;
- /* yb + yd */
- Ybplusd = ybIn + ydIn;
-
- /* index calculation for the coefficients */
- ia2 = ia1 + ia1;
- co2 = pCoef[ia2 * 2u];
- si2 = pCoef[(ia2 * 2u) + 1u];
-
- /* xa - xc */
- Xaminusc = xaIn - xcIn;
- /* xb - xd */
- Xbminusd = xbIn - xdIn;
- /* ya - yc */
- Yaminusc = yaIn - ycIn;
- /* yb - yd */
- Ybminusd = ybIn - ydIn;
-
- /* xa' = xa + xb + xc + xd */
- pSrc[(2u * i0)] = Xaplusc + Xbplusd;
- /* ya' = ya + yb + yc + yd */
- pSrc[(2u * i0) + 1u] = Yaplusc + Ybplusd;
-
- /* (xa - xc) + (yb - yd) */
- Xb12C_out = (Xaminusc + Ybminusd);
- /* (ya - yc) + (xb - xd) */
- Yb12C_out = (Yaminusc - Xbminusd);
- /* (xa + xc) - (xb + xd) */
- Xc12C_out = (Xaplusc - Xbplusd);
- /* (ya + yc) - (yb + yd) */
- Yc12C_out = (Yaplusc - Ybplusd);
- /* (xa - xc) - (yb - yd) */
- Xd12C_out = (Xaminusc - Ybminusd);
- /* (ya - yc) + (xb - xd) */
- Yd12C_out = (Xbminusd + Yaminusc);
-
- co1 = pCoef[ia1 * 2u];
- si1 = pCoef[(ia1 * 2u) + 1u];
-
- /* index calculation for the coefficients */
- ia3 = ia2 + ia1;
- co3 = pCoef[ia3 * 2u];
- si3 = pCoef[(ia3 * 2u) + 1u];
-
- Xb12_out = Xb12C_out * co1;
- Yb12_out = Yb12C_out * co1;
- Xc12_out = Xc12C_out * co2;
- Yc12_out = Yc12C_out * co2;
- Xd12_out = Xd12C_out * co3;
- Yd12_out = Yd12C_out * co3;
-
- /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
- //Xb12_out -= Yb12C_out * si1;
- p0 = Yb12C_out * si1;
- /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
- //Yb12_out += Xb12C_out * si1;
- p1 = Xb12C_out * si1;
- /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
- //Xc12_out -= Yc12C_out * si2;
- p2 = Yc12C_out * si2;
- /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
- //Yc12_out += Xc12C_out * si2;
- p3 = Xc12C_out * si2;
- /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
- //Xd12_out -= Yd12C_out * si3;
- p4 = Yd12C_out * si3;
- /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
- //Yd12_out += Xd12C_out * si3;
- p5 = Xd12C_out * si3;
-
- Xb12_out += p0;
- Yb12_out -= p1;
- Xc12_out += p2;
- Yc12_out -= p3;
- Xd12_out += p4;
- Yd12_out -= p5;
-
- /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */
- pSrc[2u * i1] = Xc12_out;
-
- /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */
- pSrc[(2u * i1) + 1u] = Yc12_out;
-
- /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */
- pSrc[2u * i2] = Xb12_out;
-
- /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */
- pSrc[(2u * i2) + 1u] = Yb12_out;
-
- /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */
- pSrc[2u * i3] = Xd12_out;
-
- /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */
- pSrc[(2u * i3) + 1u] = Yd12_out;
-
- /* Twiddle coefficients index modifier */
- ia1 += twidCoefModifier;
-
- /* Updating input index */
- i0++;
-
- }
- while(--j);
-
- twidCoefModifier <<= 2u;
-
- /* Calculation of second stage to excluding last stage */
- for (k = fftLen >> 2u; k > 4u; k >>= 2u)
- {
- /* Initializations for the first stage */
- n1 = n2;
- n2 >>= 2u;
- ia1 = 0u;
-
- /* Calculation of first stage */
- j = 0;
- do
- {
- /* index calculation for the coefficients */
- ia2 = ia1 + ia1;
- ia3 = ia2 + ia1;
- co1 = pCoef[ia1 * 2u];
- si1 = pCoef[(ia1 * 2u) + 1u];
- co2 = pCoef[ia2 * 2u];
- si2 = pCoef[(ia2 * 2u) + 1u];
- co3 = pCoef[ia3 * 2u];
- si3 = pCoef[(ia3 * 2u) + 1u];
-
- /* Twiddle coefficients index modifier */
- ia1 += twidCoefModifier;
-
- i0 = j;
- do
- {
- /* index calculation for the input as, */
- /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
- i1 = i0 + n2;
- i2 = i1 + n2;
- i3 = i2 + n2;
-
- xaIn = pSrc[(2u * i0)];
- yaIn = pSrc[(2u * i0) + 1u];
-
- xbIn = pSrc[(2u * i1)];
- ybIn = pSrc[(2u * i1) + 1u];
-
- xcIn = pSrc[(2u * i2)];
- ycIn = pSrc[(2u * i2) + 1u];
-
- xdIn = pSrc[(2u * i3)];
- ydIn = pSrc[(2u * i3) + 1u];
-
- /* xa - xc */
- Xaminusc = xaIn - xcIn;
- /* (xb - xd) */
- Xbminusd = xbIn - xdIn;
- /* ya - yc */
- Yaminusc = yaIn - ycIn;
- /* (yb - yd) */
- Ybminusd = ybIn - ydIn;
-
- /* xa + xc */
- Xaplusc = xaIn + xcIn;
- /* xb + xd */
- Xbplusd = xbIn + xdIn;
- /* ya + yc */
- Yaplusc = yaIn + ycIn;
- /* yb + yd */
- Ybplusd = ybIn + ydIn;
-
- /* (xa - xc) + (yb - yd) */
- Xb12C_out = (Xaminusc + Ybminusd);
- /* (ya - yc) - (xb - xd) */
- Yb12C_out = (Yaminusc - Xbminusd);
- /* xa + xc -(xb + xd) */
- Xc12C_out = (Xaplusc - Xbplusd);
- /* (ya + yc) - (yb + yd) */
- Yc12C_out = (Yaplusc - Ybplusd);
- /* (xa - xc) - (yb - yd) */
- Xd12C_out = (Xaminusc - Ybminusd);
- /* (ya - yc) + (xb - xd) */
- Yd12C_out = (Xbminusd + Yaminusc);
-
- pSrc[(2u * i0)] = Xaplusc + Xbplusd;
- pSrc[(2u * i0) + 1u] = Yaplusc + Ybplusd;
-
- Xb12_out = Xb12C_out * co1;
- Yb12_out = Yb12C_out * co1;
- Xc12_out = Xc12C_out * co2;
- Yc12_out = Yc12C_out * co2;
- Xd12_out = Xd12C_out * co3;
- Yd12_out = Yd12C_out * co3;
-
- /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
- //Xb12_out -= Yb12C_out * si1;
- p0 = Yb12C_out * si1;
- /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
- //Yb12_out += Xb12C_out * si1;
- p1 = Xb12C_out * si1;
- /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
- //Xc12_out -= Yc12C_out * si2;
- p2 = Yc12C_out * si2;
- /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
- //Yc12_out += Xc12C_out * si2;
- p3 = Xc12C_out * si2;
- /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
- //Xd12_out -= Yd12C_out * si3;
- p4 = Yd12C_out * si3;
- /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
- //Yd12_out += Xd12C_out * si3;
- p5 = Xd12C_out * si3;
-
- Xb12_out += p0;
- Yb12_out -= p1;
- Xc12_out += p2;
- Yc12_out -= p3;
- Xd12_out += p4;
- Yd12_out -= p5;
-
- /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */
- pSrc[2u * i1] = Xc12_out;
-
- /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */
- pSrc[(2u * i1) + 1u] = Yc12_out;
-
- /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */
- pSrc[2u * i2] = Xb12_out;
-
- /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */
- pSrc[(2u * i2) + 1u] = Yb12_out;
-
- /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */
- pSrc[2u * i3] = Xd12_out;
-
- /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */
- pSrc[(2u * i3) + 1u] = Yd12_out;
-
- i0 += n1;
- } while(i0 < fftLen);
- j++;
- } while(j <= (n2 - 1u));
- twidCoefModifier <<= 2u;
- }
-
- j = fftLen >> 2;
- ptr1 = &pSrc[0];
-
- /* Calculations of last stage */
- do
- {
- xaIn = ptr1[0];
- yaIn = ptr1[1];
- xbIn = ptr1[2];
- ybIn = ptr1[3];
- xcIn = ptr1[4];
- ycIn = ptr1[5];
- xdIn = ptr1[6];
- ydIn = ptr1[7];
-
- /* xa + xc */
- Xaplusc = xaIn + xcIn;
-
- /* xa - xc */
- Xaminusc = xaIn - xcIn;
-
- /* ya + yc */
- Yaplusc = yaIn + ycIn;
-
- /* ya - yc */
- Yaminusc = yaIn - ycIn;
-
- /* xb + xd */
- Xbplusd = xbIn + xdIn;
-
- /* yb + yd */
- Ybplusd = ybIn + ydIn;
-
- /* (xb-xd) */
- Xbminusd = xbIn - xdIn;
-
- /* (yb-yd) */
- Ybminusd = ybIn - ydIn;
-
- /* xa' = xa + xb + xc + xd */
- a0 = (Xaplusc + Xbplusd);
- /* ya' = ya + yb + yc + yd */
- a1 = (Yaplusc + Ybplusd);
- /* xc' = (xa-xb+xc-xd) */
- a2 = (Xaplusc - Xbplusd);
- /* yc' = (ya-yb+yc-yd) */
- a3 = (Yaplusc - Ybplusd);
- /* xb' = (xa+yb-xc-yd) */
- a4 = (Xaminusc + Ybminusd);
- /* yb' = (ya-xb-yc+xd) */
- a5 = (Yaminusc - Xbminusd);
- /* xd' = (xa-yb-xc+yd)) */
- a6 = (Xaminusc - Ybminusd);
- /* yd' = (ya+xb-yc-xd) */
- a7 = (Xbminusd + Yaminusc);
-
- ptr1[0] = a0;
- ptr1[1] = a1;
- ptr1[2] = a2;
- ptr1[3] = a3;
- ptr1[4] = a4;
- ptr1[5] = a5;
- ptr1[6] = a6;
- ptr1[7] = a7;
-
- /* increment pointer by 8 */
- ptr1 += 8u;
- } while(--j);
-
-#else
-
- float32_t t1, t2, r1, r2, s1, s2;
-
- /* Run the below code for Cortex-M0 */
-
- /* Initializations for the fft calculation */
- n2 = fftLen;
- n1 = n2;
- for (k = fftLen; k > 1u; k >>= 2u)
- {
- /* Initializations for the fft calculation */
- n1 = n2;
- n2 >>= 2u;
- ia1 = 0u;
-
- /* FFT Calculation */
- j = 0;
- do
- {
- /* index calculation for the coefficients */
- ia2 = ia1 + ia1;
- ia3 = ia2 + ia1;
- co1 = pCoef[ia1 * 2u];
- si1 = pCoef[(ia1 * 2u) + 1u];
- co2 = pCoef[ia2 * 2u];
- si2 = pCoef[(ia2 * 2u) + 1u];
- co3 = pCoef[ia3 * 2u];
- si3 = pCoef[(ia3 * 2u) + 1u];
-
- /* Twiddle coefficients index modifier */
- ia1 = ia1 + twidCoefModifier;
-
- i0 = j;
- do
- {
- /* index calculation for the input as, */
- /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
- i1 = i0 + n2;
- i2 = i1 + n2;
- i3 = i2 + n2;
-
- /* xa + xc */
- r1 = pSrc[(2u * i0)] + pSrc[(2u * i2)];
-
- /* xa - xc */
- r2 = pSrc[(2u * i0)] - pSrc[(2u * i2)];
-
- /* ya + yc */
- s1 = pSrc[(2u * i0) + 1u] + pSrc[(2u * i2) + 1u];
-
- /* ya - yc */
- s2 = pSrc[(2u * i0) + 1u] - pSrc[(2u * i2) + 1u];
-
- /* xb + xd */
- t1 = pSrc[2u * i1] + pSrc[2u * i3];
-
- /* xa' = xa + xb + xc + xd */
- pSrc[2u * i0] = r1 + t1;
-
- /* xa + xc -(xb + xd) */
- r1 = r1 - t1;
-
- /* yb + yd */
- t2 = pSrc[(2u * i1) + 1u] + pSrc[(2u * i3) + 1u];
-
- /* ya' = ya + yb + yc + yd */
- pSrc[(2u * i0) + 1u] = s1 + t2;
-
- /* (ya + yc) - (yb + yd) */
- s1 = s1 - t2;
-
- /* (yb - yd) */
- t1 = pSrc[(2u * i1) + 1u] - pSrc[(2u * i3) + 1u];
-
- /* (xb - xd) */
- t2 = pSrc[2u * i1] - pSrc[2u * i3];
-
- /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */
- pSrc[2u * i1] = (r1 * co2) + (s1 * si2);
-
- /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */
- pSrc[(2u * i1) + 1u] = (s1 * co2) - (r1 * si2);
-
- /* (xa - xc) + (yb - yd) */
- r1 = r2 + t1;
-
- /* (xa - xc) - (yb - yd) */
- r2 = r2 - t1;
-
- /* (ya - yc) - (xb - xd) */
- s1 = s2 - t2;
-
- /* (ya - yc) + (xb - xd) */
- s2 = s2 + t2;
-
- /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */
- pSrc[2u * i2] = (r1 * co1) + (s1 * si1);
-
- /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */
- pSrc[(2u * i2) + 1u] = (s1 * co1) - (r1 * si1);
-
- /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */
- pSrc[2u * i3] = (r2 * co3) + (s2 * si3);
-
- /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */
- pSrc[(2u * i3) + 1u] = (s2 * co3) - (r2 * si3);
-
- i0 += n1;
- } while( i0 < fftLen);
- j++;
- } while(j <= (n2 - 1u));
- twidCoefModifier <<= 2u;
- }
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY_FAMILY */
-
-}
-
-/*
-* @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)
-{
- float32_t co1, co2, co3, si1, si2, si3;
- uint32_t ia1, ia2, ia3;
- uint32_t i0, i1, i2, i3;
- uint32_t n1, n2, j, k;
-
-#ifndef ARM_MATH_CM0_FAMILY_FAMILY
-
- float32_t xaIn, yaIn, xbIn, ybIn, xcIn, ycIn, xdIn, ydIn;
- float32_t Xaplusc, Xbplusd, Yaplusc, Ybplusd, Xaminusc, Xbminusd, Yaminusc,
- Ybminusd;
- float32_t Xb12C_out, Yb12C_out, Xc12C_out, Yc12C_out, Xd12C_out, Yd12C_out;
- float32_t Xb12_out, Yb12_out, Xc12_out, Yc12_out, Xd12_out, Yd12_out;
- float32_t *ptr1;
- float32_t p0,p1,p2,p3,p4,p5,p6,p7;
- float32_t a0,a1,a2,a3,a4,a5,a6,a7;
-
-
- /* Initializations for the first stage */
- n2 = fftLen;
- n1 = n2;
-
- /* n2 = fftLen/4 */
- n2 >>= 2u;
- i0 = 0u;
- ia1 = 0u;
-
- j = n2;
-
- /* Calculation of first stage */
- do
- {
- /* index calculation for the input as, */
- /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
- i1 = i0 + n2;
- i2 = i1 + n2;
- i3 = i2 + n2;
-
- /* Butterfly implementation */
- xaIn = pSrc[(2u * i0)];
- yaIn = pSrc[(2u * i0) + 1u];
-
- xcIn = pSrc[(2u * i2)];
- ycIn = pSrc[(2u * i2) + 1u];
-
- xbIn = pSrc[(2u * i1)];
- ybIn = pSrc[(2u * i1) + 1u];
-
- xdIn = pSrc[(2u * i3)];
- ydIn = pSrc[(2u * i3) + 1u];
-
- /* xa + xc */
- Xaplusc = xaIn + xcIn;
- /* xb + xd */
- Xbplusd = xbIn + xdIn;
- /* ya + yc */
- Yaplusc = yaIn + ycIn;
- /* yb + yd */
- Ybplusd = ybIn + ydIn;
-
- /* index calculation for the coefficients */
- ia2 = ia1 + ia1;
- co2 = pCoef[ia2 * 2u];
- si2 = pCoef[(ia2 * 2u) + 1u];
-
- /* xa - xc */
- Xaminusc = xaIn - xcIn;
- /* xb - xd */
- Xbminusd = xbIn - xdIn;
- /* ya - yc */
- Yaminusc = yaIn - ycIn;
- /* yb - yd */
- Ybminusd = ybIn - ydIn;
-
- /* xa' = xa + xb + xc + xd */
- pSrc[(2u * i0)] = Xaplusc + Xbplusd;
-
- /* ya' = ya + yb + yc + yd */
- pSrc[(2u * i0) + 1u] = Yaplusc + Ybplusd;
-
- /* (xa - xc) - (yb - yd) */
- Xb12C_out = (Xaminusc - Ybminusd);
- /* (ya - yc) + (xb - xd) */
- Yb12C_out = (Yaminusc + Xbminusd);
- /* (xa + xc) - (xb + xd) */
- Xc12C_out = (Xaplusc - Xbplusd);
- /* (ya + yc) - (yb + yd) */
- Yc12C_out = (Yaplusc - Ybplusd);
- /* (xa - xc) + (yb - yd) */
- Xd12C_out = (Xaminusc + Ybminusd);
- /* (ya - yc) - (xb - xd) */
- Yd12C_out = (Yaminusc - Xbminusd);
-
- co1 = pCoef[ia1 * 2u];
- si1 = pCoef[(ia1 * 2u) + 1u];
-
- /* index calculation for the coefficients */
- ia3 = ia2 + ia1;
- co3 = pCoef[ia3 * 2u];
- si3 = pCoef[(ia3 * 2u) + 1u];
-
- Xb12_out = Xb12C_out * co1;
- Yb12_out = Yb12C_out * co1;
- Xc12_out = Xc12C_out * co2;
- Yc12_out = Yc12C_out * co2;
- Xd12_out = Xd12C_out * co3;
- Yd12_out = Yd12C_out * co3;
-
- /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
- //Xb12_out -= Yb12C_out * si1;
- p0 = Yb12C_out * si1;
- /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
- //Yb12_out += Xb12C_out * si1;
- p1 = Xb12C_out * si1;
- /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
- //Xc12_out -= Yc12C_out * si2;
- p2 = Yc12C_out * si2;
- /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
- //Yc12_out += Xc12C_out * si2;
- p3 = Xc12C_out * si2;
- /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
- //Xd12_out -= Yd12C_out * si3;
- p4 = Yd12C_out * si3;
- /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
- //Yd12_out += Xd12C_out * si3;
- p5 = Xd12C_out * si3;
-
- Xb12_out -= p0;
- Yb12_out += p1;
- Xc12_out -= p2;
- Yc12_out += p3;
- Xd12_out -= p4;
- Yd12_out += p5;
-
- /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
- pSrc[2u * i1] = Xc12_out;
-
- /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
- pSrc[(2u * i1) + 1u] = Yc12_out;
-
- /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
- pSrc[2u * i2] = Xb12_out;
-
- /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
- pSrc[(2u * i2) + 1u] = Yb12_out;
-
- /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
- pSrc[2u * i3] = Xd12_out;
-
- /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
- pSrc[(2u * i3) + 1u] = Yd12_out;
-
- /* Twiddle coefficients index modifier */
- ia1 = ia1 + twidCoefModifier;
-
- /* Updating input index */
- i0 = i0 + 1u;
-
- } while(--j);
-
- twidCoefModifier <<= 2u;
-
- /* Calculation of second stage to excluding last stage */
- for (k = fftLen >> 2u; k > 4u; k >>= 2u)
- {
- /* Initializations for the first stage */
- n1 = n2;
- n2 >>= 2u;
- ia1 = 0u;
-
- /* Calculation of first stage */
- j = 0;
- do
- {
- /* index calculation for the coefficients */
- ia2 = ia1 + ia1;
- ia3 = ia2 + ia1;
- co1 = pCoef[ia1 * 2u];
- si1 = pCoef[(ia1 * 2u) + 1u];
- co2 = pCoef[ia2 * 2u];
- si2 = pCoef[(ia2 * 2u) + 1u];
- co3 = pCoef[ia3 * 2u];
- si3 = pCoef[(ia3 * 2u) + 1u];
-
- /* Twiddle coefficients index modifier */
- ia1 = ia1 + twidCoefModifier;
-
- i0 = j;
- do
- {
- /* index calculation for the input as, */
- /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
- i1 = i0 + n2;
- i2 = i1 + n2;
- i3 = i2 + n2;
-
- xaIn = pSrc[(2u * i0)];
- yaIn = pSrc[(2u * i0) + 1u];
-
- xbIn = pSrc[(2u * i1)];
- ybIn = pSrc[(2u * i1) + 1u];
-
- xcIn = pSrc[(2u * i2)];
- ycIn = pSrc[(2u * i2) + 1u];
-
- xdIn = pSrc[(2u * i3)];
- ydIn = pSrc[(2u * i3) + 1u];
-
- /* xa - xc */
- Xaminusc = xaIn - xcIn;
- /* (xb - xd) */
- Xbminusd = xbIn - xdIn;
- /* ya - yc */
- Yaminusc = yaIn - ycIn;
- /* (yb - yd) */
- Ybminusd = ybIn - ydIn;
-
- /* xa + xc */
- Xaplusc = xaIn + xcIn;
- /* xb + xd */
- Xbplusd = xbIn + xdIn;
- /* ya + yc */
- Yaplusc = yaIn + ycIn;
- /* yb + yd */
- Ybplusd = ybIn + ydIn;
-
- /* (xa - xc) - (yb - yd) */
- Xb12C_out = (Xaminusc - Ybminusd);
- /* (ya - yc) + (xb - xd) */
- Yb12C_out = (Yaminusc + Xbminusd);
- /* xa + xc -(xb + xd) */
- Xc12C_out = (Xaplusc - Xbplusd);
- /* (ya + yc) - (yb + yd) */
- Yc12C_out = (Yaplusc - Ybplusd);
- /* (xa - xc) + (yb - yd) */
- Xd12C_out = (Xaminusc + Ybminusd);
- /* (ya - yc) - (xb - xd) */
- Yd12C_out = (Yaminusc - Xbminusd);
-
- pSrc[(2u * i0)] = Xaplusc + Xbplusd;
- pSrc[(2u * i0) + 1u] = Yaplusc + Ybplusd;
-
- Xb12_out = Xb12C_out * co1;
- Yb12_out = Yb12C_out * co1;
- Xc12_out = Xc12C_out * co2;
- Yc12_out = Yc12C_out * co2;
- Xd12_out = Xd12C_out * co3;
- Yd12_out = Yd12C_out * co3;
-
- /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
- //Xb12_out -= Yb12C_out * si1;
- p0 = Yb12C_out * si1;
- /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
- //Yb12_out += Xb12C_out * si1;
- p1 = Xb12C_out * si1;
- /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
- //Xc12_out -= Yc12C_out * si2;
- p2 = Yc12C_out * si2;
- /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
- //Yc12_out += Xc12C_out * si2;
- p3 = Xc12C_out * si2;
- /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
- //Xd12_out -= Yd12C_out * si3;
- p4 = Yd12C_out * si3;
- /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
- //Yd12_out += Xd12C_out * si3;
- p5 = Xd12C_out * si3;
-
- Xb12_out -= p0;
- Yb12_out += p1;
- Xc12_out -= p2;
- Yc12_out += p3;
- Xd12_out -= p4;
- Yd12_out += p5;
-
- /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
- pSrc[2u * i1] = Xc12_out;
-
- /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
- pSrc[(2u * i1) + 1u] = Yc12_out;
-
- /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
- pSrc[2u * i2] = Xb12_out;
-
- /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
- pSrc[(2u * i2) + 1u] = Yb12_out;
-
- /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
- pSrc[2u * i3] = Xd12_out;
-
- /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
- pSrc[(2u * i3) + 1u] = Yd12_out;
-
- i0 += n1;
- } while(i0 < fftLen);
- j++;
- } while(j <= (n2 - 1u));
- twidCoefModifier <<= 2u;
- }
- /* Initializations of last stage */
-
- j = fftLen >> 2;
- ptr1 = &pSrc[0];
-
- /* Calculations of last stage */
- do
- {
- xaIn = ptr1[0];
- yaIn = ptr1[1];
- xbIn = ptr1[2];
- ybIn = ptr1[3];
- xcIn = ptr1[4];
- ycIn = ptr1[5];
- xdIn = ptr1[6];
- ydIn = ptr1[7];
-
- /* Butterfly implementation */
- /* xa + xc */
- Xaplusc = xaIn + xcIn;
-
- /* xa - xc */
- Xaminusc = xaIn - xcIn;
-
- /* ya + yc */
- Yaplusc = yaIn + ycIn;
-
- /* ya - yc */
- Yaminusc = yaIn - ycIn;
-
- /* xb + xd */
- Xbplusd = xbIn + xdIn;
-
- /* yb + yd */
- Ybplusd = ybIn + ydIn;
-
- /* (xb-xd) */
- Xbminusd = xbIn - xdIn;
-
- /* (yb-yd) */
- Ybminusd = ybIn - ydIn;
-
- /* xa' = (xa+xb+xc+xd) * onebyfftLen */
- a0 = (Xaplusc + Xbplusd);
- /* ya' = (ya+yb+yc+yd) * onebyfftLen */
- a1 = (Yaplusc + Ybplusd);
- /* xc' = (xa-xb+xc-xd) * onebyfftLen */
- a2 = (Xaplusc - Xbplusd);
- /* yc' = (ya-yb+yc-yd) * onebyfftLen */
- a3 = (Yaplusc - Ybplusd);
- /* xb' = (xa-yb-xc+yd) * onebyfftLen */
- a4 = (Xaminusc - Ybminusd);
- /* yb' = (ya+xb-yc-xd) * onebyfftLen */
- a5 = (Yaminusc + Xbminusd);
- /* xd' = (xa-yb-xc+yd) * onebyfftLen */
- a6 = (Xaminusc + Ybminusd);
- /* yd' = (ya-xb-yc+xd) * onebyfftLen */
- a7 = (Yaminusc - Xbminusd);
-
- p0 = a0 * onebyfftLen;
- p1 = a1 * onebyfftLen;
- p2 = a2 * onebyfftLen;
- p3 = a3 * onebyfftLen;
- p4 = a4 * onebyfftLen;
- p5 = a5 * onebyfftLen;
- p6 = a6 * onebyfftLen;
- p7 = a7 * onebyfftLen;
-
- /* xa' = (xa+xb+xc+xd) * onebyfftLen */
- ptr1[0] = p0;
- /* ya' = (ya+yb+yc+yd) * onebyfftLen */
- ptr1[1] = p1;
- /* xc' = (xa-xb+xc-xd) * onebyfftLen */
- ptr1[2] = p2;
- /* yc' = (ya-yb+yc-yd) * onebyfftLen */
- ptr1[3] = p3;
- /* xb' = (xa-yb-xc+yd) * onebyfftLen */
- ptr1[4] = p4;
- /* yb' = (ya+xb-yc-xd) * onebyfftLen */
- ptr1[5] = p5;
- /* xd' = (xa-yb-xc+yd) * onebyfftLen */
- ptr1[6] = p6;
- /* yd' = (ya-xb-yc+xd) * onebyfftLen */
- ptr1[7] = p7;
-
- /* increment source pointer by 8 for next calculations */
- ptr1 = ptr1 + 8u;
-
- } while(--j);
-
-#else
-
- float32_t t1, t2, r1, r2, s1, s2;
-
- /* Run the below code for Cortex-M0 */
-
- /* Initializations for the first stage */
- n2 = fftLen;
- n1 = n2;
-
- /* Calculation of first stage */
- for (k = fftLen; k > 4u; k >>= 2u)
- {
- /* Initializations for the first stage */
- n1 = n2;
- n2 >>= 2u;
- ia1 = 0u;
-
- /* Calculation of first stage */
- j = 0;
- do
- {
- /* index calculation for the coefficients */
- ia2 = ia1 + ia1;
- ia3 = ia2 + ia1;
- co1 = pCoef[ia1 * 2u];
- si1 = pCoef[(ia1 * 2u) + 1u];
- co2 = pCoef[ia2 * 2u];
- si2 = pCoef[(ia2 * 2u) + 1u];
- co3 = pCoef[ia3 * 2u];
- si3 = pCoef[(ia3 * 2u) + 1u];
-
- /* Twiddle coefficients index modifier */
- ia1 = ia1 + twidCoefModifier;
-
- i0 = j;
- do
- {
- /* index calculation for the input as, */
- /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
- i1 = i0 + n2;
- i2 = i1 + n2;
- i3 = i2 + n2;
-
- /* xa + xc */
- r1 = pSrc[(2u * i0)] + pSrc[(2u * i2)];
-
- /* xa - xc */
- r2 = pSrc[(2u * i0)] - pSrc[(2u * i2)];
-
- /* ya + yc */
- s1 = pSrc[(2u * i0) + 1u] + pSrc[(2u * i2) + 1u];
-
- /* ya - yc */
- s2 = pSrc[(2u * i0) + 1u] - pSrc[(2u * i2) + 1u];
-
- /* xb + xd */
- t1 = pSrc[2u * i1] + pSrc[2u * i3];
-
- /* xa' = xa + xb + xc + xd */
- pSrc[2u * i0] = r1 + t1;
-
- /* xa + xc -(xb + xd) */
- r1 = r1 - t1;
-
- /* yb + yd */
- t2 = pSrc[(2u * i1) + 1u] + pSrc[(2u * i3) + 1u];
-
- /* ya' = ya + yb + yc + yd */
- pSrc[(2u * i0) + 1u] = s1 + t2;
-
- /* (ya + yc) - (yb + yd) */
- s1 = s1 - t2;
-
- /* (yb - yd) */
- t1 = pSrc[(2u * i1) + 1u] - pSrc[(2u * i3) + 1u];
-
- /* (xb - xd) */
- t2 = pSrc[2u * i1] - pSrc[2u * i3];
-
- /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
- pSrc[2u * i1] = (r1 * co2) - (s1 * si2);
-
- /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
- pSrc[(2u * i1) + 1u] = (s1 * co2) + (r1 * si2);
-
- /* (xa - xc) - (yb - yd) */
- r1 = r2 - t1;
-
- /* (xa - xc) + (yb - yd) */
- r2 = r2 + t1;
-
- /* (ya - yc) + (xb - xd) */
- s1 = s2 + t2;
-
- /* (ya - yc) - (xb - xd) */
- s2 = s2 - t2;
-
- /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
- pSrc[2u * i2] = (r1 * co1) - (s1 * si1);
-
- /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
- pSrc[(2u * i2) + 1u] = (s1 * co1) + (r1 * si1);
-
- /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
- pSrc[2u * i3] = (r2 * co3) - (s2 * si3);
-
- /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
- pSrc[(2u * i3) + 1u] = (s2 * co3) + (r2 * si3);
-
- i0 += n1;
- } while( i0 < fftLen);
- j++;
- } while(j <= (n2 - 1u));
- twidCoefModifier <<= 2u;
- }
- /* Initializations of last stage */
- n1 = n2;
- n2 >>= 2u;
-
- /* Calculations of last stage */
- for (i0 = 0u; i0 <= (fftLen - n1); i0 += n1)
- {
- /* index calculation for the input as, */
- /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
- i1 = i0 + n2;
- i2 = i1 + n2;
- i3 = i2 + n2;
-
- /* Butterfly implementation */
- /* xa + xc */
- r1 = pSrc[2u * i0] + pSrc[2u * i2];
-
- /* xa - xc */
- r2 = pSrc[2u * i0] - pSrc[2u * i2];
-
- /* ya + yc */
- s1 = pSrc[(2u * i0) + 1u] + pSrc[(2u * i2) + 1u];
-
- /* ya - yc */
- s2 = pSrc[(2u * i0) + 1u] - pSrc[(2u * i2) + 1u];
-
- /* xc + xd */
- t1 = pSrc[2u * i1] + pSrc[2u * i3];
-
- /* xa' = xa + xb + xc + xd */
- pSrc[2u * i0] = (r1 + t1) * onebyfftLen;
-
- /* (xa + xb) - (xc + xd) */
- r1 = r1 - t1;
-
- /* yb + yd */
- t2 = pSrc[(2u * i1) + 1u] + pSrc[(2u * i3) + 1u];
-
- /* ya' = ya + yb + yc + yd */
- pSrc[(2u * i0) + 1u] = (s1 + t2) * onebyfftLen;
-
- /* (ya + yc) - (yb + yd) */
- s1 = s1 - t2;
-
- /* (yb-yd) */
- t1 = pSrc[(2u * i1) + 1u] - pSrc[(2u * i3) + 1u];
-
- /* (xb-xd) */
- t2 = pSrc[2u * i1] - pSrc[2u * i3];
-
- /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
- pSrc[2u * i1] = r1 * onebyfftLen;
-
- /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
- pSrc[(2u * i1) + 1u] = s1 * onebyfftLen;
-
- /* (xa - xc) - (yb-yd) */
- r1 = r2 - t1;
-
- /* (xa - xc) + (yb-yd) */
- r2 = r2 + t1;
-
- /* (ya - yc) + (xb-xd) */
- s1 = s2 + t2;
-
- /* (ya - yc) - (xb-xd) */
- s2 = s2 - t2;
-
- /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
- pSrc[2u * i2] = r1 * onebyfftLen;
-
- /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
- pSrc[(2u * i2) + 1u] = s1 * onebyfftLen;
-
- /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
- pSrc[2u * i3] = r2 * onebyfftLen;
-
- /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
- pSrc[(2u * i3) + 1u] = s2 * onebyfftLen;
- }
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY_FAMILY */
-}
-
-/**
-* @addtogroup ComplexFFT
-* @{
-*/
-
-/**
-* @details
-* @brief Processing function for the floating-point Radix-4 CFFT/CIFFT.
-* @deprecated Do not use this function. It has been superseded by \ref arm_cfft_f32 and will be removed
-* in the future.
-* @param[in] *S points to an instance of the floating-point Radix-4 CFFT/CIFFT structure.
-* @param[in, out] *pSrc points to the complex data buffer of size 2*fftLen
. Processing occurs in-place.
-* @return none.
-*/
-
-void arm_cfft_radix4_f32(
-const arm_cfft_radix4_instance_f32 * S,
-float32_t * pSrc)
-{
-
- if(S->ifftFlag == 1u)
- {
- /* Complex IFFT radix-4 */
- arm_radix4_butterfly_inverse_f32(pSrc, S->fftLen, S->pTwiddle,
- S->twidCoefModifier, S->onebyfftLen);
- }
- else
- {
- /* Complex FFT radix-4 */
- arm_radix4_butterfly_f32(pSrc, S->fftLen, S->pTwiddle,
- S->twidCoefModifier);
- }
-
- if(S->bitReverseFlag == 1u)
- {
- /* Bit Reversal */
- arm_bitreversal_f32(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
- }
-
-}
-
-/**
-* @} end of ComplexFFT group
-*/
-
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_f32.c
deleted file mode 100644
index 815c3d2..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_f32.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_cfft_radix4_init_f32.c
-*
-* Description: Radix-4 Decimation in Frequency Floating-point CFFT & CIFFT Initialization function
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-#include "arm_common_tables.h"
-
-/**
- * @ingroup groupTransforms
- */
-
-/**
- * @addtogroup ComplexFFT
- * @{
- */
-
-/**
-* @brief Initialization function for the floating-point CFFT/CIFFT.
-* @deprecated Do not use this function. It has been superceded by \ref arm_cfft_f32 and will be removed
-* in the future.
-* @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.
-*
-* \par Description:
-* \par
-* The parameter ifftFlag
controls whether a forward or inverse transform is computed.
-* Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated
-* \par
-* The parameter bitReverseFlag
controls whether output is in normal order or bit reversed order.
-* Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order.
-* \par
-* The parameter fftLen
Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024.
-* \par
-* This Function also initializes Twiddle factor table pointer and Bit reversal table pointer.
-*/
-
-arm_status arm_cfft_radix4_init_f32(
- arm_cfft_radix4_instance_f32 * S,
- uint16_t fftLen,
- uint8_t ifftFlag,
- uint8_t bitReverseFlag)
-{
- /* Initialise the default arm status */
- arm_status status = ARM_MATH_SUCCESS;
-
- /* Initialise the FFT length */
- S->fftLen = fftLen;
-
- /* Initialise the Twiddle coefficient pointer */
- S->pTwiddle = (float32_t *) twiddleCoef;
-
- /* Initialise the Flag for selection of CFFT or CIFFT */
- S->ifftFlag = ifftFlag;
-
- /* Initialise the Flag for calculation Bit reversal or not */
- S->bitReverseFlag = bitReverseFlag;
-
- /* Initializations of structure parameters depending on the FFT length */
- switch (S->fftLen)
- {
-
- case 4096u:
- /* Initializations of structure parameters for 4096 point FFT */
-
- /* Initialise the twiddle coef modifier value */
- S->twidCoefModifier = 1u;
- /* Initialise the bit reversal table modifier */
- S->bitRevFactor = 1u;
- /* Initialise the bit reversal table pointer */
- S->pBitRevTable = (uint16_t *) armBitRevTable;
- /* Initialise the 1/fftLen Value */
- S->onebyfftLen = 0.000244140625;
- break;
-
- case 1024u:
- /* Initializations of structure parameters for 1024 point FFT */
-
- /* Initialise the twiddle coef modifier value */
- S->twidCoefModifier = 4u;
- /* Initialise the bit reversal table modifier */
- S->bitRevFactor = 4u;
- /* Initialise the bit reversal table pointer */
- S->pBitRevTable = (uint16_t *) & armBitRevTable[3];
- /* Initialise the 1/fftLen Value */
- S->onebyfftLen = 0.0009765625f;
- break;
-
-
- case 256u:
- /* Initializations of structure parameters for 256 point FFT */
- S->twidCoefModifier = 16u;
- S->bitRevFactor = 16u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[15];
- S->onebyfftLen = 0.00390625f;
- break;
-
- case 64u:
- /* Initializations of structure parameters for 64 point FFT */
- S->twidCoefModifier = 64u;
- S->bitRevFactor = 64u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[63];
- S->onebyfftLen = 0.015625f;
- break;
-
- case 16u:
- /* Initializations of structure parameters for 16 point FFT */
- S->twidCoefModifier = 256u;
- S->bitRevFactor = 256u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[255];
- S->onebyfftLen = 0.0625f;
- break;
-
-
- default:
- /* Reporting argument error if fftSize is not valid value */
- status = ARM_MATH_ARGUMENT_ERROR;
- break;
- }
-
- return (status);
-}
-
-/**
- * @} end of ComplexFFT group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_q15.c
deleted file mode 100644
index 791480e..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_q15.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_cfft_radix4_init_q15.c
-*
-* Description: Radix-4 Decimation in Frequency Q15 FFT & IFFT initialization function
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-#include "arm_common_tables.h"
-
-/**
- * @ingroup groupTransforms
- */
-
-
-/**
- * @addtogroup ComplexFFT
- * @{
- */
-
-
-/**
-* @brief Initialization function for the Q15 CFFT/CIFFT.
-* @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q15 and will be removed
-* @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 The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen
is not a supported value.
-*
-* \par Description:
-* \par
-* The parameter ifftFlag
controls whether a forward or inverse transform is computed.
-* Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated
-* \par
-* The parameter bitReverseFlag
controls whether output is in normal order or bit reversed order.
-* Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order.
-* \par
-* The parameter fftLen
Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024.
-* \par
-* This Function also initializes Twiddle factor table pointer and Bit reversal table pointer.
-*/
-
-arm_status arm_cfft_radix4_init_q15(
- arm_cfft_radix4_instance_q15 * S,
- uint16_t fftLen,
- uint8_t ifftFlag,
- uint8_t bitReverseFlag)
-{
- /* Initialise the default arm status */
- arm_status status = ARM_MATH_SUCCESS;
- /* Initialise the FFT length */
- S->fftLen = fftLen;
- /* Initialise the Twiddle coefficient pointer */
- S->pTwiddle = (q15_t *) twiddleCoef_4096_q15;
- /* Initialise the Flag for selection of CFFT or CIFFT */
- S->ifftFlag = ifftFlag;
- /* Initialise the Flag for calculation Bit reversal or not */
- S->bitReverseFlag = bitReverseFlag;
-
- /* Initializations of structure parameters depending on the FFT length */
- switch (S->fftLen)
- {
- case 4096u:
- /* Initializations of structure parameters for 4096 point FFT */
-
- /* Initialise the twiddle coef modifier value */
- S->twidCoefModifier = 1u;
- /* Initialise the bit reversal table modifier */
- S->bitRevFactor = 1u;
- /* Initialise the bit reversal table pointer */
- S->pBitRevTable = (uint16_t *) armBitRevTable;
-
- break;
-
- case 1024u:
- /* Initializations of structure parameters for 1024 point FFT */
- S->twidCoefModifier = 4u;
- S->bitRevFactor = 4u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[3];
-
- break;
-
- case 256u:
- /* Initializations of structure parameters for 256 point FFT */
- S->twidCoefModifier = 16u;
- S->bitRevFactor = 16u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[15];
-
- break;
-
- case 64u:
- /* Initializations of structure parameters for 64 point FFT */
- S->twidCoefModifier = 64u;
- S->bitRevFactor = 64u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[63];
-
- break;
-
- case 16u:
- /* Initializations of structure parameters for 16 point FFT */
- S->twidCoefModifier = 256u;
- S->bitRevFactor = 256u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[255];
-
- break;
-
- default:
- /* Reporting argument error if fftSize is not valid value */
- status = ARM_MATH_ARGUMENT_ERROR;
- break;
- }
-
- return (status);
-}
-
-/**
- * @} end of ComplexFFT group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_q31.c
deleted file mode 100644
index 9674f6e..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_q31.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_cfft_radix4_init_q31.c
-*
-* Description: Radix-4 Decimation in Frequency Q31 FFT & IFFT initialization function
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-#include "arm_common_tables.h"
-
-/**
- * @ingroup groupTransforms
- */
-
-/**
- * @addtogroup ComplexFFT
- * @{
- */
-
-/**
-*
-* @brief Initialization function for the Q31 CFFT/CIFFT.
-* @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q31 and will be removed
-* @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 The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen
is not a supported value.
-*
-* \par Description:
-* \par
-* The parameter ifftFlag
controls whether a forward or inverse transform is computed.
-* Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated
-* \par
-* The parameter bitReverseFlag
controls whether output is in normal order or bit reversed order.
-* Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order.
-* \par
-* The parameter fftLen
Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024.
-* \par
-* This Function also initializes Twiddle factor table pointer and Bit reversal table pointer.
-*/
-
-arm_status arm_cfft_radix4_init_q31(
- arm_cfft_radix4_instance_q31 * S,
- uint16_t fftLen,
- uint8_t ifftFlag,
- uint8_t bitReverseFlag)
-{
- /* Initialise the default arm status */
- arm_status status = ARM_MATH_SUCCESS;
- /* Initialise the FFT length */
- S->fftLen = fftLen;
- /* Initialise the Twiddle coefficient pointer */
- S->pTwiddle = (q31_t *) twiddleCoef_4096_q31;
- /* Initialise the Flag for selection of CFFT or CIFFT */
- S->ifftFlag = ifftFlag;
- /* Initialise the Flag for calculation Bit reversal or not */
- S->bitReverseFlag = bitReverseFlag;
-
- /* Initializations of Instance structure depending on the FFT length */
- switch (S->fftLen)
- {
- /* Initializations of structure parameters for 4096 point FFT */
- case 4096u:
- /* Initialise the twiddle coef modifier value */
- S->twidCoefModifier = 1u;
- /* Initialise the bit reversal table modifier */
- S->bitRevFactor = 1u;
- /* Initialise the bit reversal table pointer */
- S->pBitRevTable = (uint16_t *) armBitRevTable;
- break;
-
- /* Initializations of structure parameters for 1024 point FFT */
- case 1024u:
- /* Initialise the twiddle coef modifier value */
- S->twidCoefModifier = 4u;
- /* Initialise the bit reversal table modifier */
- S->bitRevFactor = 4u;
- /* Initialise the bit reversal table pointer */
- S->pBitRevTable = (uint16_t *) & armBitRevTable[3];
- break;
-
- case 256u:
- /* Initializations of structure parameters for 256 point FFT */
- S->twidCoefModifier = 16u;
- S->bitRevFactor = 16u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[15];
- break;
-
- case 64u:
- /* Initializations of structure parameters for 64 point FFT */
- S->twidCoefModifier = 64u;
- S->bitRevFactor = 64u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[63];
- break;
-
- case 16u:
- /* Initializations of structure parameters for 16 point FFT */
- S->twidCoefModifier = 256u;
- S->bitRevFactor = 256u;
- S->pBitRevTable = (uint16_t *) & armBitRevTable[255];
- break;
-
- default:
- /* Reporting argument error if fftSize is not valid value */
- status = ARM_MATH_ARGUMENT_ERROR;
- break;
- }
-
- return (status);
-}
-
-/**
- * @} end of ComplexFFT group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix8_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix8_f32.c
deleted file mode 100644
index d811b92..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix8_f32.c
+++ /dev/null
@@ -1,384 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_cfft_radix8_f32.c
-*
-* Description: Radix-8 Decimation in Frequency CFFT & CIFFT Floating point processing function
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
-* @ingroup groupTransforms
-*/
-
-/**
-* @defgroup Radix8_CFFT_CIFFT Radix-8 Complex FFT Functions
-*
-* \par
-* Complex Fast Fourier Transform(CFFT) and Complex Inverse Fast Fourier Transform(CIFFT) is an efficient algorithm to compute Discrete Fourier Transform(DFT) and Inverse Discrete Fourier Transform(IDFT).
-* Computational complexity of CFFT reduces drastically when compared to DFT.
-* \par
-* This set of functions implements CFFT/CIFFT
-* for floating-point data types. The functions operates on in-place buffer which uses same buffer for input and output.
-* Complex input is stored in input buffer in an interleaved fashion.
-*
-* \par
-* The functions operate on blocks of input and output data and each call to the function processes
-* 2*fftLen
samples through the transform. pSrc
points to In-place arrays containing 2*fftLen
values.
-* \par
-* The pSrc
points to the array of in-place buffer of size 2*fftLen
and inputs and outputs are stored in an interleaved fashion as shown below.
-* {real[0], imag[0], real[1], imag[1],..}
-*
-* \par Lengths supported by the transform:
-* \par
-* Internally, the function utilize a Radix-8 decimation in frequency(DIF) algorithm
-* and the size of the FFT supported are of the lengths [ 64, 512, 4096].
-*
-*
-* \par Algorithm:
-*
-* Complex Fast Fourier Transform:
-* \par
-* Input real and imaginary data:
-*
-* x(n) = xa + j * ya
-* x(n+N/4 ) = xb + j * yb
-* x(n+N/2 ) = xc + j * yc
-* x(n+3N 4) = xd + j * yd
-*
-* where N is length of FFT
-* \par
-* Output real and imaginary data:
-*
-* X(4r) = xa'+ j * ya'
-* X(4r+1) = xb'+ j * yb'
-* X(4r+2) = xc'+ j * yc'
-* X(4r+3) = xd'+ j * yd'
-*
-* \par
-* Twiddle factors for Radix-8 FFT:
-*
-* Wn = co1 + j * (- si1)
-* W2n = co2 + j * (- si2)
-* W3n = co3 + j * (- si3)
-*
-*
-* \par
-* \image html CFFT.gif "Radix-8 Decimation-in Frequency Complex Fast Fourier Transform"
-*
-* \par
-* Output from Radix-8 CFFT Results in Digit reversal order. Interchange middle two branches of every butterfly results in Bit reversed output.
-* \par
-* Butterfly CFFT equations:
-*
-* xa' = xa + xb + xc + xd
-* ya' = ya + yb + yc + yd
-* xc' = (xa+yb-xc-yd)* co1 + (ya-xb-yc+xd)* (si1)
-* yc' = (ya-xb-yc+xd)* co1 - (xa+yb-xc-yd)* (si1)
-* xb' = (xa-xb+xc-xd)* co2 + (ya-yb+yc-yd)* (si2)
-* yb' = (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2)
-* xd' = (xa-yb-xc+yd)* co3 + (ya+xb-yc-xd)* (si3)
-* yd' = (ya+xb-yc-xd)* co3 - (xa-yb-xc+yd)* (si3)
-*
-*
-* \par
-* where fftLen
length of CFFT/CIFFT; ifftFlag
Flag for selection of CFFT or CIFFT(Set ifftFlag to calculate CIFFT otherwise calculates CFFT);
-* bitReverseFlag
Flag for selection of output order(Set bitReverseFlag to output in normal order otherwise output in bit reversed order);
-* pTwiddle
points to array of twiddle coefficients; pBitRevTable
points to the array of bit reversal table.
-* twidCoefModifier
modifier for twiddle factor table which supports all FFT lengths with same table;
-* pBitRevTable
modifier for bit reversal table which supports all FFT lengths with same table.
-* onebyfftLen
value of 1/fftLen to calculate CIFFT;
-*
-* \par Fixed-Point Behavior
-* Care must be taken when using the fixed-point versions of the CFFT/CIFFT function.
-* Refer to the function specific documentation below for usage guidelines.
-*/
-
-
-/*
-* @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_radix8_butterfly_f32(
-float32_t * pSrc,
-uint16_t fftLen,
-const float32_t * pCoef,
-uint16_t twidCoefModifier)
-{
- uint32_t ia1, ia2, ia3, ia4, ia5, ia6, ia7;
- uint32_t i1, i2, i3, i4, i5, i6, i7, i8;
- uint32_t id;
- uint32_t n1, n2, j;
-
- float32_t r1, r2, r3, r4, r5, r6, r7, r8;
- float32_t t1, t2;
- float32_t s1, s2, s3, s4, s5, s6, s7, s8;
- float32_t p1, p2, p3, p4;
- float32_t co2, co3, co4, co5, co6, co7, co8;
- float32_t si2, si3, si4, si5, si6, si7, si8;
- const float32_t C81 = 0.70710678118f;
-
- n2 = fftLen;
-
- do
- {
- n1 = n2;
- n2 = n2 >> 3;
- i1 = 0;
-
- do
- {
- i2 = i1 + n2;
- i3 = i2 + n2;
- i4 = i3 + n2;
- i5 = i4 + n2;
- i6 = i5 + n2;
- i7 = i6 + n2;
- i8 = i7 + n2;
- r1 = pSrc[2 * i1] + pSrc[2 * i5];
- r5 = pSrc[2 * i1] - pSrc[2 * i5];
- r2 = pSrc[2 * i2] + pSrc[2 * i6];
- r6 = pSrc[2 * i2] - pSrc[2 * i6];
- r3 = pSrc[2 * i3] + pSrc[2 * i7];
- r7 = pSrc[2 * i3] - pSrc[2 * i7];
- r4 = pSrc[2 * i4] + pSrc[2 * i8];
- r8 = pSrc[2 * i4] - pSrc[2 * i8];
- t1 = r1 - r3;
- r1 = r1 + r3;
- r3 = r2 - r4;
- r2 = r2 + r4;
- pSrc[2 * i1] = r1 + r2;
- pSrc[2 * i5] = r1 - r2;
- r1 = pSrc[2 * i1 + 1] + pSrc[2 * i5 + 1];
- s5 = pSrc[2 * i1 + 1] - pSrc[2 * i5 + 1];
- r2 = pSrc[2 * i2 + 1] + pSrc[2 * i6 + 1];
- s6 = pSrc[2 * i2 + 1] - pSrc[2 * i6 + 1];
- s3 = pSrc[2 * i3 + 1] + pSrc[2 * i7 + 1];
- s7 = pSrc[2 * i3 + 1] - pSrc[2 * i7 + 1];
- r4 = pSrc[2 * i4 + 1] + pSrc[2 * i8 + 1];
- s8 = pSrc[2 * i4 + 1] - pSrc[2 * i8 + 1];
- t2 = r1 - s3;
- r1 = r1 + s3;
- s3 = r2 - r4;
- r2 = r2 + r4;
- pSrc[2 * i1 + 1] = r1 + r2;
- pSrc[2 * i5 + 1] = r1 - r2;
- pSrc[2 * i3] = t1 + s3;
- pSrc[2 * i7] = t1 - s3;
- pSrc[2 * i3 + 1] = t2 - r3;
- pSrc[2 * i7 + 1] = t2 + r3;
- r1 = (r6 - r8) * C81;
- r6 = (r6 + r8) * C81;
- r2 = (s6 - s8) * C81;
- s6 = (s6 + s8) * C81;
- t1 = r5 - r1;
- r5 = r5 + r1;
- r8 = r7 - r6;
- r7 = r7 + r6;
- t2 = s5 - r2;
- s5 = s5 + r2;
- s8 = s7 - s6;
- s7 = s7 + s6;
- pSrc[2 * i2] = r5 + s7;
- pSrc[2 * i8] = r5 - s7;
- pSrc[2 * i6] = t1 + s8;
- pSrc[2 * i4] = t1 - s8;
- pSrc[2 * i2 + 1] = s5 - r7;
- pSrc[2 * i8 + 1] = s5 + r7;
- pSrc[2 * i6 + 1] = t2 - r8;
- pSrc[2 * i4 + 1] = t2 + r8;
-
- i1 += n1;
- } while(i1 < fftLen);
-
- if(n2 < 8)
- break;
-
- ia1 = 0;
- j = 1;
-
- do
- {
- /* index calculation for the coefficients */
- id = ia1 + twidCoefModifier;
- ia1 = id;
- ia2 = ia1 + id;
- ia3 = ia2 + id;
- ia4 = ia3 + id;
- ia5 = ia4 + id;
- ia6 = ia5 + id;
- ia7 = ia6 + id;
-
- co2 = pCoef[2 * ia1];
- co3 = pCoef[2 * ia2];
- co4 = pCoef[2 * ia3];
- co5 = pCoef[2 * ia4];
- co6 = pCoef[2 * ia5];
- co7 = pCoef[2 * ia6];
- co8 = pCoef[2 * ia7];
- si2 = pCoef[2 * ia1 + 1];
- si3 = pCoef[2 * ia2 + 1];
- si4 = pCoef[2 * ia3 + 1];
- si5 = pCoef[2 * ia4 + 1];
- si6 = pCoef[2 * ia5 + 1];
- si7 = pCoef[2 * ia6 + 1];
- si8 = pCoef[2 * ia7 + 1];
-
- i1 = j;
-
- do
- {
- /* index calculation for the input */
- i2 = i1 + n2;
- i3 = i2 + n2;
- i4 = i3 + n2;
- i5 = i4 + n2;
- i6 = i5 + n2;
- i7 = i6 + n2;
- i8 = i7 + n2;
- r1 = pSrc[2 * i1] + pSrc[2 * i5];
- r5 = pSrc[2 * i1] - pSrc[2 * i5];
- r2 = pSrc[2 * i2] + pSrc[2 * i6];
- r6 = pSrc[2 * i2] - pSrc[2 * i6];
- r3 = pSrc[2 * i3] + pSrc[2 * i7];
- r7 = pSrc[2 * i3] - pSrc[2 * i7];
- r4 = pSrc[2 * i4] + pSrc[2 * i8];
- r8 = pSrc[2 * i4] - pSrc[2 * i8];
- t1 = r1 - r3;
- r1 = r1 + r3;
- r3 = r2 - r4;
- r2 = r2 + r4;
- pSrc[2 * i1] = r1 + r2;
- r2 = r1 - r2;
- s1 = pSrc[2 * i1 + 1] + pSrc[2 * i5 + 1];
- s5 = pSrc[2 * i1 + 1] - pSrc[2 * i5 + 1];
- s2 = pSrc[2 * i2 + 1] + pSrc[2 * i6 + 1];
- s6 = pSrc[2 * i2 + 1] - pSrc[2 * i6 + 1];
- s3 = pSrc[2 * i3 + 1] + pSrc[2 * i7 + 1];
- s7 = pSrc[2 * i3 + 1] - pSrc[2 * i7 + 1];
- s4 = pSrc[2 * i4 + 1] + pSrc[2 * i8 + 1];
- s8 = pSrc[2 * i4 + 1] - pSrc[2 * i8 + 1];
- t2 = s1 - s3;
- s1 = s1 + s3;
- s3 = s2 - s4;
- s2 = s2 + s4;
- r1 = t1 + s3;
- t1 = t1 - s3;
- pSrc[2 * i1 + 1] = s1 + s2;
- s2 = s1 - s2;
- s1 = t2 - r3;
- t2 = t2 + r3;
- p1 = co5 * r2;
- p2 = si5 * s2;
- p3 = co5 * s2;
- p4 = si5 * r2;
- pSrc[2 * i5] = p1 + p2;
- pSrc[2 * i5 + 1] = p3 - p4;
- p1 = co3 * r1;
- p2 = si3 * s1;
- p3 = co3 * s1;
- p4 = si3 * r1;
- pSrc[2 * i3] = p1 + p2;
- pSrc[2 * i3 + 1] = p3 - p4;
- p1 = co7 * t1;
- p2 = si7 * t2;
- p3 = co7 * t2;
- p4 = si7 * t1;
- pSrc[2 * i7] = p1 + p2;
- pSrc[2 * i7 + 1] = p3 - p4;
- r1 = (r6 - r8) * C81;
- r6 = (r6 + r8) * C81;
- s1 = (s6 - s8) * C81;
- s6 = (s6 + s8) * C81;
- t1 = r5 - r1;
- r5 = r5 + r1;
- r8 = r7 - r6;
- r7 = r7 + r6;
- t2 = s5 - s1;
- s5 = s5 + s1;
- s8 = s7 - s6;
- s7 = s7 + s6;
- r1 = r5 + s7;
- r5 = r5 - s7;
- r6 = t1 + s8;
- t1 = t1 - s8;
- s1 = s5 - r7;
- s5 = s5 + r7;
- s6 = t2 - r8;
- t2 = t2 + r8;
- p1 = co2 * r1;
- p2 = si2 * s1;
- p3 = co2 * s1;
- p4 = si2 * r1;
- pSrc[2 * i2] = p1 + p2;
- pSrc[2 * i2 + 1] = p3 - p4;
- p1 = co8 * r5;
- p2 = si8 * s5;
- p3 = co8 * s5;
- p4 = si8 * r5;
- pSrc[2 * i8] = p1 + p2;
- pSrc[2 * i8 + 1] = p3 - p4;
- p1 = co6 * r6;
- p2 = si6 * s6;
- p3 = co6 * s6;
- p4 = si6 * r6;
- pSrc[2 * i6] = p1 + p2;
- pSrc[2 * i6 + 1] = p3 - p4;
- p1 = co4 * t1;
- p2 = si4 * t2;
- p3 = co4 * t2;
- p4 = si4 * t1;
- pSrc[2 * i4] = p1 + p2;
- pSrc[2 * i4 + 1] = p3 - p4;
-
- i1 += n1;
- } while(i1 < fftLen);
-
- j++;
- } while(j < n2);
-
- twidCoefModifier <<= 3;
- } while(n2 > 7);
-}
-
-/**
-* @} end of Radix8_CFFT_CIFFT group
-*/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_f32.c
deleted file mode 100644
index 91149cc..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_f32.c
+++ /dev/null
@@ -1,461 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_dct4_f32.c
-*
-* Description: Processing function of DCT4 & IDCT4 F32.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @ingroup groupTransforms
- */
-
-/**
- * @defgroup DCT4_IDCT4 DCT Type IV Functions
- * Representation of signals by minimum number of values is important for storage and transmission.
- * The possibility of large discontinuity between the beginning and end of a period of a signal
- * in DFT can be avoided by extending the signal so that it is even-symmetric.
- * Discrete Cosine Transform (DCT) is constructed such that its energy is heavily concentrated in the lower part of the
- * spectrum and is very widely used in signal and image coding applications.
- * The family of DCTs (DCT type- 1,2,3,4) is the outcome of different combinations of homogeneous boundary conditions.
- * DCT has an excellent energy-packing capability, hence has many applications and in data compression in particular.
- *
- * DCT is essentially the Discrete Fourier Transform(DFT) of an even-extended real signal.
- * Reordering of the input data makes the computation of DCT just a problem of
- * computing the DFT of a real signal with a few additional operations.
- * This approach provides regular, simple, and very efficient DCT algorithms for practical hardware and software implementations.
- *
- * DCT type-II can be implemented using Fast fourier transform (FFT) internally, as the transform is applied on real values, Real FFT can be used.
- * DCT4 is implemented using DCT2 as their implementations are similar except with some added pre-processing and post-processing.
- * DCT2 implementation can be described in the following steps:
- * - Re-ordering input
- * - Calculating Real FFT
- * - Multiplication of weights and Real FFT output and getting real part from the product.
- *
- * This process is explained by the block diagram below:
- * \image html DCT4.gif "Discrete Cosine Transform - type-IV"
- *
- * \par Algorithm:
- * The N-point type-IV DCT is defined as a real, linear transformation by the formula:
- * \image html DCT4Equation.gif
- * where k = 0,1,2,.....N-1
- *\par
- * Its inverse is defined as follows:
- * \image html IDCT4Equation.gif
- * where n = 0,1,2,.....N-1
- *\par
- * The DCT4 matrices become involutory (i.e. they are self-inverse) by multiplying with an overall scale factor of sqrt(2/N).
- * The symmetry of the transform matrix indicates that the fast algorithms for the forward
- * and inverse transform computation are identical.
- * Note that the implementation of Inverse DCT4 and DCT4 is same, hence same process function can be used for both.
- *
- * \par Lengths supported by the transform:
- * As DCT4 internally uses Real FFT, it supports all the lengths supported by arm_rfft_f32().
- * The library provides separate functions for Q15, Q31, and floating-point data types.
- * \par Instance Structure
- * The instances for Real FFT and FFT, cosine values table and twiddle factor table are stored in an instance data structure.
- * A separate instance structure must be defined for each transform.
- * There are separate instance structure declarations for each of the 3 supported data types.
- *
- * \par Initialization Functions
- * There is also an associated initialization function for each data type.
- * The initialization function performs the following operations:
- * - Sets the values of the internal structure fields.
- * - Initializes Real FFT as its process function is used internally in DCT4, by calling arm_rfft_init_f32().
- * \par
- * Use of the initialization function is optional.
- * However, if the initialization function is used, then the instance structure cannot be placed into a const data section.
- * To place an instance structure into a const data section, the instance structure must be manually initialized.
- * Manually initialize the instance structure as follows:
- *
- *arm_dct4_instance_f32 S = {N, Nby2, normalize, pTwiddle, pCosFactor, pRfft, pCfft};
- *arm_dct4_instance_q31 S = {N, Nby2, normalize, pTwiddle, pCosFactor, pRfft, pCfft};
- *arm_dct4_instance_q15 S = {N, Nby2, normalize, pTwiddle, pCosFactor, pRfft, pCfft};
- *
- * where \c N is the length of the DCT4; \c Nby2 is half of the length of the DCT4;
- * \c normalize is normalizing factor used and is equal to sqrt(2/N)
;
- * \c pTwiddle points to the twiddle factor table;
- * \c pCosFactor points to the cosFactor table;
- * \c pRfft points to the real FFT instance;
- * \c pCfft points to the complex FFT instance;
- * The CFFT and RFFT structures also needs to be initialized, refer to arm_cfft_radix4_f32()
- * and arm_rfft_f32() respectively for details regarding static initialization.
- *
- * \par Fixed-Point Behavior
- * Care must be taken when using the fixed-point versions of the DCT4 transform 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 DCT4_IDCT4
- * @{
- */
-
-/**
- * @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)
-{
- uint32_t i; /* Loop counter */
- float32_t *weights = S->pTwiddle; /* Pointer to the Weights table */
- float32_t *cosFact = S->pCosFactor; /* Pointer to the cos factors table */
- float32_t *pS1, *pS2, *pbuff; /* Temporary pointers for input buffer and pState buffer */
- float32_t in; /* Temporary variable */
-
-
- /* DCT4 computation involves DCT2 (which is calculated using RFFT)
- * along with some pre-processing and post-processing.
- * Computational procedure is explained as follows:
- * (a) Pre-processing involves multiplying input with cos factor,
- * r(n) = 2 * u(n) * cos(pi*(2*n+1)/(4*n))
- * where,
- * r(n) -- output of preprocessing
- * u(n) -- input to preprocessing(actual Source buffer)
- * (b) Calculation of DCT2 using FFT is divided into three steps:
- * Step1: Re-ordering of even and odd elements of input.
- * Step2: Calculating FFT of the re-ordered input.
- * Step3: Taking the real part of the product of FFT output and weights.
- * (c) Post-processing - DCT4 can be obtained from DCT2 output using the following equation:
- * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
- * where,
- * Y4 -- DCT4 output, Y2 -- DCT2 output
- * (d) Multiplying the output with the normalizing factor sqrt(2/N).
- */
-
- /*-------- Pre-processing ------------*/
- /* Multiplying input with cos factor i.e. r(n) = 2 * x(n) * cos(pi*(2*n+1)/(4*n)) */
- arm_scale_f32(pInlineBuffer, 2.0f, pInlineBuffer, S->N);
- arm_mult_f32(pInlineBuffer, cosFact, pInlineBuffer, S->N);
-
- /* ----------------------------------------------------------------
- * Step1: Re-ordering of even and odd elements as,
- * pState[i] = pInlineBuffer[2*i] and
- * pState[N-i-1] = pInlineBuffer[2*i+1] where i = 0 to N/2
- ---------------------------------------------------------------------*/
-
- /* pS1 initialized to pState */
- pS1 = pState;
-
- /* pS2 initialized to pState+N-1, so that it points to the end of the state buffer */
- pS2 = pState + (S->N - 1u);
-
- /* pbuff initialized to input buffer */
- pbuff = pInlineBuffer;
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /* Initializing the loop counter to N/2 >> 2 for loop unrolling by 4 */
- i = (uint32_t) S->Nby2 >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- do
- {
- /* Re-ordering of even and odd elements */
- /* pState[i] = pInlineBuffer[2*i] */
- *pS1++ = *pbuff++;
- /* pState[N-i-1] = pInlineBuffer[2*i+1] */
- *pS2-- = *pbuff++;
-
- *pS1++ = *pbuff++;
- *pS2-- = *pbuff++;
-
- *pS1++ = *pbuff++;
- *pS2-- = *pbuff++;
-
- *pS1++ = *pbuff++;
- *pS2-- = *pbuff++;
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
- /* pbuff initialized to input buffer */
- pbuff = pInlineBuffer;
-
- /* pS1 initialized to pState */
- pS1 = pState;
-
- /* Initializing the loop counter to N/4 instead of N for loop unrolling */
- i = (uint32_t) S->N >> 2u;
-
- /* Processing with loop unrolling 4 times as N is always multiple of 4.
- * Compute 4 outputs at a time */
- do
- {
- /* Writing the re-ordered output back to inplace input buffer */
- *pbuff++ = *pS1++;
- *pbuff++ = *pS1++;
- *pbuff++ = *pS1++;
- *pbuff++ = *pS1++;
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
-
- /* ---------------------------------------------------------
- * Step2: Calculate RFFT for N-point input
- * ---------------------------------------------------------- */
- /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */
- arm_rfft_f32(S->pRfft, pInlineBuffer, pState);
-
- /*----------------------------------------------------------------------
- * Step3: Multiply the FFT output with the weights.
- *----------------------------------------------------------------------*/
- arm_cmplx_mult_cmplx_f32(pState, weights, pState, S->N);
-
- /* ----------- Post-processing ---------- */
- /* DCT-IV can be obtained from DCT-II by the equation,
- * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
- * Hence, Y4(0) = Y2(0)/2 */
- /* Getting only real part from the output and Converting to DCT-IV */
-
- /* Initializing the loop counter to N >> 2 for loop unrolling by 4 */
- i = ((uint32_t) S->N - 1u) >> 2u;
-
- /* pbuff initialized to input buffer. */
- pbuff = pInlineBuffer;
-
- /* pS1 initialized to pState */
- pS1 = pState;
-
- /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */
- in = *pS1++ * (float32_t) 0.5;
- /* input buffer acts as inplace, so output values are stored in the input itself. */
- *pbuff++ = in;
-
- /* pState pointer is incremented twice as the real values are located alternatively in the array */
- pS1++;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- do
- {
- /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
- /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
- in = *pS1++ - in;
- *pbuff++ = in;
- /* points to the next real value */
- pS1++;
-
- in = *pS1++ - in;
- *pbuff++ = in;
- pS1++;
-
- in = *pS1++ - in;
- *pbuff++ = in;
- pS1++;
-
- in = *pS1++ - in;
- *pbuff++ = in;
- pS1++;
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- i = ((uint32_t) S->N - 1u) % 0x4u;
-
- while(i > 0u)
- {
- /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
- /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
- in = *pS1++ - in;
- *pbuff++ = in;
- /* points to the next real value */
- pS1++;
-
- /* Decrement the loop counter */
- i--;
- }
-
-
- /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/
-
- /* Initializing the loop counter to N/4 instead of N for loop unrolling */
- i = (uint32_t) S->N >> 2u;
-
- /* pbuff initialized to the pInlineBuffer(now contains the output values) */
- pbuff = pInlineBuffer;
-
- /* Processing with loop unrolling 4 times as N is always multiple of 4. Compute 4 outputs at a time */
- do
- {
- /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */
- in = *pbuff;
- *pbuff++ = in * S->normalize;
-
- in = *pbuff;
- *pbuff++ = in * S->normalize;
-
- in = *pbuff;
- *pbuff++ = in * S->normalize;
-
- in = *pbuff;
- *pbuff++ = in * S->normalize;
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Initializing the loop counter to N/2 */
- i = (uint32_t) S->Nby2;
-
- do
- {
- /* Re-ordering of even and odd elements */
- /* pState[i] = pInlineBuffer[2*i] */
- *pS1++ = *pbuff++;
- /* pState[N-i-1] = pInlineBuffer[2*i+1] */
- *pS2-- = *pbuff++;
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
- /* pbuff initialized to input buffer */
- pbuff = pInlineBuffer;
-
- /* pS1 initialized to pState */
- pS1 = pState;
-
- /* Initializing the loop counter */
- i = (uint32_t) S->N;
-
- do
- {
- /* Writing the re-ordered output back to inplace input buffer */
- *pbuff++ = *pS1++;
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
-
- /* ---------------------------------------------------------
- * Step2: Calculate RFFT for N-point input
- * ---------------------------------------------------------- */
- /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */
- arm_rfft_f32(S->pRfft, pInlineBuffer, pState);
-
- /*----------------------------------------------------------------------
- * Step3: Multiply the FFT output with the weights.
- *----------------------------------------------------------------------*/
- arm_cmplx_mult_cmplx_f32(pState, weights, pState, S->N);
-
- /* ----------- Post-processing ---------- */
- /* DCT-IV can be obtained from DCT-II by the equation,
- * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
- * Hence, Y4(0) = Y2(0)/2 */
- /* Getting only real part from the output and Converting to DCT-IV */
-
- /* pbuff initialized to input buffer. */
- pbuff = pInlineBuffer;
-
- /* pS1 initialized to pState */
- pS1 = pState;
-
- /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */
- in = *pS1++ * (float32_t) 0.5;
- /* input buffer acts as inplace, so output values are stored in the input itself. */
- *pbuff++ = in;
-
- /* pState pointer is incremented twice as the real values are located alternatively in the array */
- pS1++;
-
- /* Initializing the loop counter */
- i = ((uint32_t) S->N - 1u);
-
- do
- {
- /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
- /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
- in = *pS1++ - in;
- *pbuff++ = in;
- /* points to the next real value */
- pS1++;
-
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
-
- /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/
-
- /* Initializing the loop counter */
- i = (uint32_t) S->N;
-
- /* pbuff initialized to the pInlineBuffer(now contains the output values) */
- pbuff = pInlineBuffer;
-
- do
- {
- /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */
- in = *pbuff;
- *pbuff++ = in * S->normalize;
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
-}
-
-/**
- * @} end of DCT4_IDCT4 group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_q15.c
deleted file mode 100644
index b6b3712..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_q15.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_dct4_q15.c
-*
-* Description: Processing function of DCT4 & IDCT4 Q15.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @addtogroup DCT4_IDCT4
- * @{
- */
-
-/**
- * @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.
- *
- * \par Input an output formats:
- * Internally inputs are downscaled in the RFFT process function to avoid overflows.
- * Number of bits downscaled, depends on the size of the transform.
- * The input and output formats for different DCT sizes and number of bits to upscale are mentioned in the table below:
- *
- * \image html dct4FormatsQ15Table.gif
- */
-
-void arm_dct4_q15(
- const arm_dct4_instance_q15 * S,
- q15_t * pState,
- q15_t * pInlineBuffer)
-{
- uint32_t i; /* Loop counter */
- q15_t *weights = S->pTwiddle; /* Pointer to the Weights table */
- q15_t *cosFact = S->pCosFactor; /* Pointer to the cos factors table */
- q15_t *pS1, *pS2, *pbuff; /* Temporary pointers for input buffer and pState buffer */
- q15_t in; /* Temporary variable */
-
-
- /* DCT4 computation involves DCT2 (which is calculated using RFFT)
- * along with some pre-processing and post-processing.
- * Computational procedure is explained as follows:
- * (a) Pre-processing involves multiplying input with cos factor,
- * r(n) = 2 * u(n) * cos(pi*(2*n+1)/(4*n))
- * where,
- * r(n) -- output of preprocessing
- * u(n) -- input to preprocessing(actual Source buffer)
- * (b) Calculation of DCT2 using FFT is divided into three steps:
- * Step1: Re-ordering of even and odd elements of input.
- * Step2: Calculating FFT of the re-ordered input.
- * Step3: Taking the real part of the product of FFT output and weights.
- * (c) Post-processing - DCT4 can be obtained from DCT2 output using the following equation:
- * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
- * where,
- * Y4 -- DCT4 output, Y2 -- DCT2 output
- * (d) Multiplying the output with the normalizing factor sqrt(2/N).
- */
-
- /*-------- Pre-processing ------------*/
- /* Multiplying input with cos factor i.e. r(n) = 2 * x(n) * cos(pi*(2*n+1)/(4*n)) */
- arm_mult_q15(pInlineBuffer, cosFact, pInlineBuffer, S->N);
- arm_shift_q15(pInlineBuffer, 1, pInlineBuffer, S->N);
-
- /* ----------------------------------------------------------------
- * Step1: Re-ordering of even and odd elements as
- * pState[i] = pInlineBuffer[2*i] and
- * pState[N-i-1] = pInlineBuffer[2*i+1] where i = 0 to N/2
- ---------------------------------------------------------------------*/
-
- /* pS1 initialized to pState */
- pS1 = pState;
-
- /* pS2 initialized to pState+N-1, so that it points to the end of the state buffer */
- pS2 = pState + (S->N - 1u);
-
- /* pbuff initialized to input buffer */
- pbuff = pInlineBuffer;
-
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /* Initializing the loop counter to N/2 >> 2 for loop unrolling by 4 */
- i = (uint32_t) S->Nby2 >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- do
- {
- /* Re-ordering of even and odd elements */
- /* pState[i] = pInlineBuffer[2*i] */
- *pS1++ = *pbuff++;
- /* pState[N-i-1] = pInlineBuffer[2*i+1] */
- *pS2-- = *pbuff++;
-
- *pS1++ = *pbuff++;
- *pS2-- = *pbuff++;
-
- *pS1++ = *pbuff++;
- *pS2-- = *pbuff++;
-
- *pS1++ = *pbuff++;
- *pS2-- = *pbuff++;
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
- /* pbuff initialized to input buffer */
- pbuff = pInlineBuffer;
-
- /* pS1 initialized to pState */
- pS1 = pState;
-
- /* Initializing the loop counter to N/4 instead of N for loop unrolling */
- i = (uint32_t) S->N >> 2u;
-
- /* Processing with loop unrolling 4 times as N is always multiple of 4.
- * Compute 4 outputs at a time */
- do
- {
- /* Writing the re-ordered output back to inplace input buffer */
- *pbuff++ = *pS1++;
- *pbuff++ = *pS1++;
- *pbuff++ = *pS1++;
- *pbuff++ = *pS1++;
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
-
- /* ---------------------------------------------------------
- * Step2: Calculate RFFT for N-point input
- * ---------------------------------------------------------- */
- /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */
- arm_rfft_q15(S->pRfft, pInlineBuffer, pState);
-
- /*----------------------------------------------------------------------
- * Step3: Multiply the FFT output with the weights.
- *----------------------------------------------------------------------*/
- arm_cmplx_mult_cmplx_q15(pState, weights, pState, S->N);
-
- /* The output of complex multiplication is in 3.13 format.
- * Hence changing the format of N (i.e. 2*N elements) complex numbers to 1.15 format by shifting left by 2 bits. */
- arm_shift_q15(pState, 2, pState, S->N * 2);
-
- /* ----------- Post-processing ---------- */
- /* DCT-IV can be obtained from DCT-II by the equation,
- * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
- * Hence, Y4(0) = Y2(0)/2 */
- /* Getting only real part from the output and Converting to DCT-IV */
-
- /* Initializing the loop counter to N >> 2 for loop unrolling by 4 */
- i = ((uint32_t) S->N - 1u) >> 2u;
-
- /* pbuff initialized to input buffer. */
- pbuff = pInlineBuffer;
-
- /* pS1 initialized to pState */
- pS1 = pState;
-
- /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */
- in = *pS1++ >> 1u;
- /* input buffer acts as inplace, so output values are stored in the input itself. */
- *pbuff++ = in;
-
- /* pState pointer is incremented twice as the real values are located alternatively in the array */
- pS1++;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- do
- {
- /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
- /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
- in = *pS1++ - in;
- *pbuff++ = in;
- /* points to the next real value */
- pS1++;
-
- in = *pS1++ - in;
- *pbuff++ = in;
- pS1++;
-
- in = *pS1++ - in;
- *pbuff++ = in;
- pS1++;
-
- in = *pS1++ - in;
- *pbuff++ = in;
- pS1++;
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- i = ((uint32_t) S->N - 1u) % 0x4u;
-
- while(i > 0u)
- {
- /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
- /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
- in = *pS1++ - in;
- *pbuff++ = in;
- /* points to the next real value */
- pS1++;
-
- /* Decrement the loop counter */
- i--;
- }
-
-
- /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/
-
- /* Initializing the loop counter to N/4 instead of N for loop unrolling */
- i = (uint32_t) S->N >> 2u;
-
- /* pbuff initialized to the pInlineBuffer(now contains the output values) */
- pbuff = pInlineBuffer;
-
- /* Processing with loop unrolling 4 times as N is always multiple of 4. Compute 4 outputs at a time */
- do
- {
- /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */
- in = *pbuff;
- *pbuff++ = ((q15_t) (((q31_t) in * S->normalize) >> 15));
-
- in = *pbuff;
- *pbuff++ = ((q15_t) (((q31_t) in * S->normalize) >> 15));
-
- in = *pbuff;
- *pbuff++ = ((q15_t) (((q31_t) in * S->normalize) >> 15));
-
- in = *pbuff;
- *pbuff++ = ((q15_t) (((q31_t) in * S->normalize) >> 15));
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Initializing the loop counter to N/2 */
- i = (uint32_t) S->Nby2;
-
- do
- {
- /* Re-ordering of even and odd elements */
- /* pState[i] = pInlineBuffer[2*i] */
- *pS1++ = *pbuff++;
- /* pState[N-i-1] = pInlineBuffer[2*i+1] */
- *pS2-- = *pbuff++;
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
- /* pbuff initialized to input buffer */
- pbuff = pInlineBuffer;
-
- /* pS1 initialized to pState */
- pS1 = pState;
-
- /* Initializing the loop counter */
- i = (uint32_t) S->N;
-
- do
- {
- /* Writing the re-ordered output back to inplace input buffer */
- *pbuff++ = *pS1++;
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
-
- /* ---------------------------------------------------------
- * Step2: Calculate RFFT for N-point input
- * ---------------------------------------------------------- */
- /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */
- arm_rfft_q15(S->pRfft, pInlineBuffer, pState);
-
- /*----------------------------------------------------------------------
- * Step3: Multiply the FFT output with the weights.
- *----------------------------------------------------------------------*/
- arm_cmplx_mult_cmplx_q15(pState, weights, pState, S->N);
-
- /* The output of complex multiplication is in 3.13 format.
- * Hence changing the format of N (i.e. 2*N elements) complex numbers to 1.15 format by shifting left by 2 bits. */
- arm_shift_q15(pState, 2, pState, S->N * 2);
-
- /* ----------- Post-processing ---------- */
- /* DCT-IV can be obtained from DCT-II by the equation,
- * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
- * Hence, Y4(0) = Y2(0)/2 */
- /* Getting only real part from the output and Converting to DCT-IV */
-
- /* Initializing the loop counter */
- i = ((uint32_t) S->N - 1u);
-
- /* pbuff initialized to input buffer. */
- pbuff = pInlineBuffer;
-
- /* pS1 initialized to pState */
- pS1 = pState;
-
- /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */
- in = *pS1++ >> 1u;
- /* input buffer acts as inplace, so output values are stored in the input itself. */
- *pbuff++ = in;
-
- /* pState pointer is incremented twice as the real values are located alternatively in the array */
- pS1++;
-
- do
- {
- /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
- /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
- in = *pS1++ - in;
- *pbuff++ = in;
- /* points to the next real value */
- pS1++;
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
- /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/
-
- /* Initializing the loop counter */
- i = (uint32_t) S->N;
-
- /* pbuff initialized to the pInlineBuffer(now contains the output values) */
- pbuff = pInlineBuffer;
-
- do
- {
- /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */
- in = *pbuff;
- *pbuff++ = ((q15_t) (((q31_t) in * S->normalize) >> 15));
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
-}
-
-/**
- * @} end of DCT4_IDCT4 group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_q31.c
deleted file mode 100644
index 6f2c2b3..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_q31.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_dct4_q31.c
-*
-* Description: Processing function of DCT4 & IDCT4 Q31.
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/**
- * @addtogroup DCT4_IDCT4
- * @{
- */
-
-/**
- * @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.
- * \par Input an output formats:
- * Input samples need to be downscaled by 1 bit to avoid saturations in the Q31 DCT process,
- * as the conversion from DCT2 to DCT4 involves one subtraction.
- * Internally inputs are downscaled in the RFFT process function to avoid overflows.
- * Number of bits downscaled, depends on the size of the transform.
- * The input and output formats for different DCT sizes and number of bits to upscale are mentioned in the table below:
- *
- * \image html dct4FormatsQ31Table.gif
- */
-
-void arm_dct4_q31(
- const arm_dct4_instance_q31 * S,
- q31_t * pState,
- q31_t * pInlineBuffer)
-{
- uint16_t i; /* Loop counter */
- q31_t *weights = S->pTwiddle; /* Pointer to the Weights table */
- q31_t *cosFact = S->pCosFactor; /* Pointer to the cos factors table */
- q31_t *pS1, *pS2, *pbuff; /* Temporary pointers for input buffer and pState buffer */
- q31_t in; /* Temporary variable */
-
-
- /* DCT4 computation involves DCT2 (which is calculated using RFFT)
- * along with some pre-processing and post-processing.
- * Computational procedure is explained as follows:
- * (a) Pre-processing involves multiplying input with cos factor,
- * r(n) = 2 * u(n) * cos(pi*(2*n+1)/(4*n))
- * where,
- * r(n) -- output of preprocessing
- * u(n) -- input to preprocessing(actual Source buffer)
- * (b) Calculation of DCT2 using FFT is divided into three steps:
- * Step1: Re-ordering of even and odd elements of input.
- * Step2: Calculating FFT of the re-ordered input.
- * Step3: Taking the real part of the product of FFT output and weights.
- * (c) Post-processing - DCT4 can be obtained from DCT2 output using the following equation:
- * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
- * where,
- * Y4 -- DCT4 output, Y2 -- DCT2 output
- * (d) Multiplying the output with the normalizing factor sqrt(2/N).
- */
-
- /*-------- Pre-processing ------------*/
- /* Multiplying input with cos factor i.e. r(n) = 2 * x(n) * cos(pi*(2*n+1)/(4*n)) */
- arm_mult_q31(pInlineBuffer, cosFact, pInlineBuffer, S->N);
- arm_shift_q31(pInlineBuffer, 1, pInlineBuffer, S->N);
-
- /* ----------------------------------------------------------------
- * Step1: Re-ordering of even and odd elements as
- * pState[i] = pInlineBuffer[2*i] and
- * pState[N-i-1] = pInlineBuffer[2*i+1] where i = 0 to N/2
- ---------------------------------------------------------------------*/
-
- /* pS1 initialized to pState */
- pS1 = pState;
-
- /* pS2 initialized to pState+N-1, so that it points to the end of the state buffer */
- pS2 = pState + (S->N - 1u);
-
- /* pbuff initialized to input buffer */
- pbuff = pInlineBuffer;
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
-
- /* Initializing the loop counter to N/2 >> 2 for loop unrolling by 4 */
- i = S->Nby2 >> 2u;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- do
- {
- /* Re-ordering of even and odd elements */
- /* pState[i] = pInlineBuffer[2*i] */
- *pS1++ = *pbuff++;
- /* pState[N-i-1] = pInlineBuffer[2*i+1] */
- *pS2-- = *pbuff++;
-
- *pS1++ = *pbuff++;
- *pS2-- = *pbuff++;
-
- *pS1++ = *pbuff++;
- *pS2-- = *pbuff++;
-
- *pS1++ = *pbuff++;
- *pS2-- = *pbuff++;
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
- /* pbuff initialized to input buffer */
- pbuff = pInlineBuffer;
-
- /* pS1 initialized to pState */
- pS1 = pState;
-
- /* Initializing the loop counter to N/4 instead of N for loop unrolling */
- i = S->N >> 2u;
-
- /* Processing with loop unrolling 4 times as N is always multiple of 4.
- * Compute 4 outputs at a time */
- do
- {
- /* Writing the re-ordered output back to inplace input buffer */
- *pbuff++ = *pS1++;
- *pbuff++ = *pS1++;
- *pbuff++ = *pS1++;
- *pbuff++ = *pS1++;
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
-
- /* ---------------------------------------------------------
- * Step2: Calculate RFFT for N-point input
- * ---------------------------------------------------------- */
- /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */
- arm_rfft_q31(S->pRfft, pInlineBuffer, pState);
-
- /*----------------------------------------------------------------------
- * Step3: Multiply the FFT output with the weights.
- *----------------------------------------------------------------------*/
- arm_cmplx_mult_cmplx_q31(pState, weights, pState, S->N);
-
- /* The output of complex multiplication is in 3.29 format.
- * Hence changing the format of N (i.e. 2*N elements) complex numbers to 1.31 format by shifting left by 2 bits. */
- arm_shift_q31(pState, 2, pState, S->N * 2);
-
- /* ----------- Post-processing ---------- */
- /* DCT-IV can be obtained from DCT-II by the equation,
- * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
- * Hence, Y4(0) = Y2(0)/2 */
- /* Getting only real part from the output and Converting to DCT-IV */
-
- /* Initializing the loop counter to N >> 2 for loop unrolling by 4 */
- i = (S->N - 1u) >> 2u;
-
- /* pbuff initialized to input buffer. */
- pbuff = pInlineBuffer;
-
- /* pS1 initialized to pState */
- pS1 = pState;
-
- /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */
- in = *pS1++ >> 1u;
- /* input buffer acts as inplace, so output values are stored in the input itself. */
- *pbuff++ = in;
-
- /* pState pointer is incremented twice as the real values are located alternatively in the array */
- pS1++;
-
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
- do
- {
- /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
- /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
- in = *pS1++ - in;
- *pbuff++ = in;
- /* points to the next real value */
- pS1++;
-
- in = *pS1++ - in;
- *pbuff++ = in;
- pS1++;
-
- in = *pS1++ - in;
- *pbuff++ = in;
- pS1++;
-
- in = *pS1++ - in;
- *pbuff++ = in;
- pS1++;
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
- /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- i = (S->N - 1u) % 0x4u;
-
- while(i > 0u)
- {
- /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
- /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
- in = *pS1++ - in;
- *pbuff++ = in;
- /* points to the next real value */
- pS1++;
-
- /* Decrement the loop counter */
- i--;
- }
-
-
- /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/
-
- /* Initializing the loop counter to N/4 instead of N for loop unrolling */
- i = S->N >> 2u;
-
- /* pbuff initialized to the pInlineBuffer(now contains the output values) */
- pbuff = pInlineBuffer;
-
- /* Processing with loop unrolling 4 times as N is always multiple of 4. Compute 4 outputs at a time */
- do
- {
- /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */
- in = *pbuff;
- *pbuff++ = ((q31_t) (((q63_t) in * S->normalize) >> 31));
-
- in = *pbuff;
- *pbuff++ = ((q31_t) (((q63_t) in * S->normalize) >> 31));
-
- in = *pbuff;
- *pbuff++ = ((q31_t) (((q63_t) in * S->normalize) >> 31));
-
- in = *pbuff;
- *pbuff++ = ((q31_t) (((q63_t) in * S->normalize) >> 31));
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
-
-#else
-
- /* Run the below code for Cortex-M0 */
-
- /* Initializing the loop counter to N/2 */
- i = S->Nby2;
-
- do
- {
- /* Re-ordering of even and odd elements */
- /* pState[i] = pInlineBuffer[2*i] */
- *pS1++ = *pbuff++;
- /* pState[N-i-1] = pInlineBuffer[2*i+1] */
- *pS2-- = *pbuff++;
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
- /* pbuff initialized to input buffer */
- pbuff = pInlineBuffer;
-
- /* pS1 initialized to pState */
- pS1 = pState;
-
- /* Initializing the loop counter */
- i = S->N;
-
- do
- {
- /* Writing the re-ordered output back to inplace input buffer */
- *pbuff++ = *pS1++;
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
-
- /* ---------------------------------------------------------
- * Step2: Calculate RFFT for N-point input
- * ---------------------------------------------------------- */
- /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */
- arm_rfft_q31(S->pRfft, pInlineBuffer, pState);
-
- /*----------------------------------------------------------------------
- * Step3: Multiply the FFT output with the weights.
- *----------------------------------------------------------------------*/
- arm_cmplx_mult_cmplx_q31(pState, weights, pState, S->N);
-
- /* The output of complex multiplication is in 3.29 format.
- * Hence changing the format of N (i.e. 2*N elements) complex numbers to 1.31 format by shifting left by 2 bits. */
- arm_shift_q31(pState, 2, pState, S->N * 2);
-
- /* ----------- Post-processing ---------- */
- /* DCT-IV can be obtained from DCT-II by the equation,
- * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
- * Hence, Y4(0) = Y2(0)/2 */
- /* Getting only real part from the output and Converting to DCT-IV */
-
- /* pbuff initialized to input buffer. */
- pbuff = pInlineBuffer;
-
- /* pS1 initialized to pState */
- pS1 = pState;
-
- /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */
- in = *pS1++ >> 1u;
- /* input buffer acts as inplace, so output values are stored in the input itself. */
- *pbuff++ = in;
-
- /* pState pointer is incremented twice as the real values are located alternatively in the array */
- pS1++;
-
- /* Initializing the loop counter */
- i = (S->N - 1u);
-
- while(i > 0u)
- {
- /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
- /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
- in = *pS1++ - in;
- *pbuff++ = in;
- /* points to the next real value */
- pS1++;
-
- /* Decrement the loop counter */
- i--;
- }
-
-
- /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/
-
- /* Initializing the loop counter */
- i = S->N;
-
- /* pbuff initialized to the pInlineBuffer(now contains the output values) */
- pbuff = pInlineBuffer;
-
- do
- {
- /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */
- in = *pbuff;
- *pbuff++ = ((q31_t) (((q63_t) in * S->normalize) >> 31));
-
- /* Decrement the loop counter */
- i--;
- } while(i > 0u);
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-
-}
-
-/**
- * @} end of DCT4_IDCT4 group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_f32.c
deleted file mode 100644
index f7db9fa..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_f32.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_rfft_f32.c
-*
-* Description: RFFT & RIFFT Floating point process function
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-extern void arm_radix4_butterfly_f32(
- float32_t * pSrc,
- uint16_t fftLen,
- float32_t * pCoef,
- uint16_t twidCoefModifier);
-
-extern void arm_radix4_butterfly_inverse_f32(
- float32_t * pSrc,
- uint16_t fftLen,
- float32_t * pCoef,
- uint16_t twidCoefModifier,
- float32_t onebyfftLen);
-
-extern void arm_bitreversal_f32(
- float32_t * pSrc,
- uint16_t fftSize,
- uint16_t bitRevFactor,
- uint16_t * pBitRevTab);
-
-/**
- * @ingroup groupTransforms
- */
-
-/*--------------------------------------------------------------------
- * Internal functions prototypes
- *--------------------------------------------------------------------*/
-
-void arm_split_rfft_f32(
- float32_t * pSrc,
- uint32_t fftLen,
- float32_t * pATable,
- float32_t * pBTable,
- float32_t * pDst,
- uint32_t modifier);
-void arm_split_rifft_f32(
- float32_t * pSrc,
- uint32_t fftLen,
- float32_t * pATable,
- float32_t * pBTable,
- float32_t * pDst,
- uint32_t modifier);
-
-/**
- * @addtogroup RealFFT
- * @{
- */
-
-/**
- * @brief Processing function for the floating-point RFFT/RIFFT.
- * @deprecated Do not use this function. It has been superceded by \ref arm_rfft_fast_f32 and will be removed
- * in the future.
- * @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)
-{
- const arm_cfft_radix4_instance_f32 *S_CFFT = S->pCfft;
-
-
- /* Calculation of Real IFFT of input */
- if(S->ifftFlagR == 1u)
- {
- /* Real IFFT core process */
- arm_split_rifft_f32(pSrc, S->fftLenBy2, S->pTwiddleAReal,
- S->pTwiddleBReal, pDst, S->twidCoefRModifier);
-
-
- /* Complex radix-4 IFFT process */
- arm_radix4_butterfly_inverse_f32(pDst, S_CFFT->fftLen,
- S_CFFT->pTwiddle,
- S_CFFT->twidCoefModifier,
- S_CFFT->onebyfftLen);
-
- /* Bit reversal process */
- if(S->bitReverseFlagR == 1u)
- {
- arm_bitreversal_f32(pDst, S_CFFT->fftLen,
- S_CFFT->bitRevFactor, S_CFFT->pBitRevTable);
- }
- }
- else
- {
-
- /* Calculation of RFFT of input */
-
- /* Complex radix-4 FFT process */
- arm_radix4_butterfly_f32(pSrc, S_CFFT->fftLen,
- S_CFFT->pTwiddle, S_CFFT->twidCoefModifier);
-
- /* Bit reversal process */
- if(S->bitReverseFlagR == 1u)
- {
- arm_bitreversal_f32(pSrc, S_CFFT->fftLen,
- S_CFFT->bitRevFactor, S_CFFT->pBitRevTable);
- }
-
-
- /* Real FFT core process */
- arm_split_rfft_f32(pSrc, S->fftLenBy2, S->pTwiddleAReal,
- S->pTwiddleBReal, pDst, S->twidCoefRModifier);
- }
-
-}
-
-/**
- * @} end of RealFFT group
- */
-
-/**
- * @brief Core Real FFT process
- * @param[in] *pSrc points to the input buffer.
- * @param[in] fftLen length of FFT.
- * @param[in] *pATable points to the twiddle Coef A buffer.
- * @param[in] *pBTable points to the twiddle Coef B buffer.
- * @param[out] *pDst points to the output buffer.
- * @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
- * @return none.
- */
-
-void arm_split_rfft_f32(
- float32_t * pSrc,
- uint32_t fftLen,
- float32_t * pATable,
- float32_t * pBTable,
- float32_t * pDst,
- uint32_t modifier)
-{
- uint32_t i; /* Loop Counter */
- float32_t outR, outI; /* Temporary variables for output */
- float32_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
- float32_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */
- float32_t *pDst1 = &pDst[2], *pDst2 = &pDst[(4u * fftLen) - 1u]; /* temp pointers for output buffer */
- float32_t *pSrc1 = &pSrc[2], *pSrc2 = &pSrc[(2u * fftLen) - 1u]; /* temp pointers for input buffer */
-
- /* Init coefficient pointers */
- pCoefA = &pATable[modifier * 2u];
- pCoefB = &pBTable[modifier * 2u];
-
- i = fftLen - 1u;
-
- while(i > 0u)
- {
- /*
- outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1]
- + pSrc[2 * n - 2 * i] * pBTable[2 * i] +
- pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
- */
-
- /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] +
- pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
- pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); */
-
- /* read pATable[2 * i] */
- CoefA1 = *pCoefA++;
- /* pATable[2 * i + 1] */
- CoefA2 = *pCoefA;
-
- /* pSrc[2 * i] * pATable[2 * i] */
- outR = *pSrc1 * CoefA1;
- /* pSrc[2 * i] * CoefA2 */
- outI = *pSrc1++ * CoefA2;
-
- /* (pSrc[2 * i + 1] + pSrc[2 * fftLen - 2 * i + 1]) * CoefA2 */
- outR -= (*pSrc1 + *pSrc2) * CoefA2;
- /* pSrc[2 * i + 1] * CoefA1 */
- outI += *pSrc1++ * CoefA1;
-
- CoefB1 = *pCoefB;
-
- /* pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */
- outI -= *pSrc2-- * CoefB1;
- /* pSrc[2 * fftLen - 2 * i] * CoefA2 */
- outI -= *pSrc2 * CoefA2;
-
- /* pSrc[2 * fftLen - 2 * i] * CoefB1 */
- outR += *pSrc2-- * CoefB1;
-
- /* write output */
- *pDst1++ = outR;
- *pDst1++ = outI;
-
- /* write complex conjugate output */
- *pDst2-- = -outI;
- *pDst2-- = outR;
-
- /* update coefficient pointer */
- pCoefB = pCoefB + (modifier * 2u);
- pCoefA = pCoefA + ((modifier * 2u) - 1u);
-
- i--;
-
- }
-
- pDst[2u * fftLen] = pSrc[0] - pSrc[1];
- pDst[(2u * fftLen) + 1u] = 0.0f;
-
- pDst[0] = pSrc[0] + pSrc[1];
- pDst[1] = 0.0f;
-
-}
-
-
-/**
- * @brief Core Real IFFT process
- * @param[in] *pSrc points to the input buffer.
- * @param[in] fftLen length of FFT.
- * @param[in] *pATable points to the twiddle Coef A buffer.
- * @param[in] *pBTable points to the twiddle Coef B buffer.
- * @param[out] *pDst points to the output buffer.
- * @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
- * @return none.
- */
-
-void arm_split_rifft_f32(
- float32_t * pSrc,
- uint32_t fftLen,
- float32_t * pATable,
- float32_t * pBTable,
- float32_t * pDst,
- uint32_t modifier)
-{
- float32_t outR, outI; /* Temporary variables for output */
- float32_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
- float32_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */
- float32_t *pSrc1 = &pSrc[0], *pSrc2 = &pSrc[(2u * fftLen) + 1u];
-
- pCoefA = &pATable[0];
- pCoefB = &pBTable[0];
-
- while(fftLen > 0u)
- {
- /*
- outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
- pIn[2 * n - 2 * i] * pBTable[2 * i] -
- pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
-
- outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] -
- pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
- pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
-
- */
-
- CoefA1 = *pCoefA++;
- CoefA2 = *pCoefA;
-
- /* outR = (pSrc[2 * i] * CoefA1 */
- outR = *pSrc1 * CoefA1;
-
- /* - pSrc[2 * i] * CoefA2 */
- outI = -(*pSrc1++) * CoefA2;
-
- /* (pSrc[2 * i + 1] + pSrc[2 * fftLen - 2 * i + 1]) * CoefA2 */
- outR += (*pSrc1 + *pSrc2) * CoefA2;
-
- /* pSrc[2 * i + 1] * CoefA1 */
- outI += (*pSrc1++) * CoefA1;
-
- CoefB1 = *pCoefB;
-
- /* - pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */
- outI -= *pSrc2-- * CoefB1;
-
- /* pSrc[2 * fftLen - 2 * i] * CoefB1 */
- outR += *pSrc2 * CoefB1;
-
- /* pSrc[2 * fftLen - 2 * i] * CoefA2 */
- outI += *pSrc2-- * CoefA2;
-
- /* write output */
- *pDst++ = outR;
- *pDst++ = outI;
-
- /* update coefficient pointer */
- pCoefB = pCoefB + (modifier * 2u);
- pCoefA = pCoefA + ((modifier * 2u) - 1u);
-
- /* Decrement loop count */
- fftLen--;
- }
-
-}
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_fast_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_fast_f32.c
deleted file mode 100644
index e9cea12..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_fast_f32.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_rfft_f32.c
-*
-* Description: RFFT & RIFFT Floating point process function
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-void stage_rfft_f32(
- arm_rfft_fast_instance_f32 * S,
- float32_t * p, float32_t * pOut)
-{
- uint32_t k; /* Loop Counter */
- float32_t twR, twI; /* RFFT Twiddle coefficients */
- float32_t * pCoeff = S->pTwiddleRFFT; /* Points to RFFT Twiddle factors */
- float32_t *pA = p; /* increasing pointer */
- float32_t *pB = p; /* decreasing pointer */
- float32_t xAR, xAI, xBR, xBI; /* temporary variables */
- float32_t t1a, t1b; /* temporary variables */
- float32_t p0, p1, p2, p3; /* temporary variables */
-
-
- k = (S->Sint).fftLen - 1;
-
- /* Pack first and last sample of the frequency domain together */
-
- xBR = pB[0];
- xBI = pB[1];
- xAR = pA[0];
- xAI = pA[1];
-
- twR = *pCoeff++ ;
- twI = *pCoeff++ ;
-
- // U1 = XA(1) + XB(1); % It is real
- t1a = xBR + xAR ;
-
- // U2 = XB(1) - XA(1); % It is imaginary
- t1b = xBI + xAI ;
-
- // real(tw * (xB - xA)) = twR * (xBR - xAR) - twI * (xBI - xAI);
- // imag(tw * (xB - xA)) = twI * (xBR - xAR) + twR * (xBI - xAI);
- *pOut++ = 0.5f * ( t1a + t1b );
- *pOut++ = 0.5f * ( t1a - t1b );
-
- // XA(1) = 1/2*( U1 - imag(U2) + i*( U1 +imag(U2) ));
- pB = p + 2*k;
- pA += 2;
-
- do
- {
- /*
- function X = my_split_rfft(X, ifftFlag)
- % X is a series of real numbers
- L = length(X);
- XC = X(1:2:end) +i*X(2:2:end);
- XA = fft(XC);
- XB = conj(XA([1 end:-1:2]));
- TW = i*exp(-2*pi*i*[0:L/2-1]/L).';
- for l = 2:L/2
- XA(l) = 1/2 * (XA(l) + XB(l) + TW(l) * (XB(l) - XA(l)));
- end
- XA(1) = 1/2* (XA(1) + XB(1) + TW(1) * (XB(1) - XA(1))) + i*( 1/2*( XA(1) + XB(1) + i*( XA(1) - XB(1))));
- X = XA;
- */
-
- xBI = pB[1];
- xBR = pB[0];
- xAR = pA[0];
- xAI = pA[1];
-
- twR = *pCoeff++;
- twI = *pCoeff++;
-
- t1a = xBR - xAR ;
- t1b = xBI + xAI ;
-
- // real(tw * (xB - xA)) = twR * (xBR - xAR) - twI * (xBI - xAI);
- // imag(tw * (xB - xA)) = twI * (xBR - xAR) + twR * (xBI - xAI);
- p0 = twR * t1a;
- p1 = twI * t1a;
- p2 = twR * t1b;
- p3 = twI * t1b;
-
- *pOut++ = 0.5f * (xAR + xBR + p0 + p3 ); //xAR
- *pOut++ = 0.5f * (xAI - xBI + p1 - p2 ); //xAI
-
- pA += 2;
- pB -= 2;
- k--;
- } while(k > 0u);
-}
-
-/* Prepares data for inverse cfft */
-void merge_rfft_f32(
-arm_rfft_fast_instance_f32 * S,
-float32_t * p, float32_t * pOut)
-{
- uint32_t k; /* Loop Counter */
- float32_t twR, twI; /* RFFT Twiddle coefficients */
- float32_t *pCoeff = S->pTwiddleRFFT; /* Points to RFFT Twiddle factors */
- float32_t *pA = p; /* increasing pointer */
- float32_t *pB = p; /* decreasing pointer */
- float32_t xAR, xAI, xBR, xBI; /* temporary variables */
- float32_t t1a, t1b, r, s, t, u; /* temporary variables */
-
- k = (S->Sint).fftLen - 1;
-
- xAR = pA[0];
- xAI = pA[1];
-
- pCoeff += 2 ;
-
- *pOut++ = 0.5f * ( xAR + xAI );
- *pOut++ = 0.5f * ( xAR - xAI );
-
- pB = p + 2*k ;
- pA += 2 ;
-
- while(k > 0u)
- {
- /* G is half of the frequency complex spectrum */
- //for k = 2:N
- // Xk(k) = 1/2 * (G(k) + conj(G(N-k+2)) + Tw(k)*( G(k) - conj(G(N-k+2))));
- xBI = pB[1] ;
- xBR = pB[0] ;
- xAR = pA[0];
- xAI = pA[1];
-
- twR = *pCoeff++;
- twI = *pCoeff++;
-
- t1a = xAR - xBR ;
- t1b = xAI + xBI ;
-
- r = twR * t1a;
- s = twI * t1b;
- t = twI * t1a;
- u = twR * t1b;
-
- // real(tw * (xA - xB)) = twR * (xAR - xBR) - twI * (xAI - xBI);
- // imag(tw * (xA - xB)) = twI * (xAR - xBR) + twR * (xAI - xBI);
- *pOut++ = 0.5f * (xAR + xBR - r - s ); //xAR
- *pOut++ = 0.5f * (xAI - xBI + t - u ); //xAI
-
- pA += 2;
- pB -= 2;
- k--;
- }
-
-}
-
-/**
-* @ingroup groupTransforms
-*/
-
-/**
- * @defgroup Fast Real FFT Functions
- *
- * \par
- * The CMSIS DSP library includes specialized algorithms for computing the
- * FFT of real data sequences. The FFT is defined over complex data but
- * in many applications the input is real. Real FFT algorithms take advantage
- * of the symmetry properties of the FFT and have a speed advantage over complex
- * algorithms of the same length.
- * \par
- * The Fast RFFT algorith relays on the mixed radix CFFT that save processor usage.
- * \par
- * The real length N forward FFT of a sequence is computed using the steps shown below.
- * \par
- * \image html RFFT.gif "Real Fast Fourier Transform"
- * \par
- * The real sequence is initially treated as if it were complex to perform a CFFT.
- * Later, a processing stage reshapes the data to obtain half of the frequency spectrum
- * in complex format. Except the first complex number that contains the two real numbers
- * X[0] and X[N/2] all the data is complex. In other words, the first complex sample
- * contains two real values packed.
- * \par
- * The input for the inverse RFFT should keep the same format as the output of the
- * forward RFFT. A first processing stage pre-process the data to later perform an
- * inverse CFFT.
- * \par
- * \image html RIFFT.gif "Real Inverse Fast Fourier Transform"
- * \par
- * The algorithms for floating-point, Q15, and Q31 data are slightly different
- * and we describe each algorithm in turn.
- * \par Floating-point
- * The main functions are arm_rfft_fast_f32()
- * and arm_rfft_fast_init_f32()
. The older functions
- * arm_rfft_f32()
and arm_rfft_init_f32()
have been
- * deprecated but are still documented.
- * \par
- * The FFT of a real N-point sequence has even symmetry in the frequency
- * domain. The second half of the data equals the conjugate of the first half
- * flipped in frequency:
- *
- *X[0] - real data
- *X[1] - complex data
- *X[2] - complex data
- *...
- *X[fftLen/2-1] - complex data
- *X[fftLen/2] - real data
- *X[fftLen/2+1] - conjugate of X[fftLen/2-1]
- *X[fftLen/2+2] - conjugate of X[fftLen/2-2]
- *...
- *X[fftLen-1] - conjugate of X[1]
- *
- * Looking at the data, we see that we can uniquely represent the FFT using only
- *
- *N/2+1 samples:
- *X[0] - real data
- *X[1] - complex data
- *X[2] - complex data
- *...
- *X[fftLen/2-1] - complex data
- *X[fftLen/2] - real data
- *
- * Looking more closely we see that the first and last samples are real valued.
- * They can be packed together and we can thus represent the FFT of an N-point
- * real sequence by N/2 complex values:
- *
- *X[0],X[N/2] - packed real data: X[0] + jX[N/2]
- *X[1] - complex data
- *X[2] - complex data
- *...
- *X[fftLen/2-1] - complex data
- *
- * The real FFT functions pack the frequency domain data in this fashion. The
- * forward transform outputs the data in this form and the inverse transform
- * expects input data in this form. The function always performs the needed
- * bitreversal so that the input and output data is always in normal order. The
- * functions support lengths of [32, 64, 128, ..., 4096] samples.
- * \par
- * The forward and inverse real FFT functions apply the standard FFT scaling; no
- * scaling on the forward transform and 1/fftLen scaling on the inverse
- * transform.
- * \par Q15 and Q31
- * The real algorithms are defined in a similar manner and utilize N/2 complex
- * transforms behind the scenes.
- * \par
- * The complex transforms used internally include scaling to prevent fixed-point
- * overflows. The overall scaling equals 1/(fftLen/2).
- * \par
- * A separate instance structure must be defined for each transform used but
- * twiddle factor and bit reversal tables can be reused.
- * \par
- * There is also an associated initialization function for each data type.
- * The initialization function performs the following operations:
- * - Sets the values of the internal structure fields.
- * - Initializes twiddle factor table and bit reversal table pointers.
- * - Initializes the internal complex FFT data structure.
- * \par
- * Use of the initialization function is optional.
- * However, if the initialization function is used, then the instance structure
- * cannot be placed into a const data section. To place an instance structure
- * into a const data section, the instance structure should be manually
- * initialized as follows:
- *
- *arm_rfft_instance_q31 S = {fftLenReal, fftLenBy2, ifftFlagR, bitReverseFlagR, twidCoefRModifier, pTwiddleAReal, pTwiddleBReal, pCfft};
- *arm_rfft_instance_q15 S = {fftLenReal, fftLenBy2, ifftFlagR, bitReverseFlagR, twidCoefRModifier, pTwiddleAReal, pTwiddleBReal, pCfft};
- *
- * where fftLenReal
is the length of the real transform;
- * fftLenBy2
length of the internal complex transform.
- * ifftFlagR
Selects forward (=0) or inverse (=1) transform.
- * bitReverseFlagR
Selects bit reversed output (=0) or normal order
- * output (=1).
- * twidCoefRModifier
stride modifier for the twiddle factor table.
- * The value is based on the FFT length;
- * pTwiddleAReal
points to the A array of twiddle coefficients;
- * pTwiddleBReal
points to the B array of twiddle coefficients;
- * pCfft
points to the CFFT Instance structure. The CFFT structure
- * must also be initialized. Refer to arm_cfft_radix4_f32() for details regarding
- * static initialization of the complex FFT instance structure.
- */
-
-/**
-* @addtogroup RealFFT
-* @{
-*/
-
-/**
-* @brief Processing function for the floating-point real FFT.
-* @param[in] *S points to an arm_rfft_fast_instance_f32 structure.
-* @param[in] *p points to the input buffer.
-* @param[in] *pOut points to the output buffer.
-* @param[in] ifftFlag RFFT if flag is 0, RIFFT if flag is 1
-* @return none.
-*/
-
-void arm_rfft_fast_f32(
-arm_rfft_fast_instance_f32 * S,
-float32_t * p, float32_t * pOut,
-uint8_t ifftFlag)
-{
- arm_cfft_instance_f32 * Sint = &(S->Sint);
- Sint->fftLen = S->fftLenRFFT / 2;
-
- /* Calculation of Real FFT */
- if(ifftFlag)
- {
- /* Real FFT compression */
- merge_rfft_f32(S, p, pOut);
-
- /* Complex radix-4 IFFT process */
- arm_cfft_f32( Sint, pOut, ifftFlag, 1);
- }
- else
- {
- /* Calculation of RFFT of input */
- arm_cfft_f32( Sint, p, ifftFlag, 1);
-
- /* Real FFT extraction */
- stage_rfft_f32(S, p, pOut);
- }
-}
-
-/**
-* @} end of RealFFT group
-*/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_fast_init_f32.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_fast_init_f32.c
deleted file mode 100644
index c9fa0c1..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_fast_init_f32.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_cfft_init_f32.c
-*
-* Description: Split Radix Decimation in Frequency CFFT Floating point processing function
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-#include "arm_common_tables.h"
-
-/**
- * @ingroup groupTransforms
- */
-
-/**
- * @addtogroup RealFFT
- * @{
- */
-
-/**
-* @brief Initialization function for the floating-point real FFT.
-* @param[in,out] *S points to an arm_rfft_fast_instance_f32 structure.
-* @param[in] fftLen length of the Real Sequence.
-* @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen
is not a supported value.
-*
-* \par Description:
-* \par
-* The parameter fftLen
Specifies length of RFFT/CIFFT process. Supported FFT Lengths are 32, 64, 128, 256, 512, 1024, 2048, 4096.
-* \par
-* This Function also initializes Twiddle factor table pointer and Bit reversal table pointer.
-*/
-arm_status arm_rfft_fast_init_f32(
- arm_rfft_fast_instance_f32 * S,
- uint16_t fftLen)
-{
- arm_cfft_instance_f32 * Sint;
- /* Initialise the default arm status */
- arm_status status = ARM_MATH_SUCCESS;
- /* Initialise the FFT length */
- Sint = &(S->Sint);
- Sint->fftLen = fftLen/2;
- S->fftLenRFFT = fftLen;
-
- /* Initializations of structure parameters depending on the FFT length */
- switch (Sint->fftLen)
- {
- case 2048u:
- /* Initializations of structure parameters for 2048 point FFT */
- /* Initialise the bit reversal table length */
- Sint->bitRevLength = ARMBITREVINDEXTABLE2048_TABLE_LENGTH;
- /* Initialise the bit reversal table pointer */
- Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable2048;
- /* Initialise the Twiddle coefficient pointers */
- Sint->pTwiddle = (float32_t *) twiddleCoef_2048;
- S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_4096;
- break;
- case 1024u:
- Sint->bitRevLength = ARMBITREVINDEXTABLE1024_TABLE_LENGTH;
- Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable1024;
- Sint->pTwiddle = (float32_t *) twiddleCoef_1024;
- S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_2048;
- break;
- case 512u:
- Sint->bitRevLength = ARMBITREVINDEXTABLE_512_TABLE_LENGTH;
- Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable512;
- Sint->pTwiddle = (float32_t *) twiddleCoef_512;
- S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_1024;
- break;
- case 256u:
- Sint->bitRevLength = ARMBITREVINDEXTABLE_256_TABLE_LENGTH;
- Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable256;
- Sint->pTwiddle = (float32_t *) twiddleCoef_256;
- S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_512;
- break;
- case 128u:
- Sint->bitRevLength = ARMBITREVINDEXTABLE_128_TABLE_LENGTH;
- Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable128;
- Sint->pTwiddle = (float32_t *) twiddleCoef_128;
- S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_256;
- break;
- case 64u:
- Sint->bitRevLength = ARMBITREVINDEXTABLE__64_TABLE_LENGTH;
- Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable64;
- Sint->pTwiddle = (float32_t *) twiddleCoef_64;
- S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_128;
- break;
- case 32u:
- Sint->bitRevLength = ARMBITREVINDEXTABLE__32_TABLE_LENGTH;
- Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable32;
- Sint->pTwiddle = (float32_t *) twiddleCoef_32;
- S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_64;
- break;
- case 16u:
- Sint->bitRevLength = ARMBITREVINDEXTABLE__16_TABLE_LENGTH;
- Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable16;
- Sint->pTwiddle = (float32_t *) twiddleCoef_16;
- S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_32;
- break;
- default:
- /* Reporting argument error if fftSize is not valid value */
- status = ARM_MATH_ARGUMENT_ERROR;
- break;
- }
-
- return (status);
-}
-
-/**
- * @} end of RealFFT group
- */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_q15.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_q15.c
deleted file mode 100644
index 8d2e918..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_q15.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_rfft_q15.c
-*
-* Description: RFFT & RIFFT Q15 process function
-*
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/*--------------------------------------------------------------------
-* Internal functions prototypes
---------------------------------------------------------------------*/
-
-void arm_split_rfft_q15(
- q15_t * pSrc,
- uint32_t fftLen,
- q15_t * pATable,
- q15_t * pBTable,
- q15_t * pDst,
- uint32_t modifier);
-
-void arm_split_rifft_q15(
- q15_t * pSrc,
- uint32_t fftLen,
- q15_t * pATable,
- q15_t * pBTable,
- q15_t * pDst,
- uint32_t modifier);
-
-/**
-* @addtogroup RealFFT
-* @{
-*/
-
-/**
-* @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.
-*
-* \par Input an output formats:
-* \par
-* Internally input is downscaled by 2 for every stage to avoid saturations inside CFFT/CIFFT process.
-* Hence the output format is different for different RFFT sizes.
-* The input and output formats for different RFFT sizes and number of bits to upscale are mentioned in the tables below for RFFT and RIFFT:
-* \par
-* \image html RFFTQ15.gif "Input and Output Formats for Q15 RFFT"
-* \par
-* \image html RIFFTQ15.gif "Input and Output Formats for Q15 RIFFT"
-*/
-
-void arm_rfft_q15(
- const arm_rfft_instance_q15 * S,
- q15_t * pSrc,
- q15_t * pDst)
-{
- const arm_cfft_instance_q15 *S_CFFT = S->pCfft;
- uint32_t i;
- uint32_t L2 = S->fftLenReal >> 1;
-
- /* Calculation of RIFFT of input */
- if(S->ifftFlagR == 1u)
- {
- /* Real IFFT core process */
- arm_split_rifft_q15(pSrc, L2, S->pTwiddleAReal,
- S->pTwiddleBReal, pDst, S->twidCoefRModifier);
-
- /* Complex IFFT process */
- arm_cfft_q15(S_CFFT, pDst, S->ifftFlagR, S->bitReverseFlagR);
-
- for(i=0;ifftLenReal;i++)
- {
- pDst[i] = pDst[i] << 1;
- }
- }
- else
- {
- /* Calculation of RFFT of input */
-
- /* Complex FFT process */
- arm_cfft_q15(S_CFFT, pSrc, S->ifftFlagR, S->bitReverseFlagR);
-
- /* Real FFT core process */
- arm_split_rfft_q15(pSrc, L2, S->pTwiddleAReal,
- S->pTwiddleBReal, pDst, S->twidCoefRModifier);
- }
-}
-
-/**
-* @} end of RealFFT group
-*/
-
-/**
-* @brief Core Real FFT process
-* @param *pSrc points to the input buffer.
-* @param fftLen length of FFT.
-* @param *pATable points to the A twiddle Coef buffer.
-* @param *pBTable points to the B twiddle Coef buffer.
-* @param *pDst points to the output buffer.
-* @param modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
-* @return none.
-* The function implements a Real FFT
-*/
-
-void arm_split_rfft_q15(
- q15_t * pSrc,
- uint32_t fftLen,
- q15_t * pATable,
- q15_t * pBTable,
- q15_t * pDst,
- uint32_t modifier)
-{
- uint32_t i; /* Loop Counter */
- q31_t outR, outI; /* Temporary variables for output */
- q15_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
- q15_t *pSrc1, *pSrc2;
-#ifndef ARM_MATH_CM0_FAMILY
- q15_t *pD1, *pD2;
-#endif
-
- // pSrc[2u * fftLen] = pSrc[0];
- // pSrc[(2u * fftLen) + 1u] = pSrc[1];
-
- pCoefA = &pATable[modifier * 2u];
- pCoefB = &pBTable[modifier * 2u];
-
- pSrc1 = &pSrc[2];
- pSrc2 = &pSrc[(2u * fftLen) - 2u];
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- i = 1u;
- pD1 = pDst + 2;
- pD2 = pDst + (4u * fftLen) - 2;
-
- for(i = fftLen - 1; i > 0; i--)
- {
- /*
- outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1]
- + pSrc[2 * n - 2 * i] * pBTable[2 * i] +
- pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
- */
-
- /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] +
- pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
- pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); */
-
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- /* pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1] */
- outR = __SMUSD(*__SIMD32(pSrc1), *__SIMD32(pCoefA));
-
-#else
-
- /* -(pSrc[2 * i + 1] * pATable[2 * i + 1] - pSrc[2 * i] * pATable[2 * i]) */
- outR = -(__SMUSD(*__SIMD32(pSrc1), *__SIMD32(pCoefA)));
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
- /* pSrc[2 * n - 2 * i] * pBTable[2 * i] +
- pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]) */
- outR = __SMLAD(*__SIMD32(pSrc2), *__SIMD32(pCoefB), outR) >> 16u;
-
- /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
- pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- outI = __SMUSDX(*__SIMD32(pSrc2)--, *__SIMD32(pCoefB));
-
-#else
-
- outI = __SMUSDX(*__SIMD32(pCoefB), *__SIMD32(pSrc2)--);
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
- /* (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] */
- outI = __SMLADX(*__SIMD32(pSrc1)++, *__SIMD32(pCoefA), outI);
-
- /* write output */
- *pD1++ = (q15_t) outR;
- *pD1++ = outI >> 16u;
-
- /* write complex conjugate output */
- pD2[0] = (q15_t) outR;
- pD2[1] = -(outI >> 16u);
- pD2 -= 2;
-
- /* update coefficient pointer */
- pCoefB = pCoefB + (2u * modifier);
- pCoefA = pCoefA + (2u * modifier);
- }
-
- pDst[2u * fftLen] = (pSrc[0] - pSrc[1]) >> 1;
- pDst[(2u * fftLen) + 1u] = 0;
-
- pDst[0] = (pSrc[0] + pSrc[1]) >> 1;
- pDst[1] = 0;
-
-#else
-
- /* Run the below code for Cortex-M0 */
- i = 1u;
-
- while(i < fftLen)
- {
- /*
- outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1]
- + pSrc[2 * n - 2 * i] * pBTable[2 * i] +
- pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
- */
-
- outR = *pSrc1 * *pCoefA;
- outR = outR - (*(pSrc1 + 1) * *(pCoefA + 1));
- outR = outR + (*pSrc2 * *pCoefB);
- outR = (outR + (*(pSrc2 + 1) * *(pCoefB + 1))) >> 16;
-
-
- /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] +
- pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
- pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
- */
-
- outI = *pSrc2 * *(pCoefB + 1);
- outI = outI - (*(pSrc2 + 1) * *pCoefB);
- outI = outI + (*(pSrc1 + 1) * *pCoefA);
- outI = outI + (*pSrc1 * *(pCoefA + 1));
-
- /* update input pointers */
- pSrc1 += 2u;
- pSrc2 -= 2u;
-
- /* write output */
- pDst[2u * i] = (q15_t) outR;
- pDst[(2u * i) + 1u] = outI >> 16u;
-
- /* write complex conjugate output */
- pDst[(4u * fftLen) - (2u * i)] = (q15_t) outR;
- pDst[((4u * fftLen) - (2u * i)) + 1u] = -(outI >> 16u);
-
- /* update coefficient pointer */
- pCoefB = pCoefB + (2u * modifier);
- pCoefA = pCoefA + (2u * modifier);
-
- i++;
- }
-
- pDst[2u * fftLen] = (pSrc[0] - pSrc[1]) >> 1;
- pDst[(2u * fftLen) + 1u] = 0;
-
- pDst[0] = (pSrc[0] + pSrc[1]) >> 1;
- pDst[1] = 0;
-
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-}
-
-
-/**
-* @brief Core Real IFFT process
-* @param[in] *pSrc points to the input buffer.
-* @param[in] fftLen length of FFT.
-* @param[in] *pATable points to the twiddle Coef A buffer.
-* @param[in] *pBTable points to the twiddle Coef B buffer.
-* @param[out] *pDst points to the output buffer.
-* @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
-* @return none.
-* The function implements a Real IFFT
-*/
-void arm_split_rifft_q15(
- q15_t * pSrc,
- uint32_t fftLen,
- q15_t * pATable,
- q15_t * pBTable,
- q15_t * pDst,
- uint32_t modifier)
-{
- uint32_t i; /* Loop Counter */
- q31_t outR, outI; /* Temporary variables for output */
- q15_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
- q15_t *pSrc1, *pSrc2;
- q15_t *pDst1 = &pDst[0];
-
- pCoefA = &pATable[0];
- pCoefB = &pBTable[0];
-
- pSrc1 = &pSrc[0];
- pSrc2 = &pSrc[2u * fftLen];
-
-#ifndef ARM_MATH_CM0_FAMILY
-
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- i = fftLen;
-
- while(i > 0u)
- {
- /*
- outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
- pIn[2 * n - 2 * i] * pBTable[2 * i] -
- pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
-
- outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] -
- pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
- pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
- */
-
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- /* pIn[2 * n - 2 * i] * pBTable[2 * i] -
- pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]) */
- outR = __SMUSD(*__SIMD32(pSrc2), *__SIMD32(pCoefB));
-
-#else
-
- /* -(-pIn[2 * n - 2 * i] * pBTable[2 * i] +
- pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1])) */
- outR = -(__SMUSD(*__SIMD32(pSrc2), *__SIMD32(pCoefB)));
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
- /* pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
- pIn[2 * n - 2 * i] * pBTable[2 * i] */
- outR = __SMLAD(*__SIMD32(pSrc1), *__SIMD32(pCoefA), outR) >> 16u;
-
- /*
- -pIn[2 * n - 2 * i] * pBTable[2 * i + 1] +
- pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */
- outI = __SMUADX(*__SIMD32(pSrc2)--, *__SIMD32(pCoefB));
-
- /* pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] */
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- outI = __SMLSDX(*__SIMD32(pCoefA), *__SIMD32(pSrc1)++, -outI);
-
-#else
-
- outI = __SMLSDX(*__SIMD32(pSrc1)++, *__SIMD32(pCoefA), -outI);
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
- /* write output */
-
-#ifndef ARM_MATH_BIG_ENDIAN
-
- *__SIMD32(pDst1)++ = __PKHBT(outR, (outI >> 16u), 16);
-
-#else
-
- *__SIMD32(pDst1)++ = __PKHBT((outI >> 16u), outR, 16);
-
-#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
-
- /* update coefficient pointer */
- pCoefB = pCoefB + (2u * modifier);
- pCoefA = pCoefA + (2u * modifier);
-
- i--;
- }
-#else
- /* Run the below code for Cortex-M0 */
- i = fftLen;
-
- while(i > 0u)
- {
- /*
- outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
- pIn[2 * n - 2 * i] * pBTable[2 * i] -
- pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
- */
-
- outR = *pSrc2 * *pCoefB;
- outR = outR - (*(pSrc2 + 1) * *(pCoefB + 1));
- outR = outR + (*pSrc1 * *pCoefA);
- outR = (outR + (*(pSrc1 + 1) * *(pCoefA + 1))) >> 16;
-
- /*
- outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] -
- pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
- pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
- */
-
- outI = *(pSrc1 + 1) * *pCoefA;
- outI = outI - (*pSrc1 * *(pCoefA + 1));
- outI = outI - (*pSrc2 * *(pCoefB + 1));
- outI = outI - (*(pSrc2 + 1) * *(pCoefB));
-
- /* update input pointers */
- pSrc1 += 2u;
- pSrc2 -= 2u;
-
- /* write output */
- *pDst1++ = (q15_t) outR;
- *pDst1++ = (q15_t) (outI >> 16);
-
- /* update coefficient pointer */
- pCoefB = pCoefB + (2u * modifier);
- pCoefA = pCoefA + (2u * modifier);
-
- i--;
- }
-#endif /* #ifndef ARM_MATH_CM0_FAMILY */
-}
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_q31.c b/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_q31.c
deleted file mode 100644
index 2f1cd0a..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_q31.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_rfft_q31.c
-*
-* Description: RFFT & RIFFT Q31 process function
-*
-*
-* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
-*
-* 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 ARM LIMITED 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 "arm_math.h"
-
-/*--------------------------------------------------------------------
-* Internal functions prototypes
---------------------------------------------------------------------*/
-
-void arm_split_rfft_q31(
- q31_t * pSrc,
- uint32_t fftLen,
- q31_t * pATable,
- q31_t * pBTable,
- q31_t * pDst,
- uint32_t modifier);
-
-void arm_split_rifft_q31(
- q31_t * pSrc,
- uint32_t fftLen,
- q31_t * pATable,
- q31_t * pBTable,
- q31_t * pDst,
- uint32_t modifier);
-
-/**
-* @addtogroup RealFFT
-* @{
-*/
-
-/**
-* @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.
-*
-* \par Input an output formats:
-* \par
-* Internally input is downscaled by 2 for every stage to avoid saturations inside CFFT/CIFFT process.
-* Hence the output format is different for different RFFT sizes.
-* The input and output formats for different RFFT sizes and number of bits to upscale are mentioned in the tables below for RFFT and RIFFT:
-* \par
-* \image html RFFTQ31.gif "Input and Output Formats for Q31 RFFT"
-*
-* \par
-* \image html RIFFTQ31.gif "Input and Output Formats for Q31 RIFFT"
-*/
-void arm_rfft_q31(
- const arm_rfft_instance_q31 * S,
- q31_t * pSrc,
- q31_t * pDst)
-{
- const arm_cfft_instance_q31 *S_CFFT = S->pCfft;
- uint32_t i;
- uint32_t L2 = S->fftLenReal >> 1;
-
- /* Calculation of RIFFT of input */
- if(S->ifftFlagR == 1u)
- {
- /* Real IFFT core process */
- arm_split_rifft_q31(pSrc, L2, S->pTwiddleAReal,
- S->pTwiddleBReal, pDst, S->twidCoefRModifier);
-
- /* Complex IFFT process */
- arm_cfft_q31(S_CFFT, pDst, S->ifftFlagR, S->bitReverseFlagR);
-
- for(i=0;ifftLenReal;i++)
- {
- pDst[i] = pDst[i] << 1;
- }
- }
- else
- {
- /* Calculation of RFFT of input */
-
- /* Complex FFT process */
- arm_cfft_q31(S_CFFT, pSrc, S->ifftFlagR, S->bitReverseFlagR);
-
- /* Real FFT core process */
- arm_split_rfft_q31(pSrc, L2, S->pTwiddleAReal,
- S->pTwiddleBReal, pDst, S->twidCoefRModifier);
- }
-}
-
-/**
-* @} end of RealFFT group
-*/
-
-/**
-* @brief Core Real FFT process
-* @param[in] *pSrc points to the input buffer.
-* @param[in] fftLen length of FFT.
-* @param[in] *pATable points to the twiddle Coef A buffer.
-* @param[in] *pBTable points to the twiddle Coef B buffer.
-* @param[out] *pDst points to the output buffer.
-* @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
-* @return none.
-*/
-void arm_split_rfft_q31(
- q31_t * pSrc,
- uint32_t fftLen,
- q31_t * pATable,
- q31_t * pBTable,
- q31_t * pDst,
- uint32_t modifier)
-{
- uint32_t i; /* Loop Counter */
- q31_t outR, outI; /* Temporary variables for output */
- q31_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
- q31_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */
- q31_t *pOut1 = &pDst[2], *pOut2 = &pDst[(4u * fftLen) - 1u];
- q31_t *pIn1 = &pSrc[2], *pIn2 = &pSrc[(2u * fftLen) - 1u];
-
- /* Init coefficient pointers */
- pCoefA = &pATable[modifier * 2u];
- pCoefB = &pBTable[modifier * 2u];
-
- i = fftLen - 1u;
-
- while(i > 0u)
- {
- /*
- outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1]
- + pSrc[2 * n - 2 * i] * pBTable[2 * i] +
- pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
- */
-
- /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] +
- pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
- pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); */
-
- CoefA1 = *pCoefA++;
- CoefA2 = *pCoefA;
-
- /* outR = (pSrc[2 * i] * pATable[2 * i] */
- mult_32x32_keep32_R(outR, *pIn1, CoefA1);
-
- /* outI = pIn[2 * i] * pATable[2 * i + 1] */
- mult_32x32_keep32_R(outI, *pIn1++, CoefA2);
-
- /* - pSrc[2 * i + 1] * pATable[2 * i + 1] */
- multSub_32x32_keep32_R(outR, *pIn1, CoefA2);
-
- /* (pIn[2 * i + 1] * pATable[2 * i] */
- multAcc_32x32_keep32_R(outI, *pIn1++, CoefA1);
-
- /* pSrc[2 * n - 2 * i] * pBTable[2 * i] */
- multSub_32x32_keep32_R(outR, *pIn2, CoefA2);
- CoefB1 = *pCoefB;
-
- /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] */
- multSub_32x32_keep32_R(outI, *pIn2--, CoefB1);
-
- /* pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1] */
- multAcc_32x32_keep32_R(outR, *pIn2, CoefB1);
-
- /* pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */
- multSub_32x32_keep32_R(outI, *pIn2--, CoefA2);
-
- /* write output */
- *pOut1++ = outR;
- *pOut1++ = outI;
-
- /* write complex conjugate output */
- *pOut2-- = -outI;
- *pOut2-- = outR;
-
- /* update coefficient pointer */
- pCoefB = pCoefB + (modifier * 2u);
- pCoefA = pCoefA + ((modifier * 2u) - 1u);
-
- i--;
- }
- pDst[2u * fftLen] = (pSrc[0] - pSrc[1]) >> 1;
- pDst[(2u * fftLen) + 1u] = 0;
-
- pDst[0] = (pSrc[0] + pSrc[1]) >> 1;
- pDst[1] = 0;
-}
-
-/**
-* @brief Core Real IFFT process
-* @param[in] *pSrc points to the input buffer.
-* @param[in] fftLen length of FFT.
-* @param[in] *pATable points to the twiddle Coef A buffer.
-* @param[in] *pBTable points to the twiddle Coef B buffer.
-* @param[out] *pDst points to the output buffer.
-* @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
-* @return none.
-*/
-void arm_split_rifft_q31(
- q31_t * pSrc,
- uint32_t fftLen,
- q31_t * pATable,
- q31_t * pBTable,
- q31_t * pDst,
- uint32_t modifier)
-{
- q31_t outR, outI; /* Temporary variables for output */
- q31_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
- q31_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */
- q31_t *pIn1 = &pSrc[0], *pIn2 = &pSrc[(2u * fftLen) + 1u];
-
- pCoefA = &pATable[0];
- pCoefB = &pBTable[0];
-
- while(fftLen > 0u)
- {
- /*
- outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
- pIn[2 * n - 2 * i] * pBTable[2 * i] -
- pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
-
- outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] -
- pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
- pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
- */
- CoefA1 = *pCoefA++;
- CoefA2 = *pCoefA;
-
- /* outR = (pIn[2 * i] * pATable[2 * i] */
- mult_32x32_keep32_R(outR, *pIn1, CoefA1);
-
- /* - pIn[2 * i] * pATable[2 * i + 1] */
- mult_32x32_keep32_R(outI, *pIn1++, -CoefA2);
-
- /* pIn[2 * i + 1] * pATable[2 * i + 1] */
- multAcc_32x32_keep32_R(outR, *pIn1, CoefA2);
-
- /* pIn[2 * i + 1] * pATable[2 * i] */
- multAcc_32x32_keep32_R(outI, *pIn1++, CoefA1);
-
- /* pIn[2 * n - 2 * i] * pBTable[2 * i] */
- multAcc_32x32_keep32_R(outR, *pIn2, CoefA2);
- CoefB1 = *pCoefB;
-
- /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] */
- multSub_32x32_keep32_R(outI, *pIn2--, CoefB1);
-
- /* pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1] */
- multAcc_32x32_keep32_R(outR, *pIn2, CoefB1);
-
- /* pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */
- multAcc_32x32_keep32_R(outI, *pIn2--, CoefA2);
-
- /* write output */
- *pDst++ = outR;
- *pDst++ = outI;
-
- /* update coefficient pointer */
- pCoefB = pCoefB + (modifier * 2u);
- pCoefA = pCoefA + ((modifier * 2u) - 1u);
-
- /* Decrement loop count */
- fftLen--;
- }
-}
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h
deleted file mode 100644
index 333095b..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx.h
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @brief CMSIS STM32F1xx Device Peripheral Access Layer Header File.
- *
- * The file is the unique include file that the application programmer
- * is using in the C source code, usually in main.c. This file contains:
- * - Configuration section that allows to select:
- * - The STM32F1xx device used in the target application
- * - To use or not the peripheral’s drivers in application code(i.e.
- * code will be based on direct access to peripheral’s registers
- * rather than drivers API), this option is controlled by
- * "#define USE_HAL_DRIVER"
- *
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/** @addtogroup CMSIS
- * @{
- */
-
-/** @addtogroup stm32f1xx
- * @{
- */
-
-#ifndef __STM32F1XX_H
-#define __STM32F1XX_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif /* __cplusplus */
-
-/** @addtogroup Library_configuration_section
- * @{
- */
-
-/**
- * @brief STM32 Family
- */
-#if !defined (STM32F1)
-#define STM32F1
-#endif /* STM32F1 */
-
-/* Uncomment the line below according to the target STM32L device used in your
- application
- */
-
-#if !defined (STM32F100xB) && !defined (STM32F100xE) && !defined (STM32F101x6) && \
- !defined (STM32F101xB) && !defined (STM32F101xE) && !defined (STM32F101xG) && !defined (STM32F102x6) && !defined (STM32F102xB) && !defined (STM32F103x6) && \
- !defined (STM32F103xB) && !defined (STM32F103xE) && !defined (STM32F103xG) && !defined (STM32F105xC) && !defined (STM32F107xC)
- /* #define STM32F100xB */ /*!< STM32F100C4, STM32F100R4, STM32F100C6, STM32F100R6, STM32F100C8, STM32F100R8, STM32F100V8, STM32F100CB, STM32F100RB and STM32F100VB */
- /* #define STM32F100xE */ /*!< STM32F100RC, STM32F100VC, STM32F100ZC, STM32F100RD, STM32F100VD, STM32F100ZD, STM32F100RE, STM32F100VE and STM32F100ZE */
- /* #define STM32F101x6 */ /*!< STM32F101C4, STM32F101R4, STM32F101T4, STM32F101C6, STM32F101R6 and STM32F101T6 Devices */
- /* #define STM32F101xB */ /*!< STM32F101C8, STM32F101R8, STM32F101T8, STM32F101V8, STM32F101CB, STM32F101RB, STM32F101TB and STM32F101VB */
- /* #define STM32F101xE */ /*!< STM32F101RC, STM32F101VC, STM32F101ZC, STM32F101RD, STM32F101VD, STM32F101ZD, STM32F101RE, STM32F101VE and STM32F101ZE */
- /* #define STM32F101xG */ /*!< STM32F101RF, STM32F101VF, STM32F101ZF, STM32F101RG, STM32F101VG and STM32F101ZG */
- /* #define STM32F102x6 */ /*!< STM32F102C4, STM32F102R4, STM32F102C6 and STM32F102R6 */
- /* #define STM32F102xB */ /*!< STM32F102C8, STM32F102R8, STM32F102CB and STM32F102RB */
- /* #define STM32F103x6 */ /*!< STM32F103C4, STM32F103R4, STM32F103T4, STM32F103C6, STM32F103R6 and STM32F103T6 */
- /* #define STM32F103xB */ /*!< STM32F103C8, STM32F103R8, STM32F103T8, STM32F103V8, STM32F103CB, STM32F103RB, STM32F103TB and STM32F103VB */
- /* #define STM32F103xE */ /*!< STM32F103RC, STM32F103VC, STM32F103ZC, STM32F103RD, STM32F103VD, STM32F103ZD, STM32F103RE, STM32F103VE and STM32F103ZE */
- /* #define STM32F103xG */ /*!< STM32F103RF, STM32F103VF, STM32F103ZF, STM32F103RG, STM32F103VG and STM32F103ZG */
- /* #define STM32F105xC */ /*!< STM32F105R8, STM32F105V8, STM32F105RB, STM32F105VB, STM32F105RC and STM32F105VC */
- /* #define STM32F107xC */ /*!< STM32F107RB, STM32F107VB, STM32F107RC and STM32F107VC */
-#endif
-
-/* Tip: To avoid modifying this file each time you need to switch between these
- devices, you can define the device in your toolchain compiler preprocessor.
- */
-
-#if !defined (USE_HAL_DRIVER)
-/**
- * @brief Comment the line below if you will not use the peripherals drivers.
- In this case, these drivers will not be included and the application code will
- be based on direct access to peripherals registers
- */
- /*#define USE_HAL_DRIVER */
-#endif /* USE_HAL_DRIVER */
-
-/**
- * @brief CMSIS Device version number V4.2.0
- */
-#define __STM32F1_CMSIS_VERSION_MAIN (0x04) /*!< [31:24] main version */
-#define __STM32F1_CMSIS_VERSION_SUB1 (0x02) /*!< [23:16] sub1 version */
-#define __STM32F1_CMSIS_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */
-#define __STM32F1_CMSIS_VERSION_RC (0x00) /*!< [7:0] release candidate */
-#define __STM32F1_CMSIS_VERSION ((__STM32F1_CMSIS_VERSION_MAIN << 24)\
- |(__STM32F1_CMSIS_VERSION_SUB1 << 16)\
- |(__STM32F1_CMSIS_VERSION_SUB2 << 8 )\
- |(__STM32F1_CMSIS_VERSION_RC))
-
-/**
- * @}
- */
-
-/** @addtogroup Device_Included
- * @{
- */
-
-#if defined(STM32F100xB)
- #include "stm32f100xb.h"
-#elif defined(STM32F100xE)
- #include "stm32f100xe.h"
-#elif defined(STM32F101x6)
- #include "stm32f101x6.h"
-#elif defined(STM32F101xB)
- #include "stm32f101xb.h"
-#elif defined(STM32F101xE)
- #include "stm32f101xe.h"
-#elif defined(STM32F101xG)
- #include "stm32f101xg.h"
-#elif defined(STM32F102x6)
- #include "stm32f102x6.h"
-#elif defined(STM32F102xB)
- #include "stm32f102xb.h"
-#elif defined(STM32F103x6)
- #include "stm32f103x6.h"
-#elif defined(STM32F103xB)
- #include "stm32f103xb.h"
-#elif defined(STM32F103xE)
- #include "stm32f103xe.h"
-#elif defined(STM32F103xG)
- #include "stm32f103xg.h"
-#elif defined(STM32F105xC)
- #include "stm32f105xc.h"
-#elif defined(STM32F107xC)
- #include "stm32f107xc.h"
-#else
- #error "Please select first the target STM32F1xx device used in your application (in stm32f1xx.h file)"
-#endif
-
-/**
- * @}
- */
-
-/** @addtogroup Exported_types
- * @{
- */
-typedef enum
-{
- RESET = 0,
- SET = !RESET
-} FlagStatus, ITStatus;
-
-typedef enum
-{
- DISABLE = 0,
- ENABLE = !DISABLE
-} FunctionalState;
-#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
-
-typedef enum
-{
- ERROR = 0,
- SUCCESS = !ERROR
-} ErrorStatus;
-
-/**
- * @}
- */
-
-
-/** @addtogroup Exported_macros
- * @{
- */
-#define SET_BIT(REG, BIT) ((REG) |= (BIT))
-
-#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
-
-#define READ_BIT(REG, BIT) ((REG) & (BIT))
-
-#define CLEAR_REG(REG) ((REG) = (0x0))
-
-#define WRITE_REG(REG, VAL) ((REG) = (VAL))
-
-#define READ_REG(REG) ((REG))
-
-#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
-
-#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL)))
-
-
-/**
- * @}
- */
-
-#if defined (USE_HAL_DRIVER)
- #include "stm32f1xx_hal.h"
-#endif /* USE_HAL_DRIVER */
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __STM32F1xx_H */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-
-
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h
deleted file mode 100644
index 3652ff5..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/**
- ******************************************************************************
- * @file system_stm32f10x.h
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Header File.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/** @addtogroup CMSIS
- * @{
- */
-
-/** @addtogroup stm32f10x_system
- * @{
- */
-
-/**
- * @brief Define to prevent recursive inclusion
- */
-#ifndef __SYSTEM_STM32F10X_H
-#define __SYSTEM_STM32F10X_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/** @addtogroup STM32F10x_System_Includes
- * @{
- */
-
-/**
- * @}
- */
-
-
-/** @addtogroup STM32F10x_System_Exported_types
- * @{
- */
-
-extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
-extern const uint8_t AHBPrescTable[16U]; /*!< AHB prescalers table values */
-extern const uint8_t APBPrescTable[8U]; /*!< APB prescalers table values */
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F10x_System_Exported_Constants
- * @{
- */
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F10x_System_Exported_Macros
- * @{
- */
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F10x_System_Exported_Functions
- * @{
- */
-
-extern void SystemInit(void);
-extern void SystemCoreClockUpdate(void);
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*__SYSTEM_STM32F10X_H */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f100xb.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f100xb.s
deleted file mode 100644
index 860cf6a..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f100xb.s
+++ /dev/null
@@ -1,332 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f100xb.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F100xB Devices vector table for MDK-ARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == Reset_Handler
-;* - Set the vector table entries with the exceptions ISR address
-;* - Configure the clock system
-;* - Branches to __main in the C library (which eventually
-;* calls main()).
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;
-;*******************************************************************************
-
-; Amount of memory (in bytes) allocated for Stack
-; Tailor this value to your application needs
-; Stack Configuration
-; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Stack_Size EQU 0x00000400
-
- AREA STACK, NOINIT, READWRITE, ALIGN=3
-Stack_Mem SPACE Stack_Size
-__initial_sp
-
-
-; Heap Configuration
-; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Heap_Size EQU 0x00000200
-
- AREA HEAP, NOINIT, READWRITE, ALIGN=3
-__heap_base
-Heap_Mem SPACE Heap_Size
-__heap_limit
-
- PRESERVE8
- THUMB
-
-
-; Vector Table Mapped to Address 0 at Reset
- AREA RESET, DATA, READONLY
- EXPORT __Vectors
- EXPORT __Vectors_End
- EXPORT __Vectors_Size
-
-__Vectors DCD __initial_sp ; Top of Stack
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_IRQHandler ; ADC1
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD TIM1_BRK_TIM15_IRQHandler ; TIM1 Break and TIM15
- DCD TIM1_UP_TIM16_IRQHandler ; TIM1 Update and TIM16
- DCD TIM1_TRG_COM_TIM17_IRQHandler ; TIM1 Trigger and Commutation and TIM17
- DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C2 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD CEC_IRQHandler ; HDMI-CEC
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD TIM6_DAC_IRQHandler ; TIM6 and DAC underrun
- DCD TIM7_IRQHandler ; TIM7
-__Vectors_End
-
-__Vectors_Size EQU __Vectors_End - __Vectors
-
- AREA |.text|, CODE, READONLY
-
-; Reset handler
-Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT __main
- IMPORT SystemInit
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BX R0
- ENDP
-
-; Dummy Exception Handlers (infinite loops which can be modified)
-
-NMI_Handler PROC
- EXPORT NMI_Handler [WEAK]
- B .
- ENDP
-HardFault_Handler\
- PROC
- EXPORT HardFault_Handler [WEAK]
- B .
- ENDP
-MemManage_Handler\
- PROC
- EXPORT MemManage_Handler [WEAK]
- B .
- ENDP
-BusFault_Handler\
- PROC
- EXPORT BusFault_Handler [WEAK]
- B .
- ENDP
-UsageFault_Handler\
- PROC
- EXPORT UsageFault_Handler [WEAK]
- B .
- ENDP
-SVC_Handler PROC
- EXPORT SVC_Handler [WEAK]
- B .
- ENDP
-DebugMon_Handler\
- PROC
- EXPORT DebugMon_Handler [WEAK]
- B .
- ENDP
-PendSV_Handler PROC
- EXPORT PendSV_Handler [WEAK]
- B .
- ENDP
-SysTick_Handler PROC
- EXPORT SysTick_Handler [WEAK]
- B .
- ENDP
-
-Default_Handler PROC
-
- EXPORT WWDG_IRQHandler [WEAK]
- EXPORT PVD_IRQHandler [WEAK]
- EXPORT TAMPER_IRQHandler [WEAK]
- EXPORT RTC_IRQHandler [WEAK]
- EXPORT FLASH_IRQHandler [WEAK]
- EXPORT RCC_IRQHandler [WEAK]
- EXPORT EXTI0_IRQHandler [WEAK]
- EXPORT EXTI1_IRQHandler [WEAK]
- EXPORT EXTI2_IRQHandler [WEAK]
- EXPORT EXTI3_IRQHandler [WEAK]
- EXPORT EXTI4_IRQHandler [WEAK]
- EXPORT DMA1_Channel1_IRQHandler [WEAK]
- EXPORT DMA1_Channel2_IRQHandler [WEAK]
- EXPORT DMA1_Channel3_IRQHandler [WEAK]
- EXPORT DMA1_Channel4_IRQHandler [WEAK]
- EXPORT DMA1_Channel5_IRQHandler [WEAK]
- EXPORT DMA1_Channel6_IRQHandler [WEAK]
- EXPORT DMA1_Channel7_IRQHandler [WEAK]
- EXPORT ADC1_IRQHandler [WEAK]
- EXPORT EXTI9_5_IRQHandler [WEAK]
- EXPORT TIM1_BRK_TIM15_IRQHandler [WEAK]
- EXPORT TIM1_UP_TIM16_IRQHandler [WEAK]
- EXPORT TIM1_TRG_COM_TIM17_IRQHandler [WEAK]
- EXPORT TIM1_CC_IRQHandler [WEAK]
- EXPORT TIM2_IRQHandler [WEAK]
- EXPORT TIM3_IRQHandler [WEAK]
- EXPORT TIM4_IRQHandler [WEAK]
- EXPORT I2C1_EV_IRQHandler [WEAK]
- EXPORT I2C1_ER_IRQHandler [WEAK]
- EXPORT I2C2_EV_IRQHandler [WEAK]
- EXPORT I2C2_ER_IRQHandler [WEAK]
- EXPORT SPI1_IRQHandler [WEAK]
- EXPORT SPI2_IRQHandler [WEAK]
- EXPORT USART1_IRQHandler [WEAK]
- EXPORT USART2_IRQHandler [WEAK]
- EXPORT USART3_IRQHandler [WEAK]
- EXPORT EXTI15_10_IRQHandler [WEAK]
- EXPORT RTC_Alarm_IRQHandler [WEAK]
- EXPORT CEC_IRQHandler [WEAK]
- EXPORT TIM6_DAC_IRQHandler [WEAK]
- EXPORT TIM7_IRQHandler [WEAK]
-
-WWDG_IRQHandler
-PVD_IRQHandler
-TAMPER_IRQHandler
-RTC_IRQHandler
-FLASH_IRQHandler
-RCC_IRQHandler
-EXTI0_IRQHandler
-EXTI1_IRQHandler
-EXTI2_IRQHandler
-EXTI3_IRQHandler
-EXTI4_IRQHandler
-DMA1_Channel1_IRQHandler
-DMA1_Channel2_IRQHandler
-DMA1_Channel3_IRQHandler
-DMA1_Channel4_IRQHandler
-DMA1_Channel5_IRQHandler
-DMA1_Channel6_IRQHandler
-DMA1_Channel7_IRQHandler
-ADC1_IRQHandler
-EXTI9_5_IRQHandler
-TIM1_BRK_TIM15_IRQHandler
-TIM1_UP_TIM16_IRQHandler
-TIM1_TRG_COM_TIM17_IRQHandler
-TIM1_CC_IRQHandler
-TIM2_IRQHandler
-TIM3_IRQHandler
-TIM4_IRQHandler
-I2C1_EV_IRQHandler
-I2C1_ER_IRQHandler
-I2C2_EV_IRQHandler
-I2C2_ER_IRQHandler
-SPI1_IRQHandler
-SPI2_IRQHandler
-USART1_IRQHandler
-USART2_IRQHandler
-USART3_IRQHandler
-EXTI15_10_IRQHandler
-RTC_Alarm_IRQHandler
-CEC_IRQHandler
-TIM6_DAC_IRQHandler
-TIM7_IRQHandler
- B .
-
- ENDP
-
- ALIGN
-
-;*******************************************************************************
-; User Stack and Heap initialization
-;*******************************************************************************
- IF :DEF:__MICROLIB
-
- EXPORT __initial_sp
- EXPORT __heap_base
- EXPORT __heap_limit
-
- ELSE
-
- IMPORT __use_two_region_memory
- EXPORT __user_initial_stackheap
-
-__user_initial_stackheap
-
- LDR R0, = Heap_Mem
- LDR R1, =(Stack_Mem + Stack_Size)
- LDR R2, = (Heap_Mem + Heap_Size)
- LDR R3, = Stack_Mem
- BX LR
-
- ALIGN
-
- ENDIF
-
- END
-
-;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f100xe.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f100xe.s
deleted file mode 100644
index 1d77f58..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f100xe.s
+++ /dev/null
@@ -1,363 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f100xe.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F100xE Devices vector table for MDK-ARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == Reset_Handler
-;* - Set the vector table entries with the exceptions ISR address
-;* - Configure the clock system and also configure the external
-;* SRAM mounted on STM32100E-EVAL board to be used as data
-;* memory (optional, to be enabled by user)
-;* - Branches to __main in the C library (which eventually
-;* calls main()).
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;
-;*******************************************************************************
-
-; Amount of memory (in bytes) allocated for Stack
-; Tailor this value to your application needs
-; Stack Configuration
-; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Stack_Size EQU 0x00000400
-
- AREA STACK, NOINIT, READWRITE, ALIGN=3
-Stack_Mem SPACE Stack_Size
-__initial_sp
-
-
-; Heap Configuration
-; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Heap_Size EQU 0x00000200
-
- AREA HEAP, NOINIT, READWRITE, ALIGN=3
-__heap_base
-Heap_Mem SPACE Heap_Size
-__heap_limit
-
- PRESERVE8
- THUMB
-
-
-; Vector Table Mapped to Address 0 at Reset
- AREA RESET, DATA, READONLY
- EXPORT __Vectors
- EXPORT __Vectors_End
- EXPORT __Vectors_Size
-
-__Vectors DCD __initial_sp ; Top of Stack
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_IRQHandler ; ADC1
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD TIM1_BRK_TIM15_IRQHandler ; TIM1 Break and TIM15
- DCD TIM1_UP_TIM16_IRQHandler ; TIM1 Update and TIM16
- DCD TIM1_TRG_COM_TIM17_IRQHandler ; TIM1 Trigger and Commutation and TIM17
- DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C2 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD CEC_IRQHandler ; HDMI CEC
- DCD TIM12_IRQHandler ; TIM12
- DCD TIM13_IRQHandler ; TIM13
- DCD TIM14_IRQHandler ; TIM14
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD TIM5_IRQHandler ; TIM5
- DCD SPI3_IRQHandler ; SPI3
- DCD UART4_IRQHandler ; UART4
- DCD UART5_IRQHandler ; UART5
- DCD TIM6_DAC_IRQHandler ; TIM6 and DAC underrun
- DCD TIM7_IRQHandler ; TIM7
- DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
- DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
- DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
- DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
- DCD DMA2_Channel5_IRQHandler ; DMA2 Channel5
-__Vectors_End
-
-__Vectors_Size EQU __Vectors_End - __Vectors
-
- AREA |.text|, CODE, READONLY
-
-; Reset handler
-Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT __main
- IMPORT SystemInit
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BX R0
- ENDP
-
-; Dummy Exception Handlers (infinite loops which can be modified)
-
-NMI_Handler PROC
- EXPORT NMI_Handler [WEAK]
- B .
- ENDP
-HardFault_Handler\
- PROC
- EXPORT HardFault_Handler [WEAK]
- B .
- ENDP
-MemManage_Handler\
- PROC
- EXPORT MemManage_Handler [WEAK]
- B .
- ENDP
-BusFault_Handler\
- PROC
- EXPORT BusFault_Handler [WEAK]
- B .
- ENDP
-UsageFault_Handler\
- PROC
- EXPORT UsageFault_Handler [WEAK]
- B .
- ENDP
-SVC_Handler PROC
- EXPORT SVC_Handler [WEAK]
- B .
- ENDP
-DebugMon_Handler\
- PROC
- EXPORT DebugMon_Handler [WEAK]
- B .
- ENDP
-PendSV_Handler PROC
- EXPORT PendSV_Handler [WEAK]
- B .
- ENDP
-SysTick_Handler PROC
- EXPORT SysTick_Handler [WEAK]
- B .
- ENDP
-
-Default_Handler PROC
-
- EXPORT WWDG_IRQHandler [WEAK]
- EXPORT PVD_IRQHandler [WEAK]
- EXPORT TAMPER_IRQHandler [WEAK]
- EXPORT RTC_IRQHandler [WEAK]
- EXPORT FLASH_IRQHandler [WEAK]
- EXPORT RCC_IRQHandler [WEAK]
- EXPORT EXTI0_IRQHandler [WEAK]
- EXPORT EXTI1_IRQHandler [WEAK]
- EXPORT EXTI2_IRQHandler [WEAK]
- EXPORT EXTI3_IRQHandler [WEAK]
- EXPORT EXTI4_IRQHandler [WEAK]
- EXPORT DMA1_Channel1_IRQHandler [WEAK]
- EXPORT DMA1_Channel2_IRQHandler [WEAK]
- EXPORT DMA1_Channel3_IRQHandler [WEAK]
- EXPORT DMA1_Channel4_IRQHandler [WEAK]
- EXPORT DMA1_Channel5_IRQHandler [WEAK]
- EXPORT DMA1_Channel6_IRQHandler [WEAK]
- EXPORT DMA1_Channel7_IRQHandler [WEAK]
- EXPORT ADC1_IRQHandler [WEAK]
- EXPORT EXTI9_5_IRQHandler [WEAK]
- EXPORT TIM1_BRK_TIM15_IRQHandler [WEAK]
- EXPORT TIM1_UP_TIM16_IRQHandler [WEAK]
- EXPORT TIM1_TRG_COM_TIM17_IRQHandler [WEAK]
- EXPORT TIM1_CC_IRQHandler [WEAK]
- EXPORT TIM2_IRQHandler [WEAK]
- EXPORT TIM3_IRQHandler [WEAK]
- EXPORT TIM4_IRQHandler [WEAK]
- EXPORT I2C1_EV_IRQHandler [WEAK]
- EXPORT I2C1_ER_IRQHandler [WEAK]
- EXPORT I2C2_EV_IRQHandler [WEAK]
- EXPORT I2C2_ER_IRQHandler [WEAK]
- EXPORT SPI1_IRQHandler [WEAK]
- EXPORT SPI2_IRQHandler [WEAK]
- EXPORT USART1_IRQHandler [WEAK]
- EXPORT USART2_IRQHandler [WEAK]
- EXPORT USART3_IRQHandler [WEAK]
- EXPORT EXTI15_10_IRQHandler [WEAK]
- EXPORT RTC_Alarm_IRQHandler [WEAK]
- EXPORT CEC_IRQHandler [WEAK]
- EXPORT TIM12_IRQHandler [WEAK]
- EXPORT TIM13_IRQHandler [WEAK]
- EXPORT TIM14_IRQHandler [WEAK]
- EXPORT TIM5_IRQHandler [WEAK]
- EXPORT SPI3_IRQHandler [WEAK]
- EXPORT UART4_IRQHandler [WEAK]
- EXPORT UART5_IRQHandler [WEAK]
- EXPORT TIM6_DAC_IRQHandler [WEAK]
- EXPORT TIM7_IRQHandler [WEAK]
- EXPORT DMA2_Channel1_IRQHandler [WEAK]
- EXPORT DMA2_Channel2_IRQHandler [WEAK]
- EXPORT DMA2_Channel3_IRQHandler [WEAK]
- EXPORT DMA2_Channel4_5_IRQHandler [WEAK]
- EXPORT DMA2_Channel5_IRQHandler [WEAK]
-
-WWDG_IRQHandler
-PVD_IRQHandler
-TAMPER_IRQHandler
-RTC_IRQHandler
-FLASH_IRQHandler
-RCC_IRQHandler
-EXTI0_IRQHandler
-EXTI1_IRQHandler
-EXTI2_IRQHandler
-EXTI3_IRQHandler
-EXTI4_IRQHandler
-DMA1_Channel1_IRQHandler
-DMA1_Channel2_IRQHandler
-DMA1_Channel3_IRQHandler
-DMA1_Channel4_IRQHandler
-DMA1_Channel5_IRQHandler
-DMA1_Channel6_IRQHandler
-DMA1_Channel7_IRQHandler
-ADC1_IRQHandler
-EXTI9_5_IRQHandler
-TIM1_BRK_TIM15_IRQHandler
-TIM1_UP_TIM16_IRQHandler
-TIM1_TRG_COM_TIM17_IRQHandler
-TIM1_CC_IRQHandler
-TIM2_IRQHandler
-TIM3_IRQHandler
-TIM4_IRQHandler
-I2C1_EV_IRQHandler
-I2C1_ER_IRQHandler
-I2C2_EV_IRQHandler
-I2C2_ER_IRQHandler
-SPI1_IRQHandler
-SPI2_IRQHandler
-USART1_IRQHandler
-USART2_IRQHandler
-USART3_IRQHandler
-EXTI15_10_IRQHandler
-RTC_Alarm_IRQHandler
-CEC_IRQHandler
-TIM12_IRQHandler
-TIM13_IRQHandler
-TIM14_IRQHandler
-TIM5_IRQHandler
-SPI3_IRQHandler
-UART4_IRQHandler
-UART5_IRQHandler
-TIM6_DAC_IRQHandler
-TIM7_IRQHandler
-DMA2_Channel1_IRQHandler
-DMA2_Channel2_IRQHandler
-DMA2_Channel3_IRQHandler
-DMA2_Channel4_5_IRQHandler
-DMA2_Channel5_IRQHandler
- B .
-
- ENDP
-
- ALIGN
-
-;*******************************************************************************
-; User Stack and Heap initialization
-;*******************************************************************************
- IF :DEF:__MICROLIB
-
- EXPORT __initial_sp
- EXPORT __heap_base
- EXPORT __heap_limit
-
- ELSE
-
- IMPORT __use_two_region_memory
- EXPORT __user_initial_stackheap
-
-__user_initial_stackheap
-
- LDR R0, = Heap_Mem
- LDR R1, =(Stack_Mem + Stack_Size)
- LDR R2, = (Heap_Mem + Heap_Size)
- LDR R3, = Stack_Mem
- BX LR
-
- ALIGN
-
- ENDIF
-
- END
-
-;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101x6.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101x6.s
deleted file mode 100644
index ab9813a..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101x6.s
+++ /dev/null
@@ -1,295 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f101x6.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F101x6 Devices vector table for MDK-ARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == Reset_Handler
-;* - Set the vector table entries with the exceptions ISR address
-;* - Configure the clock system
-;* - Branches to __main in the C library (which eventually
-;* calls main()).
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;
-;*******************************************************************************
-
-; Amount of memory (in bytes) allocated for Stack
-; Tailor this value to your application needs
-; Stack Configuration
-; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Stack_Size EQU 0x00000400
-
- AREA STACK, NOINIT, READWRITE, ALIGN=3
-Stack_Mem SPACE Stack_Size
-__initial_sp
-
-
-; Heap Configuration
-; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Heap_Size EQU 0x00000200
-
- AREA HEAP, NOINIT, READWRITE, ALIGN=3
-__heap_base
-Heap_Mem SPACE Heap_Size
-__heap_limit
-
- PRESERVE8
- THUMB
-
-
-; Vector Table Mapped to Address 0 at Reset
- AREA RESET, DATA, READONLY
- EXPORT __Vectors
- EXPORT __Vectors_End
- EXPORT __Vectors_Size
-
-__Vectors DCD __initial_sp ; Top of Stack
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_IRQHandler ; ADC1
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD 0 ; Reserved
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SPI1_IRQHandler ; SPI1
- DCD 0 ; Reserved
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD 0 ; Reserved
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
-__Vectors_End
-
-__Vectors_Size EQU __Vectors_End - __Vectors
-
- AREA |.text|, CODE, READONLY
-
-; Reset handler routine
-Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT __main
- IMPORT SystemInit
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BX R0
- ENDP
-
-; Dummy Exception Handlers (infinite loops which can be modified)
-
-NMI_Handler PROC
- EXPORT NMI_Handler [WEAK]
- B .
- ENDP
-HardFault_Handler\
- PROC
- EXPORT HardFault_Handler [WEAK]
- B .
- ENDP
-MemManage_Handler\
- PROC
- EXPORT MemManage_Handler [WEAK]
- B .
- ENDP
-BusFault_Handler\
- PROC
- EXPORT BusFault_Handler [WEAK]
- B .
- ENDP
-UsageFault_Handler\
- PROC
- EXPORT UsageFault_Handler [WEAK]
- B .
- ENDP
-SVC_Handler PROC
- EXPORT SVC_Handler [WEAK]
- B .
- ENDP
-DebugMon_Handler\
- PROC
- EXPORT DebugMon_Handler [WEAK]
- B .
- ENDP
-PendSV_Handler PROC
- EXPORT PendSV_Handler [WEAK]
- B .
- ENDP
-SysTick_Handler PROC
- EXPORT SysTick_Handler [WEAK]
- B .
- ENDP
-
-Default_Handler PROC
-
- EXPORT WWDG_IRQHandler [WEAK]
- EXPORT PVD_IRQHandler [WEAK]
- EXPORT TAMPER_IRQHandler [WEAK]
- EXPORT RTC_IRQHandler [WEAK]
- EXPORT FLASH_IRQHandler [WEAK]
- EXPORT RCC_IRQHandler [WEAK]
- EXPORT EXTI0_IRQHandler [WEAK]
- EXPORT EXTI1_IRQHandler [WEAK]
- EXPORT EXTI2_IRQHandler [WEAK]
- EXPORT EXTI3_IRQHandler [WEAK]
- EXPORT EXTI4_IRQHandler [WEAK]
- EXPORT DMA1_Channel1_IRQHandler [WEAK]
- EXPORT DMA1_Channel2_IRQHandler [WEAK]
- EXPORT DMA1_Channel3_IRQHandler [WEAK]
- EXPORT DMA1_Channel4_IRQHandler [WEAK]
- EXPORT DMA1_Channel5_IRQHandler [WEAK]
- EXPORT DMA1_Channel6_IRQHandler [WEAK]
- EXPORT DMA1_Channel7_IRQHandler [WEAK]
- EXPORT ADC1_IRQHandler [WEAK]
- EXPORT EXTI9_5_IRQHandler [WEAK]
- EXPORT TIM2_IRQHandler [WEAK]
- EXPORT TIM3_IRQHandler [WEAK]
- EXPORT I2C1_EV_IRQHandler [WEAK]
- EXPORT I2C1_ER_IRQHandler [WEAK]
- EXPORT SPI1_IRQHandler [WEAK]
- EXPORT USART1_IRQHandler [WEAK]
- EXPORT USART2_IRQHandler [WEAK]
- EXPORT EXTI15_10_IRQHandler [WEAK]
- EXPORT RTC_Alarm_IRQHandler [WEAK]
-
-WWDG_IRQHandler
-PVD_IRQHandler
-TAMPER_IRQHandler
-RTC_IRQHandler
-FLASH_IRQHandler
-RCC_IRQHandler
-EXTI0_IRQHandler
-EXTI1_IRQHandler
-EXTI2_IRQHandler
-EXTI3_IRQHandler
-EXTI4_IRQHandler
-DMA1_Channel1_IRQHandler
-DMA1_Channel2_IRQHandler
-DMA1_Channel3_IRQHandler
-DMA1_Channel4_IRQHandler
-DMA1_Channel5_IRQHandler
-DMA1_Channel6_IRQHandler
-DMA1_Channel7_IRQHandler
-ADC1_IRQHandler
-EXTI9_5_IRQHandler
-TIM2_IRQHandler
-TIM3_IRQHandler
-I2C1_EV_IRQHandler
-I2C1_ER_IRQHandler
-SPI1_IRQHandler
-USART1_IRQHandler
-USART2_IRQHandler
-EXTI15_10_IRQHandler
-RTC_Alarm_IRQHandler
-
- B .
-
- ENDP
-
- ALIGN
-
-;*******************************************************************************
-; User Stack and Heap initialization
-;*******************************************************************************
- IF :DEF:__MICROLIB
-
- EXPORT __initial_sp
- EXPORT __heap_base
- EXPORT __heap_limit
-
- ELSE
-
- IMPORT __use_two_region_memory
- EXPORT __user_initial_stackheap
-
-__user_initial_stackheap
-
- LDR R0, = Heap_Mem
- LDR R1, =(Stack_Mem + Stack_Size)
- LDR R2, = (Heap_Mem + Heap_Size)
- LDR R3, = Stack_Mem
- BX LR
-
- ALIGN
-
- ENDIF
-
- END
-
-;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101xb.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101xb.s
deleted file mode 100644
index 74aed8d..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101xb.s
+++ /dev/null
@@ -1,305 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f101xb.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F101xB Devices vector table for MDK-ARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == Reset_Handler
-;* - Set the vector table entries with the exceptions ISR address
-;* - Configure the clock system
-;* - Branches to __main in the C library (which eventually
-;* calls main()).
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;
-;*******************************************************************************
-
-; Amount of memory (in bytes) allocated for Stack
-; Tailor this value to your application needs
-; Stack Configuration
-; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Stack_Size EQU 0x00000400
-
- AREA STACK, NOINIT, READWRITE, ALIGN=3
-Stack_Mem SPACE Stack_Size
-__initial_sp
-
-
-; Heap Configuration
-; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Heap_Size EQU 0x00000200
-
- AREA HEAP, NOINIT, READWRITE, ALIGN=3
-__heap_base
-Heap_Mem SPACE Heap_Size
-__heap_limit
-
- PRESERVE8
- THUMB
-
-
-; Vector Table Mapped to Address 0 at Reset
- AREA RESET, DATA, READONLY
- EXPORT __Vectors
- EXPORT __Vectors_End
- EXPORT __Vectors_Size
-
-__Vectors DCD __initial_sp ; Top of Stack
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_IRQHandler ; ADC1
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C2 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
-__Vectors_End
-
-__Vectors_Size EQU __Vectors_End - __Vectors
-
- AREA |.text|, CODE, READONLY
-
-; Reset handler
-Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT __main
- IMPORT SystemInit
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BX R0
- ENDP
-
-; Dummy Exception Handlers (infinite loops which can be modified)
-
-NMI_Handler PROC
- EXPORT NMI_Handler [WEAK]
- B .
- ENDP
-HardFault_Handler\
- PROC
- EXPORT HardFault_Handler [WEAK]
- B .
- ENDP
-MemManage_Handler\
- PROC
- EXPORT MemManage_Handler [WEAK]
- B .
- ENDP
-BusFault_Handler\
- PROC
- EXPORT BusFault_Handler [WEAK]
- B .
- ENDP
-UsageFault_Handler\
- PROC
- EXPORT UsageFault_Handler [WEAK]
- B .
- ENDP
-SVC_Handler PROC
- EXPORT SVC_Handler [WEAK]
- B .
- ENDP
-DebugMon_Handler\
- PROC
- EXPORT DebugMon_Handler [WEAK]
- B .
- ENDP
-PendSV_Handler PROC
- EXPORT PendSV_Handler [WEAK]
- B .
- ENDP
-SysTick_Handler PROC
- EXPORT SysTick_Handler [WEAK]
- B .
- ENDP
-
-Default_Handler PROC
-
- EXPORT WWDG_IRQHandler [WEAK]
- EXPORT PVD_IRQHandler [WEAK]
- EXPORT TAMPER_IRQHandler [WEAK]
- EXPORT RTC_IRQHandler [WEAK]
- EXPORT FLASH_IRQHandler [WEAK]
- EXPORT RCC_IRQHandler [WEAK]
- EXPORT EXTI0_IRQHandler [WEAK]
- EXPORT EXTI1_IRQHandler [WEAK]
- EXPORT EXTI2_IRQHandler [WEAK]
- EXPORT EXTI3_IRQHandler [WEAK]
- EXPORT EXTI4_IRQHandler [WEAK]
- EXPORT DMA1_Channel1_IRQHandler [WEAK]
- EXPORT DMA1_Channel2_IRQHandler [WEAK]
- EXPORT DMA1_Channel3_IRQHandler [WEAK]
- EXPORT DMA1_Channel4_IRQHandler [WEAK]
- EXPORT DMA1_Channel5_IRQHandler [WEAK]
- EXPORT DMA1_Channel6_IRQHandler [WEAK]
- EXPORT DMA1_Channel7_IRQHandler [WEAK]
- EXPORT ADC1_IRQHandler [WEAK]
- EXPORT EXTI9_5_IRQHandler [WEAK]
- EXPORT TIM2_IRQHandler [WEAK]
- EXPORT TIM3_IRQHandler [WEAK]
- EXPORT TIM4_IRQHandler [WEAK]
- EXPORT I2C1_EV_IRQHandler [WEAK]
- EXPORT I2C1_ER_IRQHandler [WEAK]
- EXPORT I2C2_EV_IRQHandler [WEAK]
- EXPORT I2C2_ER_IRQHandler [WEAK]
- EXPORT SPI1_IRQHandler [WEAK]
- EXPORT SPI2_IRQHandler [WEAK]
- EXPORT USART1_IRQHandler [WEAK]
- EXPORT USART2_IRQHandler [WEAK]
- EXPORT USART3_IRQHandler [WEAK]
- EXPORT EXTI15_10_IRQHandler [WEAK]
- EXPORT RTC_Alarm_IRQHandler [WEAK]
-
-WWDG_IRQHandler
-PVD_IRQHandler
-TAMPER_IRQHandler
-RTC_IRQHandler
-FLASH_IRQHandler
-RCC_IRQHandler
-EXTI0_IRQHandler
-EXTI1_IRQHandler
-EXTI2_IRQHandler
-EXTI3_IRQHandler
-EXTI4_IRQHandler
-DMA1_Channel1_IRQHandler
-DMA1_Channel2_IRQHandler
-DMA1_Channel3_IRQHandler
-DMA1_Channel4_IRQHandler
-DMA1_Channel5_IRQHandler
-DMA1_Channel6_IRQHandler
-DMA1_Channel7_IRQHandler
-ADC1_IRQHandler
-EXTI9_5_IRQHandler
-TIM2_IRQHandler
-TIM3_IRQHandler
-TIM4_IRQHandler
-I2C1_EV_IRQHandler
-I2C1_ER_IRQHandler
-I2C2_EV_IRQHandler
-I2C2_ER_IRQHandler
-SPI1_IRQHandler
-SPI2_IRQHandler
-USART1_IRQHandler
-USART2_IRQHandler
-USART3_IRQHandler
-EXTI15_10_IRQHandler
-RTC_Alarm_IRQHandler
-
- B .
-
- ENDP
-
- ALIGN
-
-;*******************************************************************************
-; User Stack and Heap initialization
-;*******************************************************************************
- IF :DEF:__MICROLIB
-
- EXPORT __initial_sp
- EXPORT __heap_base
- EXPORT __heap_limit
-
- ELSE
-
- IMPORT __use_two_region_memory
- EXPORT __user_initial_stackheap
-
-__user_initial_stackheap
-
- LDR R0, = Heap_Mem
- LDR R1, =(Stack_Mem + Stack_Size)
- LDR R2, = (Heap_Mem + Heap_Size)
- LDR R3, = Stack_Mem
- BX LR
-
- ALIGN
-
- ENDIF
-
- END
-
-;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101xe.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101xe.s
deleted file mode 100644
index 865dcd1..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101xe.s
+++ /dev/null
@@ -1,343 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f101xe.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F101xE Devices vector table for MDK-ARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == Reset_Handler
-;* - Set the vector table entries with the exceptions ISR address
-;* - Configure the clock system
-;* - Branches to __main in the C library (which eventually
-;* calls main()).
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;
-;*******************************************************************************
-
-; Amount of memory (in bytes) allocated for Stack
-; Tailor this value to your application needs
-; Stack Configuration
-; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Stack_Size EQU 0x00000400
-
- AREA STACK, NOINIT, READWRITE, ALIGN=3
-Stack_Mem SPACE Stack_Size
-__initial_sp
-
-; Heap Configuration
-; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Heap_Size EQU 0x00000200
-
- AREA HEAP, NOINIT, READWRITE, ALIGN=3
-__heap_base
-Heap_Mem SPACE Heap_Size
-__heap_limit
-
- PRESERVE8
- THUMB
-
-
-; Vector Table Mapped to Address 0 at Reset
- AREA RESET, DATA, READONLY
- EXPORT __Vectors
- EXPORT __Vectors_End
- EXPORT __Vectors_Size
-
-__Vectors DCD __initial_sp ; Top of Stack
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_IRQHandler ; ADC1
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C2 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD FSMC_IRQHandler ; FSMC
- DCD 0 ; Reserved
- DCD TIM5_IRQHandler ; TIM5
- DCD SPI3_IRQHandler ; SPI3
- DCD UART4_IRQHandler ; UART4
- DCD UART5_IRQHandler ; UART5
- DCD TIM6_IRQHandler ; TIM6
- DCD TIM7_IRQHandler ; TIM7
- DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
- DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
- DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
- DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
-__Vectors_End
-
-__Vectors_Size EQU __Vectors_End - __Vectors
-
- AREA |.text|, CODE, READONLY
-
-; Reset handler
-Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT __main
- IMPORT SystemInit
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BX R0
- ENDP
-
-; Dummy Exception Handlers (infinite loops which can be modified)
-
-NMI_Handler PROC
- EXPORT NMI_Handler [WEAK]
- B .
- ENDP
-HardFault_Handler\
- PROC
- EXPORT HardFault_Handler [WEAK]
- B .
- ENDP
-MemManage_Handler\
- PROC
- EXPORT MemManage_Handler [WEAK]
- B .
- ENDP
-BusFault_Handler\
- PROC
- EXPORT BusFault_Handler [WEAK]
- B .
- ENDP
-UsageFault_Handler\
- PROC
- EXPORT UsageFault_Handler [WEAK]
- B .
- ENDP
-SVC_Handler PROC
- EXPORT SVC_Handler [WEAK]
- B .
- ENDP
-DebugMon_Handler\
- PROC
- EXPORT DebugMon_Handler [WEAK]
- B .
- ENDP
-PendSV_Handler PROC
- EXPORT PendSV_Handler [WEAK]
- B .
- ENDP
-SysTick_Handler PROC
- EXPORT SysTick_Handler [WEAK]
- B .
- ENDP
-
-Default_Handler PROC
-
- EXPORT WWDG_IRQHandler [WEAK]
- EXPORT PVD_IRQHandler [WEAK]
- EXPORT TAMPER_IRQHandler [WEAK]
- EXPORT RTC_IRQHandler [WEAK]
- EXPORT FLASH_IRQHandler [WEAK]
- EXPORT RCC_IRQHandler [WEAK]
- EXPORT EXTI0_IRQHandler [WEAK]
- EXPORT EXTI1_IRQHandler [WEAK]
- EXPORT EXTI2_IRQHandler [WEAK]
- EXPORT EXTI3_IRQHandler [WEAK]
- EXPORT EXTI4_IRQHandler [WEAK]
- EXPORT DMA1_Channel1_IRQHandler [WEAK]
- EXPORT DMA1_Channel2_IRQHandler [WEAK]
- EXPORT DMA1_Channel3_IRQHandler [WEAK]
- EXPORT DMA1_Channel4_IRQHandler [WEAK]
- EXPORT DMA1_Channel5_IRQHandler [WEAK]
- EXPORT DMA1_Channel6_IRQHandler [WEAK]
- EXPORT DMA1_Channel7_IRQHandler [WEAK]
- EXPORT ADC1_IRQHandler [WEAK]
- EXPORT EXTI9_5_IRQHandler [WEAK]
- EXPORT TIM2_IRQHandler [WEAK]
- EXPORT TIM3_IRQHandler [WEAK]
- EXPORT TIM4_IRQHandler [WEAK]
- EXPORT I2C1_EV_IRQHandler [WEAK]
- EXPORT I2C1_ER_IRQHandler [WEAK]
- EXPORT I2C2_EV_IRQHandler [WEAK]
- EXPORT I2C2_ER_IRQHandler [WEAK]
- EXPORT SPI1_IRQHandler [WEAK]
- EXPORT SPI2_IRQHandler [WEAK]
- EXPORT USART1_IRQHandler [WEAK]
- EXPORT USART2_IRQHandler [WEAK]
- EXPORT USART3_IRQHandler [WEAK]
- EXPORT EXTI15_10_IRQHandler [WEAK]
- EXPORT RTC_Alarm_IRQHandler [WEAK]
- EXPORT FSMC_IRQHandler [WEAK]
- EXPORT TIM5_IRQHandler [WEAK]
- EXPORT SPI3_IRQHandler [WEAK]
- EXPORT UART4_IRQHandler [WEAK]
- EXPORT UART5_IRQHandler [WEAK]
- EXPORT TIM6_IRQHandler [WEAK]
- EXPORT TIM7_IRQHandler [WEAK]
- EXPORT DMA2_Channel1_IRQHandler [WEAK]
- EXPORT DMA2_Channel2_IRQHandler [WEAK]
- EXPORT DMA2_Channel3_IRQHandler [WEAK]
- EXPORT DMA2_Channel4_5_IRQHandler [WEAK]
-
-WWDG_IRQHandler
-PVD_IRQHandler
-TAMPER_IRQHandler
-RTC_IRQHandler
-FLASH_IRQHandler
-RCC_IRQHandler
-EXTI0_IRQHandler
-EXTI1_IRQHandler
-EXTI2_IRQHandler
-EXTI3_IRQHandler
-EXTI4_IRQHandler
-DMA1_Channel1_IRQHandler
-DMA1_Channel2_IRQHandler
-DMA1_Channel3_IRQHandler
-DMA1_Channel4_IRQHandler
-DMA1_Channel5_IRQHandler
-DMA1_Channel6_IRQHandler
-DMA1_Channel7_IRQHandler
-ADC1_IRQHandler
-EXTI9_5_IRQHandler
-TIM2_IRQHandler
-TIM3_IRQHandler
-TIM4_IRQHandler
-I2C1_EV_IRQHandler
-I2C1_ER_IRQHandler
-I2C2_EV_IRQHandler
-I2C2_ER_IRQHandler
-SPI1_IRQHandler
-SPI2_IRQHandler
-USART1_IRQHandler
-USART2_IRQHandler
-USART3_IRQHandler
-EXTI15_10_IRQHandler
-RTC_Alarm_IRQHandler
-FSMC_IRQHandler
-TIM5_IRQHandler
-SPI3_IRQHandler
-UART4_IRQHandler
-UART5_IRQHandler
-TIM6_IRQHandler
-TIM7_IRQHandler
-DMA2_Channel1_IRQHandler
-DMA2_Channel2_IRQHandler
-DMA2_Channel3_IRQHandler
-DMA2_Channel4_5_IRQHandler
- B .
-
- ENDP
-
- ALIGN
-
-;*******************************************************************************
-; User Stack and Heap initialization
-;*******************************************************************************
- IF :DEF:__MICROLIB
-
- EXPORT __initial_sp
- EXPORT __heap_base
- EXPORT __heap_limit
-
- ELSE
-
- IMPORT __use_two_region_memory
- EXPORT __user_initial_stackheap
-
-__user_initial_stackheap
-
- LDR R0, = Heap_Mem
- LDR R1, =(Stack_Mem + Stack_Size)
- LDR R2, = (Heap_Mem + Heap_Size)
- LDR R3, = Stack_Mem
- BX LR
-
- ALIGN
-
- ENDIF
-
- END
-
-;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101xg.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101xg.s
deleted file mode 100644
index 15276ac..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101xg.s
+++ /dev/null
@@ -1,355 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f101xg.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F101xG Devices vector table for MDK-ARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == Reset_Handler
-;* - Set the vector table entries with the exceptions ISR address
-;* - Configure the clock system
-;* - Branches to __main in the C library (which eventually
-;* calls main()).
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;
-;*******************************************************************************
-
-; Amount of memory (in bytes) allocated for Stack
-; Tailor this value to your application needs
-; Stack Configuration
-; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Stack_Size EQU 0x00000400
-
- AREA STACK, NOINIT, READWRITE, ALIGN=3
-Stack_Mem SPACE Stack_Size
-__initial_sp
-
-; Heap Configuration
-; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Heap_Size EQU 0x00000200
-
- AREA HEAP, NOINIT, READWRITE, ALIGN=3
-__heap_base
-Heap_Mem SPACE Heap_Size
-__heap_limit
-
- PRESERVE8
- THUMB
-
-
-; Vector Table Mapped to Address 0 at Reset
- AREA RESET, DATA, READONLY
- EXPORT __Vectors
- EXPORT __Vectors_End
- EXPORT __Vectors_Size
-
-__Vectors DCD __initial_sp ; Top of Stack
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_2_IRQHandler ; ADC1_2
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD TIM9_IRQHandler ; TIM9
- DCD TIM10_IRQHandler ; TIM10
- DCD TIM11_IRQHandler ; TIM11
- DCD 0 ; Reserved
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C2 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD 0 ; Reserved
- DCD TIM12_IRQHandler ; TIM12
- DCD TIM13_IRQHandler ; TIM13
- DCD TIM14_IRQHandler ; TIM14
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD FSMC_IRQHandler ; FSMC
- DCD 0 ; Reserved
- DCD TIM5_IRQHandler ; TIM5
- DCD SPI3_IRQHandler ; SPI3
- DCD UART4_IRQHandler ; UART4
- DCD UART5_IRQHandler ; UART5
- DCD TIM6_IRQHandler ; TIM6
- DCD TIM7_IRQHandler ; TIM7
- DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
- DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
- DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
- DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
-__Vectors_End
-
-__Vectors_Size EQU __Vectors_End - __Vectors
-
- AREA |.text|, CODE, READONLY
-
-; Reset handler
-Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT __main
- IMPORT SystemInit
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BX R0
- ENDP
-
-; Dummy Exception Handlers (infinite loops which can be modified)
-
-NMI_Handler PROC
- EXPORT NMI_Handler [WEAK]
- B .
- ENDP
-HardFault_Handler\
- PROC
- EXPORT HardFault_Handler [WEAK]
- B .
- ENDP
-MemManage_Handler\
- PROC
- EXPORT MemManage_Handler [WEAK]
- B .
- ENDP
-BusFault_Handler\
- PROC
- EXPORT BusFault_Handler [WEAK]
- B .
- ENDP
-UsageFault_Handler\
- PROC
- EXPORT UsageFault_Handler [WEAK]
- B .
- ENDP
-SVC_Handler PROC
- EXPORT SVC_Handler [WEAK]
- B .
- ENDP
-DebugMon_Handler\
- PROC
- EXPORT DebugMon_Handler [WEAK]
- B .
- ENDP
-PendSV_Handler PROC
- EXPORT PendSV_Handler [WEAK]
- B .
- ENDP
-SysTick_Handler PROC
- EXPORT SysTick_Handler [WEAK]
- B .
- ENDP
-
-Default_Handler PROC
-
- EXPORT WWDG_IRQHandler [WEAK]
- EXPORT PVD_IRQHandler [WEAK]
- EXPORT TAMPER_IRQHandler [WEAK]
- EXPORT RTC_IRQHandler [WEAK]
- EXPORT FLASH_IRQHandler [WEAK]
- EXPORT RCC_IRQHandler [WEAK]
- EXPORT EXTI0_IRQHandler [WEAK]
- EXPORT EXTI1_IRQHandler [WEAK]
- EXPORT EXTI2_IRQHandler [WEAK]
- EXPORT EXTI3_IRQHandler [WEAK]
- EXPORT EXTI4_IRQHandler [WEAK]
- EXPORT DMA1_Channel1_IRQHandler [WEAK]
- EXPORT DMA1_Channel2_IRQHandler [WEAK]
- EXPORT DMA1_Channel3_IRQHandler [WEAK]
- EXPORT DMA1_Channel4_IRQHandler [WEAK]
- EXPORT DMA1_Channel5_IRQHandler [WEAK]
- EXPORT DMA1_Channel6_IRQHandler [WEAK]
- EXPORT DMA1_Channel7_IRQHandler [WEAK]
- EXPORT ADC1_2_IRQHandler [WEAK]
- EXPORT EXTI9_5_IRQHandler [WEAK]
- EXPORT TIM9_IRQHandler [WEAK]
- EXPORT TIM10_IRQHandler [WEAK]
- EXPORT TIM11_IRQHandler [WEAK]
- EXPORT TIM2_IRQHandler [WEAK]
- EXPORT TIM3_IRQHandler [WEAK]
- EXPORT TIM4_IRQHandler [WEAK]
- EXPORT I2C1_EV_IRQHandler [WEAK]
- EXPORT I2C1_ER_IRQHandler [WEAK]
- EXPORT I2C2_EV_IRQHandler [WEAK]
- EXPORT I2C2_ER_IRQHandler [WEAK]
- EXPORT SPI1_IRQHandler [WEAK]
- EXPORT SPI2_IRQHandler [WEAK]
- EXPORT USART1_IRQHandler [WEAK]
- EXPORT USART2_IRQHandler [WEAK]
- EXPORT USART3_IRQHandler [WEAK]
- EXPORT EXTI15_10_IRQHandler [WEAK]
- EXPORT RTC_Alarm_IRQHandler [WEAK]
- EXPORT TIM12_IRQHandler [WEAK]
- EXPORT TIM13_IRQHandler [WEAK]
- EXPORT TIM14_IRQHandler [WEAK]
- EXPORT FSMC_IRQHandler [WEAK]
- EXPORT TIM5_IRQHandler [WEAK]
- EXPORT SPI3_IRQHandler [WEAK]
- EXPORT UART4_IRQHandler [WEAK]
- EXPORT UART5_IRQHandler [WEAK]
- EXPORT TIM6_IRQHandler [WEAK]
- EXPORT TIM7_IRQHandler [WEAK]
- EXPORT DMA2_Channel1_IRQHandler [WEAK]
- EXPORT DMA2_Channel2_IRQHandler [WEAK]
- EXPORT DMA2_Channel3_IRQHandler [WEAK]
- EXPORT DMA2_Channel4_5_IRQHandler [WEAK]
-
-WWDG_IRQHandler
-PVD_IRQHandler
-TAMPER_IRQHandler
-RTC_IRQHandler
-FLASH_IRQHandler
-RCC_IRQHandler
-EXTI0_IRQHandler
-EXTI1_IRQHandler
-EXTI2_IRQHandler
-EXTI3_IRQHandler
-EXTI4_IRQHandler
-DMA1_Channel1_IRQHandler
-DMA1_Channel2_IRQHandler
-DMA1_Channel3_IRQHandler
-DMA1_Channel4_IRQHandler
-DMA1_Channel5_IRQHandler
-DMA1_Channel6_IRQHandler
-DMA1_Channel7_IRQHandler
-ADC1_2_IRQHandler
-EXTI9_5_IRQHandler
-TIM9_IRQHandler
-TIM10_IRQHandler
-TIM11_IRQHandler
-TIM2_IRQHandler
-TIM3_IRQHandler
-TIM4_IRQHandler
-I2C1_EV_IRQHandler
-I2C1_ER_IRQHandler
-I2C2_EV_IRQHandler
-I2C2_ER_IRQHandler
-SPI1_IRQHandler
-SPI2_IRQHandler
-USART1_IRQHandler
-USART2_IRQHandler
-USART3_IRQHandler
-EXTI15_10_IRQHandler
-RTC_Alarm_IRQHandler
-TIM12_IRQHandler
-TIM13_IRQHandler
-TIM14_IRQHandler
-FSMC_IRQHandler
-TIM5_IRQHandler
-SPI3_IRQHandler
-UART4_IRQHandler
-UART5_IRQHandler
-TIM6_IRQHandler
-TIM7_IRQHandler
-DMA2_Channel1_IRQHandler
-DMA2_Channel2_IRQHandler
-DMA2_Channel3_IRQHandler
-DMA2_Channel4_5_IRQHandler
- B .
-
- ENDP
-
- ALIGN
-
-;*******************************************************************************
-; User Stack and Heap initialization
-;*******************************************************************************
- IF :DEF:__MICROLIB
-
- EXPORT __initial_sp
- EXPORT __heap_base
- EXPORT __heap_limit
-
- ELSE
-
- IMPORT __use_two_region_memory
- EXPORT __user_initial_stackheap
-
-__user_initial_stackheap
-
- LDR R0, = Heap_Mem
- LDR R1, =(Stack_Mem + Stack_Size)
- LDR R2, = (Heap_Mem + Heap_Size)
- LDR R3, = Stack_Mem
- BX LR
-
- ALIGN
-
- ENDIF
-
- END
-
-;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f102x6.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f102x6.s
deleted file mode 100644
index f6e46bc..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f102x6.s
+++ /dev/null
@@ -1,302 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f102x6.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F102x6 Devices vector table for MDK-ARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == Reset_Handler
-;* - Set the vector table entries with the exceptions ISR address
-;* - Configure the clock system
-;* - Branches to __main in the C library (which eventually
-;* calls main()).
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;
-;*******************************************************************************
-
-; Amount of memory (in bytes) allocated for Stack
-; Tailor this value to your application needs
-; Stack Configuration
-; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Stack_Size EQU 0x00000400
-
- AREA STACK, NOINIT, READWRITE, ALIGN=3
-Stack_Mem SPACE Stack_Size
-__initial_sp
-
-
-; Heap Configuration
-; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Heap_Size EQU 0x00000200
-
- AREA HEAP, NOINIT, READWRITE, ALIGN=3
-__heap_base
-Heap_Mem SPACE Heap_Size
-__heap_limit
-
- PRESERVE8
- THUMB
-
-
-; Vector Table Mapped to Address 0 at Reset
- AREA RESET, DATA, READONLY
- EXPORT __Vectors
- EXPORT __Vectors_End
- EXPORT __Vectors_Size
-
-__Vectors DCD __initial_sp ; Top of Stack
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_IRQHandler ; ADC1
- DCD USB_HP_IRQHandler ; USB High Priority
- DCD USB_LP_IRQHandler ; USB Low Priority
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD 0 ; Reserved
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SPI1_IRQHandler ; SPI1
- DCD 0 ; Reserved
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD 0 ; Reserved
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
-__Vectors_End
-
-__Vectors_Size EQU __Vectors_End - __Vectors
-
- AREA |.text|, CODE, READONLY
-
-; Reset handler routine
-Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT __main
- IMPORT SystemInit
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BX R0
- ENDP
-
-; Dummy Exception Handlers (infinite loops which can be modified)
-
-NMI_Handler PROC
- EXPORT NMI_Handler [WEAK]
- B .
- ENDP
-HardFault_Handler\
- PROC
- EXPORT HardFault_Handler [WEAK]
- B .
- ENDP
-MemManage_Handler\
- PROC
- EXPORT MemManage_Handler [WEAK]
- B .
- ENDP
-BusFault_Handler\
- PROC
- EXPORT BusFault_Handler [WEAK]
- B .
- ENDP
-UsageFault_Handler\
- PROC
- EXPORT UsageFault_Handler [WEAK]
- B .
- ENDP
-SVC_Handler PROC
- EXPORT SVC_Handler [WEAK]
- B .
- ENDP
-DebugMon_Handler\
- PROC
- EXPORT DebugMon_Handler [WEAK]
- B .
- ENDP
-PendSV_Handler PROC
- EXPORT PendSV_Handler [WEAK]
- B .
- ENDP
-SysTick_Handler PROC
- EXPORT SysTick_Handler [WEAK]
- B .
- ENDP
-
-Default_Handler PROC
-
- EXPORT WWDG_IRQHandler [WEAK]
- EXPORT PVD_IRQHandler [WEAK]
- EXPORT TAMPER_IRQHandler [WEAK]
- EXPORT RTC_IRQHandler [WEAK]
- EXPORT FLASH_IRQHandler [WEAK]
- EXPORT RCC_IRQHandler [WEAK]
- EXPORT EXTI0_IRQHandler [WEAK]
- EXPORT EXTI1_IRQHandler [WEAK]
- EXPORT EXTI2_IRQHandler [WEAK]
- EXPORT EXTI3_IRQHandler [WEAK]
- EXPORT EXTI4_IRQHandler [WEAK]
- EXPORT DMA1_Channel1_IRQHandler [WEAK]
- EXPORT DMA1_Channel2_IRQHandler [WEAK]
- EXPORT DMA1_Channel3_IRQHandler [WEAK]
- EXPORT DMA1_Channel4_IRQHandler [WEAK]
- EXPORT DMA1_Channel5_IRQHandler [WEAK]
- EXPORT DMA1_Channel6_IRQHandler [WEAK]
- EXPORT DMA1_Channel7_IRQHandler [WEAK]
- EXPORT ADC1_IRQHandler [WEAK]
- EXPORT USB_HP_IRQHandler [WEAK]
- EXPORT USB_LP_IRQHandler [WEAK]
- EXPORT EXTI9_5_IRQHandler [WEAK]
- EXPORT TIM2_IRQHandler [WEAK]
- EXPORT TIM3_IRQHandler [WEAK]
- EXPORT I2C1_EV_IRQHandler [WEAK]
- EXPORT I2C1_ER_IRQHandler [WEAK]
- EXPORT SPI1_IRQHandler [WEAK]
- EXPORT USART1_IRQHandler [WEAK]
- EXPORT USART2_IRQHandler [WEAK]
- EXPORT EXTI15_10_IRQHandler [WEAK]
- EXPORT RTC_Alarm_IRQHandler [WEAK]
- EXPORT USBWakeUp_IRQHandler [WEAK]
-
-WWDG_IRQHandler
-PVD_IRQHandler
-TAMPER_IRQHandler
-RTC_IRQHandler
-FLASH_IRQHandler
-RCC_IRQHandler
-EXTI0_IRQHandler
-EXTI1_IRQHandler
-EXTI2_IRQHandler
-EXTI3_IRQHandler
-EXTI4_IRQHandler
-DMA1_Channel1_IRQHandler
-DMA1_Channel2_IRQHandler
-DMA1_Channel3_IRQHandler
-DMA1_Channel4_IRQHandler
-DMA1_Channel5_IRQHandler
-DMA1_Channel6_IRQHandler
-DMA1_Channel7_IRQHandler
-ADC1_IRQHandler
-USB_HP_IRQHandler
-USB_LP_IRQHandler
-EXTI9_5_IRQHandler
-TIM2_IRQHandler
-TIM3_IRQHandler
-I2C1_EV_IRQHandler
-I2C1_ER_IRQHandler
-SPI1_IRQHandler
-USART1_IRQHandler
-USART2_IRQHandler
-EXTI15_10_IRQHandler
-RTC_Alarm_IRQHandler
-USBWakeUp_IRQHandler
-
- B .
-
- ENDP
-
- ALIGN
-
-;*******************************************************************************
-; User Stack and Heap initialization
-;*******************************************************************************
- IF :DEF:__MICROLIB
-
- EXPORT __initial_sp
- EXPORT __heap_base
- EXPORT __heap_limit
-
- ELSE
-
- IMPORT __use_two_region_memory
- EXPORT __user_initial_stackheap
-
-__user_initial_stackheap
-
- LDR R0, = Heap_Mem
- LDR R1, =(Stack_Mem + Stack_Size)
- LDR R2, = (Heap_Mem + Heap_Size)
- LDR R3, = Stack_Mem
- BX LR
-
- ALIGN
-
- ENDIF
-
- END
-
-;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f102xb.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f102xb.s
deleted file mode 100644
index b8f2930..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f102xb.s
+++ /dev/null
@@ -1,312 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f102xb.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F102xB Devices vector table for MDK-ARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == Reset_Handler
-;* - Set the vector table entries with the exceptions ISR address
-;* - Configure the clock system
-;* - Branches to __main in the C library (which eventually
-;* calls main()).
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;
-;*******************************************************************************
-
-; Amount of memory (in bytes) allocated for Stack
-; Tailor this value to your application needs
-; Stack Configuration
-; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Stack_Size EQU 0x00000400
-
- AREA STACK, NOINIT, READWRITE, ALIGN=3
-Stack_Mem SPACE Stack_Size
-__initial_sp
-
-
-; Heap Configuration
-; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Heap_Size EQU 0x00000200
-
- AREA HEAP, NOINIT, READWRITE, ALIGN=3
-__heap_base
-Heap_Mem SPACE Heap_Size
-__heap_limit
-
- PRESERVE8
- THUMB
-
-
-; Vector Table Mapped to Address 0 at Reset
- AREA RESET, DATA, READONLY
- EXPORT __Vectors
- EXPORT __Vectors_End
- EXPORT __Vectors_Size
-
-__Vectors DCD __initial_sp ; Top of Stack
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_IRQHandler ; ADC1
- DCD USB_HP_IRQHandler ; USB High Priority
- DCD USB_LP_IRQHandler ; USB Low Priority
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C2 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
-__Vectors_End
-
-__Vectors_Size EQU __Vectors_End - __Vectors
-
- AREA |.text|, CODE, READONLY
-
-; Reset handler
-Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT __main
- IMPORT SystemInit
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BX R0
- ENDP
-
-; Dummy Exception Handlers (infinite loops which can be modified)
-
-NMI_Handler PROC
- EXPORT NMI_Handler [WEAK]
- B .
- ENDP
-HardFault_Handler\
- PROC
- EXPORT HardFault_Handler [WEAK]
- B .
- ENDP
-MemManage_Handler\
- PROC
- EXPORT MemManage_Handler [WEAK]
- B .
- ENDP
-BusFault_Handler\
- PROC
- EXPORT BusFault_Handler [WEAK]
- B .
- ENDP
-UsageFault_Handler\
- PROC
- EXPORT UsageFault_Handler [WEAK]
- B .
- ENDP
-SVC_Handler PROC
- EXPORT SVC_Handler [WEAK]
- B .
- ENDP
-DebugMon_Handler\
- PROC
- EXPORT DebugMon_Handler [WEAK]
- B .
- ENDP
-PendSV_Handler PROC
- EXPORT PendSV_Handler [WEAK]
- B .
- ENDP
-SysTick_Handler PROC
- EXPORT SysTick_Handler [WEAK]
- B .
- ENDP
-
-Default_Handler PROC
-
- EXPORT WWDG_IRQHandler [WEAK]
- EXPORT PVD_IRQHandler [WEAK]
- EXPORT TAMPER_IRQHandler [WEAK]
- EXPORT RTC_IRQHandler [WEAK]
- EXPORT FLASH_IRQHandler [WEAK]
- EXPORT RCC_IRQHandler [WEAK]
- EXPORT EXTI0_IRQHandler [WEAK]
- EXPORT EXTI1_IRQHandler [WEAK]
- EXPORT EXTI2_IRQHandler [WEAK]
- EXPORT EXTI3_IRQHandler [WEAK]
- EXPORT EXTI4_IRQHandler [WEAK]
- EXPORT DMA1_Channel1_IRQHandler [WEAK]
- EXPORT DMA1_Channel2_IRQHandler [WEAK]
- EXPORT DMA1_Channel3_IRQHandler [WEAK]
- EXPORT DMA1_Channel4_IRQHandler [WEAK]
- EXPORT DMA1_Channel5_IRQHandler [WEAK]
- EXPORT DMA1_Channel6_IRQHandler [WEAK]
- EXPORT DMA1_Channel7_IRQHandler [WEAK]
- EXPORT ADC1_IRQHandler [WEAK]
- EXPORT USB_HP_IRQHandler [WEAK]
- EXPORT USB_LP_IRQHandler [WEAK]
- EXPORT EXTI9_5_IRQHandler [WEAK]
- EXPORT TIM2_IRQHandler [WEAK]
- EXPORT TIM3_IRQHandler [WEAK]
- EXPORT TIM4_IRQHandler [WEAK]
- EXPORT I2C1_EV_IRQHandler [WEAK]
- EXPORT I2C1_ER_IRQHandler [WEAK]
- EXPORT I2C2_EV_IRQHandler [WEAK]
- EXPORT I2C2_ER_IRQHandler [WEAK]
- EXPORT SPI1_IRQHandler [WEAK]
- EXPORT SPI2_IRQHandler [WEAK]
- EXPORT USART1_IRQHandler [WEAK]
- EXPORT USART2_IRQHandler [WEAK]
- EXPORT USART3_IRQHandler [WEAK]
- EXPORT EXTI15_10_IRQHandler [WEAK]
- EXPORT RTC_Alarm_IRQHandler [WEAK]
- EXPORT USBWakeUp_IRQHandler [WEAK]
-
-WWDG_IRQHandler
-PVD_IRQHandler
-TAMPER_IRQHandler
-RTC_IRQHandler
-FLASH_IRQHandler
-RCC_IRQHandler
-EXTI0_IRQHandler
-EXTI1_IRQHandler
-EXTI2_IRQHandler
-EXTI3_IRQHandler
-EXTI4_IRQHandler
-DMA1_Channel1_IRQHandler
-DMA1_Channel2_IRQHandler
-DMA1_Channel3_IRQHandler
-DMA1_Channel4_IRQHandler
-DMA1_Channel5_IRQHandler
-DMA1_Channel6_IRQHandler
-DMA1_Channel7_IRQHandler
-ADC1_IRQHandler
-USB_HP_IRQHandler
-USB_LP_IRQHandler
-EXTI9_5_IRQHandler
-TIM2_IRQHandler
-TIM3_IRQHandler
-TIM4_IRQHandler
-I2C1_EV_IRQHandler
-I2C1_ER_IRQHandler
-I2C2_EV_IRQHandler
-I2C2_ER_IRQHandler
-SPI1_IRQHandler
-SPI2_IRQHandler
-USART1_IRQHandler
-USART2_IRQHandler
-USART3_IRQHandler
-EXTI15_10_IRQHandler
-RTC_Alarm_IRQHandler
-USBWakeUp_IRQHandler
-
- B .
-
- ENDP
-
- ALIGN
-
-;*******************************************************************************
-; User Stack and Heap initialization
-;*******************************************************************************
- IF :DEF:__MICROLIB
-
- EXPORT __initial_sp
- EXPORT __heap_base
- EXPORT __heap_limit
-
- ELSE
-
- IMPORT __use_two_region_memory
- EXPORT __user_initial_stackheap
-
-__user_initial_stackheap
-
- LDR R0, = Heap_Mem
- LDR R1, =(Stack_Mem + Stack_Size)
- LDR R2, = (Heap_Mem + Heap_Size)
- LDR R3, = Stack_Mem
- BX LR
-
- ALIGN
-
- ENDIF
-
- END
-
-;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103x6.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103x6.s
deleted file mode 100644
index e824c53..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103x6.s
+++ /dev/null
@@ -1,314 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f103x6.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F103x6 Devices vector table for MDK-ARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == Reset_Handler
-;* - Set the vector table entries with the exceptions ISR address
-;* - Configure the clock system
-;* - Branches to __main in the C library (which eventually
-;* calls main()).
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;
-;*******************************************************************************
-
-; Amount of memory (in bytes) allocated for Stack
-; Tailor this value to your application needs
-; Stack Configuration
-; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Stack_Size EQU 0x00000400
-
- AREA STACK, NOINIT, READWRITE, ALIGN=3
-Stack_Mem SPACE Stack_Size
-__initial_sp
-
-
-; Heap Configuration
-; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Heap_Size EQU 0x00000200
-
- AREA HEAP, NOINIT, READWRITE, ALIGN=3
-__heap_base
-Heap_Mem SPACE Heap_Size
-__heap_limit
-
- PRESERVE8
- THUMB
-
-
-; Vector Table Mapped to Address 0 at Reset
- AREA RESET, DATA, READONLY
- EXPORT __Vectors
- EXPORT __Vectors_End
- EXPORT __Vectors_Size
-
-__Vectors DCD __initial_sp ; Top of Stack
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_2_IRQHandler ; ADC1_2
- DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
- DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
- DCD CAN1_RX1_IRQHandler ; CAN1 RX1
- DCD CAN1_SCE_IRQHandler ; CAN1 SCE
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD TIM1_BRK_IRQHandler ; TIM1 Break
- DCD TIM1_UP_IRQHandler ; TIM1 Update
- DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
- DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD 0 ; Reserved
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SPI1_IRQHandler ; SPI1
- DCD 0 ; Reserved
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD 0 ; Reserved
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
-__Vectors_End
-
-__Vectors_Size EQU __Vectors_End - __Vectors
-
- AREA |.text|, CODE, READONLY
-
-; Reset handler routine
-Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT __main
- IMPORT SystemInit
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BX R0
- ENDP
-
-; Dummy Exception Handlers (infinite loops which can be modified)
-
-NMI_Handler PROC
- EXPORT NMI_Handler [WEAK]
- B .
- ENDP
-HardFault_Handler\
- PROC
- EXPORT HardFault_Handler [WEAK]
- B .
- ENDP
-MemManage_Handler\
- PROC
- EXPORT MemManage_Handler [WEAK]
- B .
- ENDP
-BusFault_Handler\
- PROC
- EXPORT BusFault_Handler [WEAK]
- B .
- ENDP
-UsageFault_Handler\
- PROC
- EXPORT UsageFault_Handler [WEAK]
- B .
- ENDP
-SVC_Handler PROC
- EXPORT SVC_Handler [WEAK]
- B .
- ENDP
-DebugMon_Handler\
- PROC
- EXPORT DebugMon_Handler [WEAK]
- B .
- ENDP
-PendSV_Handler PROC
- EXPORT PendSV_Handler [WEAK]
- B .
- ENDP
-SysTick_Handler PROC
- EXPORT SysTick_Handler [WEAK]
- B .
- ENDP
-
-Default_Handler PROC
-
- EXPORT WWDG_IRQHandler [WEAK]
- EXPORT PVD_IRQHandler [WEAK]
- EXPORT TAMPER_IRQHandler [WEAK]
- EXPORT RTC_IRQHandler [WEAK]
- EXPORT FLASH_IRQHandler [WEAK]
- EXPORT RCC_IRQHandler [WEAK]
- EXPORT EXTI0_IRQHandler [WEAK]
- EXPORT EXTI1_IRQHandler [WEAK]
- EXPORT EXTI2_IRQHandler [WEAK]
- EXPORT EXTI3_IRQHandler [WEAK]
- EXPORT EXTI4_IRQHandler [WEAK]
- EXPORT DMA1_Channel1_IRQHandler [WEAK]
- EXPORT DMA1_Channel2_IRQHandler [WEAK]
- EXPORT DMA1_Channel3_IRQHandler [WEAK]
- EXPORT DMA1_Channel4_IRQHandler [WEAK]
- EXPORT DMA1_Channel5_IRQHandler [WEAK]
- EXPORT DMA1_Channel6_IRQHandler [WEAK]
- EXPORT DMA1_Channel7_IRQHandler [WEAK]
- EXPORT ADC1_2_IRQHandler [WEAK]
- EXPORT USB_HP_CAN1_TX_IRQHandler [WEAK]
- EXPORT USB_LP_CAN1_RX0_IRQHandler [WEAK]
- EXPORT CAN1_RX1_IRQHandler [WEAK]
- EXPORT CAN1_SCE_IRQHandler [WEAK]
- EXPORT EXTI9_5_IRQHandler [WEAK]
- EXPORT TIM1_BRK_IRQHandler [WEAK]
- EXPORT TIM1_UP_IRQHandler [WEAK]
- EXPORT TIM1_TRG_COM_IRQHandler [WEAK]
- EXPORT TIM1_CC_IRQHandler [WEAK]
- EXPORT TIM2_IRQHandler [WEAK]
- EXPORT TIM3_IRQHandler [WEAK]
- EXPORT I2C1_EV_IRQHandler [WEAK]
- EXPORT I2C1_ER_IRQHandler [WEAK]
- EXPORT SPI1_IRQHandler [WEAK]
- EXPORT USART1_IRQHandler [WEAK]
- EXPORT USART2_IRQHandler [WEAK]
- EXPORT EXTI15_10_IRQHandler [WEAK]
- EXPORT RTC_Alarm_IRQHandler [WEAK]
- EXPORT USBWakeUp_IRQHandler [WEAK]
-
-WWDG_IRQHandler
-PVD_IRQHandler
-TAMPER_IRQHandler
-RTC_IRQHandler
-FLASH_IRQHandler
-RCC_IRQHandler
-EXTI0_IRQHandler
-EXTI1_IRQHandler
-EXTI2_IRQHandler
-EXTI3_IRQHandler
-EXTI4_IRQHandler
-DMA1_Channel1_IRQHandler
-DMA1_Channel2_IRQHandler
-DMA1_Channel3_IRQHandler
-DMA1_Channel4_IRQHandler
-DMA1_Channel5_IRQHandler
-DMA1_Channel6_IRQHandler
-DMA1_Channel7_IRQHandler
-ADC1_2_IRQHandler
-USB_HP_CAN1_TX_IRQHandler
-USB_LP_CAN1_RX0_IRQHandler
-CAN1_RX1_IRQHandler
-CAN1_SCE_IRQHandler
-EXTI9_5_IRQHandler
-TIM1_BRK_IRQHandler
-TIM1_UP_IRQHandler
-TIM1_TRG_COM_IRQHandler
-TIM1_CC_IRQHandler
-TIM2_IRQHandler
-TIM3_IRQHandler
-I2C1_EV_IRQHandler
-I2C1_ER_IRQHandler
-SPI1_IRQHandler
-USART1_IRQHandler
-USART2_IRQHandler
-EXTI15_10_IRQHandler
-RTC_Alarm_IRQHandler
-USBWakeUp_IRQHandler
-
- B .
-
- ENDP
-
- ALIGN
-
-;*******************************************************************************
-; User Stack and Heap initialization
-;*******************************************************************************
- IF :DEF:__MICROLIB
-
- EXPORT __initial_sp
- EXPORT __heap_base
- EXPORT __heap_limit
-
- ELSE
-
- IMPORT __use_two_region_memory
- EXPORT __user_initial_stackheap
-
-__user_initial_stackheap
-
- LDR R0, = Heap_Mem
- LDR R1, =(Stack_Mem + Stack_Size)
- LDR R2, = (Heap_Mem + Heap_Size)
- LDR R3, = Stack_Mem
- BX LR
-
- ALIGN
-
- ENDIF
-
- END
-
-;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xb.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xb.s
deleted file mode 100644
index b9bc319..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xb.s
+++ /dev/null
@@ -1,324 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f103xb.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F103xB Devices vector table for MDK-ARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == Reset_Handler
-;* - Set the vector table entries with the exceptions ISR address
-;* - Configure the clock system
-;* - Branches to __main in the C library (which eventually
-;* calls main()).
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;
-;*******************************************************************************
-
-; Amount of memory (in bytes) allocated for Stack
-; Tailor this value to your application needs
-; Stack Configuration
-; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Stack_Size EQU 0x00000400
-
- AREA STACK, NOINIT, READWRITE, ALIGN=3
-Stack_Mem SPACE Stack_Size
-__initial_sp
-
-
-; Heap Configuration
-; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Heap_Size EQU 0x00000200
-
- AREA HEAP, NOINIT, READWRITE, ALIGN=3
-__heap_base
-Heap_Mem SPACE Heap_Size
-__heap_limit
-
- PRESERVE8
- THUMB
-
-
-; Vector Table Mapped to Address 0 at Reset
- AREA RESET, DATA, READONLY
- EXPORT __Vectors
- EXPORT __Vectors_End
- EXPORT __Vectors_Size
-
-__Vectors DCD __initial_sp ; Top of Stack
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_2_IRQHandler ; ADC1_2
- DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
- DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
- DCD CAN1_RX1_IRQHandler ; CAN1 RX1
- DCD CAN1_SCE_IRQHandler ; CAN1 SCE
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD TIM1_BRK_IRQHandler ; TIM1 Break
- DCD TIM1_UP_IRQHandler ; TIM1 Update
- DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
- DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C2 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
-__Vectors_End
-
-__Vectors_Size EQU __Vectors_End - __Vectors
-
- AREA |.text|, CODE, READONLY
-
-; Reset handler
-Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT __main
- IMPORT SystemInit
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BX R0
- ENDP
-
-; Dummy Exception Handlers (infinite loops which can be modified)
-
-NMI_Handler PROC
- EXPORT NMI_Handler [WEAK]
- B .
- ENDP
-HardFault_Handler\
- PROC
- EXPORT HardFault_Handler [WEAK]
- B .
- ENDP
-MemManage_Handler\
- PROC
- EXPORT MemManage_Handler [WEAK]
- B .
- ENDP
-BusFault_Handler\
- PROC
- EXPORT BusFault_Handler [WEAK]
- B .
- ENDP
-UsageFault_Handler\
- PROC
- EXPORT UsageFault_Handler [WEAK]
- B .
- ENDP
-SVC_Handler PROC
- EXPORT SVC_Handler [WEAK]
- B .
- ENDP
-DebugMon_Handler\
- PROC
- EXPORT DebugMon_Handler [WEAK]
- B .
- ENDP
-PendSV_Handler PROC
- EXPORT PendSV_Handler [WEAK]
- B .
- ENDP
-SysTick_Handler PROC
- EXPORT SysTick_Handler [WEAK]
- B .
- ENDP
-
-Default_Handler PROC
-
- EXPORT WWDG_IRQHandler [WEAK]
- EXPORT PVD_IRQHandler [WEAK]
- EXPORT TAMPER_IRQHandler [WEAK]
- EXPORT RTC_IRQHandler [WEAK]
- EXPORT FLASH_IRQHandler [WEAK]
- EXPORT RCC_IRQHandler [WEAK]
- EXPORT EXTI0_IRQHandler [WEAK]
- EXPORT EXTI1_IRQHandler [WEAK]
- EXPORT EXTI2_IRQHandler [WEAK]
- EXPORT EXTI3_IRQHandler [WEAK]
- EXPORT EXTI4_IRQHandler [WEAK]
- EXPORT DMA1_Channel1_IRQHandler [WEAK]
- EXPORT DMA1_Channel2_IRQHandler [WEAK]
- EXPORT DMA1_Channel3_IRQHandler [WEAK]
- EXPORT DMA1_Channel4_IRQHandler [WEAK]
- EXPORT DMA1_Channel5_IRQHandler [WEAK]
- EXPORT DMA1_Channel6_IRQHandler [WEAK]
- EXPORT DMA1_Channel7_IRQHandler [WEAK]
- EXPORT ADC1_2_IRQHandler [WEAK]
- EXPORT USB_HP_CAN1_TX_IRQHandler [WEAK]
- EXPORT USB_LP_CAN1_RX0_IRQHandler [WEAK]
- EXPORT CAN1_RX1_IRQHandler [WEAK]
- EXPORT CAN1_SCE_IRQHandler [WEAK]
- EXPORT EXTI9_5_IRQHandler [WEAK]
- EXPORT TIM1_BRK_IRQHandler [WEAK]
- EXPORT TIM1_UP_IRQHandler [WEAK]
- EXPORT TIM1_TRG_COM_IRQHandler [WEAK]
- EXPORT TIM1_CC_IRQHandler [WEAK]
- EXPORT TIM2_IRQHandler [WEAK]
- EXPORT TIM3_IRQHandler [WEAK]
- EXPORT TIM4_IRQHandler [WEAK]
- EXPORT I2C1_EV_IRQHandler [WEAK]
- EXPORT I2C1_ER_IRQHandler [WEAK]
- EXPORT I2C2_EV_IRQHandler [WEAK]
- EXPORT I2C2_ER_IRQHandler [WEAK]
- EXPORT SPI1_IRQHandler [WEAK]
- EXPORT SPI2_IRQHandler [WEAK]
- EXPORT USART1_IRQHandler [WEAK]
- EXPORT USART2_IRQHandler [WEAK]
- EXPORT USART3_IRQHandler [WEAK]
- EXPORT EXTI15_10_IRQHandler [WEAK]
- EXPORT RTC_Alarm_IRQHandler [WEAK]
- EXPORT USBWakeUp_IRQHandler [WEAK]
-
-WWDG_IRQHandler
-PVD_IRQHandler
-TAMPER_IRQHandler
-RTC_IRQHandler
-FLASH_IRQHandler
-RCC_IRQHandler
-EXTI0_IRQHandler
-EXTI1_IRQHandler
-EXTI2_IRQHandler
-EXTI3_IRQHandler
-EXTI4_IRQHandler
-DMA1_Channel1_IRQHandler
-DMA1_Channel2_IRQHandler
-DMA1_Channel3_IRQHandler
-DMA1_Channel4_IRQHandler
-DMA1_Channel5_IRQHandler
-DMA1_Channel6_IRQHandler
-DMA1_Channel7_IRQHandler
-ADC1_2_IRQHandler
-USB_HP_CAN1_TX_IRQHandler
-USB_LP_CAN1_RX0_IRQHandler
-CAN1_RX1_IRQHandler
-CAN1_SCE_IRQHandler
-EXTI9_5_IRQHandler
-TIM1_BRK_IRQHandler
-TIM1_UP_IRQHandler
-TIM1_TRG_COM_IRQHandler
-TIM1_CC_IRQHandler
-TIM2_IRQHandler
-TIM3_IRQHandler
-TIM4_IRQHandler
-I2C1_EV_IRQHandler
-I2C1_ER_IRQHandler
-I2C2_EV_IRQHandler
-I2C2_ER_IRQHandler
-SPI1_IRQHandler
-SPI2_IRQHandler
-USART1_IRQHandler
-USART2_IRQHandler
-USART3_IRQHandler
-EXTI15_10_IRQHandler
-RTC_Alarm_IRQHandler
-USBWakeUp_IRQHandler
-
- B .
-
- ENDP
-
- ALIGN
-
-;*******************************************************************************
-; User Stack and Heap initialization
-;*******************************************************************************
- IF :DEF:__MICROLIB
-
- EXPORT __initial_sp
- EXPORT __heap_base
- EXPORT __heap_limit
-
- ELSE
-
- IMPORT __use_two_region_memory
- EXPORT __user_initial_stackheap
-
-__user_initial_stackheap
-
- LDR R0, = Heap_Mem
- LDR R1, =(Stack_Mem + Stack_Size)
- LDR R2, = (Heap_Mem + Heap_Size)
- LDR R3, = Stack_Mem
- BX LR
-
- ALIGN
-
- ENDIF
-
- END
-
-;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xe.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xe.s
deleted file mode 100644
index f23f07c..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xe.s
+++ /dev/null
@@ -1,373 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f103xe.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F103xE Devices vector table for MDK-ARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == Reset_Handler
-;* - Set the vector table entries with the exceptions ISR address
-;* - Configure the clock system
-;* - Branches to __main in the C library (which eventually
-;* calls main()).
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;
-;*******************************************************************************
-
-; Amount of memory (in bytes) allocated for Stack
-; Tailor this value to your application needs
-; Stack Configuration
-; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Stack_Size EQU 0x00000400
-
- AREA STACK, NOINIT, READWRITE, ALIGN=3
-Stack_Mem SPACE Stack_Size
-__initial_sp
-
-; Heap Configuration
-; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Heap_Size EQU 0x00000200
-
- AREA HEAP, NOINIT, READWRITE, ALIGN=3
-__heap_base
-Heap_Mem SPACE Heap_Size
-__heap_limit
-
- PRESERVE8
- THUMB
-
-
-; Vector Table Mapped to Address 0 at Reset
- AREA RESET, DATA, READONLY
- EXPORT __Vectors
- EXPORT __Vectors_End
- EXPORT __Vectors_Size
-
-__Vectors DCD __initial_sp ; Top of Stack
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_2_IRQHandler ; ADC1 & ADC2
- DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
- DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
- DCD CAN1_RX1_IRQHandler ; CAN1 RX1
- DCD CAN1_SCE_IRQHandler ; CAN1 SCE
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD TIM1_BRK_IRQHandler ; TIM1 Break
- DCD TIM1_UP_IRQHandler ; TIM1 Update
- DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
- DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C2 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
- DCD TIM8_BRK_IRQHandler ; TIM8 Break
- DCD TIM8_UP_IRQHandler ; TIM8 Update
- DCD TIM8_TRG_COM_IRQHandler ; TIM8 Trigger and Commutation
- DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare
- DCD ADC3_IRQHandler ; ADC3
- DCD FSMC_IRQHandler ; FSMC
- DCD SDIO_IRQHandler ; SDIO
- DCD TIM5_IRQHandler ; TIM5
- DCD SPI3_IRQHandler ; SPI3
- DCD UART4_IRQHandler ; UART4
- DCD UART5_IRQHandler ; UART5
- DCD TIM6_IRQHandler ; TIM6
- DCD TIM7_IRQHandler ; TIM7
- DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
- DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
- DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
- DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
-__Vectors_End
-
-__Vectors_Size EQU __Vectors_End - __Vectors
-
- AREA |.text|, CODE, READONLY
-
-; Reset handler
-Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT __main
- IMPORT SystemInit
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BX R0
- ENDP
-
-; Dummy Exception Handlers (infinite loops which can be modified)
-
-NMI_Handler PROC
- EXPORT NMI_Handler [WEAK]
- B .
- ENDP
-HardFault_Handler\
- PROC
- EXPORT HardFault_Handler [WEAK]
- B .
- ENDP
-MemManage_Handler\
- PROC
- EXPORT MemManage_Handler [WEAK]
- B .
- ENDP
-BusFault_Handler\
- PROC
- EXPORT BusFault_Handler [WEAK]
- B .
- ENDP
-UsageFault_Handler\
- PROC
- EXPORT UsageFault_Handler [WEAK]
- B .
- ENDP
-SVC_Handler PROC
- EXPORT SVC_Handler [WEAK]
- B .
- ENDP
-DebugMon_Handler\
- PROC
- EXPORT DebugMon_Handler [WEAK]
- B .
- ENDP
-PendSV_Handler PROC
- EXPORT PendSV_Handler [WEAK]
- B .
- ENDP
-SysTick_Handler PROC
- EXPORT SysTick_Handler [WEAK]
- B .
- ENDP
-
-Default_Handler PROC
-
- EXPORT WWDG_IRQHandler [WEAK]
- EXPORT PVD_IRQHandler [WEAK]
- EXPORT TAMPER_IRQHandler [WEAK]
- EXPORT RTC_IRQHandler [WEAK]
- EXPORT FLASH_IRQHandler [WEAK]
- EXPORT RCC_IRQHandler [WEAK]
- EXPORT EXTI0_IRQHandler [WEAK]
- EXPORT EXTI1_IRQHandler [WEAK]
- EXPORT EXTI2_IRQHandler [WEAK]
- EXPORT EXTI3_IRQHandler [WEAK]
- EXPORT EXTI4_IRQHandler [WEAK]
- EXPORT DMA1_Channel1_IRQHandler [WEAK]
- EXPORT DMA1_Channel2_IRQHandler [WEAK]
- EXPORT DMA1_Channel3_IRQHandler [WEAK]
- EXPORT DMA1_Channel4_IRQHandler [WEAK]
- EXPORT DMA1_Channel5_IRQHandler [WEAK]
- EXPORT DMA1_Channel6_IRQHandler [WEAK]
- EXPORT DMA1_Channel7_IRQHandler [WEAK]
- EXPORT ADC1_2_IRQHandler [WEAK]
- EXPORT USB_HP_CAN1_TX_IRQHandler [WEAK]
- EXPORT USB_LP_CAN1_RX0_IRQHandler [WEAK]
- EXPORT CAN1_RX1_IRQHandler [WEAK]
- EXPORT CAN1_SCE_IRQHandler [WEAK]
- EXPORT EXTI9_5_IRQHandler [WEAK]
- EXPORT TIM1_BRK_IRQHandler [WEAK]
- EXPORT TIM1_UP_IRQHandler [WEAK]
- EXPORT TIM1_TRG_COM_IRQHandler [WEAK]
- EXPORT TIM1_CC_IRQHandler [WEAK]
- EXPORT TIM2_IRQHandler [WEAK]
- EXPORT TIM3_IRQHandler [WEAK]
- EXPORT TIM4_IRQHandler [WEAK]
- EXPORT I2C1_EV_IRQHandler [WEAK]
- EXPORT I2C1_ER_IRQHandler [WEAK]
- EXPORT I2C2_EV_IRQHandler [WEAK]
- EXPORT I2C2_ER_IRQHandler [WEAK]
- EXPORT SPI1_IRQHandler [WEAK]
- EXPORT SPI2_IRQHandler [WEAK]
- EXPORT USART1_IRQHandler [WEAK]
- EXPORT USART2_IRQHandler [WEAK]
- EXPORT USART3_IRQHandler [WEAK]
- EXPORT EXTI15_10_IRQHandler [WEAK]
- EXPORT RTC_Alarm_IRQHandler [WEAK]
- EXPORT USBWakeUp_IRQHandler [WEAK]
- EXPORT TIM8_BRK_IRQHandler [WEAK]
- EXPORT TIM8_UP_IRQHandler [WEAK]
- EXPORT TIM8_TRG_COM_IRQHandler [WEAK]
- EXPORT TIM8_CC_IRQHandler [WEAK]
- EXPORT ADC3_IRQHandler [WEAK]
- EXPORT FSMC_IRQHandler [WEAK]
- EXPORT SDIO_IRQHandler [WEAK]
- EXPORT TIM5_IRQHandler [WEAK]
- EXPORT SPI3_IRQHandler [WEAK]
- EXPORT UART4_IRQHandler [WEAK]
- EXPORT UART5_IRQHandler [WEAK]
- EXPORT TIM6_IRQHandler [WEAK]
- EXPORT TIM7_IRQHandler [WEAK]
- EXPORT DMA2_Channel1_IRQHandler [WEAK]
- EXPORT DMA2_Channel2_IRQHandler [WEAK]
- EXPORT DMA2_Channel3_IRQHandler [WEAK]
- EXPORT DMA2_Channel4_5_IRQHandler [WEAK]
-
-WWDG_IRQHandler
-PVD_IRQHandler
-TAMPER_IRQHandler
-RTC_IRQHandler
-FLASH_IRQHandler
-RCC_IRQHandler
-EXTI0_IRQHandler
-EXTI1_IRQHandler
-EXTI2_IRQHandler
-EXTI3_IRQHandler
-EXTI4_IRQHandler
-DMA1_Channel1_IRQHandler
-DMA1_Channel2_IRQHandler
-DMA1_Channel3_IRQHandler
-DMA1_Channel4_IRQHandler
-DMA1_Channel5_IRQHandler
-DMA1_Channel6_IRQHandler
-DMA1_Channel7_IRQHandler
-ADC1_2_IRQHandler
-USB_HP_CAN1_TX_IRQHandler
-USB_LP_CAN1_RX0_IRQHandler
-CAN1_RX1_IRQHandler
-CAN1_SCE_IRQHandler
-EXTI9_5_IRQHandler
-TIM1_BRK_IRQHandler
-TIM1_UP_IRQHandler
-TIM1_TRG_COM_IRQHandler
-TIM1_CC_IRQHandler
-TIM2_IRQHandler
-TIM3_IRQHandler
-TIM4_IRQHandler
-I2C1_EV_IRQHandler
-I2C1_ER_IRQHandler
-I2C2_EV_IRQHandler
-I2C2_ER_IRQHandler
-SPI1_IRQHandler
-SPI2_IRQHandler
-USART1_IRQHandler
-USART2_IRQHandler
-USART3_IRQHandler
-EXTI15_10_IRQHandler
-RTC_Alarm_IRQHandler
-USBWakeUp_IRQHandler
-TIM8_BRK_IRQHandler
-TIM8_UP_IRQHandler
-TIM8_TRG_COM_IRQHandler
-TIM8_CC_IRQHandler
-ADC3_IRQHandler
-FSMC_IRQHandler
-SDIO_IRQHandler
-TIM5_IRQHandler
-SPI3_IRQHandler
-UART4_IRQHandler
-UART5_IRQHandler
-TIM6_IRQHandler
-TIM7_IRQHandler
-DMA2_Channel1_IRQHandler
-DMA2_Channel2_IRQHandler
-DMA2_Channel3_IRQHandler
-DMA2_Channel4_5_IRQHandler
- B .
-
- ENDP
-
- ALIGN
-
-;*******************************************************************************
-; User Stack and Heap initialization
-;*******************************************************************************
- IF :DEF:__MICROLIB
-
- EXPORT __initial_sp
- EXPORT __heap_base
- EXPORT __heap_limit
-
- ELSE
-
- IMPORT __use_two_region_memory
- EXPORT __user_initial_stackheap
-
-__user_initial_stackheap
-
- LDR R0, = Heap_Mem
- LDR R1, =(Stack_Mem + Stack_Size)
- LDR R2, = (Heap_Mem + Heap_Size)
- LDR R3, = Stack_Mem
- BX LR
-
- ALIGN
-
- ENDIF
-
- END
-
-;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xg.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xg.s
deleted file mode 100644
index 60296a1..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xg.s
+++ /dev/null
@@ -1,373 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f103xg.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F103xG Devices vector table for MDK-ARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == Reset_Handler
-;* - Set the vector table entries with the exceptions ISR address
-;* - Configure the clock system
-;* - Branches to __main in the C library (which eventually
-;* calls main()).
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;
-;*******************************************************************************
-
-; Amount of memory (in bytes) allocated for Stack
-; Tailor this value to your application needs
-; Stack Configuration
-; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Stack_Size EQU 0x00000400
-
- AREA STACK, NOINIT, READWRITE, ALIGN=3
-Stack_Mem SPACE Stack_Size
-__initial_sp
-
-; Heap Configuration
-; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Heap_Size EQU 0x00000200
-
- AREA HEAP, NOINIT, READWRITE, ALIGN=3
-__heap_base
-Heap_Mem SPACE Heap_Size
-__heap_limit
-
- PRESERVE8
- THUMB
-
-
-; Vector Table Mapped to Address 0 at Reset
- AREA RESET, DATA, READONLY
- EXPORT __Vectors
- EXPORT __Vectors_End
- EXPORT __Vectors_Size
-
-__Vectors DCD __initial_sp ; Top of Stack
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_2_IRQHandler ; ADC1 & ADC2
- DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
- DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
- DCD CAN1_RX1_IRQHandler ; CAN1 RX1
- DCD CAN1_SCE_IRQHandler ; CAN1 SCE
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD TIM1_BRK_TIM9_IRQHandler ; TIM1 Break and TIM9
- DCD TIM1_UP_TIM10_IRQHandler ; TIM1 Update and TIM10
- DCD TIM1_TRG_COM_TIM11_IRQHandler ; TIM1 Trigger and Commutation and TIM11
- DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C2 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
- DCD TIM8_BRK_TIM12_IRQHandler ; TIM8 Break and TIM12
- DCD TIM8_UP_TIM13_IRQHandler ; TIM8 Update and TIM13
- DCD TIM8_TRG_COM_TIM14_IRQHandler ; TIM8 Trigger and Commutation and TIM14
- DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare
- DCD ADC3_IRQHandler ; ADC3
- DCD FSMC_IRQHandler ; FSMC
- DCD SDIO_IRQHandler ; SDIO
- DCD TIM5_IRQHandler ; TIM5
- DCD SPI3_IRQHandler ; SPI3
- DCD UART4_IRQHandler ; UART4
- DCD UART5_IRQHandler ; UART5
- DCD TIM6_IRQHandler ; TIM6
- DCD TIM7_IRQHandler ; TIM7
- DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
- DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
- DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
- DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
-__Vectors_End
-
-__Vectors_Size EQU __Vectors_End - __Vectors
-
- AREA |.text|, CODE, READONLY
-
-; Reset handler
-Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT __main
- IMPORT SystemInit
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BX R0
- ENDP
-
-; Dummy Exception Handlers (infinite loops which can be modified)
-
-NMI_Handler PROC
- EXPORT NMI_Handler [WEAK]
- B .
- ENDP
-HardFault_Handler\
- PROC
- EXPORT HardFault_Handler [WEAK]
- B .
- ENDP
-MemManage_Handler\
- PROC
- EXPORT MemManage_Handler [WEAK]
- B .
- ENDP
-BusFault_Handler\
- PROC
- EXPORT BusFault_Handler [WEAK]
- B .
- ENDP
-UsageFault_Handler\
- PROC
- EXPORT UsageFault_Handler [WEAK]
- B .
- ENDP
-SVC_Handler PROC
- EXPORT SVC_Handler [WEAK]
- B .
- ENDP
-DebugMon_Handler\
- PROC
- EXPORT DebugMon_Handler [WEAK]
- B .
- ENDP
-PendSV_Handler PROC
- EXPORT PendSV_Handler [WEAK]
- B .
- ENDP
-SysTick_Handler PROC
- EXPORT SysTick_Handler [WEAK]
- B .
- ENDP
-
-Default_Handler PROC
-
- EXPORT WWDG_IRQHandler [WEAK]
- EXPORT PVD_IRQHandler [WEAK]
- EXPORT TAMPER_IRQHandler [WEAK]
- EXPORT RTC_IRQHandler [WEAK]
- EXPORT FLASH_IRQHandler [WEAK]
- EXPORT RCC_IRQHandler [WEAK]
- EXPORT EXTI0_IRQHandler [WEAK]
- EXPORT EXTI1_IRQHandler [WEAK]
- EXPORT EXTI2_IRQHandler [WEAK]
- EXPORT EXTI3_IRQHandler [WEAK]
- EXPORT EXTI4_IRQHandler [WEAK]
- EXPORT DMA1_Channel1_IRQHandler [WEAK]
- EXPORT DMA1_Channel2_IRQHandler [WEAK]
- EXPORT DMA1_Channel3_IRQHandler [WEAK]
- EXPORT DMA1_Channel4_IRQHandler [WEAK]
- EXPORT DMA1_Channel5_IRQHandler [WEAK]
- EXPORT DMA1_Channel6_IRQHandler [WEAK]
- EXPORT DMA1_Channel7_IRQHandler [WEAK]
- EXPORT ADC1_2_IRQHandler [WEAK]
- EXPORT USB_HP_CAN1_TX_IRQHandler [WEAK]
- EXPORT USB_LP_CAN1_RX0_IRQHandler [WEAK]
- EXPORT CAN1_RX1_IRQHandler [WEAK]
- EXPORT CAN1_SCE_IRQHandler [WEAK]
- EXPORT EXTI9_5_IRQHandler [WEAK]
- EXPORT TIM1_BRK_TIM9_IRQHandler [WEAK]
- EXPORT TIM1_UP_TIM10_IRQHandler [WEAK]
- EXPORT TIM1_TRG_COM_TIM11_IRQHandler [WEAK]
- EXPORT TIM1_CC_IRQHandler [WEAK]
- EXPORT TIM2_IRQHandler [WEAK]
- EXPORT TIM3_IRQHandler [WEAK]
- EXPORT TIM4_IRQHandler [WEAK]
- EXPORT I2C1_EV_IRQHandler [WEAK]
- EXPORT I2C1_ER_IRQHandler [WEAK]
- EXPORT I2C2_EV_IRQHandler [WEAK]
- EXPORT I2C2_ER_IRQHandler [WEAK]
- EXPORT SPI1_IRQHandler [WEAK]
- EXPORT SPI2_IRQHandler [WEAK]
- EXPORT USART1_IRQHandler [WEAK]
- EXPORT USART2_IRQHandler [WEAK]
- EXPORT USART3_IRQHandler [WEAK]
- EXPORT EXTI15_10_IRQHandler [WEAK]
- EXPORT RTC_Alarm_IRQHandler [WEAK]
- EXPORT USBWakeUp_IRQHandler [WEAK]
- EXPORT TIM8_BRK_TIM12_IRQHandler [WEAK]
- EXPORT TIM8_UP_TIM13_IRQHandler [WEAK]
- EXPORT TIM8_TRG_COM_TIM14_IRQHandler [WEAK]
- EXPORT TIM8_CC_IRQHandler [WEAK]
- EXPORT ADC3_IRQHandler [WEAK]
- EXPORT FSMC_IRQHandler [WEAK]
- EXPORT SDIO_IRQHandler [WEAK]
- EXPORT TIM5_IRQHandler [WEAK]
- EXPORT SPI3_IRQHandler [WEAK]
- EXPORT UART4_IRQHandler [WEAK]
- EXPORT UART5_IRQHandler [WEAK]
- EXPORT TIM6_IRQHandler [WEAK]
- EXPORT TIM7_IRQHandler [WEAK]
- EXPORT DMA2_Channel1_IRQHandler [WEAK]
- EXPORT DMA2_Channel2_IRQHandler [WEAK]
- EXPORT DMA2_Channel3_IRQHandler [WEAK]
- EXPORT DMA2_Channel4_5_IRQHandler [WEAK]
-
-WWDG_IRQHandler
-PVD_IRQHandler
-TAMPER_IRQHandler
-RTC_IRQHandler
-FLASH_IRQHandler
-RCC_IRQHandler
-EXTI0_IRQHandler
-EXTI1_IRQHandler
-EXTI2_IRQHandler
-EXTI3_IRQHandler
-EXTI4_IRQHandler
-DMA1_Channel1_IRQHandler
-DMA1_Channel2_IRQHandler
-DMA1_Channel3_IRQHandler
-DMA1_Channel4_IRQHandler
-DMA1_Channel5_IRQHandler
-DMA1_Channel6_IRQHandler
-DMA1_Channel7_IRQHandler
-ADC1_2_IRQHandler
-USB_HP_CAN1_TX_IRQHandler
-USB_LP_CAN1_RX0_IRQHandler
-CAN1_RX1_IRQHandler
-CAN1_SCE_IRQHandler
-EXTI9_5_IRQHandler
-TIM1_BRK_TIM9_IRQHandler
-TIM1_UP_TIM10_IRQHandler
-TIM1_TRG_COM_TIM11_IRQHandler
-TIM1_CC_IRQHandler
-TIM2_IRQHandler
-TIM3_IRQHandler
-TIM4_IRQHandler
-I2C1_EV_IRQHandler
-I2C1_ER_IRQHandler
-I2C2_EV_IRQHandler
-I2C2_ER_IRQHandler
-SPI1_IRQHandler
-SPI2_IRQHandler
-USART1_IRQHandler
-USART2_IRQHandler
-USART3_IRQHandler
-EXTI15_10_IRQHandler
-RTC_Alarm_IRQHandler
-USBWakeUp_IRQHandler
-TIM8_BRK_TIM12_IRQHandler
-TIM8_UP_TIM13_IRQHandler
-TIM8_TRG_COM_TIM14_IRQHandler
-TIM8_CC_IRQHandler
-ADC3_IRQHandler
-FSMC_IRQHandler
-SDIO_IRQHandler
-TIM5_IRQHandler
-SPI3_IRQHandler
-UART4_IRQHandler
-UART5_IRQHandler
-TIM6_IRQHandler
-TIM7_IRQHandler
-DMA2_Channel1_IRQHandler
-DMA2_Channel2_IRQHandler
-DMA2_Channel3_IRQHandler
-DMA2_Channel4_5_IRQHandler
- B .
-
- ENDP
-
- ALIGN
-
-;*******************************************************************************
-; User Stack and Heap initialization
-;*******************************************************************************
- IF :DEF:__MICROLIB
-
- EXPORT __initial_sp
- EXPORT __heap_base
- EXPORT __heap_limit
-
- ELSE
-
- IMPORT __use_two_region_memory
- EXPORT __user_initial_stackheap
-
-__user_initial_stackheap
-
- LDR R0, = Heap_Mem
- LDR R1, =(Stack_Mem + Stack_Size)
- LDR R2, = (Heap_Mem + Heap_Size)
- LDR R3, = Stack_Mem
- BX LR
-
- ALIGN
-
- ENDIF
-
- END
-
-;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f105xc.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f105xc.s
deleted file mode 100644
index d6e177d..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f105xc.s
+++ /dev/null
@@ -1,381 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f105xc.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F105xC Devices vector table for MDK-ARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == Reset_Handler
-;* - Set the vector table entries with the exceptions ISR address
-;* - Configure the clock system
-;* - Branches to __main in the C library (which eventually
-;* calls main()).
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;
-;*******************************************************************************
-
-; Amount of memory (in bytes) allocated for Stack
-; Tailor this value to your application needs
-; Stack Configuration
-; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Stack_Size EQU 0x00000400
-
- AREA STACK, NOINIT, READWRITE, ALIGN=3
-Stack_Mem SPACE Stack_Size
-__initial_sp
-
-
-; Heap Configuration
-; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Heap_Size EQU 0x00000200
-
- AREA HEAP, NOINIT, READWRITE, ALIGN=3
-__heap_base
-Heap_Mem SPACE Heap_Size
-__heap_limit
-
- PRESERVE8
- THUMB
-
-
-; Vector Table Mapped to Address 0 at Reset
- AREA RESET, DATA, READONLY
- EXPORT __Vectors
- EXPORT __Vectors_End
- EXPORT __Vectors_Size
-
-__Vectors DCD __initial_sp ; Top of Stack
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_2_IRQHandler ; ADC1 and ADC2
- DCD CAN1_TX_IRQHandler ; CAN1 TX
- DCD CAN1_RX0_IRQHandler ; CAN1 RX0
- DCD CAN1_RX1_IRQHandler ; CAN1 RX1
- DCD CAN1_SCE_IRQHandler ; CAN1 SCE
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD TIM1_BRK_IRQHandler ; TIM1 Break
- DCD TIM1_UP_IRQHandler ; TIM1 Update
- DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
- DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C1 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC alarm through EXTI line
- DCD OTG_FS_WKUP_IRQHandler ; USB OTG FS Wakeup through EXTI line
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD TIM5_IRQHandler ; TIM5
- DCD SPI3_IRQHandler ; SPI3
- DCD UART4_IRQHandler ; UART4
- DCD UART5_IRQHandler ; UART5
- DCD TIM6_IRQHandler ; TIM6
- DCD TIM7_IRQHandler ; TIM7
- DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
- DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
- DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
- DCD DMA2_Channel4_IRQHandler ; DMA2 Channel4
- DCD DMA2_Channel5_IRQHandler ; DMA2 Channel5
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD CAN2_TX_IRQHandler ; CAN2 TX
- DCD CAN2_RX0_IRQHandler ; CAN2 RX0
- DCD CAN2_RX1_IRQHandler ; CAN2 RX1
- DCD CAN2_SCE_IRQHandler ; CAN2 SCE
- DCD OTG_FS_IRQHandler ; USB OTG FS
-__Vectors_End
-
-__Vectors_Size EQU __Vectors_End - __Vectors
-
- AREA |.text|, CODE, READONLY
-
-; Reset handler
-Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT SystemInit
- IMPORT __main
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BX R0
- ENDP
-
-; Dummy Exception Handlers (infinite loops which can be modified)
-
-NMI_Handler PROC
- EXPORT NMI_Handler [WEAK]
- B .
- ENDP
-HardFault_Handler\
- PROC
- EXPORT HardFault_Handler [WEAK]
- B .
- ENDP
-MemManage_Handler\
- PROC
- EXPORT MemManage_Handler [WEAK]
- B .
- ENDP
-BusFault_Handler\
- PROC
- EXPORT BusFault_Handler [WEAK]
- B .
- ENDP
-UsageFault_Handler\
- PROC
- EXPORT UsageFault_Handler [WEAK]
- B .
- ENDP
-SVC_Handler PROC
- EXPORT SVC_Handler [WEAK]
- B .
- ENDP
-DebugMon_Handler\
- PROC
- EXPORT DebugMon_Handler [WEAK]
- B .
- ENDP
-PendSV_Handler PROC
- EXPORT PendSV_Handler [WEAK]
- B .
- ENDP
-SysTick_Handler PROC
- EXPORT SysTick_Handler [WEAK]
- B .
- ENDP
-
-Default_Handler PROC
-
- EXPORT WWDG_IRQHandler [WEAK]
- EXPORT PVD_IRQHandler [WEAK]
- EXPORT TAMPER_IRQHandler [WEAK]
- EXPORT RTC_IRQHandler [WEAK]
- EXPORT FLASH_IRQHandler [WEAK]
- EXPORT RCC_IRQHandler [WEAK]
- EXPORT EXTI0_IRQHandler [WEAK]
- EXPORT EXTI1_IRQHandler [WEAK]
- EXPORT EXTI2_IRQHandler [WEAK]
- EXPORT EXTI3_IRQHandler [WEAK]
- EXPORT EXTI4_IRQHandler [WEAK]
- EXPORT DMA1_Channel1_IRQHandler [WEAK]
- EXPORT DMA1_Channel2_IRQHandler [WEAK]
- EXPORT DMA1_Channel3_IRQHandler [WEAK]
- EXPORT DMA1_Channel4_IRQHandler [WEAK]
- EXPORT DMA1_Channel5_IRQHandler [WEAK]
- EXPORT DMA1_Channel6_IRQHandler [WEAK]
- EXPORT DMA1_Channel7_IRQHandler [WEAK]
- EXPORT ADC1_2_IRQHandler [WEAK]
- EXPORT CAN1_TX_IRQHandler [WEAK]
- EXPORT CAN1_RX0_IRQHandler [WEAK]
- EXPORT CAN1_RX1_IRQHandler [WEAK]
- EXPORT CAN1_SCE_IRQHandler [WEAK]
- EXPORT EXTI9_5_IRQHandler [WEAK]
- EXPORT TIM1_BRK_IRQHandler [WEAK]
- EXPORT TIM1_UP_IRQHandler [WEAK]
- EXPORT TIM1_TRG_COM_IRQHandler [WEAK]
- EXPORT TIM1_CC_IRQHandler [WEAK]
- EXPORT TIM2_IRQHandler [WEAK]
- EXPORT TIM3_IRQHandler [WEAK]
- EXPORT TIM4_IRQHandler [WEAK]
- EXPORT I2C1_EV_IRQHandler [WEAK]
- EXPORT I2C1_ER_IRQHandler [WEAK]
- EXPORT I2C2_EV_IRQHandler [WEAK]
- EXPORT I2C2_ER_IRQHandler [WEAK]
- EXPORT SPI1_IRQHandler [WEAK]
- EXPORT SPI2_IRQHandler [WEAK]
- EXPORT USART1_IRQHandler [WEAK]
- EXPORT USART2_IRQHandler [WEAK]
- EXPORT USART3_IRQHandler [WEAK]
- EXPORT EXTI15_10_IRQHandler [WEAK]
- EXPORT RTC_Alarm_IRQHandler [WEAK]
- EXPORT OTG_FS_WKUP_IRQHandler [WEAK]
- EXPORT TIM5_IRQHandler [WEAK]
- EXPORT SPI3_IRQHandler [WEAK]
- EXPORT UART4_IRQHandler [WEAK]
- EXPORT UART5_IRQHandler [WEAK]
- EXPORT TIM6_IRQHandler [WEAK]
- EXPORT TIM7_IRQHandler [WEAK]
- EXPORT DMA2_Channel1_IRQHandler [WEAK]
- EXPORT DMA2_Channel2_IRQHandler [WEAK]
- EXPORT DMA2_Channel3_IRQHandler [WEAK]
- EXPORT DMA2_Channel4_IRQHandler [WEAK]
- EXPORT DMA2_Channel5_IRQHandler [WEAK]
- EXPORT CAN2_TX_IRQHandler [WEAK]
- EXPORT CAN2_RX0_IRQHandler [WEAK]
- EXPORT CAN2_RX1_IRQHandler [WEAK]
- EXPORT CAN2_SCE_IRQHandler [WEAK]
- EXPORT OTG_FS_IRQHandler [WEAK]
-
-WWDG_IRQHandler
-PVD_IRQHandler
-TAMPER_IRQHandler
-RTC_IRQHandler
-FLASH_IRQHandler
-RCC_IRQHandler
-EXTI0_IRQHandler
-EXTI1_IRQHandler
-EXTI2_IRQHandler
-EXTI3_IRQHandler
-EXTI4_IRQHandler
-DMA1_Channel1_IRQHandler
-DMA1_Channel2_IRQHandler
-DMA1_Channel3_IRQHandler
-DMA1_Channel4_IRQHandler
-DMA1_Channel5_IRQHandler
-DMA1_Channel6_IRQHandler
-DMA1_Channel7_IRQHandler
-ADC1_2_IRQHandler
-CAN1_TX_IRQHandler
-CAN1_RX0_IRQHandler
-CAN1_RX1_IRQHandler
-CAN1_SCE_IRQHandler
-EXTI9_5_IRQHandler
-TIM1_BRK_IRQHandler
-TIM1_UP_IRQHandler
-TIM1_TRG_COM_IRQHandler
-TIM1_CC_IRQHandler
-TIM2_IRQHandler
-TIM3_IRQHandler
-TIM4_IRQHandler
-I2C1_EV_IRQHandler
-I2C1_ER_IRQHandler
-I2C2_EV_IRQHandler
-I2C2_ER_IRQHandler
-SPI1_IRQHandler
-SPI2_IRQHandler
-USART1_IRQHandler
-USART2_IRQHandler
-USART3_IRQHandler
-EXTI15_10_IRQHandler
-RTC_Alarm_IRQHandler
-OTG_FS_WKUP_IRQHandler
-TIM5_IRQHandler
-SPI3_IRQHandler
-UART4_IRQHandler
-UART5_IRQHandler
-TIM6_IRQHandler
-TIM7_IRQHandler
-DMA2_Channel1_IRQHandler
-DMA2_Channel2_IRQHandler
-DMA2_Channel3_IRQHandler
-DMA2_Channel4_IRQHandler
-DMA2_Channel5_IRQHandler
-CAN2_TX_IRQHandler
-CAN2_RX0_IRQHandler
-CAN2_RX1_IRQHandler
-CAN2_SCE_IRQHandler
-OTG_FS_IRQHandler
-
- B .
-
- ENDP
-
- ALIGN
-
-;*******************************************************************************
-; User Stack and Heap initialization
-;*******************************************************************************
- IF :DEF:__MICROLIB
-
- EXPORT __initial_sp
- EXPORT __heap_base
- EXPORT __heap_limit
-
- ELSE
-
- IMPORT __use_two_region_memory
- EXPORT __user_initial_stackheap
-
-__user_initial_stackheap
-
- LDR R0, = Heap_Mem
- LDR R1, =(Stack_Mem + Stack_Size)
- LDR R2, = (Heap_Mem + Heap_Size)
- LDR R3, = Stack_Mem
- BX LR
-
- ALIGN
-
- ENDIF
-
- END
-
-;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f107xc.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f107xc.s
deleted file mode 100644
index 6a6edbd..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f107xc.s
+++ /dev/null
@@ -1,385 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f107xc.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F107xC Devices vector table for MDK-ARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == Reset_Handler
-;* - Set the vector table entries with the exceptions ISR address
-;* - Configure the clock system
-;* - Branches to __main in the C library (which eventually
-;* calls main()).
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;
-;*******************************************************************************
-
-; Amount of memory (in bytes) allocated for Stack
-; Tailor this value to your application needs
-; Stack Configuration
-; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Stack_Size EQU 0x00000400
-
- AREA STACK, NOINIT, READWRITE, ALIGN=3
-Stack_Mem SPACE Stack_Size
-__initial_sp
-
-
-; Heap Configuration
-; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Heap_Size EQU 0x00000200
-
- AREA HEAP, NOINIT, READWRITE, ALIGN=3
-__heap_base
-Heap_Mem SPACE Heap_Size
-__heap_limit
-
- PRESERVE8
- THUMB
-
-
-; Vector Table Mapped to Address 0 at Reset
- AREA RESET, DATA, READONLY
- EXPORT __Vectors
- EXPORT __Vectors_End
- EXPORT __Vectors_Size
-
-__Vectors DCD __initial_sp ; Top of Stack
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_2_IRQHandler ; ADC1 and ADC2
- DCD CAN1_TX_IRQHandler ; CAN1 TX
- DCD CAN1_RX0_IRQHandler ; CAN1 RX0
- DCD CAN1_RX1_IRQHandler ; CAN1 RX1
- DCD CAN1_SCE_IRQHandler ; CAN1 SCE
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD TIM1_BRK_IRQHandler ; TIM1 Break
- DCD TIM1_UP_IRQHandler ; TIM1 Update
- DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
- DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C1 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC alarm through EXTI line
- DCD OTG_FS_WKUP_IRQHandler ; USB OTG FS Wakeup through EXTI line
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD TIM5_IRQHandler ; TIM5
- DCD SPI3_IRQHandler ; SPI3
- DCD UART4_IRQHandler ; UART4
- DCD UART5_IRQHandler ; UART5
- DCD TIM6_IRQHandler ; TIM6
- DCD TIM7_IRQHandler ; TIM7
- DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
- DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
- DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
- DCD DMA2_Channel4_IRQHandler ; DMA2 Channel4
- DCD DMA2_Channel5_IRQHandler ; DMA2 Channel5
- DCD ETH_IRQHandler ; Ethernet
- DCD ETH_WKUP_IRQHandler ; Ethernet Wakeup through EXTI line
- DCD CAN2_TX_IRQHandler ; CAN2 TX
- DCD CAN2_RX0_IRQHandler ; CAN2 RX0
- DCD CAN2_RX1_IRQHandler ; CAN2 RX1
- DCD CAN2_SCE_IRQHandler ; CAN2 SCE
- DCD OTG_FS_IRQHandler ; USB OTG FS
-__Vectors_End
-
-__Vectors_Size EQU __Vectors_End - __Vectors
-
- AREA |.text|, CODE, READONLY
-
-; Reset handler
-Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT SystemInit
- IMPORT __main
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BX R0
- ENDP
-
-; Dummy Exception Handlers (infinite loops which can be modified)
-
-NMI_Handler PROC
- EXPORT NMI_Handler [WEAK]
- B .
- ENDP
-HardFault_Handler\
- PROC
- EXPORT HardFault_Handler [WEAK]
- B .
- ENDP
-MemManage_Handler\
- PROC
- EXPORT MemManage_Handler [WEAK]
- B .
- ENDP
-BusFault_Handler\
- PROC
- EXPORT BusFault_Handler [WEAK]
- B .
- ENDP
-UsageFault_Handler\
- PROC
- EXPORT UsageFault_Handler [WEAK]
- B .
- ENDP
-SVC_Handler PROC
- EXPORT SVC_Handler [WEAK]
- B .
- ENDP
-DebugMon_Handler\
- PROC
- EXPORT DebugMon_Handler [WEAK]
- B .
- ENDP
-PendSV_Handler PROC
- EXPORT PendSV_Handler [WEAK]
- B .
- ENDP
-SysTick_Handler PROC
- EXPORT SysTick_Handler [WEAK]
- B .
- ENDP
-
-Default_Handler PROC
-
- EXPORT WWDG_IRQHandler [WEAK]
- EXPORT PVD_IRQHandler [WEAK]
- EXPORT TAMPER_IRQHandler [WEAK]
- EXPORT RTC_IRQHandler [WEAK]
- EXPORT FLASH_IRQHandler [WEAK]
- EXPORT RCC_IRQHandler [WEAK]
- EXPORT EXTI0_IRQHandler [WEAK]
- EXPORT EXTI1_IRQHandler [WEAK]
- EXPORT EXTI2_IRQHandler [WEAK]
- EXPORT EXTI3_IRQHandler [WEAK]
- EXPORT EXTI4_IRQHandler [WEAK]
- EXPORT DMA1_Channel1_IRQHandler [WEAK]
- EXPORT DMA1_Channel2_IRQHandler [WEAK]
- EXPORT DMA1_Channel3_IRQHandler [WEAK]
- EXPORT DMA1_Channel4_IRQHandler [WEAK]
- EXPORT DMA1_Channel5_IRQHandler [WEAK]
- EXPORT DMA1_Channel6_IRQHandler [WEAK]
- EXPORT DMA1_Channel7_IRQHandler [WEAK]
- EXPORT ADC1_2_IRQHandler [WEAK]
- EXPORT CAN1_TX_IRQHandler [WEAK]
- EXPORT CAN1_RX0_IRQHandler [WEAK]
- EXPORT CAN1_RX1_IRQHandler [WEAK]
- EXPORT CAN1_SCE_IRQHandler [WEAK]
- EXPORT EXTI9_5_IRQHandler [WEAK]
- EXPORT TIM1_BRK_IRQHandler [WEAK]
- EXPORT TIM1_UP_IRQHandler [WEAK]
- EXPORT TIM1_TRG_COM_IRQHandler [WEAK]
- EXPORT TIM1_CC_IRQHandler [WEAK]
- EXPORT TIM2_IRQHandler [WEAK]
- EXPORT TIM3_IRQHandler [WEAK]
- EXPORT TIM4_IRQHandler [WEAK]
- EXPORT I2C1_EV_IRQHandler [WEAK]
- EXPORT I2C1_ER_IRQHandler [WEAK]
- EXPORT I2C2_EV_IRQHandler [WEAK]
- EXPORT I2C2_ER_IRQHandler [WEAK]
- EXPORT SPI1_IRQHandler [WEAK]
- EXPORT SPI2_IRQHandler [WEAK]
- EXPORT USART1_IRQHandler [WEAK]
- EXPORT USART2_IRQHandler [WEAK]
- EXPORT USART3_IRQHandler [WEAK]
- EXPORT EXTI15_10_IRQHandler [WEAK]
- EXPORT RTC_Alarm_IRQHandler [WEAK]
- EXPORT OTG_FS_WKUP_IRQHandler [WEAK]
- EXPORT TIM5_IRQHandler [WEAK]
- EXPORT SPI3_IRQHandler [WEAK]
- EXPORT UART4_IRQHandler [WEAK]
- EXPORT UART5_IRQHandler [WEAK]
- EXPORT TIM6_IRQHandler [WEAK]
- EXPORT TIM7_IRQHandler [WEAK]
- EXPORT DMA2_Channel1_IRQHandler [WEAK]
- EXPORT DMA2_Channel2_IRQHandler [WEAK]
- EXPORT DMA2_Channel3_IRQHandler [WEAK]
- EXPORT DMA2_Channel4_IRQHandler [WEAK]
- EXPORT DMA2_Channel5_IRQHandler [WEAK]
- EXPORT ETH_IRQHandler [WEAK]
- EXPORT ETH_WKUP_IRQHandler [WEAK]
- EXPORT CAN2_TX_IRQHandler [WEAK]
- EXPORT CAN2_RX0_IRQHandler [WEAK]
- EXPORT CAN2_RX1_IRQHandler [WEAK]
- EXPORT CAN2_SCE_IRQHandler [WEAK]
- EXPORT OTG_FS_IRQHandler [WEAK]
-
-WWDG_IRQHandler
-PVD_IRQHandler
-TAMPER_IRQHandler
-RTC_IRQHandler
-FLASH_IRQHandler
-RCC_IRQHandler
-EXTI0_IRQHandler
-EXTI1_IRQHandler
-EXTI2_IRQHandler
-EXTI3_IRQHandler
-EXTI4_IRQHandler
-DMA1_Channel1_IRQHandler
-DMA1_Channel2_IRQHandler
-DMA1_Channel3_IRQHandler
-DMA1_Channel4_IRQHandler
-DMA1_Channel5_IRQHandler
-DMA1_Channel6_IRQHandler
-DMA1_Channel7_IRQHandler
-ADC1_2_IRQHandler
-CAN1_TX_IRQHandler
-CAN1_RX0_IRQHandler
-CAN1_RX1_IRQHandler
-CAN1_SCE_IRQHandler
-EXTI9_5_IRQHandler
-TIM1_BRK_IRQHandler
-TIM1_UP_IRQHandler
-TIM1_TRG_COM_IRQHandler
-TIM1_CC_IRQHandler
-TIM2_IRQHandler
-TIM3_IRQHandler
-TIM4_IRQHandler
-I2C1_EV_IRQHandler
-I2C1_ER_IRQHandler
-I2C2_EV_IRQHandler
-I2C2_ER_IRQHandler
-SPI1_IRQHandler
-SPI2_IRQHandler
-USART1_IRQHandler
-USART2_IRQHandler
-USART3_IRQHandler
-EXTI15_10_IRQHandler
-RTC_Alarm_IRQHandler
-OTG_FS_WKUP_IRQHandler
-TIM5_IRQHandler
-SPI3_IRQHandler
-UART4_IRQHandler
-UART5_IRQHandler
-TIM6_IRQHandler
-TIM7_IRQHandler
-DMA2_Channel1_IRQHandler
-DMA2_Channel2_IRQHandler
-DMA2_Channel3_IRQHandler
-DMA2_Channel4_IRQHandler
-DMA2_Channel5_IRQHandler
-ETH_IRQHandler
-ETH_WKUP_IRQHandler
-CAN2_TX_IRQHandler
-CAN2_RX0_IRQHandler
-CAN2_RX1_IRQHandler
-CAN2_SCE_IRQHandler
-OTG_FS_IRQHandler
-
- B .
-
- ENDP
-
- ALIGN
-
-;*******************************************************************************
-; User Stack and Heap initialization
-;*******************************************************************************
- IF :DEF:__MICROLIB
-
- EXPORT __initial_sp
- EXPORT __heap_base
- EXPORT __heap_limit
-
- ELSE
-
- IMPORT __use_two_region_memory
- EXPORT __user_initial_stackheap
-
-__user_initial_stackheap
-
- LDR R0, = Heap_Mem
- LDR R1, =(Stack_Mem + Stack_Size)
- LDR R2, = (Heap_Mem + Heap_Size)
- LDR R3, = Stack_Mem
- BX LR
-
- ALIGN
-
- ENDIF
-
- END
-
-;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f100xb.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f100xb.s
deleted file mode 100644
index fbf19b7..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f100xb.s
+++ /dev/null
@@ -1,422 +0,0 @@
-/**
- *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
- * @file startup_stm32f100xb.s
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @brief STM32F100xB Devices vector table for Atollic toolchain.
- * This module performs:
- * - Set the initial SP
- * - Set the initial PC == Reset_Handler,
- * - Set the vector table entries with the exceptions ISR address
- * - Configure the clock system
- * - Branches to main in the C library (which eventually
- * calls main()).
- * After Reset the Cortex-M3 processor is in Thread mode,
- * priority is Privileged, and the Stack is set to Main.
- ******************************************************************************
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
- .syntax unified
- .cpu cortex-m3
- .fpu softvfp
- .thumb
-
-.global g_pfnVectors
-.global Default_Handler
-
-/* start address for the initialization values of the .data section.
-defined in linker script */
-.word _sidata
-/* start address for the .data section. defined in linker script */
-.word _sdata
-/* end address for the .data section. defined in linker script */
-.word _edata
-/* start address for the .bss section. defined in linker script */
-.word _sbss
-/* end address for the .bss section. defined in linker script */
-.word _ebss
-
-.equ BootRAM, 0xF108F85F
-/**
- * @brief This is the code that gets called when the processor first
- * starts execution following a reset event. Only the absolutely
- * necessary set is performed, after which the application
- * supplied main() routine is called.
- * @param None
- * @retval : None
-*/
-
- .section .text.Reset_Handler
- .weak Reset_Handler
- .type Reset_Handler, %function
-Reset_Handler:
-
-/* Copy the data segment initializers from flash to SRAM */
- movs r1, #0
- b LoopCopyDataInit
-
-CopyDataInit:
- ldr r3, =_sidata
- ldr r3, [r3, r1]
- str r3, [r0, r1]
- adds r1, r1, #4
-
-LoopCopyDataInit:
- ldr r0, =_sdata
- ldr r3, =_edata
- adds r2, r0, r1
- cmp r2, r3
- bcc CopyDataInit
- ldr r2, =_sbss
- b LoopFillZerobss
-/* Zero fill the bss segment. */
-FillZerobss:
- movs r3, #0
- str r3, [r2], #4
-
-LoopFillZerobss:
- ldr r3, = _ebss
- cmp r2, r3
- bcc FillZerobss
-
-/* Call the clock system intitialization function.*/
- bl SystemInit
-/* Call static constructors */
- bl __libc_init_array
-/* Call the application's entry point.*/
- bl main
- bx lr
-.size Reset_Handler, .-Reset_Handler
-
-/**
- * @brief This is the code that gets called when the processor receives an
- * unexpected interrupt. This simply enters an infinite loop, preserving
- * the system state for examination by a debugger.
- *
- * @param None
- * @retval : None
-*/
- .section .text.Default_Handler,"ax",%progbits
-Default_Handler:
-Infinite_Loop:
- b Infinite_Loop
- .size Default_Handler, .-Default_Handler
-/******************************************************************************
-*
-* The minimal vector table for a Cortex M3. Note that the proper constructs
-* must be placed on this to ensure that it ends up at physical address
-* 0x0000.0000.
-*
-******************************************************************************/
- .section .isr_vector,"a",%progbits
- .type g_pfnVectors, %object
- .size g_pfnVectors, .-g_pfnVectors
-
-
-g_pfnVectors:
- .word _estack
- .word Reset_Handler
- .word NMI_Handler
- .word HardFault_Handler
- .word MemManage_Handler
- .word BusFault_Handler
- .word UsageFault_Handler
- .word 0
- .word 0
- .word 0
- .word 0
- .word SVC_Handler
- .word DebugMon_Handler
- .word 0
- .word PendSV_Handler
- .word SysTick_Handler
- .word WWDG_IRQHandler
- .word PVD_IRQHandler
- .word TAMPER_IRQHandler
- .word RTC_IRQHandler
- .word FLASH_IRQHandler
- .word RCC_IRQHandler
- .word EXTI0_IRQHandler
- .word EXTI1_IRQHandler
- .word EXTI2_IRQHandler
- .word EXTI3_IRQHandler
- .word EXTI4_IRQHandler
- .word DMA1_Channel1_IRQHandler
- .word DMA1_Channel2_IRQHandler
- .word DMA1_Channel3_IRQHandler
- .word DMA1_Channel4_IRQHandler
- .word DMA1_Channel5_IRQHandler
- .word DMA1_Channel6_IRQHandler
- .word DMA1_Channel7_IRQHandler
- .word ADC1_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word EXTI9_5_IRQHandler
- .word TIM1_BRK_TIM15_IRQHandler
- .word TIM1_UP_TIM16_IRQHandler
- .word TIM1_TRG_COM_TIM17_IRQHandler
- .word TIM1_CC_IRQHandler
- .word TIM2_IRQHandler
- .word TIM3_IRQHandler
- .word TIM4_IRQHandler
- .word I2C1_EV_IRQHandler
- .word I2C1_ER_IRQHandler
- .word I2C2_EV_IRQHandler
- .word I2C2_ER_IRQHandler
- .word SPI1_IRQHandler
- .word SPI2_IRQHandler
- .word USART1_IRQHandler
- .word USART2_IRQHandler
- .word USART3_IRQHandler
- .word EXTI15_10_IRQHandler
- .word RTC_Alarm_IRQHandler
- .word CEC_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word TIM6_DAC_IRQHandler
- .word TIM7_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word BootRAM /* @0x01CC. This is for boot in RAM mode for
- STM32F10xB Value Line devices. */
-
-/*******************************************************************************
-*
-* Provide weak aliases for each Exception handler to the Default_Handler.
-* As they are weak aliases, any function with the same name will override
-* this definition.
-*
-*******************************************************************************/
-
-
- .weak NMI_Handler
- .thumb_set NMI_Handler,Default_Handler
-
- .weak HardFault_Handler
- .thumb_set HardFault_Handler,Default_Handler
-
- .weak MemManage_Handler
- .thumb_set MemManage_Handler,Default_Handler
-
- .weak BusFault_Handler
- .thumb_set BusFault_Handler,Default_Handler
-
- .weak UsageFault_Handler
- .thumb_set UsageFault_Handler,Default_Handler
-
- .weak SVC_Handler
- .thumb_set SVC_Handler,Default_Handler
-
- .weak DebugMon_Handler
- .thumb_set DebugMon_Handler,Default_Handler
-
- .weak PendSV_Handler
- .thumb_set PendSV_Handler,Default_Handler
-
- .weak SysTick_Handler
- .thumb_set SysTick_Handler,Default_Handler
-
- .weak WWDG_IRQHandler
- .thumb_set WWDG_IRQHandler,Default_Handler
-
- .weak PVD_IRQHandler
- .thumb_set PVD_IRQHandler,Default_Handler
-
- .weak TAMPER_IRQHandler
- .thumb_set TAMPER_IRQHandler,Default_Handler
-
- .weak RTC_IRQHandler
- .thumb_set RTC_IRQHandler,Default_Handler
-
- .weak FLASH_IRQHandler
- .thumb_set FLASH_IRQHandler,Default_Handler
-
- .weak RCC_IRQHandler
- .thumb_set RCC_IRQHandler,Default_Handler
-
- .weak EXTI0_IRQHandler
- .thumb_set EXTI0_IRQHandler,Default_Handler
-
- .weak EXTI1_IRQHandler
- .thumb_set EXTI1_IRQHandler,Default_Handler
-
- .weak EXTI2_IRQHandler
- .thumb_set EXTI2_IRQHandler,Default_Handler
-
- .weak EXTI3_IRQHandler
- .thumb_set EXTI3_IRQHandler,Default_Handler
-
- .weak EXTI4_IRQHandler
- .thumb_set EXTI4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel1_IRQHandler
- .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
-
- .weak DMA1_Channel2_IRQHandler
- .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
-
- .weak DMA1_Channel3_IRQHandler
- .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
-
- .weak DMA1_Channel4_IRQHandler
- .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel5_IRQHandler
- .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
-
- .weak DMA1_Channel6_IRQHandler
- .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
-
- .weak DMA1_Channel7_IRQHandler
- .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
-
- .weak ADC1_IRQHandler
- .thumb_set ADC1_IRQHandler,Default_Handler
-
- .weak EXTI9_5_IRQHandler
- .thumb_set EXTI9_5_IRQHandler,Default_Handler
-
- .weak TIM1_BRK_TIM15_IRQHandler
- .thumb_set TIM1_BRK_TIM15_IRQHandler,Default_Handler
-
- .weak TIM1_UP_TIM16_IRQHandler
- .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler
-
- .weak TIM1_TRG_COM_TIM17_IRQHandler
- .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler
-
- .weak TIM1_CC_IRQHandler
- .thumb_set TIM1_CC_IRQHandler,Default_Handler
-
- .weak TIM2_IRQHandler
- .thumb_set TIM2_IRQHandler,Default_Handler
-
- .weak TIM3_IRQHandler
- .thumb_set TIM3_IRQHandler,Default_Handler
-
- .weak TIM4_IRQHandler
- .thumb_set TIM4_IRQHandler,Default_Handler
-
- .weak I2C1_EV_IRQHandler
- .thumb_set I2C1_EV_IRQHandler,Default_Handler
-
- .weak I2C1_ER_IRQHandler
- .thumb_set I2C1_ER_IRQHandler,Default_Handler
-
- .weak I2C2_EV_IRQHandler
- .thumb_set I2C1_EV_IRQHandler,Default_Handler
-
- .weak I2C2_ER_IRQHandler
- .thumb_set I2C1_ER_IRQHandler,Default_Handler
-
- .weak SPI1_IRQHandler
- .thumb_set SPI1_IRQHandler,Default_Handler
-
- .weak SPI1_IRQHandler
- .thumb_set SPI2_IRQHandler,Default_Handler
-
- .weak USART1_IRQHandler
- .thumb_set USART1_IRQHandler,Default_Handler
-
- .weak USART2_IRQHandler
- .thumb_set USART2_IRQHandler,Default_Handler
-
- .weak USART3_IRQHandler
- .thumb_set USART3_IRQHandler,Default_Handler
-
- .weak EXTI15_10_IRQHandler
- .thumb_set EXTI15_10_IRQHandler,Default_Handler
-
- .weak RTC_Alarm_IRQHandler
- .thumb_set RTC_Alarm_IRQHandler,Default_Handler
-
- .weak CEC_IRQHandler
- .thumb_set CEC_IRQHandler,Default_Handler
-
- .weak TIM6_DAC_IRQHandler
- .thumb_set TIM6_DAC_IRQHandler,Default_Handler
-
- .weak TIM7_IRQHandler
- .thumb_set TIM7_IRQHandler,Default_Handler
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f100xe.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f100xe.s
deleted file mode 100644
index 1159ddf..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f100xe.s
+++ /dev/null
@@ -1,464 +0,0 @@
-/**
- *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
- * @file startup_stm32f100xe.s
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @brief STM32F100xE Devices vector table for Atollic toolchain.
- * This module performs:
- * - Set the initial SP
- * - Set the initial PC == Reset_Handler,
- * - Set the vector table entries with the exceptions ISR address
- * - Configure the clock system
- * - Branches to main in the C library (which eventually
- * calls main()).
- * After Reset the Cortex-M3 processor is in Thread mode,
- * priority is Privileged, and the Stack is set to Main.
- ******************************************************************************
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
- .syntax unified
- .cpu cortex-m3
- .fpu softvfp
- .thumb
-
-.global g_pfnVectors
-.global Default_Handler
-
-/* start address for the initialization values of the .data section.
-defined in linker script */
-.word _sidata
-/* start address for the .data section. defined in linker script */
-.word _sdata
-/* end address for the .data section. defined in linker script */
-.word _edata
-/* start address for the .bss section. defined in linker script */
-.word _sbss
-/* end address for the .bss section. defined in linker script */
-.word _ebss
-
-.equ BootRAM, 0xF108F85F
-/**
- * @brief This is the code that gets called when the processor first
- * starts execution following a reset event. Only the absolutely
- * necessary set is performed, after which the application
- * supplied main() routine is called.
- * @param None
- * @retval : None
-*/
-
- .section .text.Reset_Handler
- .weak Reset_Handler
- .type Reset_Handler, %function
-Reset_Handler:
-
-/* Copy the data segment initializers from flash to SRAM */
- movs r1, #0
- b LoopCopyDataInit
-
-CopyDataInit:
- ldr r3, =_sidata
- ldr r3, [r3, r1]
- str r3, [r0, r1]
- adds r1, r1, #4
-
-LoopCopyDataInit:
- ldr r0, =_sdata
- ldr r3, =_edata
- adds r2, r0, r1
- cmp r2, r3
- bcc CopyDataInit
- ldr r2, =_sbss
- b LoopFillZerobss
-/* Zero fill the bss segment. */
-FillZerobss:
- movs r3, #0
- str r3, [r2], #4
-
-LoopFillZerobss:
- ldr r3, = _ebss
- cmp r2, r3
- bcc FillZerobss
-
-/* Call the clock system intitialization function.*/
- bl SystemInit
-/* Call static constructors */
- bl __libc_init_array
-/* Call the application's entry point.*/
- bl main
- bx lr
-.size Reset_Handler, .-Reset_Handler
-
-/**
- * @brief This is the code that gets called when the processor receives an
- * unexpected interrupt. This simply enters an infinite loop, preserving
- * the system state for examination by a debugger.
- *
- * @param None
- * @retval : None
-*/
- .section .text.Default_Handler,"ax",%progbits
-Default_Handler:
-Infinite_Loop:
- b Infinite_Loop
- .size Default_Handler, .-Default_Handler
-/******************************************************************************
-*
-* The minimal vector table for a Cortex M3. Note that the proper constructs
-* must be placed on this to ensure that it ends up at physical address
-* 0x0000.0000.
-*
-******************************************************************************/
- .section .isr_vector,"a",%progbits
- .type g_pfnVectors, %object
- .size g_pfnVectors, .-g_pfnVectors
-
-
-g_pfnVectors:
-
- .word _estack
- .word Reset_Handler
- .word NMI_Handler
- .word HardFault_Handler
- .word MemManage_Handler
- .word BusFault_Handler
- .word UsageFault_Handler
- .word 0
- .word 0
- .word 0
- .word 0
- .word SVC_Handler
- .word DebugMon_Handler
- .word 0
- .word PendSV_Handler
- .word SysTick_Handler
- .word WWDG_IRQHandler
- .word PVD_IRQHandler
- .word TAMPER_IRQHandler
- .word RTC_IRQHandler
- .word FLASH_IRQHandler
- .word RCC_IRQHandler
- .word EXTI0_IRQHandler
- .word EXTI1_IRQHandler
- .word EXTI2_IRQHandler
- .word EXTI3_IRQHandler
- .word EXTI4_IRQHandler
- .word DMA1_Channel1_IRQHandler
- .word DMA1_Channel2_IRQHandler
- .word DMA1_Channel3_IRQHandler
- .word DMA1_Channel4_IRQHandler
- .word DMA1_Channel5_IRQHandler
- .word DMA1_Channel6_IRQHandler
- .word DMA1_Channel7_IRQHandler
- .word ADC1_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word EXTI9_5_IRQHandler
- .word TIM1_BRK_TIM15_IRQHandler
- .word TIM1_UP_TIM16_IRQHandler
- .word TIM1_TRG_COM_TIM17_IRQHandler
- .word TIM1_CC_IRQHandler
- .word TIM2_IRQHandler
- .word TIM3_IRQHandler
- .word TIM4_IRQHandler
- .word I2C1_EV_IRQHandler
- .word I2C1_ER_IRQHandler
- .word I2C2_EV_IRQHandler
- .word I2C2_ER_IRQHandler
- .word SPI1_IRQHandler
- .word SPI2_IRQHandler
- .word USART1_IRQHandler
- .word USART2_IRQHandler
- .word USART3_IRQHandler
- .word EXTI15_10_IRQHandler
- .word RTC_Alarm_IRQHandler
- .word CEC_IRQHandler
- .word TIM12_IRQHandler
- .word TIM13_IRQHandler
- .word TIM14_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word TIM5_IRQHandler
- .word SPI3_IRQHandler
- .word UART4_IRQHandler
- .word UART5_IRQHandler
- .word TIM6_DAC_IRQHandler
- .word TIM7_IRQHandler
- .word DMA2_Channel1_IRQHandler
- .word DMA2_Channel2_IRQHandler
- .word DMA2_Channel3_IRQHandler
- .word DMA2_Channel4_5_IRQHandler
- .word DMA2_Channel5_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word BootRAM /* @0x1E0. This is for boot in RAM mode for
- STM32F10x High Density Value line devices. */
-
-/*******************************************************************************
-*
-* Provide weak aliases for each Exception handler to the Default_Handler.
-* As they are weak aliases, any function with the same name will override
-* this definition.
-*
-*******************************************************************************/
-
-
- .weak NMI_Handler
- .thumb_set NMI_Handler,Default_Handler
-
- .weak HardFault_Handler
- .thumb_set HardFault_Handler,Default_Handler
-
- .weak MemManage_Handler
- .thumb_set MemManage_Handler,Default_Handler
-
- .weak BusFault_Handler
- .thumb_set BusFault_Handler,Default_Handler
-
- .weak UsageFault_Handler
- .thumb_set UsageFault_Handler,Default_Handler
-
- .weak SVC_Handler
- .thumb_set SVC_Handler,Default_Handler
-
- .weak DebugMon_Handler
- .thumb_set DebugMon_Handler,Default_Handler
-
- .weak PendSV_Handler
- .thumb_set PendSV_Handler,Default_Handler
-
- .weak SysTick_Handler
- .thumb_set SysTick_Handler,Default_Handler
-
- .weak WWDG_IRQHandler
- .thumb_set WWDG_IRQHandler,Default_Handler
-
- .weak PVD_IRQHandler
- .thumb_set PVD_IRQHandler,Default_Handler
-
- .weak TAMPER_IRQHandler
- .thumb_set TAMPER_IRQHandler,Default_Handler
-
- .weak RTC_IRQHandler
- .thumb_set RTC_IRQHandler,Default_Handler
-
- .weak FLASH_IRQHandler
- .thumb_set FLASH_IRQHandler,Default_Handler
-
- .weak RCC_IRQHandler
- .thumb_set RCC_IRQHandler,Default_Handler
-
- .weak EXTI0_IRQHandler
- .thumb_set EXTI0_IRQHandler,Default_Handler
-
- .weak EXTI1_IRQHandler
- .thumb_set EXTI1_IRQHandler,Default_Handler
-
- .weak EXTI2_IRQHandler
- .thumb_set EXTI2_IRQHandler,Default_Handler
-
- .weak EXTI3_IRQHandler
- .thumb_set EXTI3_IRQHandler,Default_Handler
-
- .weak EXTI4_IRQHandler
- .thumb_set EXTI4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel1_IRQHandler
- .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
-
- .weak DMA1_Channel2_IRQHandler
- .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
-
- .weak DMA1_Channel3_IRQHandler
- .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
-
- .weak DMA1_Channel4_IRQHandler
- .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel5_IRQHandler
- .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
-
- .weak DMA1_Channel6_IRQHandler
- .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
-
- .weak DMA1_Channel7_IRQHandler
- .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
-
- .weak ADC1_IRQHandler
- .thumb_set ADC1_IRQHandler,Default_Handler
-
- .weak EXTI9_5_IRQHandler
- .thumb_set EXTI9_5_IRQHandler,Default_Handler
-
- .weak TIM1_BRK_TIM15_IRQHandler
- .thumb_set TIM1_BRK_TIM15_IRQHandler,Default_Handler
-
- .weak TIM1_UP_TIM16_IRQHandler
- .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler
-
- .weak TIM1_TRG_COM_TIM17_IRQHandler
- .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler
-
- .weak TIM1_CC_IRQHandler
- .thumb_set TIM1_CC_IRQHandler,Default_Handler
-
- .weak TIM2_IRQHandler
- .thumb_set TIM2_IRQHandler,Default_Handler
-
- .weak TIM3_IRQHandler
- .thumb_set TIM3_IRQHandler,Default_Handler
-
- .weak TIM4_IRQHandler
- .thumb_set TIM4_IRQHandler,Default_Handler
-
- .weak I2C1_EV_IRQHandler
- .thumb_set I2C1_EV_IRQHandler,Default_Handler
-
- .weak I2C1_ER_IRQHandler
- .thumb_set I2C1_ER_IRQHandler,Default_Handler
-
- .weak I2C2_EV_IRQHandler
- .thumb_set I2C2_EV_IRQHandler,Default_Handler
-
- .weak I2C2_ER_IRQHandler
- .thumb_set I2C2_ER_IRQHandler,Default_Handler
-
- .weak SPI1_IRQHandler
- .thumb_set SPI1_IRQHandler,Default_Handler
-
- .weak SPI2_IRQHandler
- .thumb_set SPI2_IRQHandler,Default_Handler
-
- .weak USART1_IRQHandler
- .thumb_set USART1_IRQHandler,Default_Handler
-
- .weak USART2_IRQHandler
- .thumb_set USART2_IRQHandler,Default_Handler
-
- .weak USART3_IRQHandler
- .thumb_set USART3_IRQHandler,Default_Handler
-
- .weak EXTI15_10_IRQHandler
- .thumb_set EXTI15_10_IRQHandler,Default_Handler
-
- .weak RTC_Alarm_IRQHandler
- .thumb_set RTC_Alarm_IRQHandler,Default_Handler
-
- .weak CEC_IRQHandler
- .thumb_set CEC_IRQHandler,Default_Handler
-
- .weak TIM12_IRQHandler
- .thumb_set TIM12_IRQHandler,Default_Handler
-
- .weak TIM13_IRQHandler
- .thumb_set TIM13_IRQHandler,Default_Handler
-
- .weak TIM14_IRQHandler
- .thumb_set TIM14_IRQHandler,Default_Handler
-
- .weak TIM5_IRQHandler
- .thumb_set TIM5_IRQHandler,Default_Handler
-
- .weak SPI3_IRQHandler
- .thumb_set SPI3_IRQHandler,Default_Handler
-
- .weak UART4_IRQHandler
- .thumb_set UART4_IRQHandler,Default_Handler
-
- .weak UART5_IRQHandler
- .thumb_set UART5_IRQHandler,Default_Handler
-
- .weak TIM6_DAC_IRQHandler
- .thumb_set TIM6_DAC_IRQHandler,Default_Handler
-
- .weak TIM7_IRQHandler
- .thumb_set TIM7_IRQHandler,Default_Handler
-
- .weak DMA2_Channel1_IRQHandler
- .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
-
- .weak DMA2_Channel2_IRQHandler
- .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
-
- .weak DMA2_Channel3_IRQHandler
- .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
-
- .weak DMA2_Channel4_5_IRQHandler
- .thumb_set DMA2_Channel4_5_IRQHandler,Default_Handler
-
- .weak DMA2_Channel5_IRQHandler
- .thumb_set DMA2_Channel5_IRQHandler,Default_Handler
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101x6.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101x6.s
deleted file mode 100644
index 07915af..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101x6.s
+++ /dev/null
@@ -1,337 +0,0 @@
-/**
- *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
- * @file startup_stm32f101x6.s
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @brief STM32F101x6 Devices vector table for Atollic toolchain.
- * This module performs:
- * - Set the initial SP
- * - Set the initial PC == Reset_Handler,
- * - Set the vector table entries with the exceptions ISR address
- * - Configure the clock system
- * - Branches to main in the C library (which eventually
- * calls main()).
- * After Reset the Cortex-M3 processor is in Thread mode,
- * priority is Privileged, and the Stack is set to Main.
- ******************************************************************************
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
- .syntax unified
- .cpu cortex-m3
- .fpu softvfp
- .thumb
-
-.global g_pfnVectors
-.global Default_Handler
-
-/* start address for the initialization values of the .data section.
-defined in linker script */
-.word _sidata
-/* start address for the .data section. defined in linker script */
-.word _sdata
-/* end address for the .data section. defined in linker script */
-.word _edata
-/* start address for the .bss section. defined in linker script */
-.word _sbss
-/* end address for the .bss section. defined in linker script */
-.word _ebss
-
-.equ BootRAM, 0xF108F85F
-/**
- * @brief This is the code that gets called when the processor first
- * starts execution following a reset event. Only the absolutely
- * necessary set is performed, after which the application
- * supplied main() routine is called.
- * @param None
- * @retval : None
-*/
-
- .section .text.Reset_Handler
- .weak Reset_Handler
- .type Reset_Handler, %function
-Reset_Handler:
-
-/* Copy the data segment initializers from flash to SRAM */
- movs r1, #0
- b LoopCopyDataInit
-
-CopyDataInit:
- ldr r3, =_sidata
- ldr r3, [r3, r1]
- str r3, [r0, r1]
- adds r1, r1, #4
-
-LoopCopyDataInit:
- ldr r0, =_sdata
- ldr r3, =_edata
- adds r2, r0, r1
- cmp r2, r3
- bcc CopyDataInit
- ldr r2, =_sbss
- b LoopFillZerobss
-/* Zero fill the bss segment. */
-FillZerobss:
- movs r3, #0
- str r3, [r2], #4
-
-LoopFillZerobss:
- ldr r3, = _ebss
- cmp r2, r3
- bcc FillZerobss
-
-/* Call the clock system intitialization function.*/
- bl SystemInit
-/* Call static constructors */
- bl __libc_init_array
-/* Call the application's entry point.*/
- bl main
- bx lr
-.size Reset_Handler, .-Reset_Handler
-
-/**
- * @brief This is the code that gets called when the processor receives an
- * unexpected interrupt. This simply enters an infinite loop, preserving
- * the system state for examination by a debugger.
- *
- * @param None
- * @retval : None
-*/
- .section .text.Default_Handler,"ax",%progbits
-Default_Handler:
-Infinite_Loop:
- b Infinite_Loop
- .size Default_Handler, .-Default_Handler
-/******************************************************************************
-*
-* The minimal vector table for a Cortex M3. Note that the proper constructs
-* must be placed on this to ensure that it ends up at physical address
-* 0x0000.0000.
-*
-******************************************************************************/
- .section .isr_vector,"a",%progbits
- .type g_pfnVectors, %object
- .size g_pfnVectors, .-g_pfnVectors
-
-
-g_pfnVectors:
-
-
- .word _estack
- .word Reset_Handler
- .word NMI_Handler
- .word HardFault_Handler
- .word MemManage_Handler
- .word BusFault_Handler
- .word UsageFault_Handler
- .word 0
- .word 0
- .word 0
- .word 0
- .word SVC_Handler
- .word DebugMon_Handler
- .word 0
- .word PendSV_Handler
- .word SysTick_Handler
- .word WWDG_IRQHandler
- .word PVD_IRQHandler
- .word TAMPER_IRQHandler
- .word RTC_IRQHandler
- .word FLASH_IRQHandler
- .word RCC_IRQHandler
- .word EXTI0_IRQHandler
- .word EXTI1_IRQHandler
- .word EXTI2_IRQHandler
- .word EXTI3_IRQHandler
- .word EXTI4_IRQHandler
- .word DMA1_Channel1_IRQHandler
- .word DMA1_Channel2_IRQHandler
- .word DMA1_Channel3_IRQHandler
- .word DMA1_Channel4_IRQHandler
- .word DMA1_Channel5_IRQHandler
- .word DMA1_Channel6_IRQHandler
- .word DMA1_Channel7_IRQHandler
- .word ADC1_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word EXTI9_5_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word TIM2_IRQHandler
- .word TIM3_IRQHandler
- .word 0
- .word I2C1_EV_IRQHandler
- .word I2C1_ER_IRQHandler
- .word 0
- .word 0
- .word SPI1_IRQHandler
- .word 0
- .word USART1_IRQHandler
- .word USART2_IRQHandler
- .word 0
- .word EXTI15_10_IRQHandler
- .word RTC_Alarm_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word BootRAM /* @0x108. This is for boot in RAM mode for
- STM32F10x Low Density devices.*/
-
-/*******************************************************************************
-*
-* Provide weak aliases for each Exception handler to the Default_Handler.
-* As they are weak aliases, any function with the same name will override
-* this definition.
-*
-*******************************************************************************/
-
- .weak NMI_Handler
- .thumb_set NMI_Handler,Default_Handler
-
- .weak HardFault_Handler
- .thumb_set HardFault_Handler,Default_Handler
-
- .weak MemManage_Handler
- .thumb_set MemManage_Handler,Default_Handler
-
- .weak BusFault_Handler
- .thumb_set BusFault_Handler,Default_Handler
-
- .weak UsageFault_Handler
- .thumb_set UsageFault_Handler,Default_Handler
-
- .weak SVC_Handler
- .thumb_set SVC_Handler,Default_Handler
-
- .weak DebugMon_Handler
- .thumb_set DebugMon_Handler,Default_Handler
-
- .weak PendSV_Handler
- .thumb_set PendSV_Handler,Default_Handler
-
- .weak SysTick_Handler
- .thumb_set SysTick_Handler,Default_Handler
-
- .weak WWDG_IRQHandler
- .thumb_set WWDG_IRQHandler,Default_Handler
-
- .weak PVD_IRQHandler
- .thumb_set PVD_IRQHandler,Default_Handler
-
- .weak TAMPER_IRQHandler
- .thumb_set TAMPER_IRQHandler,Default_Handler
-
- .weak RTC_IRQHandler
- .thumb_set RTC_IRQHandler,Default_Handler
-
- .weak FLASH_IRQHandler
- .thumb_set FLASH_IRQHandler,Default_Handler
-
- .weak RCC_IRQHandler
- .thumb_set RCC_IRQHandler,Default_Handler
-
- .weak EXTI0_IRQHandler
- .thumb_set EXTI0_IRQHandler,Default_Handler
-
- .weak EXTI1_IRQHandler
- .thumb_set EXTI1_IRQHandler,Default_Handler
-
- .weak EXTI2_IRQHandler
- .thumb_set EXTI2_IRQHandler,Default_Handler
-
- .weak EXTI3_IRQHandler
- .thumb_set EXTI3_IRQHandler,Default_Handler
-
- .weak EXTI4_IRQHandler
- .thumb_set EXTI4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel1_IRQHandler
- .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
-
- .weak DMA1_Channel2_IRQHandler
- .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
-
- .weak DMA1_Channel3_IRQHandler
- .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
-
- .weak DMA1_Channel4_IRQHandler
- .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel5_IRQHandler
- .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
-
- .weak DMA1_Channel6_IRQHandler
- .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
-
- .weak DMA1_Channel7_IRQHandler
- .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
-
- .weak ADC1_IRQHandler
- .thumb_set ADC1_IRQHandler,Default_Handler
-
- .weak EXTI9_5_IRQHandler
- .thumb_set EXTI9_5_IRQHandler,Default_Handler
-
- .weak TIM2_IRQHandler
- .thumb_set TIM2_IRQHandler,Default_Handler
-
- .weak TIM3_IRQHandler
- .thumb_set TIM3_IRQHandler,Default_Handler
-
- .weak I2C1_EV_IRQHandler
- .thumb_set I2C1_EV_IRQHandler,Default_Handler
-
- .weak I2C1_ER_IRQHandler
- .thumb_set I2C1_ER_IRQHandler,Default_Handler
-
- .weak SPI1_IRQHandler
- .thumb_set SPI1_IRQHandler,Default_Handler
-
- .weak USART1_IRQHandler
- .thumb_set USART1_IRQHandler,Default_Handler
-
- .weak USART2_IRQHandler
- .thumb_set USART2_IRQHandler,Default_Handler
-
- .weak EXTI15_10_IRQHandler
- .thumb_set EXTI15_10_IRQHandler,Default_Handler
-
- .weak RTC_Alarm_IRQHandler
- .thumb_set RTC_Alarm_IRQHandler,Default_Handler
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101xb.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101xb.s
deleted file mode 100644
index 52b3297..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101xb.s
+++ /dev/null
@@ -1,353 +0,0 @@
-/**
- *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
- * @file startup_stm32f101xb.s
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @brief STM32F101xB Devices vector table for Atollic toolchain.
- * This module performs:
- * - Set the initial SP
- * - Set the initial PC == Reset_Handler,
- * - Set the vector table entries with the exceptions ISR address
- * - Configure the clock system
- * - Branches to main in the C library (which eventually
- * calls main()).
- * After Reset the Cortex-M3 processor is in Thread mode,
- * priority is Privileged, and the Stack is set to Main.
- ******************************************************************************
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
- .syntax unified
- .cpu cortex-m3
- .fpu softvfp
- .thumb
-
-.global g_pfnVectors
-.global Default_Handler
-
-/* start address for the initialization values of the .data section.
-defined in linker script */
-.word _sidata
-/* start address for the .data section. defined in linker script */
-.word _sdata
-/* end address for the .data section. defined in linker script */
-.word _edata
-/* start address for the .bss section. defined in linker script */
-.word _sbss
-/* end address for the .bss section. defined in linker script */
-.word _ebss
-
-.equ BootRAM, 0xF108F85F
-/**
- * @brief This is the code that gets called when the processor first
- * starts execution following a reset event. Only the absolutely
- * necessary set is performed, after which the application
- * supplied main() routine is called.
- * @param None
- * @retval : None
-*/
-
- .section .text.Reset_Handler
- .weak Reset_Handler
- .type Reset_Handler, %function
-Reset_Handler:
-
-/* Copy the data segment initializers from flash to SRAM */
- movs r1, #0
- b LoopCopyDataInit
-
-CopyDataInit:
- ldr r3, =_sidata
- ldr r3, [r3, r1]
- str r3, [r0, r1]
- adds r1, r1, #4
-
-LoopCopyDataInit:
- ldr r0, =_sdata
- ldr r3, =_edata
- adds r2, r0, r1
- cmp r2, r3
- bcc CopyDataInit
- ldr r2, =_sbss
- b LoopFillZerobss
-/* Zero fill the bss segment. */
-FillZerobss:
- movs r3, #0
- str r3, [r2], #4
-
-LoopFillZerobss:
- ldr r3, = _ebss
- cmp r2, r3
- bcc FillZerobss
-
-/* Call the clock system intitialization function.*/
- bl SystemInit
-/* Call static constructors */
- bl __libc_init_array
-/* Call the application's entry point.*/
- bl main
- bx lr
-.size Reset_Handler, .-Reset_Handler
-
-/**
- * @brief This is the code that gets called when the processor receives an
- * unexpected interrupt. This simply enters an infinite loop, preserving
- * the system state for examination by a debugger.
- *
- * @param None
- * @retval : None
-*/
- .section .text.Default_Handler,"ax",%progbits
-Default_Handler:
-Infinite_Loop:
- b Infinite_Loop
- .size Default_Handler, .-Default_Handler
-/******************************************************************************
-*
-* The minimal vector table for a Cortex M3. Note that the proper constructs
-* must be placed on this to ensure that it ends up at physical address
-* 0x0000.0000.
-*
-******************************************************************************/
- .section .isr_vector,"a",%progbits
- .type g_pfnVectors, %object
- .size g_pfnVectors, .-g_pfnVectors
-
-
-g_pfnVectors:
-
- .word _estack
- .word Reset_Handler
- .word NMI_Handler
- .word HardFault_Handler
- .word MemManage_Handler
- .word BusFault_Handler
- .word UsageFault_Handler
- .word 0
- .word 0
- .word 0
- .word 0
- .word SVC_Handler
- .word DebugMon_Handler
- .word 0
- .word PendSV_Handler
- .word SysTick_Handler
- .word WWDG_IRQHandler
- .word PVD_IRQHandler
- .word TAMPER_IRQHandler
- .word RTC_IRQHandler
- .word FLASH_IRQHandler
- .word RCC_IRQHandler
- .word EXTI0_IRQHandler
- .word EXTI1_IRQHandler
- .word EXTI2_IRQHandler
- .word EXTI3_IRQHandler
- .word EXTI4_IRQHandler
- .word DMA1_Channel1_IRQHandler
- .word DMA1_Channel2_IRQHandler
- .word DMA1_Channel3_IRQHandler
- .word DMA1_Channel4_IRQHandler
- .word DMA1_Channel5_IRQHandler
- .word DMA1_Channel6_IRQHandler
- .word DMA1_Channel7_IRQHandler
- .word ADC1_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word EXTI9_5_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word TIM2_IRQHandler
- .word TIM3_IRQHandler
- .word TIM4_IRQHandler
- .word I2C1_EV_IRQHandler
- .word I2C1_ER_IRQHandler
- .word I2C2_EV_IRQHandler
- .word I2C2_ER_IRQHandler
- .word SPI1_IRQHandler
- .word SPI2_IRQHandler
- .word USART1_IRQHandler
- .word USART2_IRQHandler
- .word USART3_IRQHandler
- .word EXTI15_10_IRQHandler
- .word RTC_Alarm_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word BootRAM /* @0x108. This is for boot in RAM mode for
- STM32F10x Medium Density devices. */
-
-/*******************************************************************************
-*
-* Provide weak aliases for each Exception handler to the Default_Handler.
-* As they are weak aliases, any function with the same name will override
-* this definition.
-*
-*******************************************************************************/
-
- .weak NMI_Handler
- .thumb_set NMI_Handler,Default_Handler
-
- .weak HardFault_Handler
- .thumb_set HardFault_Handler,Default_Handler
-
- .weak MemManage_Handler
- .thumb_set MemManage_Handler,Default_Handler
-
- .weak BusFault_Handler
- .thumb_set BusFault_Handler,Default_Handler
-
- .weak UsageFault_Handler
- .thumb_set UsageFault_Handler,Default_Handler
-
- .weak SVC_Handler
- .thumb_set SVC_Handler,Default_Handler
-
- .weak DebugMon_Handler
- .thumb_set DebugMon_Handler,Default_Handler
-
- .weak PendSV_Handler
- .thumb_set PendSV_Handler,Default_Handler
-
- .weak SysTick_Handler
- .thumb_set SysTick_Handler,Default_Handler
-
- .weak WWDG_IRQHandler
- .thumb_set WWDG_IRQHandler,Default_Handler
-
- .weak PVD_IRQHandler
- .thumb_set PVD_IRQHandler,Default_Handler
-
- .weak TAMPER_IRQHandler
- .thumb_set TAMPER_IRQHandler,Default_Handler
-
- .weak RTC_IRQHandler
- .thumb_set RTC_IRQHandler,Default_Handler
-
- .weak FLASH_IRQHandler
- .thumb_set FLASH_IRQHandler,Default_Handler
-
- .weak RCC_IRQHandler
- .thumb_set RCC_IRQHandler,Default_Handler
-
- .weak EXTI0_IRQHandler
- .thumb_set EXTI0_IRQHandler,Default_Handler
-
- .weak EXTI1_IRQHandler
- .thumb_set EXTI1_IRQHandler,Default_Handler
-
- .weak EXTI2_IRQHandler
- .thumb_set EXTI2_IRQHandler,Default_Handler
-
- .weak EXTI3_IRQHandler
- .thumb_set EXTI3_IRQHandler,Default_Handler
-
- .weak EXTI4_IRQHandler
- .thumb_set EXTI4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel1_IRQHandler
- .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
-
- .weak DMA1_Channel2_IRQHandler
- .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
-
- .weak DMA1_Channel3_IRQHandler
- .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
-
- .weak DMA1_Channel4_IRQHandler
- .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel5_IRQHandler
- .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
-
- .weak DMA1_Channel6_IRQHandler
- .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
-
- .weak DMA1_Channel7_IRQHandler
- .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
-
- .weak ADC1_IRQHandler
- .thumb_set ADC1_IRQHandler,Default_Handler
-
- .weak EXTI9_5_IRQHandler
- .thumb_set EXTI9_5_IRQHandler,Default_Handler
-
- .weak TIM2_IRQHandler
- .thumb_set TIM2_IRQHandler,Default_Handler
-
- .weak TIM3_IRQHandler
- .thumb_set TIM3_IRQHandler,Default_Handler
-
- .weak TIM4_IRQHandler
- .thumb_set TIM4_IRQHandler,Default_Handler
-
- .weak I2C1_EV_IRQHandler
- .thumb_set I2C1_EV_IRQHandler,Default_Handler
-
- .weak I2C1_ER_IRQHandler
- .thumb_set I2C1_ER_IRQHandler,Default_Handler
-
- .weak I2C2_EV_IRQHandler
- .thumb_set I2C2_EV_IRQHandler,Default_Handler
-
- .weak I2C2_ER_IRQHandler
- .thumb_set I2C2_ER_IRQHandler,Default_Handler
-
- .weak SPI1_IRQHandler
- .thumb_set SPI1_IRQHandler,Default_Handler
-
- .weak SPI2_IRQHandler
- .thumb_set SPI2_IRQHandler,Default_Handler
-
- .weak USART1_IRQHandler
- .thumb_set USART1_IRQHandler,Default_Handler
-
- .weak USART2_IRQHandler
- .thumb_set USART2_IRQHandler,Default_Handler
-
- .weak USART3_IRQHandler
- .thumb_set USART3_IRQHandler,Default_Handler
-
- .weak EXTI15_10_IRQHandler
- .thumb_set EXTI15_10_IRQHandler,Default_Handler
-
- .weak RTC_Alarm_IRQHandler
- .thumb_set RTC_Alarm_IRQHandler,Default_Handler
-
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101xe.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101xe.s
deleted file mode 100644
index f4aefc2..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101xe.s
+++ /dev/null
@@ -1,438 +0,0 @@
-/**
- *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
- * @file startup_stm32f101xe.s
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @brief STM32F101xE Value Line Devices vector table for Atollic toolchain.
- * This module performs:
- * - Set the initial SP
- * - Set the initial PC == Reset_Handler,
- * - Set the vector table entries with the exceptions ISR address
- * - Configure the clock system
- * - Branches to main in the C library (which eventually
- * calls main()).
- * After Reset the Cortex-M3 processor is in Thread mode,
- * priority is Privileged, and the Stack is set to Main.
- ******************************************************************************
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
- .syntax unified
- .cpu cortex-m3
- .fpu softvfp
- .thumb
-
-.global g_pfnVectors
-.global Default_Handler
-
-/* start address for the initialization values of the .data section.
-defined in linker script */
-.word _sidata
-/* start address for the .data section. defined in linker script */
-.word _sdata
-/* end address for the .data section. defined in linker script */
-.word _edata
-/* start address for the .bss section. defined in linker script */
-.word _sbss
-/* end address for the .bss section. defined in linker script */
-.word _ebss
-
-.equ BootRAM, 0xF1E0F85F
-/**
- * @brief This is the code that gets called when the processor first
- * starts execution following a reset event. Only the absolutely
- * necessary set is performed, after which the application
- * supplied main() routine is called.
- * @param None
- * @retval : None
-*/
-
- .section .text.Reset_Handler
- .weak Reset_Handler
- .type Reset_Handler, %function
-Reset_Handler:
-
-/* Copy the data segment initializers from flash to SRAM */
- movs r1, #0
- b LoopCopyDataInit
-
-CopyDataInit:
- ldr r3, =_sidata
- ldr r3, [r3, r1]
- str r3, [r0, r1]
- adds r1, r1, #4
-
-LoopCopyDataInit:
- ldr r0, =_sdata
- ldr r3, =_edata
- adds r2, r0, r1
- cmp r2, r3
- bcc CopyDataInit
- ldr r2, =_sbss
- b LoopFillZerobss
-/* Zero fill the bss segment. */
-FillZerobss:
- movs r3, #0
- str r3, [r2], #4
-
-LoopFillZerobss:
- ldr r3, = _ebss
- cmp r2, r3
- bcc FillZerobss
-
-/* Call the clock system intitialization function.*/
- bl SystemInit
-/* Call static constructors */
- bl __libc_init_array
-/* Call the application's entry point.*/
- bl main
- bx lr
-.size Reset_Handler, .-Reset_Handler
-
-/**
- * @brief This is the code that gets called when the processor receives an
- * unexpected interrupt. This simply enters an infinite loop, preserving
- * the system state for examination by a debugger.
- *
- * @param None
- * @retval : None
-*/
- .section .text.Default_Handler,"ax",%progbits
-Default_Handler:
-Infinite_Loop:
- b Infinite_Loop
- .size Default_Handler, .-Default_Handler
-/******************************************************************************
-*
-* The minimal vector table for a Cortex M3. Note that the proper constructs
-* must be placed on this to ensure that it ends up at physical address
-* 0x0000.0000.
-*
-******************************************************************************/
- .section .isr_vector,"a",%progbits
- .type g_pfnVectors, %object
- .size g_pfnVectors, .-g_pfnVectors
-
-
-g_pfnVectors:
-
- .word _estack
- .word Reset_Handler
- .word NMI_Handler
- .word HardFault_Handler
- .word MemManage_Handler
- .word BusFault_Handler
- .word UsageFault_Handler
- .word 0
- .word 0
- .word 0
- .word 0
- .word SVC_Handler
- .word DebugMon_Handler
- .word 0
- .word PendSV_Handler
- .word SysTick_Handler
- .word WWDG_IRQHandler
- .word PVD_IRQHandler
- .word TAMPER_IRQHandler
- .word RTC_IRQHandler
- .word FLASH_IRQHandler
- .word RCC_IRQHandler
- .word EXTI0_IRQHandler
- .word EXTI1_IRQHandler
- .word EXTI2_IRQHandler
- .word EXTI3_IRQHandler
- .word EXTI4_IRQHandler
- .word DMA1_Channel1_IRQHandler
- .word DMA1_Channel2_IRQHandler
- .word DMA1_Channel3_IRQHandler
- .word DMA1_Channel4_IRQHandler
- .word DMA1_Channel5_IRQHandler
- .word DMA1_Channel6_IRQHandler
- .word DMA1_Channel7_IRQHandler
- .word ADC1_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word EXTI9_5_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word TIM2_IRQHandler
- .word TIM3_IRQHandler
- .word TIM4_IRQHandler
- .word I2C1_EV_IRQHandler
- .word I2C1_ER_IRQHandler
- .word I2C2_EV_IRQHandler
- .word I2C2_ER_IRQHandler
- .word SPI1_IRQHandler
- .word SPI2_IRQHandler
- .word USART1_IRQHandler
- .word USART2_IRQHandler
- .word USART3_IRQHandler
- .word EXTI15_10_IRQHandler
- .word RTC_Alarm_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word FSMC_IRQHandler
- .word 0
- .word TIM5_IRQHandler
- .word SPI3_IRQHandler
- .word UART4_IRQHandler
- .word UART5_IRQHandler
- .word TIM6_IRQHandler
- .word TIM7_IRQHandler
- .word DMA2_Channel1_IRQHandler
- .word DMA2_Channel2_IRQHandler
- .word DMA2_Channel3_IRQHandler
- .word DMA2_Channel4_5_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word BootRAM /* @0x1E0. This is for boot in RAM mode for
- STM32F10x High Density devices. */
-
-/*******************************************************************************
-*
-* Provide weak aliases for each Exception handler to the Default_Handler.
-* As they are weak aliases, any function with the same name will override
-* this definition.
-*
-*******************************************************************************/
-
- .weak NMI_Handler
- .thumb_set NMI_Handler,Default_Handler
-
- .weak HardFault_Handler
- .thumb_set HardFault_Handler,Default_Handler
-
- .weak MemManage_Handler
- .thumb_set MemManage_Handler,Default_Handler
-
- .weak BusFault_Handler
- .thumb_set BusFault_Handler,Default_Handler
-
- .weak UsageFault_Handler
- .thumb_set UsageFault_Handler,Default_Handler
-
- .weak SVC_Handler
- .thumb_set SVC_Handler,Default_Handler
-
- .weak DebugMon_Handler
- .thumb_set DebugMon_Handler,Default_Handler
-
- .weak PendSV_Handler
- .thumb_set PendSV_Handler,Default_Handler
-
- .weak SysTick_Handler
- .thumb_set SysTick_Handler,Default_Handler
-
- .weak WWDG_IRQHandler
- .thumb_set WWDG_IRQHandler,Default_Handler
-
- .weak PVD_IRQHandler
- .thumb_set PVD_IRQHandler,Default_Handler
-
- .weak TAMPER_IRQHandler
- .thumb_set TAMPER_IRQHandler,Default_Handler
-
- .weak RTC_IRQHandler
- .thumb_set RTC_IRQHandler,Default_Handler
-
- .weak FLASH_IRQHandler
- .thumb_set FLASH_IRQHandler,Default_Handler
-
- .weak RCC_IRQHandler
- .thumb_set RCC_IRQHandler,Default_Handler
-
- .weak EXTI0_IRQHandler
- .thumb_set EXTI0_IRQHandler,Default_Handler
-
- .weak EXTI1_IRQHandler
- .thumb_set EXTI1_IRQHandler,Default_Handler
-
- .weak EXTI2_IRQHandler
- .thumb_set EXTI2_IRQHandler,Default_Handler
-
- .weak EXTI3_IRQHandler
- .thumb_set EXTI3_IRQHandler,Default_Handler
-
- .weak EXTI4_IRQHandler
- .thumb_set EXTI4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel1_IRQHandler
- .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
-
- .weak DMA1_Channel2_IRQHandler
- .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
-
- .weak DMA1_Channel3_IRQHandler
- .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
-
- .weak DMA1_Channel4_IRQHandler
- .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel5_IRQHandler
- .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
-
- .weak DMA1_Channel6_IRQHandler
- .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
-
- .weak DMA1_Channel7_IRQHandler
- .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
-
- .weak ADC1_IRQHandler
- .thumb_set ADC1_IRQHandler,Default_Handler
-
- .weak EXTI9_5_IRQHandler
- .thumb_set EXTI9_5_IRQHandler,Default_Handler
-
- .weak TIM2_IRQHandler
- .thumb_set TIM2_IRQHandler,Default_Handler
-
- .weak TIM3_IRQHandler
- .thumb_set TIM3_IRQHandler,Default_Handler
-
- .weak TIM4_IRQHandler
- .thumb_set TIM4_IRQHandler,Default_Handler
-
- .weak I2C1_EV_IRQHandler
- .thumb_set I2C1_EV_IRQHandler,Default_Handler
-
- .weak I2C1_ER_IRQHandler
- .thumb_set I2C1_ER_IRQHandler,Default_Handler
-
- .weak I2C2_EV_IRQHandler
- .thumb_set I2C2_EV_IRQHandler,Default_Handler
-
- .weak I2C2_ER_IRQHandler
- .thumb_set I2C2_ER_IRQHandler,Default_Handler
-
- .weak SPI1_IRQHandler
- .thumb_set SPI1_IRQHandler,Default_Handler
-
- .weak SPI2_IRQHandler
- .thumb_set SPI2_IRQHandler,Default_Handler
-
- .weak USART1_IRQHandler
- .thumb_set USART1_IRQHandler,Default_Handler
-
- .weak USART2_IRQHandler
- .thumb_set USART2_IRQHandler,Default_Handler
-
- .weak USART3_IRQHandler
- .thumb_set USART3_IRQHandler,Default_Handler
-
- .weak EXTI15_10_IRQHandler
- .thumb_set EXTI15_10_IRQHandler,Default_Handler
-
- .weak RTC_Alarm_IRQHandler
- .thumb_set RTC_Alarm_IRQHandler,Default_Handler
-
- .weak FSMC_IRQHandler
- .thumb_set FSMC_IRQHandler,Default_Handler
-
- .weak TIM5_IRQHandler
- .thumb_set TIM5_IRQHandler,Default_Handler
-
- .weak SPI3_IRQHandler
- .thumb_set SPI3_IRQHandler,Default_Handler
-
- .weak UART4_IRQHandler
- .thumb_set UART4_IRQHandler,Default_Handler
-
- .weak UART5_IRQHandler
- .thumb_set UART5_IRQHandler,Default_Handler
-
- .weak TIM6_IRQHandler
- .thumb_set TIM6_IRQHandler,Default_Handler
-
- .weak TIM7_IRQHandler
- .thumb_set TIM7_IRQHandler,Default_Handler
-
- .weak DMA2_Channel1_IRQHandler
- .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
-
- .weak DMA2_Channel2_IRQHandler
- .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
-
- .weak DMA2_Channel3_IRQHandler
- .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
-
- .weak DMA2_Channel4_5_IRQHandler
- .thumb_set DMA2_Channel4_5_IRQHandler,Default_Handler
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101xg.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101xg.s
deleted file mode 100644
index 7e79d0c..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101xg.s
+++ /dev/null
@@ -1,454 +0,0 @@
-/**
- *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
- * @file startup_stm32f101xg.s
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @brief STM32F101xG Devices vector table for Atollic toolchain.
- * This module performs:
- * - Set the initial SP
- * - Set the initial PC == Reset_Handler,
- * - Set the vector table entries with the exceptions ISR address
- * - Configure the clock system
- * - Branches to main in the C library (which eventually
- * calls main()).
- * After Reset the Cortex-M3 processor is in Thread mode,
- * priority is Privileged, and the Stack is set to Main.
- ******************************************************************************
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
- .syntax unified
- .cpu cortex-m3
- .fpu softvfp
- .thumb
-
-.global g_pfnVectors
-.global Default_Handler
-
-/* start address for the initialization values of the .data section.
-defined in linker script */
-.word _sidata
-/* start address for the .data section. defined in linker script */
-.word _sdata
-/* end address for the .data section. defined in linker script */
-.word _edata
-/* start address for the .bss section. defined in linker script */
-.word _sbss
-/* end address for the .bss section. defined in linker script */
-.word _ebss
-
-.equ BootRAM, 0xF1E0F85F
-/**
- * @brief This is the code that gets called when the processor first
- * starts execution following a reset event. Only the absolutely
- * necessary set is performed, after which the application
- * supplied main() routine is called.
- * @param None
- * @retval : None
-*/
-
- .section .text.Reset_Handler
- .weak Reset_Handler
- .type Reset_Handler, %function
-Reset_Handler:
-
-/* Copy the data segment initializers from flash to SRAM */
- movs r1, #0
- b LoopCopyDataInit
-
-CopyDataInit:
- ldr r3, =_sidata
- ldr r3, [r3, r1]
- str r3, [r0, r1]
- adds r1, r1, #4
-
-LoopCopyDataInit:
- ldr r0, =_sdata
- ldr r3, =_edata
- adds r2, r0, r1
- cmp r2, r3
- bcc CopyDataInit
- ldr r2, =_sbss
- b LoopFillZerobss
-/* Zero fill the bss segment. */
-FillZerobss:
- movs r3, #0
- str r3, [r2], #4
-
-LoopFillZerobss:
- ldr r3, = _ebss
- cmp r2, r3
- bcc FillZerobss
-
-/* Call the clock system intitialization function.*/
- bl SystemInit
-/* Call static constructors */
- bl __libc_init_array
-/* Call the application's entry point.*/
- bl main
- bx lr
-.size Reset_Handler, .-Reset_Handler
-
-/**
- * @brief This is the code that gets called when the processor receives an
- * unexpected interrupt. This simply enters an infinite loop, preserving
- * the system state for examination by a debugger.
- * @param None
- * @retval None
-*/
- .section .text.Default_Handler,"ax",%progbits
-Default_Handler:
-Infinite_Loop:
- b Infinite_Loop
- .size Default_Handler, .-Default_Handler
-/******************************************************************************
-*
-* The minimal vector table for a Cortex M3. Note that the proper constructs
-* must be placed on this to ensure that it ends up at physical address
-* 0x0000.0000.
-*
-******************************************************************************/
- .section .isr_vector,"a",%progbits
- .type g_pfnVectors, %object
- .size g_pfnVectors, .-g_pfnVectors
-
-
-g_pfnVectors:
-
- .word _estack
- .word Reset_Handler
- .word NMI_Handler
- .word HardFault_Handler
- .word MemManage_Handler
- .word BusFault_Handler
- .word UsageFault_Handler
- .word 0
- .word 0
- .word 0
- .word 0
- .word SVC_Handler
- .word DebugMon_Handler
- .word 0
- .word PendSV_Handler
- .word SysTick_Handler
- .word WWDG_IRQHandler
- .word PVD_IRQHandler
- .word TAMPER_IRQHandler
- .word RTC_IRQHandler
- .word FLASH_IRQHandler
- .word RCC_IRQHandler
- .word EXTI0_IRQHandler
- .word EXTI1_IRQHandler
- .word EXTI2_IRQHandler
- .word EXTI3_IRQHandler
- .word EXTI4_IRQHandler
- .word DMA1_Channel1_IRQHandler
- .word DMA1_Channel2_IRQHandler
- .word DMA1_Channel3_IRQHandler
- .word DMA1_Channel4_IRQHandler
- .word DMA1_Channel5_IRQHandler
- .word DMA1_Channel6_IRQHandler
- .word DMA1_Channel7_IRQHandler
- .word ADC1_2_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word EXTI9_5_IRQHandler
- .word TIM9_IRQHandler
- .word TIM10_IRQHandler
- .word TIM11_IRQHandler
- .word 0
- .word TIM2_IRQHandler
- .word TIM3_IRQHandler
- .word TIM4_IRQHandler
- .word I2C1_EV_IRQHandler
- .word I2C1_ER_IRQHandler
- .word I2C2_EV_IRQHandler
- .word I2C2_ER_IRQHandler
- .word SPI1_IRQHandler
- .word SPI2_IRQHandler
- .word USART1_IRQHandler
- .word USART2_IRQHandler
- .word USART3_IRQHandler
- .word EXTI15_10_IRQHandler
- .word RTC_Alarm_IRQHandler
- .word 0
- .word TIM12_IRQHandler
- .word TIM13_IRQHandler
- .word TIM14_IRQHandler
- .word 0
- .word 0
- .word FSMC_IRQHandler
- .word 0
- .word TIM5_IRQHandler
- .word SPI3_IRQHandler
- .word UART4_IRQHandler
- .word UART5_IRQHandler
- .word TIM6_IRQHandler
- .word TIM7_IRQHandler
- .word DMA2_Channel1_IRQHandler
- .word DMA2_Channel2_IRQHandler
- .word DMA2_Channel3_IRQHandler
- .word DMA2_Channel4_5_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word BootRAM /* @0x1E0. This is for boot in RAM mode for
- STM32F10x XL-Density devices. */
-/*******************************************************************************
-*
-* Provide weak aliases for each Exception handler to the Default_Handler.
-* As they are weak aliases, any function with the same name will override
-* this definition.
-*
-*******************************************************************************/
-
- .weak NMI_Handler
- .thumb_set NMI_Handler,Default_Handler
-
- .weak HardFault_Handler
- .thumb_set HardFault_Handler,Default_Handler
-
- .weak MemManage_Handler
- .thumb_set MemManage_Handler,Default_Handler
-
- .weak BusFault_Handler
- .thumb_set BusFault_Handler,Default_Handler
-
- .weak UsageFault_Handler
- .thumb_set UsageFault_Handler,Default_Handler
-
- .weak SVC_Handler
- .thumb_set SVC_Handler,Default_Handler
-
- .weak DebugMon_Handler
- .thumb_set DebugMon_Handler,Default_Handler
-
- .weak PendSV_Handler
- .thumb_set PendSV_Handler,Default_Handler
-
- .weak SysTick_Handler
- .thumb_set SysTick_Handler,Default_Handler
-
- .weak WWDG_IRQHandler
- .thumb_set WWDG_IRQHandler,Default_Handler
-
- .weak PVD_IRQHandler
- .thumb_set PVD_IRQHandler,Default_Handler
-
- .weak TAMPER_IRQHandler
- .thumb_set TAMPER_IRQHandler,Default_Handler
-
- .weak RTC_IRQHandler
- .thumb_set RTC_IRQHandler,Default_Handler
-
- .weak FLASH_IRQHandler
- .thumb_set FLASH_IRQHandler,Default_Handler
-
- .weak RCC_IRQHandler
- .thumb_set RCC_IRQHandler,Default_Handler
-
- .weak EXTI0_IRQHandler
- .thumb_set EXTI0_IRQHandler,Default_Handler
-
- .weak EXTI1_IRQHandler
- .thumb_set EXTI1_IRQHandler,Default_Handler
-
- .weak EXTI2_IRQHandler
- .thumb_set EXTI2_IRQHandler,Default_Handler
-
- .weak EXTI3_IRQHandler
- .thumb_set EXTI3_IRQHandler,Default_Handler
-
- .weak EXTI4_IRQHandler
- .thumb_set EXTI4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel1_IRQHandler
- .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
-
- .weak DMA1_Channel2_IRQHandler
- .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
-
- .weak DMA1_Channel3_IRQHandler
- .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
-
- .weak DMA1_Channel4_IRQHandler
- .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel5_IRQHandler
- .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
-
- .weak DMA1_Channel6_IRQHandler
- .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
-
- .weak DMA1_Channel7_IRQHandler
- .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
-
- .weak ADC1_2_IRQHandler
- .thumb_set ADC1_2_IRQHandler,Default_Handler
-
- .weak EXTI9_5_IRQHandler
- .thumb_set EXTI9_5_IRQHandler,Default_Handler
-
- .weak TIM9_IRQHandler
- .thumb_set TIM9_IRQHandler,Default_Handler
-
- .weak TIM10_IRQHandler
- .thumb_set TIM10_IRQHandler,Default_Handler
-
- .weak TIM11_IRQHandler
- .thumb_set TIM11_IRQHandler,Default_Handler
-
- .weak TIM2_IRQHandler
- .thumb_set TIM2_IRQHandler,Default_Handler
-
- .weak TIM3_IRQHandler
- .thumb_set TIM3_IRQHandler,Default_Handler
-
- .weak TIM4_IRQHandler
- .thumb_set TIM4_IRQHandler,Default_Handler
-
- .weak I2C1_EV_IRQHandler
- .thumb_set I2C1_EV_IRQHandler,Default_Handler
-
- .weak I2C1_ER_IRQHandler
- .thumb_set I2C1_ER_IRQHandler,Default_Handler
-
- .weak I2C2_EV_IRQHandler
- .thumb_set I2C2_EV_IRQHandler,Default_Handler
-
- .weak I2C2_ER_IRQHandler
- .thumb_set I2C2_ER_IRQHandler,Default_Handler
-
- .weak SPI1_IRQHandler
- .thumb_set SPI1_IRQHandler,Default_Handler
-
- .weak SPI2_IRQHandler
- .thumb_set SPI2_IRQHandler,Default_Handler
-
- .weak USART1_IRQHandler
- .thumb_set USART1_IRQHandler,Default_Handler
-
- .weak USART2_IRQHandler
- .thumb_set USART2_IRQHandler,Default_Handler
-
- .weak USART3_IRQHandler
- .thumb_set USART3_IRQHandler,Default_Handler
-
- .weak EXTI15_10_IRQHandler
- .thumb_set EXTI15_10_IRQHandler,Default_Handler
-
- .weak RTC_Alarm_IRQHandler
- .thumb_set RTC_Alarm_IRQHandler,Default_Handler
-
- .weak TIM12_IRQHandler
- .thumb_set TIM12_IRQHandler,Default_Handler
-
- .weak TIM13_IRQHandler
- .thumb_set TIM13_IRQHandler,Default_Handler
-
- .weak TIM14_IRQHandler
- .thumb_set TIM14_IRQHandler,Default_Handler
-
- .weak FSMC_IRQHandler
- .thumb_set FSMC_IRQHandler,Default_Handler
-
- .weak TIM5_IRQHandler
- .thumb_set TIM5_IRQHandler,Default_Handler
-
- .weak SPI3_IRQHandler
- .thumb_set SPI3_IRQHandler,Default_Handler
-
- .weak UART4_IRQHandler
- .thumb_set UART4_IRQHandler,Default_Handler
-
- .weak UART5_IRQHandler
- .thumb_set UART5_IRQHandler,Default_Handler
-
- .weak TIM6_IRQHandler
- .thumb_set TIM6_IRQHandler,Default_Handler
-
- .weak TIM7_IRQHandler
- .thumb_set TIM7_IRQHandler,Default_Handler
-
- .weak DMA2_Channel1_IRQHandler
- .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
-
- .weak DMA2_Channel2_IRQHandler
- .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
-
- .weak DMA2_Channel3_IRQHandler
- .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
-
- .weak DMA2_Channel4_5_IRQHandler
- .thumb_set DMA2_Channel4_5_IRQHandler,Default_Handler
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f102x6.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f102x6.s
deleted file mode 100644
index 219c326..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f102x6.s
+++ /dev/null
@@ -1,345 +0,0 @@
-/**
- *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
- * @file startup_stm32f102x6.s
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @brief STM32F102x6 Devices vector table for Atollic toolchain.
- * This module performs:
- * - Set the initial SP
- * - Set the initial PC == Reset_Handler,
- * - Set the vector table entries with the exceptions ISR address
- * - Configure the clock system
- * - Branches to main in the C library (which eventually
- * calls main()).
- * After Reset the Cortex-M3 processor is in Thread mode,
- * priority is Privileged, and the Stack is set to Main.
- ******************************************************************************
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
- .syntax unified
- .cpu cortex-m3
- .fpu softvfp
- .thumb
-
-.global g_pfnVectors
-.global Default_Handler
-
-/* start address for the initialization values of the .data section.
-defined in linker script */
-.word _sidata
-/* start address for the .data section. defined in linker script */
-.word _sdata
-/* end address for the .data section. defined in linker script */
-.word _edata
-/* start address for the .bss section. defined in linker script */
-.word _sbss
-/* end address for the .bss section. defined in linker script */
-.word _ebss
-
-.equ BootRAM, 0xF108F85F
-/**
- * @brief This is the code that gets called when the processor first
- * starts execution following a reset event. Only the absolutely
- * necessary set is performed, after which the application
- * supplied main() routine is called.
- * @param None
- * @retval : None
-*/
-
- .section .text.Reset_Handler
- .weak Reset_Handler
- .type Reset_Handler, %function
-Reset_Handler:
-
-/* Copy the data segment initializers from flash to SRAM */
- movs r1, #0
- b LoopCopyDataInit
-
-CopyDataInit:
- ldr r3, =_sidata
- ldr r3, [r3, r1]
- str r3, [r0, r1]
- adds r1, r1, #4
-
-LoopCopyDataInit:
- ldr r0, =_sdata
- ldr r3, =_edata
- adds r2, r0, r1
- cmp r2, r3
- bcc CopyDataInit
- ldr r2, =_sbss
- b LoopFillZerobss
-/* Zero fill the bss segment. */
-FillZerobss:
- movs r3, #0
- str r3, [r2], #4
-
-LoopFillZerobss:
- ldr r3, = _ebss
- cmp r2, r3
- bcc FillZerobss
-
-/* Call the clock system intitialization function.*/
- bl SystemInit
-/* Call static constructors */
- bl __libc_init_array
-/* Call the application's entry point.*/
- bl main
- bx lr
-.size Reset_Handler, .-Reset_Handler
-
-/**
- * @brief This is the code that gets called when the processor receives an
- * unexpected interrupt. This simply enters an infinite loop, preserving
- * the system state for examination by a debugger.
- *
- * @param None
- * @retval : None
-*/
- .section .text.Default_Handler,"ax",%progbits
-Default_Handler:
-Infinite_Loop:
- b Infinite_Loop
- .size Default_Handler, .-Default_Handler
-/******************************************************************************
-*
-* The minimal vector table for a Cortex M3. Note that the proper constructs
-* must be placed on this to ensure that it ends up at physical address
-* 0x0000.0000.
-*
-******************************************************************************/
- .section .isr_vector,"a",%progbits
- .type g_pfnVectors, %object
- .size g_pfnVectors, .-g_pfnVectors
-
-
-g_pfnVectors:
-
- .word _estack
- .word Reset_Handler
- .word NMI_Handler
- .word HardFault_Handler
- .word MemManage_Handler
- .word BusFault_Handler
- .word UsageFault_Handler
- .word 0
- .word 0
- .word 0
- .word 0
- .word SVC_Handler
- .word DebugMon_Handler
- .word 0
- .word PendSV_Handler
- .word SysTick_Handler
- .word WWDG_IRQHandler
- .word PVD_IRQHandler
- .word TAMPER_IRQHandler
- .word RTC_IRQHandler
- .word FLASH_IRQHandler
- .word RCC_IRQHandler
- .word EXTI0_IRQHandler
- .word EXTI1_IRQHandler
- .word EXTI2_IRQHandler
- .word EXTI3_IRQHandler
- .word EXTI4_IRQHandler
- .word DMA1_Channel1_IRQHandler
- .word DMA1_Channel2_IRQHandler
- .word DMA1_Channel3_IRQHandler
- .word DMA1_Channel4_IRQHandler
- .word DMA1_Channel5_IRQHandler
- .word DMA1_Channel6_IRQHandler
- .word DMA1_Channel7_IRQHandler
- .word ADC1_IRQHandler
- .word USB_HP_IRQHandler
- .word USB_LP_IRQHandler
- .word 0
- .word 0
- .word EXTI9_5_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word TIM2_IRQHandler
- .word TIM3_IRQHandler
- .word 0
- .word I2C1_EV_IRQHandler
- .word I2C1_ER_IRQHandler
- .word 0
- .word 0
- .word SPI1_IRQHandler
- .word 0
- .word USART1_IRQHandler
- .word USART2_IRQHandler
- .word 0
- .word EXTI15_10_IRQHandler
- .word RTC_Alarm_IRQHandler
- .word USBWakeUp_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word BootRAM /* @0x108. This is for boot in RAM mode for
- STM32F10x Low Density devices.*/
-
-/*******************************************************************************
-*
-* Provide weak aliases for each Exception handler to the Default_Handler.
-* As they are weak aliases, any function with the same name will override
-* this definition.
-*
-*******************************************************************************/
-
- .weak NMI_Handler
- .thumb_set NMI_Handler,Default_Handler
-
- .weak HardFault_Handler
- .thumb_set HardFault_Handler,Default_Handler
-
- .weak MemManage_Handler
- .thumb_set MemManage_Handler,Default_Handler
-
- .weak BusFault_Handler
- .thumb_set BusFault_Handler,Default_Handler
-
- .weak UsageFault_Handler
- .thumb_set UsageFault_Handler,Default_Handler
-
- .weak SVC_Handler
- .thumb_set SVC_Handler,Default_Handler
-
- .weak DebugMon_Handler
- .thumb_set DebugMon_Handler,Default_Handler
-
- .weak PendSV_Handler
- .thumb_set PendSV_Handler,Default_Handler
-
- .weak SysTick_Handler
- .thumb_set SysTick_Handler,Default_Handler
-
- .weak WWDG_IRQHandler
- .thumb_set WWDG_IRQHandler,Default_Handler
-
- .weak PVD_IRQHandler
- .thumb_set PVD_IRQHandler,Default_Handler
-
- .weak TAMPER_IRQHandler
- .thumb_set TAMPER_IRQHandler,Default_Handler
-
- .weak RTC_IRQHandler
- .thumb_set RTC_IRQHandler,Default_Handler
-
- .weak FLASH_IRQHandler
- .thumb_set FLASH_IRQHandler,Default_Handler
-
- .weak RCC_IRQHandler
- .thumb_set RCC_IRQHandler,Default_Handler
-
- .weak EXTI0_IRQHandler
- .thumb_set EXTI0_IRQHandler,Default_Handler
-
- .weak EXTI1_IRQHandler
- .thumb_set EXTI1_IRQHandler,Default_Handler
-
- .weak EXTI2_IRQHandler
- .thumb_set EXTI2_IRQHandler,Default_Handler
-
- .weak EXTI3_IRQHandler
- .thumb_set EXTI3_IRQHandler,Default_Handler
-
- .weak EXTI4_IRQHandler
- .thumb_set EXTI4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel1_IRQHandler
- .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
-
- .weak DMA1_Channel2_IRQHandler
- .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
-
- .weak DMA1_Channel3_IRQHandler
- .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
-
- .weak DMA1_Channel4_IRQHandler
- .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel5_IRQHandler
- .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
-
- .weak DMA1_Channel6_IRQHandler
- .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
-
- .weak DMA1_Channel7_IRQHandler
- .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
-
- .weak ADC1_IRQHandler
- .thumb_set ADC1_IRQHandler,Default_Handler
-
- .weak USB_HP_IRQHandler
- .thumb_set USB_HP_IRQHandler,Default_Handler
-
- .weak USB_LP_IRQHandler
- .thumb_set USB_LP_IRQHandler,Default_Handler
-
- .weak EXTI9_5_IRQHandler
- .thumb_set EXTI9_5_IRQHandler,Default_Handler
-
- .weak TIM2_IRQHandler
- .thumb_set TIM2_IRQHandler,Default_Handler
-
- .weak TIM3_IRQHandler
- .thumb_set TIM3_IRQHandler,Default_Handler
-
- .weak I2C1_EV_IRQHandler
- .thumb_set I2C1_EV_IRQHandler,Default_Handler
-
- .weak I2C1_ER_IRQHandler
- .thumb_set I2C1_ER_IRQHandler,Default_Handler
-
- .weak SPI1_IRQHandler
- .thumb_set SPI1_IRQHandler,Default_Handler
-
- .weak USART1_IRQHandler
- .thumb_set USART1_IRQHandler,Default_Handler
-
- .weak USART2_IRQHandler
- .thumb_set USART2_IRQHandler,Default_Handler
-
- .weak EXTI15_10_IRQHandler
- .thumb_set EXTI15_10_IRQHandler,Default_Handler
-
- .weak RTC_Alarm_IRQHandler
- .thumb_set RTC_Alarm_IRQHandler,Default_Handler
-
- .weak USBWakeUp_IRQHandler
- .thumb_set USBWakeUp_IRQHandler,Default_Handler
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f102xb.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f102xb.s
deleted file mode 100644
index 2372c69..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f102xb.s
+++ /dev/null
@@ -1,361 +0,0 @@
-/**
- *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
- * @file startup_stm32f102xb.s
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @brief STM32F102xB Value Line Devices vector table for Atollic toolchain.
- * This module performs:
- * - Set the initial SP
- * - Set the initial PC == Reset_Handler,
- * - Set the vector table entries with the exceptions ISR address
- * - Configure the clock system
- * - Branches to main in the C library (which eventually
- * calls main()).
- * After Reset the Cortex-M3 processor is in Thread mode,
- * priority is Privileged, and the Stack is set to Main.
- ******************************************************************************
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
- .syntax unified
- .cpu cortex-m3
- .fpu softvfp
- .thumb
-
-.global g_pfnVectors
-.global Default_Handler
-
-/* start address for the initialization values of the .data section.
-defined in linker script */
-.word _sidata
-/* start address for the .data section. defined in linker script */
-.word _sdata
-/* end address for the .data section. defined in linker script */
-.word _edata
-/* start address for the .bss section. defined in linker script */
-.word _sbss
-/* end address for the .bss section. defined in linker script */
-.word _ebss
-
-.equ BootRAM, 0xF108F85F
-/**
- * @brief This is the code that gets called when the processor first
- * starts execution following a reset event. Only the absolutely
- * necessary set is performed, after which the application
- * supplied main() routine is called.
- * @param None
- * @retval : None
-*/
-
- .section .text.Reset_Handler
- .weak Reset_Handler
- .type Reset_Handler, %function
-Reset_Handler:
-
-/* Copy the data segment initializers from flash to SRAM */
- movs r1, #0
- b LoopCopyDataInit
-
-CopyDataInit:
- ldr r3, =_sidata
- ldr r3, [r3, r1]
- str r3, [r0, r1]
- adds r1, r1, #4
-
-LoopCopyDataInit:
- ldr r0, =_sdata
- ldr r3, =_edata
- adds r2, r0, r1
- cmp r2, r3
- bcc CopyDataInit
- ldr r2, =_sbss
- b LoopFillZerobss
-/* Zero fill the bss segment. */
-FillZerobss:
- movs r3, #0
- str r3, [r2], #4
-
-LoopFillZerobss:
- ldr r3, = _ebss
- cmp r2, r3
- bcc FillZerobss
-
-/* Call the clock system intitialization function.*/
- bl SystemInit
-/* Call static constructors */
- bl __libc_init_array
-/* Call the application's entry point.*/
- bl main
- bx lr
-.size Reset_Handler, .-Reset_Handler
-
-/**
- * @brief This is the code that gets called when the processor receives an
- * unexpected interrupt. This simply enters an infinite loop, preserving
- * the system state for examination by a debugger.
- *
- * @param None
- * @retval : None
-*/
- .section .text.Default_Handler,"ax",%progbits
-Default_Handler:
-Infinite_Loop:
- b Infinite_Loop
- .size Default_Handler, .-Default_Handler
-/******************************************************************************
-*
-* The minimal vector table for a Cortex M3. Note that the proper constructs
-* must be placed on this to ensure that it ends up at physical address
-* 0x0000.0000.
-*
-******************************************************************************/
- .section .isr_vector,"a",%progbits
- .type g_pfnVectors, %object
- .size g_pfnVectors, .-g_pfnVectors
-
-
-g_pfnVectors:
-
- .word _estack
- .word Reset_Handler
- .word NMI_Handler
- .word HardFault_Handler
- .word MemManage_Handler
- .word BusFault_Handler
- .word UsageFault_Handler
- .word 0
- .word 0
- .word 0
- .word 0
- .word SVC_Handler
- .word DebugMon_Handler
- .word 0
- .word PendSV_Handler
- .word SysTick_Handler
- .word WWDG_IRQHandler
- .word PVD_IRQHandler
- .word TAMPER_IRQHandler
- .word RTC_IRQHandler
- .word FLASH_IRQHandler
- .word RCC_IRQHandler
- .word EXTI0_IRQHandler
- .word EXTI1_IRQHandler
- .word EXTI2_IRQHandler
- .word EXTI3_IRQHandler
- .word EXTI4_IRQHandler
- .word DMA1_Channel1_IRQHandler
- .word DMA1_Channel2_IRQHandler
- .word DMA1_Channel3_IRQHandler
- .word DMA1_Channel4_IRQHandler
- .word DMA1_Channel5_IRQHandler
- .word DMA1_Channel6_IRQHandler
- .word DMA1_Channel7_IRQHandler
- .word ADC1_IRQHandler
- .word USB_HP_IRQHandler
- .word USB_LP_IRQHandler
- .word 0
- .word 0
- .word EXTI9_5_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word TIM2_IRQHandler
- .word TIM3_IRQHandler
- .word TIM4_IRQHandler
- .word I2C1_EV_IRQHandler
- .word I2C1_ER_IRQHandler
- .word I2C2_EV_IRQHandler
- .word I2C2_ER_IRQHandler
- .word SPI1_IRQHandler
- .word SPI2_IRQHandler
- .word USART1_IRQHandler
- .word USART2_IRQHandler
- .word USART3_IRQHandler
- .word EXTI15_10_IRQHandler
- .word RTC_Alarm_IRQHandler
- .word USBWakeUp_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word BootRAM /* @0x108. This is for boot in RAM mode for
- STM32F10x Medium Density devices. */
-
-/*******************************************************************************
-*
-* Provide weak aliases for each Exception handler to the Default_Handler.
-* As they are weak aliases, any function with the same name will override
-* this definition.
-*
-*******************************************************************************/
-
- .weak NMI_Handler
- .thumb_set NMI_Handler,Default_Handler
-
- .weak HardFault_Handler
- .thumb_set HardFault_Handler,Default_Handler
-
- .weak MemManage_Handler
- .thumb_set MemManage_Handler,Default_Handler
-
- .weak BusFault_Handler
- .thumb_set BusFault_Handler,Default_Handler
-
- .weak UsageFault_Handler
- .thumb_set UsageFault_Handler,Default_Handler
-
- .weak SVC_Handler
- .thumb_set SVC_Handler,Default_Handler
-
- .weak DebugMon_Handler
- .thumb_set DebugMon_Handler,Default_Handler
-
- .weak PendSV_Handler
- .thumb_set PendSV_Handler,Default_Handler
-
- .weak SysTick_Handler
- .thumb_set SysTick_Handler,Default_Handler
-
- .weak WWDG_IRQHandler
- .thumb_set WWDG_IRQHandler,Default_Handler
-
- .weak PVD_IRQHandler
- .thumb_set PVD_IRQHandler,Default_Handler
-
- .weak TAMPER_IRQHandler
- .thumb_set TAMPER_IRQHandler,Default_Handler
-
- .weak RTC_IRQHandler
- .thumb_set RTC_IRQHandler,Default_Handler
-
- .weak FLASH_IRQHandler
- .thumb_set FLASH_IRQHandler,Default_Handler
-
- .weak RCC_IRQHandler
- .thumb_set RCC_IRQHandler,Default_Handler
-
- .weak EXTI0_IRQHandler
- .thumb_set EXTI0_IRQHandler,Default_Handler
-
- .weak EXTI1_IRQHandler
- .thumb_set EXTI1_IRQHandler,Default_Handler
-
- .weak EXTI2_IRQHandler
- .thumb_set EXTI2_IRQHandler,Default_Handler
-
- .weak EXTI3_IRQHandler
- .thumb_set EXTI3_IRQHandler,Default_Handler
-
- .weak EXTI4_IRQHandler
- .thumb_set EXTI4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel1_IRQHandler
- .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
-
- .weak DMA1_Channel2_IRQHandler
- .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
-
- .weak DMA1_Channel3_IRQHandler
- .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
-
- .weak DMA1_Channel4_IRQHandler
- .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel5_IRQHandler
- .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
-
- .weak DMA1_Channel6_IRQHandler
- .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
-
- .weak DMA1_Channel7_IRQHandler
- .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
-
- .weak ADC1_IRQHandler
- .thumb_set ADC1_IRQHandler,Default_Handler
-
- .weak USB_HP_IRQHandler
- .thumb_set USB_HP_IRQHandler,Default_Handler
-
- .weak USB_LP_IRQHandler
- .thumb_set USB_LP_IRQHandler,Default_Handler
-
- .weak EXTI9_5_IRQHandler
- .thumb_set EXTI9_5_IRQHandler,Default_Handler
-
- .weak TIM2_IRQHandler
- .thumb_set TIM2_IRQHandler,Default_Handler
-
- .weak TIM3_IRQHandler
- .thumb_set TIM3_IRQHandler,Default_Handler
-
- .weak TIM4_IRQHandler
- .thumb_set TIM4_IRQHandler,Default_Handler
-
- .weak I2C1_EV_IRQHandler
- .thumb_set I2C1_EV_IRQHandler,Default_Handler
-
- .weak I2C1_ER_IRQHandler
- .thumb_set I2C1_ER_IRQHandler,Default_Handler
-
- .weak I2C2_EV_IRQHandler
- .thumb_set I2C2_EV_IRQHandler,Default_Handler
-
- .weak I2C2_ER_IRQHandler
- .thumb_set I2C2_ER_IRQHandler,Default_Handler
-
- .weak SPI1_IRQHandler
- .thumb_set SPI1_IRQHandler,Default_Handler
-
- .weak SPI2_IRQHandler
- .thumb_set SPI2_IRQHandler,Default_Handler
-
- .weak USART1_IRQHandler
- .thumb_set USART1_IRQHandler,Default_Handler
-
- .weak USART2_IRQHandler
- .thumb_set USART2_IRQHandler,Default_Handler
-
- .weak USART3_IRQHandler
- .thumb_set USART3_IRQHandler,Default_Handler
-
- .weak EXTI15_10_IRQHandler
- .thumb_set EXTI15_10_IRQHandler,Default_Handler
-
- .weak RTC_Alarm_IRQHandler
- .thumb_set RTC_Alarm_IRQHandler,Default_Handler
-
- .weak USBWakeUp_IRQHandler
- .thumb_set USBWakeUp_IRQHandler,Default_Handler
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103x6.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103x6.s
deleted file mode 100644
index 1e033fb..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103x6.s
+++ /dev/null
@@ -1,363 +0,0 @@
-/**
- *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
- * @file startup_stm32f103x6.s
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @brief STM32F103x6 Devices vector table for Atollic toolchain.
- * This module performs:
- * - Set the initial SP
- * - Set the initial PC == Reset_Handler,
- * - Set the vector table entries with the exceptions ISR address
- * - Configure the clock system
- * - Branches to main in the C library (which eventually
- * calls main()).
- * After Reset the Cortex-M3 processor is in Thread mode,
- * priority is Privileged, and the Stack is set to Main.
- ******************************************************************************
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
- .syntax unified
- .cpu cortex-m3
- .fpu softvfp
- .thumb
-
-.global g_pfnVectors
-.global Default_Handler
-
-/* start address for the initialization values of the .data section.
-defined in linker script */
-.word _sidata
-/* start address for the .data section. defined in linker script */
-.word _sdata
-/* end address for the .data section. defined in linker script */
-.word _edata
-/* start address for the .bss section. defined in linker script */
-.word _sbss
-/* end address for the .bss section. defined in linker script */
-.word _ebss
-
-.equ BootRAM, 0xF108F85F
-/**
- * @brief This is the code that gets called when the processor first
- * starts execution following a reset event. Only the absolutely
- * necessary set is performed, after which the application
- * supplied main() routine is called.
- * @param None
- * @retval : None
-*/
-
- .section .text.Reset_Handler
- .weak Reset_Handler
- .type Reset_Handler, %function
-Reset_Handler:
-
-/* Copy the data segment initializers from flash to SRAM */
- movs r1, #0
- b LoopCopyDataInit
-
-CopyDataInit:
- ldr r3, =_sidata
- ldr r3, [r3, r1]
- str r3, [r0, r1]
- adds r1, r1, #4
-
-LoopCopyDataInit:
- ldr r0, =_sdata
- ldr r3, =_edata
- adds r2, r0, r1
- cmp r2, r3
- bcc CopyDataInit
- ldr r2, =_sbss
- b LoopFillZerobss
-/* Zero fill the bss segment. */
-FillZerobss:
- movs r3, #0
- str r3, [r2], #4
-
-LoopFillZerobss:
- ldr r3, = _ebss
- cmp r2, r3
- bcc FillZerobss
-
-/* Call the clock system intitialization function.*/
- bl SystemInit
-/* Call static constructors */
- bl __libc_init_array
-/* Call the application's entry point.*/
- bl main
- bx lr
-.size Reset_Handler, .-Reset_Handler
-
-/**
- * @brief This is the code that gets called when the processor receives an
- * unexpected interrupt. This simply enters an infinite loop, preserving
- * the system state for examination by a debugger.
- *
- * @param None
- * @retval : None
-*/
- .section .text.Default_Handler,"ax",%progbits
-Default_Handler:
-Infinite_Loop:
- b Infinite_Loop
- .size Default_Handler, .-Default_Handler
-/******************************************************************************
-*
-* The minimal vector table for a Cortex M3. Note that the proper constructs
-* must be placed on this to ensure that it ends up at physical address
-* 0x0000.0000.
-*
-******************************************************************************/
- .section .isr_vector,"a",%progbits
- .type g_pfnVectors, %object
- .size g_pfnVectors, .-g_pfnVectors
-
-
-g_pfnVectors:
-
- .word _estack
- .word Reset_Handler
- .word NMI_Handler
- .word HardFault_Handler
- .word MemManage_Handler
- .word BusFault_Handler
- .word UsageFault_Handler
- .word 0
- .word 0
- .word 0
- .word 0
- .word SVC_Handler
- .word DebugMon_Handler
- .word 0
- .word PendSV_Handler
- .word SysTick_Handler
- .word WWDG_IRQHandler
- .word PVD_IRQHandler
- .word TAMPER_IRQHandler
- .word RTC_IRQHandler
- .word FLASH_IRQHandler
- .word RCC_IRQHandler
- .word EXTI0_IRQHandler
- .word EXTI1_IRQHandler
- .word EXTI2_IRQHandler
- .word EXTI3_IRQHandler
- .word EXTI4_IRQHandler
- .word DMA1_Channel1_IRQHandler
- .word DMA1_Channel2_IRQHandler
- .word DMA1_Channel3_IRQHandler
- .word DMA1_Channel4_IRQHandler
- .word DMA1_Channel5_IRQHandler
- .word DMA1_Channel6_IRQHandler
- .word DMA1_Channel7_IRQHandler
- .word ADC1_2_IRQHandler
- .word USB_HP_CAN1_TX_IRQHandler
- .word USB_LP_CAN1_RX0_IRQHandler
- .word CAN1_RX1_IRQHandler
- .word CAN1_SCE_IRQHandler
- .word EXTI9_5_IRQHandler
- .word TIM1_BRK_IRQHandler
- .word TIM1_UP_IRQHandler
- .word TIM1_TRG_COM_IRQHandler
- .word TIM1_CC_IRQHandler
- .word TIM2_IRQHandler
- .word TIM3_IRQHandler
- .word 0
- .word I2C1_EV_IRQHandler
- .word I2C1_ER_IRQHandler
- .word 0
- .word 0
- .word SPI1_IRQHandler
- .word 0
- .word USART1_IRQHandler
- .word USART2_IRQHandler
- .word 0
- .word EXTI15_10_IRQHandler
- .word RTC_Alarm_IRQHandler
- .word USBWakeUp_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word BootRAM /* @0x108. This is for boot in RAM mode for
- STM32F10x Low Density devices.*/
-
-/*******************************************************************************
-*
-* Provide weak aliases for each Exception handler to the Default_Handler.
-* As they are weak aliases, any function with the same name will override
-* this definition.
-*
-*******************************************************************************/
-
- .weak NMI_Handler
- .thumb_set NMI_Handler,Default_Handler
-
- .weak HardFault_Handler
- .thumb_set HardFault_Handler,Default_Handler
-
- .weak MemManage_Handler
- .thumb_set MemManage_Handler,Default_Handler
-
- .weak BusFault_Handler
- .thumb_set BusFault_Handler,Default_Handler
-
- .weak UsageFault_Handler
- .thumb_set UsageFault_Handler,Default_Handler
-
- .weak SVC_Handler
- .thumb_set SVC_Handler,Default_Handler
-
- .weak DebugMon_Handler
- .thumb_set DebugMon_Handler,Default_Handler
-
- .weak PendSV_Handler
- .thumb_set PendSV_Handler,Default_Handler
-
- .weak SysTick_Handler
- .thumb_set SysTick_Handler,Default_Handler
-
- .weak WWDG_IRQHandler
- .thumb_set WWDG_IRQHandler,Default_Handler
-
- .weak PVD_IRQHandler
- .thumb_set PVD_IRQHandler,Default_Handler
-
- .weak TAMPER_IRQHandler
- .thumb_set TAMPER_IRQHandler,Default_Handler
-
- .weak RTC_IRQHandler
- .thumb_set RTC_IRQHandler,Default_Handler
-
- .weak FLASH_IRQHandler
- .thumb_set FLASH_IRQHandler,Default_Handler
-
- .weak RCC_IRQHandler
- .thumb_set RCC_IRQHandler,Default_Handler
-
- .weak EXTI0_IRQHandler
- .thumb_set EXTI0_IRQHandler,Default_Handler
-
- .weak EXTI1_IRQHandler
- .thumb_set EXTI1_IRQHandler,Default_Handler
-
- .weak EXTI2_IRQHandler
- .thumb_set EXTI2_IRQHandler,Default_Handler
-
- .weak EXTI3_IRQHandler
- .thumb_set EXTI3_IRQHandler,Default_Handler
-
- .weak EXTI4_IRQHandler
- .thumb_set EXTI4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel1_IRQHandler
- .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
-
- .weak DMA1_Channel2_IRQHandler
- .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
-
- .weak DMA1_Channel3_IRQHandler
- .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
-
- .weak DMA1_Channel4_IRQHandler
- .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel5_IRQHandler
- .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
-
- .weak DMA1_Channel6_IRQHandler
- .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
-
- .weak DMA1_Channel7_IRQHandler
- .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
-
- .weak ADC1_2_IRQHandler
- .thumb_set ADC1_2_IRQHandler,Default_Handler
-
- .weak USB_HP_CAN1_TX_IRQHandler
- .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
-
- .weak USB_LP_CAN1_RX0_IRQHandler
- .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
-
- .weak CAN1_RX1_IRQHandler
- .thumb_set CAN1_RX1_IRQHandler,Default_Handler
-
- .weak CAN1_SCE_IRQHandler
- .thumb_set CAN1_SCE_IRQHandler,Default_Handler
-
- .weak EXTI9_5_IRQHandler
- .thumb_set EXTI9_5_IRQHandler,Default_Handler
-
- .weak TIM1_BRK_IRQHandler
- .thumb_set TIM1_BRK_IRQHandler,Default_Handler
-
- .weak TIM1_UP_IRQHandler
- .thumb_set TIM1_UP_IRQHandler,Default_Handler
-
- .weak TIM1_TRG_COM_IRQHandler
- .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
-
- .weak TIM1_CC_IRQHandler
- .thumb_set TIM1_CC_IRQHandler,Default_Handler
-
- .weak TIM2_IRQHandler
- .thumb_set TIM2_IRQHandler,Default_Handler
-
- .weak TIM3_IRQHandler
- .thumb_set TIM3_IRQHandler,Default_Handler
-
- .weak I2C1_EV_IRQHandler
- .thumb_set I2C1_EV_IRQHandler,Default_Handler
-
- .weak I2C1_ER_IRQHandler
- .thumb_set I2C1_ER_IRQHandler,Default_Handler
-
- .weak SPI1_IRQHandler
- .thumb_set SPI1_IRQHandler,Default_Handler
-
- .weak USART1_IRQHandler
- .thumb_set USART1_IRQHandler,Default_Handler
-
- .weak USART2_IRQHandler
- .thumb_set USART2_IRQHandler,Default_Handler
-
- .weak EXTI15_10_IRQHandler
- .thumb_set EXTI15_10_IRQHandler,Default_Handler
-
- .weak RTC_Alarm_IRQHandler
- .thumb_set RTC_Alarm_IRQHandler,Default_Handler
-
- .weak USBWakeUp_IRQHandler
- .thumb_set USBWakeUp_IRQHandler,Default_Handler
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xb.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xb.s
deleted file mode 100644
index 1bdd524..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xb.s
+++ /dev/null
@@ -1,379 +0,0 @@
-/**
- *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
- * @file startup_stm32f103xb.s
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @brief STM32F103xB Devices vector table for Atollic toolchain.
- * This module performs:
- * - Set the initial SP
- * - Set the initial PC == Reset_Handler,
- * - Set the vector table entries with the exceptions ISR address
- * - Configure the clock system
- * - Branches to main in the C library (which eventually
- * calls main()).
- * After Reset the Cortex-M3 processor is in Thread mode,
- * priority is Privileged, and the Stack is set to Main.
- ******************************************************************************
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
- .syntax unified
- .cpu cortex-m3
- .fpu softvfp
- .thumb
-
-.global g_pfnVectors
-.global Default_Handler
-
-/* start address for the initialization values of the .data section.
-defined in linker script */
-.word _sidata
-/* start address for the .data section. defined in linker script */
-.word _sdata
-/* end address for the .data section. defined in linker script */
-.word _edata
-/* start address for the .bss section. defined in linker script */
-.word _sbss
-/* end address for the .bss section. defined in linker script */
-.word _ebss
-
-.equ BootRAM, 0xF108F85F
-/**
- * @brief This is the code that gets called when the processor first
- * starts execution following a reset event. Only the absolutely
- * necessary set is performed, after which the application
- * supplied main() routine is called.
- * @param None
- * @retval : None
-*/
-
- .section .text.Reset_Handler
- .weak Reset_Handler
- .type Reset_Handler, %function
-Reset_Handler:
-
-/* Copy the data segment initializers from flash to SRAM */
- movs r1, #0
- b LoopCopyDataInit
-
-CopyDataInit:
- ldr r3, =_sidata
- ldr r3, [r3, r1]
- str r3, [r0, r1]
- adds r1, r1, #4
-
-LoopCopyDataInit:
- ldr r0, =_sdata
- ldr r3, =_edata
- adds r2, r0, r1
- cmp r2, r3
- bcc CopyDataInit
- ldr r2, =_sbss
- b LoopFillZerobss
-/* Zero fill the bss segment. */
-FillZerobss:
- movs r3, #0
- str r3, [r2], #4
-
-LoopFillZerobss:
- ldr r3, = _ebss
- cmp r2, r3
- bcc FillZerobss
-
-/* Call the clock system intitialization function.*/
- bl SystemInit
-/* Call static constructors */
- bl __libc_init_array
-/* Call the application's entry point.*/
- bl main
- bx lr
-.size Reset_Handler, .-Reset_Handler
-
-/**
- * @brief This is the code that gets called when the processor receives an
- * unexpected interrupt. This simply enters an infinite loop, preserving
- * the system state for examination by a debugger.
- *
- * @param None
- * @retval : None
-*/
- .section .text.Default_Handler,"ax",%progbits
-Default_Handler:
-Infinite_Loop:
- b Infinite_Loop
- .size Default_Handler, .-Default_Handler
-/******************************************************************************
-*
-* The minimal vector table for a Cortex M3. Note that the proper constructs
-* must be placed on this to ensure that it ends up at physical address
-* 0x0000.0000.
-*
-******************************************************************************/
- .section .isr_vector,"a",%progbits
- .type g_pfnVectors, %object
- .size g_pfnVectors, .-g_pfnVectors
-
-
-g_pfnVectors:
-
- .word _estack
- .word Reset_Handler
- .word NMI_Handler
- .word HardFault_Handler
- .word MemManage_Handler
- .word BusFault_Handler
- .word UsageFault_Handler
- .word 0
- .word 0
- .word 0
- .word 0
- .word SVC_Handler
- .word DebugMon_Handler
- .word 0
- .word PendSV_Handler
- .word SysTick_Handler
- .word WWDG_IRQHandler
- .word PVD_IRQHandler
- .word TAMPER_IRQHandler
- .word RTC_IRQHandler
- .word FLASH_IRQHandler
- .word RCC_IRQHandler
- .word EXTI0_IRQHandler
- .word EXTI1_IRQHandler
- .word EXTI2_IRQHandler
- .word EXTI3_IRQHandler
- .word EXTI4_IRQHandler
- .word DMA1_Channel1_IRQHandler
- .word DMA1_Channel2_IRQHandler
- .word DMA1_Channel3_IRQHandler
- .word DMA1_Channel4_IRQHandler
- .word DMA1_Channel5_IRQHandler
- .word DMA1_Channel6_IRQHandler
- .word DMA1_Channel7_IRQHandler
- .word ADC1_2_IRQHandler
- .word USB_HP_CAN1_TX_IRQHandler
- .word USB_LP_CAN1_RX0_IRQHandler
- .word CAN1_RX1_IRQHandler
- .word CAN1_SCE_IRQHandler
- .word EXTI9_5_IRQHandler
- .word TIM1_BRK_IRQHandler
- .word TIM1_UP_IRQHandler
- .word TIM1_TRG_COM_IRQHandler
- .word TIM1_CC_IRQHandler
- .word TIM2_IRQHandler
- .word TIM3_IRQHandler
- .word TIM4_IRQHandler
- .word I2C1_EV_IRQHandler
- .word I2C1_ER_IRQHandler
- .word I2C2_EV_IRQHandler
- .word I2C2_ER_IRQHandler
- .word SPI1_IRQHandler
- .word SPI2_IRQHandler
- .word USART1_IRQHandler
- .word USART2_IRQHandler
- .word USART3_IRQHandler
- .word EXTI15_10_IRQHandler
- .word RTC_Alarm_IRQHandler
- .word USBWakeUp_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word BootRAM /* @0x108. This is for boot in RAM mode for
- STM32F10x Medium Density devices. */
-
-/*******************************************************************************
-*
-* Provide weak aliases for each Exception handler to the Default_Handler.
-* As they are weak aliases, any function with the same name will override
-* this definition.
-*
-*******************************************************************************/
-
- .weak NMI_Handler
- .thumb_set NMI_Handler,Default_Handler
-
- .weak HardFault_Handler
- .thumb_set HardFault_Handler,Default_Handler
-
- .weak MemManage_Handler
- .thumb_set MemManage_Handler,Default_Handler
-
- .weak BusFault_Handler
- .thumb_set BusFault_Handler,Default_Handler
-
- .weak UsageFault_Handler
- .thumb_set UsageFault_Handler,Default_Handler
-
- .weak SVC_Handler
- .thumb_set SVC_Handler,Default_Handler
-
- .weak DebugMon_Handler
- .thumb_set DebugMon_Handler,Default_Handler
-
- .weak PendSV_Handler
- .thumb_set PendSV_Handler,Default_Handler
-
- .weak SysTick_Handler
- .thumb_set SysTick_Handler,Default_Handler
-
- .weak WWDG_IRQHandler
- .thumb_set WWDG_IRQHandler,Default_Handler
-
- .weak PVD_IRQHandler
- .thumb_set PVD_IRQHandler,Default_Handler
-
- .weak TAMPER_IRQHandler
- .thumb_set TAMPER_IRQHandler,Default_Handler
-
- .weak RTC_IRQHandler
- .thumb_set RTC_IRQHandler,Default_Handler
-
- .weak FLASH_IRQHandler
- .thumb_set FLASH_IRQHandler,Default_Handler
-
- .weak RCC_IRQHandler
- .thumb_set RCC_IRQHandler,Default_Handler
-
- .weak EXTI0_IRQHandler
- .thumb_set EXTI0_IRQHandler,Default_Handler
-
- .weak EXTI1_IRQHandler
- .thumb_set EXTI1_IRQHandler,Default_Handler
-
- .weak EXTI2_IRQHandler
- .thumb_set EXTI2_IRQHandler,Default_Handler
-
- .weak EXTI3_IRQHandler
- .thumb_set EXTI3_IRQHandler,Default_Handler
-
- .weak EXTI4_IRQHandler
- .thumb_set EXTI4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel1_IRQHandler
- .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
-
- .weak DMA1_Channel2_IRQHandler
- .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
-
- .weak DMA1_Channel3_IRQHandler
- .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
-
- .weak DMA1_Channel4_IRQHandler
- .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel5_IRQHandler
- .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
-
- .weak DMA1_Channel6_IRQHandler
- .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
-
- .weak DMA1_Channel7_IRQHandler
- .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
-
- .weak ADC1_2_IRQHandler
- .thumb_set ADC1_2_IRQHandler,Default_Handler
-
- .weak USB_HP_CAN1_TX_IRQHandler
- .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
-
- .weak USB_LP_CAN1_RX0_IRQHandler
- .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
-
- .weak CAN1_RX1_IRQHandler
- .thumb_set CAN1_RX1_IRQHandler,Default_Handler
-
- .weak CAN1_SCE_IRQHandler
- .thumb_set CAN1_SCE_IRQHandler,Default_Handler
-
- .weak EXTI9_5_IRQHandler
- .thumb_set EXTI9_5_IRQHandler,Default_Handler
-
- .weak TIM1_BRK_IRQHandler
- .thumb_set TIM1_BRK_IRQHandler,Default_Handler
-
- .weak TIM1_UP_IRQHandler
- .thumb_set TIM1_UP_IRQHandler,Default_Handler
-
- .weak TIM1_TRG_COM_IRQHandler
- .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
-
- .weak TIM1_CC_IRQHandler
- .thumb_set TIM1_CC_IRQHandler,Default_Handler
-
- .weak TIM2_IRQHandler
- .thumb_set TIM2_IRQHandler,Default_Handler
-
- .weak TIM3_IRQHandler
- .thumb_set TIM3_IRQHandler,Default_Handler
-
- .weak TIM4_IRQHandler
- .thumb_set TIM4_IRQHandler,Default_Handler
-
- .weak I2C1_EV_IRQHandler
- .thumb_set I2C1_EV_IRQHandler,Default_Handler
-
- .weak I2C1_ER_IRQHandler
- .thumb_set I2C1_ER_IRQHandler,Default_Handler
-
- .weak I2C2_EV_IRQHandler
- .thumb_set I2C2_EV_IRQHandler,Default_Handler
-
- .weak I2C2_ER_IRQHandler
- .thumb_set I2C2_ER_IRQHandler,Default_Handler
-
- .weak SPI1_IRQHandler
- .thumb_set SPI1_IRQHandler,Default_Handler
-
- .weak SPI2_IRQHandler
- .thumb_set SPI2_IRQHandler,Default_Handler
-
- .weak USART1_IRQHandler
- .thumb_set USART1_IRQHandler,Default_Handler
-
- .weak USART2_IRQHandler
- .thumb_set USART2_IRQHandler,Default_Handler
-
- .weak USART3_IRQHandler
- .thumb_set USART3_IRQHandler,Default_Handler
-
- .weak EXTI15_10_IRQHandler
- .thumb_set EXTI15_10_IRQHandler,Default_Handler
-
- .weak RTC_Alarm_IRQHandler
- .thumb_set RTC_Alarm_IRQHandler,Default_Handler
-
- .weak USBWakeUp_IRQHandler
- .thumb_set USBWakeUp_IRQHandler,Default_Handler
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xe.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xe.s
deleted file mode 100644
index 0727d65..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xe.s
+++ /dev/null
@@ -1,485 +0,0 @@
-/**
- *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
- * @file startup_stm32f103xe.s
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @brief STM32F103xE Devices vector table for Atollic toolchain.
- * This module performs:
- * - Set the initial SP
- * - Set the initial PC == Reset_Handler,
- * - Set the vector table entries with the exceptions ISR address
- * - Configure the clock system
- * - Configure external SRAM mounted on STM3210E-EVAL board
- * to be used as data memory (optional, to be enabled by user)
- * - Branches to main in the C library (which eventually
- * calls main()).
- * After Reset the Cortex-M3 processor is in Thread mode,
- * priority is Privileged, and the Stack is set to Main.
- ******************************************************************************
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
- .syntax unified
- .cpu cortex-m3
- .fpu softvfp
- .thumb
-
-.global g_pfnVectors
-.global Default_Handler
-
-/* start address for the initialization values of the .data section.
-defined in linker script */
-.word _sidata
-/* start address for the .data section. defined in linker script */
-.word _sdata
-/* end address for the .data section. defined in linker script */
-.word _edata
-/* start address for the .bss section. defined in linker script */
-.word _sbss
-/* end address for the .bss section. defined in linker script */
-.word _ebss
-
-.equ BootRAM, 0xF1E0F85F
-/**
- * @brief This is the code that gets called when the processor first
- * starts execution following a reset event. Only the absolutely
- * necessary set is performed, after which the application
- * supplied main() routine is called.
- * @param None
- * @retval : None
-*/
-
- .section .text.Reset_Handler
- .weak Reset_Handler
- .type Reset_Handler, %function
-Reset_Handler:
-
-/* Copy the data segment initializers from flash to SRAM */
- movs r1, #0
- b LoopCopyDataInit
-
-CopyDataInit:
- ldr r3, =_sidata
- ldr r3, [r3, r1]
- str r3, [r0, r1]
- adds r1, r1, #4
-
-LoopCopyDataInit:
- ldr r0, =_sdata
- ldr r3, =_edata
- adds r2, r0, r1
- cmp r2, r3
- bcc CopyDataInit
- ldr r2, =_sbss
- b LoopFillZerobss
-/* Zero fill the bss segment. */
-FillZerobss:
- movs r3, #0
- str r3, [r2], #4
-
-LoopFillZerobss:
- ldr r3, = _ebss
- cmp r2, r3
- bcc FillZerobss
-
-/* Call the clock system intitialization function.*/
- bl SystemInit
-/* Call static constructors */
- bl __libc_init_array
-/* Call the application's entry point.*/
- bl main
- bx lr
-.size Reset_Handler, .-Reset_Handler
-
-/**
- * @brief This is the code that gets called when the processor receives an
- * unexpected interrupt. This simply enters an infinite loop, preserving
- * the system state for examination by a debugger.
- *
- * @param None
- * @retval : None
-*/
- .section .text.Default_Handler,"ax",%progbits
-Default_Handler:
-Infinite_Loop:
- b Infinite_Loop
- .size Default_Handler, .-Default_Handler
-/******************************************************************************
-*
-* The minimal vector table for a Cortex M3. Note that the proper constructs
-* must be placed on this to ensure that it ends up at physical address
-* 0x0000.0000.
-*
-******************************************************************************/
- .section .isr_vector,"a",%progbits
- .type g_pfnVectors, %object
- .size g_pfnVectors, .-g_pfnVectors
-
-
-g_pfnVectors:
-
- .word _estack
- .word Reset_Handler
- .word NMI_Handler
- .word HardFault_Handler
- .word MemManage_Handler
- .word BusFault_Handler
- .word UsageFault_Handler
- .word 0
- .word 0
- .word 0
- .word 0
- .word SVC_Handler
- .word DebugMon_Handler
- .word 0
- .word PendSV_Handler
- .word SysTick_Handler
- .word WWDG_IRQHandler
- .word PVD_IRQHandler
- .word TAMPER_IRQHandler
- .word RTC_IRQHandler
- .word FLASH_IRQHandler
- .word RCC_IRQHandler
- .word EXTI0_IRQHandler
- .word EXTI1_IRQHandler
- .word EXTI2_IRQHandler
- .word EXTI3_IRQHandler
- .word EXTI4_IRQHandler
- .word DMA1_Channel1_IRQHandler
- .word DMA1_Channel2_IRQHandler
- .word DMA1_Channel3_IRQHandler
- .word DMA1_Channel4_IRQHandler
- .word DMA1_Channel5_IRQHandler
- .word DMA1_Channel6_IRQHandler
- .word DMA1_Channel7_IRQHandler
- .word ADC1_2_IRQHandler
- .word USB_HP_CAN1_TX_IRQHandler
- .word USB_LP_CAN1_RX0_IRQHandler
- .word CAN1_RX1_IRQHandler
- .word CAN1_SCE_IRQHandler
- .word EXTI9_5_IRQHandler
- .word TIM1_BRK_IRQHandler
- .word TIM1_UP_IRQHandler
- .word TIM1_TRG_COM_IRQHandler
- .word TIM1_CC_IRQHandler
- .word TIM2_IRQHandler
- .word TIM3_IRQHandler
- .word TIM4_IRQHandler
- .word I2C1_EV_IRQHandler
- .word I2C1_ER_IRQHandler
- .word I2C2_EV_IRQHandler
- .word I2C2_ER_IRQHandler
- .word SPI1_IRQHandler
- .word SPI2_IRQHandler
- .word USART1_IRQHandler
- .word USART2_IRQHandler
- .word USART3_IRQHandler
- .word EXTI15_10_IRQHandler
- .word RTC_Alarm_IRQHandler
- .word USBWakeUp_IRQHandler
- .word TIM8_BRK_IRQHandler
- .word TIM8_UP_IRQHandler
- .word TIM8_TRG_COM_IRQHandler
- .word TIM8_CC_IRQHandler
- .word ADC3_IRQHandler
- .word FSMC_IRQHandler
- .word SDIO_IRQHandler
- .word TIM5_IRQHandler
- .word SPI3_IRQHandler
- .word UART4_IRQHandler
- .word UART5_IRQHandler
- .word TIM6_IRQHandler
- .word TIM7_IRQHandler
- .word DMA2_Channel1_IRQHandler
- .word DMA2_Channel2_IRQHandler
- .word DMA2_Channel3_IRQHandler
- .word DMA2_Channel4_5_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word BootRAM /* @0x1E0. This is for boot in RAM mode for
- STM32F10x High Density devices. */
-
-/*******************************************************************************
-*
-* Provide weak aliases for each Exception handler to the Default_Handler.
-* As they are weak aliases, any function with the same name will override
-* this definition.
-*
-*******************************************************************************/
-
- .weak NMI_Handler
- .thumb_set NMI_Handler,Default_Handler
-
- .weak HardFault_Handler
- .thumb_set HardFault_Handler,Default_Handler
-
- .weak MemManage_Handler
- .thumb_set MemManage_Handler,Default_Handler
-
- .weak BusFault_Handler
- .thumb_set BusFault_Handler,Default_Handler
-
- .weak UsageFault_Handler
- .thumb_set UsageFault_Handler,Default_Handler
-
- .weak SVC_Handler
- .thumb_set SVC_Handler,Default_Handler
-
- .weak DebugMon_Handler
- .thumb_set DebugMon_Handler,Default_Handler
-
- .weak PendSV_Handler
- .thumb_set PendSV_Handler,Default_Handler
-
- .weak SysTick_Handler
- .thumb_set SysTick_Handler,Default_Handler
-
- .weak WWDG_IRQHandler
- .thumb_set WWDG_IRQHandler,Default_Handler
-
- .weak PVD_IRQHandler
- .thumb_set PVD_IRQHandler,Default_Handler
-
- .weak TAMPER_IRQHandler
- .thumb_set TAMPER_IRQHandler,Default_Handler
-
- .weak RTC_IRQHandler
- .thumb_set RTC_IRQHandler,Default_Handler
-
- .weak FLASH_IRQHandler
- .thumb_set FLASH_IRQHandler,Default_Handler
-
- .weak RCC_IRQHandler
- .thumb_set RCC_IRQHandler,Default_Handler
-
- .weak EXTI0_IRQHandler
- .thumb_set EXTI0_IRQHandler,Default_Handler
-
- .weak EXTI1_IRQHandler
- .thumb_set EXTI1_IRQHandler,Default_Handler
-
- .weak EXTI2_IRQHandler
- .thumb_set EXTI2_IRQHandler,Default_Handler
-
- .weak EXTI3_IRQHandler
- .thumb_set EXTI3_IRQHandler,Default_Handler
-
- .weak EXTI4_IRQHandler
- .thumb_set EXTI4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel1_IRQHandler
- .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
-
- .weak DMA1_Channel2_IRQHandler
- .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
-
- .weak DMA1_Channel3_IRQHandler
- .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
-
- .weak DMA1_Channel4_IRQHandler
- .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel5_IRQHandler
- .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
-
- .weak DMA1_Channel6_IRQHandler
- .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
-
- .weak DMA1_Channel7_IRQHandler
- .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
-
- .weak ADC1_2_IRQHandler
- .thumb_set ADC1_2_IRQHandler,Default_Handler
-
- .weak USB_HP_CAN1_TX_IRQHandler
- .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
-
- .weak USB_LP_CAN1_RX0_IRQHandler
- .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
-
- .weak CAN1_RX1_IRQHandler
- .thumb_set CAN1_RX1_IRQHandler,Default_Handler
-
- .weak CAN1_SCE_IRQHandler
- .thumb_set CAN1_SCE_IRQHandler,Default_Handler
-
- .weak EXTI9_5_IRQHandler
- .thumb_set EXTI9_5_IRQHandler,Default_Handler
-
- .weak TIM1_BRK_IRQHandler
- .thumb_set TIM1_BRK_IRQHandler,Default_Handler
-
- .weak TIM1_UP_IRQHandler
- .thumb_set TIM1_UP_IRQHandler,Default_Handler
-
- .weak TIM1_TRG_COM_IRQHandler
- .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
-
- .weak TIM1_CC_IRQHandler
- .thumb_set TIM1_CC_IRQHandler,Default_Handler
-
- .weak TIM2_IRQHandler
- .thumb_set TIM2_IRQHandler,Default_Handler
-
- .weak TIM3_IRQHandler
- .thumb_set TIM3_IRQHandler,Default_Handler
-
- .weak TIM4_IRQHandler
- .thumb_set TIM4_IRQHandler,Default_Handler
-
- .weak I2C1_EV_IRQHandler
- .thumb_set I2C1_EV_IRQHandler,Default_Handler
-
- .weak I2C1_ER_IRQHandler
- .thumb_set I2C1_ER_IRQHandler,Default_Handler
-
- .weak I2C2_EV_IRQHandler
- .thumb_set I2C2_EV_IRQHandler,Default_Handler
-
- .weak I2C2_ER_IRQHandler
- .thumb_set I2C2_ER_IRQHandler,Default_Handler
-
- .weak SPI1_IRQHandler
- .thumb_set SPI1_IRQHandler,Default_Handler
-
- .weak SPI2_IRQHandler
- .thumb_set SPI2_IRQHandler,Default_Handler
-
- .weak USART1_IRQHandler
- .thumb_set USART1_IRQHandler,Default_Handler
-
- .weak USART2_IRQHandler
- .thumb_set USART2_IRQHandler,Default_Handler
-
- .weak USART3_IRQHandler
- .thumb_set USART3_IRQHandler,Default_Handler
-
- .weak EXTI15_10_IRQHandler
- .thumb_set EXTI15_10_IRQHandler,Default_Handler
-
- .weak RTC_Alarm_IRQHandler
- .thumb_set RTC_Alarm_IRQHandler,Default_Handler
-
- .weak USBWakeUp_IRQHandler
- .thumb_set USBWakeUp_IRQHandler,Default_Handler
-
- .weak TIM8_BRK_IRQHandler
- .thumb_set TIM8_BRK_IRQHandler,Default_Handler
-
- .weak TIM8_UP_IRQHandler
- .thumb_set TIM8_UP_IRQHandler,Default_Handler
-
- .weak TIM8_TRG_COM_IRQHandler
- .thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler
-
- .weak TIM8_CC_IRQHandler
- .thumb_set TIM8_CC_IRQHandler,Default_Handler
-
- .weak ADC3_IRQHandler
- .thumb_set ADC3_IRQHandler,Default_Handler
-
- .weak FSMC_IRQHandler
- .thumb_set FSMC_IRQHandler,Default_Handler
-
- .weak SDIO_IRQHandler
- .thumb_set SDIO_IRQHandler,Default_Handler
-
- .weak TIM5_IRQHandler
- .thumb_set TIM5_IRQHandler,Default_Handler
-
- .weak SPI3_IRQHandler
- .thumb_set SPI3_IRQHandler,Default_Handler
-
- .weak UART4_IRQHandler
- .thumb_set UART4_IRQHandler,Default_Handler
-
- .weak UART5_IRQHandler
- .thumb_set UART5_IRQHandler,Default_Handler
-
- .weak TIM6_IRQHandler
- .thumb_set TIM6_IRQHandler,Default_Handler
-
- .weak TIM7_IRQHandler
- .thumb_set TIM7_IRQHandler,Default_Handler
-
- .weak DMA2_Channel1_IRQHandler
- .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
-
- .weak DMA2_Channel2_IRQHandler
- .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
-
- .weak DMA2_Channel3_IRQHandler
- .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
-
- .weak DMA2_Channel4_5_IRQHandler
- .thumb_set DMA2_Channel4_5_IRQHandler,Default_Handler
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xg.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xg.s
deleted file mode 100644
index 1ae0faf..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xg.s
+++ /dev/null
@@ -1,482 +0,0 @@
-/**
- *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
- * @file startup_stm32f103xb.s
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @brief STM32F103xB Devices vector table for Atollic toolchain.
- * This module performs:
- * - Set the initial SP
- * - Set the initial PC == Reset_Handler,
- * - Set the vector table entries with the exceptions ISR address
- * - Configure the clock system
- * - Branches to main in the C library (which eventually
- * calls main()).
- * After Reset the Cortex-M3 processor is in Thread mode,
- * priority is Privileged, and the Stack is set to Main.
- ******************************************************************************
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
- .syntax unified
- .cpu cortex-m3
- .fpu softvfp
- .thumb
-
-.global g_pfnVectors
-.global Default_Handler
-
-/* start address for the initialization values of the .data section.
-defined in linker script */
-.word _sidata
-/* start address for the .data section. defined in linker script */
-.word _sdata
-/* end address for the .data section. defined in linker script */
-.word _edata
-/* start address for the .bss section. defined in linker script */
-.word _sbss
-/* end address for the .bss section. defined in linker script */
-.word _ebss
-
-.equ BootRAM, 0xF1E0F85F
-/**
- * @brief This is the code that gets called when the processor first
- * starts execution following a reset event. Only the absolutely
- * necessary set is performed, after which the application
- * supplied main() routine is called.
- * @param None
- * @retval : None
-*/
-
- .section .text.Reset_Handler
- .weak Reset_Handler
- .type Reset_Handler, %function
-Reset_Handler:
-
-/* Copy the data segment initializers from flash to SRAM */
- movs r1, #0
- b LoopCopyDataInit
-
-CopyDataInit:
- ldr r3, =_sidata
- ldr r3, [r3, r1]
- str r3, [r0, r1]
- adds r1, r1, #4
-
-LoopCopyDataInit:
- ldr r0, =_sdata
- ldr r3, =_edata
- adds r2, r0, r1
- cmp r2, r3
- bcc CopyDataInit
- ldr r2, =_sbss
- b LoopFillZerobss
-
-/* Zero fill the bss segment. */
-FillZerobss:
- movs r3, #0
- str r3, [r2], #4
-
-LoopFillZerobss:
- ldr r3, = _ebss
- cmp r2, r3
- bcc FillZerobss
-
-/* Call the clock system intitialization function.*/
- bl SystemInit
-/* Call static constructors */
- bl __libc_init_array
-/* Call the application's entry point.*/
- bl main
- bx lr
-.size Reset_Handler, .-Reset_Handler
-
-/**
- * @brief This is the code that gets called when the processor receives an
- * unexpected interrupt. This simply enters an infinite loop, preserving
- * the system state for examination by a debugger.
- * @param None
- * @retval None
-*/
- .section .text.Default_Handler,"ax",%progbits
-Default_Handler:
-Infinite_Loop:
- b Infinite_Loop
- .size Default_Handler, .-Default_Handler
-/******************************************************************************
-*
-* The minimal vector table for a Cortex M3. Note that the proper constructs
-* must be placed on this to ensure that it ends up at physical address
-* 0x0000.0000.
-*
-*******************************************************************************/
- .section .isr_vector,"a",%progbits
- .type g_pfnVectors, %object
- .size g_pfnVectors, .-g_pfnVectors
-
-
-g_pfnVectors:
-
- .word _estack
- .word Reset_Handler
- .word NMI_Handler
- .word HardFault_Handler
- .word MemManage_Handler
- .word BusFault_Handler
- .word UsageFault_Handler
- .word 0
- .word 0
- .word 0
- .word 0
- .word SVC_Handler
- .word DebugMon_Handler
- .word 0
- .word PendSV_Handler
- .word SysTick_Handler
- .word WWDG_IRQHandler
- .word PVD_IRQHandler
- .word TAMPER_IRQHandler
- .word RTC_IRQHandler
- .word FLASH_IRQHandler
- .word RCC_IRQHandler
- .word EXTI0_IRQHandler
- .word EXTI1_IRQHandler
- .word EXTI2_IRQHandler
- .word EXTI3_IRQHandler
- .word EXTI4_IRQHandler
- .word DMA1_Channel1_IRQHandler
- .word DMA1_Channel2_IRQHandler
- .word DMA1_Channel3_IRQHandler
- .word DMA1_Channel4_IRQHandler
- .word DMA1_Channel5_IRQHandler
- .word DMA1_Channel6_IRQHandler
- .word DMA1_Channel7_IRQHandler
- .word ADC1_2_IRQHandler
- .word USB_HP_CAN1_TX_IRQHandler
- .word USB_LP_CAN1_RX0_IRQHandler
- .word CAN1_RX1_IRQHandler
- .word CAN1_SCE_IRQHandler
- .word EXTI9_5_IRQHandler
- .word TIM1_BRK_TIM9_IRQHandler
- .word TIM1_UP_TIM10_IRQHandler
- .word TIM1_TRG_COM_TIM11_IRQHandler
- .word TIM1_CC_IRQHandler
- .word TIM2_IRQHandler
- .word TIM3_IRQHandler
- .word TIM4_IRQHandler
- .word I2C1_EV_IRQHandler
- .word I2C1_ER_IRQHandler
- .word I2C2_EV_IRQHandler
- .word I2C2_ER_IRQHandler
- .word SPI1_IRQHandler
- .word SPI2_IRQHandler
- .word USART1_IRQHandler
- .word USART2_IRQHandler
- .word USART3_IRQHandler
- .word EXTI15_10_IRQHandler
- .word RTC_Alarm_IRQHandler
- .word USBWakeUp_IRQHandler
- .word TIM8_BRK_TIM12_IRQHandler
- .word TIM8_UP_TIM13_IRQHandler
- .word TIM8_TRG_COM_TIM14_IRQHandler
- .word TIM8_CC_IRQHandler
- .word ADC3_IRQHandler
- .word FSMC_IRQHandler
- .word SDIO_IRQHandler
- .word TIM5_IRQHandler
- .word SPI3_IRQHandler
- .word UART4_IRQHandler
- .word UART5_IRQHandler
- .word TIM6_IRQHandler
- .word TIM7_IRQHandler
- .word DMA2_Channel1_IRQHandler
- .word DMA2_Channel2_IRQHandler
- .word DMA2_Channel3_IRQHandler
- .word DMA2_Channel4_5_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word BootRAM /* @0x1E0. This is for boot in RAM mode for
- STM32F10x XL-Density devices. */
-/*******************************************************************************
-*
-* Provide weak aliases for each Exception handler to the Default_Handler.
-* As they are weak aliases, any function with the same name will override
-* this definition.
-*
-*******************************************************************************/
-
- .weak NMI_Handler
- .thumb_set NMI_Handler,Default_Handler
-
- .weak HardFault_Handler
- .thumb_set HardFault_Handler,Default_Handler
-
- .weak MemManage_Handler
- .thumb_set MemManage_Handler,Default_Handler
-
- .weak BusFault_Handler
- .thumb_set BusFault_Handler,Default_Handler
-
- .weak UsageFault_Handler
- .thumb_set UsageFault_Handler,Default_Handler
-
- .weak SVC_Handler
- .thumb_set SVC_Handler,Default_Handler
-
- .weak DebugMon_Handler
- .thumb_set DebugMon_Handler,Default_Handler
-
- .weak PendSV_Handler
- .thumb_set PendSV_Handler,Default_Handler
-
- .weak SysTick_Handler
- .thumb_set SysTick_Handler,Default_Handler
-
- .weak WWDG_IRQHandler
- .thumb_set WWDG_IRQHandler,Default_Handler
-
- .weak PVD_IRQHandler
- .thumb_set PVD_IRQHandler,Default_Handler
-
- .weak TAMPER_IRQHandler
- .thumb_set TAMPER_IRQHandler,Default_Handler
-
- .weak RTC_IRQHandler
- .thumb_set RTC_IRQHandler,Default_Handler
-
- .weak FLASH_IRQHandler
- .thumb_set FLASH_IRQHandler,Default_Handler
-
- .weak RCC_IRQHandler
- .thumb_set RCC_IRQHandler,Default_Handler
-
- .weak EXTI0_IRQHandler
- .thumb_set EXTI0_IRQHandler,Default_Handler
-
- .weak EXTI1_IRQHandler
- .thumb_set EXTI1_IRQHandler,Default_Handler
-
- .weak EXTI2_IRQHandler
- .thumb_set EXTI2_IRQHandler,Default_Handler
-
- .weak EXTI3_IRQHandler
- .thumb_set EXTI3_IRQHandler,Default_Handler
-
- .weak EXTI4_IRQHandler
- .thumb_set EXTI4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel1_IRQHandler
- .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
-
- .weak DMA1_Channel2_IRQHandler
- .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
-
- .weak DMA1_Channel3_IRQHandler
- .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
-
- .weak DMA1_Channel4_IRQHandler
- .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel5_IRQHandler
- .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
-
- .weak DMA1_Channel6_IRQHandler
- .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
-
- .weak DMA1_Channel7_IRQHandler
- .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
-
- .weak ADC1_2_IRQHandler
- .thumb_set ADC1_2_IRQHandler,Default_Handler
-
- .weak USB_HP_CAN1_TX_IRQHandler
- .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
-
- .weak USB_LP_CAN1_RX0_IRQHandler
- .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
-
- .weak CAN1_RX1_IRQHandler
- .thumb_set CAN1_RX1_IRQHandler,Default_Handler
-
- .weak CAN1_SCE_IRQHandler
- .thumb_set CAN1_SCE_IRQHandler,Default_Handler
-
- .weak EXTI9_5_IRQHandler
- .thumb_set EXTI9_5_IRQHandler,Default_Handler
-
- .weak TIM1_BRK_TIM9_IRQHandler
- .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler
-
- .weak TIM1_UP_TIM10_IRQHandler
- .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler
-
- .weak TIM1_TRG_COM_TIM11_IRQHandler
- .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler
-
- .weak TIM1_CC_IRQHandler
- .thumb_set TIM1_CC_IRQHandler,Default_Handler
-
- .weak TIM2_IRQHandler
- .thumb_set TIM2_IRQHandler,Default_Handler
-
- .weak TIM3_IRQHandler
- .thumb_set TIM3_IRQHandler,Default_Handler
-
- .weak TIM4_IRQHandler
- .thumb_set TIM4_IRQHandler,Default_Handler
-
- .weak I2C1_EV_IRQHandler
- .thumb_set I2C1_EV_IRQHandler,Default_Handler
-
- .weak I2C1_ER_IRQHandler
- .thumb_set I2C1_ER_IRQHandler,Default_Handler
-
- .weak I2C2_EV_IRQHandler
- .thumb_set I2C2_EV_IRQHandler,Default_Handler
-
- .weak I2C2_ER_IRQHandler
- .thumb_set I2C2_ER_IRQHandler,Default_Handler
-
- .weak SPI1_IRQHandler
- .thumb_set SPI1_IRQHandler,Default_Handler
-
- .weak SPI2_IRQHandler
- .thumb_set SPI2_IRQHandler,Default_Handler
-
- .weak USART1_IRQHandler
- .thumb_set USART1_IRQHandler,Default_Handler
-
- .weak USART2_IRQHandler
- .thumb_set USART2_IRQHandler,Default_Handler
-
- .weak USART3_IRQHandler
- .thumb_set USART3_IRQHandler,Default_Handler
-
- .weak EXTI15_10_IRQHandler
- .thumb_set EXTI15_10_IRQHandler,Default_Handler
-
- .weak RTC_Alarm_IRQHandler
- .thumb_set RTC_Alarm_IRQHandler,Default_Handler
-
- .weak USBWakeUp_IRQHandler
- .thumb_set USBWakeUp_IRQHandler,Default_Handler
-
- .weak TIM8_BRK_TIM12_IRQHandler
- .thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler
-
- .weak TIM8_UP_TIM13_IRQHandler
- .thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler
-
- .weak TIM8_TRG_COM_TIM14_IRQHandler
- .thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler
-
- .weak TIM8_CC_IRQHandler
- .thumb_set TIM8_CC_IRQHandler,Default_Handler
-
- .weak ADC3_IRQHandler
- .thumb_set ADC3_IRQHandler,Default_Handler
-
- .weak FSMC_IRQHandler
- .thumb_set FSMC_IRQHandler,Default_Handler
-
- .weak SDIO_IRQHandler
- .thumb_set SDIO_IRQHandler,Default_Handler
-
- .weak TIM5_IRQHandler
- .thumb_set TIM5_IRQHandler,Default_Handler
-
- .weak SPI3_IRQHandler
- .thumb_set SPI3_IRQHandler,Default_Handler
-
- .weak UART4_IRQHandler
- .thumb_set UART4_IRQHandler,Default_Handler
-
- .weak UART5_IRQHandler
- .thumb_set UART5_IRQHandler,Default_Handler
-
- .weak TIM6_IRQHandler
- .thumb_set TIM6_IRQHandler,Default_Handler
-
- .weak TIM7_IRQHandler
- .thumb_set TIM7_IRQHandler,Default_Handler
-
- .weak DMA2_Channel1_IRQHandler
- .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
-
- .weak DMA2_Channel2_IRQHandler
- .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
-
- .weak DMA2_Channel3_IRQHandler
- .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
-
- .weak DMA2_Channel4_5_IRQHandler
- .thumb_set DMA2_Channel4_5_IRQHandler,Default_Handler
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f105xc.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f105xc.s
deleted file mode 100644
index dc57f1d..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f105xc.s
+++ /dev/null
@@ -1,476 +0,0 @@
-/**
- *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
- * @file startup_stm32f105xc.s
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @brief STM32F105xC Devices vector table for Atollic toolchain.
- * This module performs:
- * - Set the initial SP
- * - Set the initial PC == Reset_Handler,
- * - Set the vector table entries with the exceptions ISR address
- * - Configure the clock system
- * - Branches to main in the C library (which eventually
- * calls main()).
- * After Reset the Cortex-M3 processor is in Thread mode,
- * priority is Privileged, and the Stack is set to Main.
- ******************************************************************************
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
- .syntax unified
- .cpu cortex-m3
- .fpu softvfp
- .thumb
-
-.global g_pfnVectors
-.global Default_Handler
-
-/* start address for the initialization values of the .data section.
-defined in linker script */
-.word _sidata
-/* start address for the .data section. defined in linker script */
-.word _sdata
-/* end address for the .data section. defined in linker script */
-.word _edata
-/* start address for the .bss section. defined in linker script */
-.word _sbss
-/* end address for the .bss section. defined in linker script */
-.word _ebss
-
-.equ BootRAM, 0xF1E0F85F
-/**
- * @brief This is the code that gets called when the processor first
- * starts execution following a reset event. Only the absolutely
- * necessary set is performed, after which the application
- * supplied main() routine is called.
- * @param None
- * @retval : None
-*/
-
- .section .text.Reset_Handler
- .weak Reset_Handler
- .type Reset_Handler, %function
-Reset_Handler:
-
-/* Copy the data segment initializers from flash to SRAM */
- movs r1, #0
- b LoopCopyDataInit
-
-CopyDataInit:
- ldr r3, =_sidata
- ldr r3, [r3, r1]
- str r3, [r0, r1]
- adds r1, r1, #4
-
-LoopCopyDataInit:
- ldr r0, =_sdata
- ldr r3, =_edata
- adds r2, r0, r1
- cmp r2, r3
- bcc CopyDataInit
- ldr r2, =_sbss
- b LoopFillZerobss
-
-/* Zero fill the bss segment. */
-FillZerobss:
- movs r3, #0
- str r3, [r2], #4
-
-LoopFillZerobss:
- ldr r3, = _ebss
- cmp r2, r3
- bcc FillZerobss
-/* Call the clock system intitialization function.*/
- bl SystemInit
-/* Call the application's entry point.*/
- bl main
- bx lr
-.size Reset_Handler, .-Reset_Handler
-
-/**
- * @brief This is the code that gets called when the processor receives an
- * unexpected interrupt. This simply enters an infinite loop, preserving
- * the system state for examination by a debugger.
- * @param None
- * @retval None
-*/
- .section .text.Default_Handler,"ax",%progbits
-Default_Handler:
-Infinite_Loop:
- b Infinite_Loop
- .size Default_Handler, .-Default_Handler
-/******************************************************************************
-*
-* The minimal vector table for a Cortex M3. Note that the proper constructs
-* must be placed on this to ensure that it ends up at physical address
-* 0x0000.0000.
-*
-******************************************************************************/
- .section .isr_vector,"a",%progbits
- .type g_pfnVectors, %object
- .size g_pfnVectors, .-g_pfnVectors
-
-
-g_pfnVectors:
-
- .word _estack
- .word Reset_Handler
- .word NMI_Handler
- .word HardFault_Handler
- .word MemManage_Handler
- .word BusFault_Handler
- .word UsageFault_Handler
- .word 0
- .word 0
- .word 0
- .word 0
- .word SVC_Handler
- .word DebugMon_Handler
- .word 0
- .word PendSV_Handler
- .word SysTick_Handler
- .word WWDG_IRQHandler
- .word PVD_IRQHandler
- .word TAMPER_IRQHandler
- .word RTC_IRQHandler
- .word FLASH_IRQHandler
- .word RCC_IRQHandler
- .word EXTI0_IRQHandler
- .word EXTI1_IRQHandler
- .word EXTI2_IRQHandler
- .word EXTI3_IRQHandler
- .word EXTI4_IRQHandler
- .word DMA1_Channel1_IRQHandler
- .word DMA1_Channel2_IRQHandler
- .word DMA1_Channel3_IRQHandler
- .word DMA1_Channel4_IRQHandler
- .word DMA1_Channel5_IRQHandler
- .word DMA1_Channel6_IRQHandler
- .word DMA1_Channel7_IRQHandler
- .word ADC1_2_IRQHandler
- .word CAN1_TX_IRQHandler
- .word CAN1_RX0_IRQHandler
- .word CAN1_RX1_IRQHandler
- .word CAN1_SCE_IRQHandler
- .word EXTI9_5_IRQHandler
- .word TIM1_BRK_IRQHandler
- .word TIM1_UP_IRQHandler
- .word TIM1_TRG_COM_IRQHandler
- .word TIM1_CC_IRQHandler
- .word TIM2_IRQHandler
- .word TIM3_IRQHandler
- .word TIM4_IRQHandler
- .word I2C1_EV_IRQHandler
- .word I2C1_ER_IRQHandler
- .word I2C2_EV_IRQHandler
- .word I2C2_ER_IRQHandler
- .word SPI1_IRQHandler
- .word SPI2_IRQHandler
- .word USART1_IRQHandler
- .word USART2_IRQHandler
- .word USART3_IRQHandler
- .word EXTI15_10_IRQHandler
- .word RTC_Alarm_IRQHandler
- .word OTG_FS_WKUP_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word TIM5_IRQHandler
- .word SPI3_IRQHandler
- .word UART4_IRQHandler
- .word UART5_IRQHandler
- .word TIM6_IRQHandler
- .word TIM7_IRQHandler
- .word DMA2_Channel1_IRQHandler
- .word DMA2_Channel2_IRQHandler
- .word DMA2_Channel3_IRQHandler
- .word DMA2_Channel4_IRQHandler
- .word DMA2_Channel5_IRQHandler
- .word 0
- .word 0
- .word CAN2_TX_IRQHandler
- .word CAN2_RX0_IRQHandler
- .word CAN2_RX1_IRQHandler
- .word CAN2_SCE_IRQHandler
- .word OTG_FS_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word BootRAM /* @0x1E0. This is for boot in RAM mode for
- STM32F10x Connectivity line Devices. */
-
-/*******************************************************************************
-*
-* Provide weak aliases for each Exception handler to the Default_Handler.
-* As they are weak aliases, any function with the same name will override
-* this definition.
-*
-*******************************************************************************/
- .weak NMI_Handler
- .thumb_set NMI_Handler,Default_Handler
-
- .weak HardFault_Handler
- .thumb_set HardFault_Handler,Default_Handler
-
- .weak MemManage_Handler
- .thumb_set MemManage_Handler,Default_Handler
-
- .weak BusFault_Handler
- .thumb_set BusFault_Handler,Default_Handler
-
- .weak UsageFault_Handler
- .thumb_set UsageFault_Handler,Default_Handler
-
- .weak SVC_Handler
- .thumb_set SVC_Handler,Default_Handler
-
- .weak DebugMon_Handler
- .thumb_set DebugMon_Handler,Default_Handler
-
- .weak PendSV_Handler
- .thumb_set PendSV_Handler,Default_Handler
-
- .weak SysTick_Handler
- .thumb_set SysTick_Handler,Default_Handler
-
- .weak WWDG_IRQHandler
- .thumb_set WWDG_IRQHandler,Default_Handler
-
- .weak PVD_IRQHandler
- .thumb_set PVD_IRQHandler,Default_Handler
-
- .weak TAMPER_IRQHandler
- .thumb_set TAMPER_IRQHandler,Default_Handler
-
- .weak RTC_IRQHandler
- .thumb_set RTC_IRQHandler,Default_Handler
-
- .weak FLASH_IRQHandler
- .thumb_set FLASH_IRQHandler,Default_Handler
-
- .weak RCC_IRQHandler
- .thumb_set RCC_IRQHandler,Default_Handler
-
- .weak EXTI0_IRQHandler
- .thumb_set EXTI0_IRQHandler,Default_Handler
-
- .weak EXTI1_IRQHandler
- .thumb_set EXTI1_IRQHandler,Default_Handler
-
- .weak EXTI2_IRQHandler
- .thumb_set EXTI2_IRQHandler,Default_Handler
-
- .weak EXTI3_IRQHandler
- .thumb_set EXTI3_IRQHandler,Default_Handler
-
- .weak EXTI4_IRQHandler
- .thumb_set EXTI4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel1_IRQHandler
- .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
-
- .weak DMA1_Channel2_IRQHandler
- .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
-
- .weak DMA1_Channel3_IRQHandler
- .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
-
- .weak DMA1_Channel4_IRQHandler
- .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel5_IRQHandler
- .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
-
- .weak DMA1_Channel6_IRQHandler
- .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
-
- .weak DMA1_Channel7_IRQHandler
- .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
-
- .weak ADC1_2_IRQHandler
- .thumb_set ADC1_2_IRQHandler,Default_Handler
-
- .weak CAN1_TX_IRQHandler
- .thumb_set CAN1_TX_IRQHandler,Default_Handler
-
- .weak CAN1_RX0_IRQHandler
- .thumb_set CAN1_RX0_IRQHandler,Default_Handler
-
- .weak CAN1_RX1_IRQHandler
- .thumb_set CAN1_RX1_IRQHandler,Default_Handler
-
- .weak CAN1_SCE_IRQHandler
- .thumb_set CAN1_SCE_IRQHandler,Default_Handler
-
- .weak EXTI9_5_IRQHandler
- .thumb_set EXTI9_5_IRQHandler,Default_Handler
-
- .weak TIM1_BRK_IRQHandler
- .thumb_set TIM1_BRK_IRQHandler,Default_Handler
-
- .weak TIM1_UP_IRQHandler
- .thumb_set TIM1_UP_IRQHandler,Default_Handler
-
- .weak TIM1_TRG_COM_IRQHandler
- .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
-
- .weak TIM1_CC_IRQHandler
- .thumb_set TIM1_CC_IRQHandler,Default_Handler
-
- .weak TIM2_IRQHandler
- .thumb_set TIM2_IRQHandler,Default_Handler
-
- .weak TIM3_IRQHandler
- .thumb_set TIM3_IRQHandler,Default_Handler
-
- .weak TIM4_IRQHandler
- .thumb_set TIM4_IRQHandler,Default_Handler
-
- .weak I2C1_EV_IRQHandler
- .thumb_set I2C1_EV_IRQHandler,Default_Handler
-
- .weak I2C1_ER_IRQHandler
- .thumb_set I2C1_ER_IRQHandler,Default_Handler
-
- .weak I2C2_EV_IRQHandler
- .thumb_set I2C2_EV_IRQHandler,Default_Handler
-
- .weak I2C2_ER_IRQHandler
- .thumb_set I2C2_ER_IRQHandler,Default_Handler
-
- .weak SPI1_IRQHandler
- .thumb_set SPI1_IRQHandler,Default_Handler
-
- .weak SPI2_IRQHandler
- .thumb_set SPI2_IRQHandler,Default_Handler
-
- .weak USART1_IRQHandler
- .thumb_set USART1_IRQHandler,Default_Handler
-
- .weak USART2_IRQHandler
- .thumb_set USART2_IRQHandler,Default_Handler
-
- .weak USART3_IRQHandler
- .thumb_set USART3_IRQHandler,Default_Handler
-
- .weak EXTI15_10_IRQHandler
- .thumb_set EXTI15_10_IRQHandler,Default_Handler
-
- .weak RTC_Alarm_IRQHandler
- .thumb_set RTC_Alarm_IRQHandler,Default_Handler
-
- .weak OTG_FS_WKUP_IRQHandler
- .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
-
- .weak TIM5_IRQHandler
- .thumb_set TIM5_IRQHandler,Default_Handler
-
- .weak SPI3_IRQHandler
- .thumb_set SPI3_IRQHandler,Default_Handler
-
- .weak UART4_IRQHandler
- .thumb_set UART4_IRQHandler,Default_Handler
-
- .weak UART5_IRQHandler
- .thumb_set UART5_IRQHandler,Default_Handler
-
- .weak TIM6_IRQHandler
- .thumb_set TIM6_IRQHandler,Default_Handler
-
- .weak TIM7_IRQHandler
- .thumb_set TIM7_IRQHandler,Default_Handler
-
- .weak DMA2_Channel1_IRQHandler
- .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
-
- .weak DMA2_Channel2_IRQHandler
- .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
-
- .weak DMA2_Channel3_IRQHandler
- .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
-
- .weak DMA2_Channel4_IRQHandler
- .thumb_set DMA2_Channel4_IRQHandler,Default_Handler
-
- .weak DMA2_Channel5_IRQHandler
- .thumb_set DMA2_Channel5_IRQHandler,Default_Handler
-
- .weak CAN2_TX_IRQHandler
- .thumb_set CAN2_TX_IRQHandler,Default_Handler
-
- .weak CAN2_RX0_IRQHandler
- .thumb_set CAN2_RX0_IRQHandler,Default_Handler
-
- .weak CAN2_RX1_IRQHandler
- .thumb_set CAN2_RX1_IRQHandler,Default_Handler
-
- .weak CAN2_SCE_IRQHandler
- .thumb_set CAN2_SCE_IRQHandler,Default_Handler
-
- .weak OTG_FS_IRQHandler
- .thumb_set OTG_FS_IRQHandler ,Default_Handler
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f107xc.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f107xc.s
deleted file mode 100644
index 35bf316..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f107xc.s
+++ /dev/null
@@ -1,487 +0,0 @@
-/**
- *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
- * @file startup_stm32f107xc.s
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @brief STM32F107xC Devices vector table for Atollic toolchain.
- * This module performs:
- * - Set the initial SP
- * - Set the initial PC == Reset_Handler,
- * - Set the vector table entries with the exceptions ISR address
- * - Configure the clock system
- * - Branches to main in the C library (which eventually
- * calls main()).
- * After Reset the Cortex-M3 processor is in Thread mode,
- * priority is Privileged, and the Stack is set to Main.
- ******************************************************************************
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
- .syntax unified
- .cpu cortex-m3
- .fpu softvfp
- .thumb
-
-.global g_pfnVectors
-.global Default_Handler
-
-/* start address for the initialization values of the .data section.
-defined in linker script */
-.word _sidata
-/* start address for the .data section. defined in linker script */
-.word _sdata
-/* end address for the .data section. defined in linker script */
-.word _edata
-/* start address for the .bss section. defined in linker script */
-.word _sbss
-/* end address for the .bss section. defined in linker script */
-.word _ebss
-
-.equ BootRAM, 0xF1E0F85F
-/**
- * @brief This is the code that gets called when the processor first
- * starts execution following a reset event. Only the absolutely
- * necessary set is performed, after which the application
- * supplied main() routine is called.
- * @param None
- * @retval : None
-*/
-
- .section .text.Reset_Handler
- .weak Reset_Handler
- .type Reset_Handler, %function
-Reset_Handler:
-
-/* Copy the data segment initializers from flash to SRAM */
- movs r1, #0
- b LoopCopyDataInit
-
-CopyDataInit:
- ldr r3, =_sidata
- ldr r3, [r3, r1]
- str r3, [r0, r1]
- adds r1, r1, #4
-
-LoopCopyDataInit:
- ldr r0, =_sdata
- ldr r3, =_edata
- adds r2, r0, r1
- cmp r2, r3
- bcc CopyDataInit
- ldr r2, =_sbss
- b LoopFillZerobss
-
-/* Zero fill the bss segment. */
-FillZerobss:
- movs r3, #0
- str r3, [r2], #4
-
-LoopFillZerobss:
- ldr r3, = _ebss
- cmp r2, r3
- bcc FillZerobss
-
-/* Call the clock system intitialization function.*/
- bl SystemInit
-/* Call static constructors */
- bl __libc_init_array
-/* Call the application's entry point.*/
- bl main
- bx lr
-.size Reset_Handler, .-Reset_Handler
-
-/**
- * @brief This is the code that gets called when the processor receives an
- * unexpected interrupt. This simply enters an infinite loop, preserving
- * the system state for examination by a debugger.
- *
- * @param None
- * @retval : None
-*/
- .section .text.Default_Handler,"ax",%progbits
-Default_Handler:
-Infinite_Loop:
- b Infinite_Loop
- .size Default_Handler, .-Default_Handler
-
-/******************************************************************************
-*
-* The minimal vector table for a Cortex M3. Note that the proper constructs
-* must be placed on this to ensure that it ends up at physical address
-* 0x0000.0000.
-*
-******************************************************************************/
- .section .isr_vector,"a",%progbits
- .type g_pfnVectors, %object
- .size g_pfnVectors, .-g_pfnVectors
-
-
-g_pfnVectors:
-
- .word _estack
- .word Reset_Handler
- .word NMI_Handler
- .word HardFault_Handler
- .word MemManage_Handler
- .word BusFault_Handler
- .word UsageFault_Handler
- .word 0
- .word 0
- .word 0
- .word 0
- .word SVC_Handler
- .word DebugMon_Handler
- .word 0
- .word PendSV_Handler
- .word SysTick_Handler
- .word WWDG_IRQHandler
- .word PVD_IRQHandler
- .word TAMPER_IRQHandler
- .word RTC_IRQHandler
- .word FLASH_IRQHandler
- .word RCC_IRQHandler
- .word EXTI0_IRQHandler
- .word EXTI1_IRQHandler
- .word EXTI2_IRQHandler
- .word EXTI3_IRQHandler
- .word EXTI4_IRQHandler
- .word DMA1_Channel1_IRQHandler
- .word DMA1_Channel2_IRQHandler
- .word DMA1_Channel3_IRQHandler
- .word DMA1_Channel4_IRQHandler
- .word DMA1_Channel5_IRQHandler
- .word DMA1_Channel6_IRQHandler
- .word DMA1_Channel7_IRQHandler
- .word ADC1_2_IRQHandler
- .word CAN1_TX_IRQHandler
- .word CAN1_RX0_IRQHandler
- .word CAN1_RX1_IRQHandler
- .word CAN1_SCE_IRQHandler
- .word EXTI9_5_IRQHandler
- .word TIM1_BRK_IRQHandler
- .word TIM1_UP_IRQHandler
- .word TIM1_TRG_COM_IRQHandler
- .word TIM1_CC_IRQHandler
- .word TIM2_IRQHandler
- .word TIM3_IRQHandler
- .word TIM4_IRQHandler
- .word I2C1_EV_IRQHandler
- .word I2C1_ER_IRQHandler
- .word I2C2_EV_IRQHandler
- .word I2C2_ER_IRQHandler
- .word SPI1_IRQHandler
- .word SPI2_IRQHandler
- .word USART1_IRQHandler
- .word USART2_IRQHandler
- .word USART3_IRQHandler
- .word EXTI15_10_IRQHandler
- .word RTC_Alarm_IRQHandler
- .word OTG_FS_WKUP_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word TIM5_IRQHandler
- .word SPI3_IRQHandler
- .word UART4_IRQHandler
- .word UART5_IRQHandler
- .word TIM6_IRQHandler
- .word TIM7_IRQHandler
- .word DMA2_Channel1_IRQHandler
- .word DMA2_Channel2_IRQHandler
- .word DMA2_Channel3_IRQHandler
- .word DMA2_Channel4_IRQHandler
- .word DMA2_Channel5_IRQHandler
- .word ETH_IRQHandler
- .word ETH_WKUP_IRQHandler
- .word CAN2_TX_IRQHandler
- .word CAN2_RX0_IRQHandler
- .word CAN2_RX1_IRQHandler
- .word CAN2_SCE_IRQHandler
- .word OTG_FS_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word BootRAM /* @0x1E0. This is for boot in RAM mode for
- STM32F10x Connectivity line Devices. */
-
-/*******************************************************************************
-*
-* Provide weak aliases for each Exception handler to the Default_Handler.
-* As they are weak aliases, any function with the same name will override
-* this definition.
-*
-*******************************************************************************/
- .weak NMI_Handler
- .thumb_set NMI_Handler,Default_Handler
-
- .weak HardFault_Handler
- .thumb_set HardFault_Handler,Default_Handler
-
- .weak MemManage_Handler
- .thumb_set MemManage_Handler,Default_Handler
-
- .weak BusFault_Handler
- .thumb_set BusFault_Handler,Default_Handler
-
- .weak UsageFault_Handler
- .thumb_set UsageFault_Handler,Default_Handler
-
- .weak SVC_Handler
- .thumb_set SVC_Handler,Default_Handler
-
- .weak DebugMon_Handler
- .thumb_set DebugMon_Handler,Default_Handler
-
- .weak PendSV_Handler
- .thumb_set PendSV_Handler,Default_Handler
-
- .weak SysTick_Handler
- .thumb_set SysTick_Handler,Default_Handler
-
- .weak WWDG_IRQHandler
- .thumb_set WWDG_IRQHandler,Default_Handler
-
- .weak PVD_IRQHandler
- .thumb_set PVD_IRQHandler,Default_Handler
-
- .weak TAMPER_IRQHandler
- .thumb_set TAMPER_IRQHandler,Default_Handler
-
- .weak RTC_IRQHandler
- .thumb_set RTC_IRQHandler,Default_Handler
-
- .weak FLASH_IRQHandler
- .thumb_set FLASH_IRQHandler,Default_Handler
-
- .weak RCC_IRQHandler
- .thumb_set RCC_IRQHandler,Default_Handler
-
- .weak EXTI0_IRQHandler
- .thumb_set EXTI0_IRQHandler,Default_Handler
-
- .weak EXTI1_IRQHandler
- .thumb_set EXTI1_IRQHandler,Default_Handler
-
- .weak EXTI2_IRQHandler
- .thumb_set EXTI2_IRQHandler,Default_Handler
-
- .weak EXTI3_IRQHandler
- .thumb_set EXTI3_IRQHandler,Default_Handler
-
- .weak EXTI4_IRQHandler
- .thumb_set EXTI4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel1_IRQHandler
- .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
-
- .weak DMA1_Channel2_IRQHandler
- .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
-
- .weak DMA1_Channel3_IRQHandler
- .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
-
- .weak DMA1_Channel4_IRQHandler
- .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel5_IRQHandler
- .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
-
- .weak DMA1_Channel6_IRQHandler
- .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
-
- .weak DMA1_Channel7_IRQHandler
- .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
-
- .weak ADC1_2_IRQHandler
- .thumb_set ADC1_2_IRQHandler,Default_Handler
-
- .weak CAN1_TX_IRQHandler
- .thumb_set CAN1_TX_IRQHandler,Default_Handler
-
- .weak CAN1_RX0_IRQHandler
- .thumb_set CAN1_RX0_IRQHandler,Default_Handler
-
- .weak CAN1_RX1_IRQHandler
- .thumb_set CAN1_RX1_IRQHandler,Default_Handler
-
- .weak CAN1_SCE_IRQHandler
- .thumb_set CAN1_SCE_IRQHandler,Default_Handler
-
- .weak EXTI9_5_IRQHandler
- .thumb_set EXTI9_5_IRQHandler,Default_Handler
-
- .weak TIM1_BRK_IRQHandler
- .thumb_set TIM1_BRK_IRQHandler,Default_Handler
-
- .weak TIM1_UP_IRQHandler
- .thumb_set TIM1_UP_IRQHandler,Default_Handler
-
- .weak TIM1_TRG_COM_IRQHandler
- .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
-
- .weak TIM1_CC_IRQHandler
- .thumb_set TIM1_CC_IRQHandler,Default_Handler
-
- .weak TIM2_IRQHandler
- .thumb_set TIM2_IRQHandler,Default_Handler
-
- .weak TIM3_IRQHandler
- .thumb_set TIM3_IRQHandler,Default_Handler
-
- .weak TIM4_IRQHandler
- .thumb_set TIM4_IRQHandler,Default_Handler
-
- .weak I2C1_EV_IRQHandler
- .thumb_set I2C1_EV_IRQHandler,Default_Handler
-
- .weak I2C1_ER_IRQHandler
- .thumb_set I2C1_ER_IRQHandler,Default_Handler
-
- .weak I2C2_EV_IRQHandler
- .thumb_set I2C2_EV_IRQHandler,Default_Handler
-
- .weak I2C2_ER_IRQHandler
- .thumb_set I2C2_ER_IRQHandler,Default_Handler
-
- .weak SPI1_IRQHandler
- .thumb_set SPI1_IRQHandler,Default_Handler
-
- .weak SPI2_IRQHandler
- .thumb_set SPI2_IRQHandler,Default_Handler
-
- .weak USART1_IRQHandler
- .thumb_set USART1_IRQHandler,Default_Handler
-
- .weak USART2_IRQHandler
- .thumb_set USART2_IRQHandler,Default_Handler
-
- .weak USART3_IRQHandler
- .thumb_set USART3_IRQHandler,Default_Handler
-
- .weak EXTI15_10_IRQHandler
- .thumb_set EXTI15_10_IRQHandler,Default_Handler
-
- .weak RTC_Alarm_IRQHandler
- .thumb_set RTC_Alarm_IRQHandler,Default_Handler
-
- .weak OTG_FS_WKUP_IRQHandler
- .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
-
- .weak TIM5_IRQHandler
- .thumb_set TIM5_IRQHandler,Default_Handler
-
- .weak SPI3_IRQHandler
- .thumb_set SPI3_IRQHandler,Default_Handler
-
- .weak UART4_IRQHandler
- .thumb_set UART4_IRQHandler,Default_Handler
-
- .weak UART5_IRQHandler
- .thumb_set UART5_IRQHandler,Default_Handler
-
- .weak TIM6_IRQHandler
- .thumb_set TIM6_IRQHandler,Default_Handler
-
- .weak TIM7_IRQHandler
- .thumb_set TIM7_IRQHandler,Default_Handler
-
- .weak DMA2_Channel1_IRQHandler
- .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
-
- .weak DMA2_Channel2_IRQHandler
- .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
-
- .weak DMA2_Channel3_IRQHandler
- .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
-
- .weak DMA2_Channel4_IRQHandler
- .thumb_set DMA2_Channel4_IRQHandler,Default_Handler
-
- .weak DMA2_Channel5_IRQHandler
- .thumb_set DMA2_Channel5_IRQHandler,Default_Handler
-
- .weak ETH_IRQHandler
- .thumb_set ETH_IRQHandler,Default_Handler
-
- .weak ETH_WKUP_IRQHandler
- .thumb_set ETH_WKUP_IRQHandler,Default_Handler
-
- .weak CAN2_TX_IRQHandler
- .thumb_set CAN2_TX_IRQHandler,Default_Handler
-
- .weak CAN2_RX0_IRQHandler
- .thumb_set CAN2_RX0_IRQHandler,Default_Handler
-
- .weak CAN2_RX1_IRQHandler
- .thumb_set CAN2_RX1_IRQHandler,Default_Handler
-
- .weak CAN2_SCE_IRQHandler
- .thumb_set CAN2_SCE_IRQHandler,Default_Handler
-
- .weak OTG_FS_IRQHandler
- .thumb_set OTG_FS_IRQHandler ,Default_Handler
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xb_flash.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xb_flash.icf
deleted file mode 100644
index b2a0288..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xb_flash.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x08000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x0801FFFF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
-define symbol __ICFEDIT_region_RAM_end__ = 0x20001FFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xb_sram.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xb_sram.icf
deleted file mode 100644
index 539a865..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xb_sram.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x20000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
-define symbol __ICFEDIT_region_RAM_end__ = 0x20001FFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xe_flash.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xe_flash.icf
deleted file mode 100644
index aeb5671..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xe_flash.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x08000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x0807FFFF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
-define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xe_sram.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xe_sram.icf
deleted file mode 100644
index 65a054a..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xe_sram.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x20000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
-define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101x6_flash.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101x6_flash.icf
deleted file mode 100644
index 6cee5e9..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101x6_flash.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x08000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x08007FFF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
-define symbol __ICFEDIT_region_RAM_end__ = 0x200017FF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101x6_sram.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101x6_sram.icf
deleted file mode 100644
index 8165db3..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101x6_sram.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x20000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
-define symbol __ICFEDIT_region_RAM_end__ = 0x200017FF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xb_flash.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xb_flash.icf
deleted file mode 100644
index 9f1b2b2..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xb_flash.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x08000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x0801FFFF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
-define symbol __ICFEDIT_region_RAM_end__ = 0x20003FFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xb_sram.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xb_sram.icf
deleted file mode 100644
index 182c24e..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xb_sram.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x20000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
-define symbol __ICFEDIT_region_RAM_end__ = 0x20003FFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xe_flash.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xe_flash.icf
deleted file mode 100644
index 80f772a..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xe_flash.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x08000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x0807FFFF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
-define symbol __ICFEDIT_region_RAM_end__ = 0x2000BFFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xe_sram.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xe_sram.icf
deleted file mode 100644
index d0afe5e..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xe_sram.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x20000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
-define symbol __ICFEDIT_region_RAM_end__ = 0x2000BFFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xg_flash.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xg_flash.icf
deleted file mode 100644
index 874cd64..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xg_flash.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x08000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x080FFFFF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
-define symbol __ICFEDIT_region_RAM_end__ = 0x20013FFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xg_sram.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xg_sram.icf
deleted file mode 100644
index e0faa07..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xg_sram.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x20000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
-define symbol __ICFEDIT_region_RAM_end__ = 0x20013FFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102x6_flash.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102x6_flash.icf
deleted file mode 100644
index 6cee5e9..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102x6_flash.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x08000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x08007FFF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
-define symbol __ICFEDIT_region_RAM_end__ = 0x200017FF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102x6_sram.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102x6_sram.icf
deleted file mode 100644
index 8165db3..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102x6_sram.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x20000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
-define symbol __ICFEDIT_region_RAM_end__ = 0x200017FF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102xb_flash.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102xb_flash.icf
deleted file mode 100644
index 9f1b2b2..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102xb_flash.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x08000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x0801FFFF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
-define symbol __ICFEDIT_region_RAM_end__ = 0x20003FFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102xb_sram.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102xb_sram.icf
deleted file mode 100644
index 182c24e..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102xb_sram.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x20000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
-define symbol __ICFEDIT_region_RAM_end__ = 0x20003FFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103x6_flash.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103x6_flash.icf
deleted file mode 100644
index a2b392d..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103x6_flash.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x08000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x08007FFF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
-define symbol __ICFEDIT_region_RAM_end__ = 0x200027FF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103x6_sram.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103x6_sram.icf
deleted file mode 100644
index 5588236..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103x6_sram.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x20000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
-define symbol __ICFEDIT_region_RAM_end__ = 0x200027FF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xb_flash.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xb_flash.icf
deleted file mode 100644
index 7d8ef19..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xb_flash.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x08000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x0801FFFF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
-define symbol __ICFEDIT_region_RAM_end__ = 0x20004FFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xb_sram.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xb_sram.icf
deleted file mode 100644
index 4207bc5..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xb_sram.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x20000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
-define symbol __ICFEDIT_region_RAM_end__ = 0x20004FFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xe_flash.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xe_flash.icf
deleted file mode 100644
index a042ad4..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xe_flash.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x08000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x0807FFFF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
-define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xe_sram.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xe_sram.icf
deleted file mode 100644
index a9335b5..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xe_sram.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x20000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
-define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xg_flash.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xg_flash.icf
deleted file mode 100644
index 1e71d00..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xg_flash.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x08000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x080FFFFF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
-define symbol __ICFEDIT_region_RAM_end__ = 0x20017FFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xg_sram.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xg_sram.icf
deleted file mode 100644
index 4a15dac..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xg_sram.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x20000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
-define symbol __ICFEDIT_region_RAM_end__ = 0x20017FFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f105xc_flash.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f105xc_flash.icf
deleted file mode 100644
index a96235f..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f105xc_flash.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x08000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x0803FFFF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
-define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f105xc_sram.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f105xc_sram.icf
deleted file mode 100644
index a9335b5..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f105xc_sram.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x20000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
-define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f107xc_flash.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f107xc_flash.icf
deleted file mode 100644
index a96235f..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f107xc_flash.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x08000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x0803FFFF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
-define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f107xc_sram.icf b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f107xc_sram.icf
deleted file mode 100644
index a9335b5..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f107xc_sram.icf
+++ /dev/null
@@ -1,31 +0,0 @@
-/*###ICF### Section handled by ICF editor, don't touch! ****/
-/*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
-/*-Specials-*/
-define symbol __ICFEDIT_intvec_start__ = 0x20000000;
-/*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
-define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
-define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF;
-/*-Sizes-*/
-define symbol __ICFEDIT_size_cstack__ = 0x400;
-define symbol __ICFEDIT_size_heap__ = 0x200;
-/**** End of ICF editor section. ###ICF###*/
-
-
-define memory mem with size = 4G;
-define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
-define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
-
-define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
-define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
-
-initialize by copy { readwrite };
-do not initialize { section .noinit };
-
-place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region { readonly };
-place in RAM_region { readwrite,
- block CSTACK, block HEAP };
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f100xb.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f100xb.s
deleted file mode 100644
index 27c7ab4..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f100xb.s
+++ /dev/null
@@ -1,413 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f100xb.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F100xB Value Line Devices vector table
-;* for EWARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Configure the clock system
-;* - Set the initial PC == __iar_program_start,
-;* - Set the vector table entries with the exceptions ISR
-;* address.
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;*
-;*******************************************************************************
-;
-;
-; The modules in this file are included in the libraries, and may be replaced
-; by any user-defined modules that define the PUBLIC symbol _program_start or
-; a user defined start symbol.
-; To override the cstartup defined in the library, simply add your modified
-; version to the workbench project.
-;
-; The vector table is normally located at address 0.
-; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
-; The name "__vector_table" has special meaning for C-SPY:
-; it is where the SP start value is found, and the NVIC vector
-; table register (VTOR) is initialized to this address if != 0.
-;
-; Cortex-M version
-;
-
- MODULE ?cstartup
-
- ;; Forward declaration of sections.
- SECTION CSTACK:DATA:NOROOT(3)
-
- SECTION .intvec:CODE:NOROOT(2)
-
- EXTERN __iar_program_start
- EXTERN SystemInit
- PUBLIC __vector_table
-
- DATA
-__vector_table
- DCD sfe(CSTACK)
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_IRQHandler ; ADC1
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD TIM1_BRK_TIM15_IRQHandler ; TIM1 Break and TIM15
- DCD TIM1_UP_TIM16_IRQHandler ; TIM1 Update and TIM16
- DCD TIM1_TRG_COM_TIM17_IRQHandler ; TIM1 Trigger and Commutation and TIM17
- DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C2 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD CEC_IRQHandler ; HDMI-CEC
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD TIM6_DAC_IRQHandler ; TIM6 and DAC underrun
- DCD TIM7_IRQHandler ; TIM7
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Default interrupt handlers.
-;;
- THUMB
-
- PUBWEAK Reset_Handler
- SECTION .text:CODE:REORDER:NOROOT(2)
-Reset_Handler
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__iar_program_start
- BX R0
-
- PUBWEAK NMI_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-NMI_Handler
- B NMI_Handler
-
- PUBWEAK HardFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-HardFault_Handler
- B HardFault_Handler
-
- PUBWEAK MemManage_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-MemManage_Handler
- B MemManage_Handler
-
- PUBWEAK BusFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-BusFault_Handler
- B BusFault_Handler
-
- PUBWEAK UsageFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UsageFault_Handler
- B UsageFault_Handler
-
- PUBWEAK SVC_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SVC_Handler
- B SVC_Handler
-
- PUBWEAK DebugMon_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DebugMon_Handler
- B DebugMon_Handler
-
- PUBWEAK PendSV_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PendSV_Handler
- B PendSV_Handler
-
- PUBWEAK SysTick_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SysTick_Handler
- B SysTick_Handler
-
- PUBWEAK WWDG_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-WWDG_IRQHandler
- B WWDG_IRQHandler
-
- PUBWEAK PVD_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PVD_IRQHandler
- B PVD_IRQHandler
-
- PUBWEAK TAMPER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TAMPER_IRQHandler
- B TAMPER_IRQHandler
-
- PUBWEAK RTC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_IRQHandler
- B RTC_IRQHandler
-
- PUBWEAK FLASH_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-FLASH_IRQHandler
- B FLASH_IRQHandler
-
- PUBWEAK RCC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RCC_IRQHandler
- B RCC_IRQHandler
-
- PUBWEAK EXTI0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI0_IRQHandler
- B EXTI0_IRQHandler
-
- PUBWEAK EXTI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI1_IRQHandler
- B EXTI1_IRQHandler
-
- PUBWEAK EXTI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI2_IRQHandler
- B EXTI2_IRQHandler
-
- PUBWEAK EXTI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI3_IRQHandler
- B EXTI3_IRQHandler
-
- PUBWEAK EXTI4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI4_IRQHandler
- B EXTI4_IRQHandler
-
- PUBWEAK DMA1_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel1_IRQHandler
- B DMA1_Channel1_IRQHandler
-
- PUBWEAK DMA1_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel2_IRQHandler
- B DMA1_Channel2_IRQHandler
-
- PUBWEAK DMA1_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel3_IRQHandler
- B DMA1_Channel3_IRQHandler
-
- PUBWEAK DMA1_Channel4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel4_IRQHandler
- B DMA1_Channel4_IRQHandler
-
- PUBWEAK DMA1_Channel5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel5_IRQHandler
- B DMA1_Channel5_IRQHandler
-
- PUBWEAK DMA1_Channel6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel6_IRQHandler
- B DMA1_Channel6_IRQHandler
-
- PUBWEAK DMA1_Channel7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel7_IRQHandler
- B DMA1_Channel7_IRQHandler
-
- PUBWEAK ADC1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ADC1_IRQHandler
- B ADC1_IRQHandler
-
- PUBWEAK EXTI9_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI9_5_IRQHandler
- B EXTI9_5_IRQHandler
-
- PUBWEAK TIM1_BRK_TIM15_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_BRK_TIM15_IRQHandler
- B TIM1_BRK_TIM15_IRQHandler
-
- PUBWEAK TIM1_UP_TIM16_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_UP_TIM16_IRQHandler
- B TIM1_UP_TIM16_IRQHandler
-
- PUBWEAK TIM1_TRG_COM_TIM17_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_TRG_COM_TIM17_IRQHandler
- B TIM1_TRG_COM_TIM17_IRQHandler
-
- PUBWEAK TIM1_CC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_CC_IRQHandler
- B TIM1_CC_IRQHandler
-
- PUBWEAK TIM2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM2_IRQHandler
- B TIM2_IRQHandler
-
- PUBWEAK TIM3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM3_IRQHandler
- B TIM3_IRQHandler
-
- PUBWEAK TIM4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM4_IRQHandler
- B TIM4_IRQHandler
-
- PUBWEAK I2C1_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_EV_IRQHandler
- B I2C1_EV_IRQHandler
-
- PUBWEAK I2C1_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_ER_IRQHandler
- B I2C1_ER_IRQHandler
-
- PUBWEAK I2C2_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_EV_IRQHandler
- B I2C2_EV_IRQHandler
-
- PUBWEAK I2C2_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_ER_IRQHandler
- B I2C2_ER_IRQHandler
-
- PUBWEAK SPI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI1_IRQHandler
- B SPI1_IRQHandler
-
- PUBWEAK SPI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI2_IRQHandler
- B SPI2_IRQHandler
-
- PUBWEAK USART1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART1_IRQHandler
- B USART1_IRQHandler
-
- PUBWEAK USART2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART2_IRQHandler
- B USART2_IRQHandler
-
- PUBWEAK USART3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART3_IRQHandler
- B USART3_IRQHandler
-
- PUBWEAK EXTI15_10_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI15_10_IRQHandler
- B EXTI15_10_IRQHandler
-
- PUBWEAK RTC_Alarm_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_Alarm_IRQHandler
- B RTC_Alarm_IRQHandler
-
- PUBWEAK CEC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CEC_IRQHandler
- B CEC_IRQHandler
-
- PUBWEAK TIM6_DAC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM6_DAC_IRQHandler
- B TIM6_DAC_IRQHandler
-
- PUBWEAK TIM7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM7_IRQHandler
- B TIM7_IRQHandler
-
- END
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f100xe.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f100xe.s
deleted file mode 100644
index abc9d4b..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f100xe.s
+++ /dev/null
@@ -1,479 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f100xe.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F100xE Value Line Devices vector table
-;* for EWARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == __iar_program_start,
-;* - Set the vector table entries with the exceptions ISR
-;* address.
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;*
-;*******************************************************************************
-;
-;
-; The modules in this file are included in the libraries, and may be replaced
-; by any user-defined modules that define the PUBLIC symbol _program_start or
-; a user defined start symbol.
-; To override the cstartup defined in the library, simply add your modified
-; version to the workbench project.
-;
-; The vector table is normally located at address 0.
-; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
-; The name "__vector_table" has special meaning for C-SPY:
-; it is where the SP start value is found, and the NVIC vector
-; table register (VTOR) is initialized to this address if != 0.
-;
-; Cortex-M version
-;
-
- MODULE ?cstartup
-
- ;; Forward declaration of sections.
- SECTION CSTACK:DATA:NOROOT(3)
-
- SECTION .intvec:CODE:NOROOT(2)
-
- EXTERN __iar_program_start
- EXTERN SystemInit
- PUBLIC __vector_table
-
- DATA
-__vector_table
- DCD sfe(CSTACK)
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_IRQHandler ; ADC1
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD TIM1_BRK_TIM15_IRQHandler ; TIM1 Break and TIM15
- DCD TIM1_UP_TIM16_IRQHandler ; TIM1 Update and TIM16
- DCD TIM1_TRG_COM_TIM17_IRQHandler ; TIM1 Trigger and Commutation and TIM17
- DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C2 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD CEC_IRQHandler ; HDMI CEC
- DCD TIM12_IRQHandler ; TIM12
- DCD TIM13_IRQHandler ; TIM13
- DCD TIM14_IRQHandler ; TIM14
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD TIM5_IRQHandler ; TIM5
- DCD SPI3_IRQHandler ; SPI3
- DCD UART4_IRQHandler ; UART4
- DCD UART5_IRQHandler ; UART5
- DCD TIM6_DAC_IRQHandler ; TIM6 and DAC underrun
- DCD TIM7_IRQHandler ; TIM7
- DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
- DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
- DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
- DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5 if MISC_REMAP is not set
- ; or DMA2 Channel4 if MISC_REMAP is set
- DCD DMA2_Channel5_IRQHandler ; DMA2 Channel5 if MISC_REMAP is set
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Default interrupt handlers.
-;;
- THUMB
-
- PUBWEAK Reset_Handler
- SECTION .text:CODE:REORDER:NOROOT(2)
-Reset_Handler
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__iar_program_start
- BX R0
-
- PUBWEAK NMI_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-NMI_Handler
- B NMI_Handler
-
- PUBWEAK HardFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-HardFault_Handler
- B HardFault_Handler
-
- PUBWEAK MemManage_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-MemManage_Handler
- B MemManage_Handler
-
- PUBWEAK BusFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-BusFault_Handler
- B BusFault_Handler
-
- PUBWEAK UsageFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UsageFault_Handler
- B UsageFault_Handler
-
- PUBWEAK SVC_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SVC_Handler
- B SVC_Handler
-
- PUBWEAK DebugMon_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DebugMon_Handler
- B DebugMon_Handler
-
- PUBWEAK PendSV_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PendSV_Handler
- B PendSV_Handler
-
- PUBWEAK SysTick_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SysTick_Handler
- B SysTick_Handler
-
- PUBWEAK WWDG_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-WWDG_IRQHandler
- B WWDG_IRQHandler
-
- PUBWEAK PVD_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PVD_IRQHandler
- B PVD_IRQHandler
-
- PUBWEAK TAMPER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TAMPER_IRQHandler
- B TAMPER_IRQHandler
-
- PUBWEAK RTC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_IRQHandler
- B RTC_IRQHandler
-
- PUBWEAK FLASH_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-FLASH_IRQHandler
- B FLASH_IRQHandler
-
- PUBWEAK RCC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RCC_IRQHandler
- B RCC_IRQHandler
-
- PUBWEAK EXTI0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI0_IRQHandler
- B EXTI0_IRQHandler
-
- PUBWEAK EXTI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI1_IRQHandler
- B EXTI1_IRQHandler
-
- PUBWEAK EXTI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI2_IRQHandler
- B EXTI2_IRQHandler
-
- PUBWEAK EXTI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI3_IRQHandler
- B EXTI3_IRQHandler
-
- PUBWEAK EXTI4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI4_IRQHandler
- B EXTI4_IRQHandler
-
- PUBWEAK DMA1_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel1_IRQHandler
- B DMA1_Channel1_IRQHandler
-
- PUBWEAK DMA1_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel2_IRQHandler
- B DMA1_Channel2_IRQHandler
-
- PUBWEAK DMA1_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel3_IRQHandler
- B DMA1_Channel3_IRQHandler
-
- PUBWEAK DMA1_Channel4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel4_IRQHandler
- B DMA1_Channel4_IRQHandler
-
- PUBWEAK DMA1_Channel5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel5_IRQHandler
- B DMA1_Channel5_IRQHandler
-
- PUBWEAK DMA1_Channel6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel6_IRQHandler
- B DMA1_Channel6_IRQHandler
-
- PUBWEAK DMA1_Channel7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel7_IRQHandler
- B DMA1_Channel7_IRQHandler
-
- PUBWEAK ADC1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ADC1_IRQHandler
- B ADC1_IRQHandler
-
- PUBWEAK EXTI9_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI9_5_IRQHandler
- B EXTI9_5_IRQHandler
-
- PUBWEAK TIM1_BRK_TIM15_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_BRK_TIM15_IRQHandler
- B TIM1_BRK_TIM15_IRQHandler
-
- PUBWEAK TIM1_UP_TIM16_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_UP_TIM16_IRQHandler
- B TIM1_UP_TIM16_IRQHandler
-
- PUBWEAK TIM1_TRG_COM_TIM17_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_TRG_COM_TIM17_IRQHandler
- B TIM1_TRG_COM_TIM17_IRQHandler
-
- PUBWEAK TIM1_CC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_CC_IRQHandler
- B TIM1_CC_IRQHandler
-
- PUBWEAK TIM2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM2_IRQHandler
- B TIM2_IRQHandler
-
- PUBWEAK TIM3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM3_IRQHandler
- B TIM3_IRQHandler
-
- PUBWEAK TIM4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM4_IRQHandler
- B TIM4_IRQHandler
-
- PUBWEAK I2C1_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_EV_IRQHandler
- B I2C1_EV_IRQHandler
-
- PUBWEAK I2C1_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_ER_IRQHandler
- B I2C1_ER_IRQHandler
-
- PUBWEAK I2C2_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_EV_IRQHandler
- B I2C2_EV_IRQHandler
-
- PUBWEAK I2C2_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_ER_IRQHandler
- B I2C2_ER_IRQHandler
-
- PUBWEAK SPI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI1_IRQHandler
- B SPI1_IRQHandler
-
- PUBWEAK SPI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI2_IRQHandler
- B SPI2_IRQHandler
-
- PUBWEAK USART1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART1_IRQHandler
- B USART1_IRQHandler
-
- PUBWEAK USART2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART2_IRQHandler
- B USART2_IRQHandler
-
- PUBWEAK USART3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART3_IRQHandler
- B USART3_IRQHandler
-
- PUBWEAK EXTI15_10_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI15_10_IRQHandler
- B EXTI15_10_IRQHandler
-
- PUBWEAK RTC_Alarm_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_Alarm_IRQHandler
- B RTC_Alarm_IRQHandler
-
-
- PUBWEAK CEC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CEC_IRQHandler
- B CEC_IRQHandler
-
- PUBWEAK TIM12_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM12_IRQHandler
- B TIM12_IRQHandler
-
- PUBWEAK TIM13_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM13_IRQHandler
- B TIM13_IRQHandler
-
- PUBWEAK TIM14_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM14_IRQHandler
- B TIM14_IRQHandler
-
- PUBWEAK TIM5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM5_IRQHandler
- B TIM5_IRQHandler
-
- PUBWEAK SPI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI3_IRQHandler
- B SPI3_IRQHandler
-
- PUBWEAK UART4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UART4_IRQHandler
- B UART4_IRQHandler
-
- PUBWEAK UART5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UART5_IRQHandler
- B UART5_IRQHandler
-
- PUBWEAK TIM6_DAC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM6_DAC_IRQHandler
- B TIM6_DAC_IRQHandler
-
- PUBWEAK TIM7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM7_IRQHandler
- B TIM7_IRQHandler
-
- PUBWEAK DMA2_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel1_IRQHandler
- B DMA2_Channel1_IRQHandler
-
- PUBWEAK DMA2_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel2_IRQHandler
- B DMA2_Channel2_IRQHandler
-
- PUBWEAK DMA2_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel3_IRQHandler
- B DMA2_Channel3_IRQHandler
-
- PUBWEAK DMA2_Channel4_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel4_5_IRQHandler
- B DMA2_Channel4_5_IRQHandler
-
- PUBWEAK DMA2_Channel5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel5_IRQHandler
- B DMA2_Channel5_IRQHandler
-
- END
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101x6.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101x6.s
deleted file mode 100644
index 41ea902..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101x6.s
+++ /dev/null
@@ -1,340 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f101x6.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F101x6 Access Line Devices vector table for EWARM
-;* toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Configure the clock system
-;* - Set the initial PC == __iar_program_start,
-;* - Set the vector table entries with the exceptions ISR
-;* address.
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;*
-;*******************************************************************************
-;
-;
-; The modules in this file are included in the libraries, and may be replaced
-; by any user-defined modules that define the PUBLIC symbol _program_start or
-; a user defined start symbol.
-; To override the cstartup defined in the library, simply add your modified
-; version to the workbench project.
-;
-; The vector table is normally located at address 0.
-; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
-; The name "__vector_table" has special meaning for C-SPY:
-; it is where the SP start value is found, and the NVIC vector
-; table register (VTOR) is initialized to this address if != 0.
-;
-; Cortex-M version
-;
-
- MODULE ?cstartup
-
- ;; Forward declaration of sections.
- SECTION CSTACK:DATA:NOROOT(3)
-
- SECTION .intvec:CODE:NOROOT(2)
-
- EXTERN __iar_program_start
- EXTERN SystemInit
- PUBLIC __vector_table
-
- DATA
-__vector_table
- DCD sfe(CSTACK)
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_IRQHandler ; ADC1
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD 0 ; Reserved
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SPI1_IRQHandler ; SPI1
- DCD 0 ; Reserved
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD 0 ; Reserved
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD 0 ; Reserved
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Default interrupt handlers.
-;;
- THUMB
-
- PUBWEAK Reset_Handler
- SECTION .text:CODE:REORDER:NOROOT(2)
-Reset_Handler
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__iar_program_start
- BX R0
-
- PUBWEAK NMI_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-NMI_Handler
- B NMI_Handler
-
- PUBWEAK HardFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-HardFault_Handler
- B HardFault_Handler
-
- PUBWEAK MemManage_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-MemManage_Handler
- B MemManage_Handler
-
- PUBWEAK BusFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-BusFault_Handler
- B BusFault_Handler
-
- PUBWEAK UsageFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UsageFault_Handler
- B UsageFault_Handler
-
- PUBWEAK SVC_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SVC_Handler
- B SVC_Handler
-
- PUBWEAK DebugMon_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DebugMon_Handler
- B DebugMon_Handler
-
- PUBWEAK PendSV_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PendSV_Handler
- B PendSV_Handler
-
- PUBWEAK SysTick_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SysTick_Handler
- B SysTick_Handler
-
- PUBWEAK WWDG_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-WWDG_IRQHandler
- B WWDG_IRQHandler
-
- PUBWEAK PVD_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PVD_IRQHandler
- B PVD_IRQHandler
-
- PUBWEAK TAMPER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TAMPER_IRQHandler
- B TAMPER_IRQHandler
-
- PUBWEAK RTC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_IRQHandler
- B RTC_IRQHandler
-
- PUBWEAK FLASH_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-FLASH_IRQHandler
- B FLASH_IRQHandler
-
- PUBWEAK RCC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RCC_IRQHandler
- B RCC_IRQHandler
-
- PUBWEAK EXTI0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI0_IRQHandler
- B EXTI0_IRQHandler
-
- PUBWEAK EXTI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI1_IRQHandler
- B EXTI1_IRQHandler
-
- PUBWEAK EXTI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI2_IRQHandler
- B EXTI2_IRQHandler
-
- PUBWEAK EXTI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI3_IRQHandler
- B EXTI3_IRQHandler
-
- PUBWEAK EXTI4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI4_IRQHandler
- B EXTI4_IRQHandler
-
- PUBWEAK DMA1_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel1_IRQHandler
- B DMA1_Channel1_IRQHandler
-
- PUBWEAK DMA1_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel2_IRQHandler
- B DMA1_Channel2_IRQHandler
-
- PUBWEAK DMA1_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel3_IRQHandler
- B DMA1_Channel3_IRQHandler
-
- PUBWEAK DMA1_Channel4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel4_IRQHandler
- B DMA1_Channel4_IRQHandler
-
- PUBWEAK DMA1_Channel5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel5_IRQHandler
- B DMA1_Channel5_IRQHandler
-
- PUBWEAK DMA1_Channel6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel6_IRQHandler
- B DMA1_Channel6_IRQHandler
-
- PUBWEAK DMA1_Channel7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel7_IRQHandler
- B DMA1_Channel7_IRQHandler
-
- PUBWEAK ADC1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ADC1_IRQHandler
- B ADC1_IRQHandler
-
- PUBWEAK EXTI9_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI9_5_IRQHandler
- B EXTI9_5_IRQHandler
-
- PUBWEAK TIM2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM2_IRQHandler
- B TIM2_IRQHandler
-
- PUBWEAK TIM3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM3_IRQHandler
- B TIM3_IRQHandler
-
- PUBWEAK I2C1_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_EV_IRQHandler
- B I2C1_EV_IRQHandler
-
- PUBWEAK I2C1_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_ER_IRQHandler
- B I2C1_ER_IRQHandler
-
- PUBWEAK SPI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI1_IRQHandler
- B SPI1_IRQHandler
-
- PUBWEAK USART1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART1_IRQHandler
- B USART1_IRQHandler
-
- PUBWEAK USART2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART2_IRQHandler
- B USART2_IRQHandler
-
- PUBWEAK EXTI15_10_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI15_10_IRQHandler
- B EXTI15_10_IRQHandler
-
- PUBWEAK RTC_Alarm_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_Alarm_IRQHandler
- B RTC_Alarm_IRQHandler
-
- END
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101xb.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101xb.s
deleted file mode 100644
index f079123..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101xb.s
+++ /dev/null
@@ -1,365 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f101xb.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F101xB Access Line Devices vector table for
-;* EWARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Configure the clock system
-;* - Set the initial PC == __iar_program_start,
-;* - Set the vector table entries with the exceptions ISR
-;* address.
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;*
-;*******************************************************************************
-;
-;
-; The modules in this file are included in the libraries, and may be replaced
-; by any user-defined modules that define the PUBLIC symbol _program_start or
-; a user defined start symbol.
-; To override the cstartup defined in the library, simply add your modified
-; version to the workbench project.
-;
-; The vector table is normally located at address 0.
-; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
-; The name "__vector_table" has special meaning for C-SPY:
-; it is where the SP start value is found, and the NVIC vector
-; table register (VTOR) is initialized to this address if != 0.
-;
-; Cortex-M version
-;
-
- MODULE ?cstartup
-
- ;; Forward declaration of sections.
- SECTION CSTACK:DATA:NOROOT(3)
-
- SECTION .intvec:CODE:NOROOT(2)
-
- EXTERN __iar_program_start
- EXTERN SystemInit
- PUBLIC __vector_table
-
- DATA
-__vector_table
- DCD sfe(CSTACK)
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_IRQHandler ; ADC1
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C2 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD 0 ; Reserved
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Default interrupt handlers.
-;;
- THUMB
-
- PUBWEAK Reset_Handler
- SECTION .text:CODE:REORDER:NOROOT(2)
-Reset_Handler
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__iar_program_start
- BX R0
-
- PUBWEAK NMI_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-NMI_Handler
- B NMI_Handler
-
- PUBWEAK HardFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-HardFault_Handler
- B HardFault_Handler
-
- PUBWEAK MemManage_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-MemManage_Handler
- B MemManage_Handler
-
- PUBWEAK BusFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-BusFault_Handler
- B BusFault_Handler
-
- PUBWEAK UsageFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UsageFault_Handler
- B UsageFault_Handler
-
- PUBWEAK SVC_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SVC_Handler
- B SVC_Handler
-
- PUBWEAK DebugMon_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DebugMon_Handler
- B DebugMon_Handler
-
- PUBWEAK PendSV_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PendSV_Handler
- B PendSV_Handler
-
- PUBWEAK SysTick_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SysTick_Handler
- B SysTick_Handler
-
- PUBWEAK WWDG_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-WWDG_IRQHandler
- B WWDG_IRQHandler
-
- PUBWEAK PVD_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PVD_IRQHandler
- B PVD_IRQHandler
-
- PUBWEAK TAMPER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TAMPER_IRQHandler
- B TAMPER_IRQHandler
-
- PUBWEAK RTC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_IRQHandler
- B RTC_IRQHandler
-
- PUBWEAK FLASH_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-FLASH_IRQHandler
- B FLASH_IRQHandler
-
- PUBWEAK RCC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RCC_IRQHandler
- B RCC_IRQHandler
-
- PUBWEAK EXTI0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI0_IRQHandler
- B EXTI0_IRQHandler
-
- PUBWEAK EXTI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI1_IRQHandler
- B EXTI1_IRQHandler
-
- PUBWEAK EXTI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI2_IRQHandler
- B EXTI2_IRQHandler
-
- PUBWEAK EXTI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI3_IRQHandler
- B EXTI3_IRQHandler
-
- PUBWEAK EXTI4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI4_IRQHandler
- B EXTI4_IRQHandler
-
- PUBWEAK DMA1_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel1_IRQHandler
- B DMA1_Channel1_IRQHandler
-
- PUBWEAK DMA1_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel2_IRQHandler
- B DMA1_Channel2_IRQHandler
-
- PUBWEAK DMA1_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel3_IRQHandler
- B DMA1_Channel3_IRQHandler
-
- PUBWEAK DMA1_Channel4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel4_IRQHandler
- B DMA1_Channel4_IRQHandler
-
- PUBWEAK DMA1_Channel5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel5_IRQHandler
- B DMA1_Channel5_IRQHandler
-
- PUBWEAK DMA1_Channel6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel6_IRQHandler
- B DMA1_Channel6_IRQHandler
-
- PUBWEAK DMA1_Channel7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel7_IRQHandler
- B DMA1_Channel7_IRQHandler
-
- PUBWEAK ADC1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ADC1_IRQHandler
- B ADC1_IRQHandler
-
- PUBWEAK EXTI9_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI9_5_IRQHandler
- B EXTI9_5_IRQHandler
-
- PUBWEAK TIM2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM2_IRQHandler
- B TIM2_IRQHandler
-
- PUBWEAK TIM3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM3_IRQHandler
- B TIM3_IRQHandler
-
- PUBWEAK TIM4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM4_IRQHandler
- B TIM4_IRQHandler
-
- PUBWEAK I2C1_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_EV_IRQHandler
- B I2C1_EV_IRQHandler
-
- PUBWEAK I2C1_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_ER_IRQHandler
- B I2C1_ER_IRQHandler
-
- PUBWEAK I2C2_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_EV_IRQHandler
- B I2C2_EV_IRQHandler
-
- PUBWEAK I2C2_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_ER_IRQHandler
- B I2C2_ER_IRQHandler
-
- PUBWEAK SPI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI1_IRQHandler
- B SPI1_IRQHandler
-
- PUBWEAK SPI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI2_IRQHandler
- B SPI2_IRQHandler
-
- PUBWEAK USART1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART1_IRQHandler
- B USART1_IRQHandler
-
- PUBWEAK USART2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART2_IRQHandler
- B USART2_IRQHandler
-
- PUBWEAK USART3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART3_IRQHandler
- B USART3_IRQHandler
-
- PUBWEAK EXTI15_10_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI15_10_IRQHandler
- B EXTI15_10_IRQHandler
-
- PUBWEAK RTC_Alarm_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_Alarm_IRQHandler
- B RTC_Alarm_IRQHandler
-
- END
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101xe.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101xe.s
deleted file mode 100644
index af58461..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101xe.s
+++ /dev/null
@@ -1,445 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f101xe.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F101xE Access Line Devices vector table for EWARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == __iar_program_start,
-;* - Set the vector table entries with the exceptions ISR
-;* address.
-;* - Configure the system clock
-;* - Branches to main in the C library (which eventually
-;* calls main()).
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;*
-;*******************************************************************************
-;
-;
-; The modules in this file are included in the libraries, and may be replaced
-; by any user-defined modules that define the PUBLIC symbol _program_start or
-; a user defined start symbol.
-; To override the cstartup defined in the library, simply add your modified
-; version to the workbench project.
-;
-; The vector table is normally located at address 0.
-; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
-; The name "__vector_table" has special meaning for C-SPY:
-; it is where the SP start value is found, and the NVIC vector
-; table register (VTOR) is initialized to this address if != 0.
-;
-; Cortex-M version
-;
-
- MODULE ?cstartup
-
- ;; Forward declaration of sections.
- SECTION CSTACK:DATA:NOROOT(3)
-
- SECTION .intvec:CODE:NOROOT(2)
-
- EXTERN __iar_program_start
- EXTERN SystemInit
- PUBLIC __vector_table
-
- DATA
-
-__vector_table
- DCD sfe(CSTACK)
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_IRQHandler ; ADC1
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C2 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD FSMC_IRQHandler ; FSMC
- DCD 0 ; Reserved
- DCD TIM5_IRQHandler ; TIM5
- DCD SPI3_IRQHandler ; SPI3
- DCD UART4_IRQHandler ; UART4
- DCD UART5_IRQHandler ; UART5
- DCD TIM6_IRQHandler ; TIM6
- DCD TIM7_IRQHandler ; TIM7
- DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
- DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
- DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
- DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Default interrupt handlers.
-;;
- THUMB
-
- PUBWEAK Reset_Handler
- SECTION .text:CODE:REORDER:NOROOT(2)
-Reset_Handler
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__iar_program_start
- BX R0
-
- PUBWEAK NMI_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-NMI_Handler
- B NMI_Handler
-
- PUBWEAK HardFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-HardFault_Handler
- B HardFault_Handler
-
- PUBWEAK MemManage_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-MemManage_Handler
- B MemManage_Handler
-
- PUBWEAK BusFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-BusFault_Handler
- B BusFault_Handler
-
- PUBWEAK UsageFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UsageFault_Handler
- B UsageFault_Handler
-
- PUBWEAK SVC_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SVC_Handler
- B SVC_Handler
-
- PUBWEAK DebugMon_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DebugMon_Handler
- B DebugMon_Handler
-
- PUBWEAK PendSV_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PendSV_Handler
- B PendSV_Handler
-
- PUBWEAK SysTick_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SysTick_Handler
- B SysTick_Handler
-
- PUBWEAK WWDG_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-WWDG_IRQHandler
- B WWDG_IRQHandler
-
- PUBWEAK PVD_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PVD_IRQHandler
- B PVD_IRQHandler
-
- PUBWEAK TAMPER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TAMPER_IRQHandler
- B TAMPER_IRQHandler
-
- PUBWEAK RTC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_IRQHandler
- B RTC_IRQHandler
-
- PUBWEAK FLASH_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-FLASH_IRQHandler
- B FLASH_IRQHandler
-
- PUBWEAK RCC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RCC_IRQHandler
- B RCC_IRQHandler
-
- PUBWEAK EXTI0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI0_IRQHandler
- B EXTI0_IRQHandler
-
- PUBWEAK EXTI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI1_IRQHandler
- B EXTI1_IRQHandler
-
- PUBWEAK EXTI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI2_IRQHandler
- B EXTI2_IRQHandler
-
- PUBWEAK EXTI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI3_IRQHandler
- B EXTI3_IRQHandler
-
- PUBWEAK EXTI4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI4_IRQHandler
- B EXTI4_IRQHandler
-
- PUBWEAK DMA1_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel1_IRQHandler
- B DMA1_Channel1_IRQHandler
-
- PUBWEAK DMA1_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel2_IRQHandler
- B DMA1_Channel2_IRQHandler
-
- PUBWEAK DMA1_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel3_IRQHandler
- B DMA1_Channel3_IRQHandler
-
- PUBWEAK DMA1_Channel4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel4_IRQHandler
- B DMA1_Channel4_IRQHandler
-
- PUBWEAK DMA1_Channel5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel5_IRQHandler
- B DMA1_Channel5_IRQHandler
-
- PUBWEAK DMA1_Channel6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel6_IRQHandler
- B DMA1_Channel6_IRQHandler
-
- PUBWEAK DMA1_Channel7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel7_IRQHandler
- B DMA1_Channel7_IRQHandler
-
- PUBWEAK ADC1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ADC1_IRQHandler
- B ADC1_IRQHandler
-
- PUBWEAK EXTI9_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI9_5_IRQHandler
- B EXTI9_5_IRQHandler
-
- PUBWEAK TIM2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM2_IRQHandler
- B TIM2_IRQHandler
-
- PUBWEAK TIM3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM3_IRQHandler
- B TIM3_IRQHandler
-
- PUBWEAK TIM4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM4_IRQHandler
- B TIM4_IRQHandler
-
- PUBWEAK I2C1_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_EV_IRQHandler
- B I2C1_EV_IRQHandler
-
- PUBWEAK I2C1_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_ER_IRQHandler
- B I2C1_ER_IRQHandler
-
- PUBWEAK I2C2_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_EV_IRQHandler
- B I2C2_EV_IRQHandler
-
- PUBWEAK I2C2_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_ER_IRQHandler
- B I2C2_ER_IRQHandler
-
- PUBWEAK SPI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI1_IRQHandler
- B SPI1_IRQHandler
-
- PUBWEAK SPI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI2_IRQHandler
- B SPI2_IRQHandler
-
- PUBWEAK USART1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART1_IRQHandler
- B USART1_IRQHandler
-
- PUBWEAK USART2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART2_IRQHandler
- B USART2_IRQHandler
-
- PUBWEAK USART3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART3_IRQHandler
- B USART3_IRQHandler
-
- PUBWEAK EXTI15_10_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI15_10_IRQHandler
- B EXTI15_10_IRQHandler
-
- PUBWEAK RTC_Alarm_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_Alarm_IRQHandler
- B RTC_Alarm_IRQHandler
-
- PUBWEAK FSMC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-FSMC_IRQHandler
- B FSMC_IRQHandler
-
- PUBWEAK SDIO_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SDIO_IRQHandler
- B SDIO_IRQHandler
-
- PUBWEAK TIM5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM5_IRQHandler
- B TIM5_IRQHandler
-
- PUBWEAK SPI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI3_IRQHandler
- B SPI3_IRQHandler
-
- PUBWEAK UART4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UART4_IRQHandler
- B UART4_IRQHandler
-
- PUBWEAK UART5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UART5_IRQHandler
- B UART5_IRQHandler
-
- PUBWEAK TIM6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM6_IRQHandler
- B TIM6_IRQHandler
-
- PUBWEAK TIM7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM7_IRQHandler
- B TIM7_IRQHandler
-
- PUBWEAK DMA2_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel1_IRQHandler
- B DMA2_Channel1_IRQHandler
-
- PUBWEAK DMA2_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel2_IRQHandler
- B DMA2_Channel2_IRQHandler
-
- PUBWEAK DMA2_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel3_IRQHandler
- B DMA2_Channel3_IRQHandler
-
- PUBWEAK DMA2_Channel4_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel4_5_IRQHandler
- B DMA2_Channel4_5_IRQHandler
-
-
- END
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101xg.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101xg.s
deleted file mode 100644
index 9ffbe36..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101xg.s
+++ /dev/null
@@ -1,476 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f101xg.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F101xG Access Line Devices vector table for EWARM
-;* toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == __iar_program_start,
-;* - Set the vector table entries with the exceptions ISR
-;* address.
-;* - Configure the system clock
-;* - Branches to main in the C library (which eventually
-;* calls main()).
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;*
-;*******************************************************************************
-;
-;
-; The modules in this file are included in the libraries, and may be replaced
-; by any user-defined modules that define the PUBLIC symbol _program_start or
-; a user defined start symbol.
-; To override the cstartup defined in the library, simply add your modified
-; version to the workbench project.
-;
-; The vector table is normally located at address 0.
-; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
-; The name "__vector_table" has special meaning for C-SPY:
-; it is where the SP start value is found, and the NVIC vector
-; table register (VTOR) is initialized to this address if != 0.
-;
-; Cortex-M version
-;
-
- MODULE ?cstartup
-
- ;; Forward declaration of sections.
- SECTION CSTACK:DATA:NOROOT(3)
-
- SECTION .intvec:CODE:NOROOT(2)
-
- EXTERN __iar_program_start
- EXTERN SystemInit
- PUBLIC __vector_table
-
- DATA
-
-__vector_table
- DCD sfe(CSTACK)
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_2_IRQHandler ; ADC1 & ADC2
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD TIM9_IRQHandler ; TIM9
- DCD TIM10_IRQHandler ; TIM10
- DCD TIM11_IRQHandler ; TIM11
- DCD 0 ; Reserved
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C2 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD 0 ; Reserved
- DCD TIM12_IRQHandler ; TIM12
- DCD TIM13_IRQHandler ; TIM13
- DCD TIM14_IRQHandler ; TIM14
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD FSMC_IRQHandler ; FSMC
- DCD 0 ; Reserved
- DCD TIM5_IRQHandler ; TIM5
- DCD SPI3_IRQHandler ; SPI3
- DCD UART4_IRQHandler ; UART4
- DCD UART5_IRQHandler ; UART5
- DCD TIM6_IRQHandler ; TIM6
- DCD TIM7_IRQHandler ; TIM7
- DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
- DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
- DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
- DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Default interrupt handlers.
-;;
- THUMB
-
- PUBWEAK Reset_Handler
- SECTION .text:CODE:REORDER:NOROOT(2)
-Reset_Handler
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__iar_program_start
- BX R0
-
- PUBWEAK NMI_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-NMI_Handler
- B NMI_Handler
-
- PUBWEAK HardFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-HardFault_Handler
- B HardFault_Handler
-
- PUBWEAK MemManage_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-MemManage_Handler
- B MemManage_Handler
-
- PUBWEAK BusFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-BusFault_Handler
- B BusFault_Handler
-
- PUBWEAK UsageFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UsageFault_Handler
- B UsageFault_Handler
-
- PUBWEAK SVC_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SVC_Handler
- B SVC_Handler
-
- PUBWEAK DebugMon_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DebugMon_Handler
- B DebugMon_Handler
-
- PUBWEAK PendSV_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PendSV_Handler
- B PendSV_Handler
-
- PUBWEAK SysTick_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SysTick_Handler
- B SysTick_Handler
-
- PUBWEAK WWDG_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-WWDG_IRQHandler
- B WWDG_IRQHandler
-
- PUBWEAK PVD_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PVD_IRQHandler
- B PVD_IRQHandler
-
- PUBWEAK TAMPER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TAMPER_IRQHandler
- B TAMPER_IRQHandler
-
- PUBWEAK RTC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_IRQHandler
- B RTC_IRQHandler
-
- PUBWEAK FLASH_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-FLASH_IRQHandler
- B FLASH_IRQHandler
-
- PUBWEAK RCC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RCC_IRQHandler
- B RCC_IRQHandler
-
- PUBWEAK EXTI0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI0_IRQHandler
- B EXTI0_IRQHandler
-
- PUBWEAK EXTI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI1_IRQHandler
- B EXTI1_IRQHandler
-
- PUBWEAK EXTI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI2_IRQHandler
- B EXTI2_IRQHandler
-
- PUBWEAK EXTI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI3_IRQHandler
- B EXTI3_IRQHandler
-
- PUBWEAK EXTI4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI4_IRQHandler
- B EXTI4_IRQHandler
-
- PUBWEAK DMA1_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel1_IRQHandler
- B DMA1_Channel1_IRQHandler
-
- PUBWEAK DMA1_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel2_IRQHandler
- B DMA1_Channel2_IRQHandler
-
- PUBWEAK DMA1_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel3_IRQHandler
- B DMA1_Channel3_IRQHandler
-
- PUBWEAK DMA1_Channel4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel4_IRQHandler
- B DMA1_Channel4_IRQHandler
-
- PUBWEAK DMA1_Channel5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel5_IRQHandler
- B DMA1_Channel5_IRQHandler
-
- PUBWEAK DMA1_Channel6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel6_IRQHandler
- B DMA1_Channel6_IRQHandler
-
- PUBWEAK DMA1_Channel7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel7_IRQHandler
- B DMA1_Channel7_IRQHandler
-
- PUBWEAK ADC1_2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ADC1_2_IRQHandler
- B ADC1_2_IRQHandler
-
- PUBWEAK EXTI9_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI9_5_IRQHandler
- B EXTI9_5_IRQHandler
-
- PUBWEAK TIM9_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM9_IRQHandler
- B TIM9_IRQHandler
-
- PUBWEAK TIM10_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM10_IRQHandler
- B TIM10_IRQHandler
-
- PUBWEAK TIM11_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM11_IRQHandler
- B TIM11_IRQHandler
-
- PUBWEAK TIM1_CC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_CC_IRQHandler
- B TIM1_CC_IRQHandler
-
- PUBWEAK TIM2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM2_IRQHandler
- B TIM2_IRQHandler
-
- PUBWEAK TIM3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM3_IRQHandler
- B TIM3_IRQHandler
-
- PUBWEAK TIM4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM4_IRQHandler
- B TIM4_IRQHandler
-
- PUBWEAK I2C1_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_EV_IRQHandler
- B I2C1_EV_IRQHandler
-
- PUBWEAK I2C1_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_ER_IRQHandler
- B I2C1_ER_IRQHandler
-
- PUBWEAK I2C2_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_EV_IRQHandler
- B I2C2_EV_IRQHandler
-
- PUBWEAK I2C2_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_ER_IRQHandler
- B I2C2_ER_IRQHandler
-
- PUBWEAK SPI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI1_IRQHandler
- B SPI1_IRQHandler
-
- PUBWEAK SPI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI2_IRQHandler
- B SPI2_IRQHandler
-
- PUBWEAK USART1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART1_IRQHandler
- B USART1_IRQHandler
-
- PUBWEAK USART2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART2_IRQHandler
- B USART2_IRQHandler
-
- PUBWEAK USART3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART3_IRQHandler
- B USART3_IRQHandler
-
- PUBWEAK EXTI15_10_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI15_10_IRQHandler
- B EXTI15_10_IRQHandler
-
- PUBWEAK RTC_Alarm_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_Alarm_IRQHandler
- B RTC_Alarm_IRQHandler
-
- PUBWEAK FSMC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-FSMC_IRQHandler
- B FSMC_IRQHandler
-
- PUBWEAK TIM12_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM12_IRQHandler
- B TIM12_IRQHandler
-
- PUBWEAK TIM13_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM13_IRQHandler
- B TIM13_IRQHandler
-
- PUBWEAK TIM14_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM14_IRQHandler
- B TIM14_IRQHandler
-
- PUBWEAK TIM5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM5_IRQHandler
- B TIM5_IRQHandler
-
- PUBWEAK SPI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI3_IRQHandler
- B SPI3_IRQHandler
-
- PUBWEAK UART4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UART4_IRQHandler
- B UART4_IRQHandler
-
- PUBWEAK UART5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UART5_IRQHandler
- B UART5_IRQHandler
-
- PUBWEAK TIM6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM6_IRQHandler
- B TIM6_IRQHandler
-
- PUBWEAK TIM7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM7_IRQHandler
- B TIM7_IRQHandler
-
- PUBWEAK DMA2_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel1_IRQHandler
- B DMA2_Channel1_IRQHandler
-
- PUBWEAK DMA2_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel2_IRQHandler
- B DMA2_Channel2_IRQHandler
-
- PUBWEAK DMA2_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel3_IRQHandler
- B DMA2_Channel3_IRQHandler
-
- PUBWEAK DMA2_Channel4_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel4_5_IRQHandler
- B DMA2_Channel4_5_IRQHandler
-
-
- END
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f102x6.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f102x6.s
deleted file mode 100644
index d032b0d..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f102x6.s
+++ /dev/null
@@ -1,355 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f102x6.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F102x6 USB Line Devices vector table for EWARM
-;* toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Configure the clock system
-;* - Set the initial PC == __iar_program_start,
-;* - Set the vector table entries with the exceptions ISR
-;* address.
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;*
-;*******************************************************************************
-;
-;
-; The modules in this file are included in the libraries, and may be replaced
-; by any user-defined modules that define the PUBLIC symbol _program_start or
-; a user defined start symbol.
-; To override the cstartup defined in the library, simply add your modified
-; version to the workbench project.
-;
-; The vector table is normally located at address 0.
-; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
-; The name "__vector_table" has special meaning for C-SPY:
-; it is where the SP start value is found, and the NVIC vector
-; table register (VTOR) is initialized to this address if != 0.
-;
-; Cortex-M version
-;
-
- MODULE ?cstartup
-
- ;; Forward declaration of sections.
- SECTION CSTACK:DATA:NOROOT(3)
-
- SECTION .intvec:CODE:NOROOT(2)
-
- EXTERN __iar_program_start
- EXTERN SystemInit
- PUBLIC __vector_table
-
- DATA
-__vector_table
- DCD sfe(CSTACK)
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_IRQHandler ; ADC1
- DCD USB_HP_IRQHandler ; USB High Priority
- DCD USB_LP_IRQHandler ; USB Low Priority
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD 0 ; Reserved
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SPI1_IRQHandler ; SPI1
- DCD 0 ; Reserved
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD 0 ; Reserved
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Default interrupt handlers.
-;;
- THUMB
-
- PUBWEAK Reset_Handler
- SECTION .text:CODE:REORDER:NOROOT(2)
-Reset_Handler
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__iar_program_start
- BX R0
-
- PUBWEAK NMI_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-NMI_Handler
- B NMI_Handler
-
- PUBWEAK HardFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-HardFault_Handler
- B HardFault_Handler
-
- PUBWEAK MemManage_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-MemManage_Handler
- B MemManage_Handler
-
- PUBWEAK BusFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-BusFault_Handler
- B BusFault_Handler
-
- PUBWEAK UsageFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UsageFault_Handler
- B UsageFault_Handler
-
- PUBWEAK SVC_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SVC_Handler
- B SVC_Handler
-
- PUBWEAK DebugMon_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DebugMon_Handler
- B DebugMon_Handler
-
- PUBWEAK PendSV_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PendSV_Handler
- B PendSV_Handler
-
- PUBWEAK SysTick_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SysTick_Handler
- B SysTick_Handler
-
- PUBWEAK WWDG_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-WWDG_IRQHandler
- B WWDG_IRQHandler
-
- PUBWEAK PVD_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PVD_IRQHandler
- B PVD_IRQHandler
-
- PUBWEAK TAMPER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TAMPER_IRQHandler
- B TAMPER_IRQHandler
-
- PUBWEAK RTC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_IRQHandler
- B RTC_IRQHandler
-
- PUBWEAK FLASH_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-FLASH_IRQHandler
- B FLASH_IRQHandler
-
- PUBWEAK RCC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RCC_IRQHandler
- B RCC_IRQHandler
-
- PUBWEAK EXTI0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI0_IRQHandler
- B EXTI0_IRQHandler
-
- PUBWEAK EXTI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI1_IRQHandler
- B EXTI1_IRQHandler
-
- PUBWEAK EXTI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI2_IRQHandler
- B EXTI2_IRQHandler
-
- PUBWEAK EXTI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI3_IRQHandler
- B EXTI3_IRQHandler
-
- PUBWEAK EXTI4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI4_IRQHandler
- B EXTI4_IRQHandler
-
- PUBWEAK DMA1_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel1_IRQHandler
- B DMA1_Channel1_IRQHandler
-
- PUBWEAK DMA1_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel2_IRQHandler
- B DMA1_Channel2_IRQHandler
-
- PUBWEAK DMA1_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel3_IRQHandler
- B DMA1_Channel3_IRQHandler
-
- PUBWEAK DMA1_Channel4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel4_IRQHandler
- B DMA1_Channel4_IRQHandler
-
- PUBWEAK DMA1_Channel5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel5_IRQHandler
- B DMA1_Channel5_IRQHandler
-
- PUBWEAK DMA1_Channel6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel6_IRQHandler
- B DMA1_Channel6_IRQHandler
-
- PUBWEAK DMA1_Channel7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel7_IRQHandler
- B DMA1_Channel7_IRQHandler
-
- PUBWEAK ADC1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ADC1_IRQHandler
- B ADC1_IRQHandler
-
- PUBWEAK USB_HP_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USB_HP_IRQHandler
- B USB_HP_IRQHandler
-
- PUBWEAK USB_LP_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USB_LP_IRQHandler
- B USB_LP_IRQHandler
-
- PUBWEAK EXTI9_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI9_5_IRQHandler
- B EXTI9_5_IRQHandler
-
- PUBWEAK TIM2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM2_IRQHandler
- B TIM2_IRQHandler
-
- PUBWEAK TIM3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM3_IRQHandler
- B TIM3_IRQHandler
-
- PUBWEAK I2C1_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_EV_IRQHandler
- B I2C1_EV_IRQHandler
-
- PUBWEAK I2C1_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_ER_IRQHandler
- B I2C1_ER_IRQHandler
-
- PUBWEAK SPI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI1_IRQHandler
- B SPI1_IRQHandler
-
- PUBWEAK USART1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART1_IRQHandler
- B USART1_IRQHandler
-
- PUBWEAK USART2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART2_IRQHandler
- B USART2_IRQHandler
-
- PUBWEAK EXTI15_10_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI15_10_IRQHandler
- B EXTI15_10_IRQHandler
-
- PUBWEAK RTC_Alarm_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_Alarm_IRQHandler
- B RTC_Alarm_IRQHandler
-
- PUBWEAK USBWakeUp_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USBWakeUp_IRQHandler
- B USBWakeUp_IRQHandler
-
- END
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f102xb.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f102xb.s
deleted file mode 100644
index 099c304..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f102xb.s
+++ /dev/null
@@ -1,380 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f102xb.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F102xB USB Line Devices vector table for
-;* EWARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Configure the clock system
-;* - Set the initial PC == __iar_program_start,
-;* - Set the vector table entries with the exceptions ISR
-;* address.
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;*
-;*******************************************************************************
-;
-;
-; The modules in this file are included in the libraries, and may be replaced
-; by any user-defined modules that define the PUBLIC symbol _program_start or
-; a user defined start symbol.
-; To override the cstartup defined in the library, simply add your modified
-; version to the workbench project.
-;
-; The vector table is normally located at address 0.
-; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
-; The name "__vector_table" has special meaning for C-SPY:
-; it is where the SP start value is found, and the NVIC vector
-; table register (VTOR) is initialized to this address if != 0.
-;
-; Cortex-M version
-;
-
- MODULE ?cstartup
-
- ;; Forward declaration of sections.
- SECTION CSTACK:DATA:NOROOT(3)
-
- SECTION .intvec:CODE:NOROOT(2)
-
- EXTERN __iar_program_start
- EXTERN SystemInit
- PUBLIC __vector_table
-
- DATA
-__vector_table
- DCD sfe(CSTACK)
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_IRQHandler ; ADC1
- DCD USB_HP_IRQHandler ; USB High Priority
- DCD USB_LP_IRQHandler ; USB Low Priority
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C2 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Default interrupt handlers.
-;;
- THUMB
-
- PUBWEAK Reset_Handler
- SECTION .text:CODE:REORDER:NOROOT(2)
-Reset_Handler
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__iar_program_start
- BX R0
-
- PUBWEAK NMI_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-NMI_Handler
- B NMI_Handler
-
- PUBWEAK HardFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-HardFault_Handler
- B HardFault_Handler
-
- PUBWEAK MemManage_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-MemManage_Handler
- B MemManage_Handler
-
- PUBWEAK BusFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-BusFault_Handler
- B BusFault_Handler
-
- PUBWEAK UsageFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UsageFault_Handler
- B UsageFault_Handler
-
- PUBWEAK SVC_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SVC_Handler
- B SVC_Handler
-
- PUBWEAK DebugMon_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DebugMon_Handler
- B DebugMon_Handler
-
- PUBWEAK PendSV_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PendSV_Handler
- B PendSV_Handler
-
- PUBWEAK SysTick_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SysTick_Handler
- B SysTick_Handler
-
- PUBWEAK WWDG_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-WWDG_IRQHandler
- B WWDG_IRQHandler
-
- PUBWEAK PVD_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PVD_IRQHandler
- B PVD_IRQHandler
-
- PUBWEAK TAMPER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TAMPER_IRQHandler
- B TAMPER_IRQHandler
-
- PUBWEAK RTC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_IRQHandler
- B RTC_IRQHandler
-
- PUBWEAK FLASH_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-FLASH_IRQHandler
- B FLASH_IRQHandler
-
- PUBWEAK RCC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RCC_IRQHandler
- B RCC_IRQHandler
-
- PUBWEAK EXTI0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI0_IRQHandler
- B EXTI0_IRQHandler
-
- PUBWEAK EXTI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI1_IRQHandler
- B EXTI1_IRQHandler
-
- PUBWEAK EXTI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI2_IRQHandler
- B EXTI2_IRQHandler
-
- PUBWEAK EXTI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI3_IRQHandler
- B EXTI3_IRQHandler
-
- PUBWEAK EXTI4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI4_IRQHandler
- B EXTI4_IRQHandler
-
- PUBWEAK DMA1_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel1_IRQHandler
- B DMA1_Channel1_IRQHandler
-
- PUBWEAK DMA1_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel2_IRQHandler
- B DMA1_Channel2_IRQHandler
-
- PUBWEAK DMA1_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel3_IRQHandler
- B DMA1_Channel3_IRQHandler
-
- PUBWEAK DMA1_Channel4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel4_IRQHandler
- B DMA1_Channel4_IRQHandler
-
- PUBWEAK DMA1_Channel5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel5_IRQHandler
- B DMA1_Channel5_IRQHandler
-
- PUBWEAK DMA1_Channel6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel6_IRQHandler
- B DMA1_Channel6_IRQHandler
-
- PUBWEAK DMA1_Channel7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel7_IRQHandler
- B DMA1_Channel7_IRQHandler
-
- PUBWEAK ADC1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ADC1_IRQHandler
- B ADC1_IRQHandler
-
- PUBWEAK USB_HP_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USB_HP_IRQHandler
- B USB_HP_IRQHandler
-
- PUBWEAK USB_LP_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USB_LP_IRQHandler
- B USB_LP_IRQHandler
-
- PUBWEAK EXTI9_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI9_5_IRQHandler
- B EXTI9_5_IRQHandler
-
- PUBWEAK TIM2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM2_IRQHandler
- B TIM2_IRQHandler
-
- PUBWEAK TIM3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM3_IRQHandler
- B TIM3_IRQHandler
-
- PUBWEAK TIM4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM4_IRQHandler
- B TIM4_IRQHandler
-
- PUBWEAK I2C1_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_EV_IRQHandler
- B I2C1_EV_IRQHandler
-
- PUBWEAK I2C1_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_ER_IRQHandler
- B I2C1_ER_IRQHandler
-
- PUBWEAK I2C2_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_EV_IRQHandler
- B I2C2_EV_IRQHandler
-
- PUBWEAK I2C2_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_ER_IRQHandler
- B I2C2_ER_IRQHandler
-
- PUBWEAK SPI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI1_IRQHandler
- B SPI1_IRQHandler
-
- PUBWEAK SPI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI2_IRQHandler
- B SPI2_IRQHandler
-
- PUBWEAK USART1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART1_IRQHandler
- B USART1_IRQHandler
-
- PUBWEAK USART2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART2_IRQHandler
- B USART2_IRQHandler
-
- PUBWEAK USART3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART3_IRQHandler
- B USART3_IRQHandler
-
- PUBWEAK EXTI15_10_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI15_10_IRQHandler
- B EXTI15_10_IRQHandler
-
- PUBWEAK RTC_Alarm_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_Alarm_IRQHandler
- B RTC_Alarm_IRQHandler
-
- PUBWEAK USBWakeUp_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USBWakeUp_IRQHandler
- B USBWakeUp_IRQHandler
-
- END
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103x6.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103x6.s
deleted file mode 100644
index 14b1653..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103x6.s
+++ /dev/null
@@ -1,385 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f103x6.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F103x6 Performance Line Devices vector table for EWARM
-;* toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Configure the clock system
-;* - Set the initial PC == __iar_program_start,
-;* - Set the vector table entries with the exceptions ISR
-;* address.
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;*
-;*******************************************************************************
-;
-;
-; The modules in this file are included in the libraries, and may be replaced
-; by any user-defined modules that define the PUBLIC symbol _program_start or
-; a user defined start symbol.
-; To override the cstartup defined in the library, simply add your modified
-; version to the workbench project.
-;
-; The vector table is normally located at address 0.
-; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
-; The name "__vector_table" has special meaning for C-SPY:
-; it is where the SP start value is found, and the NVIC vector
-; table register (VTOR) is initialized to this address if != 0.
-;
-; Cortex-M version
-;
-
- MODULE ?cstartup
-
- ;; Forward declaration of sections.
- SECTION CSTACK:DATA:NOROOT(3)
-
- SECTION .intvec:CODE:NOROOT(2)
-
- EXTERN __iar_program_start
- EXTERN SystemInit
- PUBLIC __vector_table
-
- DATA
-__vector_table
- DCD sfe(CSTACK)
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_2_IRQHandler ; ADC1 & ADC2
- DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
- DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
- DCD CAN1_RX1_IRQHandler ; CAN1 RX1
- DCD CAN1_SCE_IRQHandler ; CAN1 SCE
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD TIM1_BRK_IRQHandler ; TIM1 Break
- DCD TIM1_UP_IRQHandler ; TIM1 Update
- DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
- DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD 0 ; Reserved
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SPI1_IRQHandler ; SPI1
- DCD 0 ; Reserved
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD 0 ; Reserved
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Default interrupt handlers.
-;;
- THUMB
-
- PUBWEAK Reset_Handler
- SECTION .text:CODE:REORDER:NOROOT(2)
-Reset_Handler
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__iar_program_start
- BX R0
-
- PUBWEAK NMI_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-NMI_Handler
- B NMI_Handler
-
- PUBWEAK HardFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-HardFault_Handler
- B HardFault_Handler
-
- PUBWEAK MemManage_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-MemManage_Handler
- B MemManage_Handler
-
- PUBWEAK BusFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-BusFault_Handler
- B BusFault_Handler
-
- PUBWEAK UsageFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UsageFault_Handler
- B UsageFault_Handler
-
- PUBWEAK SVC_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SVC_Handler
- B SVC_Handler
-
- PUBWEAK DebugMon_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DebugMon_Handler
- B DebugMon_Handler
-
- PUBWEAK PendSV_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PendSV_Handler
- B PendSV_Handler
-
- PUBWEAK SysTick_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SysTick_Handler
- B SysTick_Handler
-
- PUBWEAK WWDG_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-WWDG_IRQHandler
- B WWDG_IRQHandler
-
- PUBWEAK PVD_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PVD_IRQHandler
- B PVD_IRQHandler
-
- PUBWEAK TAMPER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TAMPER_IRQHandler
- B TAMPER_IRQHandler
-
- PUBWEAK RTC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_IRQHandler
- B RTC_IRQHandler
-
- PUBWEAK FLASH_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-FLASH_IRQHandler
- B FLASH_IRQHandler
-
- PUBWEAK RCC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RCC_IRQHandler
- B RCC_IRQHandler
-
- PUBWEAK EXTI0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI0_IRQHandler
- B EXTI0_IRQHandler
-
- PUBWEAK EXTI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI1_IRQHandler
- B EXTI1_IRQHandler
-
- PUBWEAK EXTI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI2_IRQHandler
- B EXTI2_IRQHandler
-
- PUBWEAK EXTI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI3_IRQHandler
- B EXTI3_IRQHandler
-
- PUBWEAK EXTI4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI4_IRQHandler
- B EXTI4_IRQHandler
-
- PUBWEAK DMA1_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel1_IRQHandler
- B DMA1_Channel1_IRQHandler
-
- PUBWEAK DMA1_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel2_IRQHandler
- B DMA1_Channel2_IRQHandler
-
- PUBWEAK DMA1_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel3_IRQHandler
- B DMA1_Channel3_IRQHandler
-
- PUBWEAK DMA1_Channel4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel4_IRQHandler
- B DMA1_Channel4_IRQHandler
-
- PUBWEAK DMA1_Channel5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel5_IRQHandler
- B DMA1_Channel5_IRQHandler
-
- PUBWEAK DMA1_Channel6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel6_IRQHandler
- B DMA1_Channel6_IRQHandler
-
- PUBWEAK DMA1_Channel7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel7_IRQHandler
- B DMA1_Channel7_IRQHandler
-
- PUBWEAK ADC1_2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ADC1_2_IRQHandler
- B ADC1_2_IRQHandler
-
- PUBWEAK USB_HP_CAN1_TX_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USB_HP_CAN1_TX_IRQHandler
- B USB_HP_CAN1_TX_IRQHandler
-
- PUBWEAK USB_LP_CAN1_RX0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USB_LP_CAN1_RX0_IRQHandler
- B USB_LP_CAN1_RX0_IRQHandler
-
- PUBWEAK CAN1_RX1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN1_RX1_IRQHandler
- B CAN1_RX1_IRQHandler
-
- PUBWEAK CAN1_SCE_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN1_SCE_IRQHandler
- B CAN1_SCE_IRQHandler
-
- PUBWEAK EXTI9_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI9_5_IRQHandler
- B EXTI9_5_IRQHandler
-
- PUBWEAK TIM1_BRK_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_BRK_IRQHandler
- B TIM1_BRK_IRQHandler
-
- PUBWEAK TIM1_UP_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_UP_IRQHandler
- B TIM1_UP_IRQHandler
-
- PUBWEAK TIM1_TRG_COM_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_TRG_COM_IRQHandler
- B TIM1_TRG_COM_IRQHandler
-
- PUBWEAK TIM1_CC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_CC_IRQHandler
- B TIM1_CC_IRQHandler
-
- PUBWEAK TIM2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM2_IRQHandler
- B TIM2_IRQHandler
-
- PUBWEAK TIM3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM3_IRQHandler
- B TIM3_IRQHandler
-
- PUBWEAK I2C1_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_EV_IRQHandler
- B I2C1_EV_IRQHandler
-
- PUBWEAK I2C1_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_ER_IRQHandler
- B I2C1_ER_IRQHandler
-
- PUBWEAK SPI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI1_IRQHandler
- B SPI1_IRQHandler
-
- PUBWEAK USART1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART1_IRQHandler
- B USART1_IRQHandler
-
- PUBWEAK USART2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART2_IRQHandler
- B USART2_IRQHandler
-
- PUBWEAK EXTI15_10_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI15_10_IRQHandler
- B EXTI15_10_IRQHandler
-
- PUBWEAK RTC_Alarm_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_Alarm_IRQHandler
- B RTC_Alarm_IRQHandler
-
- PUBWEAK USBWakeUp_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USBWakeUp_IRQHandler
- B USBWakeUp_IRQHandler
-
- END
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103xb.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103xb.s
deleted file mode 100644
index 101a3d5..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103xb.s
+++ /dev/null
@@ -1,410 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f103xb.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F103xB Performance Line Devices vector table for
-;* EWARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Configure the clock system
-;* - Set the initial PC == __iar_program_start,
-;* - Set the vector table entries with the exceptions ISR
-;* address.
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;*
-;*******************************************************************************
-;
-;
-; The modules in this file are included in the libraries, and may be replaced
-; by any user-defined modules that define the PUBLIC symbol _program_start or
-; a user defined start symbol.
-; To override the cstartup defined in the library, simply add your modified
-; version to the workbench project.
-;
-; The vector table is normally located at address 0.
-; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
-; The name "__vector_table" has special meaning for C-SPY:
-; it is where the SP start value is found, and the NVIC vector
-; table register (VTOR) is initialized to this address if != 0.
-;
-; Cortex-M version
-;
-
- MODULE ?cstartup
-
- ;; Forward declaration of sections.
- SECTION CSTACK:DATA:NOROOT(3)
-
- SECTION .intvec:CODE:NOROOT(2)
-
- EXTERN __iar_program_start
- EXTERN SystemInit
- PUBLIC __vector_table
-
- DATA
-__vector_table
- DCD sfe(CSTACK)
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_2_IRQHandler ; ADC1 & ADC2
- DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
- DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
- DCD CAN1_RX1_IRQHandler ; CAN1 RX1
- DCD CAN1_SCE_IRQHandler ; CAN1 SCE
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD TIM1_BRK_IRQHandler ; TIM1 Break
- DCD TIM1_UP_IRQHandler ; TIM1 Update
- DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
- DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C2 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Default interrupt handlers.
-;;
- THUMB
-
- PUBWEAK Reset_Handler
- SECTION .text:CODE:REORDER:NOROOT(2)
-Reset_Handler
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__iar_program_start
- BX R0
-
- PUBWEAK NMI_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-NMI_Handler
- B NMI_Handler
-
- PUBWEAK HardFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-HardFault_Handler
- B HardFault_Handler
-
- PUBWEAK MemManage_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-MemManage_Handler
- B MemManage_Handler
-
- PUBWEAK BusFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-BusFault_Handler
- B BusFault_Handler
-
- PUBWEAK UsageFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UsageFault_Handler
- B UsageFault_Handler
-
- PUBWEAK SVC_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SVC_Handler
- B SVC_Handler
-
- PUBWEAK DebugMon_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DebugMon_Handler
- B DebugMon_Handler
-
- PUBWEAK PendSV_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PendSV_Handler
- B PendSV_Handler
-
- PUBWEAK SysTick_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SysTick_Handler
- B SysTick_Handler
-
- PUBWEAK WWDG_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-WWDG_IRQHandler
- B WWDG_IRQHandler
-
- PUBWEAK PVD_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PVD_IRQHandler
- B PVD_IRQHandler
-
- PUBWEAK TAMPER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TAMPER_IRQHandler
- B TAMPER_IRQHandler
-
- PUBWEAK RTC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_IRQHandler
- B RTC_IRQHandler
-
- PUBWEAK FLASH_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-FLASH_IRQHandler
- B FLASH_IRQHandler
-
- PUBWEAK RCC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RCC_IRQHandler
- B RCC_IRQHandler
-
- PUBWEAK EXTI0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI0_IRQHandler
- B EXTI0_IRQHandler
-
- PUBWEAK EXTI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI1_IRQHandler
- B EXTI1_IRQHandler
-
- PUBWEAK EXTI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI2_IRQHandler
- B EXTI2_IRQHandler
-
- PUBWEAK EXTI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI3_IRQHandler
- B EXTI3_IRQHandler
-
- PUBWEAK EXTI4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI4_IRQHandler
- B EXTI4_IRQHandler
-
- PUBWEAK DMA1_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel1_IRQHandler
- B DMA1_Channel1_IRQHandler
-
- PUBWEAK DMA1_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel2_IRQHandler
- B DMA1_Channel2_IRQHandler
-
- PUBWEAK DMA1_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel3_IRQHandler
- B DMA1_Channel3_IRQHandler
-
- PUBWEAK DMA1_Channel4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel4_IRQHandler
- B DMA1_Channel4_IRQHandler
-
- PUBWEAK DMA1_Channel5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel5_IRQHandler
- B DMA1_Channel5_IRQHandler
-
- PUBWEAK DMA1_Channel6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel6_IRQHandler
- B DMA1_Channel6_IRQHandler
-
- PUBWEAK DMA1_Channel7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel7_IRQHandler
- B DMA1_Channel7_IRQHandler
-
- PUBWEAK ADC1_2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ADC1_2_IRQHandler
- B ADC1_2_IRQHandler
-
- PUBWEAK USB_HP_CAN1_TX_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USB_HP_CAN1_TX_IRQHandler
- B USB_HP_CAN1_TX_IRQHandler
-
- PUBWEAK USB_LP_CAN1_RX0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USB_LP_CAN1_RX0_IRQHandler
- B USB_LP_CAN1_RX0_IRQHandler
-
- PUBWEAK CAN1_RX1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN1_RX1_IRQHandler
- B CAN1_RX1_IRQHandler
-
- PUBWEAK CAN1_SCE_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN1_SCE_IRQHandler
- B CAN1_SCE_IRQHandler
-
- PUBWEAK EXTI9_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI9_5_IRQHandler
- B EXTI9_5_IRQHandler
-
- PUBWEAK TIM1_BRK_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_BRK_IRQHandler
- B TIM1_BRK_IRQHandler
-
- PUBWEAK TIM1_UP_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_UP_IRQHandler
- B TIM1_UP_IRQHandler
-
- PUBWEAK TIM1_TRG_COM_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_TRG_COM_IRQHandler
- B TIM1_TRG_COM_IRQHandler
-
- PUBWEAK TIM1_CC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_CC_IRQHandler
- B TIM1_CC_IRQHandler
-
- PUBWEAK TIM2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM2_IRQHandler
- B TIM2_IRQHandler
-
- PUBWEAK TIM3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM3_IRQHandler
- B TIM3_IRQHandler
-
- PUBWEAK TIM4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM4_IRQHandler
- B TIM4_IRQHandler
-
- PUBWEAK I2C1_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_EV_IRQHandler
- B I2C1_EV_IRQHandler
-
- PUBWEAK I2C1_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_ER_IRQHandler
- B I2C1_ER_IRQHandler
-
- PUBWEAK I2C2_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_EV_IRQHandler
- B I2C2_EV_IRQHandler
-
- PUBWEAK I2C2_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_ER_IRQHandler
- B I2C2_ER_IRQHandler
-
- PUBWEAK SPI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI1_IRQHandler
- B SPI1_IRQHandler
-
- PUBWEAK SPI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI2_IRQHandler
- B SPI2_IRQHandler
-
- PUBWEAK USART1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART1_IRQHandler
- B USART1_IRQHandler
-
- PUBWEAK USART2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART2_IRQHandler
- B USART2_IRQHandler
-
- PUBWEAK USART3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART3_IRQHandler
- B USART3_IRQHandler
-
- PUBWEAK EXTI15_10_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI15_10_IRQHandler
- B EXTI15_10_IRQHandler
-
- PUBWEAK RTC_Alarm_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_Alarm_IRQHandler
- B RTC_Alarm_IRQHandler
-
- PUBWEAK USBWakeUp_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USBWakeUp_IRQHandler
- B USBWakeUp_IRQHandler
-
- END
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103xe.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103xe.s
deleted file mode 100644
index f5ee1e8..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103xe.s
+++ /dev/null
@@ -1,515 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f103xe.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F103xE Performance Line Devices vector table for EWARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == __iar_program_start,
-;* - Set the vector table entries with the exceptions ISR
-;* address.
-;* - Configure the system clock
-;* - Branches to main in the C library (which eventually
-;* calls main()).
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;*
-;*******************************************************************************
-;
-;
-; The modules in this file are included in the libraries, and may be replaced
-; by any user-defined modules that define the PUBLIC symbol _program_start or
-; a user defined start symbol.
-; To override the cstartup defined in the library, simply add your modified
-; version to the workbench project.
-;
-; The vector table is normally located at address 0.
-; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
-; The name "__vector_table" has special meaning for C-SPY:
-; it is where the SP start value is found, and the NVIC vector
-; table register (VTOR) is initialized to this address if != 0.
-;
-; Cortex-M version
-;
-
- MODULE ?cstartup
-
- ;; Forward declaration of sections.
- SECTION CSTACK:DATA:NOROOT(3)
-
- SECTION .intvec:CODE:NOROOT(2)
-
- EXTERN __iar_program_start
- EXTERN SystemInit
- PUBLIC __vector_table
-
- DATA
-
-__vector_table
- DCD sfe(CSTACK)
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_2_IRQHandler ; ADC1 & ADC2
- DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
- DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
- DCD CAN1_RX1_IRQHandler ; CAN1 RX1
- DCD CAN1_SCE_IRQHandler ; CAN1 SCE
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD TIM1_BRK_IRQHandler ; TIM1 Break
- DCD TIM1_UP_IRQHandler ; TIM1 Update
- DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
- DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C2 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
- DCD TIM8_BRK_IRQHandler ; TIM8 Break
- DCD TIM8_UP_IRQHandler ; TIM8 Update
- DCD TIM8_TRG_COM_IRQHandler ; TIM8 Trigger and Commutation
- DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare
- DCD ADC3_IRQHandler ; ADC3
- DCD FSMC_IRQHandler ; FSMC
- DCD SDIO_IRQHandler ; SDIO
- DCD TIM5_IRQHandler ; TIM5
- DCD SPI3_IRQHandler ; SPI3
- DCD UART4_IRQHandler ; UART4
- DCD UART5_IRQHandler ; UART5
- DCD TIM6_IRQHandler ; TIM6
- DCD TIM7_IRQHandler ; TIM7
- DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
- DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
- DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
- DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Default interrupt handlers.
-;;
- THUMB
-
- PUBWEAK Reset_Handler
- SECTION .text:CODE:REORDER:NOROOT(2)
-Reset_Handler
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__iar_program_start
- BX R0
-
- PUBWEAK NMI_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-NMI_Handler
- B NMI_Handler
-
- PUBWEAK HardFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-HardFault_Handler
- B HardFault_Handler
-
- PUBWEAK MemManage_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-MemManage_Handler
- B MemManage_Handler
-
- PUBWEAK BusFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-BusFault_Handler
- B BusFault_Handler
-
- PUBWEAK UsageFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UsageFault_Handler
- B UsageFault_Handler
-
- PUBWEAK SVC_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SVC_Handler
- B SVC_Handler
-
- PUBWEAK DebugMon_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DebugMon_Handler
- B DebugMon_Handler
-
- PUBWEAK PendSV_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PendSV_Handler
- B PendSV_Handler
-
- PUBWEAK SysTick_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SysTick_Handler
- B SysTick_Handler
-
- PUBWEAK WWDG_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-WWDG_IRQHandler
- B WWDG_IRQHandler
-
- PUBWEAK PVD_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PVD_IRQHandler
- B PVD_IRQHandler
-
- PUBWEAK TAMPER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TAMPER_IRQHandler
- B TAMPER_IRQHandler
-
- PUBWEAK RTC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_IRQHandler
- B RTC_IRQHandler
-
- PUBWEAK FLASH_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-FLASH_IRQHandler
- B FLASH_IRQHandler
-
- PUBWEAK RCC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RCC_IRQHandler
- B RCC_IRQHandler
-
- PUBWEAK EXTI0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI0_IRQHandler
- B EXTI0_IRQHandler
-
- PUBWEAK EXTI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI1_IRQHandler
- B EXTI1_IRQHandler
-
- PUBWEAK EXTI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI2_IRQHandler
- B EXTI2_IRQHandler
-
- PUBWEAK EXTI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI3_IRQHandler
- B EXTI3_IRQHandler
-
- PUBWEAK EXTI4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI4_IRQHandler
- B EXTI4_IRQHandler
-
- PUBWEAK DMA1_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel1_IRQHandler
- B DMA1_Channel1_IRQHandler
-
- PUBWEAK DMA1_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel2_IRQHandler
- B DMA1_Channel2_IRQHandler
-
- PUBWEAK DMA1_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel3_IRQHandler
- B DMA1_Channel3_IRQHandler
-
- PUBWEAK DMA1_Channel4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel4_IRQHandler
- B DMA1_Channel4_IRQHandler
-
- PUBWEAK DMA1_Channel5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel5_IRQHandler
- B DMA1_Channel5_IRQHandler
-
- PUBWEAK DMA1_Channel6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel6_IRQHandler
- B DMA1_Channel6_IRQHandler
-
- PUBWEAK DMA1_Channel7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel7_IRQHandler
- B DMA1_Channel7_IRQHandler
-
- PUBWEAK ADC1_2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ADC1_2_IRQHandler
- B ADC1_2_IRQHandler
-
- PUBWEAK USB_HP_CAN1_TX_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USB_HP_CAN1_TX_IRQHandler
- B USB_HP_CAN1_TX_IRQHandler
-
- PUBWEAK USB_LP_CAN1_RX0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USB_LP_CAN1_RX0_IRQHandler
- B USB_LP_CAN1_RX0_IRQHandler
-
- PUBWEAK CAN1_RX1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN1_RX1_IRQHandler
- B CAN1_RX1_IRQHandler
-
- PUBWEAK CAN1_SCE_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN1_SCE_IRQHandler
- B CAN1_SCE_IRQHandler
-
- PUBWEAK EXTI9_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI9_5_IRQHandler
- B EXTI9_5_IRQHandler
-
- PUBWEAK TIM1_BRK_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_BRK_IRQHandler
- B TIM1_BRK_IRQHandler
-
- PUBWEAK TIM1_UP_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_UP_IRQHandler
- B TIM1_UP_IRQHandler
-
- PUBWEAK TIM1_TRG_COM_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_TRG_COM_IRQHandler
- B TIM1_TRG_COM_IRQHandler
-
- PUBWEAK TIM1_CC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_CC_IRQHandler
- B TIM1_CC_IRQHandler
-
- PUBWEAK TIM2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM2_IRQHandler
- B TIM2_IRQHandler
-
- PUBWEAK TIM3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM3_IRQHandler
- B TIM3_IRQHandler
-
- PUBWEAK TIM4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM4_IRQHandler
- B TIM4_IRQHandler
-
- PUBWEAK I2C1_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_EV_IRQHandler
- B I2C1_EV_IRQHandler
-
- PUBWEAK I2C1_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_ER_IRQHandler
- B I2C1_ER_IRQHandler
-
- PUBWEAK I2C2_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_EV_IRQHandler
- B I2C2_EV_IRQHandler
-
- PUBWEAK I2C2_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_ER_IRQHandler
- B I2C2_ER_IRQHandler
-
- PUBWEAK SPI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI1_IRQHandler
- B SPI1_IRQHandler
-
- PUBWEAK SPI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI2_IRQHandler
- B SPI2_IRQHandler
-
- PUBWEAK USART1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART1_IRQHandler
- B USART1_IRQHandler
-
- PUBWEAK USART2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART2_IRQHandler
- B USART2_IRQHandler
-
- PUBWEAK USART3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART3_IRQHandler
- B USART3_IRQHandler
-
- PUBWEAK EXTI15_10_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI15_10_IRQHandler
- B EXTI15_10_IRQHandler
-
- PUBWEAK RTC_Alarm_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_Alarm_IRQHandler
- B RTC_Alarm_IRQHandler
-
- PUBWEAK USBWakeUp_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USBWakeUp_IRQHandler
- B USBWakeUp_IRQHandler
-
- PUBWEAK TIM8_BRK_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM8_BRK_IRQHandler
- B TIM8_BRK_IRQHandler
-
- PUBWEAK TIM8_UP_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM8_UP_IRQHandler
- B TIM8_UP_IRQHandler
-
- PUBWEAK TIM8_TRG_COM_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM8_TRG_COM_IRQHandler
- B TIM8_TRG_COM_IRQHandler
-
- PUBWEAK TIM8_CC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM8_CC_IRQHandler
- B TIM8_CC_IRQHandler
-
- PUBWEAK ADC3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ADC3_IRQHandler
- B ADC3_IRQHandler
-
- PUBWEAK FSMC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-FSMC_IRQHandler
- B FSMC_IRQHandler
-
- PUBWEAK SDIO_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SDIO_IRQHandler
- B SDIO_IRQHandler
-
- PUBWEAK TIM5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM5_IRQHandler
- B TIM5_IRQHandler
-
- PUBWEAK SPI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI3_IRQHandler
- B SPI3_IRQHandler
-
- PUBWEAK UART4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UART4_IRQHandler
- B UART4_IRQHandler
-
- PUBWEAK UART5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UART5_IRQHandler
- B UART5_IRQHandler
-
- PUBWEAK TIM6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM6_IRQHandler
- B TIM6_IRQHandler
-
- PUBWEAK TIM7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM7_IRQHandler
- B TIM7_IRQHandler
-
- PUBWEAK DMA2_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel1_IRQHandler
- B DMA2_Channel1_IRQHandler
-
- PUBWEAK DMA2_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel2_IRQHandler
- B DMA2_Channel2_IRQHandler
-
- PUBWEAK DMA2_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel3_IRQHandler
- B DMA2_Channel3_IRQHandler
-
- PUBWEAK DMA2_Channel4_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel4_5_IRQHandler
- B DMA2_Channel4_5_IRQHandler
-
-
- END
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103xg.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103xg.s
deleted file mode 100644
index f745b4b..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103xg.s
+++ /dev/null
@@ -1,512 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
-;* File Name : startup_stm32f103xg.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F103xG Performances Line Devices vector table for EWARM
-;* toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Set the initial PC == __iar_program_start,
-;* - Set the vector table entries with the exceptions ISR address,
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;*
-;*******************************************************************************
-;
-;
-; The modules in this file are included in the libraries, and may be replaced
-; by any user-defined modules that define the PUBLIC symbol _program_start or
-; a user defined start symbol.
-; To override the cstartup defined in the library, simply add your modified
-; version to the workbench project.
-;
-; The vector table is normally located at address 0.
-; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
-; The name "__vector_table" has special meaning for C-SPY:
-; it is where the SP start value is found, and the NVIC vector
-; table register (VTOR) is initialized to this address if != 0.
-;
-; Cortex-M version
-;
-
- MODULE ?cstartup
-
- ;; Forward declaration of sections.
- SECTION CSTACK:DATA:NOROOT(3)
-
- SECTION .intvec:CODE:NOROOT(2)
-
- EXTERN __iar_program_start
- EXTERN SystemInit
- PUBLIC __vector_table
-
- DATA
-
-__vector_table
- DCD sfe(CSTACK)
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_2_IRQHandler ; ADC1 & ADC2
- DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
- DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
- DCD CAN1_RX1_IRQHandler ; CAN1 RX1
- DCD CAN1_SCE_IRQHandler ; CAN1 SCE
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD TIM1_BRK_TIM9_IRQHandler ; TIM1 Break and TIM9
- DCD TIM1_UP_TIM10_IRQHandler ; TIM1 Update and TIM10
- DCD TIM1_TRG_COM_TIM11_IRQHandler ; TIM1 Trigger and Commutation and TIM11
- DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C2 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
- DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
- DCD TIM8_BRK_TIM12_IRQHandler ; TIM8 Break and TIM12
- DCD TIM8_UP_TIM13_IRQHandler ; TIM8 Update and TIM13
- DCD TIM8_TRG_COM_TIM14_IRQHandler ; TIM8 Trigger and Commutation and TIM14
- DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare
- DCD ADC3_IRQHandler ; ADC3
- DCD FSMC_IRQHandler ; FSMC
- DCD SDIO_IRQHandler ; SDIO
- DCD TIM5_IRQHandler ; TIM5
- DCD SPI3_IRQHandler ; SPI3
- DCD UART4_IRQHandler ; UART4
- DCD UART5_IRQHandler ; UART5
- DCD TIM6_IRQHandler ; TIM6
- DCD TIM7_IRQHandler ; TIM7
- DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
- DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
- DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
- DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Default interrupt handlers.
-;;
- THUMB
-
- PUBWEAK Reset_Handler
- SECTION .text:CODE:REORDER:NOROOT(2)
-Reset_Handler
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__iar_program_start
- BX R0
-
- PUBWEAK NMI_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-NMI_Handler
- B NMI_Handler
-
- PUBWEAK HardFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-HardFault_Handler
- B HardFault_Handler
-
- PUBWEAK MemManage_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-MemManage_Handler
- B MemManage_Handler
-
- PUBWEAK BusFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-BusFault_Handler
- B BusFault_Handler
-
- PUBWEAK UsageFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UsageFault_Handler
- B UsageFault_Handler
-
- PUBWEAK SVC_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SVC_Handler
- B SVC_Handler
-
- PUBWEAK DebugMon_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DebugMon_Handler
- B DebugMon_Handler
-
- PUBWEAK PendSV_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PendSV_Handler
- B PendSV_Handler
-
- PUBWEAK SysTick_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SysTick_Handler
- B SysTick_Handler
-
- PUBWEAK WWDG_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-WWDG_IRQHandler
- B WWDG_IRQHandler
-
- PUBWEAK PVD_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PVD_IRQHandler
- B PVD_IRQHandler
-
- PUBWEAK TAMPER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TAMPER_IRQHandler
- B TAMPER_IRQHandler
-
- PUBWEAK RTC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_IRQHandler
- B RTC_IRQHandler
-
- PUBWEAK FLASH_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-FLASH_IRQHandler
- B FLASH_IRQHandler
-
- PUBWEAK RCC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RCC_IRQHandler
- B RCC_IRQHandler
-
- PUBWEAK EXTI0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI0_IRQHandler
- B EXTI0_IRQHandler
-
- PUBWEAK EXTI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI1_IRQHandler
- B EXTI1_IRQHandler
-
- PUBWEAK EXTI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI2_IRQHandler
- B EXTI2_IRQHandler
-
- PUBWEAK EXTI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI3_IRQHandler
- B EXTI3_IRQHandler
-
- PUBWEAK EXTI4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI4_IRQHandler
- B EXTI4_IRQHandler
-
- PUBWEAK DMA1_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel1_IRQHandler
- B DMA1_Channel1_IRQHandler
-
- PUBWEAK DMA1_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel2_IRQHandler
- B DMA1_Channel2_IRQHandler
-
- PUBWEAK DMA1_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel3_IRQHandler
- B DMA1_Channel3_IRQHandler
-
- PUBWEAK DMA1_Channel4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel4_IRQHandler
- B DMA1_Channel4_IRQHandler
-
- PUBWEAK DMA1_Channel5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel5_IRQHandler
- B DMA1_Channel5_IRQHandler
-
- PUBWEAK DMA1_Channel6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel6_IRQHandler
- B DMA1_Channel6_IRQHandler
-
- PUBWEAK DMA1_Channel7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel7_IRQHandler
- B DMA1_Channel7_IRQHandler
-
- PUBWEAK ADC1_2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ADC1_2_IRQHandler
- B ADC1_2_IRQHandler
-
- PUBWEAK USB_HP_CAN1_TX_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USB_HP_CAN1_TX_IRQHandler
- B USB_HP_CAN1_TX_IRQHandler
-
- PUBWEAK USB_LP_CAN1_RX0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USB_LP_CAN1_RX0_IRQHandler
- B USB_LP_CAN1_RX0_IRQHandler
-
- PUBWEAK CAN1_RX1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN1_RX1_IRQHandler
- B CAN1_RX1_IRQHandler
-
- PUBWEAK CAN1_SCE_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN1_SCE_IRQHandler
- B CAN1_SCE_IRQHandler
-
- PUBWEAK EXTI9_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI9_5_IRQHandler
- B EXTI9_5_IRQHandler
-
- PUBWEAK TIM1_BRK_TIM9_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_BRK_TIM9_IRQHandler
- B TIM1_BRK_TIM9_IRQHandler
-
- PUBWEAK TIM1_UP_TIM10_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_UP_TIM10_IRQHandler
- B TIM1_UP_TIM10_IRQHandler
-
- PUBWEAK TIM1_TRG_COM_TIM11_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_TRG_COM_TIM11_IRQHandler
- B TIM1_TRG_COM_TIM11_IRQHandler
-
- PUBWEAK TIM1_CC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_CC_IRQHandler
- B TIM1_CC_IRQHandler
-
- PUBWEAK TIM2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM2_IRQHandler
- B TIM2_IRQHandler
-
- PUBWEAK TIM3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM3_IRQHandler
- B TIM3_IRQHandler
-
- PUBWEAK TIM4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM4_IRQHandler
- B TIM4_IRQHandler
-
- PUBWEAK I2C1_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_EV_IRQHandler
- B I2C1_EV_IRQHandler
-
- PUBWEAK I2C1_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_ER_IRQHandler
- B I2C1_ER_IRQHandler
-
- PUBWEAK I2C2_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_EV_IRQHandler
- B I2C2_EV_IRQHandler
-
- PUBWEAK I2C2_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_ER_IRQHandler
- B I2C2_ER_IRQHandler
-
- PUBWEAK SPI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI1_IRQHandler
- B SPI1_IRQHandler
-
- PUBWEAK SPI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI2_IRQHandler
- B SPI2_IRQHandler
-
- PUBWEAK USART1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART1_IRQHandler
- B USART1_IRQHandler
-
- PUBWEAK USART2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART2_IRQHandler
- B USART2_IRQHandler
-
- PUBWEAK USART3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART3_IRQHandler
- B USART3_IRQHandler
-
- PUBWEAK EXTI15_10_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI15_10_IRQHandler
- B EXTI15_10_IRQHandler
-
- PUBWEAK RTC_Alarm_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_Alarm_IRQHandler
- B RTC_Alarm_IRQHandler
-
- PUBWEAK USBWakeUp_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USBWakeUp_IRQHandler
- B USBWakeUp_IRQHandler
-
- PUBWEAK TIM8_BRK_TIM12_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM8_BRK_TIM12_IRQHandler
- B TIM8_BRK_TIM12_IRQHandler
-
- PUBWEAK TIM8_UP_TIM13_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM8_UP_TIM13_IRQHandler
- B TIM8_UP_TIM13_IRQHandler
-
- PUBWEAK TIM8_TRG_COM_TIM14_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM8_TRG_COM_TIM14_IRQHandler
- B TIM8_TRG_COM_TIM14_IRQHandler
-
- PUBWEAK TIM8_CC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM8_CC_IRQHandler
- B TIM8_CC_IRQHandler
-
- PUBWEAK ADC3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ADC3_IRQHandler
- B ADC3_IRQHandler
-
- PUBWEAK FSMC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-FSMC_IRQHandler
- B FSMC_IRQHandler
-
- PUBWEAK SDIO_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SDIO_IRQHandler
- B SDIO_IRQHandler
-
- PUBWEAK TIM5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM5_IRQHandler
- B TIM5_IRQHandler
-
- PUBWEAK SPI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI3_IRQHandler
- B SPI3_IRQHandler
-
- PUBWEAK UART4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UART4_IRQHandler
- B UART4_IRQHandler
-
- PUBWEAK UART5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UART5_IRQHandler
- B UART5_IRQHandler
-
- PUBWEAK TIM6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM6_IRQHandler
- B TIM6_IRQHandler
-
- PUBWEAK TIM7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM7_IRQHandler
- B TIM7_IRQHandler
-
- PUBWEAK DMA2_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel1_IRQHandler
- B DMA2_Channel1_IRQHandler
-
- PUBWEAK DMA2_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel2_IRQHandler
- B DMA2_Channel2_IRQHandler
-
- PUBWEAK DMA2_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel3_IRQHandler
- B DMA2_Channel3_IRQHandler
-
- PUBWEAK DMA2_Channel4_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel4_5_IRQHandler
- B DMA2_Channel4_5_IRQHandler
-
-
- END
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f105xc.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f105xc.s
deleted file mode 100644
index 26302e1..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f105xc.s
+++ /dev/null
@@ -1,526 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics *******************
-;* File Name : startup_stm32f105xc.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F105xC Connectivity line devices vector table for
-;* EWARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Configure the clock system
-;* - Set the initial PC == __iar_program_start,
-;* - Set the vector table entries with the exceptions ISR
-;* address.
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;*
-;*******************************************************************************
-;
-;
-; The modules in this file are included in the libraries, and may be replaced
-; by any user-defined modules that define the PUBLIC symbol _program_start or
-; a user defined start symbol.
-; To override the cstartup defined in the library, simply add your modified
-; version to the workbench project.
-;
-; The vector table is normally located at address 0.
-; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
-; The name "__vector_table" has special meaning for C-SPY:
-; it is where the SP start value is found, and the NVIC vector
-; table register (VTOR) is initialized to this address if != 0.
-;
-; Cortex-M version
-;
-
- MODULE ?cstartup
-
- ;; Forward declaration of sections.
- SECTION CSTACK:DATA:NOROOT(3)
-
- SECTION .intvec:CODE:NOROOT(2)
-
- EXTERN __iar_program_start
- EXTERN SystemInit
- PUBLIC __vector_table
-
- DATA
-__vector_table
- DCD sfe(CSTACK)
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_2_IRQHandler ; ADC1 and ADC2
- DCD CAN1_TX_IRQHandler ; CAN1 TX
- DCD CAN1_RX0_IRQHandler ; CAN1 RX0
- DCD CAN1_RX1_IRQHandler ; CAN1 RX1
- DCD CAN1_SCE_IRQHandler ; CAN1 SCE
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD TIM1_BRK_IRQHandler ; TIM1 Break
- DCD TIM1_UP_IRQHandler ; TIM1 Update
- DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
- DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C1 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC alarm through EXTI line
- DCD OTG_FS_WKUP_IRQHandler ; USB OTG FS Wakeup through EXTI line
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD TIM5_IRQHandler ; TIM5
- DCD SPI3_IRQHandler ; SPI3
- DCD UART4_IRQHandler ; UART4
- DCD UART5_IRQHandler ; UART5
- DCD TIM6_IRQHandler ; TIM6
- DCD TIM7_IRQHandler ; TIM7
- DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
- DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
- DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
- DCD DMA2_Channel4_IRQHandler ; DMA2 Channel4
- DCD DMA2_Channel5_IRQHandler ; DMA2 Channel5
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD CAN2_TX_IRQHandler ; CAN2 TX
- DCD CAN2_RX0_IRQHandler ; CAN2 RX0
- DCD CAN2_RX1_IRQHandler ; CAN2 RX1
- DCD CAN2_SCE_IRQHandler ; CAN2 SCE
- DCD OTG_FS_IRQHandler ; USB OTG FS
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Default interrupt handlers.
-;;
- THUMB
-
- PUBWEAK Reset_Handler
- SECTION .text:CODE:REORDER:NOROOT(2)
-Reset_Handler
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__iar_program_start
- BX R0
-
- PUBWEAK NMI_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-NMI_Handler
- B NMI_Handler
-
- PUBWEAK HardFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-HardFault_Handler
- B HardFault_Handler
-
- PUBWEAK MemManage_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-MemManage_Handler
- B MemManage_Handler
-
- PUBWEAK BusFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-BusFault_Handler
- B BusFault_Handler
-
- PUBWEAK UsageFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UsageFault_Handler
- B UsageFault_Handler
-
- PUBWEAK SVC_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SVC_Handler
- B SVC_Handler
-
- PUBWEAK DebugMon_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DebugMon_Handler
- B DebugMon_Handler
-
- PUBWEAK PendSV_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PendSV_Handler
- B PendSV_Handler
-
- PUBWEAK SysTick_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SysTick_Handler
- B SysTick_Handler
-
- PUBWEAK WWDG_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-WWDG_IRQHandler
- B WWDG_IRQHandler
-
- PUBWEAK PVD_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PVD_IRQHandler
- B PVD_IRQHandler
-
- PUBWEAK TAMPER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TAMPER_IRQHandler
- B TAMPER_IRQHandler
-
- PUBWEAK RTC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_IRQHandler
- B RTC_IRQHandler
-
- PUBWEAK FLASH_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-FLASH_IRQHandler
- B FLASH_IRQHandler
-
- PUBWEAK RCC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RCC_IRQHandler
- B RCC_IRQHandler
-
- PUBWEAK EXTI0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI0_IRQHandler
- B EXTI0_IRQHandler
-
- PUBWEAK EXTI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI1_IRQHandler
- B EXTI1_IRQHandler
-
- PUBWEAK EXTI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI2_IRQHandler
- B EXTI2_IRQHandler
-
- PUBWEAK EXTI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI3_IRQHandler
- B EXTI3_IRQHandler
-
-
- PUBWEAK EXTI4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI4_IRQHandler
- B EXTI4_IRQHandler
-
- PUBWEAK DMA1_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel1_IRQHandler
- B DMA1_Channel1_IRQHandler
-
- PUBWEAK DMA1_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel2_IRQHandler
- B DMA1_Channel2_IRQHandler
-
- PUBWEAK DMA1_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel3_IRQHandler
- B DMA1_Channel3_IRQHandler
-
- PUBWEAK DMA1_Channel4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel4_IRQHandler
- B DMA1_Channel4_IRQHandler
-
- PUBWEAK DMA1_Channel5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel5_IRQHandler
- B DMA1_Channel5_IRQHandler
-
- PUBWEAK DMA1_Channel6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel6_IRQHandler
- B DMA1_Channel6_IRQHandler
-
- PUBWEAK DMA1_Channel7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel7_IRQHandler
- B DMA1_Channel7_IRQHandler
-
- PUBWEAK ADC1_2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ADC1_2_IRQHandler
- B ADC1_2_IRQHandler
-
- PUBWEAK CAN1_TX_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN1_TX_IRQHandler
- B CAN1_TX_IRQHandler
-
- PUBWEAK CAN1_RX0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN1_RX0_IRQHandler
- B CAN1_RX0_IRQHandler
-
- PUBWEAK CAN1_RX1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN1_RX1_IRQHandler
- B CAN1_RX1_IRQHandler
-
- PUBWEAK CAN1_SCE_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN1_SCE_IRQHandler
- B CAN1_SCE_IRQHandler
-
- PUBWEAK EXTI9_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI9_5_IRQHandler
- B EXTI9_5_IRQHandler
-
- PUBWEAK TIM1_BRK_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_BRK_IRQHandler
- B TIM1_BRK_IRQHandler
-
- PUBWEAK TIM1_UP_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_UP_IRQHandler
- B TIM1_UP_IRQHandler
-
- PUBWEAK TIM1_TRG_COM_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_TRG_COM_IRQHandler
- B TIM1_TRG_COM_IRQHandler
-
- PUBWEAK TIM1_CC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_CC_IRQHandler
- B TIM1_CC_IRQHandler
-
- PUBWEAK TIM2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM2_IRQHandler
- B TIM2_IRQHandler
-
- PUBWEAK TIM3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM3_IRQHandler
- B TIM3_IRQHandler
-
- PUBWEAK TIM4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM4_IRQHandler
- B TIM4_IRQHandler
-
- PUBWEAK I2C1_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_EV_IRQHandler
- B I2C1_EV_IRQHandler
-
- PUBWEAK I2C1_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_ER_IRQHandler
- B I2C1_ER_IRQHandler
-
- PUBWEAK I2C2_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_EV_IRQHandler
- B I2C2_EV_IRQHandler
-
- PUBWEAK I2C2_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_ER_IRQHandler
- B I2C2_ER_IRQHandler
-
- PUBWEAK SPI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI1_IRQHandler
- B SPI1_IRQHandler
-
- PUBWEAK SPI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI2_IRQHandler
- B SPI2_IRQHandler
-
- PUBWEAK USART1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART1_IRQHandler
- B USART1_IRQHandler
-
- PUBWEAK USART2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART2_IRQHandler
- B USART2_IRQHandler
-
- PUBWEAK USART3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART3_IRQHandler
- B USART3_IRQHandler
-
- PUBWEAK EXTI15_10_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI15_10_IRQHandler
- B EXTI15_10_IRQHandler
-
- PUBWEAK RTC_Alarm_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_Alarm_IRQHandler
- B RTC_Alarm_IRQHandler
-
- PUBWEAK OTG_FS_WKUP_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-OTG_FS_WKUP_IRQHandler
- B OTG_FS_WKUP_IRQHandler
-
- PUBWEAK TIM5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM5_IRQHandler
- B TIM5_IRQHandler
-
- PUBWEAK SPI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI3_IRQHandler
- B SPI3_IRQHandler
-
- PUBWEAK UART4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UART4_IRQHandler
- B UART4_IRQHandler
-
- PUBWEAK UART5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UART5_IRQHandler
- B UART5_IRQHandler
-
- PUBWEAK TIM6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM6_IRQHandler
- B TIM6_IRQHandler
-
- PUBWEAK TIM7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM7_IRQHandler
- B TIM7_IRQHandler
-
- PUBWEAK DMA2_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel1_IRQHandler
- B DMA2_Channel1_IRQHandler
-
- PUBWEAK DMA2_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel2_IRQHandler
- B DMA2_Channel2_IRQHandler
-
- PUBWEAK DMA2_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel3_IRQHandler
- B DMA2_Channel3_IRQHandler
-
- PUBWEAK DMA2_Channel4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel4_IRQHandler
- B DMA2_Channel4_IRQHandler
-
- PUBWEAK DMA2_Channel5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel5_IRQHandler
- B DMA2_Channel5_IRQHandler
-
- PUBWEAK ETH_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ETH_IRQHandler
- B ETH_IRQHandler
-
- PUBWEAK ETH_WKUP_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ETH_WKUP_IRQHandler
- B ETH_WKUP_IRQHandler
-
- PUBWEAK CAN2_TX_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN2_TX_IRQHandler
- B CAN2_TX_IRQHandler
-
- PUBWEAK CAN2_RX0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN2_RX0_IRQHandler
- B CAN2_RX0_IRQHandler
-
- PUBWEAK CAN2_RX1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN2_RX1_IRQHandler
- B CAN2_RX1_IRQHandler
-
- PUBWEAK CAN2_SCE_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN2_SCE_IRQHandler
- B CAN2_SCE_IRQHandler
-
- PUBWEAK OTG_FS_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-OTG_FS_IRQHandler
- B OTG_FS_IRQHandler
-
- END
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f107xc.s b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f107xc.s
deleted file mode 100644
index 635c0d3..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f107xc.s
+++ /dev/null
@@ -1,526 +0,0 @@
-;******************** (C) COPYRIGHT 2017 STMicroelectronics *******************
-;* File Name : startup_stm32f107xc.s
-;* Author : MCD Application Team
-;* Version : V4.2.0
-;* Date : 31-March-2017
-;* Description : STM32F107xC Connectivity line devices vector table for
-;* EWARM toolchain.
-;* This module performs:
-;* - Set the initial SP
-;* - Configure the clock system
-;* - Set the initial PC == __iar_program_start,
-;* - Set the vector table entries with the exceptions ISR
-;* address.
-;* After Reset the Cortex-M3 processor is in Thread mode,
-;* priority is Privileged, and the Stack is set to Main.
-;********************************************************************************
-;*
-;* © COPYRIGHT(c) 2017 STMicroelectronics
-;*
-;* Redistribution and use in source and binary forms, with or without modification,
-;* are permitted provided that the following conditions are met:
-;* 1. Redistributions of source code must retain the above copyright notice,
-;* this list of conditions and the following disclaimer.
-;* 2. 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.
-;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
-;*
-;*******************************************************************************
-;
-;
-; The modules in this file are included in the libraries, and may be replaced
-; by any user-defined modules that define the PUBLIC symbol _program_start or
-; a user defined start symbol.
-; To override the cstartup defined in the library, simply add your modified
-; version to the workbench project.
-;
-; The vector table is normally located at address 0.
-; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
-; The name "__vector_table" has special meaning for C-SPY:
-; it is where the SP start value is found, and the NVIC vector
-; table register (VTOR) is initialized to this address if != 0.
-;
-; Cortex-M version
-;
-
- MODULE ?cstartup
-
- ;; Forward declaration of sections.
- SECTION CSTACK:DATA:NOROOT(3)
-
- SECTION .intvec:CODE:NOROOT(2)
-
- EXTERN __iar_program_start
- EXTERN SystemInit
- PUBLIC __vector_table
-
- DATA
-__vector_table
- DCD sfe(CSTACK)
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD WWDG_IRQHandler ; Window Watchdog
- DCD PVD_IRQHandler ; PVD through EXTI Line detect
- DCD TAMPER_IRQHandler ; Tamper
- DCD RTC_IRQHandler ; RTC
- DCD FLASH_IRQHandler ; Flash
- DCD RCC_IRQHandler ; RCC
- DCD EXTI0_IRQHandler ; EXTI Line 0
- DCD EXTI1_IRQHandler ; EXTI Line 1
- DCD EXTI2_IRQHandler ; EXTI Line 2
- DCD EXTI3_IRQHandler ; EXTI Line 3
- DCD EXTI4_IRQHandler ; EXTI Line 4
- DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
- DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
- DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
- DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
- DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
- DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
- DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
- DCD ADC1_2_IRQHandler ; ADC1 and ADC2
- DCD CAN1_TX_IRQHandler ; CAN1 TX
- DCD CAN1_RX0_IRQHandler ; CAN1 RX0
- DCD CAN1_RX1_IRQHandler ; CAN1 RX1
- DCD CAN1_SCE_IRQHandler ; CAN1 SCE
- DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
- DCD TIM1_BRK_IRQHandler ; TIM1 Break
- DCD TIM1_UP_IRQHandler ; TIM1 Update
- DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
- DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
- DCD TIM2_IRQHandler ; TIM2
- DCD TIM3_IRQHandler ; TIM3
- DCD TIM4_IRQHandler ; TIM4
- DCD I2C1_EV_IRQHandler ; I2C1 Event
- DCD I2C1_ER_IRQHandler ; I2C1 Error
- DCD I2C2_EV_IRQHandler ; I2C2 Event
- DCD I2C2_ER_IRQHandler ; I2C1 Error
- DCD SPI1_IRQHandler ; SPI1
- DCD SPI2_IRQHandler ; SPI2
- DCD USART1_IRQHandler ; USART1
- DCD USART2_IRQHandler ; USART2
- DCD USART3_IRQHandler ; USART3
- DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
- DCD RTC_Alarm_IRQHandler ; RTC alarm through EXTI line
- DCD OTG_FS_WKUP_IRQHandler ; USB OTG FS Wakeup through EXTI line
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD TIM5_IRQHandler ; TIM5
- DCD SPI3_IRQHandler ; SPI3
- DCD UART4_IRQHandler ; UART4
- DCD UART5_IRQHandler ; UART5
- DCD TIM6_IRQHandler ; TIM6
- DCD TIM7_IRQHandler ; TIM7
- DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
- DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
- DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
- DCD DMA2_Channel4_IRQHandler ; DMA2 Channel4
- DCD DMA2_Channel5_IRQHandler ; DMA2 Channel5
- DCD ETH_IRQHandler ; Ethernet
- DCD ETH_WKUP_IRQHandler ; Ethernet Wakeup through EXTI line
- DCD CAN2_TX_IRQHandler ; CAN2 TX
- DCD CAN2_RX0_IRQHandler ; CAN2 RX0
- DCD CAN2_RX1_IRQHandler ; CAN2 RX1
- DCD CAN2_SCE_IRQHandler ; CAN2 SCE
- DCD OTG_FS_IRQHandler ; USB OTG FS
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Default interrupt handlers.
-;;
- THUMB
-
- PUBWEAK Reset_Handler
- SECTION .text:CODE:REORDER:NOROOT(2)
-Reset_Handler
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__iar_program_start
- BX R0
-
- PUBWEAK NMI_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-NMI_Handler
- B NMI_Handler
-
- PUBWEAK HardFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-HardFault_Handler
- B HardFault_Handler
-
- PUBWEAK MemManage_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-MemManage_Handler
- B MemManage_Handler
-
- PUBWEAK BusFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-BusFault_Handler
- B BusFault_Handler
-
- PUBWEAK UsageFault_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UsageFault_Handler
- B UsageFault_Handler
-
- PUBWEAK SVC_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SVC_Handler
- B SVC_Handler
-
- PUBWEAK DebugMon_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DebugMon_Handler
- B DebugMon_Handler
-
- PUBWEAK PendSV_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PendSV_Handler
- B PendSV_Handler
-
- PUBWEAK SysTick_Handler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SysTick_Handler
- B SysTick_Handler
-
- PUBWEAK WWDG_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-WWDG_IRQHandler
- B WWDG_IRQHandler
-
- PUBWEAK PVD_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-PVD_IRQHandler
- B PVD_IRQHandler
-
- PUBWEAK TAMPER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TAMPER_IRQHandler
- B TAMPER_IRQHandler
-
- PUBWEAK RTC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_IRQHandler
- B RTC_IRQHandler
-
- PUBWEAK FLASH_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-FLASH_IRQHandler
- B FLASH_IRQHandler
-
- PUBWEAK RCC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RCC_IRQHandler
- B RCC_IRQHandler
-
- PUBWEAK EXTI0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI0_IRQHandler
- B EXTI0_IRQHandler
-
- PUBWEAK EXTI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI1_IRQHandler
- B EXTI1_IRQHandler
-
- PUBWEAK EXTI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI2_IRQHandler
- B EXTI2_IRQHandler
-
- PUBWEAK EXTI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI3_IRQHandler
- B EXTI3_IRQHandler
-
-
- PUBWEAK EXTI4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI4_IRQHandler
- B EXTI4_IRQHandler
-
- PUBWEAK DMA1_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel1_IRQHandler
- B DMA1_Channel1_IRQHandler
-
- PUBWEAK DMA1_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel2_IRQHandler
- B DMA1_Channel2_IRQHandler
-
- PUBWEAK DMA1_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel3_IRQHandler
- B DMA1_Channel3_IRQHandler
-
- PUBWEAK DMA1_Channel4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel4_IRQHandler
- B DMA1_Channel4_IRQHandler
-
- PUBWEAK DMA1_Channel5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel5_IRQHandler
- B DMA1_Channel5_IRQHandler
-
- PUBWEAK DMA1_Channel6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel6_IRQHandler
- B DMA1_Channel6_IRQHandler
-
- PUBWEAK DMA1_Channel7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA1_Channel7_IRQHandler
- B DMA1_Channel7_IRQHandler
-
- PUBWEAK ADC1_2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ADC1_2_IRQHandler
- B ADC1_2_IRQHandler
-
- PUBWEAK CAN1_TX_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN1_TX_IRQHandler
- B CAN1_TX_IRQHandler
-
- PUBWEAK CAN1_RX0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN1_RX0_IRQHandler
- B CAN1_RX0_IRQHandler
-
- PUBWEAK CAN1_RX1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN1_RX1_IRQHandler
- B CAN1_RX1_IRQHandler
-
- PUBWEAK CAN1_SCE_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN1_SCE_IRQHandler
- B CAN1_SCE_IRQHandler
-
- PUBWEAK EXTI9_5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI9_5_IRQHandler
- B EXTI9_5_IRQHandler
-
- PUBWEAK TIM1_BRK_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_BRK_IRQHandler
- B TIM1_BRK_IRQHandler
-
- PUBWEAK TIM1_UP_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_UP_IRQHandler
- B TIM1_UP_IRQHandler
-
- PUBWEAK TIM1_TRG_COM_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_TRG_COM_IRQHandler
- B TIM1_TRG_COM_IRQHandler
-
- PUBWEAK TIM1_CC_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM1_CC_IRQHandler
- B TIM1_CC_IRQHandler
-
- PUBWEAK TIM2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM2_IRQHandler
- B TIM2_IRQHandler
-
- PUBWEAK TIM3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM3_IRQHandler
- B TIM3_IRQHandler
-
- PUBWEAK TIM4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM4_IRQHandler
- B TIM4_IRQHandler
-
- PUBWEAK I2C1_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_EV_IRQHandler
- B I2C1_EV_IRQHandler
-
- PUBWEAK I2C1_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C1_ER_IRQHandler
- B I2C1_ER_IRQHandler
-
- PUBWEAK I2C2_EV_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_EV_IRQHandler
- B I2C2_EV_IRQHandler
-
- PUBWEAK I2C2_ER_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-I2C2_ER_IRQHandler
- B I2C2_ER_IRQHandler
-
- PUBWEAK SPI1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI1_IRQHandler
- B SPI1_IRQHandler
-
- PUBWEAK SPI2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI2_IRQHandler
- B SPI2_IRQHandler
-
- PUBWEAK USART1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART1_IRQHandler
- B USART1_IRQHandler
-
- PUBWEAK USART2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART2_IRQHandler
- B USART2_IRQHandler
-
- PUBWEAK USART3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-USART3_IRQHandler
- B USART3_IRQHandler
-
- PUBWEAK EXTI15_10_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-EXTI15_10_IRQHandler
- B EXTI15_10_IRQHandler
-
- PUBWEAK RTC_Alarm_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-RTC_Alarm_IRQHandler
- B RTC_Alarm_IRQHandler
-
- PUBWEAK OTG_FS_WKUP_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-OTG_FS_WKUP_IRQHandler
- B OTG_FS_WKUP_IRQHandler
-
- PUBWEAK TIM5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM5_IRQHandler
- B TIM5_IRQHandler
-
- PUBWEAK SPI3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-SPI3_IRQHandler
- B SPI3_IRQHandler
-
- PUBWEAK UART4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UART4_IRQHandler
- B UART4_IRQHandler
-
- PUBWEAK UART5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-UART5_IRQHandler
- B UART5_IRQHandler
-
- PUBWEAK TIM6_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM6_IRQHandler
- B TIM6_IRQHandler
-
- PUBWEAK TIM7_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-TIM7_IRQHandler
- B TIM7_IRQHandler
-
- PUBWEAK DMA2_Channel1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel1_IRQHandler
- B DMA2_Channel1_IRQHandler
-
- PUBWEAK DMA2_Channel2_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel2_IRQHandler
- B DMA2_Channel2_IRQHandler
-
- PUBWEAK DMA2_Channel3_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel3_IRQHandler
- B DMA2_Channel3_IRQHandler
-
- PUBWEAK DMA2_Channel4_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel4_IRQHandler
- B DMA2_Channel4_IRQHandler
-
- PUBWEAK DMA2_Channel5_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-DMA2_Channel5_IRQHandler
- B DMA2_Channel5_IRQHandler
-
- PUBWEAK ETH_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ETH_IRQHandler
- B ETH_IRQHandler
-
- PUBWEAK ETH_WKUP_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-ETH_WKUP_IRQHandler
- B ETH_WKUP_IRQHandler
-
- PUBWEAK CAN2_TX_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN2_TX_IRQHandler
- B CAN2_TX_IRQHandler
-
- PUBWEAK CAN2_RX0_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN2_RX0_IRQHandler
- B CAN2_RX0_IRQHandler
-
- PUBWEAK CAN2_RX1_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN2_RX1_IRQHandler
- B CAN2_RX1_IRQHandler
-
- PUBWEAK CAN2_SCE_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-CAN2_SCE_IRQHandler
- B CAN2_SCE_IRQHandler
-
- PUBWEAK OTG_FS_IRQHandler
- SECTION .text:CODE:REORDER:NOROOT(1)
-OTG_FS_IRQHandler
- B OTG_FS_IRQHandler
-
- END
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c b/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c
deleted file mode 100644
index 789b551..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/**
- ******************************************************************************
- * @file system_stm32f1xx.c
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @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_stm32f1xx_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_stm32f1xx_xx.s" file, to
- * configure the system clock before to branch to main program.
- *
- * 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depending on
- * the product used), refer to "HSE_VALUE".
- * 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
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/** @addtogroup CMSIS
- * @{
- */
-
-/** @addtogroup stm32f1xx_system
- * @{
- */
-
-/** @addtogroup STM32F1xx_System_Private_Includes
- * @{
- */
-
-#include "stm32f1xx.h"
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F1xx_System_Private_TypesDefinitions
- * @{
- */
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F1xx_System_Private_Defines
- * @{
- */
-
-#if !defined (HSE_VALUE)
- #define HSE_VALUE 8000000U /*!< Default value of the External oscillator in Hz.
- This value can be provided and adapted by the user application. */
-#endif /* HSE_VALUE */
-
-#if !defined (HSI_VALUE)
- #define HSI_VALUE 8000000U /*!< Default value of the Internal oscillator in Hz.
- This value can be provided and adapted by the user application. */
-#endif /* HSI_VALUE */
-
-/*!< Uncomment the following line if you need to use external SRAM */
-#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
-/* #define DATA_IN_ExtSRAM */
-#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
-
-/*!< Uncomment the following line if you need to relocate your vector Table in
- Internal SRAM. */
-/* #define VECT_TAB_SRAM */
-#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
- This value must be a multiple of 0x200. */
-
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F1xx_System_Private_Macros
- * @{
- */
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F1xx_System_Private_Variables
- * @{
- */
-
-/*******************************************************************************
-* Clock Definitions
-*******************************************************************************/
-#if defined(STM32F100xB) ||defined(STM32F100xE)
- uint32_t SystemCoreClock = 24000000U; /*!< System Clock Frequency (Core Clock) */
-#else /*!< HSI Selected as System Clock source */
- uint32_t SystemCoreClock = 72000000U; /*!< System Clock Frequency (Core Clock) */
-#endif
-
-const uint8_t AHBPrescTable[16U] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
-const uint8_t APBPrescTable[8U] = {0, 0, 0, 0, 1, 2, 3, 4};
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F1xx_System_Private_FunctionPrototypes
- * @{
- */
-
-#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
-#ifdef DATA_IN_ExtSRAM
- static void SystemInit_ExtMemCtl(void);
-#endif /* DATA_IN_ExtSRAM */
-#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F1xx_System_Private_Functions
- * @{
- */
-
-/**
- * @brief Setup the microcontroller system
- * Initialize the Embedded Flash Interface, the PLL and update the
- * SystemCoreClock variable.
- * @note This function should be used only after reset.
- * @param None
- * @retval None
- */
-void SystemInit (void)
-{
- /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
- /* Set HSION bit */
- RCC->CR |= 0x00000001U;
-
- /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
-#if !defined(STM32F105xC) && !defined(STM32F107xC)
- RCC->CFGR &= 0xF8FF0000U;
-#else
- RCC->CFGR &= 0xF0FF0000U;
-#endif /* STM32F105xC */
-
- /* Reset HSEON, CSSON and PLLON bits */
- RCC->CR &= 0xFEF6FFFFU;
-
- /* Reset HSEBYP bit */
- RCC->CR &= 0xFFFBFFFFU;
-
- /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
- RCC->CFGR &= 0xFF80FFFFU;
-
-#if defined(STM32F105xC) || defined(STM32F107xC)
- /* Reset PLL2ON and PLL3ON bits */
- RCC->CR &= 0xEBFFFFFFU;
-
- /* Disable all interrupts and clear pending bits */
- RCC->CIR = 0x00FF0000U;
-
- /* Reset CFGR2 register */
- RCC->CFGR2 = 0x00000000U;
-#elif defined(STM32F100xB) || defined(STM32F100xE)
- /* Disable all interrupts and clear pending bits */
- RCC->CIR = 0x009F0000U;
-
- /* Reset CFGR2 register */
- RCC->CFGR2 = 0x00000000U;
-#else
- /* Disable all interrupts and clear pending bits */
- RCC->CIR = 0x009F0000U;
-#endif /* STM32F105xC */
-
-#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
- #ifdef DATA_IN_ExtSRAM
- SystemInit_ExtMemCtl();
- #endif /* DATA_IN_ExtSRAM */
-#endif
-
-#ifdef VECT_TAB_SRAM
- SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
-#else
- SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
-#endif
-}
-
-/**
- * @brief Update SystemCoreClock variable according to Clock Register Values.
- * The SystemCoreClock variable contains the core clock (HCLK), it can
- * be used by the user application to setup the SysTick timer or configure
- * other parameters.
- *
- * @note Each time the core clock (HCLK) changes, this function must be called
- * to update SystemCoreClock variable value. Otherwise, any configuration
- * based on this variable will be incorrect.
- *
- * @note - The system frequency computed by this function is not the real
- * frequency in the chip. It is calculated based on the predefined
- * constant and the selected clock source:
- *
- * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
- *
- * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
- *
- * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
- * or HSI_VALUE(*) multiplied by the PLL factors.
- *
- * (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
- * 8 MHz) but the real value may vary depending on the variations
- * in voltage and temperature.
- *
- * (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
- * 8 MHz or 25 MHz, depending on the product used), user has to ensure
- * that HSE_VALUE is same as the real frequency of the crystal used.
- * Otherwise, this function may have wrong result.
- *
- * - The result of this function could be not correct when using fractional
- * value for HSE crystal.
- * @param None
- * @retval None
- */
-void SystemCoreClockUpdate (void)
-{
- uint32_t tmp = 0U, pllmull = 0U, pllsource = 0U;
-
-#if defined(STM32F105xC) || defined(STM32F107xC)
- uint32_t prediv1source = 0U, prediv1factor = 0U, prediv2factor = 0U, pll2mull = 0U;
-#endif /* STM32F105xC */
-
-#if defined(STM32F100xB) || defined(STM32F100xE)
- uint32_t prediv1factor = 0U;
-#endif /* STM32F100xB or STM32F100xE */
-
- /* Get SYSCLK source -------------------------------------------------------*/
- tmp = RCC->CFGR & RCC_CFGR_SWS;
-
- switch (tmp)
- {
- case 0x00U: /* HSI used as system clock */
- SystemCoreClock = HSI_VALUE;
- break;
- case 0x04U: /* HSE used as system clock */
- SystemCoreClock = HSE_VALUE;
- break;
- case 0x08U: /* PLL used as system clock */
-
- /* Get PLL clock source and multiplication factor ----------------------*/
- pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
- pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
-
-#if !defined(STM32F105xC) && !defined(STM32F107xC)
- pllmull = ( pllmull >> 18U) + 2U;
-
- if (pllsource == 0x00U)
- {
- /* HSI oscillator clock divided by 2 selected as PLL clock entry */
- SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
- }
- else
- {
- #if defined(STM32F100xB) || defined(STM32F100xE)
- prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
- /* HSE oscillator clock selected as PREDIV1 clock entry */
- SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
- #else
- /* HSE selected as PLL clock entry */
- if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
- {/* HSE oscillator clock divided by 2 */
- SystemCoreClock = (HSE_VALUE >> 1U) * pllmull;
- }
- else
- {
- SystemCoreClock = HSE_VALUE * pllmull;
- }
- #endif
- }
-#else
- pllmull = pllmull >> 18U;
-
- if (pllmull != 0x0DU)
- {
- pllmull += 2U;
- }
- else
- { /* PLL multiplication factor = PLL input clock * 6.5 */
- pllmull = 13U / 2U;
- }
-
- if (pllsource == 0x00U)
- {
- /* HSI oscillator clock divided by 2 selected as PLL clock entry */
- SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
- }
- else
- {/* PREDIV1 selected as PLL clock entry */
-
- /* Get PREDIV1 clock source and division factor */
- prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
- prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
-
- if (prediv1source == 0U)
- {
- /* HSE oscillator clock selected as PREDIV1 clock entry */
- SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
- }
- else
- {/* PLL2 clock selected as PREDIV1 clock entry */
-
- /* Get PREDIV2 division factor and PLL2 multiplication factor */
- prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4U) + 1U;
- pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8U) + 2U;
- SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
- }
- }
-#endif /* STM32F105xC */
- break;
-
- default:
- SystemCoreClock = HSI_VALUE;
- break;
- }
-
- /* Compute HCLK clock frequency ----------------*/
- /* Get HCLK prescaler */
- tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
- /* HCLK clock frequency */
- SystemCoreClock >>= tmp;
-}
-
-#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
-/**
- * @brief Setup the external memory controller. Called in startup_stm32f1xx.s
- * before jump to __main
- * @param None
- * @retval None
- */
-#ifdef DATA_IN_ExtSRAM
-/**
- * @brief Setup the external memory controller.
- * Called in startup_stm32f1xx_xx.s/.c before jump to main.
- * This function configures the external SRAM mounted on STM3210E-EVAL
- * board (STM32 High density devices). This SRAM will be used as program
- * data memory (including heap and stack).
- * @param None
- * @retval None
- */
-void SystemInit_ExtMemCtl(void)
-{
- __IO uint32_t tmpreg;
- /*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
- required, then adjust the Register Addresses */
-
- /* Enable FSMC clock */
- RCC->AHBENR = 0x00000114U;
-
- /* Delay after an RCC peripheral clock enabling */
- tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN);
-
- /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
- RCC->APB2ENR = 0x000001E0U;
-
- /* Delay after an RCC peripheral clock enabling */
- tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);
-
- (void)(tmpreg);
-
-/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/
-/*---------------- SRAM Address lines configuration -------------------------*/
-/*---------------- NOE and NWE configuration --------------------------------*/
-/*---------------- NE3 configuration ----------------------------------------*/
-/*---------------- NBL0, NBL1 configuration ---------------------------------*/
-
- GPIOD->CRL = 0x44BB44BBU;
- GPIOD->CRH = 0xBBBBBBBBU;
-
- GPIOE->CRL = 0xB44444BBU;
- GPIOE->CRH = 0xBBBBBBBBU;
-
- GPIOF->CRL = 0x44BBBBBBU;
- GPIOF->CRH = 0xBBBB4444U;
-
- GPIOG->CRL = 0x44BBBBBBU;
- GPIOG->CRH = 0x444B4B44U;
-
-/*---------------- FSMC Configuration ---------------------------------------*/
-/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/
-
- FSMC_Bank1->BTCR[4U] = 0x00001091U;
- FSMC_Bank1->BTCR[5U] = 0x00110212U;
-}
-#endif /* DATA_IN_ExtSRAM */
-#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Include/arm_common_tables.h b/assets/templates/blackpill/Drivers/CMSIS/Include/arm_common_tables.h
deleted file mode 100644
index d5d7241..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Include/arm_common_tables.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. October 2015
-* $Revision: V.1.4.5 a
-*
-* 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
-*
-* 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 ARM LIMITED 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 _ARM_COMMON_TABLES_H
-#define _ARM_COMMON_TABLES_H
-
-#include "arm_math.h"
-
-extern const uint16_t armBitRevTable[1024];
-extern const q15_t armRecipTableQ15[64];
-extern const q31_t armRecipTableQ31[64];
-/* extern const q31_t realCoefAQ31[1024]; */
-/* extern const q31_t realCoefBQ31[1024]; */
-extern const float32_t twiddleCoef_16[32];
-extern const float32_t twiddleCoef_32[64];
-extern const float32_t twiddleCoef_64[128];
-extern const float32_t twiddleCoef_128[256];
-extern const float32_t twiddleCoef_256[512];
-extern const float32_t twiddleCoef_512[1024];
-extern const float32_t twiddleCoef_1024[2048];
-extern const float32_t twiddleCoef_2048[4096];
-extern const float32_t twiddleCoef_4096[8192];
-#define twiddleCoef twiddleCoef_4096
-extern const q31_t twiddleCoef_16_q31[24];
-extern const q31_t twiddleCoef_32_q31[48];
-extern const q31_t twiddleCoef_64_q31[96];
-extern const q31_t twiddleCoef_128_q31[192];
-extern const q31_t twiddleCoef_256_q31[384];
-extern const q31_t twiddleCoef_512_q31[768];
-extern const q31_t twiddleCoef_1024_q31[1536];
-extern const q31_t twiddleCoef_2048_q31[3072];
-extern const q31_t twiddleCoef_4096_q31[6144];
-extern const q15_t twiddleCoef_16_q15[24];
-extern const q15_t twiddleCoef_32_q15[48];
-extern const q15_t twiddleCoef_64_q15[96];
-extern const q15_t twiddleCoef_128_q15[192];
-extern const q15_t twiddleCoef_256_q15[384];
-extern const q15_t twiddleCoef_512_q15[768];
-extern const q15_t twiddleCoef_1024_q15[1536];
-extern const q15_t twiddleCoef_2048_q15[3072];
-extern const q15_t twiddleCoef_4096_q15[6144];
-extern const float32_t twiddleCoef_rfft_32[32];
-extern const float32_t twiddleCoef_rfft_64[64];
-extern const float32_t twiddleCoef_rfft_128[128];
-extern const float32_t twiddleCoef_rfft_256[256];
-extern const float32_t twiddleCoef_rfft_512[512];
-extern const float32_t twiddleCoef_rfft_1024[1024];
-extern const float32_t twiddleCoef_rfft_2048[2048];
-extern const float32_t twiddleCoef_rfft_4096[4096];
-
-
-/* floating-point bit reversal tables */
-#define ARMBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20 )
-#define ARMBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48 )
-#define ARMBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56 )
-#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 )
-#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 )
-#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 )
-#define ARMBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800)
-#define ARMBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808)
-#define ARMBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032)
-
-extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE__16_TABLE_LENGTH];
-extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE__32_TABLE_LENGTH];
-extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE__64_TABLE_LENGTH];
-extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH];
-extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH];
-extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH];
-extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE1024_TABLE_LENGTH];
-extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE2048_TABLE_LENGTH];
-extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE4096_TABLE_LENGTH];
-
-/* fixed-point bit reversal tables */
-#define ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH ((uint16_t)12 )
-#define ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH ((uint16_t)24 )
-#define ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH ((uint16_t)56 )
-#define ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH ((uint16_t)112 )
-#define ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH ((uint16_t)240 )
-#define ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH ((uint16_t)480 )
-#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992 )
-#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984)
-#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032)
-
-extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH];
-extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH];
-extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH];
-extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH];
-extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH];
-extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH];
-extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH];
-extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH];
-extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH];
-
-/* Tables for Fast Math Sine and Cosine */
-extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1];
-extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1];
-extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1];
-
-#endif /* ARM_COMMON_TABLES_H */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Include/arm_const_structs.h b/assets/templates/blackpill/Drivers/CMSIS/Include/arm_const_structs.h
deleted file mode 100644
index 54595f5..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Include/arm_const_structs.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* ----------------------------------------------------------------------
-* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
-*
-* $Date: 19. March 2015
-* $Revision: V.1.4.5
-*
-* Project: CMSIS DSP Library
-* Title: arm_const_structs.h
-*
-* Description: This file has constant structs that are initialized for
-* user convenience. For example, some can be given as
-* arguments to the arm_cfft_f32() function.
-*
-* Target Processor: Cortex-M4/Cortex-M3
-*
-* 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 ARM LIMITED 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 _ARM_CONST_STRUCTS_H
-#define _ARM_CONST_STRUCTS_H
-
-#include "arm_math.h"
-#include "arm_common_tables.h"
-
- extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16;
- extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32;
- extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64;
- extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128;
- extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256;
- extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512;
- extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024;
- extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048;
- extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096;
-
- extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16;
- extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32;
- extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64;
- extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128;
- extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256;
- extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512;
- extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024;
- extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048;
- extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096;
-
- extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16;
- extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32;
- extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64;
- extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128;
- extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256;
- extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512;
- extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024;
- extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048;
- extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096;
-
-#endif
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Include/cmsis_armcc.h b/assets/templates/blackpill/Drivers/CMSIS/Include/cmsis_armcc.h
deleted file mode 100644
index f2bb66a..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Include/cmsis_armcc.h
+++ /dev/null
@@ -1,734 +0,0 @@
-/**************************************************************************//**
- * @file cmsis_armcc.h
- * @brief CMSIS Cortex-M Core Function/Instruction Header File
- * @version V4.30
- * @date 20. October 2015
- ******************************************************************************/
-/* Copyright (c) 2009 - 2015 ARM LIMITED
-
- 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 ARM 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 COPYRIGHT HOLDERS AND 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 __CMSIS_ARMCC_H
-#define __CMSIS_ARMCC_H
-
-
-#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
- #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
-#endif
-
-/* ########################### Core Function Access ########################### */
-/** \ingroup CMSIS_Core_FunctionInterface
- \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
- @{
- */
-
-/* intrinsic void __enable_irq(); */
-/* intrinsic void __disable_irq(); */
-
-/**
- \brief Get Control Register
- \details Returns the content of the Control Register.
- \return Control Register value
- */
-__STATIC_INLINE uint32_t __get_CONTROL(void)
-{
- register uint32_t __regControl __ASM("control");
- return(__regControl);
-}
-
-
-/**
- \brief Set Control Register
- \details Writes the given value to the Control Register.
- \param [in] control Control Register value to set
- */
-__STATIC_INLINE void __set_CONTROL(uint32_t control)
-{
- register uint32_t __regControl __ASM("control");
- __regControl = control;
-}
-
-
-/**
- \brief Get IPSR Register
- \details Returns the content of the IPSR Register.
- \return IPSR Register value
- */
-__STATIC_INLINE uint32_t __get_IPSR(void)
-{
- register uint32_t __regIPSR __ASM("ipsr");
- return(__regIPSR);
-}
-
-
-/**
- \brief Get APSR Register
- \details Returns the content of the APSR Register.
- \return APSR Register value
- */
-__STATIC_INLINE uint32_t __get_APSR(void)
-{
- register uint32_t __regAPSR __ASM("apsr");
- return(__regAPSR);
-}
-
-
-/**
- \brief Get xPSR Register
- \details Returns the content of the xPSR Register.
- \return xPSR Register value
- */
-__STATIC_INLINE uint32_t __get_xPSR(void)
-{
- register uint32_t __regXPSR __ASM("xpsr");
- return(__regXPSR);
-}
-
-
-/**
- \brief Get Process Stack Pointer
- \details Returns the current value of the Process Stack Pointer (PSP).
- \return PSP Register value
- */
-__STATIC_INLINE uint32_t __get_PSP(void)
-{
- register uint32_t __regProcessStackPointer __ASM("psp");
- return(__regProcessStackPointer);
-}
-
-
-/**
- \brief Set Process Stack Pointer
- \details Assigns the given value to the Process Stack Pointer (PSP).
- \param [in] topOfProcStack Process Stack Pointer value to set
- */
-__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
-{
- register uint32_t __regProcessStackPointer __ASM("psp");
- __regProcessStackPointer = topOfProcStack;
-}
-
-
-/**
- \brief Get Main Stack Pointer
- \details Returns the current value of the Main Stack Pointer (MSP).
- \return MSP Register value
- */
-__STATIC_INLINE uint32_t __get_MSP(void)
-{
- register uint32_t __regMainStackPointer __ASM("msp");
- return(__regMainStackPointer);
-}
-
-
-/**
- \brief Set Main Stack Pointer
- \details Assigns the given value to the Main Stack Pointer (MSP).
- \param [in] topOfMainStack Main Stack Pointer value to set
- */
-__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
-{
- register uint32_t __regMainStackPointer __ASM("msp");
- __regMainStackPointer = topOfMainStack;
-}
-
-
-/**
- \brief Get Priority Mask
- \details Returns the current state of the priority mask bit from the Priority Mask Register.
- \return Priority Mask value
- */
-__STATIC_INLINE uint32_t __get_PRIMASK(void)
-{
- register uint32_t __regPriMask __ASM("primask");
- return(__regPriMask);
-}
-
-
-/**
- \brief Set Priority Mask
- \details Assigns the given value to the Priority Mask Register.
- \param [in] priMask Priority Mask
- */
-__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
-{
- register uint32_t __regPriMask __ASM("primask");
- __regPriMask = (priMask);
-}
-
-
-#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
-
-/**
- \brief Enable FIQ
- \details Enables FIQ interrupts by clearing the F-bit in the CPSR.
- Can only be executed in Privileged modes.
- */
-#define __enable_fault_irq __enable_fiq
-
-
-/**
- \brief Disable FIQ
- \details Disables FIQ interrupts by setting the F-bit in the CPSR.
- Can only be executed in Privileged modes.
- */
-#define __disable_fault_irq __disable_fiq
-
-
-/**
- \brief Get Base Priority
- \details Returns the current value of the Base Priority register.
- \return Base Priority register value
- */
-__STATIC_INLINE uint32_t __get_BASEPRI(void)
-{
- register uint32_t __regBasePri __ASM("basepri");
- return(__regBasePri);
-}
-
-
-/**
- \brief Set Base Priority
- \details Assigns the given value to the Base Priority register.
- \param [in] basePri Base Priority value to set
- */
-__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
-{
- register uint32_t __regBasePri __ASM("basepri");
- __regBasePri = (basePri & 0xFFU);
-}
-
-
-/**
- \brief Set Base Priority with condition
- \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
- or the new value increases the BASEPRI priority level.
- \param [in] basePri Base Priority value to set
- */
-__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
-{
- register uint32_t __regBasePriMax __ASM("basepri_max");
- __regBasePriMax = (basePri & 0xFFU);
-}
-
-
-/**
- \brief Get Fault Mask
- \details Returns the current value of the Fault Mask register.
- \return Fault Mask register value
- */
-__STATIC_INLINE uint32_t __get_FAULTMASK(void)
-{
- register uint32_t __regFaultMask __ASM("faultmask");
- return(__regFaultMask);
-}
-
-
-/**
- \brief Set Fault Mask
- \details Assigns the given value to the Fault Mask register.
- \param [in] faultMask Fault Mask value to set
- */
-__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
-{
- register uint32_t __regFaultMask __ASM("faultmask");
- __regFaultMask = (faultMask & (uint32_t)1);
-}
-
-#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
-
-
-#if (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U)
-
-/**
- \brief Get FPSCR
- \details Returns the current value of the Floating Point Status/Control register.
- \return Floating Point Status/Control register value
- */
-__STATIC_INLINE uint32_t __get_FPSCR(void)
-{
-#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
- register uint32_t __regfpscr __ASM("fpscr");
- return(__regfpscr);
-#else
- return(0U);
-#endif
-}
-
-
-/**
- \brief Set FPSCR
- \details Assigns the given value to the Floating Point Status/Control register.
- \param [in] fpscr Floating Point Status/Control value to set
- */
-__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
-{
-#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
- register uint32_t __regfpscr __ASM("fpscr");
- __regfpscr = (fpscr);
-#endif
-}
-
-#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */
-
-
-
-/*@} end of CMSIS_Core_RegAccFunctions */
-
-
-/* ########################## Core Instruction Access ######################### */
-/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
- Access to dedicated instructions
- @{
-*/
-
-/**
- \brief No Operation
- \details No Operation does nothing. This instruction can be used for code alignment purposes.
- */
-#define __NOP __nop
-
-
-/**
- \brief Wait For Interrupt
- \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
- */
-#define __WFI __wfi
-
-
-/**
- \brief Wait For Event
- \details Wait For Event is a hint instruction that permits the processor to enter
- a low-power state until one of a number of events occurs.
- */
-#define __WFE __wfe
-
-
-/**
- \brief Send Event
- \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
- */
-#define __SEV __sev
-
-
-/**
- \brief Instruction Synchronization Barrier
- \details Instruction Synchronization Barrier flushes the pipeline in the processor,
- so that all instructions following the ISB are fetched from cache or memory,
- after the instruction has been completed.
- */
-#define __ISB() do {\
- __schedule_barrier();\
- __isb(0xF);\
- __schedule_barrier();\
- } while (0U)
-
-/**
- \brief Data Synchronization Barrier
- \details Acts as a special kind of Data Memory Barrier.
- It completes when all explicit memory accesses before this instruction complete.
- */
-#define __DSB() do {\
- __schedule_barrier();\
- __dsb(0xF);\
- __schedule_barrier();\
- } while (0U)
-
-/**
- \brief Data Memory Barrier
- \details Ensures the apparent order of the explicit memory operations before
- and after the instruction, without ensuring their completion.
- */
-#define __DMB() do {\
- __schedule_barrier();\
- __dmb(0xF);\
- __schedule_barrier();\
- } while (0U)
-
-/**
- \brief Reverse byte order (32 bit)
- \details Reverses the byte order in integer value.
- \param [in] value Value to reverse
- \return Reversed value
- */
-#define __REV __rev
-
-
-/**
- \brief Reverse byte order (16 bit)
- \details Reverses the byte order in two unsigned short values.
- \param [in] value Value to reverse
- \return Reversed value
- */
-#ifndef __NO_EMBEDDED_ASM
-__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
-{
- rev16 r0, r0
- bx lr
-}
-#endif
-
-/**
- \brief Reverse byte order in signed short value
- \details Reverses the byte order in a signed short value with sign extension to integer.
- \param [in] value Value to reverse
- \return Reversed value
- */
-#ifndef __NO_EMBEDDED_ASM
-__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
-{
- revsh r0, r0
- bx lr
-}
-#endif
-
-
-/**
- \brief Rotate Right in unsigned value (32 bit)
- \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
- \param [in] value Value to rotate
- \param [in] value Number of Bits to rotate
- \return Rotated value
- */
-#define __ROR __ror
-
-
-/**
- \brief Breakpoint
- \details Causes the processor to enter Debug state.
- Debug tools can use this to investigate system state when the instruction at a particular address is reached.
- \param [in] value is ignored by the processor.
- If required, a debugger can use it to store additional information about the breakpoint.
- */
-#define __BKPT(value) __breakpoint(value)
-
-
-/**
- \brief Reverse bit order of value
- \details Reverses the bit order of the given value.
- \param [in] value Value to reverse
- \return Reversed value
- */
-#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
- #define __RBIT __rbit
-#else
-__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
-{
- uint32_t result;
- int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
-
- result = value; /* r will be reversed bits of v; first get LSB of v */
- for (value >>= 1U; value; value >>= 1U)
- {
- result <<= 1U;
- result |= value & 1U;
- s--;
- }
- result <<= s; /* shift when v's highest bits are zero */
- return(result);
-}
-#endif
-
-
-/**
- \brief Count leading zeros
- \details Counts the number of leading zeros of a data value.
- \param [in] value Value to count the leading zeros
- \return number of leading zeros in value
- */
-#define __CLZ __clz
-
-
-#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
-
-/**
- \brief LDR Exclusive (8 bit)
- \details Executes a exclusive LDR instruction for 8 bit value.
- \param [in] ptr Pointer to data
- \return value of type uint8_t at (*ptr)
- */
-#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
- #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
-#else
- #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
-#endif
-
-
-/**
- \brief LDR Exclusive (16 bit)
- \details Executes a exclusive LDR instruction for 16 bit values.
- \param [in] ptr Pointer to data
- \return value of type uint16_t at (*ptr)
- */
-#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
- #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
-#else
- #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
-#endif
-
-
-/**
- \brief LDR Exclusive (32 bit)
- \details Executes a exclusive LDR instruction for 32 bit values.
- \param [in] ptr Pointer to data
- \return value of type uint32_t at (*ptr)
- */
-#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
- #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
-#else
- #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
-#endif
-
-
-/**
- \brief STR Exclusive (8 bit)
- \details Executes a exclusive STR instruction for 8 bit values.
- \param [in] value Value to store
- \param [in] ptr Pointer to location
- \return 0 Function succeeded
- \return 1 Function failed
- */
-#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
- #define __STREXB(value, ptr) __strex(value, ptr)
-#else
- #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
-#endif
-
-
-/**
- \brief STR Exclusive (16 bit)
- \details Executes a exclusive STR instruction for 16 bit values.
- \param [in] value Value to store
- \param [in] ptr Pointer to location
- \return 0 Function succeeded
- \return 1 Function failed
- */
-#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
- #define __STREXH(value, ptr) __strex(value, ptr)
-#else
- #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
-#endif
-
-
-/**
- \brief STR Exclusive (32 bit)
- \details Executes a exclusive STR instruction for 32 bit values.
- \param [in] value Value to store
- \param [in] ptr Pointer to location
- \return 0 Function succeeded
- \return 1 Function failed
- */
-#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
- #define __STREXW(value, ptr) __strex(value, ptr)
-#else
- #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
-#endif
-
-
-/**
- \brief Remove the exclusive lock
- \details Removes the exclusive lock which is created by LDREX.
- */
-#define __CLREX __clrex
-
-
-/**
- \brief Signed Saturate
- \details Saturates a signed value.
- \param [in] value Value to be saturated
- \param [in] sat Bit position to saturate to (1..32)
- \return Saturated value
- */
-#define __SSAT __ssat
-
-
-/**
- \brief Unsigned Saturate
- \details Saturates an unsigned value.
- \param [in] value Value to be saturated
- \param [in] sat Bit position to saturate to (0..31)
- \return Saturated value
- */
-#define __USAT __usat
-
-
-/**
- \brief Rotate Right with Extend (32 bit)
- \details Moves each bit of a bitstring right by one bit.
- The carry input is shifted in at the left end of the bitstring.
- \param [in] value Value to rotate
- \return Rotated value
- */
-#ifndef __NO_EMBEDDED_ASM
-__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
-{
- rrx r0, r0
- bx lr
-}
-#endif
-
-
-/**
- \brief LDRT Unprivileged (8 bit)
- \details Executes a Unprivileged LDRT instruction for 8 bit value.
- \param [in] ptr Pointer to data
- \return value of type uint8_t at (*ptr)
- */
-#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
-
-
-/**
- \brief LDRT Unprivileged (16 bit)
- \details Executes a Unprivileged LDRT instruction for 16 bit values.
- \param [in] ptr Pointer to data
- \return value of type uint16_t at (*ptr)
- */
-#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
-
-
-/**
- \brief LDRT Unprivileged (32 bit)
- \details Executes a Unprivileged LDRT instruction for 32 bit values.
- \param [in] ptr Pointer to data
- \return value of type uint32_t at (*ptr)
- */
-#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
-
-
-/**
- \brief STRT Unprivileged (8 bit)
- \details Executes a Unprivileged STRT instruction for 8 bit values.
- \param [in] value Value to store
- \param [in] ptr Pointer to location
- */
-#define __STRBT(value, ptr) __strt(value, ptr)
-
-
-/**
- \brief STRT Unprivileged (16 bit)
- \details Executes a Unprivileged STRT instruction for 16 bit values.
- \param [in] value Value to store
- \param [in] ptr Pointer to location
- */
-#define __STRHT(value, ptr) __strt(value, ptr)
-
-
-/**
- \brief STRT Unprivileged (32 bit)
- \details Executes a Unprivileged STRT instruction for 32 bit values.
- \param [in] value Value to store
- \param [in] ptr Pointer to location
- */
-#define __STRT(value, ptr) __strt(value, ptr)
-
-#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
-
-/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
-
-
-/* ################### Compiler specific Intrinsics ########################### */
-/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
- Access to dedicated SIMD instructions
- @{
-*/
-
-#if (__CORTEX_M >= 0x04U) /* only for Cortex-M4 and above */
-
-#define __SADD8 __sadd8
-#define __QADD8 __qadd8
-#define __SHADD8 __shadd8
-#define __UADD8 __uadd8
-#define __UQADD8 __uqadd8
-#define __UHADD8 __uhadd8
-#define __SSUB8 __ssub8
-#define __QSUB8 __qsub8
-#define __SHSUB8 __shsub8
-#define __USUB8 __usub8
-#define __UQSUB8 __uqsub8
-#define __UHSUB8 __uhsub8
-#define __SADD16 __sadd16
-#define __QADD16 __qadd16
-#define __SHADD16 __shadd16
-#define __UADD16 __uadd16
-#define __UQADD16 __uqadd16
-#define __UHADD16 __uhadd16
-#define __SSUB16 __ssub16
-#define __QSUB16 __qsub16
-#define __SHSUB16 __shsub16
-#define __USUB16 __usub16
-#define __UQSUB16 __uqsub16
-#define __UHSUB16 __uhsub16
-#define __SASX __sasx
-#define __QASX __qasx
-#define __SHASX __shasx
-#define __UASX __uasx
-#define __UQASX __uqasx
-#define __UHASX __uhasx
-#define __SSAX __ssax
-#define __QSAX __qsax
-#define __SHSAX __shsax
-#define __USAX __usax
-#define __UQSAX __uqsax
-#define __UHSAX __uhsax
-#define __USAD8 __usad8
-#define __USADA8 __usada8
-#define __SSAT16 __ssat16
-#define __USAT16 __usat16
-#define __UXTB16 __uxtb16
-#define __UXTAB16 __uxtab16
-#define __SXTB16 __sxtb16
-#define __SXTAB16 __sxtab16
-#define __SMUAD __smuad
-#define __SMUADX __smuadx
-#define __SMLAD __smlad
-#define __SMLADX __smladx
-#define __SMLALD __smlald
-#define __SMLALDX __smlaldx
-#define __SMUSD __smusd
-#define __SMUSDX __smusdx
-#define __SMLSD __smlsd
-#define __SMLSDX __smlsdx
-#define __SMLSLD __smlsld
-#define __SMLSLDX __smlsldx
-#define __SEL __sel
-#define __QADD __qadd
-#define __QSUB __qsub
-
-#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
- ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
-
-#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
- ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
-
-#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
- ((int64_t)(ARG3) << 32U) ) >> 32U))
-
-#endif /* (__CORTEX_M >= 0x04) */
-/*@} end of group CMSIS_SIMD_intrinsics */
-
-
-#endif /* __CMSIS_ARMCC_H */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Include/cmsis_gcc.h b/assets/templates/blackpill/Drivers/CMSIS/Include/cmsis_gcc.h
deleted file mode 100644
index d868f2e..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Include/cmsis_gcc.h
+++ /dev/null
@@ -1,1373 +0,0 @@
-/**************************************************************************//**
- * @file cmsis_gcc.h
- * @brief CMSIS Cortex-M Core Function/Instruction Header File
- * @version V4.30
- * @date 20. October 2015
- ******************************************************************************/
-/* Copyright (c) 2009 - 2015 ARM LIMITED
-
- 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 ARM 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 COPYRIGHT HOLDERS AND 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 __CMSIS_GCC_H
-#define __CMSIS_GCC_H
-
-/* ignore some GCC warnings */
-#if defined ( __GNUC__ )
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wsign-conversion"
-#pragma GCC diagnostic ignored "-Wconversion"
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-
-/* ########################### Core Function Access ########################### */
-/** \ingroup CMSIS_Core_FunctionInterface
- \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
- @{
- */
-
-/**
- \brief Enable IRQ Interrupts
- \details Enables IRQ interrupts by clearing the I-bit in the CPSR.
- Can only be executed in Privileged modes.
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
-{
- __ASM volatile ("cpsie i" : : : "memory");
-}
-
-
-/**
- \brief Disable IRQ Interrupts
- \details Disables IRQ interrupts by setting the I-bit in the CPSR.
- Can only be executed in Privileged modes.
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
-{
- __ASM volatile ("cpsid i" : : : "memory");
-}
-
-
-/**
- \brief Get Control Register
- \details Returns the content of the Control Register.
- \return Control Register value
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
-{
- uint32_t result;
-
- __ASM volatile ("MRS %0, control" : "=r" (result) );
- return(result);
-}
-
-
-/**
- \brief Set Control Register
- \details Writes the given value to the Control Register.
- \param [in] control Control Register value to set
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
-{
- __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
-}
-
-
-/**
- \brief Get IPSR Register
- \details Returns the content of the IPSR Register.
- \return IPSR Register value
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
-{
- uint32_t result;
-
- __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
- return(result);
-}
-
-
-/**
- \brief Get APSR Register
- \details Returns the content of the APSR Register.
- \return APSR Register value
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
-{
- uint32_t result;
-
- __ASM volatile ("MRS %0, apsr" : "=r" (result) );
- return(result);
-}
-
-
-/**
- \brief Get xPSR Register
- \details Returns the content of the xPSR Register.
-
- \return xPSR Register value
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
-{
- uint32_t result;
-
- __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
- return(result);
-}
-
-
-/**
- \brief Get Process Stack Pointer
- \details Returns the current value of the Process Stack Pointer (PSP).
- \return PSP Register value
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
-{
- register uint32_t result;
-
- __ASM volatile ("MRS %0, psp\n" : "=r" (result) );
- return(result);
-}
-
-
-/**
- \brief Set Process Stack Pointer
- \details Assigns the given value to the Process Stack Pointer (PSP).
- \param [in] topOfProcStack Process Stack Pointer value to set
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
-{
- __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
-}
-
-
-/**
- \brief Get Main Stack Pointer
- \details Returns the current value of the Main Stack Pointer (MSP).
- \return MSP Register value
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
-{
- register uint32_t result;
-
- __ASM volatile ("MRS %0, msp\n" : "=r" (result) );
- return(result);
-}
-
-
-/**
- \brief Set Main Stack Pointer
- \details Assigns the given value to the Main Stack Pointer (MSP).
-
- \param [in] topOfMainStack Main Stack Pointer value to set
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
-{
- __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
-}
-
-
-/**
- \brief Get Priority Mask
- \details Returns the current state of the priority mask bit from the Priority Mask Register.
- \return Priority Mask value
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
-{
- uint32_t result;
-
- __ASM volatile ("MRS %0, primask" : "=r" (result) );
- return(result);
-}
-
-
-/**
- \brief Set Priority Mask
- \details Assigns the given value to the Priority Mask Register.
- \param [in] priMask Priority Mask
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
-{
- __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
-}
-
-
-#if (__CORTEX_M >= 0x03U)
-
-/**
- \brief Enable FIQ
- \details Enables FIQ interrupts by clearing the F-bit in the CPSR.
- Can only be executed in Privileged modes.
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
-{
- __ASM volatile ("cpsie f" : : : "memory");
-}
-
-
-/**
- \brief Disable FIQ
- \details Disables FIQ interrupts by setting the F-bit in the CPSR.
- Can only be executed in Privileged modes.
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
-{
- __ASM volatile ("cpsid f" : : : "memory");
-}
-
-
-/**
- \brief Get Base Priority
- \details Returns the current value of the Base Priority register.
- \return Base Priority register value
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
-{
- uint32_t result;
-
- __ASM volatile ("MRS %0, basepri" : "=r" (result) );
- return(result);
-}
-
-
-/**
- \brief Set Base Priority
- \details Assigns the given value to the Base Priority register.
- \param [in] basePri Base Priority value to set
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
-{
- __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
-}
-
-
-/**
- \brief Set Base Priority with condition
- \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
- or the new value increases the BASEPRI priority level.
- \param [in] basePri Base Priority value to set
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value)
-{
- __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory");
-}
-
-
-/**
- \brief Get Fault Mask
- \details Returns the current value of the Fault Mask register.
- \return Fault Mask register value
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
-{
- uint32_t result;
-
- __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
- return(result);
-}
-
-
-/**
- \brief Set Fault Mask
- \details Assigns the given value to the Fault Mask register.
- \param [in] faultMask Fault Mask value to set
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
-{
- __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
-}
-
-#endif /* (__CORTEX_M >= 0x03U) */
-
-
-#if (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U)
-
-/**
- \brief Get FPSCR
- \details Returns the current value of the Floating Point Status/Control register.
- \return Floating Point Status/Control register value
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
-{
-#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
- uint32_t result;
-
- /* Empty asm statement works as a scheduling barrier */
- __ASM volatile ("");
- __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
- __ASM volatile ("");
- return(result);
-#else
- return(0);
-#endif
-}
-
-
-/**
- \brief Set FPSCR
- \details Assigns the given value to the Floating Point Status/Control register.
- \param [in] fpscr Floating Point Status/Control value to set
- */
-__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
-{
-#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
- /* Empty asm statement works as a scheduling barrier */
- __ASM volatile ("");
- __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
- __ASM volatile ("");
-#endif
-}
-
-#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */
-
-
-
-/*@} end of CMSIS_Core_RegAccFunctions */
-
-
-/* ########################## Core Instruction Access ######################### */
-/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
- Access to dedicated instructions
- @{
-*/
-
-/* Define macros for porting to both thumb1 and thumb2.
- * For thumb1, use low register (r0-r7), specified by constraint "l"
- * Otherwise, use general registers, specified by constraint "r" */
-#if defined (__thumb__) && !defined (__thumb2__)
-#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
-#define __CMSIS_GCC_USE_REG(r) "l" (r)
-#else
-#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
-#define __CMSIS_GCC_USE_REG(r) "r" (r)
-#endif
-
-/**
- \brief No Operation
- \details No Operation does nothing. This instruction can be used for code alignment purposes.
- */
-__attribute__((always_inline)) __STATIC_INLINE void __NOP(void)
-{
- __ASM volatile ("nop");
-}
-
-
-/**
- \brief Wait For Interrupt
- \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
- */
-__attribute__((always_inline)) __STATIC_INLINE void __WFI(void)
-{
- __ASM volatile ("wfi");
-}
-
-
-/**
- \brief Wait For Event
- \details Wait For Event is a hint instruction that permits the processor to enter
- a low-power state until one of a number of events occurs.
- */
-__attribute__((always_inline)) __STATIC_INLINE void __WFE(void)
-{
- __ASM volatile ("wfe");
-}
-
-
-/**
- \brief Send Event
- \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
- */
-__attribute__((always_inline)) __STATIC_INLINE void __SEV(void)
-{
- __ASM volatile ("sev");
-}
-
-
-/**
- \brief Instruction Synchronization Barrier
- \details Instruction Synchronization Barrier flushes the pipeline in the processor,
- so that all instructions following the ISB are fetched from cache or memory,
- after the instruction has been completed.
- */
-__attribute__((always_inline)) __STATIC_INLINE void __ISB(void)
-{
- __ASM volatile ("isb 0xF":::"memory");
-}
-
-
-/**
- \brief Data Synchronization Barrier
- \details Acts as a special kind of Data Memory Barrier.
- It completes when all explicit memory accesses before this instruction complete.
- */
-__attribute__((always_inline)) __STATIC_INLINE void __DSB(void)
-{
- __ASM volatile ("dsb 0xF":::"memory");
-}
-
-
-/**
- \brief Data Memory Barrier
- \details Ensures the apparent order of the explicit memory operations before
- and after the instruction, without ensuring their completion.
- */
-__attribute__((always_inline)) __STATIC_INLINE void __DMB(void)
-{
- __ASM volatile ("dmb 0xF":::"memory");
-}
-
-
-/**
- \brief Reverse byte order (32 bit)
- \details Reverses the byte order in integer value.
- \param [in] value Value to reverse
- \return Reversed value
- */
-__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value)
-{
-#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
- return __builtin_bswap32(value);
-#else
- uint32_t result;
-
- __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
- return(result);
-#endif
-}
-
-
-/**
- \brief Reverse byte order (16 bit)
- \details Reverses the byte order in two unsigned short values.
- \param [in] value Value to reverse
- \return Reversed value
- */
-__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
-{
- uint32_t result;
-
- __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
- return(result);
-}
-
-
-/**
- \brief Reverse byte order in signed short value
- \details Reverses the byte order in a signed short value with sign extension to integer.
- \param [in] value Value to reverse
- \return Reversed value
- */
-__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)
-{
-#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
- return (short)__builtin_bswap16(value);
-#else
- int32_t result;
-
- __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
- return(result);
-#endif
-}
-
-
-/**
- \brief Rotate Right in unsigned value (32 bit)
- \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
- \param [in] value Value to rotate
- \param [in] value Number of Bits to rotate
- \return Rotated value
- */
-__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
-{
- return (op1 >> op2) | (op1 << (32U - op2));
-}
-
-
-/**
- \brief Breakpoint
- \details Causes the processor to enter Debug state.
- Debug tools can use this to investigate system state when the instruction at a particular address is reached.
- \param [in] value is ignored by the processor.
- If required, a debugger can use it to store additional information about the breakpoint.
- */
-#define __BKPT(value) __ASM volatile ("bkpt "#value)
-
-
-/**
- \brief Reverse bit order of value
- \details Reverses the bit order of the given value.
- \param [in] value Value to reverse
- \return Reversed value
- */
-__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
-{
- uint32_t result;
-
-#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
- __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
-#else
- int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
-
- result = value; /* r will be reversed bits of v; first get LSB of v */
- for (value >>= 1U; value; value >>= 1U)
- {
- result <<= 1U;
- result |= value & 1U;
- s--;
- }
- result <<= s; /* shift when v's highest bits are zero */
-#endif
- return(result);
-}
-
-
-/**
- \brief Count leading zeros
- \details Counts the number of leading zeros of a data value.
- \param [in] value Value to count the leading zeros
- \return number of leading zeros in value
- */
-#define __CLZ __builtin_clz
-
-
-#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
-
-/**
- \brief LDR Exclusive (8 bit)
- \details Executes a exclusive LDR instruction for 8 bit value.
- \param [in] ptr Pointer to data
- \return value of type uint8_t at (*ptr)
- */
-__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
-{
- uint32_t result;
-
-#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
- __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
-#else
- /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
- accepted by assembler. So has to use following less efficient pattern.
- */
- __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
-#endif
- return ((uint8_t) result); /* Add explicit type cast here */
-}
-
-
-/**
- \brief LDR Exclusive (16 bit)
- \details Executes a exclusive LDR instruction for 16 bit values.
- \param [in] ptr Pointer to data
- \return value of type uint16_t at (*ptr)
- */
-__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
-{
- uint32_t result;
-
-#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
- __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
-#else
- /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
- accepted by assembler. So has to use following less efficient pattern.
- */
- __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
-#endif
- return ((uint16_t) result); /* Add explicit type cast here */
-}
-
-
-/**
- \brief LDR Exclusive (32 bit)
- \details Executes a exclusive LDR instruction for 32 bit values.
- \param [in] ptr Pointer to data
- \return value of type uint32_t at (*ptr)
- */
-__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
-{
- uint32_t result;
-
- __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
- return(result);
-}
-
-
-/**
- \brief STR Exclusive (8 bit)
- \details Executes a exclusive STR instruction for 8 bit values.
- \param [in] value Value to store
- \param [in] ptr Pointer to location
- \return 0 Function succeeded
- \return 1 Function failed
- */
-__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
-{
- uint32_t result;
-
- __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
- return(result);
-}
-
-
-/**
- \brief STR Exclusive (16 bit)
- \details Executes a exclusive STR instruction for 16 bit values.
- \param [in] value Value to store
- \param [in] ptr Pointer to location
- \return 0 Function succeeded
- \return 1 Function failed
- */
-__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
-{
- uint32_t result;
-
- __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
- return(result);
-}
-
-
-/**
- \brief STR Exclusive (32 bit)
- \details Executes a exclusive STR instruction for 32 bit values.
- \param [in] value Value to store
- \param [in] ptr Pointer to location
- \return 0 Function succeeded
- \return 1 Function failed
- */
-__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
-{
- uint32_t result;
-
- __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
- return(result);
-}
-
-
-/**
- \brief Remove the exclusive lock
- \details Removes the exclusive lock which is created by LDREX.
- */
-__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void)
-{
- __ASM volatile ("clrex" ::: "memory");
-}
-
-
-/**
- \brief Signed Saturate
- \details Saturates a signed value.
- \param [in] value Value to be saturated
- \param [in] sat Bit position to saturate to (1..32)
- \return Saturated value
- */
-#define __SSAT(ARG1,ARG2) \
-({ \
- uint32_t __RES, __ARG1 = (ARG1); \
- __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
- __RES; \
- })
-
-
-/**
- \brief Unsigned Saturate
- \details Saturates an unsigned value.
- \param [in] value Value to be saturated
- \param [in] sat Bit position to saturate to (0..31)
- \return Saturated value
- */
-#define __USAT(ARG1,ARG2) \
-({ \
- uint32_t __RES, __ARG1 = (ARG1); \
- __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
- __RES; \
- })
-
-
-/**
- \brief Rotate Right with Extend (32 bit)
- \details Moves each bit of a bitstring right by one bit.
- The carry input is shifted in at the left end of the bitstring.
- \param [in] value Value to rotate
- \return Rotated value
- */
-__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value)
-{
- uint32_t result;
-
- __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
- return(result);
-}
-
-
-/**
- \brief LDRT Unprivileged (8 bit)
- \details Executes a Unprivileged LDRT instruction for 8 bit value.
- \param [in] ptr Pointer to data
- \return value of type uint8_t at (*ptr)
- */
-__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
-{
- uint32_t result;
-
-#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
- __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) );
-#else
- /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
- accepted by assembler. So has to use following less efficient pattern.
- */
- __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
-#endif
- return ((uint8_t) result); /* Add explicit type cast here */
-}
-
-
-/**
- \brief LDRT Unprivileged (16 bit)
- \details Executes a Unprivileged LDRT instruction for 16 bit values.
- \param [in] ptr Pointer to data
- \return value of type uint16_t at (*ptr)
- */
-__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
-{
- uint32_t result;
-
-#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
- __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) );
-#else
- /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
- accepted by assembler. So has to use following less efficient pattern.
- */
- __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
-#endif
- return ((uint16_t) result); /* Add explicit type cast here */
-}
-
-
-/**
- \brief LDRT Unprivileged (32 bit)
- \details Executes a Unprivileged LDRT instruction for 32 bit values.
- \param [in] ptr Pointer to data
- \return value of type uint32_t at (*ptr)
- */
-__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr)
-{
- uint32_t result;
-
- __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) );
- return(result);
-}
-
-
-/**
- \brief STRT Unprivileged (8 bit)
- \details Executes a Unprivileged STRT instruction for 8 bit values.
- \param [in] value Value to store
- \param [in] ptr Pointer to location
- */
-__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
-{
- __ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
-}
-
-
-/**
- \brief STRT Unprivileged (16 bit)
- \details Executes a Unprivileged STRT instruction for 16 bit values.
- \param [in] value Value to store
- \param [in] ptr Pointer to location
- */
-__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
-{
- __ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
-}
-
-
-/**
- \brief STRT Unprivileged (32 bit)
- \details Executes a Unprivileged STRT instruction for 32 bit values.
- \param [in] value Value to store
- \param [in] ptr Pointer to location
- */
-__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
-{
- __ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) );
-}
-
-#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
-
-/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
-
-
-/* ################### Compiler specific Intrinsics ########################### */
-/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
- Access to dedicated SIMD instructions
- @{
-*/
-
-#if (__CORTEX_M >= 0x04U) /* only for Cortex-M4 and above */
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
-{
- uint32_t result;
-
- __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
- return(result);
-}
-
-#define __SSAT16(ARG1,ARG2) \
-({ \
- int32_t __RES, __ARG1 = (ARG1); \
- __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
- __RES; \
- })
-
-#define __USAT16(ARG1,ARG2) \
-({ \
- uint32_t __RES, __ARG1 = (ARG1); \
- __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
- __RES; \
- })
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
-{
- uint32_t result;
-
- __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
-{
- uint32_t result;
-
- __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
-{
- uint32_t result;
-
- __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
-{
- uint32_t result;
-
- __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
-{
- union llreg_u{
- uint32_t w32[2];
- uint64_t w64;
- } llr;
- llr.w64 = acc;
-
-#ifndef __ARMEB__ /* Little endian */
- __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
-#else /* Big endian */
- __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
-#endif
-
- return(llr.w64);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
-{
- union llreg_u{
- uint32_t w32[2];
- uint64_t w64;
- } llr;
- llr.w64 = acc;
-
-#ifndef __ARMEB__ /* Little endian */
- __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
-#else /* Big endian */
- __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
-#endif
-
- return(llr.w64);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
-{
- uint32_t result;
-
- __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
-{
- uint32_t result;
-
- __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
-{
- union llreg_u{
- uint32_t w32[2];
- uint64_t w64;
- } llr;
- llr.w64 = acc;
-
-#ifndef __ARMEB__ /* Little endian */
- __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
-#else /* Big endian */
- __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
-#endif
-
- return(llr.w64);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
-{
- union llreg_u{
- uint32_t w32[2];
- uint64_t w64;
- } llr;
- llr.w64 = acc;
-
-#ifndef __ARMEB__ /* Little endian */
- __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
-#else /* Big endian */
- __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
-#endif
-
- return(llr.w64);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
-{
- uint32_t result;
-
- __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __QADD( int32_t op1, int32_t op2)
-{
- int32_t result;
-
- __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __QSUB( int32_t op1, int32_t op2)
-{
- int32_t result;
-
- __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
- return(result);
-}
-
-#define __PKHBT(ARG1,ARG2,ARG3) \
-({ \
- uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
- __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
- __RES; \
- })
-
-#define __PKHTB(ARG1,ARG2,ARG3) \
-({ \
- uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
- if (ARG3 == 0) \
- __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
- else \
- __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
- __RES; \
- })
-
-__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
-{
- int32_t result;
-
- __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
- return(result);
-}
-
-#endif /* (__CORTEX_M >= 0x04) */
-/*@} end of group CMSIS_SIMD_intrinsics */
-
-
-#if defined ( __GNUC__ )
-#pragma GCC diagnostic pop
-#endif
-
-#endif /* __CMSIS_GCC_H */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Include/core_cm0.h b/assets/templates/blackpill/Drivers/CMSIS/Include/core_cm0.h
deleted file mode 100644
index fdee521..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Include/core_cm0.h
+++ /dev/null
@@ -1,798 +0,0 @@
-/**************************************************************************//**
- * @file core_cm0.h
- * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
- * @version V4.30
- * @date 20. October 2015
- ******************************************************************************/
-/* Copyright (c) 2009 - 2015 ARM LIMITED
-
- 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 ARM 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 COPYRIGHT HOLDERS AND 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.
- ---------------------------------------------------------------------------*/
-
-
-#if defined ( __ICCARM__ )
- #pragma system_include /* treat file as system include file for MISRA check */
-#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
- #pragma clang system_header /* treat file as system include file */
-#endif
-
-#ifndef __CORE_CM0_H_GENERIC
-#define __CORE_CM0_H_GENERIC
-
-#include
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/**
- \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
- CMSIS violates the following MISRA-C:2004 rules:
-
- \li Required Rule 8.5, object/function definition in header file.
- Function definitions in header files are used to allow 'inlining'.
-
- \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers.
-
- \li Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code.
- */
-
-
-/*******************************************************************************
- * CMSIS definitions
- ******************************************************************************/
-/**
- \ingroup Cortex_M0
- @{
- */
-
-/* CMSIS CM0 definitions */
-#define __CM0_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
-#define __CM0_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
-#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \
- __CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
-
-#define __CORTEX_M (0x00U) /*!< Cortex-M Core */
-
-
-#if defined ( __CC_ARM )
- #define __ASM __asm /*!< asm keyword for ARM Compiler */
- #define __INLINE __inline /*!< inline keyword for ARM Compiler */
- #define __STATIC_INLINE static __inline
-
-#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
- #define __ASM __asm /*!< asm keyword for ARM Compiler */
- #define __INLINE __inline /*!< inline keyword for ARM Compiler */
- #define __STATIC_INLINE static __inline
-
-#elif defined ( __GNUC__ )
- #define __ASM __asm /*!< asm keyword for GNU Compiler */
- #define __INLINE inline /*!< inline keyword for GNU Compiler */
- #define __STATIC_INLINE static inline
-
-#elif defined ( __ICCARM__ )
- #define __ASM __asm /*!< asm keyword for IAR Compiler */
- #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
- #define __STATIC_INLINE static inline
-
-#elif defined ( __TMS470__ )
- #define __ASM __asm /*!< asm keyword for TI CCS Compiler */
- #define __STATIC_INLINE static inline
-
-#elif defined ( __TASKING__ )
- #define __ASM __asm /*!< asm keyword for TASKING Compiler */
- #define __INLINE inline /*!< inline keyword for TASKING Compiler */
- #define __STATIC_INLINE static inline
-
-#elif defined ( __CSMC__ )
- #define __packed
- #define __ASM _asm /*!< asm keyword for COSMIC Compiler */
- #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
- #define __STATIC_INLINE static inline
-
-#else
- #error Unknown compiler
-#endif
-
-/** __FPU_USED indicates whether an FPU is used or not.
- This core does not support an FPU at all
-*/
-#define __FPU_USED 0U
-
-#if defined ( __CC_ARM )
- #if defined __TARGET_FPU_VFP
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
- #if defined __ARM_PCS_VFP
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#elif defined ( __GNUC__ )
- #if defined (__VFP_FP__) && !defined(__SOFTFP__)
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#elif defined ( __ICCARM__ )
- #if defined __ARMVFP__
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#elif defined ( __TMS470__ )
- #if defined __TI_VFP_SUPPORT__
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#elif defined ( __TASKING__ )
- #if defined __FPU_VFP__
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#elif defined ( __CSMC__ )
- #if ( __CSMC__ & 0x400U)
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#endif
-
-#include "core_cmInstr.h" /* Core Instruction Access */
-#include "core_cmFunc.h" /* Core Function Access */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __CORE_CM0_H_GENERIC */
-
-#ifndef __CMSIS_GENERIC
-
-#ifndef __CORE_CM0_H_DEPENDANT
-#define __CORE_CM0_H_DEPENDANT
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* check device defines and use defaults */
-#if defined __CHECK_DEVICE_DEFINES
- #ifndef __CM0_REV
- #define __CM0_REV 0x0000U
- #warning "__CM0_REV not defined in device header file; using default!"
- #endif
-
- #ifndef __NVIC_PRIO_BITS
- #define __NVIC_PRIO_BITS 2U
- #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
- #endif
-
- #ifndef __Vendor_SysTickConfig
- #define __Vendor_SysTickConfig 0U
- #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
- #endif
-#endif
-
-/* IO definitions (access restrictions to peripheral registers) */
-/**
- \defgroup CMSIS_glob_defs CMSIS Global Defines
-
- IO Type Qualifiers are used
- \li to specify the access to peripheral variables.
- \li for automatic generation of peripheral register debug information.
-*/
-#ifdef __cplusplus
- #define __I volatile /*!< Defines 'read only' permissions */
-#else
- #define __I volatile const /*!< Defines 'read only' permissions */
-#endif
-#define __O volatile /*!< Defines 'write only' permissions */
-#define __IO volatile /*!< Defines 'read / write' permissions */
-
-/* following defines should be used for structure members */
-#define __IM volatile const /*! Defines 'read only' structure member permissions */
-#define __OM volatile /*! Defines 'write only' structure member permissions */
-#define __IOM volatile /*! Defines 'read / write' structure member permissions */
-
-/*@} end of group Cortex_M0 */
-
-
-
-/*******************************************************************************
- * Register Abstraction
- Core Register contain:
- - Core Register
- - Core NVIC Register
- - Core SCB Register
- - Core SysTick Register
- ******************************************************************************/
-/**
- \defgroup CMSIS_core_register Defines and Type Definitions
- \brief Type definitions and defines for Cortex-M processor based devices.
-*/
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_CORE Status and Control Registers
- \brief Core Register type definitions.
- @{
- */
-
-/**
- \brief Union type to access the Application Program Status Register (APSR).
- */
-typedef union
-{
- struct
- {
- uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
- uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
- uint32_t C:1; /*!< bit: 29 Carry condition code flag */
- uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
- uint32_t N:1; /*!< bit: 31 Negative condition code flag */
- } b; /*!< Structure used for bit access */
- uint32_t w; /*!< Type used for word access */
-} APSR_Type;
-
-/* APSR Register Definitions */
-#define APSR_N_Pos 31U /*!< APSR: N Position */
-#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
-
-#define APSR_Z_Pos 30U /*!< APSR: Z Position */
-#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
-
-#define APSR_C_Pos 29U /*!< APSR: C Position */
-#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
-
-#define APSR_V_Pos 28U /*!< APSR: V Position */
-#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
-
-
-/**
- \brief Union type to access the Interrupt Program Status Register (IPSR).
- */
-typedef union
-{
- struct
- {
- uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
- uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
- } b; /*!< Structure used for bit access */
- uint32_t w; /*!< Type used for word access */
-} IPSR_Type;
-
-/* IPSR Register Definitions */
-#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
-#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
-
-
-/**
- \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
- */
-typedef union
-{
- struct
- {
- uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
- uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
- uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
- uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
- uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
- uint32_t C:1; /*!< bit: 29 Carry condition code flag */
- uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
- uint32_t N:1; /*!< bit: 31 Negative condition code flag */
- } b; /*!< Structure used for bit access */
- uint32_t w; /*!< Type used for word access */
-} xPSR_Type;
-
-/* xPSR Register Definitions */
-#define xPSR_N_Pos 31U /*!< xPSR: N Position */
-#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
-
-#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
-#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
-
-#define xPSR_C_Pos 29U /*!< xPSR: C Position */
-#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
-
-#define xPSR_V_Pos 28U /*!< xPSR: V Position */
-#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
-
-#define xPSR_T_Pos 24U /*!< xPSR: T Position */
-#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
-
-#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
-#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
-
-
-/**
- \brief Union type to access the Control Registers (CONTROL).
- */
-typedef union
-{
- struct
- {
- uint32_t _reserved0:1; /*!< bit: 0 Reserved */
- uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
- uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
- } b; /*!< Structure used for bit access */
- uint32_t w; /*!< Type used for word access */
-} CONTROL_Type;
-
-/* CONTROL Register Definitions */
-#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
-#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
-
-/*@} end of group CMSIS_CORE */
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
- \brief Type definitions for the NVIC Registers
- @{
- */
-
-/**
- \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
- */
-typedef struct
-{
- __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
- uint32_t RESERVED0[31U];
- __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
- uint32_t RSERVED1[31U];
- __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
- uint32_t RESERVED2[31U];
- __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
- uint32_t RESERVED3[31U];
- uint32_t RESERVED4[64U];
- __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
-} NVIC_Type;
-
-/*@} end of group CMSIS_NVIC */
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_SCB System Control Block (SCB)
- \brief Type definitions for the System Control Block Registers
- @{
- */
-
-/**
- \brief Structure type to access the System Control Block (SCB).
- */
-typedef struct
-{
- __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
- __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
- uint32_t RESERVED0;
- __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
- __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
- __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
- uint32_t RESERVED1;
- __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
- __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
-} SCB_Type;
-
-/* SCB CPUID Register Definitions */
-#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
-#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
-
-#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
-#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
-
-#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
-#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
-
-#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
-#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
-
-#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
-#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
-
-/* SCB Interrupt Control State Register Definitions */
-#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
-#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
-
-#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
-#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
-
-#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
-#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
-
-#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
-#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
-
-#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
-#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
-
-#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
-#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
-
-#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
-#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
-
-#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
-#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
-
-#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
-#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
-
-/* SCB Application Interrupt and Reset Control Register Definitions */
-#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
-#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
-
-#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
-#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
-
-#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
-#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
-
-#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
-#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
-
-#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
-#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
-
-/* SCB System Control Register Definitions */
-#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
-#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
-
-#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
-#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
-
-#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
-#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
-
-/* SCB Configuration Control Register Definitions */
-#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
-#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
-
-#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
-#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
-
-/* SCB System Handler Control and State Register Definitions */
-#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
-#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
-
-/*@} end of group CMSIS_SCB */
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_SysTick System Tick Timer (SysTick)
- \brief Type definitions for the System Timer Registers.
- @{
- */
-
-/**
- \brief Structure type to access the System Timer (SysTick).
- */
-typedef struct
-{
- __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
- __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
- __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
- __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
-} SysTick_Type;
-
-/* SysTick Control / Status Register Definitions */
-#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
-#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
-
-#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
-#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
-
-#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
-#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
-
-#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
-#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
-
-/* SysTick Reload Register Definitions */
-#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
-#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
-
-/* SysTick Current Register Definitions */
-#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
-#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
-
-/* SysTick Calibration Register Definitions */
-#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
-#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
-
-#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
-#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
-
-#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
-#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
-
-/*@} end of group CMSIS_SysTick */
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
- \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
- Therefore they are not covered by the Cortex-M0 header file.
- @{
- */
-/*@} end of group CMSIS_CoreDebug */
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_core_bitfield Core register bit field macros
- \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
- @{
- */
-
-/**
- \brief Mask and shift a bit field value for use in a register bit range.
- \param[in] field Name of the register bit field.
- \param[in] value Value of the bit field.
- \return Masked and shifted value.
-*/
-#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
-
-/**
- \brief Mask and shift a register value to extract a bit filed value.
- \param[in] field Name of the register bit field.
- \param[in] value Value of register.
- \return Masked and shifted bit field value.
-*/
-#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
-
-/*@} end of group CMSIS_core_bitfield */
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_core_base Core Definitions
- \brief Definitions for base addresses, unions, and structures.
- @{
- */
-
-/* Memory mapping of Cortex-M0 Hardware */
-#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
-#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
-#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
-#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
-
-#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
-#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
-#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
-
-
-/*@} */
-
-
-
-/*******************************************************************************
- * Hardware Abstraction Layer
- Core Function Interface contains:
- - Core NVIC Functions
- - Core SysTick Functions
- - Core Register Access Functions
- ******************************************************************************/
-/**
- \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
-*/
-
-
-
-/* ########################## NVIC functions #################################### */
-/**
- \ingroup CMSIS_Core_FunctionInterface
- \defgroup CMSIS_Core_NVICFunctions NVIC Functions
- \brief Functions that manage interrupts and exceptions via the NVIC.
- @{
- */
-
-/* Interrupt Priorities are WORD accessible only under ARMv6M */
-/* The following MACROS handle generation of the register offset and byte masks */
-#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
-#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
-#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
-
-
-/**
- \brief Enable External Interrupt
- \details Enables a device-specific interrupt in the NVIC interrupt controller.
- \param [in] IRQn External interrupt number. Value cannot be negative.
- */
-__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
-{
- NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
-}
-
-
-/**
- \brief Disable External Interrupt
- \details Disables a device-specific interrupt in the NVIC interrupt controller.
- \param [in] IRQn External interrupt number. Value cannot be negative.
- */
-__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
-{
- NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
-}
-
-
-/**
- \brief Get Pending Interrupt
- \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
- \param [in] IRQn Interrupt number.
- \return 0 Interrupt status is not pending.
- \return 1 Interrupt status is pending.
- */
-__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
-{
- return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
-}
-
-
-/**
- \brief Set Pending Interrupt
- \details Sets the pending bit of an external interrupt.
- \param [in] IRQn Interrupt number. Value cannot be negative.
- */
-__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
-{
- NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
-}
-
-
-/**
- \brief Clear Pending Interrupt
- \details Clears the pending bit of an external interrupt.
- \param [in] IRQn External interrupt number. Value cannot be negative.
- */
-__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
-{
- NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
-}
-
-
-/**
- \brief Set Interrupt Priority
- \details Sets the priority of an interrupt.
- \note The priority cannot be set for every core interrupt.
- \param [in] IRQn Interrupt number.
- \param [in] priority Priority to set.
- */
-__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
-{
- if ((int32_t)(IRQn) < 0)
- {
- SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
- (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
- }
- else
- {
- NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
- (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
- }
-}
-
-
-/**
- \brief Get Interrupt Priority
- \details Reads the priority of an interrupt.
- The interrupt number can be positive to specify an external (device specific) interrupt,
- or negative to specify an internal (core) interrupt.
- \param [in] IRQn Interrupt number.
- \return Interrupt Priority.
- Value is aligned automatically to the implemented priority bits of the microcontroller.
- */
-__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
-{
-
- if ((int32_t)(IRQn) < 0)
- {
- return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
- }
- else
- {
- return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
- }
-}
-
-
-/**
- \brief System Reset
- \details Initiates a system reset request to reset the MCU.
- */
-__STATIC_INLINE void NVIC_SystemReset(void)
-{
- __DSB(); /* Ensure all outstanding memory accesses included
- buffered write are completed before reset */
- SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
- SCB_AIRCR_SYSRESETREQ_Msk);
- __DSB(); /* Ensure completion of memory access */
-
- for(;;) /* wait until reset */
- {
- __NOP();
- }
-}
-
-/*@} end of CMSIS_Core_NVICFunctions */
-
-
-
-/* ################################## SysTick function ############################################ */
-/**
- \ingroup CMSIS_Core_FunctionInterface
- \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
- \brief Functions that configure the System.
- @{
- */
-
-#if (__Vendor_SysTickConfig == 0U)
-
-/**
- \brief System Tick Configuration
- \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
- Counter is in free running mode to generate periodic interrupts.
- \param [in] ticks Number of ticks between two interrupts.
- \return 0 Function succeeded.
- \return 1 Function failed.
- \note When the variable __Vendor_SysTickConfig is set to 1, then the
- function SysTick_Config is not included. In this case, the file device.h
- must contain a vendor-specific implementation of this function.
- */
-__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
-{
- if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
- {
- return (1UL); /* Reload value impossible */
- }
-
- SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
- NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
- SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
- SysTick_CTRL_TICKINT_Msk |
- SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
- return (0UL); /* Function successful */
-}
-
-#endif
-
-/*@} end of CMSIS_Core_SysTickFunctions */
-
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __CORE_CM0_H_DEPENDANT */
-
-#endif /* __CMSIS_GENERIC */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Include/core_cm0plus.h b/assets/templates/blackpill/Drivers/CMSIS/Include/core_cm0plus.h
deleted file mode 100644
index 7614450..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Include/core_cm0plus.h
+++ /dev/null
@@ -1,914 +0,0 @@
-/**************************************************************************//**
- * @file core_cm0plus.h
- * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
- * @version V4.30
- * @date 20. October 2015
- ******************************************************************************/
-/* Copyright (c) 2009 - 2015 ARM LIMITED
-
- 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 ARM 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 COPYRIGHT HOLDERS AND 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.
- ---------------------------------------------------------------------------*/
-
-
-#if defined ( __ICCARM__ )
- #pragma system_include /* treat file as system include file for MISRA check */
-#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
- #pragma clang system_header /* treat file as system include file */
-#endif
-
-#ifndef __CORE_CM0PLUS_H_GENERIC
-#define __CORE_CM0PLUS_H_GENERIC
-
-#include
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/**
- \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
- CMSIS violates the following MISRA-C:2004 rules:
-
- \li Required Rule 8.5, object/function definition in header file.
- Function definitions in header files are used to allow 'inlining'.
-
- \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers.
-
- \li Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code.
- */
-
-
-/*******************************************************************************
- * CMSIS definitions
- ******************************************************************************/
-/**
- \ingroup Cortex-M0+
- @{
- */
-
-/* CMSIS CM0+ definitions */
-#define __CM0PLUS_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
-#define __CM0PLUS_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
-#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \
- __CM0PLUS_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
-
-#define __CORTEX_M (0x00U) /*!< Cortex-M Core */
-
-
-#if defined ( __CC_ARM )
- #define __ASM __asm /*!< asm keyword for ARM Compiler */
- #define __INLINE __inline /*!< inline keyword for ARM Compiler */
- #define __STATIC_INLINE static __inline
-
-#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
- #define __ASM __asm /*!< asm keyword for ARM Compiler */
- #define __INLINE __inline /*!< inline keyword for ARM Compiler */
- #define __STATIC_INLINE static __inline
-
-#elif defined ( __GNUC__ )
- #define __ASM __asm /*!< asm keyword for GNU Compiler */
- #define __INLINE inline /*!< inline keyword for GNU Compiler */
- #define __STATIC_INLINE static inline
-
-#elif defined ( __ICCARM__ )
- #define __ASM __asm /*!< asm keyword for IAR Compiler */
- #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
- #define __STATIC_INLINE static inline
-
-#elif defined ( __TMS470__ )
- #define __ASM __asm /*!< asm keyword for TI CCS Compiler */
- #define __STATIC_INLINE static inline
-
-#elif defined ( __TASKING__ )
- #define __ASM __asm /*!< asm keyword for TASKING Compiler */
- #define __INLINE inline /*!< inline keyword for TASKING Compiler */
- #define __STATIC_INLINE static inline
-
-#elif defined ( __CSMC__ )
- #define __packed
- #define __ASM _asm /*!< asm keyword for COSMIC Compiler */
- #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
- #define __STATIC_INLINE static inline
-
-#else
- #error Unknown compiler
-#endif
-
-/** __FPU_USED indicates whether an FPU is used or not.
- This core does not support an FPU at all
-*/
-#define __FPU_USED 0U
-
-#if defined ( __CC_ARM )
- #if defined __TARGET_FPU_VFP
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
- #if defined __ARM_PCS_VFP
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#elif defined ( __GNUC__ )
- #if defined (__VFP_FP__) && !defined(__SOFTFP__)
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#elif defined ( __ICCARM__ )
- #if defined __ARMVFP__
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#elif defined ( __TMS470__ )
- #if defined __TI_VFP_SUPPORT__
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#elif defined ( __TASKING__ )
- #if defined __FPU_VFP__
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#elif defined ( __CSMC__ )
- #if ( __CSMC__ & 0x400U)
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#endif
-
-#include "core_cmInstr.h" /* Core Instruction Access */
-#include "core_cmFunc.h" /* Core Function Access */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __CORE_CM0PLUS_H_GENERIC */
-
-#ifndef __CMSIS_GENERIC
-
-#ifndef __CORE_CM0PLUS_H_DEPENDANT
-#define __CORE_CM0PLUS_H_DEPENDANT
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* check device defines and use defaults */
-#if defined __CHECK_DEVICE_DEFINES
- #ifndef __CM0PLUS_REV
- #define __CM0PLUS_REV 0x0000U
- #warning "__CM0PLUS_REV not defined in device header file; using default!"
- #endif
-
- #ifndef __MPU_PRESENT
- #define __MPU_PRESENT 0U
- #warning "__MPU_PRESENT not defined in device header file; using default!"
- #endif
-
- #ifndef __VTOR_PRESENT
- #define __VTOR_PRESENT 0U
- #warning "__VTOR_PRESENT not defined in device header file; using default!"
- #endif
-
- #ifndef __NVIC_PRIO_BITS
- #define __NVIC_PRIO_BITS 2U
- #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
- #endif
-
- #ifndef __Vendor_SysTickConfig
- #define __Vendor_SysTickConfig 0U
- #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
- #endif
-#endif
-
-/* IO definitions (access restrictions to peripheral registers) */
-/**
- \defgroup CMSIS_glob_defs CMSIS Global Defines
-
- IO Type Qualifiers are used
- \li to specify the access to peripheral variables.
- \li for automatic generation of peripheral register debug information.
-*/
-#ifdef __cplusplus
- #define __I volatile /*!< Defines 'read only' permissions */
-#else
- #define __I volatile const /*!< Defines 'read only' permissions */
-#endif
-#define __O volatile /*!< Defines 'write only' permissions */
-#define __IO volatile /*!< Defines 'read / write' permissions */
-
-/* following defines should be used for structure members */
-#define __IM volatile const /*! Defines 'read only' structure member permissions */
-#define __OM volatile /*! Defines 'write only' structure member permissions */
-#define __IOM volatile /*! Defines 'read / write' structure member permissions */
-
-/*@} end of group Cortex-M0+ */
-
-
-
-/*******************************************************************************
- * Register Abstraction
- Core Register contain:
- - Core Register
- - Core NVIC Register
- - Core SCB Register
- - Core SysTick Register
- - Core MPU Register
- ******************************************************************************/
-/**
- \defgroup CMSIS_core_register Defines and Type Definitions
- \brief Type definitions and defines for Cortex-M processor based devices.
-*/
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_CORE Status and Control Registers
- \brief Core Register type definitions.
- @{
- */
-
-/**
- \brief Union type to access the Application Program Status Register (APSR).
- */
-typedef union
-{
- struct
- {
- uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
- uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
- uint32_t C:1; /*!< bit: 29 Carry condition code flag */
- uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
- uint32_t N:1; /*!< bit: 31 Negative condition code flag */
- } b; /*!< Structure used for bit access */
- uint32_t w; /*!< Type used for word access */
-} APSR_Type;
-
-/* APSR Register Definitions */
-#define APSR_N_Pos 31U /*!< APSR: N Position */
-#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
-
-#define APSR_Z_Pos 30U /*!< APSR: Z Position */
-#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
-
-#define APSR_C_Pos 29U /*!< APSR: C Position */
-#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
-
-#define APSR_V_Pos 28U /*!< APSR: V Position */
-#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
-
-
-/**
- \brief Union type to access the Interrupt Program Status Register (IPSR).
- */
-typedef union
-{
- struct
- {
- uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
- uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
- } b; /*!< Structure used for bit access */
- uint32_t w; /*!< Type used for word access */
-} IPSR_Type;
-
-/* IPSR Register Definitions */
-#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
-#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
-
-
-/**
- \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
- */
-typedef union
-{
- struct
- {
- uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
- uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
- uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
- uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
- uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
- uint32_t C:1; /*!< bit: 29 Carry condition code flag */
- uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
- uint32_t N:1; /*!< bit: 31 Negative condition code flag */
- } b; /*!< Structure used for bit access */
- uint32_t w; /*!< Type used for word access */
-} xPSR_Type;
-
-/* xPSR Register Definitions */
-#define xPSR_N_Pos 31U /*!< xPSR: N Position */
-#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
-
-#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
-#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
-
-#define xPSR_C_Pos 29U /*!< xPSR: C Position */
-#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
-
-#define xPSR_V_Pos 28U /*!< xPSR: V Position */
-#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
-
-#define xPSR_T_Pos 24U /*!< xPSR: T Position */
-#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
-
-#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
-#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
-
-
-/**
- \brief Union type to access the Control Registers (CONTROL).
- */
-typedef union
-{
- struct
- {
- uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
- uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
- uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
- } b; /*!< Structure used for bit access */
- uint32_t w; /*!< Type used for word access */
-} CONTROL_Type;
-
-/* CONTROL Register Definitions */
-#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
-#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
-
-#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */
-#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
-
-/*@} end of group CMSIS_CORE */
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
- \brief Type definitions for the NVIC Registers
- @{
- */
-
-/**
- \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
- */
-typedef struct
-{
- __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
- uint32_t RESERVED0[31U];
- __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
- uint32_t RSERVED1[31U];
- __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
- uint32_t RESERVED2[31U];
- __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
- uint32_t RESERVED3[31U];
- uint32_t RESERVED4[64U];
- __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
-} NVIC_Type;
-
-/*@} end of group CMSIS_NVIC */
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_SCB System Control Block (SCB)
- \brief Type definitions for the System Control Block Registers
- @{
- */
-
-/**
- \brief Structure type to access the System Control Block (SCB).
- */
-typedef struct
-{
- __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
- __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
-#if (__VTOR_PRESENT == 1U)
- __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
-#else
- uint32_t RESERVED0;
-#endif
- __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
- __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
- __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
- uint32_t RESERVED1;
- __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
- __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
-} SCB_Type;
-
-/* SCB CPUID Register Definitions */
-#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
-#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
-
-#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
-#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
-
-#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
-#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
-
-#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
-#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
-
-#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
-#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
-
-/* SCB Interrupt Control State Register Definitions */
-#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
-#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
-
-#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
-#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
-
-#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
-#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
-
-#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
-#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
-
-#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
-#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
-
-#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
-#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
-
-#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
-#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
-
-#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
-#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
-
-#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
-#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
-
-#if (__VTOR_PRESENT == 1U)
-/* SCB Interrupt Control State Register Definitions */
-#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */
-#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
-#endif
-
-/* SCB Application Interrupt and Reset Control Register Definitions */
-#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
-#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
-
-#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
-#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
-
-#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
-#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
-
-#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
-#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
-
-#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
-#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
-
-/* SCB System Control Register Definitions */
-#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
-#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
-
-#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
-#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
-
-#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
-#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
-
-/* SCB Configuration Control Register Definitions */
-#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
-#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
-
-#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
-#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
-
-/* SCB System Handler Control and State Register Definitions */
-#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
-#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
-
-/*@} end of group CMSIS_SCB */
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_SysTick System Tick Timer (SysTick)
- \brief Type definitions for the System Timer Registers.
- @{
- */
-
-/**
- \brief Structure type to access the System Timer (SysTick).
- */
-typedef struct
-{
- __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
- __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
- __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
- __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
-} SysTick_Type;
-
-/* SysTick Control / Status Register Definitions */
-#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
-#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
-
-#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
-#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
-
-#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
-#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
-
-#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
-#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
-
-/* SysTick Reload Register Definitions */
-#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
-#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
-
-/* SysTick Current Register Definitions */
-#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
-#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
-
-/* SysTick Calibration Register Definitions */
-#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
-#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
-
-#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
-#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
-
-#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
-#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
-
-/*@} end of group CMSIS_SysTick */
-
-#if (__MPU_PRESENT == 1U)
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_MPU Memory Protection Unit (MPU)
- \brief Type definitions for the Memory Protection Unit (MPU)
- @{
- */
-
-/**
- \brief Structure type to access the Memory Protection Unit (MPU).
- */
-typedef struct
-{
- __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
- __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
- __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
- __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
- __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
-} MPU_Type;
-
-/* MPU Type Register Definitions */
-#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
-#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
-
-#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
-#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
-
-#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
-#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
-
-/* MPU Control Register Definitions */
-#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
-#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
-
-#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
-#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
-
-#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
-#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
-
-/* MPU Region Number Register Definitions */
-#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
-#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
-
-/* MPU Region Base Address Register Definitions */
-#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */
-#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
-
-#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */
-#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
-
-#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */
-#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */
-
-/* MPU Region Attribute and Size Register Definitions */
-#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */
-#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
-
-#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */
-#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
-
-#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */
-#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
-
-#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */
-#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
-
-#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */
-#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
-
-#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */
-#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
-
-#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */
-#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
-
-#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */
-#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
-
-#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */
-#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
-
-#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */
-#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */
-
-/*@} end of group CMSIS_MPU */
-#endif
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
- \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
- Therefore they are not covered by the Cortex-M0+ header file.
- @{
- */
-/*@} end of group CMSIS_CoreDebug */
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_core_bitfield Core register bit field macros
- \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
- @{
- */
-
-/**
- \brief Mask and shift a bit field value for use in a register bit range.
- \param[in] field Name of the register bit field.
- \param[in] value Value of the bit field.
- \return Masked and shifted value.
-*/
-#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
-
-/**
- \brief Mask and shift a register value to extract a bit filed value.
- \param[in] field Name of the register bit field.
- \param[in] value Value of register.
- \return Masked and shifted bit field value.
-*/
-#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
-
-/*@} end of group CMSIS_core_bitfield */
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_core_base Core Definitions
- \brief Definitions for base addresses, unions, and structures.
- @{
- */
-
-/* Memory mapping of Cortex-M0+ Hardware */
-#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
-#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
-#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
-#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
-
-#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
-#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
-#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
-
-#if (__MPU_PRESENT == 1U)
- #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
- #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
-#endif
-
-/*@} */
-
-
-
-/*******************************************************************************
- * Hardware Abstraction Layer
- Core Function Interface contains:
- - Core NVIC Functions
- - Core SysTick Functions
- - Core Register Access Functions
- ******************************************************************************/
-/**
- \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
-*/
-
-
-
-/* ########################## NVIC functions #################################### */
-/**
- \ingroup CMSIS_Core_FunctionInterface
- \defgroup CMSIS_Core_NVICFunctions NVIC Functions
- \brief Functions that manage interrupts and exceptions via the NVIC.
- @{
- */
-
-/* Interrupt Priorities are WORD accessible only under ARMv6M */
-/* The following MACROS handle generation of the register offset and byte masks */
-#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
-#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
-#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
-
-
-/**
- \brief Enable External Interrupt
- \details Enables a device-specific interrupt in the NVIC interrupt controller.
- \param [in] IRQn External interrupt number. Value cannot be negative.
- */
-__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
-{
- NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
-}
-
-
-/**
- \brief Disable External Interrupt
- \details Disables a device-specific interrupt in the NVIC interrupt controller.
- \param [in] IRQn External interrupt number. Value cannot be negative.
- */
-__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
-{
- NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
-}
-
-
-/**
- \brief Get Pending Interrupt
- \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
- \param [in] IRQn Interrupt number.
- \return 0 Interrupt status is not pending.
- \return 1 Interrupt status is pending.
- */
-__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
-{
- return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
-}
-
-
-/**
- \brief Set Pending Interrupt
- \details Sets the pending bit of an external interrupt.
- \param [in] IRQn Interrupt number. Value cannot be negative.
- */
-__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
-{
- NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
-}
-
-
-/**
- \brief Clear Pending Interrupt
- \details Clears the pending bit of an external interrupt.
- \param [in] IRQn External interrupt number. Value cannot be negative.
- */
-__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
-{
- NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
-}
-
-
-/**
- \brief Set Interrupt Priority
- \details Sets the priority of an interrupt.
- \note The priority cannot be set for every core interrupt.
- \param [in] IRQn Interrupt number.
- \param [in] priority Priority to set.
- */
-__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
-{
- if ((int32_t)(IRQn) < 0)
- {
- SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
- (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
- }
- else
- {
- NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
- (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
- }
-}
-
-
-/**
- \brief Get Interrupt Priority
- \details Reads the priority of an interrupt.
- The interrupt number can be positive to specify an external (device specific) interrupt,
- or negative to specify an internal (core) interrupt.
- \param [in] IRQn Interrupt number.
- \return Interrupt Priority.
- Value is aligned automatically to the implemented priority bits of the microcontroller.
- */
-__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
-{
-
- if ((int32_t)(IRQn) < 0)
- {
- return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
- }
- else
- {
- return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
- }
-}
-
-
-/**
- \brief System Reset
- \details Initiates a system reset request to reset the MCU.
- */
-__STATIC_INLINE void NVIC_SystemReset(void)
-{
- __DSB(); /* Ensure all outstanding memory accesses included
- buffered write are completed before reset */
- SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
- SCB_AIRCR_SYSRESETREQ_Msk);
- __DSB(); /* Ensure completion of memory access */
-
- for(;;) /* wait until reset */
- {
- __NOP();
- }
-}
-
-/*@} end of CMSIS_Core_NVICFunctions */
-
-
-
-/* ################################## SysTick function ############################################ */
-/**
- \ingroup CMSIS_Core_FunctionInterface
- \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
- \brief Functions that configure the System.
- @{
- */
-
-#if (__Vendor_SysTickConfig == 0U)
-
-/**
- \brief System Tick Configuration
- \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
- Counter is in free running mode to generate periodic interrupts.
- \param [in] ticks Number of ticks between two interrupts.
- \return 0 Function succeeded.
- \return 1 Function failed.
- \note When the variable __Vendor_SysTickConfig is set to 1, then the
- function SysTick_Config is not included. In this case, the file device.h
- must contain a vendor-specific implementation of this function.
- */
-__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
-{
- if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
- {
- return (1UL); /* Reload value impossible */
- }
-
- SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
- NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
- SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
- SysTick_CTRL_TICKINT_Msk |
- SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
- return (0UL); /* Function successful */
-}
-
-#endif
-
-/*@} end of CMSIS_Core_SysTickFunctions */
-
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __CORE_CM0PLUS_H_DEPENDANT */
-
-#endif /* __CMSIS_GENERIC */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Include/core_cmFunc.h b/assets/templates/blackpill/Drivers/CMSIS/Include/core_cmFunc.h
deleted file mode 100644
index ca319a5..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Include/core_cmFunc.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/**************************************************************************//**
- * @file core_cmFunc.h
- * @brief CMSIS Cortex-M Core Function Access Header File
- * @version V4.30
- * @date 20. October 2015
- ******************************************************************************/
-/* Copyright (c) 2009 - 2015 ARM LIMITED
-
- 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 ARM 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 COPYRIGHT HOLDERS AND 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.
- ---------------------------------------------------------------------------*/
-
-
-#if defined ( __ICCARM__ )
- #pragma system_include /* treat file as system include file for MISRA check */
-#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
- #pragma clang system_header /* treat file as system include file */
-#endif
-
-#ifndef __CORE_CMFUNC_H
-#define __CORE_CMFUNC_H
-
-
-/* ########################### Core Function Access ########################### */
-/** \ingroup CMSIS_Core_FunctionInterface
- \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
- @{
-*/
-
-/*------------------ RealView Compiler -----------------*/
-#if defined ( __CC_ARM )
- #include "cmsis_armcc.h"
-
-/*------------------ ARM Compiler V6 -------------------*/
-#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
- #include "cmsis_armcc_V6.h"
-
-/*------------------ GNU Compiler ----------------------*/
-#elif defined ( __GNUC__ )
- #include "cmsis_gcc.h"
-
-/*------------------ ICC Compiler ----------------------*/
-#elif defined ( __ICCARM__ )
- #include
-
-/*------------------ TI CCS Compiler -------------------*/
-#elif defined ( __TMS470__ )
- #include
-
-/*------------------ TASKING Compiler ------------------*/
-#elif defined ( __TASKING__ )
- /*
- * The CMSIS functions have been implemented as intrinsics in the compiler.
- * Please use "carm -?i" to get an up to date list of all intrinsics,
- * Including the CMSIS ones.
- */
-
-/*------------------ COSMIC Compiler -------------------*/
-#elif defined ( __CSMC__ )
- #include
-
-#endif
-
-/*@} end of CMSIS_Core_RegAccFunctions */
-
-#endif /* __CORE_CMFUNC_H */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Include/core_cmInstr.h b/assets/templates/blackpill/Drivers/CMSIS/Include/core_cmInstr.h
deleted file mode 100644
index a0a5064..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Include/core_cmInstr.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/**************************************************************************//**
- * @file core_cmInstr.h
- * @brief CMSIS Cortex-M Core Instruction Access Header File
- * @version V4.30
- * @date 20. October 2015
- ******************************************************************************/
-/* Copyright (c) 2009 - 2015 ARM LIMITED
-
- 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 ARM 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 COPYRIGHT HOLDERS AND 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.
- ---------------------------------------------------------------------------*/
-
-
-#if defined ( __ICCARM__ )
- #pragma system_include /* treat file as system include file for MISRA check */
-#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
- #pragma clang system_header /* treat file as system include file */
-#endif
-
-#ifndef __CORE_CMINSTR_H
-#define __CORE_CMINSTR_H
-
-
-/* ########################## Core Instruction Access ######################### */
-/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
- Access to dedicated instructions
- @{
-*/
-
-/*------------------ RealView Compiler -----------------*/
-#if defined ( __CC_ARM )
- #include "cmsis_armcc.h"
-
-/*------------------ ARM Compiler V6 -------------------*/
-#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
- #include "cmsis_armcc_V6.h"
-
-/*------------------ GNU Compiler ----------------------*/
-#elif defined ( __GNUC__ )
- #include "cmsis_gcc.h"
-
-/*------------------ ICC Compiler ----------------------*/
-#elif defined ( __ICCARM__ )
- #include
-
-/*------------------ TI CCS Compiler -------------------*/
-#elif defined ( __TMS470__ )
- #include
-
-/*------------------ TASKING Compiler ------------------*/
-#elif defined ( __TASKING__ )
- /*
- * The CMSIS functions have been implemented as intrinsics in the compiler.
- * Please use "carm -?i" to get an up to date list of all intrinsics,
- * Including the CMSIS ones.
- */
-
-/*------------------ COSMIC Compiler -------------------*/
-#elif defined ( __CSMC__ )
- #include
-
-#endif
-
-/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
-
-#endif /* __CORE_CMINSTR_H */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Include/core_cmSimd.h b/assets/templates/blackpill/Drivers/CMSIS/Include/core_cmSimd.h
deleted file mode 100644
index 4d76bf9..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Include/core_cmSimd.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/**************************************************************************//**
- * @file core_cmSimd.h
- * @brief CMSIS Cortex-M SIMD Header File
- * @version V4.30
- * @date 20. October 2015
- ******************************************************************************/
-/* Copyright (c) 2009 - 2015 ARM LIMITED
-
- 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 ARM 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 COPYRIGHT HOLDERS AND 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.
- ---------------------------------------------------------------------------*/
-
-
-#if defined ( __ICCARM__ )
- #pragma system_include /* treat file as system include file for MISRA check */
-#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
- #pragma clang system_header /* treat file as system include file */
-#endif
-
-#ifndef __CORE_CMSIMD_H
-#define __CORE_CMSIMD_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-
-/* ################### Compiler specific Intrinsics ########################### */
-/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
- Access to dedicated SIMD instructions
- @{
-*/
-
-/*------------------ RealView Compiler -----------------*/
-#if defined ( __CC_ARM )
- #include "cmsis_armcc.h"
-
-/*------------------ ARM Compiler V6 -------------------*/
-#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
- #include "cmsis_armcc_V6.h"
-
-/*------------------ GNU Compiler ----------------------*/
-#elif defined ( __GNUC__ )
- #include "cmsis_gcc.h"
-
-/*------------------ ICC Compiler ----------------------*/
-#elif defined ( __ICCARM__ )
- #include
-
-/*------------------ TI CCS Compiler -------------------*/
-#elif defined ( __TMS470__ )
- #include
-
-/*------------------ TASKING Compiler ------------------*/
-#elif defined ( __TASKING__ )
- /*
- * The CMSIS functions have been implemented as intrinsics in the compiler.
- * Please use "carm -?i" to get an up to date list of all intrinsics,
- * Including the CMSIS ones.
- */
-
-/*------------------ COSMIC Compiler -------------------*/
-#elif defined ( __CSMC__ )
- #include
-
-#endif
-
-/*@} end of group CMSIS_SIMD_intrinsics */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __CORE_CMSIMD_H */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Include/core_sc000.h b/assets/templates/blackpill/Drivers/CMSIS/Include/core_sc000.h
deleted file mode 100644
index ea16bf3..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/Include/core_sc000.h
+++ /dev/null
@@ -1,926 +0,0 @@
-/**************************************************************************//**
- * @file core_sc000.h
- * @brief CMSIS SC000 Core Peripheral Access Layer Header File
- * @version V4.30
- * @date 20. October 2015
- ******************************************************************************/
-/* Copyright (c) 2009 - 2015 ARM LIMITED
-
- 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 ARM 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 COPYRIGHT HOLDERS AND 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.
- ---------------------------------------------------------------------------*/
-
-
-#if defined ( __ICCARM__ )
- #pragma system_include /* treat file as system include file for MISRA check */
-#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
- #pragma clang system_header /* treat file as system include file */
-#endif
-
-#ifndef __CORE_SC000_H_GENERIC
-#define __CORE_SC000_H_GENERIC
-
-#include
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/**
- \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
- CMSIS violates the following MISRA-C:2004 rules:
-
- \li Required Rule 8.5, object/function definition in header file.
- Function definitions in header files are used to allow 'inlining'.
-
- \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers.
-
- \li Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code.
- */
-
-
-/*******************************************************************************
- * CMSIS definitions
- ******************************************************************************/
-/**
- \ingroup SC000
- @{
- */
-
-/* CMSIS SC000 definitions */
-#define __SC000_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
-#define __SC000_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
-#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16U) | \
- __SC000_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
-
-#define __CORTEX_SC (000U) /*!< Cortex secure core */
-
-
-#if defined ( __CC_ARM )
- #define __ASM __asm /*!< asm keyword for ARM Compiler */
- #define __INLINE __inline /*!< inline keyword for ARM Compiler */
- #define __STATIC_INLINE static __inline
-
-#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
- #define __ASM __asm /*!< asm keyword for ARM Compiler */
- #define __INLINE __inline /*!< inline keyword for ARM Compiler */
- #define __STATIC_INLINE static __inline
-
-#elif defined ( __GNUC__ )
- #define __ASM __asm /*!< asm keyword for GNU Compiler */
- #define __INLINE inline /*!< inline keyword for GNU Compiler */
- #define __STATIC_INLINE static inline
-
-#elif defined ( __ICCARM__ )
- #define __ASM __asm /*!< asm keyword for IAR Compiler */
- #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
- #define __STATIC_INLINE static inline
-
-#elif defined ( __TMS470__ )
- #define __ASM __asm /*!< asm keyword for TI CCS Compiler */
- #define __STATIC_INLINE static inline
-
-#elif defined ( __TASKING__ )
- #define __ASM __asm /*!< asm keyword for TASKING Compiler */
- #define __INLINE inline /*!< inline keyword for TASKING Compiler */
- #define __STATIC_INLINE static inline
-
-#elif defined ( __CSMC__ )
- #define __packed
- #define __ASM _asm /*!< asm keyword for COSMIC Compiler */
- #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
- #define __STATIC_INLINE static inline
-
-#else
- #error Unknown compiler
-#endif
-
-/** __FPU_USED indicates whether an FPU is used or not.
- This core does not support an FPU at all
-*/
-#define __FPU_USED 0U
-
-#if defined ( __CC_ARM )
- #if defined __TARGET_FPU_VFP
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
- #if defined __ARM_PCS_VFP
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#elif defined ( __GNUC__ )
- #if defined (__VFP_FP__) && !defined(__SOFTFP__)
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#elif defined ( __ICCARM__ )
- #if defined __ARMVFP__
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#elif defined ( __TMS470__ )
- #if defined __TI_VFP_SUPPORT__
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#elif defined ( __TASKING__ )
- #if defined __FPU_VFP__
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#elif defined ( __CSMC__ )
- #if ( __CSMC__ & 0x400U)
- #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
- #endif
-
-#endif
-
-#include "core_cmInstr.h" /* Core Instruction Access */
-#include "core_cmFunc.h" /* Core Function Access */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __CORE_SC000_H_GENERIC */
-
-#ifndef __CMSIS_GENERIC
-
-#ifndef __CORE_SC000_H_DEPENDANT
-#define __CORE_SC000_H_DEPENDANT
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* check device defines and use defaults */
-#if defined __CHECK_DEVICE_DEFINES
- #ifndef __SC000_REV
- #define __SC000_REV 0x0000U
- #warning "__SC000_REV not defined in device header file; using default!"
- #endif
-
- #ifndef __MPU_PRESENT
- #define __MPU_PRESENT 0U
- #warning "__MPU_PRESENT not defined in device header file; using default!"
- #endif
-
- #ifndef __NVIC_PRIO_BITS
- #define __NVIC_PRIO_BITS 2U
- #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
- #endif
-
- #ifndef __Vendor_SysTickConfig
- #define __Vendor_SysTickConfig 0U
- #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
- #endif
-#endif
-
-/* IO definitions (access restrictions to peripheral registers) */
-/**
- \defgroup CMSIS_glob_defs CMSIS Global Defines
-
- IO Type Qualifiers are used
- \li to specify the access to peripheral variables.
- \li for automatic generation of peripheral register debug information.
-*/
-#ifdef __cplusplus
- #define __I volatile /*!< Defines 'read only' permissions */
-#else
- #define __I volatile const /*!< Defines 'read only' permissions */
-#endif
-#define __O volatile /*!< Defines 'write only' permissions */
-#define __IO volatile /*!< Defines 'read / write' permissions */
-
-/* following defines should be used for structure members */
-#define __IM volatile const /*! Defines 'read only' structure member permissions */
-#define __OM volatile /*! Defines 'write only' structure member permissions */
-#define __IOM volatile /*! Defines 'read / write' structure member permissions */
-
-/*@} end of group SC000 */
-
-
-
-/*******************************************************************************
- * Register Abstraction
- Core Register contain:
- - Core Register
- - Core NVIC Register
- - Core SCB Register
- - Core SysTick Register
- - Core MPU Register
- ******************************************************************************/
-/**
- \defgroup CMSIS_core_register Defines and Type Definitions
- \brief Type definitions and defines for Cortex-M processor based devices.
-*/
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_CORE Status and Control Registers
- \brief Core Register type definitions.
- @{
- */
-
-/**
- \brief Union type to access the Application Program Status Register (APSR).
- */
-typedef union
-{
- struct
- {
- uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
- uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
- uint32_t C:1; /*!< bit: 29 Carry condition code flag */
- uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
- uint32_t N:1; /*!< bit: 31 Negative condition code flag */
- } b; /*!< Structure used for bit access */
- uint32_t w; /*!< Type used for word access */
-} APSR_Type;
-
-/* APSR Register Definitions */
-#define APSR_N_Pos 31U /*!< APSR: N Position */
-#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
-
-#define APSR_Z_Pos 30U /*!< APSR: Z Position */
-#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
-
-#define APSR_C_Pos 29U /*!< APSR: C Position */
-#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
-
-#define APSR_V_Pos 28U /*!< APSR: V Position */
-#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
-
-
-/**
- \brief Union type to access the Interrupt Program Status Register (IPSR).
- */
-typedef union
-{
- struct
- {
- uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
- uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
- } b; /*!< Structure used for bit access */
- uint32_t w; /*!< Type used for word access */
-} IPSR_Type;
-
-/* IPSR Register Definitions */
-#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
-#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
-
-
-/**
- \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
- */
-typedef union
-{
- struct
- {
- uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
- uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
- uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
- uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
- uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
- uint32_t C:1; /*!< bit: 29 Carry condition code flag */
- uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
- uint32_t N:1; /*!< bit: 31 Negative condition code flag */
- } b; /*!< Structure used for bit access */
- uint32_t w; /*!< Type used for word access */
-} xPSR_Type;
-
-/* xPSR Register Definitions */
-#define xPSR_N_Pos 31U /*!< xPSR: N Position */
-#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
-
-#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
-#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
-
-#define xPSR_C_Pos 29U /*!< xPSR: C Position */
-#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
-
-#define xPSR_V_Pos 28U /*!< xPSR: V Position */
-#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
-
-#define xPSR_T_Pos 24U /*!< xPSR: T Position */
-#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
-
-#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
-#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
-
-
-/**
- \brief Union type to access the Control Registers (CONTROL).
- */
-typedef union
-{
- struct
- {
- uint32_t _reserved0:1; /*!< bit: 0 Reserved */
- uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
- uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
- } b; /*!< Structure used for bit access */
- uint32_t w; /*!< Type used for word access */
-} CONTROL_Type;
-
-/* CONTROL Register Definitions */
-#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
-#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
-
-/*@} end of group CMSIS_CORE */
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
- \brief Type definitions for the NVIC Registers
- @{
- */
-
-/**
- \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
- */
-typedef struct
-{
- __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
- uint32_t RESERVED0[31U];
- __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
- uint32_t RSERVED1[31U];
- __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
- uint32_t RESERVED2[31U];
- __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
- uint32_t RESERVED3[31U];
- uint32_t RESERVED4[64U];
- __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
-} NVIC_Type;
-
-/*@} end of group CMSIS_NVIC */
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_SCB System Control Block (SCB)
- \brief Type definitions for the System Control Block Registers
- @{
- */
-
-/**
- \brief Structure type to access the System Control Block (SCB).
- */
-typedef struct
-{
- __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
- __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
- __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
- __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
- __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
- __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
- uint32_t RESERVED0[1U];
- __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
- __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
- uint32_t RESERVED1[154U];
- __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */
-} SCB_Type;
-
-/* SCB CPUID Register Definitions */
-#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
-#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
-
-#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
-#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
-
-#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
-#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
-
-#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
-#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
-
-#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
-#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
-
-/* SCB Interrupt Control State Register Definitions */
-#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
-#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
-
-#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
-#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
-
-#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
-#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
-
-#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
-#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
-
-#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
-#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
-
-#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
-#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
-
-#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
-#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
-
-#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
-#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
-
-#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
-#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
-
-/* SCB Interrupt Control State Register Definitions */
-#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */
-#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
-
-/* SCB Application Interrupt and Reset Control Register Definitions */
-#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
-#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
-
-#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
-#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
-
-#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
-#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
-
-#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
-#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
-
-#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
-#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
-
-/* SCB System Control Register Definitions */
-#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
-#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
-
-#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
-#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
-
-#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
-#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
-
-/* SCB Configuration Control Register Definitions */
-#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
-#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
-
-#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
-#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
-
-/* SCB System Handler Control and State Register Definitions */
-#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
-#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
-
-/*@} end of group CMSIS_SCB */
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
- \brief Type definitions for the System Control and ID Register not in the SCB
- @{
- */
-
-/**
- \brief Structure type to access the System Control and ID Register not in the SCB.
- */
-typedef struct
-{
- uint32_t RESERVED0[2U];
- __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */
-} SCnSCB_Type;
-
-/* Auxiliary Control Register Definitions */
-#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */
-#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */
-
-/*@} end of group CMSIS_SCnotSCB */
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_SysTick System Tick Timer (SysTick)
- \brief Type definitions for the System Timer Registers.
- @{
- */
-
-/**
- \brief Structure type to access the System Timer (SysTick).
- */
-typedef struct
-{
- __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
- __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
- __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
- __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
-} SysTick_Type;
-
-/* SysTick Control / Status Register Definitions */
-#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
-#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
-
-#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
-#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
-
-#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
-#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
-
-#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
-#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
-
-/* SysTick Reload Register Definitions */
-#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
-#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
-
-/* SysTick Current Register Definitions */
-#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
-#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
-
-/* SysTick Calibration Register Definitions */
-#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
-#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
-
-#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
-#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
-
-#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
-#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
-
-/*@} end of group CMSIS_SysTick */
-
-#if (__MPU_PRESENT == 1U)
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_MPU Memory Protection Unit (MPU)
- \brief Type definitions for the Memory Protection Unit (MPU)
- @{
- */
-
-/**
- \brief Structure type to access the Memory Protection Unit (MPU).
- */
-typedef struct
-{
- __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
- __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
- __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
- __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
- __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
-} MPU_Type;
-
-/* MPU Type Register Definitions */
-#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
-#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
-
-#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
-#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
-
-#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
-#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
-
-/* MPU Control Register Definitions */
-#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
-#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
-
-#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
-#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
-
-#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
-#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
-
-/* MPU Region Number Register Definitions */
-#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
-#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
-
-/* MPU Region Base Address Register Definitions */
-#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */
-#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
-
-#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */
-#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
-
-#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */
-#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */
-
-/* MPU Region Attribute and Size Register Definitions */
-#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */
-#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
-
-#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */
-#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
-
-#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */
-#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
-
-#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */
-#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
-
-#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */
-#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
-
-#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */
-#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
-
-#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */
-#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
-
-#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */
-#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
-
-#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */
-#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
-
-#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */
-#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */
-
-/*@} end of group CMSIS_MPU */
-#endif
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
- \brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
- Therefore they are not covered by the SC000 header file.
- @{
- */
-/*@} end of group CMSIS_CoreDebug */
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_core_bitfield Core register bit field macros
- \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
- @{
- */
-
-/**
- \brief Mask and shift a bit field value for use in a register bit range.
- \param[in] field Name of the register bit field.
- \param[in] value Value of the bit field.
- \return Masked and shifted value.
-*/
-#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
-
-/**
- \brief Mask and shift a register value to extract a bit filed value.
- \param[in] field Name of the register bit field.
- \param[in] value Value of register.
- \return Masked and shifted bit field value.
-*/
-#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
-
-/*@} end of group CMSIS_core_bitfield */
-
-
-/**
- \ingroup CMSIS_core_register
- \defgroup CMSIS_core_base Core Definitions
- \brief Definitions for base addresses, unions, and structures.
- @{
- */
-
-/* Memory mapping of SC000 Hardware */
-#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
-#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
-#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
-#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
-
-#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
-#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
-#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
-#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
-
-#if (__MPU_PRESENT == 1U)
- #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
- #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
-#endif
-
-/*@} */
-
-
-
-/*******************************************************************************
- * Hardware Abstraction Layer
- Core Function Interface contains:
- - Core NVIC Functions
- - Core SysTick Functions
- - Core Register Access Functions
- ******************************************************************************/
-/**
- \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
-*/
-
-
-
-/* ########################## NVIC functions #################################### */
-/**
- \ingroup CMSIS_Core_FunctionInterface
- \defgroup CMSIS_Core_NVICFunctions NVIC Functions
- \brief Functions that manage interrupts and exceptions via the NVIC.
- @{
- */
-
-/* Interrupt Priorities are WORD accessible only under ARMv6M */
-/* The following MACROS handle generation of the register offset and byte masks */
-#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
-#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
-#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
-
-
-/**
- \brief Enable External Interrupt
- \details Enables a device-specific interrupt in the NVIC interrupt controller.
- \param [in] IRQn External interrupt number. Value cannot be negative.
- */
-__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
-{
- NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
-}
-
-
-/**
- \brief Disable External Interrupt
- \details Disables a device-specific interrupt in the NVIC interrupt controller.
- \param [in] IRQn External interrupt number. Value cannot be negative.
- */
-__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
-{
- NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
-}
-
-
-/**
- \brief Get Pending Interrupt
- \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
- \param [in] IRQn Interrupt number.
- \return 0 Interrupt status is not pending.
- \return 1 Interrupt status is pending.
- */
-__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
-{
- return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
-}
-
-
-/**
- \brief Set Pending Interrupt
- \details Sets the pending bit of an external interrupt.
- \param [in] IRQn Interrupt number. Value cannot be negative.
- */
-__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
-{
- NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
-}
-
-
-/**
- \brief Clear Pending Interrupt
- \details Clears the pending bit of an external interrupt.
- \param [in] IRQn External interrupt number. Value cannot be negative.
- */
-__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
-{
- NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
-}
-
-
-/**
- \brief Set Interrupt Priority
- \details Sets the priority of an interrupt.
- \note The priority cannot be set for every core interrupt.
- \param [in] IRQn Interrupt number.
- \param [in] priority Priority to set.
- */
-__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
-{
- if ((int32_t)(IRQn) < 0)
- {
- SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
- (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
- }
- else
- {
- NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
- (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
- }
-}
-
-
-/**
- \brief Get Interrupt Priority
- \details Reads the priority of an interrupt.
- The interrupt number can be positive to specify an external (device specific) interrupt,
- or negative to specify an internal (core) interrupt.
- \param [in] IRQn Interrupt number.
- \return Interrupt Priority.
- Value is aligned automatically to the implemented priority bits of the microcontroller.
- */
-__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
-{
-
- if ((int32_t)(IRQn) < 0)
- {
- return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
- }
- else
- {
- return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
- }
-}
-
-
-/**
- \brief System Reset
- \details Initiates a system reset request to reset the MCU.
- */
-__STATIC_INLINE void NVIC_SystemReset(void)
-{
- __DSB(); /* Ensure all outstanding memory accesses included
- buffered write are completed before reset */
- SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
- SCB_AIRCR_SYSRESETREQ_Msk);
- __DSB(); /* Ensure completion of memory access */
-
- for(;;) /* wait until reset */
- {
- __NOP();
- }
-}
-
-/*@} end of CMSIS_Core_NVICFunctions */
-
-
-
-/* ################################## SysTick function ############################################ */
-/**
- \ingroup CMSIS_Core_FunctionInterface
- \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
- \brief Functions that configure the System.
- @{
- */
-
-#if (__Vendor_SysTickConfig == 0U)
-
-/**
- \brief System Tick Configuration
- \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
- Counter is in free running mode to generate periodic interrupts.
- \param [in] ticks Number of ticks between two interrupts.
- \return 0 Function succeeded.
- \return 1 Function failed.
- \note When the variable __Vendor_SysTickConfig is set to 1, then the
- function SysTick_Config is not included. In this case, the file device.h
- must contain a vendor-specific implementation of this function.
- */
-__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
-{
- if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
- {
- return (1UL); /* Reload value impossible */
- }
-
- SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
- NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
- SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
- SysTick_CTRL_TICKINT_Msk |
- SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
- return (0UL); /* Function successful */
-}
-
-#endif
-
-/*@} end of CMSIS_Core_SysTickFunctions */
-
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __CORE_SC000_H_DEPENDANT */
-
-#endif /* __CMSIS_GENERIC */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/RTOS/Template/cmsis_os.h b/assets/templates/blackpill/Drivers/CMSIS/RTOS/Template/cmsis_os.h
deleted file mode 100644
index 068ebca..0000000
--- a/assets/templates/blackpill/Drivers/CMSIS/RTOS/Template/cmsis_os.h
+++ /dev/null
@@ -1,707 +0,0 @@
-/* ----------------------------------------------------------------------
- * $Date: 5. February 2013
- * $Revision: V1.02
- *
- * Project: CMSIS-RTOS API
- * Title: cmsis_os.h template header file
- *
- * Version 0.02
- * Initial Proposal Phase
- * Version 0.03
- * osKernelStart added, optional feature: main started as thread
- * osSemaphores have standard behavior
- * osTimerCreate does not start the timer, added osTimerStart
- * osThreadPass is renamed to osThreadYield
- * Version 1.01
- * Support for C++ interface
- * - const attribute removed from the osXxxxDef_t typedef's
- * - const attribute added to the osXxxxDef macros
- * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete
- * Added: osKernelInitialize
- * Version 1.02
- * Control functions for short timeouts in microsecond resolution:
- * Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec
- * Removed: osSignalGet
- *----------------------------------------------------------------------------
- *
- * Copyright (c) 2013 ARM LIMITED
- * 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 ARM 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 COPYRIGHT HOLDERS AND 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 _CMSIS_OS_H
-#define _CMSIS_OS_H
-
-/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version.
-#define osCMSIS 0x10002 ///< API version (main [31:16] .sub [15:0])
-
-/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number.
-#define osCMSIS_KERNEL 0x10000 ///< RTOS identification and version (main [31:16] .sub [15:0])
-
-/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS.
-#define osKernelSystemId "KERNEL V1.00" ///< RTOS identification string
-
-/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS.
-#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available
-#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available
-#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available
-#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available
-#define osFeature_Signals 8 ///< maximum number of Signal Flags available per thread
-#define osFeature_Semaphore 30 ///< maximum count for \ref osSemaphoreCreate function
-#define osFeature_Wait 1 ///< osWait function: 1=available, 0=not available
-#define osFeature_SysTick 1 ///< osKernelSysTick functions: 1=available, 0=not available
-
-#include
-#include
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-
-// ==== Enumeration, structures, defines ====
-
-/// Priority used for thread control.
-/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS.
-typedef enum {
- osPriorityIdle = -3, ///< priority: idle (lowest)
- osPriorityLow = -2, ///< priority: low
- osPriorityBelowNormal = -1, ///< priority: below normal
- osPriorityNormal = 0, ///< priority: normal (default)
- osPriorityAboveNormal = +1, ///< priority: above normal
- osPriorityHigh = +2, ///< priority: high
- osPriorityRealtime = +3, ///< priority: realtime (highest)
- osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority
-} osPriority;
-
-/// Timeout value.
-/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS.
-#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value
-
-/// Status code values returned by CMSIS-RTOS functions.
-/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS.
-typedef enum {
- osOK = 0, ///< function completed; no error or event occurred.
- osEventSignal = 0x08, ///< function completed; signal event occurred.
- osEventMessage = 0x10, ///< function completed; message event occurred.
- osEventMail = 0x20, ///< function completed; mail event occurred.
- osEventTimeout = 0x40, ///< function completed; timeout occurred.
- osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object.
- osErrorResource = 0x81, ///< resource not available: a specified resource was not available.
- osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period.
- osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines.
- osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object.
- osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority.
- osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation.
- osErrorValue = 0x86, ///< value of a parameter is out of range.
- osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits.
- os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization.
-} osStatus;
-
-
-/// Timer type value for the timer definition.
-/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS.
-typedef enum {
- osTimerOnce = 0, ///< one-shot timer
- osTimerPeriodic = 1 ///< repeating timer
-} os_timer_type;
-
-/// Entry point of a thread.
-/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS.
-typedef void (*os_pthread) (void const *argument);
-
-/// Entry point of a timer call back function.
-/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS.
-typedef void (*os_ptimer) (void const *argument);
-
-// >>> the following data type definitions may shall adapted towards a specific RTOS
-
-/// Thread ID identifies the thread (pointer to a thread control block).
-/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS.
-typedef struct os_thread_cb *osThreadId;
-
-/// Timer ID identifies the timer (pointer to a timer control block).
-/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS.
-typedef struct os_timer_cb *osTimerId;
-
-/// Mutex ID identifies the mutex (pointer to a mutex control block).
-/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS.
-typedef struct os_mutex_cb *osMutexId;
-
-/// Semaphore ID identifies the semaphore (pointer to a semaphore control block).
-/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS.
-typedef struct os_semaphore_cb *osSemaphoreId;
-
-/// Pool ID identifies the memory pool (pointer to a memory pool control block).
-/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS.
-typedef struct os_pool_cb *osPoolId;
-
-/// Message ID identifies the message queue (pointer to a message queue control block).
-/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS.
-typedef struct os_messageQ_cb *osMessageQId;
-
-/// Mail ID identifies the mail queue (pointer to a mail queue control block).
-/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS.
-typedef struct os_mailQ_cb *osMailQId;
-
-
-/// Thread Definition structure contains startup information of a thread.
-/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS.
-typedef struct os_thread_def {
- os_pthread pthread; ///< start address of thread function
- osPriority tpriority; ///< initial thread priority
- uint32_t instances; ///< maximum number of instances of that thread function
- uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size
-} osThreadDef_t;
-
-/// Timer Definition structure contains timer parameters.
-/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS.
-typedef struct os_timer_def {
- os_ptimer ptimer; ///< start address of a timer function
-} osTimerDef_t;
-
-/// Mutex Definition structure contains setup information for a mutex.
-/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS.
-typedef struct os_mutex_def {
- uint32_t dummy; ///< dummy value.
-} osMutexDef_t;
-
-/// Semaphore Definition structure contains setup information for a semaphore.
-/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS.
-typedef struct os_semaphore_def {
- uint32_t dummy; ///< dummy value.
-} osSemaphoreDef_t;
-
-/// Definition structure for memory block allocation.
-/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS.
-typedef struct os_pool_def {
- uint32_t pool_sz; ///< number of items (elements) in the pool
- uint32_t item_sz; ///< size of an item
- void *pool; ///< pointer to memory for pool
-} osPoolDef_t;
-
-/// Definition structure for message queue.
-/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS.
-typedef struct os_messageQ_def {
- uint32_t queue_sz; ///< number of elements in the queue
- uint32_t item_sz; ///< size of an item
- void *pool; ///< memory array for messages
-} osMessageQDef_t;
-
-/// Definition structure for mail queue.
-/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS.
-typedef struct os_mailQ_def {
- uint32_t queue_sz; ///< number of elements in the queue
- uint32_t item_sz; ///< size of an item
- void *pool; ///< memory array for mail
-} osMailQDef_t;
-
-/// Event structure contains detailed information about an event.
-/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS.
-/// However the struct may be extended at the end.
-typedef struct {
- osStatus status; ///< status code: event or error information
- union {
- uint32_t v; ///< message as 32-bit value
- void *p; ///< message or mail as void pointer
- int32_t signals; ///< signal flags
- } value; ///< event value
- union {
- osMailQId mail_id; ///< mail id obtained by \ref osMailCreate
- osMessageQId message_id; ///< message id obtained by \ref osMessageCreate
- } def; ///< event definition
-} osEvent;
-
-
-// ==== Kernel Control Functions ====
-
-/// Initialize the RTOS Kernel for creating objects.
-/// \return status code that indicates the execution status of the function.
-/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS.
-osStatus osKernelInitialize (void);
-
-/// Start the RTOS Kernel.
-/// \return status code that indicates the execution status of the function.
-/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS.
-osStatus osKernelStart (void);
-
-/// Check if the RTOS kernel is already started.
-/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS.
-/// \return 0 RTOS is not started, 1 RTOS is started.
-int32_t osKernelRunning(void);
-
-#if (defined (osFeature_SysTick) && (osFeature_SysTick != 0)) // System Timer available
-
-/// Get the RTOS kernel system timer counter
-/// \note MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS.
-/// \return RTOS kernel system timer as 32-bit value
-uint32_t osKernelSysTick (void);
-
-/// The RTOS kernel system timer frequency in Hz
-/// \note Reflects the system timer setting and is typically defined in a configuration file.
-#define osKernelSysTickFrequency 100000000
-
-/// Convert a microseconds value to a RTOS kernel system timer value.
-/// \param microsec time value in microseconds.
-/// \return time value normalized to the \ref osKernelSysTickFrequency
-#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000)
-
-#endif // System Timer available
-
-// ==== Thread Management ====
-
-/// Create a Thread Definition with function, priority, and stack requirements.
-/// \param name name of the thread function.
-/// \param priority initial priority of the thread function.
-/// \param instances number of possible thread instances.
-/// \param stacksz stack size (in bytes) requirements for the thread function.
-/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the
-/// macro body is implementation specific in every CMSIS-RTOS.
-#if defined (osObjectsExternal) // object is external
-#define osThreadDef(name, priority, instances, stacksz) \
-extern const osThreadDef_t os_thread_def_##name
-#else // define the object
-#define osThreadDef(name, priority, instances, stacksz) \
-const osThreadDef_t os_thread_def_##name = \
-{ (name), (priority), (instances), (stacksz) }
-#endif
-
-/// Access a Thread definition.
-/// \param name name of the thread definition object.
-/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the
-/// macro body is implementation specific in every CMSIS-RTOS.
-#define osThread(name) \
-&os_thread_def_##name
-
-/// Create a thread and add it to Active Threads and set it to state READY.
-/// \param[in] thread_def thread definition referenced with \ref osThread.
-/// \param[in] argument pointer that is passed to the thread function as start argument.
-/// \return thread ID for reference by other functions or NULL in case of error.
-/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS.
-osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument);
-
-/// Return the thread ID of the current running thread.
-/// \return thread ID for reference by other functions or NULL in case of error.
-/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS.
-osThreadId osThreadGetId (void);
-
-/// Terminate execution of a thread and remove it from Active Threads.
-/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
-/// \return status code that indicates the execution status of the function.
-/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS.
-osStatus osThreadTerminate (osThreadId thread_id);
-
-/// Pass control to next thread that is in state \b READY.
-/// \return status code that indicates the execution status of the function.
-/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS.
-osStatus osThreadYield (void);
-
-/// Change priority of an active thread.
-/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
-/// \param[in] priority new priority value for the thread function.
-/// \return status code that indicates the execution status of the function.
-/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS.
-osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority);
-
-/// Get current priority of an active thread.
-/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
-/// \return current priority value of the thread function.
-/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS.
-osPriority osThreadGetPriority (osThreadId thread_id);
-
-
-// ==== Generic Wait Functions ====
-
-/// Wait for Timeout (Time Delay).
-/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "time delay" value
-/// \return status code that indicates the execution status of the function.
-osStatus osDelay (uint32_t millisec);
-
-#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available
-
-/// Wait for Signal, Message, Mail, or Timeout.
-/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
-/// \return event that contains signal, message, or mail information or error code.
-/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS.
-osEvent osWait (uint32_t millisec);
-
-#endif // Generic Wait available
-
-
-// ==== Timer Management Functions ====
-/// Define a Timer object.
-/// \param name name of the timer object.
-/// \param function name of the timer call back function.
-/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the
-/// macro body is implementation specific in every CMSIS-RTOS.
-#if defined (osObjectsExternal) // object is external
-#define osTimerDef(name, function) \
-extern const osTimerDef_t os_timer_def_##name
-#else // define the object
-#define osTimerDef(name, function) \
-const osTimerDef_t os_timer_def_##name = \
-{ (function) }
-#endif
-
-/// Access a Timer definition.
-/// \param name name of the timer object.
-/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the
-/// macro body is implementation specific in every CMSIS-RTOS.
-#define osTimer(name) \
-&os_timer_def_##name
-
-/// Create a timer.
-/// \param[in] timer_def timer object referenced with \ref osTimer.
-/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
-/// \param[in] argument argument to the timer call back function.
-/// \return timer ID for reference by other functions or NULL in case of error.
-/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS.
-osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument);
-
-/// Start or restart a timer.
-/// \param[in] timer_id timer ID obtained by \ref osTimerCreate.
-/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "time delay" value of the timer.
-/// \return status code that indicates the execution status of the function.
-/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS.
-osStatus osTimerStart (osTimerId timer_id, uint32_t millisec);
-
-/// Stop the timer.
-/// \param[in] timer_id timer ID obtained by \ref osTimerCreate.
-/// \return status code that indicates the execution status of the function.
-/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS.
-osStatus osTimerStop (osTimerId timer_id);
-
-/// Delete a timer that was created by \ref osTimerCreate.
-/// \param[in] timer_id timer ID obtained by \ref osTimerCreate.
-/// \return status code that indicates the execution status of the function.
-/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS.
-osStatus osTimerDelete (osTimerId timer_id);
-
-
-// ==== Signal Management ====
-
-/// Set the specified Signal Flags of an active thread.
-/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
-/// \param[in] signals specifies the signal flags of the thread that should be set.
-/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
-/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS.
-int32_t osSignalSet (osThreadId thread_id, int32_t signals);
-
-/// Clear the specified Signal Flags of an active thread.
-/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
-/// \param[in] signals specifies the signal flags of the thread that shall be cleared.
-/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters or call from ISR.
-/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS.
-int32_t osSignalClear (osThreadId thread_id, int32_t signals);
-
-/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread.
-/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag.
-/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
-/// \return event flag information or error code.
-/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS.
-osEvent osSignalWait (int32_t signals, uint32_t millisec);
-
-
-// ==== Mutex Management ====
-
-/// Define a Mutex.
-/// \param name name of the mutex object.
-/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the
-/// macro body is implementation specific in every CMSIS-RTOS.
-#if defined (osObjectsExternal) // object is external
-#define osMutexDef(name) \
-extern const osMutexDef_t os_mutex_def_##name
-#else // define the object
-#define osMutexDef(name) \
-const osMutexDef_t os_mutex_def_##name = { 0 }
-#endif
-
-/// Access a Mutex definition.
-/// \param name name of the mutex object.
-/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the
-/// macro body is implementation specific in every CMSIS-RTOS.
-#define osMutex(name) \
-&os_mutex_def_##name
-
-/// Create and Initialize a Mutex object.
-/// \param[in] mutex_def mutex definition referenced with \ref osMutex.
-/// \return mutex ID for reference by other functions or NULL in case of error.
-/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS.
-osMutexId osMutexCreate (const osMutexDef_t *mutex_def);
-
-/// Wait until a Mutex becomes available.
-/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate.
-/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
-/// \return status code that indicates the execution status of the function.
-/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS.
-osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec);
-
-/// Release a Mutex that was obtained by \ref osMutexWait.
-/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate.
-/// \return status code that indicates the execution status of the function.
-/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS.
-osStatus osMutexRelease (osMutexId mutex_id);
-
-/// Delete a Mutex that was created by \ref osMutexCreate.
-/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate.
-/// \return status code that indicates the execution status of the function.
-/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS.
-osStatus osMutexDelete (osMutexId mutex_id);
-
-
-// ==== Semaphore Management Functions ====
-
-#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available
-
-/// Define a Semaphore object.
-/// \param name name of the semaphore object.
-/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the
-/// macro body is implementation specific in every CMSIS-RTOS.
-#if defined (osObjectsExternal) // object is external
-#define osSemaphoreDef(name) \
-extern const osSemaphoreDef_t os_semaphore_def_##name
-#else // define the object
-#define osSemaphoreDef(name) \
-const osSemaphoreDef_t os_semaphore_def_##name = { 0 }
-#endif
-
-/// Access a Semaphore definition.
-/// \param name name of the semaphore object.
-/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the
-/// macro body is implementation specific in every CMSIS-RTOS.
-#define osSemaphore(name) \
-&os_semaphore_def_##name
-
-/// Create and Initialize a Semaphore object used for managing resources.
-/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore.
-/// \param[in] count number of available resources.
-/// \return semaphore ID for reference by other functions or NULL in case of error.
-/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS.
-osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count);
-
-/// Wait until a Semaphore token becomes available.
-/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate.
-/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
-/// \return number of available tokens, or -1 in case of incorrect parameters.
-/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS.
-int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec);
-
-/// Release a Semaphore token.
-/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate.
-/// \return status code that indicates the execution status of the function.
-/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS.
-osStatus osSemaphoreRelease (osSemaphoreId semaphore_id);
-
-/// Delete a Semaphore that was created by \ref osSemaphoreCreate.
-/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate.
-/// \return status code that indicates the execution status of the function.
-/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS.
-osStatus osSemaphoreDelete (osSemaphoreId semaphore_id);
-
-#endif // Semaphore available
-
-
-// ==== Memory Pool Management Functions ====
-
-#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available
-
-/// \brief Define a Memory Pool.
-/// \param name name of the memory pool.
-/// \param no maximum number of blocks (objects) in the memory pool.
-/// \param type data type of a single block (object).
-/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the
-/// macro body is implementation specific in every CMSIS-RTOS.
-#if defined (osObjectsExternal) // object is external
-#define osPoolDef(name, no, type) \
-extern const osPoolDef_t os_pool_def_##name
-#else // define the object
-#define osPoolDef(name, no, type) \
-const osPoolDef_t os_pool_def_##name = \
-{ (no), sizeof(type), NULL }
-#endif
-
-/// \brief Access a Memory Pool definition.
-/// \param name name of the memory pool
-/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the
-/// macro body is implementation specific in every CMSIS-RTOS.
-#define osPool(name) \
-&os_pool_def_##name
-
-/// Create and Initialize a memory pool.
-/// \param[in] pool_def memory pool definition referenced with \ref osPool.
-/// \return memory pool ID for reference by other functions or NULL in case of error.
-/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS.
-osPoolId osPoolCreate (const osPoolDef_t *pool_def);
-
-/// Allocate a memory block from a memory pool.
-/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate.
-/// \return address of the allocated memory block or NULL in case of no memory available.
-/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS.
-void *osPoolAlloc (osPoolId pool_id);
-
-/// Allocate a memory block from a memory pool and set memory block to zero.
-/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate.
-/// \return address of the allocated memory block or NULL in case of no memory available.
-/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS.
-void *osPoolCAlloc (osPoolId pool_id);
-
-/// Return an allocated memory block back to a specific memory pool.
-/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate.
-/// \param[in] block address of the allocated memory block that is returned to the memory pool.
-/// \return status code that indicates the execution status of the function.
-/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS.
-osStatus osPoolFree (osPoolId pool_id, void *block);
-
-#endif // Memory Pool Management available
-
-
-// ==== Message Queue Management Functions ====
-
-#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available
-
-/// \brief Create a Message Queue Definition.
-/// \param name name of the queue.
-/// \param queue_sz maximum number of messages in the queue.
-/// \param type data type of a single message element (for debugger).
-/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the
-/// macro body is implementation specific in every CMSIS-RTOS.
-#if defined (osObjectsExternal) // object is external
-#define osMessageQDef(name, queue_sz, type) \
-extern const osMessageQDef_t os_messageQ_def_##name
-#else // define the object
-#define osMessageQDef(name, queue_sz, type) \
-const osMessageQDef_t os_messageQ_def_##name = \
-{ (queue_sz), sizeof (type) }
-#endif
-
-/// \brief Access a Message Queue Definition.
-/// \param name name of the queue
-/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the
-/// macro body is implementation specific in every CMSIS-RTOS.
-#define osMessageQ(name) \
-&os_messageQ_def_##name
-
-/// Create and Initialize a Message Queue.
-/// \param[in] queue_def queue definition referenced with \ref osMessageQ.
-/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
-/// \return message queue ID for reference by other functions or NULL in case of error.
-/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS.
-osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id);
-
-/// Put a Message to a Queue.
-/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate.
-/// \param[in] info message information.
-/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
-/// \return status code that indicates the execution status of the function.
-/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS.
-osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec);
-
-/// Get a Message or Wait for a Message from a Queue.
-/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate.
-/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
-/// \return event information that includes status code.
-/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS.
-osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec);
-
-#endif // Message Queues available
-
-
-// ==== Mail Queue Management Functions ====
-
-#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available
-
-/// \brief Create a Mail Queue Definition.
-/// \param name name of the queue
-/// \param queue_sz maximum number of messages in queue
-/// \param type data type of a single message element
-/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the
-/// macro body is implementation specific in every CMSIS-RTOS.
-#if defined (osObjectsExternal) // object is external
-#define osMailQDef(name, queue_sz, type) \
-extern const osMailQDef_t os_mailQ_def_##name
-#else // define the object
-#define osMailQDef(name, queue_sz, type) \
-const osMailQDef_t os_mailQ_def_##name = \
-{ (queue_sz), sizeof (type) }
-#endif
-
-/// \brief Access a Mail Queue Definition.
-/// \param name name of the queue
-/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the
-/// macro body is implementation specific in every CMSIS-RTOS.
-#define osMailQ(name) \
-&os_mailQ_def_##name
-
-/// Create and Initialize mail queue.
-/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ
-/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
-/// \return mail queue ID for reference by other functions or NULL in case of error.
-/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS.
-osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id);
-
-/// Allocate a memory block from a mail.
-/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
-/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
-/// \return pointer to memory block that can be filled with mail or NULL in case of error.
-/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS.
-void *osMailAlloc (osMailQId queue_id, uint32_t millisec);
-
-/// Allocate a memory block from a mail and set memory block to zero.
-/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
-/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
-/// \return pointer to memory block that can be filled with mail or NULL in case of error.
-/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS.
-void *osMailCAlloc (osMailQId queue_id, uint32_t millisec);
-
-/// Put a mail to a queue.
-/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
-/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc.
-/// \return status code that indicates the execution status of the function.
-/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS.
-osStatus osMailPut (osMailQId queue_id, void *mail);
-
-/// Get a mail from a queue.
-/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
-/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
-/// \return event that contains mail information or error code.
-/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS.
-osEvent osMailGet (osMailQId queue_id, uint32_t millisec);
-
-/// Free a memory block from a mail.
-/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
-/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet.
-/// \return status code that indicates the execution status of the function.
-/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS.
-osStatus osMailFree (osMailQId queue_id, void *mail);
-
-#endif // Mail Queues available
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _CMSIS_OS_H
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32f1xx_hal_can_ex_legacy.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32f1xx_hal_can_ex_legacy.h
deleted file mode 100644
index b389603..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32f1xx_hal_can_ex_legacy.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_can_ex.h
- * @author MCD Application Team
- * @brief Header file of CAN HAL Extension module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_CAN_EX_H
-#define __STM32F1xx_HAL_CAN_EX_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-#if defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || \
- defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup CANEx CANEx
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-
-/**
- * @brief CAN filter configuration structure definition
- */
-/* CAN filter banks differences over STM32F1 devices: */
-/* - STM32F1 Connectivity line: 28 filter banks shared between CAN1 and CAN2 */
-/* - Other STM32F10x devices: 14 filter banks */
-
-typedef struct
-{
- uint32_t FilterIdHigh; /*!< Specifies the filter identification number (MSBs for a 32-bit
- configuration, first one for a 16-bit configuration).
- This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
-
- uint32_t FilterIdLow; /*!< Specifies the filter identification number (LSBs for a 32-bit
- configuration, second one for a 16-bit configuration).
- This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
-
- uint32_t FilterMaskIdHigh; /*!< Specifies the filter mask number or identification number,
- according to the mode (MSBs for a 32-bit configuration,
- first one for a 16-bit configuration).
- This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
-
- uint32_t FilterMaskIdLow; /*!< Specifies the filter mask number or identification number,
- according to the mode (LSBs for a 32-bit configuration,
- second one for a 16-bit configuration).
- This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
-
- uint32_t FilterFIFOAssignment; /*!< Specifies the FIFO (0 or 1) which will be assigned to the filter.
- This parameter can be a value of @ref CAN_filter_FIFO */
-#if defined(STM32F105xC) || defined(STM32F107xC)
- uint32_t FilterNumber; /*!< Specifies the filter which will be initialized.
- This parameter must be a number between Min_Data = 0 and Max_Data = 27. */
-#else
- uint32_t FilterNumber; /*!< Specifies the filter which will be initialized.
- This parameter must be a number between Min_Data = 0 and Max_Data = 13. */
-#endif /* STM32F105xC || STM32F107xC */
- uint32_t FilterMode; /*!< Specifies the filter mode to be initialized.
- This parameter can be a value of @ref CAN_filter_mode */
-
- uint32_t FilterScale; /*!< Specifies the filter scale.
- This parameter can be a value of @ref CAN_filter_scale */
-
- uint32_t FilterActivation; /*!< Enable or disable the filter.
- This parameter can be set to ENABLE or DISABLE. */
-
- uint32_t BankNumber; /*!< Select the start slave bank filter
- This parameter must be a number between Min_Data = 0 and Max_Data = 28. */
-
-}CAN_FilterConfTypeDef;
-
-/* Exported constants --------------------------------------------------------*/
-/* Exported macro ------------------------------------------------------------*/
-/* Private macro -------------------------------------------------------------*/
-
-/** @defgroup CANEx_Private_Macros CAN Extended Private Macros
- * @{
- */
-#if defined(STM32F105xC) || defined(STM32F107xC)
-#define IS_CAN_FILTER_NUMBER(NUMBER) ((NUMBER) <= 27U)
-#else
-#define IS_CAN_FILTER_NUMBER(NUMBER) ((NUMBER) <= 13U)
-#endif /* STM32F105xC || STM32F107xC */
-
-/**
- * @}
- */
-
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* STM32F103x6) || STM32F103xB || STM32F103xE || STM32F103xG) || STM32F105xC || STM32F107xC */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_CAN_EX_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32f1xx_hal_can_legacy.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32f1xx_hal_can_legacy.h
deleted file mode 100644
index 6af75e0..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32f1xx_hal_can_legacy.h
+++ /dev/null
@@ -1,796 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_can.h
- * @author MCD Application Team
- * @brief Header file of CAN HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_CAN_H
-#define __STM32F1xx_HAL_CAN_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-#if defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || \
- defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup CAN
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup CAN_Exported_Types CAN Exported Types
- * @{
- */
-
-/**
- * @brief HAL State structures definition
- */
-typedef enum
-{
- HAL_CAN_STATE_RESET = 0x00U, /*!< CAN not yet initialized or disabled */
- HAL_CAN_STATE_READY = 0x01U, /*!< CAN initialized and ready for use */
- HAL_CAN_STATE_BUSY = 0x02U, /*!< CAN process is ongoing */
- HAL_CAN_STATE_BUSY_TX = 0x12U, /*!< CAN process is ongoing */
- HAL_CAN_STATE_BUSY_RX0 = 0x22U, /*!< CAN process is ongoing */
- HAL_CAN_STATE_BUSY_RX1 = 0x32U, /*!< CAN process is ongoing */
- HAL_CAN_STATE_BUSY_TX_RX0 = 0x42U, /*!< CAN process is ongoing */
- HAL_CAN_STATE_BUSY_TX_RX1 = 0x52U, /*!< CAN process is ongoing */
- HAL_CAN_STATE_BUSY_RX0_RX1 = 0x62U, /*!< CAN process is ongoing */
- HAL_CAN_STATE_BUSY_TX_RX0_RX1 = 0x72U, /*!< CAN process is ongoing */
- HAL_CAN_STATE_TIMEOUT = 0x03U, /*!< CAN in Timeout state */
- HAL_CAN_STATE_ERROR = 0x04U /*!< CAN error state */
-
-}HAL_CAN_StateTypeDef;
-
-/**
- * @brief CAN init structure definition
- */
-typedef struct
-{
- uint32_t Prescaler; /*!< Specifies the length of a time quantum.
- This parameter must be a number between Min_Data = 1 and Max_Data = 1024 */
-
- uint32_t Mode; /*!< Specifies the CAN operating mode.
- This parameter can be a value of @ref CAN_operating_mode */
-
- uint32_t SJW; /*!< Specifies the maximum number of time quanta
- the CAN hardware is allowed to lengthen or
- shorten a bit to perform resynchronization.
- This parameter can be a value of @ref CAN_synchronisation_jump_width */
-
- uint32_t BS1; /*!< Specifies the number of time quanta in Bit Segment 1.
- This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_1 */
-
- uint32_t BS2; /*!< Specifies the number of time quanta in Bit Segment 2.
- This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_2 */
-
- uint32_t TTCM; /*!< Enable or disable the time triggered communication mode.
- This parameter can be set to ENABLE or DISABLE. */
-
- uint32_t ABOM; /*!< Enable or disable the automatic bus-off management.
- This parameter can be set to ENABLE or DISABLE */
-
- uint32_t AWUM; /*!< Enable or disable the automatic wake-up mode.
- This parameter can be set to ENABLE or DISABLE */
-
- uint32_t NART; /*!< Enable or disable the non-automatic retransmission mode.
- This parameter can be set to ENABLE or DISABLE */
-
- uint32_t RFLM; /*!< Enable or disable the receive FIFO Locked mode.
- This parameter can be set to ENABLE or DISABLE */
-
- uint32_t TXFP; /*!< Enable or disable the transmit FIFO priority.
- This parameter can be set to ENABLE or DISABLE */
-}CAN_InitTypeDef;
-
-/**
- * @brief CAN Tx message structure definition
- */
-typedef struct
-{
- uint32_t StdId; /*!< Specifies the standard identifier.
- This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF */
-
- uint32_t ExtId; /*!< Specifies the extended identifier.
- This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF */
-
- uint32_t IDE; /*!< Specifies the type of identifier for the message that will be transmitted.
- This parameter can be a value of @ref CAN_Identifier_Type */
-
- uint32_t RTR; /*!< Specifies the type of frame for the message that will be transmitted.
- This parameter can be a value of @ref CAN_remote_transmission_request */
-
- uint32_t DLC; /*!< Specifies the length of the frame that will be transmitted.
- This parameter must be a number between Min_Data = 0 and Max_Data = 8 */
-
- uint8_t Data[8]; /*!< Contains the data to be transmitted.
- This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF */
-
-}CanTxMsgTypeDef;
-
-/**
- * @brief CAN Rx message structure definition
- */
-typedef struct
-{
- uint32_t StdId; /*!< Specifies the standard identifier.
- This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF */
-
- uint32_t ExtId; /*!< Specifies the extended identifier.
- This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF */
-
- uint32_t IDE; /*!< Specifies the type of identifier for the message that will be received.
- This parameter can be a value of @ref CAN_Identifier_Type */
-
- uint32_t RTR; /*!< Specifies the type of frame for the received message.
- This parameter can be a value of @ref CAN_remote_transmission_request */
-
- uint32_t DLC; /*!< Specifies the length of the frame that will be received.
- This parameter must be a number between Min_Data = 0 and Max_Data = 8 */
-
- uint8_t Data[8]; /*!< Contains the data to be received.
- This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF */
-
- uint32_t FMI; /*!< Specifies the index of the filter the message stored in the mailbox passes through.
- This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF */
-
- uint32_t FIFONumber; /*!< Specifies the receive FIFO number.
- This parameter can be CAN_FIFO0 or CAN_FIFO1 */
-
-}CanRxMsgTypeDef;
-
-/**
- * @brief CAN handle Structure definition
- */
-typedef struct
-{
- CAN_TypeDef *Instance; /*!< Register base address */
-
- CAN_InitTypeDef Init; /*!< CAN required parameters */
-
- CanTxMsgTypeDef* pTxMsg; /*!< Pointer to transmit structure */
-
- CanRxMsgTypeDef* pRxMsg; /*!< Pointer to reception structure for RX FIFO0 msg */
-
- CanRxMsgTypeDef* pRx1Msg; /*!< Pointer to reception structure for RX FIFO1 msg */
-
- __IO HAL_CAN_StateTypeDef State; /*!< CAN communication state */
-
- HAL_LockTypeDef Lock; /*!< CAN locking object */
-
- __IO uint32_t ErrorCode; /*!< CAN Error code */
-
-}CAN_HandleTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup CAN_Exported_Constants CAN Exported Constants
- * @{
- */
-
-/** @defgroup CAN_Error_Code CAN Error Code
- * @{
- */
-#define HAL_CAN_ERROR_NONE 0x00000000U /*!< No error */
-#define HAL_CAN_ERROR_EWG 0x00000001U /*!< EWG error */
-#define HAL_CAN_ERROR_EPV 0x00000002U /*!< EPV error */
-#define HAL_CAN_ERROR_BOF 0x00000004U /*!< BOF error */
-#define HAL_CAN_ERROR_STF 0x00000008U /*!< Stuff error */
-#define HAL_CAN_ERROR_FOR 0x00000010U /*!< Form error */
-#define HAL_CAN_ERROR_ACK 0x00000020U /*!< Acknowledgment error */
-#define HAL_CAN_ERROR_BR 0x00000040U /*!< Bit recessive */
-#define HAL_CAN_ERROR_BD 0x00000080U /*!< LEC dominant */
-#define HAL_CAN_ERROR_CRC 0x00000100U /*!< LEC transfer error */
-#define HAL_CAN_ERROR_FOV0 0x00000200U /*!< FIFO0 overrun error */
-#define HAL_CAN_ERROR_FOV1 0x00000400U /*!< FIFO1 overrun error */
-#define HAL_CAN_ERROR_TXFAIL 0x00000800U /*!< Transmit failure */
-/**
- * @}
- */
-
-/** @defgroup CAN_InitStatus CAN initialization Status
- * @{
- */
-#define CAN_INITSTATUS_FAILED 0x00000000U /*!< CAN initialization failed */
-#define CAN_INITSTATUS_SUCCESS 0x00000001U /*!< CAN initialization OK */
-/**
- * @}
- */
-
-/** @defgroup CAN_operating_mode CAN Operating Mode
- * @{
- */
-#define CAN_MODE_NORMAL 0x00000000U /*!< Normal mode */
-#define CAN_MODE_LOOPBACK ((uint32_t)CAN_BTR_LBKM) /*!< Loopback mode */
-#define CAN_MODE_SILENT ((uint32_t)CAN_BTR_SILM) /*!< Silent mode */
-#define CAN_MODE_SILENT_LOOPBACK ((uint32_t)(CAN_BTR_LBKM | CAN_BTR_SILM)) /*!< Loopback combined with silent mode */
-/**
- * @}
- */
-
-/** @defgroup CAN_synchronisation_jump_width CAN Synchronization Jump Width
- * @{
- */
-#define CAN_SJW_1TQ 0x00000000U /*!< 1 time quantum */
-#define CAN_SJW_2TQ ((uint32_t)CAN_BTR_SJW_0) /*!< 2 time quantum */
-#define CAN_SJW_3TQ ((uint32_t)CAN_BTR_SJW_1) /*!< 3 time quantum */
-#define CAN_SJW_4TQ ((uint32_t)CAN_BTR_SJW) /*!< 4 time quantum */
-/**
- * @}
- */
-
-/** @defgroup CAN_time_quantum_in_bit_segment_1 CAN Time Quantum in Bit Segment 1
- * @{
- */
-#define CAN_BS1_1TQ 0x00000000U /*!< 1 time quantum */
-#define CAN_BS1_2TQ ((uint32_t)CAN_BTR_TS1_0) /*!< 2 time quantum */
-#define CAN_BS1_3TQ ((uint32_t)CAN_BTR_TS1_1) /*!< 3 time quantum */
-#define CAN_BS1_4TQ ((uint32_t)(CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 4 time quantum */
-#define CAN_BS1_5TQ ((uint32_t)CAN_BTR_TS1_2) /*!< 5 time quantum */
-#define CAN_BS1_6TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_0)) /*!< 6 time quantum */
-#define CAN_BS1_7TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_1)) /*!< 7 time quantum */
-#define CAN_BS1_8TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 8 time quantum */
-#define CAN_BS1_9TQ ((uint32_t)CAN_BTR_TS1_3) /*!< 9 time quantum */
-#define CAN_BS1_10TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_0)) /*!< 10 time quantum */
-#define CAN_BS1_11TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_1)) /*!< 11 time quantum */
-#define CAN_BS1_12TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 12 time quantum */
-#define CAN_BS1_13TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2)) /*!< 13 time quantum */
-#define CAN_BS1_14TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2 | CAN_BTR_TS1_0)) /*!< 14 time quantum */
-#define CAN_BS1_15TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2 | CAN_BTR_TS1_1)) /*!< 15 time quantum */
-#define CAN_BS1_16TQ ((uint32_t)CAN_BTR_TS1) /*!< 16 time quantum */
-/**
- * @}
- */
-
-/** @defgroup CAN_time_quantum_in_bit_segment_2 CAN Time Quantum in bit segment 2
- * @{
- */
-#define CAN_BS2_1TQ 0x00000000U /*!< 1 time quantum */
-#define CAN_BS2_2TQ ((uint32_t)CAN_BTR_TS2_0) /*!< 2 time quantum */
-#define CAN_BS2_3TQ ((uint32_t)CAN_BTR_TS2_1) /*!< 3 time quantum */
-#define CAN_BS2_4TQ ((uint32_t)(CAN_BTR_TS2_1 | CAN_BTR_TS2_0)) /*!< 4 time quantum */
-#define CAN_BS2_5TQ ((uint32_t)CAN_BTR_TS2_2) /*!< 5 time quantum */
-#define CAN_BS2_6TQ ((uint32_t)(CAN_BTR_TS2_2 | CAN_BTR_TS2_0)) /*!< 6 time quantum */
-#define CAN_BS2_7TQ ((uint32_t)(CAN_BTR_TS2_2 | CAN_BTR_TS2_1)) /*!< 7 time quantum */
-#define CAN_BS2_8TQ ((uint32_t)CAN_BTR_TS2) /*!< 8 time quantum */
-/**
- * @}
- */
-
-/** @defgroup CAN_filter_mode CAN Filter Mode
- * @{
- */
-#define CAN_FILTERMODE_IDMASK ((uint8_t)0x00) /*!< Identifier mask mode */
-#define CAN_FILTERMODE_IDLIST ((uint8_t)0x01) /*!< Identifier list mode */
-/**
- * @}
- */
-
-/** @defgroup CAN_filter_scale CAN Filter Scale
- * @{
- */
-#define CAN_FILTERSCALE_16BIT ((uint8_t)0x00) /*!< Two 16-bit filters */
-#define CAN_FILTERSCALE_32BIT ((uint8_t)0x01) /*!< One 32-bit filter */
-/**
- * @}
- */
-
-/** @defgroup CAN_filter_FIFO CAN Filter FIFO
- * @{
- */
-#define CAN_FILTER_FIFO0 ((uint8_t)0x00) /*!< Filter FIFO 0 assignment for filter x */
-#define CAN_FILTER_FIFO1 ((uint8_t)0x01) /*!< Filter FIFO 1 assignment for filter x */
-/**
- * @}
- */
-
-/** @defgroup CAN_Identifier_Type CAN Identifier Type
- * @{
- */
-#define CAN_ID_STD 0x00000000U /*!< Standard Id */
-#define CAN_ID_EXT 0x00000004U /*!< Extended Id */
-/**
- * @}
- */
-
-/** @defgroup CAN_remote_transmission_request CAN Remote Transmission Request
- * @{
- */
-#define CAN_RTR_DATA 0x00000000U /*!< Data frame */
-#define CAN_RTR_REMOTE 0x00000002U /*!< Remote frame */
-/**
- * @}
- */
-
-/** @defgroup CAN_transmit_constants CAN Transmit Constants
- * @{
- */
-#define CAN_TXSTATUS_NOMAILBOX ((uint8_t)0x04) /*!< CAN cell did not provide CAN_TxStatus_NoMailBox */
-/**
- * @}
- */
-
-/** @defgroup CAN_receive_FIFO_number_constants CAN Receive FIFO Number
- * @{
- */
-#define CAN_FIFO0 ((uint8_t)0x00) /*!< CAN FIFO 0 used to receive */
-#define CAN_FIFO1 ((uint8_t)0x01) /*!< CAN FIFO 1 used to receive */
-/**
- * @}
- */
-
-/** @defgroup CAN_flags CAN Flags
- * @{
- */
-/* If the flag is 0x3XXXXXXX, it means that it can be used with CAN_GetFlagStatus()
- and CAN_ClearFlag() functions. */
-/* If the flag is 0x1XXXXXXX, it means that it can only be used with
- CAN_GetFlagStatus() function. */
-
-/* Transmit Flags */
-#define CAN_FLAG_RQCP0 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_RQCP0_BIT_POSITION)) /*!< Request MailBox0 flag */
-#define CAN_FLAG_RQCP1 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_RQCP1_BIT_POSITION)) /*!< Request MailBox1 flag */
-#define CAN_FLAG_RQCP2 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_RQCP2_BIT_POSITION)) /*!< Request MailBox2 flag */
-#define CAN_FLAG_TXOK0 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_TXOK0_BIT_POSITION)) /*!< Transmission OK MailBox0 flag */
-#define CAN_FLAG_TXOK1 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_TXOK1_BIT_POSITION)) /*!< Transmission OK MailBox1 flag */
-#define CAN_FLAG_TXOK2 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_TXOK2_BIT_POSITION)) /*!< Transmission OK MailBox2 flag */
-#define CAN_FLAG_TME0 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_TME0_BIT_POSITION)) /*!< Transmit mailbox 0 empty flag */
-#define CAN_FLAG_TME1 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_TME1_BIT_POSITION)) /*!< Transmit mailbox 0 empty flag */
-#define CAN_FLAG_TME2 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_TME2_BIT_POSITION)) /*!< Transmit mailbox 0 empty flag */
-
-/* Receive Flags */
-#define CAN_FLAG_FF0 ((uint32_t)((RF0R_REGISTER_INDEX << 8U) | CAN_RF0R_FF0_BIT_POSITION)) /*!< FIFO 0 Full flag */
-#define CAN_FLAG_FOV0 ((uint32_t)((RF0R_REGISTER_INDEX << 8U) | CAN_RF0R_FOV0_BIT_POSITION)) /*!< FIFO 0 Overrun flag */
-
-#define CAN_FLAG_FF1 ((uint32_t)((RF1R_REGISTER_INDEX << 8U) | CAN_RF1R_FF1_BIT_POSITION)) /*!< FIFO 1 Full flag */
-#define CAN_FLAG_FOV1 ((uint32_t)((RF1R_REGISTER_INDEX << 8U) | CAN_RF1R_FOV1_BIT_POSITION)) /*!< FIFO 1 Overrun flag */
-
-/* Operating Mode Flags */
-#define CAN_FLAG_WKU ((uint32_t)((MSR_REGISTER_INDEX << 8U) | CAN_MSR_WKU_BIT_POSITION)) /*!< Wake up flag */
-#define CAN_FLAG_SLAK ((uint32_t)((MSR_REGISTER_INDEX << 8U) | CAN_MSR_SLAK_BIT_POSITION)) /*!< Sleep acknowledge flag */
-#define CAN_FLAG_SLAKI ((uint32_t)((MSR_REGISTER_INDEX << 8U) | CAN_MSR_SLAKI_BIT_POSITION)) /*!< Sleep acknowledge flag */
-
-/* @note When SLAK interrupt is disabled (SLKIE=0), no polling on SLAKI is possible.
- In this case the SLAK bit can be polled.*/
-
-/* Error Flags */
-#define CAN_FLAG_EWG ((uint32_t)((ESR_REGISTER_INDEX << 8U) | CAN_ESR_EWG_BIT_POSITION)) /*!< Error warning flag */
-#define CAN_FLAG_EPV ((uint32_t)((ESR_REGISTER_INDEX << 8U) | CAN_ESR_EPV_BIT_POSITION)) /*!< Error passive flag */
-#define CAN_FLAG_BOF ((uint32_t)((ESR_REGISTER_INDEX << 8U) | CAN_ESR_BOF_BIT_POSITION)) /*!< Bus-Off flag */
-
-/**
- * @}
- */
-
-/** @defgroup CAN_Interrupts CAN Interrupts
- * @{
- */
-#define CAN_IT_TME ((uint32_t)CAN_IER_TMEIE) /*!< Transmit mailbox empty interrupt */
-
-/* Receive Interrupts */
-#define CAN_IT_FMP0 ((uint32_t)CAN_IER_FMPIE0) /*!< FIFO 0 message pending interrupt */
-#define CAN_IT_FF0 ((uint32_t)CAN_IER_FFIE0) /*!< FIFO 0 full interrupt */
-#define CAN_IT_FOV0 ((uint32_t)CAN_IER_FOVIE0) /*!< FIFO 0 overrun interrupt */
-#define CAN_IT_FMP1 ((uint32_t)CAN_IER_FMPIE1) /*!< FIFO 1 message pending interrupt */
-#define CAN_IT_FF1 ((uint32_t)CAN_IER_FFIE1) /*!< FIFO 1 full interrupt */
-#define CAN_IT_FOV1 ((uint32_t)CAN_IER_FOVIE1) /*!< FIFO 1 overrun interrupt */
-
-/* Operating Mode Interrupts */
-#define CAN_IT_WKU ((uint32_t)CAN_IER_WKUIE) /*!< Wake-up interrupt */
-#define CAN_IT_SLK ((uint32_t)CAN_IER_SLKIE) /*!< Sleep acknowledge interrupt */
-
-/* Error Interrupts */
-#define CAN_IT_EWG ((uint32_t)CAN_IER_EWGIE) /*!< Error warning interrupt */
-#define CAN_IT_EPV ((uint32_t)CAN_IER_EPVIE) /*!< Error passive interrupt */
-#define CAN_IT_BOF ((uint32_t)CAN_IER_BOFIE) /*!< Bus-off interrupt */
-#define CAN_IT_LEC ((uint32_t)CAN_IER_LECIE) /*!< Last error code interrupt */
-#define CAN_IT_ERR ((uint32_t)CAN_IER_ERRIE) /*!< Error Interrupt */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @defgroup CAN_Private_Constants CAN Private Constants
- * @{
- */
-
-/* CAN intermediate shift values used for CAN flags */
-#define TSR_REGISTER_INDEX 0x5U
-#define RF0R_REGISTER_INDEX 0x2U
-#define RF1R_REGISTER_INDEX 0x4U
-#define MSR_REGISTER_INDEX 0x1U
-#define ESR_REGISTER_INDEX 0x3U
-
-/* CAN flags bits position into their respective register (TSR, RF0R, RF1R or MSR regsiters) */
-/* Transmit Flags */
-#define CAN_TSR_RQCP0_BIT_POSITION 0x00000000U
-#define CAN_TSR_RQCP1_BIT_POSITION 0x00000008U
-#define CAN_TSR_RQCP2_BIT_POSITION 0x00000010U
-#define CAN_TSR_TXOK0_BIT_POSITION 0x00000001U
-#define CAN_TSR_TXOK1_BIT_POSITION 0x00000009U
-#define CAN_TSR_TXOK2_BIT_POSITION 0x00000011U
-#define CAN_TSR_TME0_BIT_POSITION 0x0000001AU
-#define CAN_TSR_TME1_BIT_POSITION 0x0000001BU
-#define CAN_TSR_TME2_BIT_POSITION 0x0000001CU
-
-/* Receive Flags */
-#define CAN_RF0R_FF0_BIT_POSITION 0x00000003U
-#define CAN_RF0R_FOV0_BIT_POSITION 0x00000004U
-
-#define CAN_RF1R_FF1_BIT_POSITION 0x00000003U
-#define CAN_RF1R_FOV1_BIT_POSITION 0x00000004U
-
-/* Operating Mode Flags */
-#define CAN_MSR_WKU_BIT_POSITION 0x00000003U
-#define CAN_MSR_SLAK_BIT_POSITION 0x00000001U
-#define CAN_MSR_SLAKI_BIT_POSITION 0x00000004U
-
-/* Error Flags */
-#define CAN_ESR_EWG_BIT_POSITION 0x00000000U
-#define CAN_ESR_EPV_BIT_POSITION 0x00000001U
-#define CAN_ESR_BOF_BIT_POSITION 0x00000002U
-
-/* Mask used by macro to get/clear CAN flags*/
-#define CAN_FLAG_MASK 0x000000FFU
-
-/* Mailboxes definition */
-#define CAN_TXMAILBOX_0 ((uint8_t)0x00)
-#define CAN_TXMAILBOX_1 ((uint8_t)0x01)
-#define CAN_TXMAILBOX_2 ((uint8_t)0x02)
-/**
- * @}
- */
-
-/* Exported macros -----------------------------------------------------------*/
-/** @defgroup CAN_Exported_Macros CAN Exported Macros
- * @{
- */
-
-/** @brief Reset CAN handle state
- * @param __HANDLE__: CAN handle.
- * @retval None
- */
-#define __HAL_CAN_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_CAN_STATE_RESET)
-
-/**
- * @brief Enable the specified CAN interrupts
- * @param __HANDLE__: CAN handle.
- * @param __INTERRUPT__: CAN Interrupt.
- * This parameter can be one of the following values:
- * @arg CAN_IT_TME: Transmit mailbox empty interrupt enable
- * @arg CAN_IT_FMP0: FIFO 0 message pending interrupt
- * @arg CAN_IT_FF0 : FIFO 0 full interrupt
- * @arg CAN_IT_FOV0: FIFO 0 overrun interrupt
- * @arg CAN_IT_FMP1: FIFO 1 message pending interrupt
- * @arg CAN_IT_FF1 : FIFO 1 full interrupt
- * @arg CAN_IT_FOV1: FIFO 1 overrun interrupt
- * @arg CAN_IT_WKU : Wake-up interrupt
- * @arg CAN_IT_SLK : Sleep acknowledge interrupt
- * @arg CAN_IT_EWG : Error warning interrupt
- * @arg CAN_IT_EPV : Error passive interrupt
- * @arg CAN_IT_BOF : Bus-off interrupt
- * @arg CAN_IT_LEC : Last error code interrupt
- * @arg CAN_IT_ERR : Error Interrupt
- * @retval None.
- */
-#define __HAL_CAN_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) |= (__INTERRUPT__))
-
-/**
- * @brief Disable the specified CAN interrupts
- * @param __HANDLE__: CAN handle.
- * @param __INTERRUPT__: CAN Interrupt.
- * This parameter can be one of the following values:
- * @arg CAN_IT_TME: Transmit mailbox empty interrupt enable
- * @arg CAN_IT_FMP0: FIFO 0 message pending interrupt
- * @arg CAN_IT_FF0 : FIFO 0 full interrupt
- * @arg CAN_IT_FOV0: FIFO 0 overrun interrupt
- * @arg CAN_IT_FMP1: FIFO 1 message pending interrupt
- * @arg CAN_IT_FF1 : FIFO 1 full interrupt
- * @arg CAN_IT_FOV1: FIFO 1 overrun interrupt
- * @arg CAN_IT_WKU : Wake-up interrupt
- * @arg CAN_IT_SLK : Sleep acknowledge interrupt
- * @arg CAN_IT_EWG : Error warning interrupt
- * @arg CAN_IT_EPV : Error passive interrupt
- * @arg CAN_IT_BOF : Bus-off interrupt
- * @arg CAN_IT_LEC : Last error code interrupt
- * @arg CAN_IT_ERR : Error Interrupt
- * @retval None.
- */
-#define __HAL_CAN_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) &= ~(__INTERRUPT__))
-
-/**
- * @brief Return the number of pending received messages.
- * @param __HANDLE__: CAN handle.
- * @param __FIFONUMBER__: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.
- * @retval The number of pending message.
- */
-#define __HAL_CAN_MSG_PENDING(__HANDLE__, __FIFONUMBER__) (((__FIFONUMBER__) == CAN_FIFO0)? \
-((uint8_t)((__HANDLE__)->Instance->RF0R & 0x03U)) : ((uint8_t)((__HANDLE__)->Instance->RF1R & 0x03U)))
-
-/** @brief Check whether the specified CAN flag is set or not.
- * @param __HANDLE__: specifies the CAN Handle.
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg CAN_TSR_RQCP0: Request MailBox0 Flag
- * @arg CAN_TSR_RQCP1: Request MailBox1 Flag
- * @arg CAN_TSR_RQCP2: Request MailBox2 Flag
- * @arg CAN_FLAG_TXOK0: Transmission OK MailBox0 Flag
- * @arg CAN_FLAG_TXOK1: Transmission OK MailBox1 Flag
- * @arg CAN_FLAG_TXOK2: Transmission OK MailBox2 Flag
- * @arg CAN_FLAG_TME0: Transmit mailbox 0 empty Flag
- * @arg CAN_FLAG_TME1: Transmit mailbox 1 empty Flag
- * @arg CAN_FLAG_TME2: Transmit mailbox 2 empty Flag
- * @arg CAN_FLAG_FMP0: FIFO 0 Message Pending Flag
- * @arg CAN_FLAG_FF0: FIFO 0 Full Flag
- * @arg CAN_FLAG_FOV0: FIFO 0 Overrun Flag
- * @arg CAN_FLAG_FMP1: FIFO 1 Message Pending Flag
- * @arg CAN_FLAG_FF1: FIFO 1 Full Flag
- * @arg CAN_FLAG_FOV1: FIFO 1 Overrun Flag
- * @arg CAN_FLAG_WKU: Wake up Flag
- * @arg CAN_FLAG_SLAK: Sleep acknowledge Flag
- * @arg CAN_FLAG_SLAKI: Sleep acknowledge Flag
- * @arg CAN_FLAG_EWG: Error Warning Flag
- * @arg CAN_FLAG_EPV: Error Passive Flag
- * @arg CAN_FLAG_BOF: Bus-Off Flag
- * @retval The new state of __FLAG__ (TRUE or FALSE).
- */
-#define __HAL_CAN_GET_FLAG(__HANDLE__, __FLAG__) \
-((((__FLAG__) >> 8U) == 5U)? ((((__HANDLE__)->Instance->TSR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
- (((__FLAG__) >> 8U) == 2U)? ((((__HANDLE__)->Instance->RF0R) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
- (((__FLAG__) >> 8U) == 4U)? ((((__HANDLE__)->Instance->RF1R) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
- (((__FLAG__) >> 8U) == 1U)? ((((__HANDLE__)->Instance->MSR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
- ((((__HANDLE__)->Instance->ESR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))))
-
-/** @brief Clear the specified CAN pending flag.
- * @param __HANDLE__: specifies the CAN Handle.
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg CAN_TSR_RQCP0: Request MailBox0 Flag
- * @arg CAN_TSR_RQCP1: Request MailBox1 Flag
- * @arg CAN_TSR_RQCP2: Request MailBox2 Flag
- * @arg CAN_FLAG_TXOK0: Transmission OK MailBox0 Flag
- * @arg CAN_FLAG_TXOK1: Transmission OK MailBox1 Flag
- * @arg CAN_FLAG_TXOK2: Transmission OK MailBox2 Flag
- * @arg CAN_FLAG_TME0: Transmit mailbox 0 empty Flag
- * @arg CAN_FLAG_TME1: Transmit mailbox 1 empty Flag
- * @arg CAN_FLAG_TME2: Transmit mailbox 2 empty Flag
- * @arg CAN_FLAG_FMP0: FIFO 0 Message Pending Flag
- * @arg CAN_FLAG_FF0: FIFO 0 Full Flag
- * @arg CAN_FLAG_FOV0: FIFO 0 Overrun Flag
- * @arg CAN_FLAG_FMP1: FIFO 1 Message Pending Flag
- * @arg CAN_FLAG_FF1: FIFO 1 Full Flag
- * @arg CAN_FLAG_FOV1: FIFO 1 Overrun Flag
- * @arg CAN_FLAG_WKU: Wake up Flag
- * @arg CAN_FLAG_SLAKI: Sleep acknowledge Flag
- * @retval The new state of __FLAG__ (TRUE or FALSE).
- */
-#define __HAL_CAN_CLEAR_FLAG(__HANDLE__, __FLAG__) \
-((((__FLAG__) >> 8U) == TSR_REGISTER_INDEX) ? (((__HANDLE__)->Instance->TSR) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
- (((__FLAG__) >> 8U) == RF0R_REGISTER_INDEX)? (((__HANDLE__)->Instance->RF0R) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
- (((__FLAG__) >> 8U) == RF1R_REGISTER_INDEX)? (((__HANDLE__)->Instance->RF1R) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
- (((__FLAG__) >> 8U) == MSR_REGISTER_INDEX) ? (((__HANDLE__)->Instance->MSR) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): 0U)
-
-/** @brief Check if the specified CAN interrupt source is enabled or disabled.
- * @param __HANDLE__: specifies the CAN Handle.
- * @param __INTERRUPT__: specifies the CAN interrupt source to check.
- * This parameter can be one of the following values:
- * @arg CAN_IT_TME: Transmit mailbox empty interrupt enable
- * @arg CAN_IT_FMP0: FIFO 0 message pending interrupt
- * @arg CAN_IT_FF0 : FIFO 0 full interrupt
- * @arg CAN_IT_FOV0: FIFO 0 overrun interrupt
- * @arg CAN_IT_FMP1: FIFO 1 message pending interrupt
- * @arg CAN_IT_FF1 : FIFO 1 full interrupt
- * @arg CAN_IT_FOV1: FIFO 1 overrun interrupt
- * @arg CAN_IT_WKU : Wake-up interrupt
- * @arg CAN_IT_SLK : Sleep acknowledge interrupt
- * @arg CAN_IT_EWG : Error warning interrupt
- * @arg CAN_IT_EPV : Error passive interrupt
- * @arg CAN_IT_BOF : Bus-off interrupt
- * @arg CAN_IT_LEC : Last error code interrupt
- * @arg CAN_IT_ERR : Error Interrupt
- * @retval The new state of __IT__ (TRUE or FALSE).
- */
-#define __HAL_CAN_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->IER & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
-
-/**
- * @brief Check the transmission status of a CAN Frame.
- * @param __HANDLE__: specifies the CAN Handle.
- * @param __TRANSMITMAILBOX__: the number of the mailbox that is used for transmission.
- * @retval The new status of transmission (TRUE or FALSE).
- */
-#define __HAL_CAN_TRANSMIT_STATUS(__HANDLE__, __TRANSMITMAILBOX__)\
-(((__TRANSMITMAILBOX__) == CAN_TXMAILBOX_0)? ((((__HANDLE__)->Instance->TSR) & (CAN_TSR_RQCP0 | CAN_TSR_TME0)) == (CAN_TSR_RQCP0 | CAN_TSR_TME0)) :\
- ((__TRANSMITMAILBOX__) == CAN_TXMAILBOX_1)? ((((__HANDLE__)->Instance->TSR) & (CAN_TSR_RQCP1 | CAN_TSR_TME1)) == (CAN_TSR_RQCP1 | CAN_TSR_TME1)) :\
- ((((__HANDLE__)->Instance->TSR) & (CAN_TSR_RQCP2 | CAN_TSR_TME2)) == (CAN_TSR_RQCP2 | CAN_TSR_TME2)))
-
-/**
- * @brief Release the specified receive FIFO.
- * @param __HANDLE__: CAN handle.
- * @param __FIFONUMBER__: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.
- * @retval None.
- */
-#define __HAL_CAN_FIFO_RELEASE(__HANDLE__, __FIFONUMBER__) (((__FIFONUMBER__) == CAN_FIFO0)? \
-((__HANDLE__)->Instance->RF0R = CAN_RF0R_RFOM0) : ((__HANDLE__)->Instance->RF1R = CAN_RF1R_RFOM1))
-
-/**
- * @brief Cancel a transmit request.
- * @param __HANDLE__: specifies the CAN Handle.
- * @param __TRANSMITMAILBOX__: the number of the mailbox that is used for transmission.
- * @retval None.
- */
-#define __HAL_CAN_CANCEL_TRANSMIT(__HANDLE__, __TRANSMITMAILBOX__)\
-(((__TRANSMITMAILBOX__) == CAN_TXMAILBOX_0)? ((__HANDLE__)->Instance->TSR = CAN_TSR_ABRQ0) :\
- ((__TRANSMITMAILBOX__) == CAN_TXMAILBOX_1)? ((__HANDLE__)->Instance->TSR = CAN_TSR_ABRQ1) :\
- ((__HANDLE__)->Instance->TSR = CAN_TSR_ABRQ2))
-
-/**
- * @brief Enable or disables the DBG Freeze for CAN.
- * @param __HANDLE__: specifies the CAN Handle.
- * @param __NEWSTATE__: new state of the CAN peripheral.
- * This parameter can be: ENABLE (CAN reception/transmission is frozen
- * during debug. Reception FIFOs can still be accessed/controlled normally)
- * or DISABLE (CAN is working during debug).
- * @retval None
- */
-#define __HAL_CAN_DBG_FREEZE(__HANDLE__, __NEWSTATE__) (((__NEWSTATE__) == ENABLE)? \
-((__HANDLE__)->Instance->MCR |= CAN_MCR_DBF) : ((__HANDLE__)->Instance->MCR &= ~CAN_MCR_DBF))
-
-/**
- * @}
- */
-
-/* Include CAN HAL Extension module */
-#include "stm32f1xx_hal_can_ex_legacy.h"
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup CAN_Exported_Functions
- * @{
- */
-
-/** @addtogroup CAN_Exported_Functions_Group1
- * @brief Initialization and Configuration functions
- * @{
- */
-/* Initialization and de-initialization functions *****************************/
-HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan);
-HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig);
-HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan);
-void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan);
-void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan);
-/**
- * @}
- */
-
-/** @addtogroup CAN_Exported_Functions_Group2
- * @brief I/O operation functions
- * @{
- */
-/* I/O operation functions *****************************************************/
-HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef *hcan, uint32_t Timeout);
-HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef *hcan);
-HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef *hcan, uint8_t FIFONumber, uint32_t Timeout);
-HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef *hcan, uint8_t FIFONumber);
-HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef *hcan);
-HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef *hcan);
-void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan);
-void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan);
-void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan);
-void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan);
-/**
- * @}
- */
-
-/** @addtogroup CAN_Exported_Functions_Group3
- * @brief CAN Peripheral State functions
- * @{
- */
-/* Peripheral State and Error functions ***************************************/
-uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan);
-HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private macros --------------------------------------------------------*/
-/** @defgroup CAN_Private_Macros CAN Private Macros
- * @{
- */
-
-#define IS_CAN_MODE(MODE) (((MODE) == CAN_MODE_NORMAL) || \
- ((MODE) == CAN_MODE_LOOPBACK)|| \
- ((MODE) == CAN_MODE_SILENT) || \
- ((MODE) == CAN_MODE_SILENT_LOOPBACK))
-#define IS_CAN_SJW(SJW) (((SJW) == CAN_SJW_1TQ) || ((SJW) == CAN_SJW_2TQ)|| \
- ((SJW) == CAN_SJW_3TQ) || ((SJW) == CAN_SJW_4TQ))
-#define IS_CAN_BS1(BS1) ((BS1) <= CAN_BS1_16TQ)
-#define IS_CAN_BS2(BS2) ((BS2) <= CAN_BS2_8TQ)
-#define IS_CAN_PRESCALER(PRESCALER) (((PRESCALER) >= 1U) && ((PRESCALER) <= 1024U))
-
-#define IS_CAN_FILTER_MODE(MODE) (((MODE) == CAN_FILTERMODE_IDMASK) || \
- ((MODE) == CAN_FILTERMODE_IDLIST))
-#define IS_CAN_FILTER_SCALE(SCALE) (((SCALE) == CAN_FILTERSCALE_16BIT) || \
- ((SCALE) == CAN_FILTERSCALE_32BIT))
-#define IS_CAN_FILTER_FIFO(FIFO) (((FIFO) == CAN_FILTER_FIFO0) || \
- ((FIFO) == CAN_FILTER_FIFO1))
-#define IS_CAN_BANKNUMBER(BANKNUMBER) ((BANKNUMBER) <= 28U)
-
-#define IS_CAN_TRANSMITMAILBOX(TRANSMITMAILBOX) ((TRANSMITMAILBOX) <= ((uint8_t)0x02))
-#define IS_CAN_STDID(STDID) ((STDID) <= 0x00007FFU)
-#define IS_CAN_EXTID(EXTID) ((EXTID) <= 0x1FFFFFFFU)
-#define IS_CAN_DLC(DLC) ((DLC) <= ((uint8_t)0x08))
-
-#define IS_CAN_IDTYPE(IDTYPE) (((IDTYPE) == CAN_ID_STD) || \
- ((IDTYPE) == CAN_ID_EXT))
-#define IS_CAN_RTR(RTR) (((RTR) == CAN_RTR_DATA) || ((RTR) == CAN_RTR_REMOTE))
-#define IS_CAN_FIFO(FIFO) (((FIFO) == CAN_FIFO0) || ((FIFO) == CAN_FIFO1))
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* STM32F103x6) || STM32F103xB || STM32F103xE || STM32F103xG) || STM32F105xC || STM32F107xC */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_CAN_H */
-
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32_assert_template.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32_assert_template.h
deleted file mode 100644
index f647587..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32_assert_template.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32_assert.h
- * @author MCD Application Team
- * @brief STM32 assert template file.
- * This file should be copied to the application folder and renamed
- * to stm32_assert.h.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32_ASSERT_H
-#define __STM32_ASSERT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Exported types ------------------------------------------------------------*/
-/* Exported constants --------------------------------------------------------*/
-/* Includes ------------------------------------------------------------------*/
-/* 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)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
-/* Exported functions ------------------------------------------------------- */
-void assert_failed(uint8_t *file, uint32_t line);
-#else
-#define assert_param(expr) ((void)0U)
-#endif /* USE_FULL_ASSERT */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32_ASSERT_H */
-
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
deleted file mode 100644
index 653a094..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
+++ /dev/null
@@ -1,367 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal.h
- * @author MCD Application Team
- * @brief This file contains all the functions prototypes for the HAL
- * module driver.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_H
-#define __STM32F1xx_HAL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_conf.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup HAL
- * @{
- */
-
-/* Exported constants --------------------------------------------------------*/
-
-/** @defgroup HAL_Exported_Constants HAL Exported Constants
- * @{
- */
-
-/** @defgroup HAL_TICK_FREQ Tick Frequency
- * @{
- */
-typedef enum
-{
- HAL_TICK_FREQ_10HZ = 100U,
- HAL_TICK_FREQ_100HZ = 10U,
- HAL_TICK_FREQ_1KHZ = 1U,
- HAL_TICK_FREQ_DEFAULT = HAL_TICK_FREQ_1KHZ
-} HAL_TickFreqTypeDef;
-/**
- * @}
- */
-/* Exported types ------------------------------------------------------------*/
-extern uint32_t uwTickPrio;
-extern HAL_TickFreqTypeDef uwTickFreq;
-
-/**
- * @}
- */
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup HAL_Exported_Macros HAL Exported Macros
- * @{
- */
-
-/** @defgroup DBGMCU_Freeze_Unfreeze Freeze Unfreeze Peripherals in Debug mode
- * @brief Freeze/Unfreeze Peripherals in Debug mode
- * Note: On devices STM32F10xx8 and STM32F10xxB,
- * STM32F101xC/D/E and STM32F103xC/D/E,
- * STM32F101xF/G and STM32F103xF/G
- * STM32F10xx4 and STM32F10xx6
- * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
- * debug mode (not accessible by the user software in normal mode).
- * Refer to errata sheet of these devices for more details.
- * @{
- */
-
-/* Peripherals on APB1 */
-/**
- * @brief TIM2 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_TIM2() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM2_STOP)
-#define __HAL_DBGMCU_UNFREEZE_TIM2() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM2_STOP)
-
-/**
- * @brief TIM3 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_TIM3() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM3_STOP)
-#define __HAL_DBGMCU_UNFREEZE_TIM3() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM3_STOP)
-
-#if defined (DBGMCU_CR_DBG_TIM4_STOP)
-/**
- * @brief TIM4 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_TIM4() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM4_STOP)
-#define __HAL_DBGMCU_UNFREEZE_TIM4() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM4_STOP)
-#endif
-
-#if defined (DBGMCU_CR_DBG_TIM5_STOP)
-/**
- * @brief TIM5 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_TIM5() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM5_STOP)
-#define __HAL_DBGMCU_UNFREEZE_TIM5() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM5_STOP)
-#endif
-
-#if defined (DBGMCU_CR_DBG_TIM6_STOP)
-/**
- * @brief TIM6 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_TIM6() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM6_STOP)
-#define __HAL_DBGMCU_UNFREEZE_TIM6() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM6_STOP)
-#endif
-
-#if defined (DBGMCU_CR_DBG_TIM7_STOP)
-/**
- * @brief TIM7 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_TIM7() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM7_STOP)
-#define __HAL_DBGMCU_UNFREEZE_TIM7() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM7_STOP)
-#endif
-
-#if defined (DBGMCU_CR_DBG_TIM12_STOP)
-/**
- * @brief TIM12 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_TIM12() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM12_STOP)
-#define __HAL_DBGMCU_UNFREEZE_TIM12() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM12_STOP)
-#endif
-
-#if defined (DBGMCU_CR_DBG_TIM13_STOP)
-/**
- * @brief TIM13 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_TIM13() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM13_STOP)
-#define __HAL_DBGMCU_UNFREEZE_TIM13() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM13_STOP)
-#endif
-
-#if defined (DBGMCU_CR_DBG_TIM14_STOP)
-/**
- * @brief TIM14 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_TIM14() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM14_STOP)
-#define __HAL_DBGMCU_UNFREEZE_TIM14() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM14_STOP)
-#endif
-
-/**
- * @brief WWDG Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_WWDG() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_WWDG_STOP)
-#define __HAL_DBGMCU_UNFREEZE_WWDG() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_WWDG_STOP)
-
-/**
- * @brief IWDG Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_IWDG() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_IWDG_STOP)
-#define __HAL_DBGMCU_UNFREEZE_IWDG() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_IWDG_STOP)
-
-/**
- * @brief I2C1 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_I2C1_TIMEOUT() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_I2C1_SMBUS_TIMEOUT)
-#define __HAL_DBGMCU_UNFREEZE_I2C1_TIMEOUT() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_I2C1_SMBUS_TIMEOUT)
-
-#if defined (DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT)
-/**
- * @brief I2C2 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_I2C2_TIMEOUT() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT)
-#define __HAL_DBGMCU_UNFREEZE_I2C2_TIMEOUT() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT)
-#endif
-
-#if defined (DBGMCU_CR_DBG_CAN1_STOP)
-/**
- * @brief CAN1 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_CAN1() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_CAN1_STOP)
-#define __HAL_DBGMCU_UNFREEZE_CAN1() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_CAN1_STOP)
-#endif
-
-#if defined (DBGMCU_CR_DBG_CAN2_STOP)
-/**
- * @brief CAN2 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_CAN2() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_CAN2_STOP)
-#define __HAL_DBGMCU_UNFREEZE_CAN2() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_CAN2_STOP)
-#endif
-
-/* Peripherals on APB2 */
-#if defined (DBGMCU_CR_DBG_TIM1_STOP)
-/**
- * @brief TIM1 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_TIM1() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM1_STOP)
-#define __HAL_DBGMCU_UNFREEZE_TIM1() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM1_STOP)
-#endif
-
-#if defined (DBGMCU_CR_DBG_TIM8_STOP)
-/**
- * @brief TIM8 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_TIM8() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM8_STOP)
-#define __HAL_DBGMCU_UNFREEZE_TIM8() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM8_STOP)
-#endif
-
-#if defined (DBGMCU_CR_DBG_TIM9_STOP)
-/**
- * @brief TIM9 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_TIM9() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM9_STOP)
-#define __HAL_DBGMCU_UNFREEZE_TIM9() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM9_STOP)
-#endif
-
-#if defined (DBGMCU_CR_DBG_TIM10_STOP)
-/**
- * @brief TIM10 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_TIM10() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM10_STOP)
-#define __HAL_DBGMCU_UNFREEZE_TIM10() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM10_STOP)
-#endif
-
-#if defined (DBGMCU_CR_DBG_TIM11_STOP)
-/**
- * @brief TIM11 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_TIM11() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM11_STOP)
-#define __HAL_DBGMCU_UNFREEZE_TIM11() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM11_STOP)
-#endif
-
-
-#if defined (DBGMCU_CR_DBG_TIM15_STOP)
-/**
- * @brief TIM15 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_TIM15() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM15_STOP)
-#define __HAL_DBGMCU_UNFREEZE_TIM15() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM15_STOP)
-#endif
-
-#if defined (DBGMCU_CR_DBG_TIM16_STOP)
-/**
- * @brief TIM16 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_TIM16() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM16_STOP)
-#define __HAL_DBGMCU_UNFREEZE_TIM16() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM16_STOP)
-#endif
-
-#if defined (DBGMCU_CR_DBG_TIM17_STOP)
-/**
- * @brief TIM17 Peripherals Debug mode
- */
-#define __HAL_DBGMCU_FREEZE_TIM17() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM17_STOP)
-#define __HAL_DBGMCU_UNFREEZE_TIM17() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM17_STOP)
-#endif
-
-/**
- * @}
- */
-
-/** @defgroup HAL_Private_Macros HAL Private Macros
- * @{
- */
-#define IS_TICKFREQ(FREQ) (((FREQ) == HAL_TICK_FREQ_10HZ) || \
- ((FREQ) == HAL_TICK_FREQ_100HZ) || \
- ((FREQ) == HAL_TICK_FREQ_1KHZ))
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup HAL_Exported_Functions
- * @{
- */
-/** @addtogroup HAL_Exported_Functions_Group1
- * @{
- */
-/* Initialization and de-initialization functions ******************************/
-HAL_StatusTypeDef HAL_Init(void);
-HAL_StatusTypeDef HAL_DeInit(void);
-void HAL_MspInit(void);
-void HAL_MspDeInit(void);
-HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority);
-/**
- * @}
- */
-
-/** @addtogroup HAL_Exported_Functions_Group2
- * @{
- */
-/* Peripheral Control functions ************************************************/
-void HAL_IncTick(void);
-void HAL_Delay(uint32_t Delay);
-uint32_t HAL_GetTick(void);
-uint32_t HAL_GetTickPrio(void);
-HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq);
-HAL_TickFreqTypeDef HAL_GetTickFreq(void);
-void HAL_SuspendTick(void);
-void HAL_ResumeTick(void);
-uint32_t HAL_GetHalVersion(void);
-uint32_t HAL_GetREVID(void);
-uint32_t HAL_GetDEVID(void);
-void HAL_DBGMCU_EnableDBGSleepMode(void);
-void HAL_DBGMCU_DisableDBGSleepMode(void);
-void HAL_DBGMCU_EnableDBGStopMode(void);
-void HAL_DBGMCU_DisableDBGStopMode(void);
-void HAL_DBGMCU_EnableDBGStandbyMode(void);
-void HAL_DBGMCU_DisableDBGStandbyMode(void);
-void HAL_GetUID(uint32_t *UID);
-/**
- * @}
- */
-
-/**
- * @}
- */
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/** @defgroup HAL_Private_Variables HAL Private Variables
- * @{
- */
-/**
- * @}
- */
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup HAL_Private_Constants HAL Private Constants
- * @{
- */
-/**
- * @}
- */
-/* Private macros ------------------------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc.h
deleted file mode 100644
index fd79972..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc.h
+++ /dev/null
@@ -1,965 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_adc.h
- * @author MCD Application Team
- * @brief Header file containing functions prototypes of ADC HAL library.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_ADC_H
-#define __STM32F1xx_HAL_ADC_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup ADC
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup ADC_Exported_Types ADC Exported Types
- * @{
- */
-
-/**
- * @brief Structure definition of ADC and regular group initialization
- * @note Parameters of this structure are shared within 2 scopes:
- * - Scope entire ADC (affects regular and injected groups): DataAlign, ScanConvMode.
- * - Scope regular group: ContinuousConvMode, NbrOfConversion, DiscontinuousConvMode, NbrOfDiscConversion, ExternalTrigConvEdge, ExternalTrigConv.
- * @note The setting of these parameters with function HAL_ADC_Init() is conditioned to ADC state.
- * ADC can be either disabled or enabled without conversion on going on regular group.
- */
-typedef struct
-{
- uint32_t DataAlign; /*!< Specifies ADC data alignment to right (MSB on register bit 11 and LSB on register bit 0) (default setting)
- or to left (if regular group: MSB on register bit 15 and LSB on register bit 4, if injected group (MSB kept as signed value due to potential negative value after offset application): MSB on register bit 14 and LSB on register bit 3).
- This parameter can be a value of @ref ADC_Data_align */
- uint32_t ScanConvMode; /*!< Configures the sequencer of regular and injected groups.
- This parameter can be associated to parameter 'DiscontinuousConvMode' to have main sequence subdivided in successive parts.
- If disabled: Conversion is performed in single mode (one channel converted, the one defined in rank 1).
- Parameters 'NbrOfConversion' and 'InjectedNbrOfConversion' are discarded (equivalent to set to 1).
- If enabled: Conversions are performed in sequence mode (multiple ranks defined by 'NbrOfConversion'/'InjectedNbrOfConversion' and each channel rank).
- Scan direction is upward: from rank1 to rank 'n'.
- This parameter can be a value of @ref ADC_Scan_mode
- Note: For regular group, this parameter should be enabled in conversion either by polling (HAL_ADC_Start with Discontinuous mode and NbrOfDiscConversion=1)
- or by DMA (HAL_ADC_Start_DMA), but not by interruption (HAL_ADC_Start_IT): in scan mode, interruption is triggered only on the
- the last conversion of the sequence. All previous conversions would be overwritten by the last one.
- Injected group used with scan mode has not this constraint: each rank has its own result register, no data is overwritten. */
- uint32_t ContinuousConvMode; /*!< Specifies whether the conversion is performed in single mode (one conversion) or continuous mode for regular group,
- after the selected trigger occurred (software start or external trigger).
- This parameter can be set to ENABLE or DISABLE. */
- uint32_t NbrOfConversion; /*!< Specifies the number of ranks that will be converted within the regular group sequencer.
- To use regular group sequencer and convert several ranks, parameter 'ScanConvMode' must be enabled.
- This parameter must be a number between Min_Data = 1 and Max_Data = 16. */
- uint32_t DiscontinuousConvMode; /*!< Specifies whether the conversions sequence of regular group is performed in Complete-sequence/Discontinuous-sequence (main sequence subdivided in successive parts).
- Discontinuous mode is used only if sequencer is enabled (parameter 'ScanConvMode'). If sequencer is disabled, this parameter is discarded.
- Discontinuous mode can be enabled only if continuous mode is disabled. If continuous mode is enabled, this parameter setting is discarded.
- This parameter can be set to ENABLE or DISABLE. */
- uint32_t NbrOfDiscConversion; /*!< Specifies the number of discontinuous conversions in which the main sequence of regular group (parameter NbrOfConversion) will be subdivided.
- If parameter 'DiscontinuousConvMode' is disabled, this parameter is discarded.
- This parameter must be a number between Min_Data = 1 and Max_Data = 8. */
- uint32_t ExternalTrigConv; /*!< Selects the external event used to trigger the conversion start of regular group.
- If set to ADC_SOFTWARE_START, external triggers are disabled.
- If set to external trigger source, triggering is on event rising edge.
- This parameter can be a value of @ref ADC_External_trigger_source_Regular */
-}ADC_InitTypeDef;
-
-/**
- * @brief Structure definition of ADC channel for regular group
- * @note The setting of these parameters with function HAL_ADC_ConfigChannel() is conditioned to ADC state.
- * ADC can be either disabled or enabled without conversion on going on regular group.
- */
-typedef struct
-{
- uint32_t Channel; /*!< Specifies the channel to configure into ADC regular group.
- This parameter can be a value of @ref ADC_channels
- Note: Depending on devices, some channels may not be available on package pins. Refer to device datasheet for channels availability.
- Note: On STM32F1 devices with several ADC: Only ADC1 can access internal measurement channels (VrefInt/TempSensor)
- Note: On STM32F10xx8 and STM32F10xxB devices: A low-amplitude voltage glitch may be generated (on ADC input 0) on the PA0 pin, when the ADC is converting with injection trigger.
- It is advised to distribute the analog channels so that Channel 0 is configured as an injected channel.
- Refer to errata sheet of these devices for more details. */
- uint32_t Rank; /*!< Specifies the rank in the regular group sequencer
- This parameter can be a value of @ref ADC_regular_rank
- Note: In case of need to disable a channel or change order of conversion sequencer, rank containing a previous channel setting can be overwritten by the new channel setting (or parameter number of conversions can be adjusted) */
- uint32_t SamplingTime; /*!< Sampling time value to be set for the selected channel.
- Unit: ADC clock cycles
- Conversion time is the addition of sampling time and processing time (12.5 ADC clock cycles at ADC resolution 12 bits).
- This parameter can be a value of @ref ADC_sampling_times
- Caution: This parameter updates the parameter property of the channel, that can be used into regular and/or injected groups.
- If this same channel has been previously configured in the other group (regular/injected), it will be updated to last setting.
- Note: In case of usage of internal measurement channels (VrefInt/TempSensor),
- sampling time constraints must be respected (sampling time can be adjusted in function of ADC clock frequency and sampling time setting)
- Refer to device datasheet for timings values, parameters TS_vrefint, TS_temp (values rough order: 5us to 17.1us min). */
-}ADC_ChannelConfTypeDef;
-
-/**
- * @brief ADC Configuration analog watchdog definition
- * @note The setting of these parameters with function is conditioned to ADC state.
- * ADC state can be either disabled or enabled without conversion on going on regular and injected groups.
- */
-typedef struct
-{
- uint32_t WatchdogMode; /*!< Configures the ADC analog watchdog mode: single/all channels, regular/injected group.
- This parameter can be a value of @ref ADC_analog_watchdog_mode. */
- uint32_t Channel; /*!< Selects which ADC channel to monitor by analog watchdog.
- This parameter has an effect only if watchdog mode is configured on single channel (parameter WatchdogMode)
- This parameter can be a value of @ref ADC_channels. */
- uint32_t ITMode; /*!< Specifies whether the analog watchdog is configured in interrupt or polling mode.
- This parameter can be set to ENABLE or DISABLE */
- uint32_t HighThreshold; /*!< Configures the ADC analog watchdog High threshold value.
- This parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF. */
- uint32_t LowThreshold; /*!< Configures the ADC analog watchdog High threshold value.
- This parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF. */
- uint32_t WatchdogNumber; /*!< Reserved for future use, can be set to 0 */
-}ADC_AnalogWDGConfTypeDef;
-
-/**
- * @brief HAL ADC state machine: ADC states definition (bitfields)
- */
-/* States of ADC global scope */
-#define HAL_ADC_STATE_RESET 0x00000000U /*!< ADC not yet initialized or disabled */
-#define HAL_ADC_STATE_READY 0x00000001U /*!< ADC peripheral ready for use */
-#define HAL_ADC_STATE_BUSY_INTERNAL 0x00000002U /*!< ADC is busy to internal process (initialization, calibration) */
-#define HAL_ADC_STATE_TIMEOUT 0x00000004U /*!< TimeOut occurrence */
-
-/* States of ADC errors */
-#define HAL_ADC_STATE_ERROR_INTERNAL 0x00000010U /*!< Internal error occurrence */
-#define HAL_ADC_STATE_ERROR_CONFIG 0x00000020U /*!< Configuration error occurrence */
-#define HAL_ADC_STATE_ERROR_DMA 0x00000040U /*!< DMA error occurrence */
-
-/* States of ADC group regular */
-#define HAL_ADC_STATE_REG_BUSY 0x00000100U /*!< A conversion on group regular is ongoing or can occur (either by continuous mode,
- external trigger, low power auto power-on, multimode ADC master control) */
-#define HAL_ADC_STATE_REG_EOC 0x00000200U /*!< Conversion data available on group regular */
-#define HAL_ADC_STATE_REG_OVR 0x00000400U /*!< Not available on STM32F1 device: Overrun occurrence */
-#define HAL_ADC_STATE_REG_EOSMP 0x00000800U /*!< Not available on STM32F1 device: End Of Sampling flag raised */
-
-/* States of ADC group injected */
-#define HAL_ADC_STATE_INJ_BUSY 0x00001000U /*!< A conversion on group injected is ongoing or can occur (either by auto-injection mode,
- external trigger, low power auto power-on, multimode ADC master control) */
-#define HAL_ADC_STATE_INJ_EOC 0x00002000U /*!< Conversion data available on group injected */
-#define HAL_ADC_STATE_INJ_JQOVF 0x00004000U /*!< Not available on STM32F1 device: Injected queue overflow occurrence */
-
-/* States of ADC analog watchdogs */
-#define HAL_ADC_STATE_AWD1 0x00010000U /*!< Out-of-window occurrence of analog watchdog 1 */
-#define HAL_ADC_STATE_AWD2 0x00020000U /*!< Not available on STM32F1 device: Out-of-window occurrence of analog watchdog 2 */
-#define HAL_ADC_STATE_AWD3 0x00040000U /*!< Not available on STM32F1 device: Out-of-window occurrence of analog watchdog 3 */
-
-/* States of ADC multi-mode */
-#define HAL_ADC_STATE_MULTIMODE_SLAVE 0x00100000U /*!< ADC in multimode slave state, controlled by another ADC master ( */
-
-
-/**
- * @brief ADC handle Structure definition
- */
-typedef struct
-{
- ADC_TypeDef *Instance; /*!< Register base address */
-
- ADC_InitTypeDef Init; /*!< ADC required parameters */
-
- DMA_HandleTypeDef *DMA_Handle; /*!< Pointer DMA Handler */
-
- HAL_LockTypeDef Lock; /*!< ADC locking object */
-
- __IO uint32_t State; /*!< ADC communication state (bitmap of ADC states) */
-
- __IO uint32_t ErrorCode; /*!< ADC Error code */
-}ADC_HandleTypeDef;
-/**
- * @}
- */
-
-
-
-/* Exported constants --------------------------------------------------------*/
-
-/** @defgroup ADC_Exported_Constants ADC Exported Constants
- * @{
- */
-
-/** @defgroup ADC_Error_Code ADC Error Code
- * @{
- */
-#define HAL_ADC_ERROR_NONE 0x00U /*!< No error */
-#define HAL_ADC_ERROR_INTERNAL 0x01U /*!< ADC IP internal error: if problem of clocking,
- enable/disable, erroneous state */
-#define HAL_ADC_ERROR_OVR 0x02U /*!< Overrun error */
-#define HAL_ADC_ERROR_DMA 0x04U /*!< DMA transfer error */
-
-/**
- * @}
- */
-
-
-/** @defgroup ADC_Data_align ADC data alignment
- * @{
- */
-#define ADC_DATAALIGN_RIGHT 0x00000000U
-#define ADC_DATAALIGN_LEFT ((uint32_t)ADC_CR2_ALIGN)
-/**
- * @}
- */
-
-/** @defgroup ADC_Scan_mode ADC scan mode
- * @{
- */
-/* Note: Scan mode values are not among binary choices ENABLE/DISABLE for */
-/* compatibility with other STM32 devices having a sequencer with */
-/* additional options. */
-#define ADC_SCAN_DISABLE 0x00000000U
-#define ADC_SCAN_ENABLE ((uint32_t)ADC_CR1_SCAN)
-/**
- * @}
- */
-
-/** @defgroup ADC_External_trigger_edge_Regular ADC external trigger enable for regular group
- * @{
- */
-#define ADC_EXTERNALTRIGCONVEDGE_NONE 0x00000000U
-#define ADC_EXTERNALTRIGCONVEDGE_RISING ((uint32_t)ADC_CR2_EXTTRIG)
-/**
- * @}
- */
-
-/** @defgroup ADC_channels ADC channels
- * @{
- */
-/* Note: Depending on devices, some channels may not be available on package */
-/* pins. Refer to device datasheet for channels availability. */
-#define ADC_CHANNEL_0 0x00000000U
-#define ADC_CHANNEL_1 ((uint32_t)( ADC_SQR3_SQ1_0))
-#define ADC_CHANNEL_2 ((uint32_t)( ADC_SQR3_SQ1_1 ))
-#define ADC_CHANNEL_3 ((uint32_t)( ADC_SQR3_SQ1_1 | ADC_SQR3_SQ1_0))
-#define ADC_CHANNEL_4 ((uint32_t)( ADC_SQR3_SQ1_2 ))
-#define ADC_CHANNEL_5 ((uint32_t)( ADC_SQR3_SQ1_2 | ADC_SQR3_SQ1_0))
-#define ADC_CHANNEL_6 ((uint32_t)( ADC_SQR3_SQ1_2 | ADC_SQR3_SQ1_1 ))
-#define ADC_CHANNEL_7 ((uint32_t)( ADC_SQR3_SQ1_2 | ADC_SQR3_SQ1_1 | ADC_SQR3_SQ1_0))
-#define ADC_CHANNEL_8 ((uint32_t)( ADC_SQR3_SQ1_3 ))
-#define ADC_CHANNEL_9 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_0))
-#define ADC_CHANNEL_10 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_1 ))
-#define ADC_CHANNEL_11 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_1 | ADC_SQR3_SQ1_0))
-#define ADC_CHANNEL_12 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_2 ))
-#define ADC_CHANNEL_13 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_2 | ADC_SQR3_SQ1_0))
-#define ADC_CHANNEL_14 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_2 | ADC_SQR3_SQ1_1 ))
-#define ADC_CHANNEL_15 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_2 | ADC_SQR3_SQ1_1 | ADC_SQR3_SQ1_0))
-#define ADC_CHANNEL_16 ((uint32_t)(ADC_SQR3_SQ1_4 ))
-#define ADC_CHANNEL_17 ((uint32_t)(ADC_SQR3_SQ1_4 | ADC_SQR3_SQ1_0))
-
-#define ADC_CHANNEL_TEMPSENSOR ADC_CHANNEL_16 /* ADC internal channel (no connection on device pin) */
-#define ADC_CHANNEL_VREFINT ADC_CHANNEL_17 /* ADC internal channel (no connection on device pin) */
-/**
- * @}
- */
-
-/** @defgroup ADC_sampling_times ADC sampling times
- * @{
- */
-#define ADC_SAMPLETIME_1CYCLE_5 0x00000000U /*!< Sampling time 1.5 ADC clock cycle */
-#define ADC_SAMPLETIME_7CYCLES_5 ((uint32_t)( ADC_SMPR2_SMP0_0)) /*!< Sampling time 7.5 ADC clock cycles */
-#define ADC_SAMPLETIME_13CYCLES_5 ((uint32_t)( ADC_SMPR2_SMP0_1 )) /*!< Sampling time 13.5 ADC clock cycles */
-#define ADC_SAMPLETIME_28CYCLES_5 ((uint32_t)( ADC_SMPR2_SMP0_1 | ADC_SMPR2_SMP0_0)) /*!< Sampling time 28.5 ADC clock cycles */
-#define ADC_SAMPLETIME_41CYCLES_5 ((uint32_t)(ADC_SMPR2_SMP0_2 )) /*!< Sampling time 41.5 ADC clock cycles */
-#define ADC_SAMPLETIME_55CYCLES_5 ((uint32_t)(ADC_SMPR2_SMP0_2 | ADC_SMPR2_SMP0_0)) /*!< Sampling time 55.5 ADC clock cycles */
-#define ADC_SAMPLETIME_71CYCLES_5 ((uint32_t)(ADC_SMPR2_SMP0_2 | ADC_SMPR2_SMP0_1 )) /*!< Sampling time 71.5 ADC clock cycles */
-#define ADC_SAMPLETIME_239CYCLES_5 ((uint32_t)(ADC_SMPR2_SMP0_2 | ADC_SMPR2_SMP0_1 | ADC_SMPR2_SMP0_0)) /*!< Sampling time 239.5 ADC clock cycles */
-/**
- * @}
- */
-
-/** @defgroup ADC_regular_rank ADC rank into regular group
- * @{
- */
-#define ADC_REGULAR_RANK_1 0x00000001U
-#define ADC_REGULAR_RANK_2 0x00000002U
-#define ADC_REGULAR_RANK_3 0x00000003U
-#define ADC_REGULAR_RANK_4 0x00000004U
-#define ADC_REGULAR_RANK_5 0x00000005U
-#define ADC_REGULAR_RANK_6 0x00000006U
-#define ADC_REGULAR_RANK_7 0x00000007U
-#define ADC_REGULAR_RANK_8 0x00000008U
-#define ADC_REGULAR_RANK_9 0x00000009U
-#define ADC_REGULAR_RANK_10 0x0000000AU
-#define ADC_REGULAR_RANK_11 0x0000000BU
-#define ADC_REGULAR_RANK_12 0x0000000CU
-#define ADC_REGULAR_RANK_13 0x0000000DU
-#define ADC_REGULAR_RANK_14 0x0000000EU
-#define ADC_REGULAR_RANK_15 0x0000000FU
-#define ADC_REGULAR_RANK_16 0x00000010U
-/**
- * @}
- */
-
-/** @defgroup ADC_analog_watchdog_mode ADC analog watchdog mode
- * @{
- */
-#define ADC_ANALOGWATCHDOG_NONE 0x00000000U
-#define ADC_ANALOGWATCHDOG_SINGLE_REG ((uint32_t)(ADC_CR1_AWDSGL | ADC_CR1_AWDEN))
-#define ADC_ANALOGWATCHDOG_SINGLE_INJEC ((uint32_t)(ADC_CR1_AWDSGL | ADC_CR1_JAWDEN))
-#define ADC_ANALOGWATCHDOG_SINGLE_REGINJEC ((uint32_t)(ADC_CR1_AWDSGL | ADC_CR1_AWDEN | ADC_CR1_JAWDEN))
-#define ADC_ANALOGWATCHDOG_ALL_REG ((uint32_t)ADC_CR1_AWDEN)
-#define ADC_ANALOGWATCHDOG_ALL_INJEC ((uint32_t)ADC_CR1_JAWDEN)
-#define ADC_ANALOGWATCHDOG_ALL_REGINJEC ((uint32_t)(ADC_CR1_AWDEN | ADC_CR1_JAWDEN))
-/**
- * @}
- */
-
-/** @defgroup ADC_conversion_group ADC conversion group
- * @{
- */
-#define ADC_REGULAR_GROUP ((uint32_t)(ADC_FLAG_EOC))
-#define ADC_INJECTED_GROUP ((uint32_t)(ADC_FLAG_JEOC))
-#define ADC_REGULAR_INJECTED_GROUP ((uint32_t)(ADC_FLAG_EOC | ADC_FLAG_JEOC))
-/**
- * @}
- */
-
-/** @defgroup ADC_Event_type ADC Event type
- * @{
- */
-#define ADC_AWD_EVENT ((uint32_t)ADC_FLAG_AWD) /*!< ADC Analog watchdog event */
-
-#define ADC_AWD1_EVENT ADC_AWD_EVENT /*!< ADC Analog watchdog 1 event: Alternate naming for compatibility with other STM32 devices having several analog watchdogs */
-/**
- * @}
- */
-
-/** @defgroup ADC_interrupts_definition ADC interrupts definition
- * @{
- */
-#define ADC_IT_EOC ADC_CR1_EOCIE /*!< ADC End of Regular Conversion interrupt source */
-#define ADC_IT_JEOC ADC_CR1_JEOCIE /*!< ADC End of Injected Conversion interrupt source */
-#define ADC_IT_AWD ADC_CR1_AWDIE /*!< ADC Analog watchdog interrupt source */
-/**
- * @}
- */
-
-/** @defgroup ADC_flags_definition ADC flags definition
- * @{
- */
-#define ADC_FLAG_STRT ADC_SR_STRT /*!< ADC Regular group start flag */
-#define ADC_FLAG_JSTRT ADC_SR_JSTRT /*!< ADC Injected group start flag */
-#define ADC_FLAG_EOC ADC_SR_EOC /*!< ADC End of Regular conversion flag */
-#define ADC_FLAG_JEOC ADC_SR_JEOC /*!< ADC End of Injected conversion flag */
-#define ADC_FLAG_AWD ADC_SR_AWD /*!< ADC Analog watchdog flag */
-/**
- * @}
- */
-
-
-/**
- * @}
- */
-
-/* Private constants ---------------------------------------------------------*/
-
-/** @addtogroup ADC_Private_Constants ADC Private Constants
- * @{
- */
-
-/** @defgroup ADC_conversion_cycles ADC conversion cycles
- * @{
- */
-/* ADC conversion cycles (unit: ADC clock cycles) */
-/* (selected sampling time + conversion time of 12.5 ADC clock cycles, with */
-/* resolution 12 bits) */
-#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_1CYCLE5 14U
-#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_7CYCLES5 20U
-#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_13CYCLES5 26U
-#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_28CYCLES5 41U
-#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_41CYCLES5 54U
-#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_55CYCLES5 68U
-#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_71CYCLES5 84U
-#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_239CYCLES5 252U
-/**
- * @}
- */
-
-/** @defgroup ADC_sampling_times_all_channels ADC sampling times all channels
- * @{
- */
-#define ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT2 \
- (ADC_SMPR2_SMP9_2 | ADC_SMPR2_SMP8_2 | ADC_SMPR2_SMP7_2 | ADC_SMPR2_SMP6_2 | \
- ADC_SMPR2_SMP5_2 | ADC_SMPR2_SMP4_2 | ADC_SMPR2_SMP3_2 | ADC_SMPR2_SMP2_2 | \
- ADC_SMPR2_SMP1_2 | ADC_SMPR2_SMP0_2)
-#define ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT2 \
- (ADC_SMPR1_SMP17_2 | ADC_SMPR1_SMP16_2 | ADC_SMPR1_SMP15_2 | ADC_SMPR1_SMP14_2 | \
- ADC_SMPR1_SMP13_2 | ADC_SMPR1_SMP12_2 | ADC_SMPR1_SMP11_2 | ADC_SMPR1_SMP10_2 )
-
-#define ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1 \
- (ADC_SMPR2_SMP9_1 | ADC_SMPR2_SMP8_1 | ADC_SMPR2_SMP7_1 | ADC_SMPR2_SMP6_1 | \
- ADC_SMPR2_SMP5_1 | ADC_SMPR2_SMP4_1 | ADC_SMPR2_SMP3_1 | ADC_SMPR2_SMP2_1 | \
- ADC_SMPR2_SMP1_1 | ADC_SMPR2_SMP0_1)
-#define ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1 \
- (ADC_SMPR1_SMP17_1 | ADC_SMPR1_SMP16_1 | ADC_SMPR1_SMP15_1 | ADC_SMPR1_SMP14_1 | \
- ADC_SMPR1_SMP13_1 | ADC_SMPR1_SMP12_1 | ADC_SMPR1_SMP11_1 | ADC_SMPR1_SMP10_1 )
-
-#define ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT0 \
- (ADC_SMPR2_SMP9_0 | ADC_SMPR2_SMP8_0 | ADC_SMPR2_SMP7_0 | ADC_SMPR2_SMP6_0 | \
- ADC_SMPR2_SMP5_0 | ADC_SMPR2_SMP4_0 | ADC_SMPR2_SMP3_0 | ADC_SMPR2_SMP2_0 | \
- ADC_SMPR2_SMP1_0 | ADC_SMPR2_SMP0_0)
-#define ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0 \
- (ADC_SMPR1_SMP17_0 | ADC_SMPR1_SMP16_0 | ADC_SMPR1_SMP15_0 | ADC_SMPR1_SMP14_0 | \
- ADC_SMPR1_SMP13_0 | ADC_SMPR1_SMP12_0 | ADC_SMPR1_SMP11_0 | ADC_SMPR1_SMP10_0 )
-
-#define ADC_SAMPLETIME_1CYCLE5_SMPR2ALLCHANNELS 0x00000000U
-#define ADC_SAMPLETIME_7CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT0)
-#define ADC_SAMPLETIME_13CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1)
-#define ADC_SAMPLETIME_28CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1 | ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT0)
-#define ADC_SAMPLETIME_41CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT2)
-#define ADC_SAMPLETIME_55CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT2 | ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT0)
-#define ADC_SAMPLETIME_71CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT2 | ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1)
-#define ADC_SAMPLETIME_239CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT2 | ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1 | ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT0)
-
-#define ADC_SAMPLETIME_1CYCLE5_SMPR1ALLCHANNELS 0x00000000U
-#define ADC_SAMPLETIME_7CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0)
-#define ADC_SAMPLETIME_13CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1)
-#define ADC_SAMPLETIME_28CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1 | ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0)
-#define ADC_SAMPLETIME_41CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT2)
-#define ADC_SAMPLETIME_55CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT2 | ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0)
-#define ADC_SAMPLETIME_71CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT2 | ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1)
-#define ADC_SAMPLETIME_239CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT2 | ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1 | ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0)
-/**
- * @}
- */
-
-/* Combination of all post-conversion flags bits: EOC/EOS, JEOC/JEOS, OVR, AWDx */
-#define ADC_FLAG_POSTCONV_ALL (ADC_FLAG_EOC | ADC_FLAG_JEOC | ADC_FLAG_AWD )
-
-/**
- * @}
- */
-
-
-/* Exported macro ------------------------------------------------------------*/
-
-/** @defgroup ADC_Exported_Macros ADC Exported Macros
- * @{
- */
-/* Macro for internal HAL driver usage, and possibly can be used into code of */
-/* final user. */
-
-/**
- * @brief Enable the ADC peripheral
- * @note ADC enable requires a delay for ADC stabilization time
- * (refer to device datasheet, parameter tSTAB)
- * @note On STM32F1, if ADC is already enabled this macro trigs a conversion
- * SW start on regular group.
- * @param __HANDLE__: ADC handle
- * @retval None
- */
-#define __HAL_ADC_ENABLE(__HANDLE__) \
- (SET_BIT((__HANDLE__)->Instance->CR2, (ADC_CR2_ADON)))
-
-/**
- * @brief Disable the ADC peripheral
- * @param __HANDLE__: ADC handle
- * @retval None
- */
-#define __HAL_ADC_DISABLE(__HANDLE__) \
- (CLEAR_BIT((__HANDLE__)->Instance->CR2, (ADC_CR2_ADON)))
-
-/** @brief Enable the ADC end of conversion interrupt.
- * @param __HANDLE__: ADC handle
- * @param __INTERRUPT__: ADC Interrupt
- * This parameter can be any combination of the following values:
- * @arg ADC_IT_EOC: ADC End of Regular Conversion interrupt source
- * @arg ADC_IT_JEOC: ADC End of Injected Conversion interrupt source
- * @arg ADC_IT_AWD: ADC Analog watchdog interrupt source
- * @retval None
- */
-#define __HAL_ADC_ENABLE_IT(__HANDLE__, __INTERRUPT__) \
- (SET_BIT((__HANDLE__)->Instance->CR1, (__INTERRUPT__)))
-
-/** @brief Disable the ADC end of conversion interrupt.
- * @param __HANDLE__: ADC handle
- * @param __INTERRUPT__: ADC Interrupt
- * This parameter can be any combination of the following values:
- * @arg ADC_IT_EOC: ADC End of Regular Conversion interrupt source
- * @arg ADC_IT_JEOC: ADC End of Injected Conversion interrupt source
- * @arg ADC_IT_AWD: ADC Analog watchdog interrupt source
- * @retval None
- */
-#define __HAL_ADC_DISABLE_IT(__HANDLE__, __INTERRUPT__) \
- (CLEAR_BIT((__HANDLE__)->Instance->CR1, (__INTERRUPT__)))
-
-/** @brief Checks if the specified ADC interrupt source is enabled or disabled.
- * @param __HANDLE__: ADC handle
- * @param __INTERRUPT__: ADC interrupt source to check
- * This parameter can be any combination of the following values:
- * @arg ADC_IT_EOC: ADC End of Regular Conversion interrupt source
- * @arg ADC_IT_JEOC: ADC End of Injected Conversion interrupt source
- * @arg ADC_IT_AWD: ADC Analog watchdog interrupt source
- * @retval None
- */
-#define __HAL_ADC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \
- (((__HANDLE__)->Instance->CR1 & (__INTERRUPT__)) == (__INTERRUPT__))
-
-/** @brief Get the selected ADC's flag status.
- * @param __HANDLE__: ADC handle
- * @param __FLAG__: ADC flag
- * This parameter can be any combination of the following values:
- * @arg ADC_FLAG_STRT: ADC Regular group start flag
- * @arg ADC_FLAG_JSTRT: ADC Injected group start flag
- * @arg ADC_FLAG_EOC: ADC End of Regular conversion flag
- * @arg ADC_FLAG_JEOC: ADC End of Injected conversion flag
- * @arg ADC_FLAG_AWD: ADC Analog watchdog flag
- * @retval None
- */
-#define __HAL_ADC_GET_FLAG(__HANDLE__, __FLAG__) \
- ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__))
-
-/** @brief Clear the ADC's pending flags
- * @param __HANDLE__: ADC handle
- * @param __FLAG__: ADC flag
- * This parameter can be any combination of the following values:
- * @arg ADC_FLAG_STRT: ADC Regular group start flag
- * @arg ADC_FLAG_JSTRT: ADC Injected group start flag
- * @arg ADC_FLAG_EOC: ADC End of Regular conversion flag
- * @arg ADC_FLAG_JEOC: ADC End of Injected conversion flag
- * @arg ADC_FLAG_AWD: ADC Analog watchdog flag
- * @retval None
- */
-#define __HAL_ADC_CLEAR_FLAG(__HANDLE__, __FLAG__) \
- (WRITE_REG((__HANDLE__)->Instance->SR, ~(__FLAG__)))
-
-/** @brief Reset ADC handle state
- * @param __HANDLE__: ADC handle
- * @retval None
- */
-#define __HAL_ADC_RESET_HANDLE_STATE(__HANDLE__) \
- ((__HANDLE__)->State = HAL_ADC_STATE_RESET)
-
-/**
- * @}
- */
-
-/* Private macro ------------------------------------------------------------*/
-
-/** @defgroup ADC_Private_Macros ADC Private Macros
- * @{
- */
-/* Macro reserved for internal HAL driver usage, not intended to be used in */
-/* code of final user. */
-
-/**
- * @brief Verification of ADC state: enabled or disabled
- * @param __HANDLE__: ADC handle
- * @retval SET (ADC enabled) or RESET (ADC disabled)
- */
-#define ADC_IS_ENABLE(__HANDLE__) \
- ((( ((__HANDLE__)->Instance->CR2 & ADC_CR2_ADON) == ADC_CR2_ADON ) \
- ) ? SET : RESET)
-
-/**
- * @brief Test if conversion trigger of regular group is software start
- * or external trigger.
- * @param __HANDLE__: ADC handle
- * @retval SET (software start) or RESET (external trigger)
- */
-#define ADC_IS_SOFTWARE_START_REGULAR(__HANDLE__) \
- (READ_BIT((__HANDLE__)->Instance->CR2, ADC_CR2_EXTSEL) == ADC_SOFTWARE_START)
-
-/**
- * @brief Test if conversion trigger of injected group is software start
- * or external trigger.
- * @param __HANDLE__: ADC handle
- * @retval SET (software start) or RESET (external trigger)
- */
-#define ADC_IS_SOFTWARE_START_INJECTED(__HANDLE__) \
- (READ_BIT((__HANDLE__)->Instance->CR2, ADC_CR2_JEXTSEL) == ADC_INJECTED_SOFTWARE_START)
-
-/**
- * @brief Simultaneously clears and sets specific bits of the handle State
- * @note: ADC_STATE_CLR_SET() macro is merely aliased to generic macro MODIFY_REG(),
- * the first parameter is the ADC handle State, the second parameter is the
- * bit field to clear, the third and last parameter is the bit field to set.
- * @retval None
- */
-#define ADC_STATE_CLR_SET MODIFY_REG
-
-/**
- * @brief Clear ADC error code (set it to error code: "no error")
- * @param __HANDLE__: ADC handle
- * @retval None
- */
-#define ADC_CLEAR_ERRORCODE(__HANDLE__) \
- ((__HANDLE__)->ErrorCode = HAL_ADC_ERROR_NONE)
-
-/**
- * @brief Set ADC number of conversions into regular channel sequence length.
- * @param _NbrOfConversion_: Regular channel sequence length
- * @retval None
- */
-#define ADC_SQR1_L_SHIFT(_NbrOfConversion_) \
- (((_NbrOfConversion_) - (uint8_t)1) << ADC_SQR1_L_Pos)
-
-/**
- * @brief Set the ADC's sample time for channel numbers between 10 and 18.
- * @param _SAMPLETIME_: Sample time parameter.
- * @param _CHANNELNB_: Channel number.
- * @retval None
- */
-#define ADC_SMPR1(_SAMPLETIME_, _CHANNELNB_) \
- ((_SAMPLETIME_) << (ADC_SMPR1_SMP11_Pos * ((_CHANNELNB_) - 10)))
-
-/**
- * @brief Set the ADC's sample time for channel numbers between 0 and 9.
- * @param _SAMPLETIME_: Sample time parameter.
- * @param _CHANNELNB_: Channel number.
- * @retval None
- */
-#define ADC_SMPR2(_SAMPLETIME_, _CHANNELNB_) \
- ((_SAMPLETIME_) << (ADC_SMPR2_SMP1_Pos * (_CHANNELNB_)))
-
-/**
- * @brief Set the selected regular channel rank for rank between 1 and 6.
- * @param _CHANNELNB_: Channel number.
- * @param _RANKNB_: Rank number.
- * @retval None
- */
-#define ADC_SQR3_RK(_CHANNELNB_, _RANKNB_) \
- ((_CHANNELNB_) << (ADC_SQR3_SQ2_Pos * ((_RANKNB_) - 1)))
-
-/**
- * @brief Set the selected regular channel rank for rank between 7 and 12.
- * @param _CHANNELNB_: Channel number.
- * @param _RANKNB_: Rank number.
- * @retval None
- */
-#define ADC_SQR2_RK(_CHANNELNB_, _RANKNB_) \
- ((_CHANNELNB_) << (ADC_SQR2_SQ8_Pos * ((_RANKNB_) - 7)))
-
-/**
- * @brief Set the selected regular channel rank for rank between 13 and 16.
- * @param _CHANNELNB_: Channel number.
- * @param _RANKNB_: Rank number.
- * @retval None
- */
-#define ADC_SQR1_RK(_CHANNELNB_, _RANKNB_) \
- ((_CHANNELNB_) << (ADC_SQR1_SQ14_Pos * ((_RANKNB_) - 13)))
-
-/**
- * @brief Set the injected sequence length.
- * @param _JSQR_JL_: Sequence length.
- * @retval None
- */
-#define ADC_JSQR_JL_SHIFT(_JSQR_JL_) \
- (((_JSQR_JL_) -1) << ADC_JSQR_JL_Pos)
-
-/**
- * @brief Set the selected injected channel rank
- * Note: on STM32F1 devices, channel rank position in JSQR register
- * is depending on total number of ranks selected into
- * injected sequencer (ranks sequence starting from 4-JL)
- * @param _CHANNELNB_: Channel number.
- * @param _RANKNB_: Rank number.
- * @param _JSQR_JL_: Sequence length.
- * @retval None
- */
-#define ADC_JSQR_RK_JL(_CHANNELNB_, _RANKNB_, _JSQR_JL_) \
- ((_CHANNELNB_) << (ADC_JSQR_JSQ2_Pos * ((4 - ((_JSQR_JL_) - (_RANKNB_))) - 1)))
-
-/**
- * @brief Enable ADC continuous conversion mode.
- * @param _CONTINUOUS_MODE_: Continuous mode.
- * @retval None
- */
-#define ADC_CR2_CONTINUOUS(_CONTINUOUS_MODE_) \
- ((_CONTINUOUS_MODE_) << ADC_CR2_CONT_Pos)
-
-/**
- * @brief Configures the number of discontinuous conversions for the regular group channels.
- * @param _NBR_DISCONTINUOUS_CONV_: Number of discontinuous conversions.
- * @retval None
- */
-#define ADC_CR1_DISCONTINUOUS_NUM(_NBR_DISCONTINUOUS_CONV_) \
- (((_NBR_DISCONTINUOUS_CONV_) - 1) << ADC_CR1_DISCNUM_Pos)
-
-/**
- * @brief Enable ADC scan mode to convert multiple ranks with sequencer.
- * @param _SCAN_MODE_: Scan conversion mode.
- * @retval None
- */
-/* Note: Scan mode is compared to ENABLE for legacy purpose, this parameter */
-/* is equivalent to ADC_SCAN_ENABLE. */
-#define ADC_CR1_SCAN_SET(_SCAN_MODE_) \
- (( ((_SCAN_MODE_) == ADC_SCAN_ENABLE) || ((_SCAN_MODE_) == ENABLE) \
- )? (ADC_SCAN_ENABLE) : (ADC_SCAN_DISABLE) \
- )
-
-/**
- * @brief Get the maximum ADC conversion cycles on all channels.
- * Returns the selected sampling time + conversion time (12.5 ADC clock cycles)
- * Approximation of sampling time within 4 ranges, returns the highest value:
- * below 7.5 cycles {1.5 cycle; 7.5 cycles},
- * between 13.5 cycles and 28.5 cycles {13.5 cycles; 28.5 cycles}
- * between 41.5 cycles and 71.5 cycles {41.5 cycles; 55.5 cycles; 71.5cycles}
- * equal to 239.5 cycles
- * Unit: ADC clock cycles
- * @param __HANDLE__: ADC handle
- * @retval ADC conversion cycles on all channels
- */
-#define ADC_CONVCYCLES_MAX_RANGE(__HANDLE__) \
- (( (((__HANDLE__)->Instance->SMPR2 & ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT2) == RESET) && \
- (((__HANDLE__)->Instance->SMPR1 & ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT2) == RESET) ) ? \
- \
- (( (((__HANDLE__)->Instance->SMPR2 & ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1) == RESET) && \
- (((__HANDLE__)->Instance->SMPR1 & ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1) == RESET) ) ? \
- ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_7CYCLES5 : ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_28CYCLES5) \
- : \
- ((((((__HANDLE__)->Instance->SMPR2 & ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1) == RESET) && \
- (((__HANDLE__)->Instance->SMPR1 & ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1) == RESET)) || \
- ((((__HANDLE__)->Instance->SMPR2 & ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0) == RESET) && \
- (((__HANDLE__)->Instance->SMPR1 & ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0) == RESET))) ? \
- ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_71CYCLES5 : ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_239CYCLES5) \
- )
-
-#define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DATAALIGN_RIGHT) || \
- ((ALIGN) == ADC_DATAALIGN_LEFT) )
-
-#define IS_ADC_SCAN_MODE(SCAN_MODE) (((SCAN_MODE) == ADC_SCAN_DISABLE) || \
- ((SCAN_MODE) == ADC_SCAN_ENABLE) )
-
-#define IS_ADC_EXTTRIG_EDGE(EDGE) (((EDGE) == ADC_EXTERNALTRIGCONVEDGE_NONE) || \
- ((EDGE) == ADC_EXTERNALTRIGCONVEDGE_RISING) )
-
-#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_CHANNEL_0) || \
- ((CHANNEL) == ADC_CHANNEL_1) || \
- ((CHANNEL) == ADC_CHANNEL_2) || \
- ((CHANNEL) == ADC_CHANNEL_3) || \
- ((CHANNEL) == ADC_CHANNEL_4) || \
- ((CHANNEL) == ADC_CHANNEL_5) || \
- ((CHANNEL) == ADC_CHANNEL_6) || \
- ((CHANNEL) == ADC_CHANNEL_7) || \
- ((CHANNEL) == ADC_CHANNEL_8) || \
- ((CHANNEL) == ADC_CHANNEL_9) || \
- ((CHANNEL) == ADC_CHANNEL_10) || \
- ((CHANNEL) == ADC_CHANNEL_11) || \
- ((CHANNEL) == ADC_CHANNEL_12) || \
- ((CHANNEL) == ADC_CHANNEL_13) || \
- ((CHANNEL) == ADC_CHANNEL_14) || \
- ((CHANNEL) == ADC_CHANNEL_15) || \
- ((CHANNEL) == ADC_CHANNEL_16) || \
- ((CHANNEL) == ADC_CHANNEL_17) )
-
-#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SAMPLETIME_1CYCLE_5) || \
- ((TIME) == ADC_SAMPLETIME_7CYCLES_5) || \
- ((TIME) == ADC_SAMPLETIME_13CYCLES_5) || \
- ((TIME) == ADC_SAMPLETIME_28CYCLES_5) || \
- ((TIME) == ADC_SAMPLETIME_41CYCLES_5) || \
- ((TIME) == ADC_SAMPLETIME_55CYCLES_5) || \
- ((TIME) == ADC_SAMPLETIME_71CYCLES_5) || \
- ((TIME) == ADC_SAMPLETIME_239CYCLES_5) )
-
-#define IS_ADC_REGULAR_RANK(CHANNEL) (((CHANNEL) == ADC_REGULAR_RANK_1 ) || \
- ((CHANNEL) == ADC_REGULAR_RANK_2 ) || \
- ((CHANNEL) == ADC_REGULAR_RANK_3 ) || \
- ((CHANNEL) == ADC_REGULAR_RANK_4 ) || \
- ((CHANNEL) == ADC_REGULAR_RANK_5 ) || \
- ((CHANNEL) == ADC_REGULAR_RANK_6 ) || \
- ((CHANNEL) == ADC_REGULAR_RANK_7 ) || \
- ((CHANNEL) == ADC_REGULAR_RANK_8 ) || \
- ((CHANNEL) == ADC_REGULAR_RANK_9 ) || \
- ((CHANNEL) == ADC_REGULAR_RANK_10) || \
- ((CHANNEL) == ADC_REGULAR_RANK_11) || \
- ((CHANNEL) == ADC_REGULAR_RANK_12) || \
- ((CHANNEL) == ADC_REGULAR_RANK_13) || \
- ((CHANNEL) == ADC_REGULAR_RANK_14) || \
- ((CHANNEL) == ADC_REGULAR_RANK_15) || \
- ((CHANNEL) == ADC_REGULAR_RANK_16) )
-
-#define IS_ADC_ANALOG_WATCHDOG_MODE(WATCHDOG) (((WATCHDOG) == ADC_ANALOGWATCHDOG_NONE) || \
- ((WATCHDOG) == ADC_ANALOGWATCHDOG_SINGLE_REG) || \
- ((WATCHDOG) == ADC_ANALOGWATCHDOG_SINGLE_INJEC) || \
- ((WATCHDOG) == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC) || \
- ((WATCHDOG) == ADC_ANALOGWATCHDOG_ALL_REG) || \
- ((WATCHDOG) == ADC_ANALOGWATCHDOG_ALL_INJEC) || \
- ((WATCHDOG) == ADC_ANALOGWATCHDOG_ALL_REGINJEC) )
-
-#define IS_ADC_CONVERSION_GROUP(CONVERSION) (((CONVERSION) == ADC_REGULAR_GROUP) || \
- ((CONVERSION) == ADC_INJECTED_GROUP) || \
- ((CONVERSION) == ADC_REGULAR_INJECTED_GROUP) )
-
-#define IS_ADC_EVENT_TYPE(EVENT) ((EVENT) == ADC_AWD_EVENT)
-
-
-/** @defgroup ADC_range_verification ADC range verification
- * For a unique ADC resolution: 12 bits
- * @{
- */
-#define IS_ADC_RANGE(ADC_VALUE) ((ADC_VALUE) <= 0x0FFFU)
-/**
- * @}
- */
-
-/** @defgroup ADC_regular_nb_conv_verification ADC regular nb conv verification
- * @{
- */
-#define IS_ADC_REGULAR_NB_CONV(LENGTH) (((LENGTH) >= 1U) && ((LENGTH) <= 16U))
-/**
- * @}
- */
-
-/** @defgroup ADC_regular_discontinuous_mode_number_verification ADC regular discontinuous mode number verification
- * @{
- */
-#define IS_ADC_REGULAR_DISCONT_NUMBER(NUMBER) (((NUMBER) >= 1U) && ((NUMBER) <= 8U))
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Include ADC HAL Extension module */
-#include "stm32f1xx_hal_adc_ex.h"
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup ADC_Exported_Functions
- * @{
- */
-
-/** @addtogroup ADC_Exported_Functions_Group1
- * @{
- */
-
-
-/* Initialization and de-initialization functions **********************************/
-HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc);
-HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef *hadc);
-void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc);
-void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc);
-/**
- * @}
- */
-
-/* IO operation functions *****************************************************/
-
-/** @addtogroup ADC_Exported_Functions_Group2
- * @{
- */
-
-
-/* Blocking mode: Polling */
-HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc);
-HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc);
-HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout);
-HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventType, uint32_t Timeout);
-
-/* Non-blocking mode: Interruption */
-HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc);
-HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc);
-
-/* Non-blocking mode: DMA */
-HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length);
-HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc);
-
-/* ADC retrieve conversion value intended to be used with polling or interruption */
-uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc);
-
-/* ADC IRQHandler and Callbacks used in non-blocking modes (Interruption and DMA) */
-void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc);
-void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc);
-void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc);
-void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc);
-void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc);
-/**
- * @}
- */
-
-
-/* Peripheral Control functions ***********************************************/
-/** @addtogroup ADC_Exported_Functions_Group3
- * @{
- */
-HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig);
-HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDGConfTypeDef* AnalogWDGConfig);
-/**
- * @}
- */
-
-
-/* Peripheral State functions *************************************************/
-/** @addtogroup ADC_Exported_Functions_Group4
- * @{
- */
-uint32_t HAL_ADC_GetState(ADC_HandleTypeDef* hadc);
-uint32_t HAL_ADC_GetError(ADC_HandleTypeDef *hadc);
-/**
- * @}
- */
-
-
-/**
- * @}
- */
-
-
-/* Internal HAL driver functions **********************************************/
-/** @addtogroup ADC_Private_Functions
- * @{
- */
-HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef* hadc);
-HAL_StatusTypeDef ADC_ConversionStop_Disable(ADC_HandleTypeDef* hadc);
-void ADC_StabilizationTime(uint32_t DelayUs);
-void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma);
-void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma);
-void ADC_DMAError(DMA_HandleTypeDef *hdma);
-/**
- * @}
- */
-
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* __STM32F1xx_HAL_ADC_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc_ex.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc_ex.h
deleted file mode 100644
index b923ce4..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc_ex.h
+++ /dev/null
@@ -1,726 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_adc_ex.h
- * @author MCD Application Team
- * @brief Header file of ADC HAL extension module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_ADC_EX_H
-#define __STM32F1xx_HAL_ADC_EX_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup ADCEx
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup ADCEx_Exported_Types ADCEx Exported Types
- * @{
- */
-
-/**
- * @brief ADC Configuration injected Channel structure definition
- * @note Parameters of this structure are shared within 2 scopes:
- * - Scope channel: InjectedChannel, InjectedRank, InjectedSamplingTime, InjectedOffset
- * - Scope injected group (affects all channels of injected group): InjectedNbrOfConversion, InjectedDiscontinuousConvMode,
- * AutoInjectedConv, ExternalTrigInjecConvEdge, ExternalTrigInjecConv.
- * @note The setting of these parameters with function HAL_ADCEx_InjectedConfigChannel() is conditioned to ADC state.
- * ADC state can be either:
- * - For all parameters: ADC disabled (this is the only possible ADC state to modify parameter 'ExternalTrigInjecConv')
- * - For all except parameters 'ExternalTrigInjecConv': ADC enabled without conversion on going on injected group.
- */
-typedef struct
-{
- uint32_t InjectedChannel; /*!< Selection of ADC channel to configure
- This parameter can be a value of @ref ADC_channels
- Note: Depending on devices, some channels may not be available on package pins. Refer to device datasheet for channels availability.
- Note: On STM32F1 devices with several ADC: Only ADC1 can access internal measurement channels (VrefInt/TempSensor)
- Note: On STM32F10xx8 and STM32F10xxB devices: A low-amplitude voltage glitch may be generated (on ADC input 0) on the PA0 pin, when the ADC is converting with injection trigger.
- It is advised to distribute the analog channels so that Channel 0 is configured as an injected channel.
- Refer to errata sheet of these devices for more details. */
- uint32_t InjectedRank; /*!< Rank in the injected group sequencer
- This parameter must be a value of @ref ADCEx_injected_rank
- Note: In case of need to disable a channel or change order of conversion sequencer, rank containing a previous channel setting can be overwritten by the new channel setting (or parameter number of conversions can be adjusted) */
- uint32_t InjectedSamplingTime; /*!< Sampling time value to be set for the selected channel.
- Unit: ADC clock cycles
- Conversion time is the addition of sampling time and processing time (12.5 ADC clock cycles at ADC resolution 12 bits).
- This parameter can be a value of @ref ADC_sampling_times
- Caution: This parameter updates the parameter property of the channel, that can be used into regular and/or injected groups.
- If this same channel has been previously configured in the other group (regular/injected), it will be updated to last setting.
- Note: In case of usage of internal measurement channels (VrefInt/TempSensor),
- sampling time constraints must be respected (sampling time can be adjusted in function of ADC clock frequency and sampling time setting)
- Refer to device datasheet for timings values, parameters TS_vrefint, TS_temp (values rough order: 5us to 17.1us min). */
- uint32_t InjectedOffset; /*!< Defines the offset to be subtracted from the raw converted data (for channels set on injected group only).
- Offset value must be a positive number.
- Depending of ADC resolution selected (12, 10, 8 or 6 bits),
- this parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF, 0x3FF, 0xFF or 0x3F respectively. */
- uint32_t InjectedNbrOfConversion; /*!< Specifies the number of ranks that will be converted within the injected group sequencer.
- To use the injected group sequencer and convert several ranks, parameter 'ScanConvMode' must be enabled.
- This parameter must be a number between Min_Data = 1 and Max_Data = 4.
- Caution: this setting impacts the entire injected group. Therefore, call of HAL_ADCEx_InjectedConfigChannel() to
- configure a channel on injected group can impact the configuration of other channels previously set. */
- uint32_t InjectedDiscontinuousConvMode; /*!< Specifies whether the conversions sequence of injected group is performed in Complete-sequence/Discontinuous-sequence (main sequence subdivided in successive parts).
- Discontinuous mode is used only if sequencer is enabled (parameter 'ScanConvMode'). If sequencer is disabled, this parameter is discarded.
- Discontinuous mode can be enabled only if continuous mode is disabled. If continuous mode is enabled, this parameter setting is discarded.
- This parameter can be set to ENABLE or DISABLE.
- Note: For injected group, number of discontinuous ranks increment is fixed to one-by-one.
- Caution: this setting impacts the entire injected group. Therefore, call of HAL_ADCEx_InjectedConfigChannel() to
- configure a channel on injected group can impact the configuration of other channels previously set. */
- uint32_t AutoInjectedConv; /*!< Enables or disables the selected ADC automatic injected group conversion after regular one
- This parameter can be set to ENABLE or DISABLE.
- Note: To use Automatic injected conversion, discontinuous mode must be disabled ('DiscontinuousConvMode' and 'InjectedDiscontinuousConvMode' set to DISABLE)
- Note: To use Automatic injected conversion, injected group external triggers must be disabled ('ExternalTrigInjecConv' set to ADC_SOFTWARE_START)
- Note: In case of DMA used with regular group: if DMA configured in normal mode (single shot) JAUTO will be stopped upon DMA transfer complete.
- To maintain JAUTO always enabled, DMA must be configured in circular mode.
- Caution: this setting impacts the entire injected group. Therefore, call of HAL_ADCEx_InjectedConfigChannel() to
- configure a channel on injected group can impact the configuration of other channels previously set. */
- uint32_t ExternalTrigInjecConv; /*!< Selects the external event used to trigger the conversion start of injected group.
- If set to ADC_INJECTED_SOFTWARE_START, external triggers are disabled.
- If set to external trigger source, triggering is on event rising edge.
- This parameter can be a value of @ref ADCEx_External_trigger_source_Injected
- Note: This parameter must be modified when ADC is disabled (before ADC start conversion or after ADC stop conversion).
- If ADC is enabled, this parameter setting is bypassed without error reporting (as it can be the expected behaviour in case of another parameter update on the fly)
- Caution: this setting impacts the entire injected group. Therefore, call of HAL_ADCEx_InjectedConfigChannel() to
- configure a channel on injected group can impact the configuration of other channels previously set. */
-}ADC_InjectionConfTypeDef;
-
-#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
-/**
- * @brief Structure definition of ADC multimode
- * @note The setting of these parameters with function HAL_ADCEx_MultiModeConfigChannel() is conditioned to ADCs state (both ADCs of the common group).
- * State of ADCs of the common group must be: disabled.
- */
-typedef struct
-{
- uint32_t Mode; /*!< Configures the ADC to operate in independent or multi mode.
- This parameter can be a value of @ref ADCEx_Common_mode
- Note: In dual mode, a change of channel configuration generates a restart that can produce a loss of synchronization. It is recommended to disable dual mode before any configuration change.
- Note: In case of simultaneous mode used: Exactly the same sampling time should be configured for the 2 channels that will be sampled simultaneously by ACD1 and ADC2.
- Note: In case of interleaved mode used: To avoid overlap between conversions, maximum sampling time allowed is 7 ADC clock cycles for fast interleaved mode and 14 ADC clock cycles for slow interleaved mode.
- Note: Some multimode parameters are fixed on STM32F1 and can be configured on other STM32 devices with several ADC (multimode configuration structure can have additional parameters).
- The equivalences are:
- - Parameter 'DMAAccessMode': On STM32F1, this parameter is fixed to 1 DMA channel (one DMA channel for both ADC, DMA of ADC master). On other STM32 devices with several ADC, this is equivalent to parameter 'ADC_DMAACCESSMODE_12_10_BITS'.
- - Parameter 'TwoSamplingDelay': On STM32F1, this parameter is fixed to 7 or 14 ADC clock cycles depending on fast or slow interleaved mode selected. On other STM32 devices with several ADC, this is equivalent to parameter 'ADC_TWOSAMPLINGDELAY_7CYCLES' (for fast interleaved mode). */
-
-
-}ADC_MultiModeTypeDef;
-#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
-
-/**
- * @}
- */
-
-
-/* Exported constants --------------------------------------------------------*/
-
-/** @defgroup ADCEx_Exported_Constants ADCEx Exported Constants
- * @{
- */
-
-/** @defgroup ADCEx_injected_rank ADCEx rank into injected group
- * @{
- */
-#define ADC_INJECTED_RANK_1 0x00000001U
-#define ADC_INJECTED_RANK_2 0x00000002U
-#define ADC_INJECTED_RANK_3 0x00000003U
-#define ADC_INJECTED_RANK_4 0x00000004U
-/**
- * @}
- */
-
-/** @defgroup ADCEx_External_trigger_edge_Injected ADCEx external trigger enable for injected group
- * @{
- */
-#define ADC_EXTERNALTRIGINJECCONV_EDGE_NONE 0x00000000U
-#define ADC_EXTERNALTRIGINJECCONV_EDGE_RISING ((uint32_t)ADC_CR2_JEXTTRIG)
-/**
- * @}
- */
-
-/** @defgroup ADC_External_trigger_source_Regular ADC External trigger selection for regular group
- * @{
- */
-/*!< List of external triggers with generic trigger name, independently of */
-/* ADC target, sorted by trigger name: */
-
-/*!< External triggers of regular group for ADC1&ADC2 only */
-#define ADC_EXTERNALTRIGCONV_T1_CC1 ADC1_2_EXTERNALTRIG_T1_CC1
-#define ADC_EXTERNALTRIGCONV_T1_CC2 ADC1_2_EXTERNALTRIG_T1_CC2
-#define ADC_EXTERNALTRIGCONV_T2_CC2 ADC1_2_EXTERNALTRIG_T2_CC2
-#define ADC_EXTERNALTRIGCONV_T3_TRGO ADC1_2_EXTERNALTRIG_T3_TRGO
-#define ADC_EXTERNALTRIGCONV_T4_CC4 ADC1_2_EXTERNALTRIG_T4_CC4
-#define ADC_EXTERNALTRIGCONV_EXT_IT11 ADC1_2_EXTERNALTRIG_EXT_IT11
-
-#if defined (STM32F103xE) || defined (STM32F103xG)
-/*!< External triggers of regular group for ADC3 only */
-#define ADC_EXTERNALTRIGCONV_T2_CC3 ADC3_EXTERNALTRIG_T2_CC3
-#define ADC_EXTERNALTRIGCONV_T3_CC1 ADC3_EXTERNALTRIG_T3_CC1
-#define ADC_EXTERNALTRIGCONV_T5_CC1 ADC3_EXTERNALTRIG_T5_CC1
-#define ADC_EXTERNALTRIGCONV_T5_CC3 ADC3_EXTERNALTRIG_T5_CC3
-#define ADC_EXTERNALTRIGCONV_T8_CC1 ADC3_EXTERNALTRIG_T8_CC1
-#endif /* STM32F103xE || defined STM32F103xG */
-
-/*!< External triggers of regular group for all ADC instances */
-#define ADC_EXTERNALTRIGCONV_T1_CC3 ADC1_2_3_EXTERNALTRIG_T1_CC3
-
-#if defined (STM32F101xE) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC)
-/*!< Note: TIM8_TRGO is available on ADC1 and ADC2 only in high-density and */
-/* XL-density devices. */
-/* To use it on ADC or ADC2, a remap of trigger must be done from */
-/* EXTI line 11 to TIM8_TRGO with macro: */
-/* __HAL_AFIO_REMAP_ADC1_ETRGREG_ENABLE() */
-/* __HAL_AFIO_REMAP_ADC2_ETRGREG_ENABLE() */
-
-/* Note for internal constant value management: If TIM8_TRGO is available, */
-/* its definition is set to value for ADC1&ADC2 by default and changed to */
-/* value for ADC3 by HAL ADC driver if ADC3 is selected. */
-#define ADC_EXTERNALTRIGCONV_T8_TRGO ADC1_2_EXTERNALTRIG_T8_TRGO
-#endif /* STM32F101xE || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
-
-#define ADC_SOFTWARE_START ADC1_2_3_SWSTART
-/**
- * @}
- */
-
-/** @defgroup ADCEx_External_trigger_source_Injected ADCEx External trigger selection for injected group
- * @{
- */
-/*!< List of external triggers with generic trigger name, independently of */
-/* ADC target, sorted by trigger name: */
-
-/*!< External triggers of injected group for ADC1&ADC2 only */
-#define ADC_EXTERNALTRIGINJECCONV_T2_TRGO ADC1_2_EXTERNALTRIGINJEC_T2_TRGO
-#define ADC_EXTERNALTRIGINJECCONV_T2_CC1 ADC1_2_EXTERNALTRIGINJEC_T2_CC1
-#define ADC_EXTERNALTRIGINJECCONV_T3_CC4 ADC1_2_EXTERNALTRIGINJEC_T3_CC4
-#define ADC_EXTERNALTRIGINJECCONV_T4_TRGO ADC1_2_EXTERNALTRIGINJEC_T4_TRGO
-#define ADC_EXTERNALTRIGINJECCONV_EXT_IT15 ADC1_2_EXTERNALTRIGINJEC_EXT_IT15
-
-#if defined (STM32F103xE) || defined (STM32F103xG)
-/*!< External triggers of injected group for ADC3 only */
-#define ADC_EXTERNALTRIGINJECCONV_T4_CC3 ADC3_EXTERNALTRIGINJEC_T4_CC3
-#define ADC_EXTERNALTRIGINJECCONV_T8_CC2 ADC3_EXTERNALTRIGINJEC_T8_CC2
-#define ADC_EXTERNALTRIGINJECCONV_T5_TRGO ADC3_EXTERNALTRIGINJEC_T5_TRGO
-#define ADC_EXTERNALTRIGINJECCONV_T5_CC4 ADC3_EXTERNALTRIGINJEC_T5_CC4
-#endif /* STM32F103xE || defined STM32F103xG */
-
-/*!< External triggers of injected group for all ADC instances */
-#define ADC_EXTERNALTRIGINJECCONV_T1_CC4 ADC1_2_3_EXTERNALTRIGINJEC_T1_CC4
-#define ADC_EXTERNALTRIGINJECCONV_T1_TRGO ADC1_2_3_EXTERNALTRIGINJEC_T1_TRGO
-
-#if defined (STM32F101xE) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC)
-/*!< Note: TIM8_CC4 is available on ADC1 and ADC2 only in high-density and */
-/* XL-density devices. */
-/* To use it on ADC1 or ADC2, a remap of trigger must be done from */
-/* EXTI line 11 to TIM8_CC4 with macro: */
-/* __HAL_AFIO_REMAP_ADC1_ETRGINJ_ENABLE() */
-/* __HAL_AFIO_REMAP_ADC2_ETRGINJ_ENABLE() */
-
-/* Note for internal constant value management: If TIM8_CC4 is available, */
-/* its definition is set to value for ADC1&ADC2 by default and changed to */
-/* value for ADC3 by HAL ADC driver if ADC3 is selected. */
-#define ADC_EXTERNALTRIGINJECCONV_T8_CC4 ADC1_2_EXTERNALTRIGINJEC_T8_CC4
-#endif /* STM32F101xE || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
-
-#define ADC_INJECTED_SOFTWARE_START ADC1_2_3_JSWSTART
-/**
- * @}
- */
-
-#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
-/** @defgroup ADCEx_Common_mode ADC Extended Dual ADC Mode
- * @{
- */
-#define ADC_MODE_INDEPENDENT 0x00000000U /*!< ADC dual mode disabled (ADC independent mode) */
-#define ADC_DUALMODE_REGSIMULT_INJECSIMULT ((uint32_t)( ADC_CR1_DUALMOD_0)) /*!< ADC dual mode enabled: Combined regular simultaneous + injected simultaneous mode, on groups regular and injected */
-#define ADC_DUALMODE_REGSIMULT_ALTERTRIG ((uint32_t)( ADC_CR1_DUALMOD_1 )) /*!< ADC dual mode enabled: Combined regular simultaneous + alternate trigger mode, on groups regular and injected */
-#define ADC_DUALMODE_INJECSIMULT_INTERLFAST ((uint32_t)( ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0)) /*!< ADC dual mode enabled: Combined injected simultaneous + fast interleaved mode, on groups regular and injected (delay between ADC sampling phases: 7 ADC clock cycles (equivalent to parameter "TwoSamplingDelay" set to "ADC_TWOSAMPLINGDELAY_7CYCLES" on other STM32 devices)) */
-#define ADC_DUALMODE_INJECSIMULT_INTERLSLOW ((uint32_t)( ADC_CR1_DUALMOD_2 )) /*!< ADC dual mode enabled: Combined injected simultaneous + slow Interleaved mode, on groups regular and injected (delay between ADC sampling phases: 14 ADC clock cycles (equivalent to parameter "TwoSamplingDelay" set to "ADC_TWOSAMPLINGDELAY_7CYCLES" on other STM32 devices)) */
-#define ADC_DUALMODE_INJECSIMULT ((uint32_t)( ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_0)) /*!< ADC dual mode enabled: Injected simultaneous mode, on group injected */
-#define ADC_DUALMODE_REGSIMULT ((uint32_t)( ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 )) /*!< ADC dual mode enabled: Regular simultaneous mode, on group regular */
-#define ADC_DUALMODE_INTERLFAST ((uint32_t)( ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0)) /*!< ADC dual mode enabled: Fast interleaved mode, on group regular (delay between ADC sampling phases: 7 ADC clock cycles (equivalent to parameter "TwoSamplingDelay" set to "ADC_TWOSAMPLINGDELAY_7CYCLES" on other STM32 devices)) */
-#define ADC_DUALMODE_INTERLSLOW ((uint32_t)(ADC_CR1_DUALMOD_3 )) /*!< ADC dual mode enabled: Slow interleaved mode, on group regular (delay between ADC sampling phases: 14 ADC clock cycles (equivalent to parameter "TwoSamplingDelay" set to "ADC_TWOSAMPLINGDELAY_7CYCLES" on other STM32 devices)) */
-#define ADC_DUALMODE_ALTERTRIG ((uint32_t)(ADC_CR1_DUALMOD_3 | ADC_CR1_DUALMOD_0)) /*!< ADC dual mode enabled: Alternate trigger mode, on group injected */
-/**
- * @}
- */
-#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
-
-/**
- * @}
- */
-
-
-/* Private constants ---------------------------------------------------------*/
-
-/** @addtogroup ADCEx_Private_Constants ADCEx Private Constants
- * @{
- */
-
-/** @defgroup ADCEx_Internal_HAL_driver_Ext_trig_src_Regular ADC Extended Internal HAL driver trigger selection for regular group
- * @{
- */
-/* List of external triggers of regular group for ADC1, ADC2, ADC3 (if ADC */
-/* instance is available on the selected device). */
-/* (used internally by HAL driver. To not use into HAL structure parameters) */
-
-/* External triggers of regular group for ADC1&ADC2 (if ADCx available) */
-#define ADC1_2_EXTERNALTRIG_T1_CC1 0x00000000U
-#define ADC1_2_EXTERNALTRIG_T1_CC2 ((uint32_t)( ADC_CR2_EXTSEL_0))
-#define ADC1_2_EXTERNALTRIG_T2_CC2 ((uint32_t)( ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0))
-#define ADC1_2_EXTERNALTRIG_T3_TRGO ((uint32_t)(ADC_CR2_EXTSEL_2 ))
-#define ADC1_2_EXTERNALTRIG_T4_CC4 ((uint32_t)(ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_0))
-#define ADC1_2_EXTERNALTRIG_EXT_IT11 ((uint32_t)(ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1 ))
-#if defined (STM32F101xE) || defined (STM32F103xE) || defined (STM32F103xG)
-/* Note: TIM8_TRGO is available on ADC1 and ADC2 only in high-density and */
-/* XL-density devices. */
-#define ADC1_2_EXTERNALTRIG_T8_TRGO ADC1_2_EXTERNALTRIG_EXT_IT11
-#endif
-
-#if defined (STM32F103xE) || defined (STM32F103xG)
-/* External triggers of regular group for ADC3 */
-#define ADC3_EXTERNALTRIG_T3_CC1 ADC1_2_EXTERNALTRIG_T1_CC1
-#define ADC3_EXTERNALTRIG_T2_CC3 ADC1_2_EXTERNALTRIG_T1_CC2
-#define ADC3_EXTERNALTRIG_T8_CC1 ADC1_2_EXTERNALTRIG_T2_CC2
-#define ADC3_EXTERNALTRIG_T8_TRGO ADC1_2_EXTERNALTRIG_T3_TRGO
-#define ADC3_EXTERNALTRIG_T5_CC1 ADC1_2_EXTERNALTRIG_T4_CC4
-#define ADC3_EXTERNALTRIG_T5_CC3 ADC1_2_EXTERNALTRIG_EXT_IT11
-#endif
-
-/* External triggers of regular group for ADC1&ADC2&ADC3 (if ADCx available) */
-#define ADC1_2_3_EXTERNALTRIG_T1_CC3 ((uint32_t)( ADC_CR2_EXTSEL_1 ))
-#define ADC1_2_3_SWSTART ((uint32_t)(ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0))
-/**
- * @}
- */
-
-/** @defgroup ADCEx_Internal_HAL_driver_Ext_trig_src_Injected ADC Extended Internal HAL driver trigger selection for injected group
- * @{
- */
-/* List of external triggers of injected group for ADC1, ADC2, ADC3 (if ADC */
-/* instance is available on the selected device). */
-/* (used internally by HAL driver. To not use into HAL structure parameters) */
-
-/* External triggers of injected group for ADC1&ADC2 (if ADCx available) */
-#define ADC1_2_EXTERNALTRIGINJEC_T2_TRGO ((uint32_t)( ADC_CR2_JEXTSEL_1 ))
-#define ADC1_2_EXTERNALTRIGINJEC_T2_CC1 ((uint32_t)( ADC_CR2_JEXTSEL_1 | ADC_CR2_JEXTSEL_0))
-#define ADC1_2_EXTERNALTRIGINJEC_T3_CC4 ((uint32_t)(ADC_CR2_JEXTSEL_2 ))
-#define ADC1_2_EXTERNALTRIGINJEC_T4_TRGO ((uint32_t)(ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_0))
-#define ADC1_2_EXTERNALTRIGINJEC_EXT_IT15 ((uint32_t)(ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_1 ))
-#if defined (STM32F101xE) || defined (STM32F103xE) || defined (STM32F103xG)
-/* Note: TIM8_CC4 is available on ADC1 and ADC2 only in high-density and */
-/* XL-density devices. */
-#define ADC1_2_EXTERNALTRIGINJEC_T8_CC4 ADC1_2_EXTERNALTRIGINJEC_EXT_IT15
-#endif
-
-#if defined (STM32F103xE) || defined (STM32F103xG)
-/* External triggers of injected group for ADC3 */
-#define ADC3_EXTERNALTRIGINJEC_T4_CC3 ADC1_2_EXTERNALTRIGINJEC_T2_TRGO
-#define ADC3_EXTERNALTRIGINJEC_T8_CC2 ADC1_2_EXTERNALTRIGINJEC_T2_CC1
-#define ADC3_EXTERNALTRIGINJEC_T8_CC4 ADC1_2_EXTERNALTRIGINJEC_T3_CC4
-#define ADC3_EXTERNALTRIGINJEC_T5_TRGO ADC1_2_EXTERNALTRIGINJEC_T4_TRGO
-#define ADC3_EXTERNALTRIGINJEC_T5_CC4 ADC1_2_EXTERNALTRIGINJEC_EXT_IT15
-#endif /* STM32F103xE || defined STM32F103xG */
-
-/* External triggers of injected group for ADC1&ADC2&ADC3 (if ADCx available) */
-#define ADC1_2_3_EXTERNALTRIGINJEC_T1_TRGO 0x00000000U
-#define ADC1_2_3_EXTERNALTRIGINJEC_T1_CC4 ((uint32_t)( ADC_CR2_JEXTSEL_0))
-#define ADC1_2_3_JSWSTART ((uint32_t)(ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_1 | ADC_CR2_JEXTSEL_0))
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-
-/* Exported macro ------------------------------------------------------------*/
-
-/* Private macro -------------------------------------------------------------*/
-
-/** @defgroup ADCEx_Private_Macro ADCEx Private Macro
- * @{
- */
-/* Macro reserved for internal HAL driver usage, not intended to be used in */
-/* code of final user. */
-
-
-/**
- * @brief For devices with 3 ADCs: Defines the external trigger source
- * for regular group according to ADC into common group ADC1&ADC2 or
- * ADC3 (some triggers with same source have different value to
- * be programmed into ADC EXTSEL bits of CR2 register).
- * For devices with 2 ADCs or less: this macro makes no change.
- * @param __HANDLE__: ADC handle
- * @param __EXT_TRIG_CONV__: External trigger selected for regular group.
- * @retval External trigger to be programmed into EXTSEL bits of CR2 register
- */
-#if defined (STM32F103xE) || defined (STM32F103xG)
-#define ADC_CFGR_EXTSEL(__HANDLE__, __EXT_TRIG_CONV__) \
- (( (((__HANDLE__)->Instance) == ADC3) \
- )? \
- ( ( (__EXT_TRIG_CONV__) == ADC_EXTERNALTRIGCONV_T8_TRGO \
- )? \
- (ADC3_EXTERNALTRIG_T8_TRGO) \
- : \
- (__EXT_TRIG_CONV__) \
- ) \
- : \
- (__EXT_TRIG_CONV__) \
- )
-#else
-#define ADC_CFGR_EXTSEL(__HANDLE__, __EXT_TRIG_CONV__) \
- (__EXT_TRIG_CONV__)
-#endif /* STM32F103xE || STM32F103xG */
-
-/**
- * @brief For devices with 3 ADCs: Defines the external trigger source
- * for injected group according to ADC into common group ADC1&ADC2 or
- * ADC3 (some triggers with same source have different value to
- * be programmed into ADC JEXTSEL bits of CR2 register).
- * For devices with 2 ADCs or less: this macro makes no change.
- * @param __HANDLE__: ADC handle
- * @param __EXT_TRIG_INJECTCONV__: External trigger selected for injected group.
- * @retval External trigger to be programmed into JEXTSEL bits of CR2 register
- */
-#if defined (STM32F103xE) || defined (STM32F103xG)
-#define ADC_CFGR_JEXTSEL(__HANDLE__, __EXT_TRIG_INJECTCONV__) \
- (( (((__HANDLE__)->Instance) == ADC3) \
- )? \
- ( ( (__EXT_TRIG_INJECTCONV__) == ADC_EXTERNALTRIGINJECCONV_T8_CC4 \
- )? \
- (ADC3_EXTERNALTRIGINJEC_T8_CC4) \
- : \
- (__EXT_TRIG_INJECTCONV__) \
- ) \
- : \
- (__EXT_TRIG_INJECTCONV__) \
- )
-#else
-#define ADC_CFGR_JEXTSEL(__HANDLE__, __EXT_TRIG_INJECTCONV__) \
- (__EXT_TRIG_INJECTCONV__)
-#endif /* STM32F103xE || STM32F103xG */
-
-
-/**
- * @brief Verification if multimode is enabled for the selected ADC (multimode ADC master or ADC slave) (applicable for devices with several ADCs)
- * @param __HANDLE__: ADC handle
- * @retval Multimode state: RESET if multimode is disabled, other value if multimode is enabled
- */
-#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
-#define ADC_MULTIMODE_IS_ENABLE(__HANDLE__) \
- (( (((__HANDLE__)->Instance) == ADC1) || (((__HANDLE__)->Instance) == ADC2) \
- )? \
- (ADC1->CR1 & ADC_CR1_DUALMOD) \
- : \
- (RESET) \
- )
-#else
-#define ADC_MULTIMODE_IS_ENABLE(__HANDLE__) \
- (RESET)
-#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
-
-/**
- * @brief Verification of condition for ADC start conversion: ADC must be in non-multimode, or multimode with handle of ADC master (applicable for devices with several ADCs)
- * @param __HANDLE__: ADC handle
- * @retval None
- */
-#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
-#define ADC_NONMULTIMODE_OR_MULTIMODEMASTER(__HANDLE__) \
- (( (((__HANDLE__)->Instance) == ADC2) \
- )? \
- ((ADC1->CR1 & ADC_CR1_DUALMOD) == RESET) \
- : \
- (!RESET) \
- )
-#else
-#define ADC_NONMULTIMODE_OR_MULTIMODEMASTER(__HANDLE__) \
- (!RESET)
-#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
-
-/**
- * @brief Check ADC multimode setting: In case of multimode, check whether ADC master of the selected ADC has feature auto-injection enabled (applicable for devices with several ADCs)
- * @param __HANDLE__: ADC handle
- * @retval None
- */
-#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
-#define ADC_MULTIMODE_AUTO_INJECTED(__HANDLE__) \
- (( (((__HANDLE__)->Instance) == ADC1) || (((__HANDLE__)->Instance) == ADC2) \
- )? \
- (ADC1->CR1 & ADC_CR1_JAUTO) \
- : \
- (RESET) \
- )
-#else
-#define ADC_MULTIMODE_AUTO_INJECTED(__HANDLE__) \
- (RESET)
-#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
-
-#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
-/**
- * @brief Set handle of the other ADC sharing the common multimode settings
- * @param __HANDLE__: ADC handle
- * @param __HANDLE_OTHER_ADC__: other ADC handle
- * @retval None
- */
-#define ADC_COMMON_ADC_OTHER(__HANDLE__, __HANDLE_OTHER_ADC__) \
- ((__HANDLE_OTHER_ADC__)->Instance = ADC2)
-
-/**
- * @brief Set handle of the ADC slave associated to the ADC master
- * On STM32F1 devices, ADC slave is always ADC2 (this can be different
- * on other STM32 devices)
- * @param __HANDLE_MASTER__: ADC master handle
- * @param __HANDLE_SLAVE__: ADC slave handle
- * @retval None
- */
-#define ADC_MULTI_SLAVE(__HANDLE_MASTER__, __HANDLE_SLAVE__) \
- ((__HANDLE_SLAVE__)->Instance = ADC2)
-
-#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
-
-#define IS_ADC_INJECTED_RANK(CHANNEL) (((CHANNEL) == ADC_INJECTED_RANK_1) || \
- ((CHANNEL) == ADC_INJECTED_RANK_2) || \
- ((CHANNEL) == ADC_INJECTED_RANK_3) || \
- ((CHANNEL) == ADC_INJECTED_RANK_4))
-
-#define IS_ADC_EXTTRIGINJEC_EDGE(EDGE) (((EDGE) == ADC_EXTERNALTRIGINJECCONV_EDGE_NONE) || \
- ((EDGE) == ADC_EXTERNALTRIGINJECCONV_EDGE_RISING))
-
-/** @defgroup ADCEx_injected_nb_conv_verification ADCEx injected nb conv verification
- * @{
- */
-#define IS_ADC_INJECTED_NB_CONV(LENGTH) (((LENGTH) >= 1U) && ((LENGTH) <= 4U))
-/**
- * @}
- */
-
-#if defined (STM32F100xB) || defined (STM32F100xE) || defined (STM32F101x6) || defined (STM32F101xB) || defined (STM32F102x6) || defined (STM32F102xB) || defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC)
-#define IS_ADC_EXTTRIG(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC1) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC2) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC2) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_TRGO) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T4_CC4) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_EXT_IT11) || \
- ((REGTRIG) == ADC_SOFTWARE_START))
-#endif
-#if defined (STM32F101xE)
-#define IS_ADC_EXTTRIG(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC1) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC2) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC2) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_TRGO) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T4_CC4) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_EXT_IT11) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T8_TRGO) || \
- ((REGTRIG) == ADC_SOFTWARE_START))
-#endif
-#if defined (STM32F101xG)
-#define IS_ADC_EXTTRIG(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC1) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC2) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC2) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_TRGO) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T4_CC4) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_EXT_IT11) || \
- ((REGTRIG) == ADC_SOFTWARE_START))
-#endif
-#if defined (STM32F103xE) || defined (STM32F103xG)
-#define IS_ADC_EXTTRIG(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC1) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC2) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC2) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_TRGO) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T4_CC4) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_EXT_IT11) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_CC1) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC3) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T8_CC1) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T5_CC1) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T5_CC3) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC3) || \
- ((REGTRIG) == ADC_EXTERNALTRIGCONV_T8_TRGO) || \
- ((REGTRIG) == ADC_SOFTWARE_START))
-#endif
-
-#if defined (STM32F100xB) || defined (STM32F100xE) || defined (STM32F101x6) || defined (STM32F101xB) || defined (STM32F102x6) || defined (STM32F102xB) || defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC)
-#define IS_ADC_EXTTRIGINJEC(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_TRGO) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_CC1) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T3_CC4) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_TRGO) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_EXT_IT15) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_CC4) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_TRGO) || \
- ((REGTRIG) == ADC_INJECTED_SOFTWARE_START))
-#endif
-#if defined (STM32F101xE)
-#define IS_ADC_EXTTRIGINJEC(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_TRGO) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_CC1) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T3_CC4) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_TRGO) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_EXT_IT15) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_CC4) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_TRGO) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T8_CC4) || \
- ((REGTRIG) == ADC_INJECTED_SOFTWARE_START))
-#endif
-#if defined (STM32F101xG)
-#define IS_ADC_EXTTRIGINJEC(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_TRGO) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_CC1) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T3_CC4) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_TRGO) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_EXT_IT15) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_CC4) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_TRGO) || \
- ((REGTRIG) == ADC_INJECTED_SOFTWARE_START))
-#endif
-#if defined (STM32F103xE) || defined (STM32F103xG)
-#define IS_ADC_EXTTRIGINJEC(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_TRGO) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_CC1) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T3_CC4) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_TRGO) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T5_CC4) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_EXT_IT15) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_CC3) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T8_CC2) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T5_TRGO) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T5_CC4) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_CC4) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_TRGO) || \
- ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T8_CC4) || \
- ((REGTRIG) == ADC_INJECTED_SOFTWARE_START))
-#endif
-
-#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
-#define IS_ADC_MODE(MODE) (((MODE) == ADC_MODE_INDEPENDENT) || \
- ((MODE) == ADC_DUALMODE_REGSIMULT_INJECSIMULT) || \
- ((MODE) == ADC_DUALMODE_REGSIMULT_ALTERTRIG) || \
- ((MODE) == ADC_DUALMODE_INJECSIMULT_INTERLFAST) || \
- ((MODE) == ADC_DUALMODE_INJECSIMULT_INTERLSLOW) || \
- ((MODE) == ADC_DUALMODE_INJECSIMULT) || \
- ((MODE) == ADC_DUALMODE_REGSIMULT) || \
- ((MODE) == ADC_DUALMODE_INTERLFAST) || \
- ((MODE) == ADC_DUALMODE_INTERLSLOW) || \
- ((MODE) == ADC_DUALMODE_ALTERTRIG) )
-#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
-
-/**
- * @}
- */
-
-
-
-
-
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup ADCEx_Exported_Functions
- * @{
- */
-
-/* IO operation functions *****************************************************/
-/** @addtogroup ADCEx_Exported_Functions_Group1
- * @{
- */
-
-/* ADC calibration */
-HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc);
-
-/* Blocking mode: Polling */
-HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef* hadc);
-HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef* hadc);
-HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout);
-
-/* Non-blocking mode: Interruption */
-HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef* hadc);
-HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef* hadc);
-
-#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
-/* ADC multimode */
-HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, uint32_t Length);
-HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef *hadc);
-#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
-
-/* ADC retrieve conversion value intended to be used with polling or interruption */
-uint32_t HAL_ADCEx_InjectedGetValue(ADC_HandleTypeDef* hadc, uint32_t InjectedRank);
-#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
-uint32_t HAL_ADCEx_MultiModeGetValue(ADC_HandleTypeDef *hadc);
-#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
-
-/* ADC IRQHandler and Callbacks used in non-blocking modes (Interruption) */
-void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc);
-/**
- * @}
- */
-
-
-/* Peripheral Control functions ***********************************************/
-/** @addtogroup ADCEx_Exported_Functions_Group2
- * @{
- */
-HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc,ADC_InjectionConfTypeDef* sConfigInjected);
-#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
-HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef *hadc, ADC_MultiModeTypeDef *multimode);
-#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
-/**
- * @}
- */
-
-
-/**
- * @}
- */
-
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_ADC_EX_H */
-
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_can.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_can.h
deleted file mode 100644
index a33816c..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_can.h
+++ /dev/null
@@ -1,799 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_can.h
- * @author MCD Application Team
- * @brief Header file of CAN HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef STM32F1xx_HAL_CAN_H
-#define STM32F1xx_HAL_CAN_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#if defined (CAN1)
-/** @addtogroup CAN
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup CAN_Exported_Types CAN Exported Types
- * @{
- */
-/**
- * @brief HAL State structures definition
- */
-typedef enum
-{
- HAL_CAN_STATE_RESET = 0x00U, /*!< CAN not yet initialized or disabled */
- HAL_CAN_STATE_READY = 0x01U, /*!< CAN initialized and ready for use */
- HAL_CAN_STATE_LISTENING = 0x02U, /*!< CAN receive process is ongoing */
- HAL_CAN_STATE_SLEEP_PENDING = 0x03U, /*!< CAN sleep request is pending */
- HAL_CAN_STATE_SLEEP_ACTIVE = 0x04U, /*!< CAN sleep mode is active */
- HAL_CAN_STATE_ERROR = 0x05U /*!< CAN error state */
-
-} HAL_CAN_StateTypeDef;
-
-/**
- * @brief CAN init structure definition
- */
-typedef struct
-{
- uint32_t Prescaler; /*!< Specifies the length of a time quantum.
- This parameter must be a number between Min_Data = 1 and Max_Data = 1024. */
-
- uint32_t Mode; /*!< Specifies the CAN operating mode.
- This parameter can be a value of @ref CAN_operating_mode */
-
- uint32_t SyncJumpWidth; /*!< Specifies the maximum number of time quanta the CAN hardware
- is allowed to lengthen or shorten a bit to perform resynchronization.
- This parameter can be a value of @ref CAN_synchronisation_jump_width */
-
- uint32_t TimeSeg1; /*!< Specifies the number of time quanta in Bit Segment 1.
- This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_1 */
-
- uint32_t TimeSeg2; /*!< Specifies the number of time quanta in Bit Segment 2.
- This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_2 */
-
- FunctionalState TimeTriggeredMode; /*!< Enable or disable the time triggered communication mode.
- This parameter can be set to ENABLE or DISABLE. */
-
- FunctionalState AutoBusOff; /*!< Enable or disable the automatic bus-off management.
- This parameter can be set to ENABLE or DISABLE. */
-
- FunctionalState AutoWakeUp; /*!< Enable or disable the automatic wake-up mode.
- This parameter can be set to ENABLE or DISABLE. */
-
- FunctionalState AutoRetransmission; /*!< Enable or disable the non-automatic retransmission mode.
- This parameter can be set to ENABLE or DISABLE. */
-
- FunctionalState ReceiveFifoLocked; /*!< Enable or disable the Receive FIFO Locked mode.
- This parameter can be set to ENABLE or DISABLE. */
-
- FunctionalState TransmitFifoPriority;/*!< Enable or disable the transmit FIFO priority.
- This parameter can be set to ENABLE or DISABLE. */
-
-} CAN_InitTypeDef;
-
-/**
- * @brief CAN filter configuration structure definition
- */
-typedef struct
-{
- uint32_t FilterIdHigh; /*!< Specifies the filter identification number (MSBs for a 32-bit
- configuration, first one for a 16-bit configuration).
- This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
-
- uint32_t FilterIdLow; /*!< Specifies the filter identification number (LSBs for a 32-bit
- configuration, second one for a 16-bit configuration).
- This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
-
- uint32_t FilterMaskIdHigh; /*!< Specifies the filter mask number or identification number,
- according to the mode (MSBs for a 32-bit configuration,
- first one for a 16-bit configuration).
- This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
-
- uint32_t FilterMaskIdLow; /*!< Specifies the filter mask number or identification number,
- according to the mode (LSBs for a 32-bit configuration,
- second one for a 16-bit configuration).
- This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
-
- uint32_t FilterFIFOAssignment; /*!< Specifies the FIFO (0 or 1U) which will be assigned to the filter.
- This parameter can be a value of @ref CAN_filter_FIFO */
-
- uint32_t FilterBank; /*!< Specifies the filter bank which will be initialized.
- For single CAN instance(14 dedicated filter banks),
- this parameter must be a number between Min_Data = 0 and Max_Data = 13.
- For dual CAN instances(28 filter banks shared),
- this parameter must be a number between Min_Data = 0 and Max_Data = 27. */
-
- uint32_t FilterMode; /*!< Specifies the filter mode to be initialized.
- This parameter can be a value of @ref CAN_filter_mode */
-
- uint32_t FilterScale; /*!< Specifies the filter scale.
- This parameter can be a value of @ref CAN_filter_scale */
-
- uint32_t FilterActivation; /*!< Enable or disable the filter.
- This parameter can be a value of @ref CAN_filter_activation */
-
- uint32_t SlaveStartFilterBank; /*!< Select the start filter bank for the slave CAN instance.
- For single CAN instances, this parameter is meaningless.
- For dual CAN instances, all filter banks with lower index are assigned to master
- CAN instance, whereas all filter banks with greater index are assigned to slave
- CAN instance.
- This parameter must be a number between Min_Data = 0 and Max_Data = 27. */
-
-} CAN_FilterTypeDef;
-
-/**
- * @brief CAN Tx message header structure definition
- */
-typedef struct
-{
- uint32_t StdId; /*!< Specifies the standard identifier.
- This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF. */
-
- uint32_t ExtId; /*!< Specifies the extended identifier.
- This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF. */
-
- uint32_t IDE; /*!< Specifies the type of identifier for the message that will be transmitted.
- This parameter can be a value of @ref CAN_identifier_type */
-
- uint32_t RTR; /*!< Specifies the type of frame for the message that will be transmitted.
- This parameter can be a value of @ref CAN_remote_transmission_request */
-
- uint32_t DLC; /*!< Specifies the length of the frame that will be transmitted.
- This parameter must be a number between Min_Data = 0 and Max_Data = 8. */
-
- FunctionalState TransmitGlobalTime; /*!< Specifies whether the timestamp counter value captured on start
- of frame transmission, is sent in DATA6 and DATA7 replacing pData[6] and pData[7].
- @note: Time Triggered Communication Mode must be enabled.
- @note: DLC must be programmed as 8 bytes, in order these 2 bytes are sent.
- This parameter can be set to ENABLE or DISABLE. */
-
-} CAN_TxHeaderTypeDef;
-
-/**
- * @brief CAN Rx message header structure definition
- */
-typedef struct
-{
- uint32_t StdId; /*!< Specifies the standard identifier.
- This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF. */
-
- uint32_t ExtId; /*!< Specifies the extended identifier.
- This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF. */
-
- uint32_t IDE; /*!< Specifies the type of identifier for the message that will be transmitted.
- This parameter can be a value of @ref CAN_identifier_type */
-
- uint32_t RTR; /*!< Specifies the type of frame for the message that will be transmitted.
- This parameter can be a value of @ref CAN_remote_transmission_request */
-
- uint32_t DLC; /*!< Specifies the length of the frame that will be transmitted.
- This parameter must be a number between Min_Data = 0 and Max_Data = 8. */
-
- uint32_t Timestamp; /*!< Specifies the timestamp counter value captured on start of frame reception.
- @note: Time Triggered Communication Mode must be enabled.
- This parameter must be a number between Min_Data = 0 and Max_Data = 0xFFFF. */
-
- uint32_t FilterMatchIndex; /*!< Specifies the index of matching acceptance filter element.
- This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF. */
-
-} CAN_RxHeaderTypeDef;
-
-/**
- * @brief CAN handle Structure definition
- */
-typedef struct __CAN_HandleTypeDef
-{
- CAN_TypeDef *Instance; /*!< Register base address */
-
- CAN_InitTypeDef Init; /*!< CAN required parameters */
-
- __IO HAL_CAN_StateTypeDef State; /*!< CAN communication state */
-
- __IO uint32_t ErrorCode; /*!< CAN Error code.
- This parameter can be a value of @ref CAN_Error_Code */
-
-} CAN_HandleTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-
-/** @defgroup CAN_Exported_Constants CAN Exported Constants
- * @{
- */
-
-/** @defgroup CAN_Error_Code CAN Error Code
- * @{
- */
-#define HAL_CAN_ERROR_NONE (0x00000000U) /*!< No error */
-#define HAL_CAN_ERROR_EWG (0x00000001U) /*!< Protocol Error Warning */
-#define HAL_CAN_ERROR_EPV (0x00000002U) /*!< Error Passive */
-#define HAL_CAN_ERROR_BOF (0x00000004U) /*!< Bus-off error */
-#define HAL_CAN_ERROR_STF (0x00000008U) /*!< Stuff error */
-#define HAL_CAN_ERROR_FOR (0x00000010U) /*!< Form error */
-#define HAL_CAN_ERROR_ACK (0x00000020U) /*!< Acknowledgment error */
-#define HAL_CAN_ERROR_BR (0x00000040U) /*!< Bit recessive error */
-#define HAL_CAN_ERROR_BD (0x00000080U) /*!< Bit dominant error */
-#define HAL_CAN_ERROR_CRC (0x00000100U) /*!< CRC error */
-#define HAL_CAN_ERROR_RX_FOV0 (0x00000200U) /*!< Rx FIFO0 overrun error */
-#define HAL_CAN_ERROR_RX_FOV1 (0x00000400U) /*!< Rx FIFO1 overrun error */
-#define HAL_CAN_ERROR_TX_ALST0 (0x00000800U) /*!< TxMailbox 0 transmit failure due to arbitration lost */
-#define HAL_CAN_ERROR_TX_TERR0 (0x00001000U) /*!< TxMailbox 1 transmit failure due to tranmit error */
-#define HAL_CAN_ERROR_TX_ALST1 (0x00002000U) /*!< TxMailbox 0 transmit failure due to arbitration lost */
-#define HAL_CAN_ERROR_TX_TERR1 (0x00004000U) /*!< TxMailbox 1 transmit failure due to tranmit error */
-#define HAL_CAN_ERROR_TX_ALST2 (0x00008000U) /*!< TxMailbox 0 transmit failure due to arbitration lost */
-#define HAL_CAN_ERROR_TX_TERR2 (0x00010000U) /*!< TxMailbox 1 transmit failure due to tranmit error */
-#define HAL_CAN_ERROR_TIMEOUT (0x00020000U) /*!< Timeout error */
-#define HAL_CAN_ERROR_NOT_INITIALIZED (0x00040000U) /*!< Peripheral not initialized */
-#define HAL_CAN_ERROR_NOT_READY (0x00080000U) /*!< Peripheral not ready */
-#define HAL_CAN_ERROR_NOT_STARTED (0x00100000U) /*!< Peripheral not started */
-#define HAL_CAN_ERROR_PARAM (0x00200000U) /*!< Parameter error */
-
-#define HAL_CAN_ERROR_INTERNAL (0x00800000U) /*!< Internal error */
-
-/**
- * @}
- */
-
-/** @defgroup CAN_InitStatus CAN InitStatus
- * @{
- */
-#define CAN_INITSTATUS_FAILED (0x00000000U) /*!< CAN initialization failed */
-#define CAN_INITSTATUS_SUCCESS (0x00000001U) /*!< CAN initialization OK */
-/**
- * @}
- */
-
-/** @defgroup CAN_operating_mode CAN Operating Mode
- * @{
- */
-#define CAN_MODE_NORMAL (0x00000000U) /*!< Normal mode */
-#define CAN_MODE_LOOPBACK ((uint32_t)CAN_BTR_LBKM) /*!< Loopback mode */
-#define CAN_MODE_SILENT ((uint32_t)CAN_BTR_SILM) /*!< Silent mode */
-#define CAN_MODE_SILENT_LOOPBACK ((uint32_t)(CAN_BTR_LBKM | CAN_BTR_SILM)) /*!< Loopback combined with silent mode */
-/**
- * @}
- */
-
-
-/** @defgroup CAN_synchronisation_jump_width CAN Synchronization Jump Width
- * @{
- */
-#define CAN_SJW_1TQ (0x00000000U) /*!< 1 time quantum */
-#define CAN_SJW_2TQ ((uint32_t)CAN_BTR_SJW_0) /*!< 2 time quantum */
-#define CAN_SJW_3TQ ((uint32_t)CAN_BTR_SJW_1) /*!< 3 time quantum */
-#define CAN_SJW_4TQ ((uint32_t)CAN_BTR_SJW) /*!< 4 time quantum */
-/**
- * @}
- */
-
-/** @defgroup CAN_time_quantum_in_bit_segment_1 CAN Time Quantum in Bit Segment 1
- * @{
- */
-#define CAN_BS1_1TQ (0x00000000U) /*!< 1 time quantum */
-#define CAN_BS1_2TQ ((uint32_t)CAN_BTR_TS1_0) /*!< 2 time quantum */
-#define CAN_BS1_3TQ ((uint32_t)CAN_BTR_TS1_1) /*!< 3 time quantum */
-#define CAN_BS1_4TQ ((uint32_t)(CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 4 time quantum */
-#define CAN_BS1_5TQ ((uint32_t)CAN_BTR_TS1_2) /*!< 5 time quantum */
-#define CAN_BS1_6TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_0)) /*!< 6 time quantum */
-#define CAN_BS1_7TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_1)) /*!< 7 time quantum */
-#define CAN_BS1_8TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 8 time quantum */
-#define CAN_BS1_9TQ ((uint32_t)CAN_BTR_TS1_3) /*!< 9 time quantum */
-#define CAN_BS1_10TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_0)) /*!< 10 time quantum */
-#define CAN_BS1_11TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_1)) /*!< 11 time quantum */
-#define CAN_BS1_12TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 12 time quantum */
-#define CAN_BS1_13TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2)) /*!< 13 time quantum */
-#define CAN_BS1_14TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2 | CAN_BTR_TS1_0)) /*!< 14 time quantum */
-#define CAN_BS1_15TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2 | CAN_BTR_TS1_1)) /*!< 15 time quantum */
-#define CAN_BS1_16TQ ((uint32_t)CAN_BTR_TS1) /*!< 16 time quantum */
-/**
- * @}
- */
-
-/** @defgroup CAN_time_quantum_in_bit_segment_2 CAN Time Quantum in Bit Segment 2
- * @{
- */
-#define CAN_BS2_1TQ (0x00000000U) /*!< 1 time quantum */
-#define CAN_BS2_2TQ ((uint32_t)CAN_BTR_TS2_0) /*!< 2 time quantum */
-#define CAN_BS2_3TQ ((uint32_t)CAN_BTR_TS2_1) /*!< 3 time quantum */
-#define CAN_BS2_4TQ ((uint32_t)(CAN_BTR_TS2_1 | CAN_BTR_TS2_0)) /*!< 4 time quantum */
-#define CAN_BS2_5TQ ((uint32_t)CAN_BTR_TS2_2) /*!< 5 time quantum */
-#define CAN_BS2_6TQ ((uint32_t)(CAN_BTR_TS2_2 | CAN_BTR_TS2_0)) /*!< 6 time quantum */
-#define CAN_BS2_7TQ ((uint32_t)(CAN_BTR_TS2_2 | CAN_BTR_TS2_1)) /*!< 7 time quantum */
-#define CAN_BS2_8TQ ((uint32_t)CAN_BTR_TS2) /*!< 8 time quantum */
-/**
- * @}
- */
-
-/** @defgroup CAN_filter_mode CAN Filter Mode
- * @{
- */
-#define CAN_FILTERMODE_IDMASK (0x00000000U) /*!< Identifier mask mode */
-#define CAN_FILTERMODE_IDLIST (0x00000001U) /*!< Identifier list mode */
-/**
- * @}
- */
-
-/** @defgroup CAN_filter_scale CAN Filter Scale
- * @{
- */
-#define CAN_FILTERSCALE_16BIT (0x00000000U) /*!< Two 16-bit filters */
-#define CAN_FILTERSCALE_32BIT (0x00000001U) /*!< One 32-bit filter */
-/**
- * @}
- */
-
-/** @defgroup CAN_filter_activation CAN Filter Activation
- * @{
- */
-#define CAN_FILTER_DISABLE (0x00000000U) /*!< Disable filter */
-#define CAN_FILTER_ENABLE (0x00000001U) /*!< Enable filter */
-/**
- * @}
- */
-
-/** @defgroup CAN_filter_FIFO CAN Filter FIFO
- * @{
- */
-#define CAN_FILTER_FIFO0 (0x00000000U) /*!< Filter FIFO 0 assignment for filter x */
-#define CAN_FILTER_FIFO1 (0x00000001U) /*!< Filter FIFO 1 assignment for filter x */
-/**
- * @}
- */
-
-/** @defgroup CAN_identifier_type CAN Identifier Type
- * @{
- */
-#define CAN_ID_STD (0x00000000U) /*!< Standard Id */
-#define CAN_ID_EXT (0x00000004U) /*!< Extended Id */
-/**
- * @}
- */
-
-/** @defgroup CAN_remote_transmission_request CAN Remote Transmission Request
- * @{
- */
-#define CAN_RTR_DATA (0x00000000U) /*!< Data frame */
-#define CAN_RTR_REMOTE (0x00000002U) /*!< Remote frame */
-/**
- * @}
- */
-
-/** @defgroup CAN_receive_FIFO_number CAN Receive FIFO Number
- * @{
- */
-#define CAN_RX_FIFO0 (0x00000000U) /*!< CAN receive FIFO 0 */
-#define CAN_RX_FIFO1 (0x00000001U) /*!< CAN receive FIFO 1 */
-/**
- * @}
- */
-
-/** @defgroup CAN_Tx_Mailboxes CAN Tx Mailboxes
- * @{
- */
-#define CAN_TX_MAILBOX0 (0x00000001U) /*!< Tx Mailbox 0 */
-#define CAN_TX_MAILBOX1 (0x00000002U) /*!< Tx Mailbox 1 */
-#define CAN_TX_MAILBOX2 (0x00000004U) /*!< Tx Mailbox 2 */
-/**
- * @}
- */
-
-/** @defgroup CAN_flags CAN Flags
- * @{
- */
-/* Transmit Flags */
-#define CAN_FLAG_RQCP0 (0x00000500U) /*!< Request complete MailBox 0 flag */
-#define CAN_FLAG_TXOK0 (0x00000501U) /*!< Transmission OK MailBox 0 flag */
-#define CAN_FLAG_ALST0 (0x00000502U) /*!< Arbitration Lost MailBox 0 flag */
-#define CAN_FLAG_TERR0 (0x00000503U) /*!< Transmission error MailBox 0 flag */
-#define CAN_FLAG_RQCP1 (0x00000508U) /*!< Request complete MailBox1 flag */
-#define CAN_FLAG_TXOK1 (0x00000509U) /*!< Transmission OK MailBox 1 flag */
-#define CAN_FLAG_ALST1 (0x0000050AU) /*!< Arbitration Lost MailBox 1 flag */
-#define CAN_FLAG_TERR1 (0x0000050BU) /*!< Transmission error MailBox 1 flag */
-#define CAN_FLAG_RQCP2 (0x00000510U) /*!< Request complete MailBox2 flag */
-#define CAN_FLAG_TXOK2 (0x00000511U) /*!< Transmission OK MailBox 2 flag */
-#define CAN_FLAG_ALST2 (0x00000512U) /*!< Arbitration Lost MailBox 2 flag */
-#define CAN_FLAG_TERR2 (0x00000513U) /*!< Transmission error MailBox 2 flag */
-#define CAN_FLAG_TME0 (0x0000051AU) /*!< Transmit mailbox 0 empty flag */
-#define CAN_FLAG_TME1 (0x0000051BU) /*!< Transmit mailbox 1 empty flag */
-#define CAN_FLAG_TME2 (0x0000051CU) /*!< Transmit mailbox 2 empty flag */
-#define CAN_FLAG_LOW0 (0x0000051DU) /*!< Lowest priority mailbox 0 flag */
-#define CAN_FLAG_LOW1 (0x0000051EU) /*!< Lowest priority mailbox 1 flag */
-#define CAN_FLAG_LOW2 (0x0000051FU) /*!< Lowest priority mailbox 2 flag */
-
-/* Receive Flags */
-#define CAN_FLAG_FF0 (0x00000203U) /*!< RX FIFO 0 Full flag */
-#define CAN_FLAG_FOV0 (0x00000204U) /*!< RX FIFO 0 Overrun flag */
-#define CAN_FLAG_FF1 (0x00000403U) /*!< RX FIFO 1 Full flag */
-#define CAN_FLAG_FOV1 (0x00000404U) /*!< RX FIFO 1 Overrun flag */
-
-/* Operating Mode Flags */
-#define CAN_FLAG_INAK (0x00000100U) /*!< Initialization acknowledge flag */
-#define CAN_FLAG_SLAK (0x00000101U) /*!< Sleep acknowledge flag */
-#define CAN_FLAG_ERRI (0x00000102U) /*!< Error flag */
-#define CAN_FLAG_WKU (0x00000103U) /*!< Wake up interrupt flag */
-#define CAN_FLAG_SLAKI (0x00000104U) /*!< Sleep acknowledge interrupt flag */
-
-/* Error Flags */
-#define CAN_FLAG_EWG (0x00000300U) /*!< Error warning flag */
-#define CAN_FLAG_EPV (0x00000301U) /*!< Error passive flag */
-#define CAN_FLAG_BOF (0x00000302U) /*!< Bus-Off flag */
-/**
- * @}
- */
-
-
-/** @defgroup CAN_Interrupts CAN Interrupts
- * @{
- */
-/* Transmit Interrupt */
-#define CAN_IT_TX_MAILBOX_EMPTY ((uint32_t)CAN_IER_TMEIE) /*!< Transmit mailbox empty interrupt */
-
-/* Receive Interrupts */
-#define CAN_IT_RX_FIFO0_MSG_PENDING ((uint32_t)CAN_IER_FMPIE0) /*!< FIFO 0 message pending interrupt */
-#define CAN_IT_RX_FIFO0_FULL ((uint32_t)CAN_IER_FFIE0) /*!< FIFO 0 full interrupt */
-#define CAN_IT_RX_FIFO0_OVERRUN ((uint32_t)CAN_IER_FOVIE0) /*!< FIFO 0 overrun interrupt */
-#define CAN_IT_RX_FIFO1_MSG_PENDING ((uint32_t)CAN_IER_FMPIE1) /*!< FIFO 1 message pending interrupt */
-#define CAN_IT_RX_FIFO1_FULL ((uint32_t)CAN_IER_FFIE1) /*!< FIFO 1 full interrupt */
-#define CAN_IT_RX_FIFO1_OVERRUN ((uint32_t)CAN_IER_FOVIE1) /*!< FIFO 1 overrun interrupt */
-
-/* Operating Mode Interrupts */
-#define CAN_IT_WAKEUP ((uint32_t)CAN_IER_WKUIE) /*!< Wake-up interrupt */
-#define CAN_IT_SLEEP_ACK ((uint32_t)CAN_IER_SLKIE) /*!< Sleep acknowledge interrupt */
-
-/* Error Interrupts */
-#define CAN_IT_ERROR_WARNING ((uint32_t)CAN_IER_EWGIE) /*!< Error warning interrupt */
-#define CAN_IT_ERROR_PASSIVE ((uint32_t)CAN_IER_EPVIE) /*!< Error passive interrupt */
-#define CAN_IT_BUSOFF ((uint32_t)CAN_IER_BOFIE) /*!< Bus-off interrupt */
-#define CAN_IT_LAST_ERROR_CODE ((uint32_t)CAN_IER_LECIE) /*!< Last error code interrupt */
-#define CAN_IT_ERROR ((uint32_t)CAN_IER_ERRIE) /*!< Error Interrupt */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macros -----------------------------------------------------------*/
-/** @defgroup CAN_Exported_Macros CAN Exported Macros
- * @{
- */
-
-/** @brief Reset CAN handle state
- * @param __HANDLE__ CAN handle.
- * @retval None
- */
-#define __HAL_CAN_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_CAN_STATE_RESET)
-
-/**
- * @brief Enable the specified CAN interrupts.
- * @param __HANDLE__ CAN handle.
- * @param __INTERRUPT__ CAN Interrupt sources to enable.
- * This parameter can be any combination of @arg CAN_Interrupts
- * @retval None
- */
-#define __HAL_CAN_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) |= (__INTERRUPT__))
-
-/**
- * @brief Disable the specified CAN interrupts.
- * @param __HANDLE__ CAN handle.
- * @param __INTERRUPT__ CAN Interrupt sources to disable.
- * This parameter can be any combination of @arg CAN_Interrupts
- * @retval None
- */
-#define __HAL_CAN_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) &= ~(__INTERRUPT__))
-
-/** @brief Check if the specified CAN interrupt source is enabled or disabled.
- * @param __HANDLE__ specifies the CAN Handle.
- * @param __INTERRUPT__ specifies the CAN interrupt source to check.
- * This parameter can be a value of @arg CAN_Interrupts
- * @retval The state of __IT__ (TRUE or FALSE).
- */
-#define __HAL_CAN_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) & (__INTERRUPT__))
-
-/** @brief Check whether the specified CAN flag is set or not.
- * @param __HANDLE__ specifies the CAN Handle.
- * @param __FLAG__ specifies the flag to check.
- * This parameter can be one of @arg CAN_flags
- * @retval The state of __FLAG__ (TRUE or FALSE).
- */
-#define __HAL_CAN_GET_FLAG(__HANDLE__, __FLAG__) \
- ((((__FLAG__) >> 8U) == 5U)? ((((__HANDLE__)->Instance->TSR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
- (((__FLAG__) >> 8U) == 2U)? ((((__HANDLE__)->Instance->RF0R) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
- (((__FLAG__) >> 8U) == 4U)? ((((__HANDLE__)->Instance->RF1R) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
- (((__FLAG__) >> 8U) == 1U)? ((((__HANDLE__)->Instance->MSR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
- (((__FLAG__) >> 8U) == 3U)? ((((__HANDLE__)->Instance->ESR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): 0U)
-
-/** @brief Clear the specified CAN pending flag.
- * @param __HANDLE__ specifies the CAN Handle.
- * @param __FLAG__ specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg CAN_FLAG_RQCP0: Request complete MailBox 0 Flag
- * @arg CAN_FLAG_TXOK0: Transmission OK MailBox 0 Flag
- * @arg CAN_FLAG_ALST0: Arbitration Lost MailBox 0 Flag
- * @arg CAN_FLAG_TERR0: Transmission error MailBox 0 Flag
- * @arg CAN_FLAG_RQCP1: Request complete MailBox 1 Flag
- * @arg CAN_FLAG_TXOK1: Transmission OK MailBox 1 Flag
- * @arg CAN_FLAG_ALST1: Arbitration Lost MailBox 1 Flag
- * @arg CAN_FLAG_TERR1: Transmission error MailBox 1 Flag
- * @arg CAN_FLAG_RQCP2: Request complete MailBox 2 Flag
- * @arg CAN_FLAG_TXOK2: Transmission OK MailBox 2 Flag
- * @arg CAN_FLAG_ALST2: Arbitration Lost MailBox 2 Flag
- * @arg CAN_FLAG_TERR2: Transmission error MailBox 2 Flag
- * @arg CAN_FLAG_FF0: RX FIFO 0 Full Flag
- * @arg CAN_FLAG_FOV0: RX FIFO 0 Overrun Flag
- * @arg CAN_FLAG_FF1: RX FIFO 1 Full Flag
- * @arg CAN_FLAG_FOV1: RX FIFO 1 Overrun Flag
- * @arg CAN_FLAG_WKUI: Wake up Interrupt Flag
- * @arg CAN_FLAG_SLAKI: Sleep acknowledge Interrupt Flag
- * @retval None
- */
-#define __HAL_CAN_CLEAR_FLAG(__HANDLE__, __FLAG__) \
- ((((__FLAG__) >> 8U) == 5U)? (((__HANDLE__)->Instance->TSR) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
- (((__FLAG__) >> 8U) == 2U)? (((__HANDLE__)->Instance->RF0R) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
- (((__FLAG__) >> 8U) == 4U)? (((__HANDLE__)->Instance->RF1R) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
- (((__FLAG__) >> 8U) == 1U)? (((__HANDLE__)->Instance->MSR) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): 0U)
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup CAN_Exported_Functions CAN Exported Functions
- * @{
- */
-
-/** @addtogroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- * @{
- */
-
-/* Initialization and de-initialization functions *****************************/
-HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef *hcan);
-HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef *hcan);
-void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan);
-void HAL_CAN_MspDeInit(CAN_HandleTypeDef *hcan);
-
-/**
- * @}
- */
-
-/** @addtogroup CAN_Exported_Functions_Group2 Configuration functions
- * @brief Configuration functions
- * @{
- */
-
-/* Configuration functions ****************************************************/
-HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan, CAN_FilterTypeDef *sFilterConfig);
-
-/**
- * @}
- */
-
-/** @addtogroup CAN_Exported_Functions_Group3 Control functions
- * @brief Control functions
- * @{
- */
-
-/* Control functions **********************************************************/
-HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *hcan);
-HAL_StatusTypeDef HAL_CAN_Stop(CAN_HandleTypeDef *hcan);
-HAL_StatusTypeDef HAL_CAN_RequestSleep(CAN_HandleTypeDef *hcan);
-HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef *hcan);
-uint32_t HAL_CAN_IsSleepActive(CAN_HandleTypeDef *hcan);
-HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, CAN_TxHeaderTypeDef *pHeader, uint8_t aData[], uint32_t *pTxMailbox);
-HAL_StatusTypeDef HAL_CAN_AbortTxRequest(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes);
-uint32_t HAL_CAN_GetTxMailboxesFreeLevel(CAN_HandleTypeDef *hcan);
-uint32_t HAL_CAN_IsTxMessagePending(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes);
-uint32_t HAL_CAN_GetTxTimestamp(CAN_HandleTypeDef *hcan, uint32_t TxMailbox);
-HAL_StatusTypeDef HAL_CAN_GetRxMessage(CAN_HandleTypeDef *hcan, uint32_t RxFifo, CAN_RxHeaderTypeDef *pHeader, uint8_t aData[]);
-uint32_t HAL_CAN_GetRxFifoFillLevel(CAN_HandleTypeDef *hcan, uint32_t RxFifo);
-
-/**
- * @}
- */
-
-/** @addtogroup CAN_Exported_Functions_Group4 Interrupts management
- * @brief Interrupts management
- * @{
- */
-/* Interrupts management ******************************************************/
-HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan, uint32_t ActiveITs);
-HAL_StatusTypeDef HAL_CAN_DeactivateNotification(CAN_HandleTypeDef *hcan, uint32_t InactiveITs);
-void HAL_CAN_IRQHandler(CAN_HandleTypeDef *hcan);
-
-/**
- * @}
- */
-
-/** @addtogroup CAN_Exported_Functions_Group5 Callback functions
- * @brief Callback functions
- * @{
- */
-/* Callbacks functions ********************************************************/
-
-void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan);
-void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan);
-void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan);
-void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan);
-void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan);
-void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan);
-void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan);
-void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan);
-void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan);
-void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan);
-void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan);
-void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan);
-void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan);
-
-/**
- * @}
- */
-
-/** @addtogroup CAN_Exported_Functions_Group6 Peripheral State and Error functions
- * @brief CAN Peripheral State functions
- * @{
- */
-/* Peripheral State and Error functions ***************************************/
-HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef *hcan);
-uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan);
-HAL_StatusTypeDef HAL_CAN_ResetError(CAN_HandleTypeDef *hcan);
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private types -------------------------------------------------------------*/
-/** @defgroup CAN_Private_Types CAN Private Types
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private variables ---------------------------------------------------------*/
-/** @defgroup CAN_Private_Variables CAN Private Variables
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup CAN_Private_Constants CAN Private Constants
- * @{
- */
-#define CAN_FLAG_MASK (0x000000FFU)
-/**
- * @}
- */
-
-/* Private Macros -----------------------------------------------------------*/
-/** @defgroup CAN_Private_Macros CAN Private Macros
- * @{
- */
-
-#define IS_CAN_MODE(MODE) (((MODE) == CAN_MODE_NORMAL) || \
- ((MODE) == CAN_MODE_LOOPBACK)|| \
- ((MODE) == CAN_MODE_SILENT) || \
- ((MODE) == CAN_MODE_SILENT_LOOPBACK))
-#define IS_CAN_SJW(SJW) (((SJW) == CAN_SJW_1TQ) || ((SJW) == CAN_SJW_2TQ) || \
- ((SJW) == CAN_SJW_3TQ) || ((SJW) == CAN_SJW_4TQ))
-#define IS_CAN_BS1(BS1) (((BS1) == CAN_BS1_1TQ) || ((BS1) == CAN_BS1_2TQ) || \
- ((BS1) == CAN_BS1_3TQ) || ((BS1) == CAN_BS1_4TQ) || \
- ((BS1) == CAN_BS1_5TQ) || ((BS1) == CAN_BS1_6TQ) || \
- ((BS1) == CAN_BS1_7TQ) || ((BS1) == CAN_BS1_8TQ) || \
- ((BS1) == CAN_BS1_9TQ) || ((BS1) == CAN_BS1_10TQ)|| \
- ((BS1) == CAN_BS1_11TQ)|| ((BS1) == CAN_BS1_12TQ)|| \
- ((BS1) == CAN_BS1_13TQ)|| ((BS1) == CAN_BS1_14TQ)|| \
- ((BS1) == CAN_BS1_15TQ)|| ((BS1) == CAN_BS1_16TQ))
-#define IS_CAN_BS2(BS2) (((BS2) == CAN_BS2_1TQ) || ((BS2) == CAN_BS2_2TQ) || \
- ((BS2) == CAN_BS2_3TQ) || ((BS2) == CAN_BS2_4TQ) || \
- ((BS2) == CAN_BS2_5TQ) || ((BS2) == CAN_BS2_6TQ) || \
- ((BS2) == CAN_BS2_7TQ) || ((BS2) == CAN_BS2_8TQ))
-#define IS_CAN_PRESCALER(PRESCALER) (((PRESCALER) >= 1U) && ((PRESCALER) <= 1024U))
-#define IS_CAN_FILTER_ID_HALFWORD(HALFWORD) ((HALFWORD) <= 0xFFFFU)
-#if defined(CAN2)
-#define IS_CAN_FILTER_BANK_DUAL(BANK) ((BANK) <= 27U)
-#endif
-#define IS_CAN_FILTER_BANK_SINGLE(BANK) ((BANK) <= 13U)
-#define IS_CAN_FILTER_MODE(MODE) (((MODE) == CAN_FILTERMODE_IDMASK) || \
- ((MODE) == CAN_FILTERMODE_IDLIST))
-#define IS_CAN_FILTER_SCALE(SCALE) (((SCALE) == CAN_FILTERSCALE_16BIT) || \
- ((SCALE) == CAN_FILTERSCALE_32BIT))
-#define IS_CAN_FILTER_ACTIVATION(ACTIVATION) (((ACTIVATION) == CAN_FILTER_DISABLE) || \
- ((ACTIVATION) == CAN_FILTER_ENABLE))
-#define IS_CAN_FILTER_FIFO(FIFO) (((FIFO) == CAN_FILTER_FIFO0) || \
- ((FIFO) == CAN_FILTER_FIFO1))
-#define IS_CAN_TX_MAILBOX(TRANSMITMAILBOX) (((TRANSMITMAILBOX) == CAN_TX_MAILBOX0 ) || \
- ((TRANSMITMAILBOX) == CAN_TX_MAILBOX1 ) || \
- ((TRANSMITMAILBOX) == CAN_TX_MAILBOX2 ))
-#define IS_CAN_TX_MAILBOX_LIST(TRANSMITMAILBOX) ((TRANSMITMAILBOX) <= (CAN_TX_MAILBOX0 | CAN_TX_MAILBOX1 | CAN_TX_MAILBOX2))
-#define IS_CAN_STDID(STDID) ((STDID) <= 0x7FFU)
-#define IS_CAN_EXTID(EXTID) ((EXTID) <= 0x1FFFFFFFU)
-#define IS_CAN_DLC(DLC) ((DLC) <= 8U)
-#define IS_CAN_IDTYPE(IDTYPE) (((IDTYPE) == CAN_ID_STD) || \
- ((IDTYPE) == CAN_ID_EXT))
-#define IS_CAN_RTR(RTR) (((RTR) == CAN_RTR_DATA) || ((RTR) == CAN_RTR_REMOTE))
-#define IS_CAN_RX_FIFO(FIFO) (((FIFO) == CAN_RX_FIFO0) || ((FIFO) == CAN_RX_FIFO1))
-#define IS_CAN_IT(IT) ((IT) <= (CAN_IT_TX_MAILBOX_EMPTY | CAN_IT_RX_FIFO0_MSG_PENDING | \
- CAN_IT_RX_FIFO0_FULL | CAN_IT_RX_FIFO0_OVERRUN | \
- CAN_IT_RX_FIFO1_MSG_PENDING | CAN_IT_RX_FIFO1_FULL | \
- CAN_IT_RX_FIFO1_OVERRUN | CAN_IT_WAKEUP | \
- CAN_IT_SLEEP_ACK | CAN_IT_ERROR_WARNING | \
- CAN_IT_ERROR_PASSIVE | CAN_IT_BUSOFF | \
- CAN_IT_LAST_ERROR_CODE | CAN_IT_ERROR))
-
-/**
- * @}
- */
-/* End of private macros -----------------------------------------------------*/
-
-/**
- * @}
- */
-
-
-#endif /* CAN1 */
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32F1xx_HAL_CAN_H */
-
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cec.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cec.h
deleted file mode 100644
index dfd16da..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cec.h
+++ /dev/null
@@ -1,516 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_cec.h
- * @author MCD Application Team
- * @brief Header file of CEC HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_CEC_H
-#define __STM32F1xx_HAL_CEC_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-#if defined(STM32F100xB) || defined(STM32F100xE)
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup CEC
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup CEC_Exported_Types CEC Exported Types
- * @{
- */
-/**
- * @brief CEC Init Structure definition
- */
-typedef struct
-{
- uint32_t TimingErrorFree; /*!< Configures the CEC Bit Timing Error Mode.
- This parameter can be a value of @ref CEC_BitTimingErrorMode */
- uint32_t PeriodErrorFree; /*!< Configures the CEC Bit Period Error Mode.
- This parameter can be a value of @ref CEC_BitPeriodErrorMode */
- uint16_t OwnAddress; /*!< Own addresses configuration
- This parameter can be a value of @ref CEC_OWN_ADDRESS */
- uint8_t *RxBuffer; /*!< CEC Rx buffer pointeur */
-}CEC_InitTypeDef;
-
-/**
- * @brief HAL CEC State structures definition
- * @note HAL CEC State value is a combination of 2 different substates: gState and RxState.
- * - gState contains CEC state information related to global Handle management
- * and also information related to Tx operations.
- * gState value coding follow below described bitmap :
- * b7 (not used)
- * x : Should be set to 0
- * b6 Error information
- * 0 : No Error
- * 1 : Error
- * b5 IP initilisation status
- * 0 : Reset (IP not initialized)
- * 1 : Init done (IP initialized. HAL CEC Init function already called)
- * b4-b3 (not used)
- * xx : Should be set to 00
- * b2 Intrinsic process state
- * 0 : Ready
- * 1 : Busy (IP busy with some configuration or internal operations)
- * b1 (not used)
- * x : Should be set to 0
- * b0 Tx state
- * 0 : Ready (no Tx operation ongoing)
- * 1 : Busy (Tx operation ongoing)
- * - RxState contains information related to Rx operations.
- * RxState value coding follow below described bitmap :
- * b7-b6 (not used)
- * xx : Should be set to 00
- * b5 IP initilisation status
- * 0 : Reset (IP not initialized)
- * 1 : Init done (IP initialized)
- * b4-b2 (not used)
- * xxx : Should be set to 000
- * b1 Rx state
- * 0 : Ready (no Rx operation ongoing)
- * 1 : Busy (Rx operation ongoing)
- * b0 (not used)
- * x : Should be set to 0.
- */
-typedef enum
-{
- HAL_CEC_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized
- Value is allowed for gState and RxState */
- HAL_CEC_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use
- Value is allowed for gState and RxState */
- HAL_CEC_STATE_BUSY = 0x24U, /*!< an internal process is ongoing
- Value is allowed for gState only */
- HAL_CEC_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing
- Value is allowed for RxState only */
- HAL_CEC_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing
- Value is allowed for gState only */
- HAL_CEC_STATE_BUSY_RX_TX = 0x23U, /*!< an internal process is ongoing
- Value is allowed for gState only */
- HAL_CEC_STATE_ERROR = 0x60U /*!< Error Value is allowed for gState only */
-}HAL_CEC_StateTypeDef;
-
-/**
- * @brief CEC handle Structure definition
- */
-typedef struct
-{
- CEC_TypeDef *Instance; /*!< CEC registers base address */
-
- CEC_InitTypeDef Init; /*!< CEC communication parameters */
-
- uint8_t *pTxBuffPtr; /*!< Pointer to CEC Tx transfer Buffer */
-
- uint16_t TxXferCount; /*!< CEC Tx Transfer Counter */
-
- uint16_t RxXferSize; /*!< CEC Rx Transfer size, 0: header received only */
-
- HAL_LockTypeDef Lock; /*!< Locking object */
-
- HAL_CEC_StateTypeDef gState; /*!< CEC state information related to global Handle management
- and also related to Tx operations.
- This parameter can be a value of @ref HAL_CEC_StateTypeDef */
-
- HAL_CEC_StateTypeDef RxState; /*!< CEC state information related to Rx operations.
- This parameter can be a value of @ref HAL_CEC_StateTypeDef */
-
- uint32_t ErrorCode; /*!< For errors handling purposes, copy of ISR register
- in case error is reported */
-}CEC_HandleTypeDef;
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup CEC_Exported_Constants CEC Exported Constants
- * @{
- */
-
-/** @defgroup CEC_Error_Code CEC Error Code
- * @{
- */
-#define HAL_CEC_ERROR_NONE 0x00000000U /*!< no error */
-#define HAL_CEC_ERROR_BTE CEC_ESR_BTE /*!< Bit Timing Error */
-#define HAL_CEC_ERROR_BPE CEC_ESR_BPE /*!< Bit Period Error */
-#define HAL_CEC_ERROR_RBTFE CEC_ESR_RBTFE /*!< Rx Block Transfer Finished Error */
-#define HAL_CEC_ERROR_SBE CEC_ESR_SBE /*!< Start Bit Error */
-#define HAL_CEC_ERROR_ACKE CEC_ESR_ACKE /*!< Block Acknowledge Error */
-#define HAL_CEC_ERROR_LINE CEC_ESR_LINE /*!< Line Error */
-#define HAL_CEC_ERROR_TBTFE CEC_ESR_TBTFE /*!< Tx Block Transfer Finished Error */
-/**
- * @}
- */
-
-/** @defgroup CEC_BitTimingErrorMode Bit Timing Error Mode
- * @{
- */
-#define CEC_BIT_TIMING_ERROR_MODE_STANDARD 0x00000000U /*!< Bit timing error Standard Mode */
-#define CEC_BIT_TIMING_ERROR_MODE_ERRORFREE CEC_CFGR_BTEM /*!< Bit timing error Free Mode */
-/**
- * @}
- */
-
-/** @defgroup CEC_BitPeriodErrorMode Bit Period Error Mode
- * @{
- */
-#define CEC_BIT_PERIOD_ERROR_MODE_STANDARD 0x00000000U /*!< Bit period error Standard Mode */
-#define CEC_BIT_PERIOD_ERROR_MODE_FLEXIBLE CEC_CFGR_BPEM /*!< Bit period error Flexible Mode */
-/**
- * @}
- */
-
-/** @defgroup CEC_Initiator_Position CEC Initiator logical address position in message header
- * @{
- */
-#define CEC_INITIATOR_LSB_POS 4U
-/**
- * @}
- */
-
-/** @defgroup CEC_OWN_ADDRESS CEC Own Address
- * @{
- */
-#define CEC_OWN_ADDRESS_NONE CEC_OWN_ADDRESS_0 /* Reset value */
-#define CEC_OWN_ADDRESS_0 ((uint16_t)0x0000U) /* Logical Address 0 */
-#define CEC_OWN_ADDRESS_1 ((uint16_t)0x0001U) /* Logical Address 1 */
-#define CEC_OWN_ADDRESS_2 ((uint16_t)0x0002U) /* Logical Address 2 */
-#define CEC_OWN_ADDRESS_3 ((uint16_t)0x0003U) /* Logical Address 3 */
-#define CEC_OWN_ADDRESS_4 ((uint16_t)0x0004U) /* Logical Address 4 */
-#define CEC_OWN_ADDRESS_5 ((uint16_t)0x0005U) /* Logical Address 5 */
-#define CEC_OWN_ADDRESS_6 ((uint16_t)0x0006U) /* Logical Address 6 */
-#define CEC_OWN_ADDRESS_7 ((uint16_t)0x0007U) /* Logical Address 7 */
-#define CEC_OWN_ADDRESS_8 ((uint16_t)0x0008U) /* Logical Address 8 */
-#define CEC_OWN_ADDRESS_9 ((uint16_t)0x0009U) /* Logical Address 9 */
-#define CEC_OWN_ADDRESS_10 ((uint16_t)0x000AU) /* Logical Address 10 */
-#define CEC_OWN_ADDRESS_11 ((uint16_t)0x000BU) /* Logical Address 11 */
-#define CEC_OWN_ADDRESS_12 ((uint16_t)0x000CU) /* Logical Address 12 */
-#define CEC_OWN_ADDRESS_13 ((uint16_t)0x000DU) /* Logical Address 13 */
-#define CEC_OWN_ADDRESS_14 ((uint16_t)0x000EU) /* Logical Address 14 */
-#define CEC_OWN_ADDRESS_15 ((uint16_t)0x000FU) /* Logical Address 15 */
-/**
- * @}
- */
-
-/** @defgroup CEC_Interrupts_Definitions Interrupts definition
- * @{
- */
-#define CEC_IT_IE CEC_CFGR_IE
-/**
- * @}
- */
-
-/** @defgroup CEC_Flags_Definitions Flags definition
- * @{
- */
-#define CEC_FLAG_TSOM CEC_CSR_TSOM
-#define CEC_FLAG_TEOM CEC_CSR_TEOM
-#define CEC_FLAG_TERR CEC_CSR_TERR
-#define CEC_FLAG_TBTRF CEC_CSR_TBTRF
-#define CEC_FLAG_RSOM CEC_CSR_RSOM
-#define CEC_FLAG_REOM CEC_CSR_REOM
-#define CEC_FLAG_RERR CEC_CSR_RERR
-#define CEC_FLAG_RBTF CEC_CSR_RBTF
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macros -----------------------------------------------------------*/
-/** @defgroup CEC_Exported_Macros CEC Exported Macros
- * @{
- */
-
-/** @brief Reset CEC handle gstate & RxState
- * @param __HANDLE__: CEC handle.
- * @retval None
- */
-#define __HAL_CEC_RESET_HANDLE_STATE(__HANDLE__) do{ \
- (__HANDLE__)->gState = HAL_CEC_STATE_RESET; \
- (__HANDLE__)->RxState = HAL_CEC_STATE_RESET; \
- } while(0U)
-
-/** @brief Checks whether or not the specified CEC interrupt flag is set.
- * @param __HANDLE__: specifies the CEC Handle.
- * @param __FLAG__: specifies the flag to check.
- * @arg CEC_FLAG_TERR: Tx Error
- * @arg CEC_FLAG_TBTRF:Tx Block Transfer Finished
- * @arg CEC_FLAG_RERR: Rx Error
- * @arg CEC_FLAG_RBTF: Rx Block Transfer Finished
- * @retval ITStatus
- */
-#define __HAL_CEC_GET_FLAG(__HANDLE__, __FLAG__) READ_BIT((__HANDLE__)->Instance->CSR,(__FLAG__))
-
-/** @brief Clears the CEC's pending flags.
- * @param __HANDLE__: specifies the CEC Handle.
- * @param __FLAG__: specifies the flag to clear.
- * This parameter can be any combination of the following values:
- * @arg CEC_CSR_TERR: Tx Error
- * @arg CEC_FLAG_TBTRF: Tx Block Transfer Finished
- * @arg CEC_CSR_RERR: Rx Error
- * @arg CEC_CSR_RBTF: Rx Block Transfer Finished
- * @retval none
- */
-#define __HAL_CEC_CLEAR_FLAG(__HANDLE__, __FLAG__) \
- do { \
- uint32_t tmp = 0x0U; \
- tmp = (__HANDLE__)->Instance->CSR & 0x00000002U; \
- (__HANDLE__)->Instance->CSR &= (uint32_t)(((~(uint32_t)(__FLAG__)) & 0xFFFFFFFCU) | tmp);\
- } while(0U)
-
-/** @brief Enables the specified CEC interrupt.
- * @param __HANDLE__: specifies the CEC Handle.
- * @param __INTERRUPT__: specifies the CEC interrupt to enable.
- * This parameter can be:
- * @arg CEC_IT_IE : Interrupt Enable.
- * @retval none
- */
-#define __HAL_CEC_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->CFGR, (__INTERRUPT__))
-
-/** @brief Disables the specified CEC interrupt.
- * @param __HANDLE__: specifies the CEC Handle.
- * @param __INTERRUPT__: specifies the CEC interrupt to disable.
- * This parameter can be:
- * @arg CEC_IT_IE : Interrupt Enable
- * @retval none
- */
-#define __HAL_CEC_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT((__HANDLE__)->Instance->CFGR, (__INTERRUPT__))
-
-/** @brief Checks whether or not the specified CEC interrupt is enabled.
- * @param __HANDLE__: specifies the CEC Handle.
- * @param __INTERRUPT__: specifies the CEC interrupt to check.
- * This parameter can be:
- * @arg CEC_IT_IE : Interrupt Enable
- * @retval FlagStatus
- */
-#define __HAL_CEC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) READ_BIT((__HANDLE__)->Instance->CFGR, (__INTERRUPT__))
-
-/** @brief Enables the CEC device
- * @param __HANDLE__: specifies the CEC Handle.
- * @retval none
- */
-#define __HAL_CEC_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CFGR, CEC_CFGR_PE)
-
-/** @brief Disables the CEC device
- * @param __HANDLE__: specifies the CEC Handle.
- * @retval none
- */
-#define __HAL_CEC_DISABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CFGR, CEC_CFGR_PE)
-
-/** @brief Set Transmission Start flag
- * @param __HANDLE__: specifies the CEC Handle.
- * @retval none
- */
-#define __HAL_CEC_FIRST_BYTE_TX_SET(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CSR, CEC_CSR_TSOM)
-
-/** @brief Set Transmission End flag
- * @param __HANDLE__: specifies the CEC Handle.
- * @retval none
- */
-#define __HAL_CEC_LAST_BYTE_TX_SET(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CSR, CEC_CSR_TEOM)
-
-/** @brief Get Transmission Start flag
- * @param __HANDLE__: specifies the CEC Handle.
- * @retval FlagStatus
- */
-#define __HAL_CEC_GET_TRANSMISSION_START_FLAG(__HANDLE__) READ_BIT((__HANDLE__)->Instance->CSR, CEC_CSR_TSOM)
-
-/** @brief Get Transmission End flag
- * @param __HANDLE__: specifies the CEC Handle.
- * @retval FlagStatus
- */
-#define __HAL_CEC_GET_TRANSMISSION_END_FLAG(__HANDLE__) READ_BIT((__HANDLE__)->Instance->CSR, CEC_CSR_TEOM)
-
-/** @brief Clear OAR register
- * @param __HANDLE__: specifies the CEC Handle.
- * @retval none
- */
-#define __HAL_CEC_CLEAR_OAR(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->OAR, CEC_OAR_OA)
-
-/** @brief Set OAR register
- * @param __HANDLE__: specifies the CEC Handle.
- * @param __ADDRESS__: Own Address value.
- * @retval none
- */
-#define __HAL_CEC_SET_OAR(__HANDLE__,__ADDRESS__) MODIFY_REG((__HANDLE__)->Instance->OAR, CEC_OAR_OA, (__ADDRESS__));
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup CEC_Exported_Functions CEC Exported Functions
- * @{
- */
-
-/** @addtogroup CEC_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- * @{
- */
-/* Initialization and de-initialization functions ****************************/
-HAL_StatusTypeDef HAL_CEC_Init(CEC_HandleTypeDef *hcec);
-HAL_StatusTypeDef HAL_CEC_DeInit(CEC_HandleTypeDef *hcec);
-HAL_StatusTypeDef HAL_CEC_SetDeviceAddress(CEC_HandleTypeDef *hcec, uint16_t CEC_OwnAddress);
-void HAL_CEC_MspInit(CEC_HandleTypeDef *hcec);
-void HAL_CEC_MspDeInit(CEC_HandleTypeDef *hcec);
-/**
- * @}
- */
-
-/** @addtogroup CEC_Exported_Functions_Group2 Input and Output operation functions
- * @brief CEC Transmit/Receive functions
- * @{
- */
-/* I/O operation functions ***************************************************/
-HAL_StatusTypeDef HAL_CEC_Transmit_IT(CEC_HandleTypeDef *hcec, uint8_t InitiatorAddress,uint8_t DestinationAddress, uint8_t *pData, uint32_t Size);
-uint32_t HAL_CEC_GetLastReceivedFrameSize(CEC_HandleTypeDef *hcec);
-void HAL_CEC_ChangeRxBuffer(CEC_HandleTypeDef *hcec, uint8_t* Rxbuffer);
-void HAL_CEC_IRQHandler(CEC_HandleTypeDef *hcec);
-void HAL_CEC_TxCpltCallback(CEC_HandleTypeDef *hcec);
-void HAL_CEC_RxCpltCallback(CEC_HandleTypeDef *hcec, uint32_t RxFrameSize);
-void HAL_CEC_ErrorCallback(CEC_HandleTypeDef *hcec);
-/**
- * @}
- */
-
-/** @defgroup CEC_Exported_Functions_Group3 Peripheral Control functions
- * @brief CEC control functions
- * @{
- */
-/* Peripheral State and Error functions ***************************************/
-HAL_CEC_StateTypeDef HAL_CEC_GetState(CEC_HandleTypeDef *hcec);
-uint32_t HAL_CEC_GetError(CEC_HandleTypeDef *hcec);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private types -------------------------------------------------------------*/
-/** @defgroup CEC_Private_Types CEC Private Types
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private variables ---------------------------------------------------------*/
-/** @defgroup CEC_Private_Variables CEC Private Variables
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup CEC_Private_Constants CEC Private Constants
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup CEC_Private_Macros CEC Private Macros
- * @{
- */
-#define IS_CEC_BIT_TIMING_ERROR_MODE(MODE) (((MODE) == CEC_BIT_TIMING_ERROR_MODE_STANDARD) || \
- ((MODE) == CEC_BIT_TIMING_ERROR_MODE_ERRORFREE))
-
-#define IS_CEC_BIT_PERIOD_ERROR_MODE(MODE) (((MODE) == CEC_BIT_PERIOD_ERROR_MODE_STANDARD) || \
- ((MODE) == CEC_BIT_PERIOD_ERROR_MODE_FLEXIBLE))
-
-/** @brief Check CEC message size.
- * The message size is the payload size: without counting the header,
- * it varies from 0 byte (ping operation, one header only, no payload) to
- * 15 bytes (1 opcode and up to 14 operands following the header).
- * @param __SIZE__: CEC message size.
- * @retval Test result (TRUE or FALSE).
- */
-#define IS_CEC_MSGSIZE(__SIZE__) ((__SIZE__) <= 0x10U)
-/** @brief Check CEC device Own Address Register (OAR) setting.
- * @param __ADDRESS__: CEC own address.
- * @retval Test result (TRUE or FALSE).
- */
-#define IS_CEC_OWN_ADDRESS(__ADDRESS__) ((__ADDRESS__) <= 0x0000000FU)
-
-/** @brief Check CEC initiator or destination logical address setting.
- * Initiator and destination addresses are coded over 4 bits.
- * @param __ADDRESS__: CEC initiator or logical address.
- * @retval Test result (TRUE or FALSE).
- */
-#define IS_CEC_ADDRESS(__ADDRESS__) ((__ADDRESS__) <= 0x0000000FU)
-
-
-
-/**
- * @}
- */
-/* Private functions ---------------------------------------------------------*/
-/** @defgroup CEC_Private_Functions CEC Private Functions
- * @{
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-#endif /* defined(STM32F100xB) || defined(STM32F100xE) */
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_CEC_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_conf_template.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_conf_template.h
deleted file mode 100644
index ce39019..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_conf_template.h
+++ /dev/null
@@ -1,386 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_conf.h
- * @author MCD Application Team
- * @brief HAL configuration template file.
- * This file should be copied to the application folder and renamed
- * to stm32f1xx_hal_conf.h.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_CONF_H
-#define __STM32F1xx_HAL_CONF_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Exported types ------------------------------------------------------------*/
-/* Exported constants --------------------------------------------------------*/
-
-/* ########################## Module Selection ############################## */
-/**
- * @brief This is the list of modules to be used in the HAL driver
- */
-#define HAL_MODULE_ENABLED
-#define HAL_ADC_MODULE_ENABLED
-#define HAL_CAN_MODULE_ENABLED
-/* #define HAL_CAN_LEGACY_MODULE_ENABLED */
-#define HAL_CEC_MODULE_ENABLED
-#define HAL_CORTEX_MODULE_ENABLED
-#define HAL_CRC_MODULE_ENABLED
-#define HAL_DAC_MODULE_ENABLED
-#define HAL_DMA_MODULE_ENABLED
-#define HAL_ETH_MODULE_ENABLED
-#define HAL_FLASH_MODULE_ENABLED
-#define HAL_GPIO_MODULE_ENABLED
-#define HAL_HCD_MODULE_ENABLED
-#define HAL_I2C_MODULE_ENABLED
-#define HAL_I2S_MODULE_ENABLED
-#define HAL_IRDA_MODULE_ENABLED
-#define HAL_IWDG_MODULE_ENABLED
-#define HAL_NAND_MODULE_ENABLED
-#define HAL_NOR_MODULE_ENABLED
-#define HAL_PCCARD_MODULE_ENABLED
-#define HAL_PCD_MODULE_ENABLED
-#define HAL_PWR_MODULE_ENABLED
-#define HAL_RCC_MODULE_ENABLED
-#define HAL_RTC_MODULE_ENABLED
-#define HAL_SD_MODULE_ENABLED
-#define HAL_SMARTCARD_MODULE_ENABLED
-#define HAL_SPI_MODULE_ENABLED
-#define HAL_SRAM_MODULE_ENABLED
-#define HAL_TIM_MODULE_ENABLED
-#define HAL_UART_MODULE_ENABLED
-#define HAL_USART_MODULE_ENABLED
-#define HAL_WWDG_MODULE_ENABLED
-#define HAL_MMC_MODULE_ENABLED
-
-/* ########################## Oscillator Values adaptation ####################*/
-/**
- * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
- * This value is used by the RCC HAL module to compute the system frequency
- * (when HSE is used as system clock source, directly or through the PLL).
- */
-#if !defined (HSE_VALUE)
-#if defined(USE_STM3210C_EVAL)
-#define HSE_VALUE 25000000U /*!< Value of the External oscillator in Hz */
-#else
-#define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */
-#endif
-#endif /* HSE_VALUE */
-
-#if !defined (HSE_STARTUP_TIMEOUT)
-#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */
-#endif /* HSE_STARTUP_TIMEOUT */
-
-/**
- * @brief Internal High Speed oscillator (HSI) value.
- * This value is used by the RCC HAL module to compute the system frequency
- * (when HSI is used as system clock source, directly or through the PLL).
- */
-#if !defined (HSI_VALUE)
-#define HSI_VALUE 8000000U /*!< Value of the Internal oscillator in Hz */
-#endif /* HSI_VALUE */
-
-/**
- * @brief Internal Low Speed oscillator (LSI) value.
- */
-#if !defined (LSI_VALUE)
-#define LSI_VALUE 32000U /*!< LSI Typical Value in Hz */
-#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
- The real value may vary depending on the variations
- in voltage and temperature. */
-/**
- * @brief External Low Speed oscillator (LSE) value.
- * This value is used by the UART, RTC HAL module to compute the system frequency
- */
-#if !defined (LSE_VALUE)
-#define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */
-#endif /* LSE_VALUE */
-
-#if !defined (LSE_STARTUP_TIMEOUT)
-#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */
-#endif /* LSE_STARTUP_TIMEOUT */
-
-/* Tip: To avoid modifying this file each time you need to use different HSE,
- === you can define the HSE value in your toolchain compiler preprocessor. */
-
-/* ########################### System Configuration ######################### */
-/**
- * @brief This is the HAL system configuration section
- */
-#define VDD_VALUE 3300U /*!< Value of VDD in mv */
-#define TICK_INT_PRIORITY 0x0FU /*!< tick interrupt priority */
-#define USE_RTOS 0U
-#define PREFETCH_ENABLE 1U
-
-/* ########################## Assert Selection ############################## */
-/**
- * @brief Uncomment the line below to expanse the "assert_param" macro in the
- * HAL drivers code
- */
-/* #define USE_FULL_ASSERT 1U */
-
-/* ################## Ethernet peripheral configuration ##################### */
-
-/* Section 1 : Ethernet peripheral configuration */
-
-/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
-#define MAC_ADDR0 2U
-#define MAC_ADDR1 0U
-#define MAC_ADDR2 0U
-#define MAC_ADDR3 0U
-#define MAC_ADDR4 0U
-#define MAC_ADDR5 0U
-
-/* Definition of the Ethernet driver buffers size and count */
-#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
-#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
-#define ETH_RXBUFNB 8U /* 8 Rx buffers of size ETH_RX_BUF_SIZE */
-#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
-
-/* Section 2: PHY configuration section */
-
-/* DP83848 PHY Address*/
-#define DP83848_PHY_ADDRESS 0x01U
-/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
-#define PHY_RESET_DELAY 0x000000FFU
-/* PHY Configuration delay */
-#define PHY_CONFIG_DELAY 0x00000FFFU
-
-#define PHY_READ_TO 0x0000FFFFU
-#define PHY_WRITE_TO 0x0000FFFFU
-
-/* Section 3: Common PHY Registers */
-
-#define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */
-#define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */
-
-#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */
-#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */
-#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */
-#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */
-#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */
-#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */
-#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */
-#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */
-#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */
-#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */
-
-#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */
-#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */
-#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */
-
-/* Section 4: Extended PHY Registers */
-
-#define PHY_SR ((uint16_t)0x0010) /*!< PHY status register Offset */
-#define PHY_MICR ((uint16_t)0x0011) /*!< MII Interrupt Control Register */
-#define PHY_MISR ((uint16_t)0x0012) /*!< MII Interrupt Status and Misc. Control Register */
-
-#define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */
-#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */
-#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */
-
-#define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */
-#define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */
-
-#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */
-#define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */
-
-/* ################## SPI peripheral configuration ########################## */
-
-/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
-* Activated: CRC code is present inside driver
-* Deactivated: CRC code cleaned from driver
-*/
-
-#define USE_SPI_CRC 1U
-
-/* Includes ------------------------------------------------------------------*/
-/**
- * @brief Include module's header file
- */
-
-#ifdef HAL_RCC_MODULE_ENABLED
-#include "stm32f1xx_hal_rcc.h"
-#endif /* HAL_RCC_MODULE_ENABLED */
-
-#ifdef HAL_GPIO_MODULE_ENABLED
-#include "stm32f1xx_hal_gpio.h"
-#endif /* HAL_GPIO_MODULE_ENABLED */
-
-#ifdef HAL_DMA_MODULE_ENABLED
-#include "stm32f1xx_hal_dma.h"
-#endif /* HAL_DMA_MODULE_ENABLED */
-
-#ifdef HAL_ETH_MODULE_ENABLED
-#include "stm32f1xx_hal_eth.h"
-#endif /* HAL_ETH_MODULE_ENABLED */
-
-#ifdef HAL_CAN_MODULE_ENABLED
-#include "stm32f1xx_hal_can.h"
-#endif /* HAL_CAN_MODULE_ENABLED */
-
-#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
- #include "Legacy/stm32f1xx_hal_can_legacy.h"
-#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
-
-#ifdef HAL_CEC_MODULE_ENABLED
-#include "stm32f1xx_hal_cec.h"
-#endif /* HAL_CEC_MODULE_ENABLED */
-
-#ifdef HAL_CORTEX_MODULE_ENABLED
-#include "stm32f1xx_hal_cortex.h"
-#endif /* HAL_CORTEX_MODULE_ENABLED */
-
-#ifdef HAL_ADC_MODULE_ENABLED
-#include "stm32f1xx_hal_adc.h"
-#endif /* HAL_ADC_MODULE_ENABLED */
-
-#ifdef HAL_CRC_MODULE_ENABLED
-#include "stm32f1xx_hal_crc.h"
-#endif /* HAL_CRC_MODULE_ENABLED */
-
-#ifdef HAL_DAC_MODULE_ENABLED
-#include "stm32f1xx_hal_dac.h"
-#endif /* HAL_DAC_MODULE_ENABLED */
-
-#ifdef HAL_FLASH_MODULE_ENABLED
-#include "stm32f1xx_hal_flash.h"
-#endif /* HAL_FLASH_MODULE_ENABLED */
-
-#ifdef HAL_SRAM_MODULE_ENABLED
-#include "stm32f1xx_hal_sram.h"
-#endif /* HAL_SRAM_MODULE_ENABLED */
-
-#ifdef HAL_NOR_MODULE_ENABLED
-#include "stm32f1xx_hal_nor.h"
-#endif /* HAL_NOR_MODULE_ENABLED */
-
-#ifdef HAL_I2C_MODULE_ENABLED
-#include "stm32f1xx_hal_i2c.h"
-#endif /* HAL_I2C_MODULE_ENABLED */
-
-#ifdef HAL_I2S_MODULE_ENABLED
-#include "stm32f1xx_hal_i2s.h"
-#endif /* HAL_I2S_MODULE_ENABLED */
-
-#ifdef HAL_IWDG_MODULE_ENABLED
-#include "stm32f1xx_hal_iwdg.h"
-#endif /* HAL_IWDG_MODULE_ENABLED */
-
-#ifdef HAL_PWR_MODULE_ENABLED
-#include "stm32f1xx_hal_pwr.h"
-#endif /* HAL_PWR_MODULE_ENABLED */
-
-#ifdef HAL_RTC_MODULE_ENABLED
-#include "stm32f1xx_hal_rtc.h"
-#endif /* HAL_RTC_MODULE_ENABLED */
-
-#ifdef HAL_PCCARD_MODULE_ENABLED
-#include "stm32f1xx_hal_pccard.h"
-#endif /* HAL_PCCARD_MODULE_ENABLED */
-
-#ifdef HAL_SD_MODULE_ENABLED
-#include "stm32f1xx_hal_sd.h"
-#endif /* HAL_SD_MODULE_ENABLED */
-
-#ifdef HAL_NAND_MODULE_ENABLED
-#include "stm32f1xx_hal_nand.h"
-#endif /* HAL_NAND_MODULE_ENABLED */
-
-#ifdef HAL_SPI_MODULE_ENABLED
-#include "stm32f1xx_hal_spi.h"
-#endif /* HAL_SPI_MODULE_ENABLED */
-
-#ifdef HAL_TIM_MODULE_ENABLED
-#include "stm32f1xx_hal_tim.h"
-#endif /* HAL_TIM_MODULE_ENABLED */
-
-#ifdef HAL_UART_MODULE_ENABLED
-#include "stm32f1xx_hal_uart.h"
-#endif /* HAL_UART_MODULE_ENABLED */
-
-#ifdef HAL_USART_MODULE_ENABLED
-#include "stm32f1xx_hal_usart.h"
-#endif /* HAL_USART_MODULE_ENABLED */
-
-#ifdef HAL_IRDA_MODULE_ENABLED
-#include "stm32f1xx_hal_irda.h"
-#endif /* HAL_IRDA_MODULE_ENABLED */
-
-#ifdef HAL_SMARTCARD_MODULE_ENABLED
-#include "stm32f1xx_hal_smartcard.h"
-#endif /* HAL_SMARTCARD_MODULE_ENABLED */
-
-#ifdef HAL_WWDG_MODULE_ENABLED
-#include "stm32f1xx_hal_wwdg.h"
-#endif /* HAL_WWDG_MODULE_ENABLED */
-
-#ifdef HAL_PCD_MODULE_ENABLED
-#include "stm32f1xx_hal_pcd.h"
-#endif /* HAL_PCD_MODULE_ENABLED */
-
-#ifdef HAL_HCD_MODULE_ENABLED
-#include "stm32f1xx_hal_hcd.h"
-#endif /* HAL_HCD_MODULE_ENABLED */
-
-#ifdef HAL_MMC_MODULE_ENABLED
-#include "stm32f1xx_hal_mmc.h"
-#endif /* HAL_MMC_MODULE_ENABLED */
-
-/* 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)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
-/* Exported functions ------------------------------------------------------- */
-void assert_failed(uint8_t *file, uint32_t line);
-#else
-#define assert_param(expr) ((void)0U)
-#endif /* USE_FULL_ASSERT */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_CONF_H */
-
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h
deleted file mode 100644
index 9cb0c83..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h
+++ /dev/null
@@ -1,426 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_cortex.h
- * @author MCD Application Team
- * @brief Header file of CORTEX HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_CORTEX_H
-#define __STM32F1xx_HAL_CORTEX_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup CORTEX
- * @{
- */
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup CORTEX_Exported_Types Cortex Exported Types
- * @{
- */
-
-#if (__MPU_PRESENT == 1U)
-/** @defgroup CORTEX_MPU_Region_Initialization_Structure_definition MPU Region Initialization Structure Definition
- * @brief MPU Region initialization structure
- * @{
- */
-typedef struct
-{
- uint8_t Enable; /*!< Specifies the status of the region.
- This parameter can be a value of @ref CORTEX_MPU_Region_Enable */
- uint8_t Number; /*!< Specifies the number of the region to protect.
- This parameter can be a value of @ref CORTEX_MPU_Region_Number */
- uint32_t BaseAddress; /*!< Specifies the base address of the region to protect. */
- uint8_t Size; /*!< Specifies the size of the region to protect.
- This parameter can be a value of @ref CORTEX_MPU_Region_Size */
- uint8_t SubRegionDisable; /*!< Specifies the number of the subregion protection to disable.
- This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF */
- uint8_t TypeExtField; /*!< Specifies the TEX field level.
- This parameter can be a value of @ref CORTEX_MPU_TEX_Levels */
- uint8_t AccessPermission; /*!< Specifies the region access permission type.
- This parameter can be a value of @ref CORTEX_MPU_Region_Permission_Attributes */
- uint8_t DisableExec; /*!< Specifies the instruction access status.
- This parameter can be a value of @ref CORTEX_MPU_Instruction_Access */
- uint8_t IsShareable; /*!< Specifies the shareability status of the protected region.
- This parameter can be a value of @ref CORTEX_MPU_Access_Shareable */
- uint8_t IsCacheable; /*!< Specifies the cacheable status of the region protected.
- This parameter can be a value of @ref CORTEX_MPU_Access_Cacheable */
- uint8_t IsBufferable; /*!< Specifies the bufferable status of the protected region.
- This parameter can be a value of @ref CORTEX_MPU_Access_Bufferable */
-}MPU_Region_InitTypeDef;
-/**
- * @}
- */
-#endif /* __MPU_PRESENT */
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-
-/** @defgroup CORTEX_Exported_Constants CORTEX Exported Constants
- * @{
- */
-
-/** @defgroup CORTEX_Preemption_Priority_Group CORTEX Preemption Priority Group
- * @{
- */
-#define NVIC_PRIORITYGROUP_0 0x00000007U /*!< 0 bits for pre-emption priority
- 4 bits for subpriority */
-#define NVIC_PRIORITYGROUP_1 0x00000006U /*!< 1 bits for pre-emption priority
- 3 bits for subpriority */
-#define NVIC_PRIORITYGROUP_2 0x00000005U /*!< 2 bits for pre-emption priority
- 2 bits for subpriority */
-#define NVIC_PRIORITYGROUP_3 0x00000004U /*!< 3 bits for pre-emption priority
- 1 bits for subpriority */
-#define NVIC_PRIORITYGROUP_4 0x00000003U /*!< 4 bits for pre-emption priority
- 0 bits for subpriority */
-/**
- * @}
- */
-
-/** @defgroup CORTEX_SysTick_clock_source CORTEX _SysTick clock source
- * @{
- */
-#define SYSTICK_CLKSOURCE_HCLK_DIV8 0x00000000U
-#define SYSTICK_CLKSOURCE_HCLK 0x00000004U
-
-/**
- * @}
- */
-
-#if (__MPU_PRESENT == 1)
-/** @defgroup CORTEX_MPU_HFNMI_PRIVDEF_Control MPU HFNMI and PRIVILEGED Access control
- * @{
- */
-#define MPU_HFNMI_PRIVDEF_NONE 0x00000000U
-#define MPU_HARDFAULT_NMI MPU_CTRL_HFNMIENA_Msk
-#define MPU_PRIVILEGED_DEFAULT MPU_CTRL_PRIVDEFENA_Msk
-#define MPU_HFNMI_PRIVDEF (MPU_CTRL_HFNMIENA_Msk | MPU_CTRL_PRIVDEFENA_Msk)
-
-/**
- * @}
- */
-
-/** @defgroup CORTEX_MPU_Region_Enable CORTEX MPU Region Enable
- * @{
- */
-#define MPU_REGION_ENABLE ((uint8_t)0x01)
-#define MPU_REGION_DISABLE ((uint8_t)0x00)
-/**
- * @}
- */
-
-/** @defgroup CORTEX_MPU_Instruction_Access CORTEX MPU Instruction Access
- * @{
- */
-#define MPU_INSTRUCTION_ACCESS_ENABLE ((uint8_t)0x00)
-#define MPU_INSTRUCTION_ACCESS_DISABLE ((uint8_t)0x01)
-/**
- * @}
- */
-
-/** @defgroup CORTEX_MPU_Access_Shareable CORTEX MPU Instruction Access Shareable
- * @{
- */
-#define MPU_ACCESS_SHAREABLE ((uint8_t)0x01)
-#define MPU_ACCESS_NOT_SHAREABLE ((uint8_t)0x00)
-/**
- * @}
- */
-
-/** @defgroup CORTEX_MPU_Access_Cacheable CORTEX MPU Instruction Access Cacheable
- * @{
- */
-#define MPU_ACCESS_CACHEABLE ((uint8_t)0x01)
-#define MPU_ACCESS_NOT_CACHEABLE ((uint8_t)0x00)
-/**
- * @}
- */
-
-/** @defgroup CORTEX_MPU_Access_Bufferable CORTEX MPU Instruction Access Bufferable
- * @{
- */
-#define MPU_ACCESS_BUFFERABLE ((uint8_t)0x01)
-#define MPU_ACCESS_NOT_BUFFERABLE ((uint8_t)0x00)
-/**
- * @}
- */
-
-/** @defgroup CORTEX_MPU_TEX_Levels MPU TEX Levels
- * @{
- */
-#define MPU_TEX_LEVEL0 ((uint8_t)0x00)
-#define MPU_TEX_LEVEL1 ((uint8_t)0x01)
-#define MPU_TEX_LEVEL2 ((uint8_t)0x02)
-/**
- * @}
- */
-
-/** @defgroup CORTEX_MPU_Region_Size CORTEX MPU Region Size
- * @{
- */
-#define MPU_REGION_SIZE_32B ((uint8_t)0x04)
-#define MPU_REGION_SIZE_64B ((uint8_t)0x05)
-#define MPU_REGION_SIZE_128B ((uint8_t)0x06)
-#define MPU_REGION_SIZE_256B ((uint8_t)0x07)
-#define MPU_REGION_SIZE_512B ((uint8_t)0x08)
-#define MPU_REGION_SIZE_1KB ((uint8_t)0x09)
-#define MPU_REGION_SIZE_2KB ((uint8_t)0x0A)
-#define MPU_REGION_SIZE_4KB ((uint8_t)0x0B)
-#define MPU_REGION_SIZE_8KB ((uint8_t)0x0C)
-#define MPU_REGION_SIZE_16KB ((uint8_t)0x0D)
-#define MPU_REGION_SIZE_32KB ((uint8_t)0x0E)
-#define MPU_REGION_SIZE_64KB ((uint8_t)0x0F)
-#define MPU_REGION_SIZE_128KB ((uint8_t)0x10)
-#define MPU_REGION_SIZE_256KB ((uint8_t)0x11)
-#define MPU_REGION_SIZE_512KB ((uint8_t)0x12)
-#define MPU_REGION_SIZE_1MB ((uint8_t)0x13)
-#define MPU_REGION_SIZE_2MB ((uint8_t)0x14)
-#define MPU_REGION_SIZE_4MB ((uint8_t)0x15)
-#define MPU_REGION_SIZE_8MB ((uint8_t)0x16)
-#define MPU_REGION_SIZE_16MB ((uint8_t)0x17)
-#define MPU_REGION_SIZE_32MB ((uint8_t)0x18)
-#define MPU_REGION_SIZE_64MB ((uint8_t)0x19)
-#define MPU_REGION_SIZE_128MB ((uint8_t)0x1A)
-#define MPU_REGION_SIZE_256MB ((uint8_t)0x1B)
-#define MPU_REGION_SIZE_512MB ((uint8_t)0x1C)
-#define MPU_REGION_SIZE_1GB ((uint8_t)0x1D)
-#define MPU_REGION_SIZE_2GB ((uint8_t)0x1E)
-#define MPU_REGION_SIZE_4GB ((uint8_t)0x1F)
-/**
- * @}
- */
-
-/** @defgroup CORTEX_MPU_Region_Permission_Attributes CORTEX MPU Region Permission Attributes
- * @{
- */
-#define MPU_REGION_NO_ACCESS ((uint8_t)0x00)
-#define MPU_REGION_PRIV_RW ((uint8_t)0x01)
-#define MPU_REGION_PRIV_RW_URO ((uint8_t)0x02)
-#define MPU_REGION_FULL_ACCESS ((uint8_t)0x03)
-#define MPU_REGION_PRIV_RO ((uint8_t)0x05)
-#define MPU_REGION_PRIV_RO_URO ((uint8_t)0x06)
-/**
- * @}
- */
-
-/** @defgroup CORTEX_MPU_Region_Number CORTEX MPU Region Number
- * @{
- */
-#define MPU_REGION_NUMBER0 ((uint8_t)0x00)
-#define MPU_REGION_NUMBER1 ((uint8_t)0x01)
-#define MPU_REGION_NUMBER2 ((uint8_t)0x02)
-#define MPU_REGION_NUMBER3 ((uint8_t)0x03)
-#define MPU_REGION_NUMBER4 ((uint8_t)0x04)
-#define MPU_REGION_NUMBER5 ((uint8_t)0x05)
-#define MPU_REGION_NUMBER6 ((uint8_t)0x06)
-#define MPU_REGION_NUMBER7 ((uint8_t)0x07)
-/**
- * @}
- */
-#endif /* __MPU_PRESENT */
-
-/**
- * @}
- */
-
-
-/* Exported Macros -----------------------------------------------------------*/
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup CORTEX_Exported_Functions
- * @{
- */
-
-/** @addtogroup CORTEX_Exported_Functions_Group1
- * @{
- */
-/* Initialization and de-initialization functions *****************************/
-void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup);
-void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority);
-void HAL_NVIC_EnableIRQ(IRQn_Type IRQn);
-void HAL_NVIC_DisableIRQ(IRQn_Type IRQn);
-void HAL_NVIC_SystemReset(void);
-uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb);
-/**
- * @}
- */
-
-/** @addtogroup CORTEX_Exported_Functions_Group2
- * @{
- */
-/* Peripheral Control functions ***********************************************/
-uint32_t HAL_NVIC_GetPriorityGrouping(void);
-void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority);
-uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn);
-void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn);
-void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn);
-uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn);
-void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource);
-void HAL_SYSTICK_IRQHandler(void);
-void HAL_SYSTICK_Callback(void);
-
-#if (__MPU_PRESENT == 1U)
-void HAL_MPU_Enable(uint32_t MPU_Control);
-void HAL_MPU_Disable(void);
-void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init);
-#endif /* __MPU_PRESENT */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup CORTEX_Private_Macros CORTEX Private Macros
- * @{
- */
-#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PRIORITYGROUP_0) || \
- ((GROUP) == NVIC_PRIORITYGROUP_1) || \
- ((GROUP) == NVIC_PRIORITYGROUP_2) || \
- ((GROUP) == NVIC_PRIORITYGROUP_3) || \
- ((GROUP) == NVIC_PRIORITYGROUP_4))
-
-#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10U)
-
-#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10U)
-
-#define IS_NVIC_DEVICE_IRQ(IRQ) ((IRQ) >= (IRQn_Type)0x00U)
-
-#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SYSTICK_CLKSOURCE_HCLK) || \
- ((SOURCE) == SYSTICK_CLKSOURCE_HCLK_DIV8))
-
-#if (__MPU_PRESENT == 1U)
-#define IS_MPU_REGION_ENABLE(STATE) (((STATE) == MPU_REGION_ENABLE) || \
- ((STATE) == MPU_REGION_DISABLE))
-
-#define IS_MPU_INSTRUCTION_ACCESS(STATE) (((STATE) == MPU_INSTRUCTION_ACCESS_ENABLE) || \
- ((STATE) == MPU_INSTRUCTION_ACCESS_DISABLE))
-
-#define IS_MPU_ACCESS_SHAREABLE(STATE) (((STATE) == MPU_ACCESS_SHAREABLE) || \
- ((STATE) == MPU_ACCESS_NOT_SHAREABLE))
-
-#define IS_MPU_ACCESS_CACHEABLE(STATE) (((STATE) == MPU_ACCESS_CACHEABLE) || \
- ((STATE) == MPU_ACCESS_NOT_CACHEABLE))
-
-#define IS_MPU_ACCESS_BUFFERABLE(STATE) (((STATE) == MPU_ACCESS_BUFFERABLE) || \
- ((STATE) == MPU_ACCESS_NOT_BUFFERABLE))
-
-#define IS_MPU_TEX_LEVEL(TYPE) (((TYPE) == MPU_TEX_LEVEL0) || \
- ((TYPE) == MPU_TEX_LEVEL1) || \
- ((TYPE) == MPU_TEX_LEVEL2))
-
-#define IS_MPU_REGION_PERMISSION_ATTRIBUTE(TYPE) (((TYPE) == MPU_REGION_NO_ACCESS) || \
- ((TYPE) == MPU_REGION_PRIV_RW) || \
- ((TYPE) == MPU_REGION_PRIV_RW_URO) || \
- ((TYPE) == MPU_REGION_FULL_ACCESS) || \
- ((TYPE) == MPU_REGION_PRIV_RO) || \
- ((TYPE) == MPU_REGION_PRIV_RO_URO))
-
-#define IS_MPU_REGION_NUMBER(NUMBER) (((NUMBER) == MPU_REGION_NUMBER0) || \
- ((NUMBER) == MPU_REGION_NUMBER1) || \
- ((NUMBER) == MPU_REGION_NUMBER2) || \
- ((NUMBER) == MPU_REGION_NUMBER3) || \
- ((NUMBER) == MPU_REGION_NUMBER4) || \
- ((NUMBER) == MPU_REGION_NUMBER5) || \
- ((NUMBER) == MPU_REGION_NUMBER6) || \
- ((NUMBER) == MPU_REGION_NUMBER7))
-
-#define IS_MPU_REGION_SIZE(SIZE) (((SIZE) == MPU_REGION_SIZE_32B) || \
- ((SIZE) == MPU_REGION_SIZE_64B) || \
- ((SIZE) == MPU_REGION_SIZE_128B) || \
- ((SIZE) == MPU_REGION_SIZE_256B) || \
- ((SIZE) == MPU_REGION_SIZE_512B) || \
- ((SIZE) == MPU_REGION_SIZE_1KB) || \
- ((SIZE) == MPU_REGION_SIZE_2KB) || \
- ((SIZE) == MPU_REGION_SIZE_4KB) || \
- ((SIZE) == MPU_REGION_SIZE_8KB) || \
- ((SIZE) == MPU_REGION_SIZE_16KB) || \
- ((SIZE) == MPU_REGION_SIZE_32KB) || \
- ((SIZE) == MPU_REGION_SIZE_64KB) || \
- ((SIZE) == MPU_REGION_SIZE_128KB) || \
- ((SIZE) == MPU_REGION_SIZE_256KB) || \
- ((SIZE) == MPU_REGION_SIZE_512KB) || \
- ((SIZE) == MPU_REGION_SIZE_1MB) || \
- ((SIZE) == MPU_REGION_SIZE_2MB) || \
- ((SIZE) == MPU_REGION_SIZE_4MB) || \
- ((SIZE) == MPU_REGION_SIZE_8MB) || \
- ((SIZE) == MPU_REGION_SIZE_16MB) || \
- ((SIZE) == MPU_REGION_SIZE_32MB) || \
- ((SIZE) == MPU_REGION_SIZE_64MB) || \
- ((SIZE) == MPU_REGION_SIZE_128MB) || \
- ((SIZE) == MPU_REGION_SIZE_256MB) || \
- ((SIZE) == MPU_REGION_SIZE_512MB) || \
- ((SIZE) == MPU_REGION_SIZE_1GB) || \
- ((SIZE) == MPU_REGION_SIZE_2GB) || \
- ((SIZE) == MPU_REGION_SIZE_4GB))
-
-#define IS_MPU_SUB_REGION_DISABLE(SUBREGION) ((SUBREGION) < (uint16_t)0x00FF)
-#endif /* __MPU_PRESENT */
-
-/**
- * @}
- */
-
-/* Private functions ---------------------------------------------------------*/
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_CORTEX_H */
-
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_crc.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_crc.h
deleted file mode 100644
index 1430bf8..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_crc.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_crc.h
- * @author MCD Application Team
- * @brief Header file of CRC HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_CRC_H
-#define __STM32F1xx_HAL_CRC_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup CRC
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-
-/** @defgroup CRC_Exported_Types CRC Exported Types
- * @{
- */
-
-/**
- * @brief CRC HAL State Structure definition
- */
-typedef enum
-{
- HAL_CRC_STATE_RESET = 0x00U, /*!< CRC not yet initialized or disabled */
- HAL_CRC_STATE_READY = 0x01U, /*!< CRC initialized and ready for use */
- HAL_CRC_STATE_BUSY = 0x02U, /*!< CRC internal process is ongoing */
- HAL_CRC_STATE_TIMEOUT = 0x03U, /*!< CRC timeout state */
- HAL_CRC_STATE_ERROR = 0x04U /*!< CRC error state */
-
-}HAL_CRC_StateTypeDef;
-
-/**
- * @brief CRC handle Structure definition
- */
-typedef struct
-{
- CRC_TypeDef *Instance; /*!< Register base address */
-
- HAL_LockTypeDef Lock; /*!< CRC locking object */
-
- __IO HAL_CRC_StateTypeDef State; /*!< CRC communication state */
-
-}CRC_HandleTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/* Exported macro ------------------------------------------------------------*/
-
-/** @defgroup CRC_Exported_Macros CRC Exported Macros
- * @{
- */
-
-/** @brief Reset CRC handle state
- * @param __HANDLE__: CRC handle
- * @retval None
- */
-#define __HAL_CRC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_CRC_STATE_RESET)
-
-/**
- * @brief Resets CRC Data Register.
- * @param __HANDLE__: CRC handle
- * @retval None
- */
-#define __HAL_CRC_DR_RESET(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR,CRC_CR_RESET))
-
-/**
- * @brief Stores a 8-bit data in the Independent Data(ID) register.
- * @param __HANDLE__: CRC handle
- * @param __VALUE__: 8-bit value to be stored in the ID register
- * @retval None
- */
-#define __HAL_CRC_SET_IDR(__HANDLE__, __VALUE__) (WRITE_REG((__HANDLE__)->Instance->IDR, (__VALUE__)))
-
-/**
- * @brief Returns the 8-bit data stored in the Independent Data(ID) register.
- * @param __HANDLE__: CRC handle
- * @retval 8-bit value of the ID register
- */
-#define __HAL_CRC_GET_IDR(__HANDLE__) (((__HANDLE__)->Instance->IDR) & CRC_IDR_IDR)
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-
-/** @addtogroup CRC_Exported_Functions
- * @{
- */
-
-/** @addtogroup CRC_Exported_Functions_Group1
- * @{
- */
-
-/* Initialization/de-initialization functions **********************************/
-HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc);
-HAL_StatusTypeDef HAL_CRC_DeInit (CRC_HandleTypeDef *hcrc);
-void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc);
-void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc);
-
-/**
- * @}
- */
-
-/** @addtogroup CRC_Exported_Functions_Group2
- * @{
- */
-
-/* Peripheral Control functions ************************************************/
-uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength);
-uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength);
-
-
-/**
- * @}
- */
-
-/** @addtogroup CRC_Exported_Functions_Group3
- ** @{
- */
-
-/* Peripheral State functions **************************************************/
-HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc);
-
-/**
- * @}
- */
-
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_CRC_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dac.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dac.h
deleted file mode 100644
index 3ea0317..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dac.h
+++ /dev/null
@@ -1,322 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_dac.h
- * @author MCD Application Team
- * @brief Header file of DAC HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_DAC_H
-#define __STM32F1xx_HAL_DAC_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-#if defined (STM32F100xB) || defined (STM32F100xE) || defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup DAC
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-
-/** @defgroup DAC_Exported_Types DAC Exported Types
- * @{
- */
-
-/**
- * @brief HAL State structures definition
- */
-typedef enum
-{
- HAL_DAC_STATE_RESET = 0x00U, /*!< DAC not yet initialized or disabled */
- HAL_DAC_STATE_READY = 0x01U, /*!< DAC initialized and ready for use */
- HAL_DAC_STATE_BUSY = 0x02U, /*!< DAC internal processing is ongoing */
- HAL_DAC_STATE_TIMEOUT = 0x03U, /*!< DAC timeout state */
- HAL_DAC_STATE_ERROR = 0x04U /*!< DAC error state */
-
-}HAL_DAC_StateTypeDef;
-
-/**
- * @brief DAC handle Structure definition
- */
-typedef struct
-{
- DAC_TypeDef *Instance; /*!< Register base address */
-
- __IO HAL_DAC_StateTypeDef State; /*!< DAC communication state */
-
- HAL_LockTypeDef Lock; /*!< DAC locking object */
-
- DMA_HandleTypeDef *DMA_Handle1; /*!< Pointer DMA handler for channel 1 */
-
- DMA_HandleTypeDef *DMA_Handle2; /*!< Pointer DMA handler for channel 2 */
-
- __IO uint32_t ErrorCode; /*!< DAC Error code */
-
-}DAC_HandleTypeDef;
-
-/**
- * @brief DAC Configuration regular Channel structure definition
- */
-typedef struct
-{
- uint32_t DAC_Trigger; /*!< Specifies the external trigger for the selected DAC channel.
- This parameter can be a value of @ref DACEx_trigger_selection
- Note: For STM32F100x high-density value line devices, additional trigger sources are available. */
-
- uint32_t DAC_OutputBuffer; /*!< Specifies whether the DAC channel output buffer is enabled or disabled.
- This parameter can be a value of @ref DAC_output_buffer */
-
-}DAC_ChannelConfTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-
-/** @defgroup DAC_Exported_Constants DAC Exported Constants
- * @{
- */
-
-/** @defgroup DAC_Error_Code DAC Error Code
- * @{
- */
-#define HAL_DAC_ERROR_NONE 0x00000000U /*!< No error */
-#define HAL_DAC_ERROR_DMAUNDERRUNCH1 0x00000001U /*!< DAC channel1 DMA underrun error */
-#define HAL_DAC_ERROR_DMAUNDERRUNCH2 0x00000002U /*!< DAC channel2 DMA underrun error */
-#define HAL_DAC_ERROR_DMA 0x00000004U /*!< DMA error */
-/**
- * @}
- */
-
-/** @defgroup DAC_output_buffer DAC output buffer
- * @{
- */
-#define DAC_OUTPUTBUFFER_ENABLE 0x00000000U
-#define DAC_OUTPUTBUFFER_DISABLE ((uint32_t)DAC_CR_BOFF1)
-
-/**
- * @}
- */
-
-/** @defgroup DAC_Channel_selection DAC Channel selection
- * @{
- */
-#define DAC_CHANNEL_1 0x00000000U
-#define DAC_CHANNEL_2 0x00000010U
-
-/**
- * @}
- */
-
-/** @defgroup DAC_data_alignement DAC data alignement
- * @{
- */
-#define DAC_ALIGN_12B_R 0x00000000U
-#define DAC_ALIGN_12B_L 0x00000004U
-#define DAC_ALIGN_8B_R 0x00000008U
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-
-/** @defgroup DAC_Exported_Macros DAC Exported Macros
- * @{
- */
-
-/** @brief Reset DAC handle state
- * @param __HANDLE__: specifies the DAC handle.
- * @retval None
- */
-#define __HAL_DAC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_DAC_STATE_RESET)
-
-/** @brief Enable the DAC channel
- * @param __HANDLE__: specifies the DAC handle.
- * @param __DAC_Channel__: specifies the DAC channel
- * @retval None
- */
-#define __HAL_DAC_ENABLE(__HANDLE__, __DAC_Channel__) \
-((__HANDLE__)->Instance->CR |= (DAC_CR_EN1 << (__DAC_Channel__)))
-
-/** @brief Disable the DAC channel
- * @param __HANDLE__: specifies the DAC handle
- * @param __DAC_Channel__: specifies the DAC channel.
- * @retval None
- */
-#define __HAL_DAC_DISABLE(__HANDLE__, __DAC_Channel__) \
-((__HANDLE__)->Instance->CR &= ~(DAC_CR_EN1 << (__DAC_Channel__)))
-
-
-/**
- * @}
- */
-
-/* Private macro -------------------------------------------------------------*/
-
-/** @defgroup DAC_Private_Macros DAC Private Macros
- * @{
- */
-#define IS_DAC_OUTPUT_BUFFER_STATE(STATE) (((STATE) == DAC_OUTPUTBUFFER_ENABLE) || \
- ((STATE) == DAC_OUTPUTBUFFER_DISABLE))
-
-#define IS_DAC_CHANNEL(CHANNEL) (((CHANNEL) == DAC_CHANNEL_1) || \
- ((CHANNEL) == DAC_CHANNEL_2))
-
-#define IS_DAC_ALIGN(ALIGN) (((ALIGN) == DAC_ALIGN_12B_R) || \
- ((ALIGN) == DAC_ALIGN_12B_L) || \
- ((ALIGN) == DAC_ALIGN_8B_R))
-
-#define IS_DAC_DATA(DATA) ((DATA) <= 0xFFF0U)
-
-#define DAC_DHR12R1_ALIGNMENT(__ALIGNMENT__) (0x00000008U + (__ALIGNMENT__))
-
-#define DAC_DHR12R2_ALIGNMENT(__ALIGNMENT__) (0x00000014U + (__ALIGNMENT__))
-
-#define DAC_DHR12RD_ALIGNMENT(__ALIGNMENT__) (0x00000020U + (__ALIGNMENT__))
-
-/**
- * @}
- */
-
-
-/* Include DAC HAL Extension module */
-#include "stm32f1xx_hal_dac_ex.h"
-
-/* Exported functions --------------------------------------------------------*/
-
-/** @addtogroup DAC_Exported_Functions
- * @{
- */
-
-/** @addtogroup DAC_Exported_Functions_Group1
- * @{
- */
-/* Initialization and de-initialization functions *****************************/
-HAL_StatusTypeDef HAL_DAC_Init(DAC_HandleTypeDef* hdac);
-HAL_StatusTypeDef HAL_DAC_DeInit(DAC_HandleTypeDef* hdac);
-void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac);
-void HAL_DAC_MspDeInit(DAC_HandleTypeDef* hdac);
-
-/**
- * @}
- */
-
-/** @addtogroup DAC_Exported_Functions_Group2
- * @{
- */
-/* IO operation functions *****************************************************/
-HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef* hdac, uint32_t Channel);
-HAL_StatusTypeDef HAL_DAC_Stop(DAC_HandleTypeDef* hdac, uint32_t Channel);
-HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t* pData, uint32_t Length, uint32_t Alignment);
-HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel);
-HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data);
-uint32_t HAL_DAC_GetValue(DAC_HandleTypeDef* hdac, uint32_t Channel);
-
-/**
- * @}
- */
-
-/** @addtogroup DAC_Exported_Functions_Group3
- * @{
- */
-/* Peripheral Control functions ***********************************************/
-HAL_StatusTypeDef HAL_DAC_ConfigChannel(DAC_HandleTypeDef* hdac, DAC_ChannelConfTypeDef* sConfig, uint32_t Channel);
-
-/**
- * @}
- */
-
-/** @addtogroup DAC_Exported_Functions_Group4
- * @{
- */
-/* Peripheral State functions *************************************************/
-HAL_DAC_StateTypeDef HAL_DAC_GetState(DAC_HandleTypeDef* hdac);
-uint32_t HAL_DAC_GetError(DAC_HandleTypeDef *hdac);
-
-void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef* hdac);
-void HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef* hdac);
-void HAL_DAC_ErrorCallbackCh1(DAC_HandleTypeDef *hdac);
-
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup DAC_Private_Functions DAC Private Functions
- * @{
- */
-void DAC_DMAConvCpltCh1(DMA_HandleTypeDef *hdma);
-void DAC_DMAHalfConvCpltCh1(DMA_HandleTypeDef *hdma);
-void DAC_DMAErrorCh1(DMA_HandleTypeDef *hdma);
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* STM32F100xB || STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /*__STM32F1xx_HAL_DAC_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dac_ex.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dac_ex.h
deleted file mode 100644
index 520b87b..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dac_ex.h
+++ /dev/null
@@ -1,370 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_dac_ex.h
- * @author MCD Application Team
- * @brief Header file of DAC HAL Extension module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_DAC_EX_H
-#define __STM32F1xx_HAL_DAC_EX_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-#if defined (STM32F100xB) || defined (STM32F100xE) || defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup DACEx
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-
-/* Exported constants --------------------------------------------------------*/
-
-/** @defgroup DACEx_Exported_Constants DACEx Exported Constants
- * @{
- */
-
-/** @defgroup DACEx_lfsrunmask_triangleamplitude DACEx lfsrunmask triangleamplitude
- * @{
- */
-#define DAC_LFSRUNMASK_BIT0 0x00000000U /*!< Unmask DAC channel LFSR bit0 for noise wave generation */
-#define DAC_LFSRUNMASK_BITS1_0 ((uint32_t)DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[1:0] for noise wave generation */
-#define DAC_LFSRUNMASK_BITS2_0 ((uint32_t)DAC_CR_MAMP1_1) /*!< Unmask DAC channel LFSR bit[2:0] for noise wave generation */
-#define DAC_LFSRUNMASK_BITS3_0 ((uint32_t)DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0)/*!< Unmask DAC channel LFSR bit[3:0] for noise wave generation */
-#define DAC_LFSRUNMASK_BITS4_0 ((uint32_t)DAC_CR_MAMP1_2) /*!< Unmask DAC channel LFSR bit[4:0] for noise wave generation */
-#define DAC_LFSRUNMASK_BITS5_0 ((uint32_t)DAC_CR_MAMP1_2 | DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[5:0] for noise wave generation */
-#define DAC_LFSRUNMASK_BITS6_0 ((uint32_t)DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1) /*!< Unmask DAC channel LFSR bit[6:0] for noise wave generation */
-#define DAC_LFSRUNMASK_BITS7_0 ((uint32_t)DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[7:0] for noise wave generation */
-#define DAC_LFSRUNMASK_BITS8_0 ((uint32_t)DAC_CR_MAMP1_3) /*!< Unmask DAC channel LFSR bit[8:0] for noise wave generation */
-#define DAC_LFSRUNMASK_BITS9_0 ((uint32_t)DAC_CR_MAMP1_3 | DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[9:0] for noise wave generation */
-#define DAC_LFSRUNMASK_BITS10_0 ((uint32_t)DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1) /*!< Unmask DAC channel LFSR bit[10:0] for noise wave generation */
-#define DAC_LFSRUNMASK_BITS11_0 ((uint32_t)DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[11:0] for noise wave generation */
-#define DAC_TRIANGLEAMPLITUDE_1 0x00000000U /*!< Select max triangle amplitude of 1 */
-#define DAC_TRIANGLEAMPLITUDE_3 ((uint32_t)DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 3 */
-#define DAC_TRIANGLEAMPLITUDE_7 ((uint32_t)DAC_CR_MAMP1_1) /*!< Select max triangle amplitude of 7 */
-#define DAC_TRIANGLEAMPLITUDE_15 ((uint32_t)DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 15 */
-#define DAC_TRIANGLEAMPLITUDE_31 ((uint32_t)DAC_CR_MAMP1_2) /*!< Select max triangle amplitude of 31 */
-#define DAC_TRIANGLEAMPLITUDE_63 ((uint32_t)DAC_CR_MAMP1_2 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 63 */
-#define DAC_TRIANGLEAMPLITUDE_127 ((uint32_t)DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1) /*!< Select max triangle amplitude of 127 */
-#define DAC_TRIANGLEAMPLITUDE_255 ((uint32_t)DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 255 */
-#define DAC_TRIANGLEAMPLITUDE_511 ((uint32_t)DAC_CR_MAMP1_3) /*!< Select max triangle amplitude of 511 */
-#define DAC_TRIANGLEAMPLITUDE_1023 ((uint32_t)DAC_CR_MAMP1_3 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 1023 */
-#define DAC_TRIANGLEAMPLITUDE_2047 ((uint32_t)DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1) /*!< Select max triangle amplitude of 2047 */
-#define DAC_TRIANGLEAMPLITUDE_4095 ((uint32_t)DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 4095 */
-
-/**
- * @}
- */
-
-/** @defgroup DACEx_trigger_selection DAC trigger selection
- * @{
- */
-#define DAC_TRIGGER_NONE 0x00000000U /*!< Conversion is automatic once the DAC1_DHRxxxx register
- has been loaded, and not by external trigger */
-#define DAC_TRIGGER_T6_TRGO ((uint32_t) DAC_CR_TEN1) /*!< TIM6 TRGO selected as external conversion trigger for DAC channel */
-#define DAC_TRIGGER_T7_TRGO ((uint32_t)( DAC_CR_TSEL1_1 | DAC_CR_TEN1)) /*!< TIM7 TRGO selected as external conversion trigger for DAC channel */
-#define DAC_TRIGGER_T2_TRGO ((uint32_t)(DAC_CR_TSEL1_2 | DAC_CR_TEN1)) /*!< TIM2 TRGO selected as external conversion trigger for DAC channel */
-#define DAC_TRIGGER_T4_TRGO ((uint32_t)(DAC_CR_TSEL1_2 | DAC_CR_TSEL1_0 | DAC_CR_TEN1)) /*!< TIM4 TRGO selected as external conversion trigger for DAC channel */
-#define DAC_TRIGGER_EXT_IT9 ((uint32_t)(DAC_CR_TSEL1_2 | DAC_CR_TSEL1_1 | DAC_CR_TEN1)) /*!< EXTI Line9 event selected as external conversion trigger for DAC channel */
-#define DAC_TRIGGER_SOFTWARE ((uint32_t)(DAC_CR_TSEL1 | DAC_CR_TEN1)) /*!< Conversion started by software trigger for DAC channel */
-
-#if defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG)
-/* For STM32F10x high-density and XL-density devices: TIM8 */
-#define DAC_TRIGGER_T8_TRGO ((uint32_t) DAC_CR_TSEL1_0 | DAC_CR_TEN1) /*!< TIM8 TRGO selected as external conversion trigger for DAC channel */
-#endif /* STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
-
-#if defined (STM32F100xB) || defined (STM32F100xE) || defined (STM32F105xC) || defined (STM32F107xC)
-/* For STM32F10x connectivity line devices and STM32F100x devices: TIM3 */
-#define DAC_TRIGGER_T3_TRGO ((uint32_t) DAC_CR_TSEL1_0 | DAC_CR_TEN1) /*!< TIM3 TRGO selected as external conversion trigger for DAC channel */
-#endif /* STM32F100xB || STM32F100xE || STM32F105xC || STM32F107xC */
-
-/* Availability of trigger from TIM5 and TIM15: */
-/* - For STM32F10x value line devices STM32F100xB: */
-/* trigger from TIM15 is available, TIM5 not available. */
-/* - For STM32F10x value line devices STM32F100xE: */
-/* trigger from TIM15 and TIM5 are both available, */
-/* selection depends on remap (with TIM5 as default configuration). */
-/* - Other STM32F1 devices: */
-/* trigger from TIM5 is available, TIM15 not available. */
-#if defined (STM32F100xB)
-#define DAC_TRIGGER_T15_TRGO ((uint32_t)( DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0 | DAC_CR_TEN1)) /*!< TIM15 TRGO selected as external conversion trigger for DAC channel */
-#else
-
-#define DAC_TRIGGER_T5_TRGO ((uint32_t)( DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0 | DAC_CR_TEN1)) /*!< TIM5 TRGO selected as external conversion trigger for DAC channel */
-
-#if defined (STM32F100xE)
-/*!< DAC trigger availability depending on STM32F1 devices:
- For STM32F100x high-density value line devices, the TIM15 TRGO event can be selected
- as replacement of TIM5 TRGO if the MISC_REMAP bit in the AFIO_MAPR2 register is set.
- Refer to macro "__HAL_AFIO_REMAP_MISC_ENABLE()/__HAL_AFIO_REMAP_MISC_DISABLE()".
- Otherwise, TIM5 TRGO is used and TIM15 TRGO is not used (default case).
- For more details please refer to the AFIO section. */
-#define DAC_TRIGGER_T15_TRGO DAC_TRIGGER_T5_TRGO
-#endif /* STM32F100xE */
-
-#endif /* STM32F100xB */
-/**
- * @}
- */
-
-#if defined (STM32F100xB) || defined (STM32F100xE)
-/** @defgroup DAC_flags_definition DAC flags definition
- * @{
- */
-#define DAC_FLAG_DMAUDR1 ((uint32_t)DAC_SR_DMAUDR1)
-#define DAC_FLAG_DMAUDR2 ((uint32_t)DAC_SR_DMAUDR2)
-
-/**
- * @}
- */
-
-/** @defgroup DAC_IT_definition DAC IT definition
- * @{
- */
-#define DAC_IT_DMAUDR1 ((uint32_t)DAC_SR_DMAUDR1)
-#define DAC_IT_DMAUDR2 ((uint32_t)DAC_SR_DMAUDR2)
-
-/**
- * @}
- */
-#endif /* STM32F100xB || STM32F100xE */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-
-#if defined (STM32F100xB) || defined (STM32F100xE)
-/** @defgroup DACEx_Exported_Macros DACEx Exported Macros
- * @{
- */
-
-/** @brief Enable the DAC interrupt
- * @param __HANDLE__: specifies the DAC handle
- * @param __INTERRUPT__: specifies the DAC interrupt.
- * This parameter can be any combination of the following values:
- * @arg DAC_IT_DMAUDR1: DAC channel 1 DMA underrun interrupt
- * @arg DAC_IT_DMAUDR2: DAC channel 2 DMA underrun interrupt
- * @retval None
- */
-#define __HAL_DAC_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CR) |= (__INTERRUPT__))
-
-/** @brief Disable the DAC interrupt
- * @param __HANDLE__: specifies the DAC handle
- * @param __INTERRUPT__: specifies the DAC interrupt.
- * This parameter can be any combination of the following values:
- * @arg DAC_IT_DMAUDR1: DAC channel 1 DMA underrun interrupt
- * @arg DAC_IT_DMAUDR2: DAC channel 2 DMA underrun interrupt
- * @retval None
- */
-#define __HAL_DAC_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CR) &= ~(__INTERRUPT__))
-
-/** @brief Checks if the specified DAC interrupt source is enabled or disabled.
- * @param __HANDLE__: DAC handle
- * @param __INTERRUPT__: DAC interrupt source to check
- * This parameter can be any combination of the following values:
- * @arg DAC_IT_DMAUDR1: DAC channel 1 DMA underrun interrupt
- * @arg DAC_IT_DMAUDR2: DAC channel 2 DMA underrun interrupt
- * @retval State of interruption (SET or RESET)
- */
-#define __HAL_DAC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CR & (__INTERRUPT__)) == (__INTERRUPT__))
-
-/** @brief Get the selected DAC's flag status.
- * @param __HANDLE__: specifies the DAC handle.
- * @param __FLAG__: specifies the DAC flag to get.
- * This parameter can be any combination of the following values:
- * @arg DAC_FLAG_DMAUDR1: DAC channel 1 DMA underrun flag
- * @arg DAC_FLAG_DMAUDR2: DAC channel 2 DMA underrun flag
- * @retval None
- */
-#define __HAL_DAC_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__))
-
-/** @brief Clear the DAC's flag.
- * @param __HANDLE__: specifies the DAC handle.
- * @param __FLAG__: specifies the DAC flag to clear.
- * This parameter can be any combination of the following values:
- * @arg DAC_FLAG_DMAUDR1: DAC channel 1 DMA underrun flag
- * @arg DAC_FLAG_DMAUDR2: DAC channel 2 DMA underrun flag
- * @retval None
- */
-#define __HAL_DAC_CLEAR_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR) = (__FLAG__))
-
-
-/**
- * @}
- */
-#endif /* STM32F100xB || STM32F100xE */
-
-/* Private macro -------------------------------------------------------------*/
-
-/** @defgroup DACEx_Private_Macros DACEx Private Macros
- * @{
- */
-#if defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG)
-#define IS_DAC_TRIGGER(TRIGGER) (((TRIGGER) == DAC_TRIGGER_NONE) || \
- ((TRIGGER) == DAC_TRIGGER_T6_TRGO) || \
- ((TRIGGER) == DAC_TRIGGER_T8_TRGO) || \
- ((TRIGGER) == DAC_TRIGGER_T7_TRGO) || \
- ((TRIGGER) == DAC_TRIGGER_T5_TRGO) || \
- ((TRIGGER) == DAC_TRIGGER_T2_TRGO) || \
- ((TRIGGER) == DAC_TRIGGER_T4_TRGO) || \
- ((TRIGGER) == DAC_TRIGGER_EXT_IT9) || \
- ((TRIGGER) == DAC_TRIGGER_SOFTWARE))
-#endif /* STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
-#if defined (STM32F100xE) || defined (STM32F105xC) || defined (STM32F107xC)
-#define IS_DAC_TRIGGER(TRIGGER) (((TRIGGER) == DAC_TRIGGER_NONE) || \
- ((TRIGGER) == DAC_TRIGGER_T6_TRGO) || \
- ((TRIGGER) == DAC_TRIGGER_T3_TRGO) || \
- ((TRIGGER) == DAC_TRIGGER_T7_TRGO) || \
- ((TRIGGER) == DAC_TRIGGER_T5_TRGO) || \
- ((TRIGGER) == DAC_TRIGGER_T2_TRGO) || \
- ((TRIGGER) == DAC_TRIGGER_T4_TRGO) || \
- ((TRIGGER) == DAC_TRIGGER_EXT_IT9) || \
- ((TRIGGER) == DAC_TRIGGER_SOFTWARE))
-#endif /* STM32F100xE || STM32F105xC || STM32F107xC */
-#if defined (STM32F100xB)
-#define IS_DAC_TRIGGER(TRIGGER) (((TRIGGER) == DAC_TRIGGER_NONE) || \
- ((TRIGGER) == DAC_TRIGGER_T6_TRGO) || \
- ((TRIGGER) == DAC_TRIGGER_T3_TRGO) || \
- ((TRIGGER) == DAC_TRIGGER_T7_TRGO) || \
- ((TRIGGER) == DAC_TRIGGER_T15_TRGO) || \
- ((TRIGGER) == DAC_TRIGGER_T2_TRGO) || \
- ((TRIGGER) == DAC_TRIGGER_T4_TRGO) || \
- ((TRIGGER) == DAC_TRIGGER_EXT_IT9) || \
- ((TRIGGER) == DAC_TRIGGER_SOFTWARE))
-#endif /* STM32F100xB */
-
-#define IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(VALUE) (((VALUE) == DAC_LFSRUNMASK_BIT0) || \
- ((VALUE) == DAC_LFSRUNMASK_BITS1_0) || \
- ((VALUE) == DAC_LFSRUNMASK_BITS2_0) || \
- ((VALUE) == DAC_LFSRUNMASK_BITS3_0) || \
- ((VALUE) == DAC_LFSRUNMASK_BITS4_0) || \
- ((VALUE) == DAC_LFSRUNMASK_BITS5_0) || \
- ((VALUE) == DAC_LFSRUNMASK_BITS6_0) || \
- ((VALUE) == DAC_LFSRUNMASK_BITS7_0) || \
- ((VALUE) == DAC_LFSRUNMASK_BITS8_0) || \
- ((VALUE) == DAC_LFSRUNMASK_BITS9_0) || \
- ((VALUE) == DAC_LFSRUNMASK_BITS10_0) || \
- ((VALUE) == DAC_LFSRUNMASK_BITS11_0) || \
- ((VALUE) == DAC_TRIANGLEAMPLITUDE_1) || \
- ((VALUE) == DAC_TRIANGLEAMPLITUDE_3) || \
- ((VALUE) == DAC_TRIANGLEAMPLITUDE_7) || \
- ((VALUE) == DAC_TRIANGLEAMPLITUDE_15) || \
- ((VALUE) == DAC_TRIANGLEAMPLITUDE_31) || \
- ((VALUE) == DAC_TRIANGLEAMPLITUDE_63) || \
- ((VALUE) == DAC_TRIANGLEAMPLITUDE_127) || \
- ((VALUE) == DAC_TRIANGLEAMPLITUDE_255) || \
- ((VALUE) == DAC_TRIANGLEAMPLITUDE_511) || \
- ((VALUE) == DAC_TRIANGLEAMPLITUDE_1023) || \
- ((VALUE) == DAC_TRIANGLEAMPLITUDE_2047) || \
- ((VALUE) == DAC_TRIANGLEAMPLITUDE_4095))
-
-/**
- * @}
- */
-
-
-/* Exported functions --------------------------------------------------------*/
-
-/** @addtogroup DACEx_Exported_Functions
- * @{
- */
-
-/** @addtogroup DACEx_Exported_Functions_Group1
- * @{
- */
-/* Extension features functions ***********************************************/
-
-uint32_t HAL_DACEx_DualGetValue(DAC_HandleTypeDef* hdac);
-HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Amplitude);
-HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Amplitude);
-HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef* hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2);
-
-void HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef* hdac);
-void HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef* hdac);
-void HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef* hdac);
-
-#if defined (STM32F100xB) || defined (STM32F100xE)
-void HAL_DAC_IRQHandler(DAC_HandleTypeDef* hdac);
-void HAL_DAC_DMAUnderrunCallbackCh1(DAC_HandleTypeDef *hdac);
-void HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef* hdac);
-#endif /* STM32F100xB) || defined (STM32F100xE) */
-
-/**
- * @}
- */
-
-
-
-
-/**
- * @}
- */
-
-/** @addtogroup DACEx_Private_Functions
- * @{
- */
-void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma);
-void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma);
-void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma);
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* STM32F100xB || STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*__STM32F1xx_HAL_DAC_EX_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h
deleted file mode 100644
index 0a0e54f..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_def.h
- * @author MCD Application Team
- * @brief This file contains HAL common defines, enumeration, macros and
- * structures definitions.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_DEF
-#define __STM32F1xx_HAL_DEF
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx.h"
-#if defined(USE_HAL_LEGACY)
-#include "Legacy/stm32_hal_legacy.h"
-#endif
-#include
-
-/* Exported types ------------------------------------------------------------*/
-
-/**
- * @brief HAL Status structures definition
- */
-typedef enum
-{
- HAL_OK = 0x00U,
- HAL_ERROR = 0x01U,
- HAL_BUSY = 0x02U,
- HAL_TIMEOUT = 0x03U
-} HAL_StatusTypeDef;
-
-/**
- * @brief HAL Lock structures definition
- */
-typedef enum
-{
- HAL_UNLOCKED = 0x00U,
- HAL_LOCKED = 0x01U
-} HAL_LockTypeDef;
-
-/* Exported macro ------------------------------------------------------------*/
-#define HAL_MAX_DELAY 0xFFFFFFFFU
-
-#define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) != 0U)
-#define HAL_IS_BIT_CLR(REG, BIT) (((REG) & (BIT)) == 0U)
-
-#define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD__, __DMA_HANDLE__) \
- do{ \
- (__HANDLE__)->__PPP_DMA_FIELD__ = &(__DMA_HANDLE__); \
- (__DMA_HANDLE__).Parent = (__HANDLE__); \
- } while(0U)
-
-#define UNUSED(X) (void)X /* To avoid gcc/g++ warnings */
-
-/** @brief Reset the Handle's State field.
- * @param __HANDLE__: specifies the Peripheral Handle.
- * @note This macro can be used for the following purpose:
- * - When the Handle is declared as local variable; before passing it as parameter
- * to HAL_PPP_Init() for the first time, it is mandatory to use this macro
- * to set to 0 the Handle's "State" field.
- * Otherwise, "State" field may have any random value and the first time the function
- * HAL_PPP_Init() is called, the low level hardware initialization will be missed
- * (i.e. HAL_PPP_MspInit() will not be executed).
- * - When there is a need to reconfigure the low level hardware: instead of calling
- * HAL_PPP_DeInit() then HAL_PPP_Init(), user can make a call to this macro then HAL_PPP_Init().
- * In this later function, when the Handle's "State" field is set to 0, it will execute the function
- * HAL_PPP_MspInit() which will reconfigure the low level hardware.
- * @retval None
- */
-#define __HAL_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = 0U)
-
-#if (USE_RTOS == 1U)
-/* Reserved for future use */
-#error "USE_RTOS should be 0 in the current HAL release"
-#else
-#define __HAL_LOCK(__HANDLE__) \
- do{ \
- if((__HANDLE__)->Lock == HAL_LOCKED) \
- { \
- return HAL_BUSY; \
- } \
- else \
- { \
- (__HANDLE__)->Lock = HAL_LOCKED; \
- } \
- }while (0U)
-
-#define __HAL_UNLOCK(__HANDLE__) \
- do{ \
- (__HANDLE__)->Lock = HAL_UNLOCKED; \
- }while (0U)
-#endif /* USE_RTOS */
-
-#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */
-#ifndef __weak
-#define __weak __attribute__((weak))
-#endif /* __weak */
-#ifndef __packed
-#define __packed __attribute__((__packed__))
-#endif /* __packed */
-#endif /* __GNUC__ */
-
-
-/* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma data_alignment=4" must be used instead */
-#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */
-#ifndef __ALIGN_END
-#define __ALIGN_END __attribute__ ((aligned (4)))
-#endif /* __ALIGN_END */
-#ifndef __ALIGN_BEGIN
-#define __ALIGN_BEGIN
-#endif /* __ALIGN_BEGIN */
-#else
-#ifndef __ALIGN_END
-#define __ALIGN_END
-#endif /* __ALIGN_END */
-#ifndef __ALIGN_BEGIN
-#if defined (__CC_ARM) /* ARM Compiler */
-#define __ALIGN_BEGIN __align(4)
-#elif defined (__ICCARM__) /* IAR Compiler */
-#define __ALIGN_BEGIN
-#endif /* __CC_ARM */
-#endif /* __ALIGN_BEGIN */
-#endif /* __GNUC__ */
-
-
-/**
- * @brief __RAM_FUNC definition
- */
-#if defined ( __CC_ARM )
-/* ARM Compiler
- ------------
- RAM functions are defined using the toolchain options.
- Functions that are executed in RAM should reside in a separate source module.
- Using the 'Options for File' dialog you can simply change the 'Code / Const'
- area of a module to a memory space in physical RAM.
- Available memory areas are declared in the 'Target' tab of the 'Options for Target'
- dialog.
-*/
-#define __RAM_FUNC
-
-#elif defined ( __ICCARM__ )
-/* ICCARM Compiler
- ---------------
- RAM functions are defined using a specific toolchain keyword "__ramfunc".
-*/
-#define __RAM_FUNC __ramfunc
-
-#elif defined ( __GNUC__ )
-/* GNU Compiler
- ------------
- RAM functions are defined using a specific toolchain attribute
- "__attribute__((section(".RamFunc")))".
-*/
-#define __RAM_FUNC __attribute__((section(".RamFunc")))
-
-#endif
-
-/**
- * @brief __NOINLINE definition
- */
-#if defined ( __CC_ARM ) || defined ( __GNUC__ )
-/* ARM & GNUCompiler
- ----------------
-*/
-#define __NOINLINE __attribute__ ( (noinline) )
-
-#elif defined ( __ICCARM__ )
-/* ICCARM Compiler
- ---------------
-*/
-#define __NOINLINE _Pragma("optimize = no_inline")
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ___STM32F1xx_HAL_DEF */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h
deleted file mode 100644
index 524f61f..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h
+++ /dev/null
@@ -1,473 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_dma.h
- * @author MCD Application Team
- * @brief Header file of DMA HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_DMA_H
-#define __STM32F1xx_HAL_DMA_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup DMA
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-
-/** @defgroup DMA_Exported_Types DMA Exported Types
- * @{
- */
-
-/**
- * @brief DMA Configuration Structure definition
- */
-typedef struct
-{
- uint32_t Direction; /*!< Specifies if the data will be transferred from memory to peripheral,
- from memory to memory or from peripheral to memory.
- This parameter can be a value of @ref DMA_Data_transfer_direction */
-
- uint32_t PeriphInc; /*!< Specifies whether the Peripheral address register should be incremented or not.
- This parameter can be a value of @ref DMA_Peripheral_incremented_mode */
-
- uint32_t MemInc; /*!< Specifies whether the memory address register should be incremented or not.
- This parameter can be a value of @ref DMA_Memory_incremented_mode */
-
- uint32_t PeriphDataAlignment; /*!< Specifies the Peripheral data width.
- This parameter can be a value of @ref DMA_Peripheral_data_size */
-
- uint32_t MemDataAlignment; /*!< Specifies the Memory data width.
- This parameter can be a value of @ref DMA_Memory_data_size */
-
- uint32_t Mode; /*!< Specifies the operation mode of the DMAy Channelx.
- This parameter can be a value of @ref DMA_mode
- @note The circular buffer mode cannot be used if the memory-to-memory
- data transfer is configured on the selected Channel */
-
- uint32_t Priority; /*!< Specifies the software priority for the DMAy Channelx.
- This parameter can be a value of @ref DMA_Priority_level */
-} DMA_InitTypeDef;
-
-/**
- * @brief HAL DMA State structures definition
- */
-typedef enum
-{
- HAL_DMA_STATE_RESET = 0x00U, /*!< DMA not yet initialized or disabled */
- HAL_DMA_STATE_READY = 0x01U, /*!< DMA initialized and ready for use */
- HAL_DMA_STATE_BUSY = 0x02U, /*!< DMA process is ongoing */
- HAL_DMA_STATE_TIMEOUT = 0x03U /*!< DMA timeout state */
-}HAL_DMA_StateTypeDef;
-
-/**
- * @brief HAL DMA Error Code structure definition
- */
-typedef enum
-{
- HAL_DMA_FULL_TRANSFER = 0x00U, /*!< Full transfer */
- HAL_DMA_HALF_TRANSFER = 0x01U /*!< Half Transfer */
-}HAL_DMA_LevelCompleteTypeDef;
-
-/**
- * @brief HAL DMA Callback ID structure definition
- */
-typedef enum
-{
- HAL_DMA_XFER_CPLT_CB_ID = 0x00U, /*!< Full transfer */
- HAL_DMA_XFER_HALFCPLT_CB_ID = 0x01U, /*!< Half transfer */
- HAL_DMA_XFER_ERROR_CB_ID = 0x02U, /*!< Error */
- HAL_DMA_XFER_ABORT_CB_ID = 0x03U, /*!< Abort */
- HAL_DMA_XFER_ALL_CB_ID = 0x04U /*!< All */
-
-}HAL_DMA_CallbackIDTypeDef;
-
-/**
- * @brief DMA handle Structure definition
- */
-typedef struct __DMA_HandleTypeDef
-{
- DMA_Channel_TypeDef *Instance; /*!< Register base address */
-
- DMA_InitTypeDef Init; /*!< DMA communication parameters */
-
- HAL_LockTypeDef Lock; /*!< DMA locking object */
-
- HAL_DMA_StateTypeDef State; /*!< DMA transfer state */
-
- void *Parent; /*!< Parent object state */
-
- void (* XferCpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer complete callback */
-
- void (* XferHalfCpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA Half transfer complete callback */
-
- void (* XferErrorCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer error callback */
-
- void (* XferAbortCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer abort callback */
-
- __IO uint32_t ErrorCode; /*!< DMA Error code */
-
- DMA_TypeDef *DmaBaseAddress; /*!< DMA Channel Base Address */
-
- uint32_t ChannelIndex; /*!< DMA Channel Index */
-
-} DMA_HandleTypeDef;
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-
-/** @defgroup DMA_Exported_Constants DMA Exported Constants
- * @{
- */
-
-/** @defgroup DMA_Error_Code DMA Error Code
- * @{
- */
-#define HAL_DMA_ERROR_NONE 0x00000000U /*!< No error */
-#define HAL_DMA_ERROR_TE 0x00000001U /*!< Transfer error */
-#define HAL_DMA_ERROR_NO_XFER 0x00000004U /*!< no ongoing transfer */
-#define HAL_DMA_ERROR_TIMEOUT 0x00000020U /*!< Timeout error */
-#define HAL_DMA_ERROR_NOT_SUPPORTED 0x00000100U /*!< Not supported mode */
-/**
- * @}
- */
-
-/** @defgroup DMA_Data_transfer_direction DMA Data transfer direction
- * @{
- */
-#define DMA_PERIPH_TO_MEMORY 0x00000000U /*!< Peripheral to memory direction */
-#define DMA_MEMORY_TO_PERIPH ((uint32_t)DMA_CCR_DIR) /*!< Memory to peripheral direction */
-#define DMA_MEMORY_TO_MEMORY ((uint32_t)DMA_CCR_MEM2MEM) /*!< Memory to memory direction */
-
-/**
- * @}
- */
-
-/** @defgroup DMA_Peripheral_incremented_mode DMA Peripheral incremented mode
- * @{
- */
-#define DMA_PINC_ENABLE ((uint32_t)DMA_CCR_PINC) /*!< Peripheral increment mode Enable */
-#define DMA_PINC_DISABLE 0x00000000U /*!< Peripheral increment mode Disable */
-/**
- * @}
- */
-
-/** @defgroup DMA_Memory_incremented_mode DMA Memory incremented mode
- * @{
- */
-#define DMA_MINC_ENABLE ((uint32_t)DMA_CCR_MINC) /*!< Memory increment mode Enable */
-#define DMA_MINC_DISABLE 0x00000000U /*!< Memory increment mode Disable */
-/**
- * @}
- */
-
-/** @defgroup DMA_Peripheral_data_size DMA Peripheral data size
- * @{
- */
-#define DMA_PDATAALIGN_BYTE 0x00000000U /*!< Peripheral data alignment: Byte */
-#define DMA_PDATAALIGN_HALFWORD ((uint32_t)DMA_CCR_PSIZE_0) /*!< Peripheral data alignment: HalfWord */
-#define DMA_PDATAALIGN_WORD ((uint32_t)DMA_CCR_PSIZE_1) /*!< Peripheral data alignment: Word */
-/**
- * @}
- */
-
-/** @defgroup DMA_Memory_data_size DMA Memory data size
- * @{
- */
-#define DMA_MDATAALIGN_BYTE 0x00000000U /*!< Memory data alignment: Byte */
-#define DMA_MDATAALIGN_HALFWORD ((uint32_t)DMA_CCR_MSIZE_0) /*!< Memory data alignment: HalfWord */
-#define DMA_MDATAALIGN_WORD ((uint32_t)DMA_CCR_MSIZE_1) /*!< Memory data alignment: Word */
-/**
- * @}
- */
-
-/** @defgroup DMA_mode DMA mode
- * @{
- */
-#define DMA_NORMAL 0x00000000U /*!< Normal mode */
-#define DMA_CIRCULAR ((uint32_t)DMA_CCR_CIRC) /*!< Circular mode */
-/**
- * @}
- */
-
-/** @defgroup DMA_Priority_level DMA Priority level
- * @{
- */
-#define DMA_PRIORITY_LOW 0x00000000U /*!< Priority level : Low */
-#define DMA_PRIORITY_MEDIUM ((uint32_t)DMA_CCR_PL_0) /*!< Priority level : Medium */
-#define DMA_PRIORITY_HIGH ((uint32_t)DMA_CCR_PL_1) /*!< Priority level : High */
-#define DMA_PRIORITY_VERY_HIGH ((uint32_t)DMA_CCR_PL) /*!< Priority level : Very_High */
-/**
- * @}
- */
-
-
-/** @defgroup DMA_interrupt_enable_definitions DMA interrupt enable definitions
- * @{
- */
-#define DMA_IT_TC ((uint32_t)DMA_CCR_TCIE)
-#define DMA_IT_HT ((uint32_t)DMA_CCR_HTIE)
-#define DMA_IT_TE ((uint32_t)DMA_CCR_TEIE)
-/**
- * @}
- */
-
-/** @defgroup DMA_flag_definitions DMA flag definitions
- * @{
- */
-#define DMA_FLAG_GL1 0x00000001U
-#define DMA_FLAG_TC1 0x00000002U
-#define DMA_FLAG_HT1 0x00000004U
-#define DMA_FLAG_TE1 0x00000008U
-#define DMA_FLAG_GL2 0x00000010U
-#define DMA_FLAG_TC2 0x00000020U
-#define DMA_FLAG_HT2 0x00000040U
-#define DMA_FLAG_TE2 0x00000080U
-#define DMA_FLAG_GL3 0x00000100U
-#define DMA_FLAG_TC3 0x00000200U
-#define DMA_FLAG_HT3 0x00000400U
-#define DMA_FLAG_TE3 0x00000800U
-#define DMA_FLAG_GL4 0x00001000U
-#define DMA_FLAG_TC4 0x00002000U
-#define DMA_FLAG_HT4 0x00004000U
-#define DMA_FLAG_TE4 0x00008000U
-#define DMA_FLAG_GL5 0x00010000U
-#define DMA_FLAG_TC5 0x00020000U
-#define DMA_FLAG_HT5 0x00040000U
-#define DMA_FLAG_TE5 0x00080000U
-#define DMA_FLAG_GL6 0x00100000U
-#define DMA_FLAG_TC6 0x00200000U
-#define DMA_FLAG_HT6 0x00400000U
-#define DMA_FLAG_TE6 0x00800000U
-#define DMA_FLAG_GL7 0x01000000U
-#define DMA_FLAG_TC7 0x02000000U
-#define DMA_FLAG_HT7 0x04000000U
-#define DMA_FLAG_TE7 0x08000000U
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-
-/* Exported macros -----------------------------------------------------------*/
-/** @defgroup DMA_Exported_Macros DMA Exported Macros
- * @{
- */
-
-/** @brief Reset DMA handle state.
- * @param __HANDLE__: DMA handle
- * @retval None
- */
-#define __HAL_DMA_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_DMA_STATE_RESET)
-
-/**
- * @brief Enable the specified DMA Channel.
- * @param __HANDLE__: DMA handle
- * @retval None
- */
-#define __HAL_DMA_ENABLE(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CCR, DMA_CCR_EN))
-
-/**
- * @brief Disable the specified DMA Channel.
- * @param __HANDLE__: DMA handle
- * @retval None
- */
-#define __HAL_DMA_DISABLE(__HANDLE__) (CLEAR_BIT((__HANDLE__)->Instance->CCR, DMA_CCR_EN))
-
-
-/* Interrupt & Flag management */
-
-/**
- * @brief Enables the specified DMA Channel interrupts.
- * @param __HANDLE__: DMA handle
- * @param __INTERRUPT__: specifies the DMA interrupt sources to be enabled or disabled.
- * This parameter can be any combination of the following values:
- * @arg DMA_IT_TC: Transfer complete interrupt mask
- * @arg DMA_IT_HT: Half transfer complete interrupt mask
- * @arg DMA_IT_TE: Transfer error interrupt mask
- * @retval None
- */
-#define __HAL_DMA_ENABLE_IT(__HANDLE__, __INTERRUPT__) (SET_BIT((__HANDLE__)->Instance->CCR, (__INTERRUPT__)))
-
-/**
- * @brief Disable the specified DMA Channel interrupts.
- * @param __HANDLE__: DMA handle
- * @param __INTERRUPT__: specifies the DMA interrupt sources to be enabled or disabled.
- * This parameter can be any combination of the following values:
- * @arg DMA_IT_TC: Transfer complete interrupt mask
- * @arg DMA_IT_HT: Half transfer complete interrupt mask
- * @arg DMA_IT_TE: Transfer error interrupt mask
- * @retval None
- */
-#define __HAL_DMA_DISABLE_IT(__HANDLE__, __INTERRUPT__) (CLEAR_BIT((__HANDLE__)->Instance->CCR , (__INTERRUPT__)))
-
-/**
- * @brief Check whether the specified DMA Channel interrupt is enabled or not.
- * @param __HANDLE__: DMA handle
- * @param __INTERRUPT__: specifies the DMA interrupt source to check.
- * This parameter can be one of the following values:
- * @arg DMA_IT_TC: Transfer complete interrupt mask
- * @arg DMA_IT_HT: Half transfer complete interrupt mask
- * @arg DMA_IT_TE: Transfer error interrupt mask
- * @retval The state of DMA_IT (SET or RESET).
- */
-#define __HAL_DMA_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CCR & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
-
-/**
- * @brief Return the number of remaining data units in the current DMA Channel transfer.
- * @param __HANDLE__: DMA handle
- * @retval The number of remaining data units in the current DMA Channel transfer.
- */
-#define __HAL_DMA_GET_COUNTER(__HANDLE__) ((__HANDLE__)->Instance->CNDTR)
-
-/**
- * @}
- */
-
-/* Include DMA HAL Extension module */
-#include "stm32f1xx_hal_dma_ex.h"
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup DMA_Exported_Functions
- * @{
- */
-
-/** @addtogroup DMA_Exported_Functions_Group1
- * @{
- */
-/* Initialization and de-initialization functions *****************************/
-HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma);
-HAL_StatusTypeDef HAL_DMA_DeInit (DMA_HandleTypeDef *hdma);
-/**
- * @}
- */
-
-/** @addtogroup DMA_Exported_Functions_Group2
- * @{
- */
-/* IO operation functions *****************************************************/
-HAL_StatusTypeDef HAL_DMA_Start (DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
-HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
-HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma);
-HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma);
-HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout);
-void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma);
-HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)( DMA_HandleTypeDef * _hdma));
-HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID);
-
-/**
- * @}
- */
-
-/** @addtogroup DMA_Exported_Functions_Group3
- * @{
- */
-/* Peripheral State and Error functions ***************************************/
-HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma);
-uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup DMA_Private_Macros DMA Private Macros
- * @{
- */
-
-#define IS_DMA_DIRECTION(DIRECTION) (((DIRECTION) == DMA_PERIPH_TO_MEMORY ) || \
- ((DIRECTION) == DMA_MEMORY_TO_PERIPH) || \
- ((DIRECTION) == DMA_MEMORY_TO_MEMORY))
-
-#define IS_DMA_BUFFER_SIZE(SIZE) (((SIZE) >= 0x1U) && ((SIZE) < 0x10000U))
-
-#define IS_DMA_PERIPHERAL_INC_STATE(STATE) (((STATE) == DMA_PINC_ENABLE) || \
- ((STATE) == DMA_PINC_DISABLE))
-
-#define IS_DMA_MEMORY_INC_STATE(STATE) (((STATE) == DMA_MINC_ENABLE) || \
- ((STATE) == DMA_MINC_DISABLE))
-
-#define IS_DMA_PERIPHERAL_DATA_SIZE(SIZE) (((SIZE) == DMA_PDATAALIGN_BYTE) || \
- ((SIZE) == DMA_PDATAALIGN_HALFWORD) || \
- ((SIZE) == DMA_PDATAALIGN_WORD))
-
-#define IS_DMA_MEMORY_DATA_SIZE(SIZE) (((SIZE) == DMA_MDATAALIGN_BYTE) || \
- ((SIZE) == DMA_MDATAALIGN_HALFWORD) || \
- ((SIZE) == DMA_MDATAALIGN_WORD ))
-
-#define IS_DMA_MODE(MODE) (((MODE) == DMA_NORMAL ) || \
- ((MODE) == DMA_CIRCULAR))
-
-#define IS_DMA_PRIORITY(PRIORITY) (((PRIORITY) == DMA_PRIORITY_LOW ) || \
- ((PRIORITY) == DMA_PRIORITY_MEDIUM) || \
- ((PRIORITY) == DMA_PRIORITY_HIGH) || \
- ((PRIORITY) == DMA_PRIORITY_VERY_HIGH))
-
-/**
- * @}
- */
-
-/* Private functions ---------------------------------------------------------*/
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_DMA_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h
deleted file mode 100644
index b5caf9f..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h
+++ /dev/null
@@ -1,293 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_dma_ex.h
- * @author MCD Application Team
- * @brief Header file of DMA HAL extension module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_DMA_EX_H
-#define __STM32F1xx_HAL_DMA_EX_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup DMAEx DMAEx
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/* Exported constants --------------------------------------------------------*/
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup DMAEx_Exported_Macros DMA Extended Exported Macros
- * @{
- */
-/* Interrupt & Flag management */
-#if defined (STM32F100xE) || defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || \
- defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC)
-/** @defgroup DMAEx_High_density_XL_density_Product_devices DMAEx High density and XL density product devices
- * @{
- */
-
-/**
- * @brief Returns the current DMA Channel transfer complete flag.
- * @param __HANDLE__: DMA handle
- * @retval The specified transfer complete flag index.
- */
-#define __HAL_DMA_GET_TC_FLAG_INDEX(__HANDLE__) \
-(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_TC1 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_TC2 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_TC3 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_TC4 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_TC5 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_TC6 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel7))? DMA_FLAG_TC7 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel1))? DMA_FLAG_TC1 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel2))? DMA_FLAG_TC2 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel3))? DMA_FLAG_TC3 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel4))? DMA_FLAG_TC4 :\
- DMA_FLAG_TC5)
-
-/**
- * @brief Returns the current DMA Channel half transfer complete flag.
- * @param __HANDLE__: DMA handle
- * @retval The specified half transfer complete flag index.
- */
-#define __HAL_DMA_GET_HT_FLAG_INDEX(__HANDLE__)\
-(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_HT1 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_HT2 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_HT3 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_HT4 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_HT5 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_HT6 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel7))? DMA_FLAG_HT7 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel1))? DMA_FLAG_HT1 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel2))? DMA_FLAG_HT2 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel3))? DMA_FLAG_HT3 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel4))? DMA_FLAG_HT4 :\
- DMA_FLAG_HT5)
-
-/**
- * @brief Returns the current DMA Channel transfer error flag.
- * @param __HANDLE__: DMA handle
- * @retval The specified transfer error flag index.
- */
-#define __HAL_DMA_GET_TE_FLAG_INDEX(__HANDLE__)\
-(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_TE1 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_TE2 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_TE3 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_TE4 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_TE5 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_TE6 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel7))? DMA_FLAG_TE7 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel1))? DMA_FLAG_TE1 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel2))? DMA_FLAG_TE2 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel3))? DMA_FLAG_TE3 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel4))? DMA_FLAG_TE4 :\
- DMA_FLAG_TE5)
-
-/**
- * @brief Return the current DMA Channel Global interrupt flag.
- * @param __HANDLE__: DMA handle
- * @retval The specified transfer error flag index.
- */
-#define __HAL_DMA_GET_GI_FLAG_INDEX(__HANDLE__)\
-(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_GL1 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_GL2 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_GL3 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_GL4 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_GL5 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_GL6 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel7))? DMA_FLAG_GL7 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel1))? DMA_FLAG_GL1 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel2))? DMA_FLAG_GL2 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel3))? DMA_FLAG_GL3 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel4))? DMA_FLAG_GL4 :\
- DMA_FLAG_GL5)
-
-/**
- * @brief Get the DMA Channel pending flags.
- * @param __HANDLE__: DMA handle
- * @param __FLAG__: Get the specified flag.
- * This parameter can be any combination of the following values:
- * @arg DMA_FLAG_TCx: Transfer complete flag
- * @arg DMA_FLAG_HTx: Half transfer complete flag
- * @arg DMA_FLAG_TEx: Transfer error flag
- * Where x can be 1_7 or 1_5 (depending on DMA1 or DMA2) to select the DMA Channel flag.
- * @retval The state of FLAG (SET or RESET).
- */
-#define __HAL_DMA_GET_FLAG(__HANDLE__, __FLAG__)\
-(((uint32_t)((__HANDLE__)->Instance) > (uint32_t)DMA1_Channel7)? (DMA2->ISR & (__FLAG__)) :\
- (DMA1->ISR & (__FLAG__)))
-
-/**
- * @brief Clears the DMA Channel pending flags.
- * @param __HANDLE__: DMA handle
- * @param __FLAG__: specifies the flag to clear.
- * This parameter can be any combination of the following values:
- * @arg DMA_FLAG_TCx: Transfer complete flag
- * @arg DMA_FLAG_HTx: Half transfer complete flag
- * @arg DMA_FLAG_TEx: Transfer error flag
- * Where x can be 1_7 or 1_5 (depending on DMA1 or DMA2) to select the DMA Channel flag.
- * @retval None
- */
-#define __HAL_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) \
-(((uint32_t)((__HANDLE__)->Instance) > (uint32_t)DMA1_Channel7)? (DMA2->IFCR = (__FLAG__)) :\
- (DMA1->IFCR = (__FLAG__)))
-
-/**
- * @}
- */
-
-#else
-/** @defgroup DMA_Low_density_Medium_density_Product_devices DMA Low density and Medium density product devices
- * @{
- */
-
-/**
- * @brief Returns the current DMA Channel transfer complete flag.
- * @param __HANDLE__: DMA handle
- * @retval The specified transfer complete flag index.
- */
-#define __HAL_DMA_GET_TC_FLAG_INDEX(__HANDLE__) \
-(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_TC1 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_TC2 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_TC3 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_TC4 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_TC5 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_TC6 :\
- DMA_FLAG_TC7)
-
-/**
- * @brief Return the current DMA Channel half transfer complete flag.
- * @param __HANDLE__: DMA handle
- * @retval The specified half transfer complete flag index.
- */
-#define __HAL_DMA_GET_HT_FLAG_INDEX(__HANDLE__)\
-(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_HT1 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_HT2 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_HT3 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_HT4 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_HT5 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_HT6 :\
- DMA_FLAG_HT7)
-
-/**
- * @brief Return the current DMA Channel transfer error flag.
- * @param __HANDLE__: DMA handle
- * @retval The specified transfer error flag index.
- */
-#define __HAL_DMA_GET_TE_FLAG_INDEX(__HANDLE__)\
-(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_TE1 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_TE2 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_TE3 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_TE4 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_TE5 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_TE6 :\
- DMA_FLAG_TE7)
-
-/**
- * @brief Return the current DMA Channel Global interrupt flag.
- * @param __HANDLE__: DMA handle
- * @retval The specified transfer error flag index.
- */
-#define __HAL_DMA_GET_GI_FLAG_INDEX(__HANDLE__)\
-(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_GL1 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_GL2 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_GL3 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_GL4 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_GL5 :\
- ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_GL6 :\
- DMA_FLAG_GL7)
-
-/**
- * @brief Get the DMA Channel pending flags.
- * @param __HANDLE__: DMA handle
- * @param __FLAG__: Get the specified flag.
- * This parameter can be any combination of the following values:
- * @arg DMA_FLAG_TCx: Transfer complete flag
- * @arg DMA_FLAG_HTx: Half transfer complete flag
- * @arg DMA_FLAG_TEx: Transfer error flag
- * @arg DMA_FLAG_GLx: Global interrupt flag
- * Where x can be 1_7 to select the DMA Channel flag.
- * @retval The state of FLAG (SET or RESET).
- */
-
-#define __HAL_DMA_GET_FLAG(__HANDLE__, __FLAG__) (DMA1->ISR & (__FLAG__))
-
-/**
- * @brief Clear the DMA Channel pending flags.
- * @param __HANDLE__: DMA handle
- * @param __FLAG__: specifies the flag to clear.
- * This parameter can be any combination of the following values:
- * @arg DMA_FLAG_TCx: Transfer complete flag
- * @arg DMA_FLAG_HTx: Half transfer complete flag
- * @arg DMA_FLAG_TEx: Transfer error flag
- * @arg DMA_FLAG_GLx: Global interrupt flag
- * Where x can be 1_7 to select the DMA Channel flag.
- * @retval None
- */
-#define __HAL_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) (DMA1->IFCR = (__FLAG__))
-
-/**
- * @}
- */
-
-#endif
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || */
- /* STM32F103xG || STM32F105xC || STM32F107xC */
-
-#endif /* __STM32F1xx_HAL_DMA_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h
deleted file mode 100644
index 399076d..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h
+++ /dev/null
@@ -1,344 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_flash.h
- * @author MCD Application Team
- * @brief Header file of Flash HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_FLASH_H
-#define __STM32F1xx_HAL_FLASH_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup FLASH
- * @{
- */
-
-/** @addtogroup FLASH_Private_Constants
- * @{
- */
-#define FLASH_TIMEOUT_VALUE 50000U /* 50 s */
-/**
- * @}
- */
-
-/** @addtogroup FLASH_Private_Macros
- * @{
- */
-
-#define IS_FLASH_TYPEPROGRAM(VALUE) (((VALUE) == FLASH_TYPEPROGRAM_HALFWORD) || \
- ((VALUE) == FLASH_TYPEPROGRAM_WORD) || \
- ((VALUE) == FLASH_TYPEPROGRAM_DOUBLEWORD))
-
-#if defined(FLASH_ACR_LATENCY)
-#define IS_FLASH_LATENCY(__LATENCY__) (((__LATENCY__) == FLASH_LATENCY_0) || \
- ((__LATENCY__) == FLASH_LATENCY_1) || \
- ((__LATENCY__) == FLASH_LATENCY_2))
-
-#else
-#define IS_FLASH_LATENCY(__LATENCY__) ((__LATENCY__) == FLASH_LATENCY_0)
-#endif /* FLASH_ACR_LATENCY */
-/**
- * @}
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup FLASH_Exported_Types FLASH Exported Types
- * @{
- */
-
-/**
- * @brief FLASH Procedure structure definition
- */
-typedef enum
-{
- FLASH_PROC_NONE = 0U,
- FLASH_PROC_PAGEERASE = 1U,
- FLASH_PROC_MASSERASE = 2U,
- FLASH_PROC_PROGRAMHALFWORD = 3U,
- FLASH_PROC_PROGRAMWORD = 4U,
- FLASH_PROC_PROGRAMDOUBLEWORD = 5U
-} FLASH_ProcedureTypeDef;
-
-/**
- * @brief FLASH handle Structure definition
- */
-typedef struct
-{
- __IO FLASH_ProcedureTypeDef ProcedureOnGoing; /*!< Internal variable to indicate which procedure is ongoing or not in IT context */
-
- __IO uint32_t DataRemaining; /*!< Internal variable to save the remaining pages to erase or half-word to program in IT context */
-
- __IO uint32_t Address; /*!< Internal variable to save address selected for program or erase */
-
- __IO uint64_t Data; /*!< Internal variable to save data to be programmed */
-
- HAL_LockTypeDef Lock; /*!< FLASH locking object */
-
- __IO uint32_t ErrorCode; /*!< FLASH error code
- This parameter can be a value of @ref FLASH_Error_Codes */
-} FLASH_ProcessTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup FLASH_Exported_Constants FLASH Exported Constants
- * @{
- */
-
-/** @defgroup FLASH_Error_Codes FLASH Error Codes
- * @{
- */
-
-#define HAL_FLASH_ERROR_NONE 0x00U /*!< No error */
-#define HAL_FLASH_ERROR_PROG 0x01U /*!< Programming error */
-#define HAL_FLASH_ERROR_WRP 0x02U /*!< Write protection error */
-#define HAL_FLASH_ERROR_OPTV 0x04U /*!< Option validity error */
-
-/**
- * @}
- */
-
-/** @defgroup FLASH_Type_Program FLASH Type Program
- * @{
- */
-#define FLASH_TYPEPROGRAM_HALFWORD 0x01U /*!ACR |= FLASH_ACR_HLFCYA)
-
-/**
- * @brief Disable the FLASH half cycle access.
- * @note half cycle access can only be used with a low-frequency clock of less than
- 8 MHz that can be obtained with the use of HSI or HSE but not of PLL.
- * @retval None
- */
-#define __HAL_FLASH_HALF_CYCLE_ACCESS_DISABLE() (FLASH->ACR &= (~FLASH_ACR_HLFCYA))
-
-/**
- * @}
- */
-
-#if defined(FLASH_ACR_LATENCY)
-/** @defgroup FLASH_EM_Latency FLASH Latency
- * @brief macros to handle FLASH Latency
- * @{
- */
-
-/**
- * @brief Set the FLASH Latency.
- * @param __LATENCY__ FLASH Latency
- * The value of this parameter depend on device used within the same series
- * @retval None
- */
-#define __HAL_FLASH_SET_LATENCY(__LATENCY__) (FLASH->ACR = (FLASH->ACR&(~FLASH_ACR_LATENCY)) | (__LATENCY__))
-
-
-/**
- * @brief Get the FLASH Latency.
- * @retval FLASH Latency
- * The value of this parameter depend on device used within the same series
- */
-#define __HAL_FLASH_GET_LATENCY() (READ_BIT((FLASH->ACR), FLASH_ACR_LATENCY))
-
-/**
- * @}
- */
-
-#endif /* FLASH_ACR_LATENCY */
-/** @defgroup FLASH_Prefetch FLASH Prefetch
- * @brief macros to handle FLASH Prefetch buffer
- * @{
- */
-/**
- * @brief Enable the FLASH prefetch buffer.
- * @retval None
- */
-#define __HAL_FLASH_PREFETCH_BUFFER_ENABLE() (FLASH->ACR |= FLASH_ACR_PRFTBE)
-
-/**
- * @brief Disable the FLASH prefetch buffer.
- * @retval None
- */
-#define __HAL_FLASH_PREFETCH_BUFFER_DISABLE() (FLASH->ACR &= (~FLASH_ACR_PRFTBE))
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Include FLASH HAL Extended module */
-#include "stm32f1xx_hal_flash_ex.h"
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup FLASH_Exported_Functions
- * @{
- */
-
-/** @addtogroup FLASH_Exported_Functions_Group1
- * @{
- */
-/* IO operation functions *****************************************************/
-HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data);
-HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data);
-
-/* FLASH IRQ handler function */
-void HAL_FLASH_IRQHandler(void);
-/* Callbacks in non blocking modes */
-void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue);
-void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue);
-
-/**
- * @}
- */
-
-/** @addtogroup FLASH_Exported_Functions_Group2
- * @{
- */
-/* Peripheral Control functions ***********************************************/
-HAL_StatusTypeDef HAL_FLASH_Unlock(void);
-HAL_StatusTypeDef HAL_FLASH_Lock(void);
-HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void);
-HAL_StatusTypeDef HAL_FLASH_OB_Lock(void);
-void HAL_FLASH_OB_Launch(void);
-
-/**
- * @}
- */
-
-/** @addtogroup FLASH_Exported_Functions_Group3
- * @{
- */
-/* Peripheral State and Error functions ***************************************/
-uint32_t HAL_FLASH_GetError(void);
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private function -------------------------------------------------*/
-/** @addtogroup FLASH_Private_Functions
- * @{
- */
-HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout);
-#if defined(FLASH_BANK2_END)
-HAL_StatusTypeDef FLASH_WaitForLastOperationBank2(uint32_t Timeout);
-#endif /* FLASH_BANK2_END */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_FLASH_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h
deleted file mode 100644
index 5ec0163..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h
+++ /dev/null
@@ -1,802 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_flash_ex.h
- * @author MCD Application Team
- * @brief Header file of Flash HAL Extended module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_FLASH_EX_H
-#define __STM32F1xx_HAL_FLASH_EX_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup FLASHEx
- * @{
- */
-
-/** @addtogroup FLASHEx_Private_Constants
- * @{
- */
-
-#define FLASH_SIZE_DATA_REGISTER 0x1FFFF7E0U
-#define OBR_REG_INDEX 1U
-#define SR_FLAG_MASK ((uint32_t)(FLASH_SR_BSY | FLASH_SR_PGERR | FLASH_SR_WRPRTERR | FLASH_SR_EOP))
-
-/**
- * @}
- */
-
-/** @addtogroup FLASHEx_Private_Macros
- * @{
- */
-
-#define IS_FLASH_TYPEERASE(VALUE) (((VALUE) == FLASH_TYPEERASE_PAGES) || ((VALUE) == FLASH_TYPEERASE_MASSERASE))
-
-#define IS_OPTIONBYTE(VALUE) (((VALUE) <= (OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER | OPTIONBYTE_DATA)))
-
-#define IS_WRPSTATE(VALUE) (((VALUE) == OB_WRPSTATE_DISABLE) || ((VALUE) == OB_WRPSTATE_ENABLE))
-
-#define IS_OB_RDP_LEVEL(LEVEL) (((LEVEL) == OB_RDP_LEVEL_0) || ((LEVEL) == OB_RDP_LEVEL_1))
-
-#define IS_OB_DATA_ADDRESS(ADDRESS) (((ADDRESS) == OB_DATA_ADDRESS_DATA0) || ((ADDRESS) == OB_DATA_ADDRESS_DATA1))
-
-#define IS_OB_IWDG_SOURCE(SOURCE) (((SOURCE) == OB_IWDG_SW) || ((SOURCE) == OB_IWDG_HW))
-
-#define IS_OB_STOP_SOURCE(SOURCE) (((SOURCE) == OB_STOP_NO_RST) || ((SOURCE) == OB_STOP_RST))
-
-#define IS_OB_STDBY_SOURCE(SOURCE) (((SOURCE) == OB_STDBY_NO_RST) || ((SOURCE) == OB_STDBY_RST))
-
-#if defined(FLASH_BANK2_END)
-#define IS_OB_BOOT1(BOOT1) (((BOOT1) == OB_BOOT1_RESET) || ((BOOT1) == OB_BOOT1_SET))
-#endif /* FLASH_BANK2_END */
-
-/* Low Density */
-#if (defined(STM32F101x6) || defined(STM32F102x6) || defined(STM32F103x6))
-#define IS_FLASH_NB_PAGES(ADDRESS,NBPAGES) (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x20U) ? ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)- 1 <= 0x08007FFFU) : \
- ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)- 1 <= 0x08003FFFU))
-#endif /* STM32F101x6 || STM32F102x6 || STM32F103x6 */
-
-/* Medium Density */
-#if (defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB))
-#define IS_FLASH_NB_PAGES(ADDRESS,NBPAGES) (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x80U) ? ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x0801FFFFU) : \
- (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x40U) ? ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x0800FFFFU) : \
- (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x20U) ? ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x08007FFFU) : \
- ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x08003FFFU))))
-#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB*/
-
-/* High Density */
-#if (defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE))
-#define IS_FLASH_NB_PAGES(ADDRESS,NBPAGES) (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x200U) ? ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x0807FFFFU) : \
- (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x180U) ? ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x0805FFFFU) : \
- ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x0803FFFFU)))
-#endif /* STM32F100xE || STM32F101xE || STM32F103xE */
-
-/* XL Density */
-#if defined(FLASH_BANK2_END)
-#define IS_FLASH_NB_PAGES(ADDRESS,NBPAGES) (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x400U) ? ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x080FFFFFU) : \
- ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x080BFFFFU))
-#endif /* FLASH_BANK2_END */
-
-/* Connectivity Line */
-#if (defined(STM32F105xC) || defined(STM32F107xC))
-#define IS_FLASH_NB_PAGES(ADDRESS,NBPAGES) (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x100U) ? ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x0803FFFFU) : \
- (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x80U) ? ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x0801FFFFU) : \
- ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x0800FFFFU)))
-#endif /* STM32F105xC || STM32F107xC */
-
-#define IS_OB_WRP(PAGE) (((PAGE) != 0x0000000U))
-
-#if defined(FLASH_BANK2_END)
-#define IS_FLASH_BANK(BANK) (((BANK) == FLASH_BANK_1) || \
- ((BANK) == FLASH_BANK_2) || \
- ((BANK) == FLASH_BANK_BOTH))
-#else
-#define IS_FLASH_BANK(BANK) (((BANK) == FLASH_BANK_1))
-#endif /* FLASH_BANK2_END */
-
-/* Low Density */
-#if (defined(STM32F101x6) || defined(STM32F102x6) || defined(STM32F103x6))
-#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (((ADDRESS) >= FLASH_BASE) && (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x20U) ? \
- ((ADDRESS) <= FLASH_BANK1_END) : ((ADDRESS) <= 0x08003FFFU)))
-
-#endif /* STM32F101x6 || STM32F102x6 || STM32F103x6 */
-
-/* Medium Density */
-#if (defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB))
-#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (((ADDRESS) >= FLASH_BASE) && (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x80U) ? \
- ((ADDRESS) <= FLASH_BANK1_END) : (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x40U) ? \
- ((ADDRESS) <= 0x0800FFFF) : (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x20U) ? \
- ((ADDRESS) <= 0x08007FFF) : ((ADDRESS) <= 0x08003FFFU)))))
-
-#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB*/
-
-/* High Density */
-#if (defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE))
-#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (((ADDRESS) >= FLASH_BASE) && (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x200U) ? \
- ((ADDRESS) <= FLASH_BANK1_END) : (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x180U) ? \
- ((ADDRESS) <= 0x0805FFFFU) : ((ADDRESS) <= 0x0803FFFFU))))
-
-#endif /* STM32F100xE || STM32F101xE || STM32F103xE */
-
-/* XL Density */
-#if defined(FLASH_BANK2_END)
-#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (((ADDRESS) >= FLASH_BASE) && (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x400U) ? \
- ((ADDRESS) <= FLASH_BANK2_END) : ((ADDRESS) <= 0x080BFFFFU)))
-
-#endif /* FLASH_BANK2_END */
-
-/* Connectivity Line */
-#if (defined(STM32F105xC) || defined(STM32F107xC))
-#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (((ADDRESS) >= FLASH_BASE) && (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x100U) ? \
- ((ADDRESS) <= FLASH_BANK1_END) : (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x80U) ? \
- ((ADDRESS) <= 0x0801FFFFU) : ((ADDRESS) <= 0x0800FFFFU))))
-
-#endif /* STM32F105xC || STM32F107xC */
-
-/**
- * @}
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup FLASHEx_Exported_Types FLASHEx Exported Types
- * @{
- */
-
-/**
- * @brief FLASH Erase structure definition
- */
-typedef struct
-{
- uint32_t TypeErase; /*!< TypeErase: Mass erase or page erase.
- This parameter can be a value of @ref FLASHEx_Type_Erase */
-
- uint32_t Banks; /*!< Select banks to erase when Mass erase is enabled.
- This parameter must be a value of @ref FLASHEx_Banks */
-
- uint32_t PageAddress; /*!< PageAdress: Initial FLASH page address to erase when mass erase is disabled
- This parameter must be a number between Min_Data = 0x08000000 and Max_Data = FLASH_BANKx_END
- (x = 1 or 2 depending on devices)*/
-
- uint32_t NbPages; /*!< NbPages: Number of pagess to be erased.
- This parameter must be a value between Min_Data = 1 and Max_Data = (max number of pages - value of initial page)*/
-
-} FLASH_EraseInitTypeDef;
-
-/**
- * @brief FLASH Options bytes program structure definition
- */
-typedef struct
-{
- uint32_t OptionType; /*!< OptionType: Option byte to be configured.
- This parameter can be a value of @ref FLASHEx_OB_Type */
-
- uint32_t WRPState; /*!< WRPState: Write protection activation or deactivation.
- This parameter can be a value of @ref FLASHEx_OB_WRP_State */
-
- uint32_t WRPPage; /*!< WRPPage: specifies the page(s) to be write protected
- This parameter can be a value of @ref FLASHEx_OB_Write_Protection */
-
- uint32_t Banks; /*!< Select banks for WRP activation/deactivation of all sectors.
- This parameter must be a value of @ref FLASHEx_Banks */
-
- uint8_t RDPLevel; /*!< RDPLevel: Set the read protection level..
- This parameter can be a value of @ref FLASHEx_OB_Read_Protection */
-
-#if defined(FLASH_BANK2_END)
- uint8_t USERConfig; /*!< USERConfig: Program the FLASH User Option Byte:
- IWDG / STOP / STDBY / BOOT1
- This parameter can be a combination of @ref FLASHEx_OB_IWatchdog, @ref FLASHEx_OB_nRST_STOP,
- @ref FLASHEx_OB_nRST_STDBY, @ref FLASHEx_OB_BOOT1 */
-#else
- uint8_t USERConfig; /*!< USERConfig: Program the FLASH User Option Byte:
- IWDG / STOP / STDBY
- This parameter can be a combination of @ref FLASHEx_OB_IWatchdog, @ref FLASHEx_OB_nRST_STOP,
- @ref FLASHEx_OB_nRST_STDBY */
-#endif /* FLASH_BANK2_END */
-
- uint32_t DATAAddress; /*!< DATAAddress: Address of the option byte DATA to be programmed
- This parameter can be a value of @ref FLASHEx_OB_Data_Address */
-
- uint8_t DATAData; /*!< DATAData: Data to be stored in the option byte DATA
- This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF */
-} FLASH_OBProgramInitTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup FLASHEx_Exported_Constants FLASHEx Exported Constants
- * @{
- */
-
-/** @defgroup FLASHEx_Constants FLASH Constants
- * @{
- */
-
-/** @defgroup FLASHEx_Page_Size Page Size
- * @{
- */
-#if (defined(STM32F101x6) || defined(STM32F102x6) || defined(STM32F103x6) || defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB))
-#define FLASH_PAGE_SIZE 0x400U
-#endif /* STM32F101x6 || STM32F102x6 || STM32F103x6 */
- /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB */
-
-#if (defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC))
-#define FLASH_PAGE_SIZE 0x800U
-#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB */
- /* STM32F101xG || STM32F103xG */
- /* STM32F105xC || STM32F107xC */
-
-/**
- * @}
- */
-
-/** @defgroup FLASHEx_Type_Erase Type Erase
- * @{
- */
-#define FLASH_TYPEERASE_PAGES 0x00U /*!CR, ((__INTERRUPT__) & 0x0000FFFFU)); \
- /* Enable Bank2 IT */ \
- SET_BIT(FLASH->CR2, ((__INTERRUPT__) >> 16U)); \
- } while(0U)
-
-/**
- * @brief Disable the specified FLASH interrupt.
- * @param __INTERRUPT__ FLASH interrupt
- * This parameter can be any combination of the following values:
- * @arg @ref FLASH_IT_EOP_BANK1 End of FLASH Operation Interrupt on bank1
- * @arg @ref FLASH_IT_ERR_BANK1 Error Interrupt on bank1
- * @arg @ref FLASH_IT_EOP_BANK2 End of FLASH Operation Interrupt on bank2
- * @arg @ref FLASH_IT_ERR_BANK2 Error Interrupt on bank2
- * @retval none
- */
-#define __HAL_FLASH_DISABLE_IT(__INTERRUPT__) do { \
- /* Disable Bank1 IT */ \
- CLEAR_BIT(FLASH->CR, ((__INTERRUPT__) & 0x0000FFFFU)); \
- /* Disable Bank2 IT */ \
- CLEAR_BIT(FLASH->CR2, ((__INTERRUPT__) >> 16U)); \
- } while(0U)
-
-/**
- * @brief Get the specified FLASH flag status.
- * @param __FLAG__ specifies the FLASH flag to check.
- * This parameter can be one of the following values:
- * @arg @ref FLASH_FLAG_EOP_BANK1 FLASH End of Operation flag on bank1
- * @arg @ref FLASH_FLAG_WRPERR_BANK1 FLASH Write protected error flag on bank1
- * @arg @ref FLASH_FLAG_PGERR_BANK1 FLASH Programming error flag on bank1
- * @arg @ref FLASH_FLAG_BSY_BANK1 FLASH Busy flag on bank1
- * @arg @ref FLASH_FLAG_EOP_BANK2 FLASH End of Operation flag on bank2
- * @arg @ref FLASH_FLAG_WRPERR_BANK2 FLASH Write protected error flag on bank2
- * @arg @ref FLASH_FLAG_PGERR_BANK2 FLASH Programming error flag on bank2
- * @arg @ref FLASH_FLAG_BSY_BANK2 FLASH Busy flag on bank2
- * @arg @ref FLASH_FLAG_OPTVERR Loaded OB and its complement do not match
- * @retval The new state of __FLAG__ (SET or RESET).
- */
-#define __HAL_FLASH_GET_FLAG(__FLAG__) (((__FLAG__) == FLASH_FLAG_OPTVERR) ? \
- (FLASH->OBR & FLASH_OBR_OPTERR) : \
- ((((__FLAG__) & SR_FLAG_MASK) != RESET)? \
- (FLASH->SR & ((__FLAG__) & SR_FLAG_MASK)) : \
- (FLASH->SR2 & ((__FLAG__) >> 16U))))
-
-/**
- * @brief Clear the specified FLASH flag.
- * @param __FLAG__ specifies the FLASH flags to clear.
- * This parameter can be any combination of the following values:
- * @arg @ref FLASH_FLAG_EOP_BANK1 FLASH End of Operation flag on bank1
- * @arg @ref FLASH_FLAG_WRPERR_BANK1 FLASH Write protected error flag on bank1
- * @arg @ref FLASH_FLAG_PGERR_BANK1 FLASH Programming error flag on bank1
- * @arg @ref FLASH_FLAG_BSY_BANK1 FLASH Busy flag on bank1
- * @arg @ref FLASH_FLAG_EOP_BANK2 FLASH End of Operation flag on bank2
- * @arg @ref FLASH_FLAG_WRPERR_BANK2 FLASH Write protected error flag on bank2
- * @arg @ref FLASH_FLAG_PGERR_BANK2 FLASH Programming error flag on bank2
- * @arg @ref FLASH_FLAG_BSY_BANK2 FLASH Busy flag on bank2
- * @arg @ref FLASH_FLAG_OPTVERR Loaded OB and its complement do not match
- * @retval none
- */
-#define __HAL_FLASH_CLEAR_FLAG(__FLAG__) do { \
- /* Clear FLASH_FLAG_OPTVERR flag */ \
- if ((__FLAG__) == FLASH_FLAG_OPTVERR) \
- { \
- CLEAR_BIT(FLASH->OBR, FLASH_OBR_OPTERR); \
- } \
- else { \
- /* Clear Flag in Bank1 */ \
- if (((__FLAG__) & SR_FLAG_MASK) != RESET) \
- { \
- FLASH->SR = ((__FLAG__) & SR_FLAG_MASK); \
- } \
- /* Clear Flag in Bank2 */ \
- if (((__FLAG__) >> 16U) != RESET) \
- { \
- FLASH->SR2 = ((__FLAG__) >> 16U); \
- } \
- } \
- } while(0U)
-#else
-/**
- * @brief Enable the specified FLASH interrupt.
- * @param __INTERRUPT__ FLASH interrupt
- * This parameter can be any combination of the following values:
- * @arg @ref FLASH_IT_EOP End of FLASH Operation Interrupt
- * @arg @ref FLASH_IT_ERR Error Interrupt
- * @retval none
- */
-#define __HAL_FLASH_ENABLE_IT(__INTERRUPT__) (FLASH->CR |= (__INTERRUPT__))
-
-/**
- * @brief Disable the specified FLASH interrupt.
- * @param __INTERRUPT__ FLASH interrupt
- * This parameter can be any combination of the following values:
- * @arg @ref FLASH_IT_EOP End of FLASH Operation Interrupt
- * @arg @ref FLASH_IT_ERR Error Interrupt
- * @retval none
- */
-#define __HAL_FLASH_DISABLE_IT(__INTERRUPT__) (FLASH->CR &= ~(__INTERRUPT__))
-
-/**
- * @brief Get the specified FLASH flag status.
- * @param __FLAG__ specifies the FLASH flag to check.
- * This parameter can be one of the following values:
- * @arg @ref FLASH_FLAG_EOP FLASH End of Operation flag
- * @arg @ref FLASH_FLAG_WRPERR FLASH Write protected error flag
- * @arg @ref FLASH_FLAG_PGERR FLASH Programming error flag
- * @arg @ref FLASH_FLAG_BSY FLASH Busy flag
- * @arg @ref FLASH_FLAG_OPTVERR Loaded OB and its complement do not match
- * @retval The new state of __FLAG__ (SET or RESET).
- */
-#define __HAL_FLASH_GET_FLAG(__FLAG__) (((__FLAG__) == FLASH_FLAG_OPTVERR) ? \
- (FLASH->OBR & FLASH_OBR_OPTERR) : \
- (FLASH->SR & (__FLAG__)))
-/**
- * @brief Clear the specified FLASH flag.
- * @param __FLAG__ specifies the FLASH flags to clear.
- * This parameter can be any combination of the following values:
- * @arg @ref FLASH_FLAG_EOP FLASH End of Operation flag
- * @arg @ref FLASH_FLAG_WRPERR FLASH Write protected error flag
- * @arg @ref FLASH_FLAG_PGERR FLASH Programming error flag
- * @arg @ref FLASH_FLAG_OPTVERR Loaded OB and its complement do not match
- * @retval none
- */
-#define __HAL_FLASH_CLEAR_FLAG(__FLAG__) do { \
- /* Clear FLASH_FLAG_OPTVERR flag */ \
- if ((__FLAG__) == FLASH_FLAG_OPTVERR) \
- { \
- CLEAR_BIT(FLASH->OBR, FLASH_OBR_OPTERR); \
- } \
- else { \
- /* Clear Flag in Bank1 */ \
- FLASH->SR = (__FLAG__); \
- } \
- } while(0U)
-
-#endif
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup FLASHEx_Exported_Functions
- * @{
- */
-
-/** @addtogroup FLASHEx_Exported_Functions_Group1
- * @{
- */
-/* IO operation functions *****************************************************/
-HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError);
-HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit);
-
-/**
- * @}
- */
-
-/** @addtogroup FLASHEx_Exported_Functions_Group2
- * @{
- */
-/* Peripheral Control functions ***********************************************/
-HAL_StatusTypeDef HAL_FLASHEx_OBErase(void);
-HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit);
-void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit);
-uint32_t HAL_FLASHEx_OBGetUserData(uint32_t DATAAdress);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_FLASH_EX_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h
deleted file mode 100644
index 2594a19..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h
+++ /dev/null
@@ -1,324 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_gpio.h
- * @author MCD Application Team
- * @brief Header file of GPIO HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_GPIO_H
-#define __STM32F1xx_HAL_GPIO_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup GPIO
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup GPIO_Exported_Types GPIO Exported Types
- * @{
- */
-
-/**
- * @brief GPIO Init structure definition
- */
-typedef struct
-{
- uint32_t Pin; /*!< Specifies the GPIO pins to be configured.
- This parameter can be any value of @ref GPIO_pins_define */
-
- uint32_t Mode; /*!< Specifies the operating mode for the selected pins.
- This parameter can be a value of @ref GPIO_mode_define */
-
- uint32_t Pull; /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.
- This parameter can be a value of @ref GPIO_pull_define */
-
- uint32_t Speed; /*!< Specifies the speed for the selected pins.
- This parameter can be a value of @ref GPIO_speed_define */
-} GPIO_InitTypeDef;
-
-/**
- * @brief GPIO Bit SET and Bit RESET enumeration
- */
-typedef enum
-{
- GPIO_PIN_RESET = 0U,
- GPIO_PIN_SET
-} GPIO_PinState;
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-
-/** @defgroup GPIO_Exported_Constants GPIO Exported Constants
- * @{
- */
-
-/** @defgroup GPIO_pins_define GPIO pins define
- * @{
- */
-#define GPIO_PIN_0 ((uint16_t)0x0001) /* Pin 0 selected */
-#define GPIO_PIN_1 ((uint16_t)0x0002) /* Pin 1 selected */
-#define GPIO_PIN_2 ((uint16_t)0x0004) /* Pin 2 selected */
-#define GPIO_PIN_3 ((uint16_t)0x0008) /* Pin 3 selected */
-#define GPIO_PIN_4 ((uint16_t)0x0010) /* Pin 4 selected */
-#define GPIO_PIN_5 ((uint16_t)0x0020) /* Pin 5 selected */
-#define GPIO_PIN_6 ((uint16_t)0x0040) /* Pin 6 selected */
-#define GPIO_PIN_7 ((uint16_t)0x0080) /* Pin 7 selected */
-#define GPIO_PIN_8 ((uint16_t)0x0100) /* Pin 8 selected */
-#define GPIO_PIN_9 ((uint16_t)0x0200) /* Pin 9 selected */
-#define GPIO_PIN_10 ((uint16_t)0x0400) /* Pin 10 selected */
-#define GPIO_PIN_11 ((uint16_t)0x0800) /* Pin 11 selected */
-#define GPIO_PIN_12 ((uint16_t)0x1000) /* Pin 12 selected */
-#define GPIO_PIN_13 ((uint16_t)0x2000) /* Pin 13 selected */
-#define GPIO_PIN_14 ((uint16_t)0x4000) /* Pin 14 selected */
-#define GPIO_PIN_15 ((uint16_t)0x8000) /* Pin 15 selected */
-#define GPIO_PIN_All ((uint16_t)0xFFFF) /* All pins selected */
-
-#define GPIO_PIN_MASK 0x0000FFFFU /* PIN mask for assert test */
-/**
- * @}
- */
-
-/** @defgroup GPIO_mode_define GPIO mode define
- * @brief GPIO Configuration Mode
- * Elements values convention: 0xX0yz00YZ
- * - X : GPIO mode or EXTI Mode
- * - y : External IT or Event trigger detection
- * - z : IO configuration on External IT or Event
- * - Y : Output type (Push Pull or Open Drain)
- * - Z : IO Direction mode (Input, Output, Alternate or Analog)
- * @{
- */
-#define GPIO_MODE_INPUT 0x00000000U /*!< Input Floating Mode */
-#define GPIO_MODE_OUTPUT_PP 0x00000001U /*!< Output Push Pull Mode */
-#define GPIO_MODE_OUTPUT_OD 0x00000011U /*!< Output Open Drain Mode */
-#define GPIO_MODE_AF_PP 0x00000002U /*!< Alternate Function Push Pull Mode */
-#define GPIO_MODE_AF_OD 0x00000012U /*!< Alternate Function Open Drain Mode */
-#define GPIO_MODE_AF_INPUT GPIO_MODE_INPUT /*!< Alternate Function Input Mode */
-
-#define GPIO_MODE_ANALOG 0x00000003U /*!< Analog Mode */
-
-#define GPIO_MODE_IT_RISING 0x10110000U /*!< External Interrupt Mode with Rising edge trigger detection */
-#define GPIO_MODE_IT_FALLING 0x10210000U /*!< External Interrupt Mode with Falling edge trigger detection */
-#define GPIO_MODE_IT_RISING_FALLING 0x10310000U /*!< External Interrupt Mode with Rising/Falling edge trigger detection */
-
-#define GPIO_MODE_EVT_RISING 0x10120000U /*!< External Event Mode with Rising edge trigger detection */
-#define GPIO_MODE_EVT_FALLING 0x10220000U /*!< External Event Mode with Falling edge trigger detection */
-#define GPIO_MODE_EVT_RISING_FALLING 0x10320000U /*!< External Event Mode with Rising/Falling edge trigger detection */
-
-/**
- * @}
- */
-
-/** @defgroup GPIO_speed_define GPIO speed define
- * @brief GPIO Output Maximum frequency
- * @{
- */
-#define GPIO_SPEED_FREQ_LOW (GPIO_CRL_MODE0_1) /*!< Low speed */
-#define GPIO_SPEED_FREQ_MEDIUM (GPIO_CRL_MODE0_0) /*!< Medium speed */
-#define GPIO_SPEED_FREQ_HIGH (GPIO_CRL_MODE0) /*!< High speed */
-
-/**
- * @}
- */
-
-/** @defgroup GPIO_pull_define GPIO pull define
- * @brief GPIO Pull-Up or Pull-Down Activation
- * @{
- */
-#define GPIO_NOPULL 0x00000000U /*!< No Pull-up or Pull-down activation */
-#define GPIO_PULLUP 0x00000001U /*!< Pull-up activation */
-#define GPIO_PULLDOWN 0x00000002U /*!< Pull-down activation */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup GPIO_Exported_Macros GPIO Exported Macros
- * @{
- */
-
-/**
- * @brief Checks whether the specified EXTI line flag is set or not.
- * @param __EXTI_LINE__: specifies the EXTI line flag to check.
- * This parameter can be GPIO_PIN_x where x can be(0..15)
- * @retval The new state of __EXTI_LINE__ (SET or RESET).
- */
-#define __HAL_GPIO_EXTI_GET_FLAG(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__))
-
-/**
- * @brief Clears the EXTI's line pending flags.
- * @param __EXTI_LINE__: specifies the EXTI lines flags to clear.
- * This parameter can be any combination of GPIO_PIN_x where x can be (0..15)
- * @retval None
- */
-#define __HAL_GPIO_EXTI_CLEAR_FLAG(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__))
-
-/**
- * @brief Checks whether the specified EXTI line is asserted or not.
- * @param __EXTI_LINE__: specifies the EXTI line to check.
- * This parameter can be GPIO_PIN_x where x can be(0..15)
- * @retval The new state of __EXTI_LINE__ (SET or RESET).
- */
-#define __HAL_GPIO_EXTI_GET_IT(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__))
-
-/**
- * @brief Clears the EXTI's line pending bits.
- * @param __EXTI_LINE__: specifies the EXTI lines to clear.
- * This parameter can be any combination of GPIO_PIN_x where x can be (0..15)
- * @retval None
- */
-#define __HAL_GPIO_EXTI_CLEAR_IT(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__))
-
-/**
- * @brief Generates a Software interrupt on selected EXTI line.
- * @param __EXTI_LINE__: specifies the EXTI line to check.
- * This parameter can be GPIO_PIN_x where x can be(0..15)
- * @retval None
- */
-#define __HAL_GPIO_EXTI_GENERATE_SWIT(__EXTI_LINE__) (EXTI->SWIER |= (__EXTI_LINE__))
-/**
- * @}
- */
-
-/* Include GPIO HAL Extension module */
-#include "stm32f1xx_hal_gpio_ex.h"
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup GPIO_Exported_Functions
- * @{
- */
-
-/** @addtogroup GPIO_Exported_Functions_Group1
- * @{
- */
-/* Initialization and de-initialization functions *****************************/
-void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
-void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);
-/**
- * @}
- */
-
-/** @addtogroup GPIO_Exported_Functions_Group2
- * @{
- */
-/* IO operation functions *****************************************************/
-GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
-void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
-void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
-HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
-void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
-void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup GPIO_Private_Constants GPIO Private Constants
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup GPIO_Private_Macros GPIO Private Macros
- * @{
- */
-#define IS_GPIO_PIN_ACTION(ACTION) (((ACTION) == GPIO_PIN_RESET) || ((ACTION) == GPIO_PIN_SET))
-#define IS_GPIO_PIN(PIN) ((((PIN) & GPIO_PIN_MASK ) != 0x00U) && (((PIN) & ~GPIO_PIN_MASK) == 0x00U))
-#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_MODE_INPUT) ||\
- ((MODE) == GPIO_MODE_OUTPUT_PP) ||\
- ((MODE) == GPIO_MODE_OUTPUT_OD) ||\
- ((MODE) == GPIO_MODE_AF_PP) ||\
- ((MODE) == GPIO_MODE_AF_OD) ||\
- ((MODE) == GPIO_MODE_IT_RISING) ||\
- ((MODE) == GPIO_MODE_IT_FALLING) ||\
- ((MODE) == GPIO_MODE_IT_RISING_FALLING) ||\
- ((MODE) == GPIO_MODE_EVT_RISING) ||\
- ((MODE) == GPIO_MODE_EVT_FALLING) ||\
- ((MODE) == GPIO_MODE_EVT_RISING_FALLING) ||\
- ((MODE) == GPIO_MODE_ANALOG))
-#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_SPEED_FREQ_LOW) || \
- ((SPEED) == GPIO_SPEED_FREQ_MEDIUM) || ((SPEED) == GPIO_SPEED_FREQ_HIGH))
-#define IS_GPIO_PULL(PULL) (((PULL) == GPIO_NOPULL) || ((PULL) == GPIO_PULLUP) || \
- ((PULL) == GPIO_PULLDOWN))
-/**
- * @}
- */
-
-/* Private functions ---------------------------------------------------------*/
-/** @defgroup GPIO_Private_Functions GPIO Private Functions
- * @{
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_GPIO_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h
deleted file mode 100644
index ff4b96a..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h
+++ /dev/null
@@ -1,910 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_gpio_ex.h
- * @author MCD Application Team
- * @brief Header file of GPIO HAL Extension module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_GPIO_EX_H
-#define __STM32F1xx_HAL_GPIO_EX_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup GPIOEx GPIOEx
- * @{
- */
-/* Exported types ------------------------------------------------------------*/
-/* Exported constants --------------------------------------------------------*/
-
-/** @defgroup GPIOEx_Exported_Constants GPIOEx Exported Constants
- * @{
- */
-
-/** @defgroup GPIOEx_EVENTOUT EVENTOUT Cortex Configuration
- * @brief This section propose definition to use the Cortex EVENTOUT signal.
- * @{
- */
-
-/** @defgroup GPIOEx_EVENTOUT_PIN EVENTOUT Pin
- * @{
- */
-
-#define AFIO_EVENTOUT_PIN_0 AFIO_EVCR_PIN_PX0 /*!< EVENTOUT on pin 0 */
-#define AFIO_EVENTOUT_PIN_1 AFIO_EVCR_PIN_PX1 /*!< EVENTOUT on pin 1 */
-#define AFIO_EVENTOUT_PIN_2 AFIO_EVCR_PIN_PX2 /*!< EVENTOUT on pin 2 */
-#define AFIO_EVENTOUT_PIN_3 AFIO_EVCR_PIN_PX3 /*!< EVENTOUT on pin 3 */
-#define AFIO_EVENTOUT_PIN_4 AFIO_EVCR_PIN_PX4 /*!< EVENTOUT on pin 4 */
-#define AFIO_EVENTOUT_PIN_5 AFIO_EVCR_PIN_PX5 /*!< EVENTOUT on pin 5 */
-#define AFIO_EVENTOUT_PIN_6 AFIO_EVCR_PIN_PX6 /*!< EVENTOUT on pin 6 */
-#define AFIO_EVENTOUT_PIN_7 AFIO_EVCR_PIN_PX7 /*!< EVENTOUT on pin 7 */
-#define AFIO_EVENTOUT_PIN_8 AFIO_EVCR_PIN_PX8 /*!< EVENTOUT on pin 8 */
-#define AFIO_EVENTOUT_PIN_9 AFIO_EVCR_PIN_PX9 /*!< EVENTOUT on pin 9 */
-#define AFIO_EVENTOUT_PIN_10 AFIO_EVCR_PIN_PX10 /*!< EVENTOUT on pin 10 */
-#define AFIO_EVENTOUT_PIN_11 AFIO_EVCR_PIN_PX11 /*!< EVENTOUT on pin 11 */
-#define AFIO_EVENTOUT_PIN_12 AFIO_EVCR_PIN_PX12 /*!< EVENTOUT on pin 12 */
-#define AFIO_EVENTOUT_PIN_13 AFIO_EVCR_PIN_PX13 /*!< EVENTOUT on pin 13 */
-#define AFIO_EVENTOUT_PIN_14 AFIO_EVCR_PIN_PX14 /*!< EVENTOUT on pin 14 */
-#define AFIO_EVENTOUT_PIN_15 AFIO_EVCR_PIN_PX15 /*!< EVENTOUT on pin 15 */
-
-#define IS_AFIO_EVENTOUT_PIN(__PIN__) (((__PIN__) == AFIO_EVENTOUT_PIN_0) || \
- ((__PIN__) == AFIO_EVENTOUT_PIN_1) || \
- ((__PIN__) == AFIO_EVENTOUT_PIN_2) || \
- ((__PIN__) == AFIO_EVENTOUT_PIN_3) || \
- ((__PIN__) == AFIO_EVENTOUT_PIN_4) || \
- ((__PIN__) == AFIO_EVENTOUT_PIN_5) || \
- ((__PIN__) == AFIO_EVENTOUT_PIN_6) || \
- ((__PIN__) == AFIO_EVENTOUT_PIN_7) || \
- ((__PIN__) == AFIO_EVENTOUT_PIN_8) || \
- ((__PIN__) == AFIO_EVENTOUT_PIN_9) || \
- ((__PIN__) == AFIO_EVENTOUT_PIN_10) || \
- ((__PIN__) == AFIO_EVENTOUT_PIN_11) || \
- ((__PIN__) == AFIO_EVENTOUT_PIN_12) || \
- ((__PIN__) == AFIO_EVENTOUT_PIN_13) || \
- ((__PIN__) == AFIO_EVENTOUT_PIN_14) || \
- ((__PIN__) == AFIO_EVENTOUT_PIN_15))
-/**
- * @}
- */
-
-/** @defgroup GPIOEx_EVENTOUT_PORT EVENTOUT Port
- * @{
- */
-
-#define AFIO_EVENTOUT_PORT_A AFIO_EVCR_PORT_PA /*!< EVENTOUT on port A */
-#define AFIO_EVENTOUT_PORT_B AFIO_EVCR_PORT_PB /*!< EVENTOUT on port B */
-#define AFIO_EVENTOUT_PORT_C AFIO_EVCR_PORT_PC /*!< EVENTOUT on port C */
-#define AFIO_EVENTOUT_PORT_D AFIO_EVCR_PORT_PD /*!< EVENTOUT on port D */
-#define AFIO_EVENTOUT_PORT_E AFIO_EVCR_PORT_PE /*!< EVENTOUT on port E */
-
-#define IS_AFIO_EVENTOUT_PORT(__PORT__) (((__PORT__) == AFIO_EVENTOUT_PORT_A) || \
- ((__PORT__) == AFIO_EVENTOUT_PORT_B) || \
- ((__PORT__) == AFIO_EVENTOUT_PORT_C) || \
- ((__PORT__) == AFIO_EVENTOUT_PORT_D) || \
- ((__PORT__) == AFIO_EVENTOUT_PORT_E))
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @defgroup GPIOEx_AFIO_AF_REMAPPING Alternate Function Remapping
- * @brief This section propose definition to remap the alternate function to some other port/pins.
- * @{
- */
-
-/**
- * @brief Enable the remapping of SPI1 alternate function NSS, SCK, MISO and MOSI.
- * @note ENABLE: Remap (NSS/PA15, SCK/PB3, MISO/PB4, MOSI/PB5)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_SPI1_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_SPI1_REMAP)
-
-/**
- * @brief Disable the remapping of SPI1 alternate function NSS, SCK, MISO and MOSI.
- * @note DISABLE: No remap (NSS/PA4, SCK/PA5, MISO/PA6, MOSI/PA7)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_SPI1_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_SPI1_REMAP)
-
-/**
- * @brief Enable the remapping of I2C1 alternate function SCL and SDA.
- * @note ENABLE: Remap (SCL/PB8, SDA/PB9)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_I2C1_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_I2C1_REMAP)
-
-/**
- * @brief Disable the remapping of I2C1 alternate function SCL and SDA.
- * @note DISABLE: No remap (SCL/PB6, SDA/PB7)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_I2C1_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_I2C1_REMAP)
-
-/**
- * @brief Enable the remapping of USART1 alternate function TX and RX.
- * @note ENABLE: Remap (TX/PB6, RX/PB7)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_USART1_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_USART1_REMAP)
-
-/**
- * @brief Disable the remapping of USART1 alternate function TX and RX.
- * @note DISABLE: No remap (TX/PA9, RX/PA10)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_USART1_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_USART1_REMAP)
-
-/**
- * @brief Enable the remapping of USART2 alternate function CTS, RTS, CK, TX and RX.
- * @note ENABLE: Remap (CTS/PD3, RTS/PD4, TX/PD5, RX/PD6, CK/PD7)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_USART2_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_USART2_REMAP)
-
-/**
- * @brief Disable the remapping of USART2 alternate function CTS, RTS, CK, TX and RX.
- * @note DISABLE: No remap (CTS/PA0, RTS/PA1, TX/PA2, RX/PA3, CK/PA4)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_USART2_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_USART2_REMAP)
-
-/**
- * @brief Enable the remapping of USART3 alternate function CTS, RTS, CK, TX and RX.
- * @note ENABLE: Full remap (TX/PD8, RX/PD9, CK/PD10, CTS/PD11, RTS/PD12)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_USART3_ENABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_USART3_REMAP_FULLREMAP, AFIO_MAPR_USART3_REMAP_FULLREMAP)
-
-/**
- * @brief Enable the remapping of USART3 alternate function CTS, RTS, CK, TX and RX.
- * @note PARTIAL: Partial remap (TX/PC10, RX/PC11, CK/PC12, CTS/PB13, RTS/PB14)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_USART3_PARTIAL() AFIO_REMAP_PARTIAL(AFIO_MAPR_USART3_REMAP_PARTIALREMAP, AFIO_MAPR_USART3_REMAP_FULLREMAP)
-
-/**
- * @brief Disable the remapping of USART3 alternate function CTS, RTS, CK, TX and RX.
- * @note DISABLE: No remap (TX/PB10, RX/PB11, CK/PB12, CTS/PB13, RTS/PB14)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_USART3_DISABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_USART3_REMAP_NOREMAP, AFIO_MAPR_USART3_REMAP_FULLREMAP)
-
-/**
- * @brief Enable the remapping of TIM1 alternate function channels 1 to 4, 1N to 3N, external trigger (ETR) and Break input (BKIN)
- * @note ENABLE: Full remap (ETR/PE7, CH1/PE9, CH2/PE11, CH3/PE13, CH4/PE14, BKIN/PE15, CH1N/PE8, CH2N/PE10, CH3N/PE12)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM1_ENABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM1_REMAP_FULLREMAP, AFIO_MAPR_TIM1_REMAP_FULLREMAP)
-
-/**
- * @brief Enable the remapping of TIM1 alternate function channels 1 to 4, 1N to 3N, external trigger (ETR) and Break input (BKIN)
- * @note PARTIAL: Partial remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PA6, CH1N/PA7, CH2N/PB0, CH3N/PB1)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM1_PARTIAL() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM1_REMAP_PARTIALREMAP, AFIO_MAPR_TIM1_REMAP_FULLREMAP)
-
-/**
- * @brief Disable the remapping of TIM1 alternate function channels 1 to 4, 1N to 3N, external trigger (ETR) and Break input (BKIN)
- * @note DISABLE: No remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PB12, CH1N/PB13, CH2N/PB14, CH3N/PB15)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM1_DISABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM1_REMAP_NOREMAP, AFIO_MAPR_TIM1_REMAP_FULLREMAP)
-
-/**
- * @brief Enable the remapping of TIM2 alternate function channels 1 to 4 and external trigger (ETR)
- * @note ENABLE: Full remap (CH1/ETR/PA15, CH2/PB3, CH3/PB10, CH4/PB11)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM2_ENABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM2_REMAP_FULLREMAP, AFIO_MAPR_TIM2_REMAP_FULLREMAP)
-
-/**
- * @brief Enable the remapping of TIM2 alternate function channels 1 to 4 and external trigger (ETR)
- * @note PARTIAL_2: Partial remap (CH1/ETR/PA0, CH2/PA1, CH3/PB10, CH4/PB11)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM2_PARTIAL_2() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM2_REMAP_PARTIALREMAP2, AFIO_MAPR_TIM2_REMAP_FULLREMAP)
-
-/**
- * @brief Enable the remapping of TIM2 alternate function channels 1 to 4 and external trigger (ETR)
- * @note PARTIAL_1: Partial remap (CH1/ETR/PA15, CH2/PB3, CH3/PA2, CH4/PA3)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM2_PARTIAL_1() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM2_REMAP_PARTIALREMAP1, AFIO_MAPR_TIM2_REMAP_FULLREMAP)
-
-/**
- * @brief Disable the remapping of TIM2 alternate function channels 1 to 4 and external trigger (ETR)
- * @note DISABLE: No remap (CH1/ETR/PA0, CH2/PA1, CH3/PA2, CH4/PA3)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM2_DISABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM2_REMAP_NOREMAP, AFIO_MAPR_TIM2_REMAP_FULLREMAP)
-
-/**
- * @brief Enable the remapping of TIM3 alternate function channels 1 to 4
- * @note ENABLE: Full remap (CH1/PC6, CH2/PC7, CH3/PC8, CH4/PC9)
- * @note TIM3_ETR on PE0 is not re-mapped.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM3_ENABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM3_REMAP_FULLREMAP, AFIO_MAPR_TIM3_REMAP_FULLREMAP)
-
-/**
- * @brief Enable the remapping of TIM3 alternate function channels 1 to 4
- * @note PARTIAL: Partial remap (CH1/PB4, CH2/PB5, CH3/PB0, CH4/PB1)
- * @note TIM3_ETR on PE0 is not re-mapped.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM3_PARTIAL() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM3_REMAP_PARTIALREMAP, AFIO_MAPR_TIM3_REMAP_FULLREMAP)
-
-/**
- * @brief Disable the remapping of TIM3 alternate function channels 1 to 4
- * @note DISABLE: No remap (CH1/PA6, CH2/PA7, CH3/PB0, CH4/PB1)
- * @note TIM3_ETR on PE0 is not re-mapped.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM3_DISABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM3_REMAP_NOREMAP, AFIO_MAPR_TIM3_REMAP_FULLREMAP)
-
-/**
- * @brief Enable the remapping of TIM4 alternate function channels 1 to 4.
- * @note ENABLE: Full remap (TIM4_CH1/PD12, TIM4_CH2/PD13, TIM4_CH3/PD14, TIM4_CH4/PD15)
- * @note TIM4_ETR on PE0 is not re-mapped.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM4_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_TIM4_REMAP)
-
-/**
- * @brief Disable the remapping of TIM4 alternate function channels 1 to 4.
- * @note DISABLE: No remap (TIM4_CH1/PB6, TIM4_CH2/PB7, TIM4_CH3/PB8, TIM4_CH4/PB9)
- * @note TIM4_ETR on PE0 is not re-mapped.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM4_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_TIM4_REMAP)
-
-#if defined(AFIO_MAPR_CAN_REMAP_REMAP1)
-
-/**
- * @brief Enable or disable the remapping of CAN alternate function CAN_RX and CAN_TX in devices with a single CAN interface.
- * @note CASE 1: CAN_RX mapped to PA11, CAN_TX mapped to PA12
- * @retval None
- */
-#define __HAL_AFIO_REMAP_CAN1_1() AFIO_REMAP_PARTIAL(AFIO_MAPR_CAN_REMAP_REMAP1, AFIO_MAPR_CAN_REMAP)
-
-/**
- * @brief Enable or disable the remapping of CAN alternate function CAN_RX and CAN_TX in devices with a single CAN interface.
- * @note CASE 2: CAN_RX mapped to PB8, CAN_TX mapped to PB9 (not available on 36-pin package)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_CAN1_2() AFIO_REMAP_PARTIAL(AFIO_MAPR_CAN_REMAP_REMAP2, AFIO_MAPR_CAN_REMAP)
-
-/**
- * @brief Enable or disable the remapping of CAN alternate function CAN_RX and CAN_TX in devices with a single CAN interface.
- * @note CASE 3: CAN_RX mapped to PD0, CAN_TX mapped to PD1
- * @retval None
- */
-#define __HAL_AFIO_REMAP_CAN1_3() AFIO_REMAP_PARTIAL(AFIO_MAPR_CAN_REMAP_REMAP3, AFIO_MAPR_CAN_REMAP)
-
-#endif
-
-/**
- * @brief Enable the remapping of PD0 and PD1. When the HSE oscillator is not used
- * (application running on internal 8 MHz RC) PD0 and PD1 can be mapped on OSC_IN and
- * OSC_OUT. This is available only on 36, 48 and 64 pins packages (PD0 and PD1 are available
- * on 100-pin and 144-pin packages, no need for remapping).
- * @note ENABLE: PD0 remapped on OSC_IN, PD1 remapped on OSC_OUT.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_PD01_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_PD01_REMAP)
-
-/**
- * @brief Disable the remapping of PD0 and PD1. When the HSE oscillator is not used
- * (application running on internal 8 MHz RC) PD0 and PD1 can be mapped on OSC_IN and
- * OSC_OUT. This is available only on 36, 48 and 64 pins packages (PD0 and PD1 are available
- * on 100-pin and 144-pin packages, no need for remapping).
- * @note DISABLE: No remapping of PD0 and PD1
- * @retval None
- */
-#define __HAL_AFIO_REMAP_PD01_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_PD01_REMAP)
-
-#if defined(AFIO_MAPR_TIM5CH4_IREMAP)
-/**
- * @brief Enable the remapping of TIM5CH4.
- * @note ENABLE: LSI internal clock is connected to TIM5_CH4 input for calibration purpose.
- * @note This function is available only in high density value line devices.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM5CH4_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_TIM5CH4_IREMAP)
-
-/**
- * @brief Disable the remapping of TIM5CH4.
- * @note DISABLE: TIM5_CH4 is connected to PA3
- * @note This function is available only in high density value line devices.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM5CH4_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_TIM5CH4_IREMAP)
-#endif
-
-#if defined(AFIO_MAPR_ETH_REMAP)
-/**
- * @brief Enable the remapping of Ethernet MAC connections with the PHY.
- * @note ENABLE: Remap (RX_DV-CRS_DV/PD8, RXD0/PD9, RXD1/PD10, RXD2/PD11, RXD3/PD12)
- * @note This bit is available only in connectivity line devices and is reserved otherwise.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_ETH_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_ETH_REMAP)
-
-/**
- * @brief Disable the remapping of Ethernet MAC connections with the PHY.
- * @note DISABLE: No remap (RX_DV-CRS_DV/PA7, RXD0/PC4, RXD1/PC5, RXD2/PB0, RXD3/PB1)
- * @note This bit is available only in connectivity line devices and is reserved otherwise.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_ETH_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_ETH_REMAP)
-#endif
-
-#if defined(AFIO_MAPR_CAN2_REMAP)
-
-/**
- * @brief Enable the remapping of CAN2 alternate function CAN2_RX and CAN2_TX.
- * @note ENABLE: Remap (CAN2_RX/PB5, CAN2_TX/PB6)
- * @note This bit is available only in connectivity line devices and is reserved otherwise.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_CAN2_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_CAN2_REMAP)
-
-/**
- * @brief Disable the remapping of CAN2 alternate function CAN2_RX and CAN2_TX.
- * @note DISABLE: No remap (CAN2_RX/PB12, CAN2_TX/PB13)
- * @note This bit is available only in connectivity line devices and is reserved otherwise.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_CAN2_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_CAN2_REMAP)
-#endif
-
-#if defined(AFIO_MAPR_MII_RMII_SEL)
-/**
- * @brief Configures the Ethernet MAC internally for use with an external MII or RMII PHY.
- * @note ETH_RMII: Configure Ethernet MAC for connection with an RMII PHY
- * @note This bit is available only in connectivity line devices and is reserved otherwise.
- * @retval None
- */
-#define __HAL_AFIO_ETH_RMII() AFIO_REMAP_ENABLE(AFIO_MAPR_MII_RMII_SEL)
-
-/**
- * @brief Configures the Ethernet MAC internally for use with an external MII or RMII PHY.
- * @note ETH_MII: Configure Ethernet MAC for connection with an MII PHY
- * @note This bit is available only in connectivity line devices and is reserved otherwise.
- * @retval None
- */
-#define __HAL_AFIO_ETH_MII() AFIO_REMAP_DISABLE(AFIO_MAPR_MII_RMII_SEL)
-#endif
-
-/**
- * @brief Enable the remapping of ADC1_ETRGINJ (ADC 1 External trigger injected conversion).
- * @note ENABLE: ADC1 External Event injected conversion is connected to TIM8 Channel4.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_ADC1_ETRGINJ_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_ADC1_ETRGINJ_REMAP)
-
-/**
- * @brief Disable the remapping of ADC1_ETRGINJ (ADC 1 External trigger injected conversion).
- * @note DISABLE: ADC1 External trigger injected conversion is connected to EXTI15
- * @retval None
- */
-#define __HAL_AFIO_REMAP_ADC1_ETRGINJ_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_ADC1_ETRGINJ_REMAP)
-
-/**
- * @brief Enable the remapping of ADC1_ETRGREG (ADC 1 External trigger regular conversion).
- * @note ENABLE: ADC1 External Event regular conversion is connected to TIM8 TRG0.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_ADC1_ETRGREG_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_ADC1_ETRGREG_REMAP)
-
-/**
- * @brief Disable the remapping of ADC1_ETRGREG (ADC 1 External trigger regular conversion).
- * @note DISABLE: ADC1 External trigger regular conversion is connected to EXTI11
- * @retval None
- */
-#define __HAL_AFIO_REMAP_ADC1_ETRGREG_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_ADC1_ETRGREG_REMAP)
-
-#if defined(AFIO_MAPR_ADC2_ETRGINJ_REMAP)
-
-/**
- * @brief Enable the remapping of ADC2_ETRGREG (ADC 2 External trigger injected conversion).
- * @note ENABLE: ADC2 External Event injected conversion is connected to TIM8 Channel4.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_ADC2_ETRGINJ_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_ADC2_ETRGINJ_REMAP)
-
-/**
- * @brief Disable the remapping of ADC2_ETRGREG (ADC 2 External trigger injected conversion).
- * @note DISABLE: ADC2 External trigger injected conversion is connected to EXTI15
- * @retval None
- */
-#define __HAL_AFIO_REMAP_ADC2_ETRGINJ_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_ADC2_ETRGINJ_REMAP)
-#endif
-
-#if defined (AFIO_MAPR_ADC2_ETRGREG_REMAP)
-
-/**
- * @brief Enable the remapping of ADC2_ETRGREG (ADC 2 External trigger regular conversion).
- * @note ENABLE: ADC2 External Event regular conversion is connected to TIM8 TRG0.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_ADC2_ETRGREG_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_ADC2_ETRGREG_REMAP)
-
-/**
- * @brief Disable the remapping of ADC2_ETRGREG (ADC 2 External trigger regular conversion).
- * @note DISABLE: ADC2 External trigger regular conversion is connected to EXTI11
- * @retval None
- */
-#define __HAL_AFIO_REMAP_ADC2_ETRGREG_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_ADC2_ETRGREG_REMAP)
-#endif
-
-/**
- * @brief Enable the Serial wire JTAG configuration
- * @note ENABLE: Full SWJ (JTAG-DP + SW-DP): Reset State
- * @retval None
- */
-#define __HAL_AFIO_REMAP_SWJ_ENABLE() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_RESET)
-
-/**
- * @brief Enable the Serial wire JTAG configuration
- * @note NONJTRST: Full SWJ (JTAG-DP + SW-DP) but without NJTRST
- * @retval None
- */
-#define __HAL_AFIO_REMAP_SWJ_NONJTRST() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_NOJNTRST)
-
-/**
- * @brief Enable the Serial wire JTAG configuration
- * @note NOJTAG: JTAG-DP Disabled and SW-DP Enabled
- * @retval None
- */
-
-#define __HAL_AFIO_REMAP_SWJ_NOJTAG() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_JTAGDISABLE)
-
-/**
- * @brief Disable the Serial wire JTAG configuration
- * @note DISABLE: JTAG-DP Disabled and SW-DP Disabled
- * @retval None
- */
-#define __HAL_AFIO_REMAP_SWJ_DISABLE() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_DISABLE)
-
-#if defined(AFIO_MAPR_SPI3_REMAP)
-
-/**
- * @brief Enable the remapping of SPI3 alternate functions SPI3_NSS/I2S3_WS, SPI3_SCK/I2S3_CK, SPI3_MISO, SPI3_MOSI/I2S3_SD.
- * @note ENABLE: Remap (SPI3_NSS-I2S3_WS/PA4, SPI3_SCK-I2S3_CK/PC10, SPI3_MISO/PC11, SPI3_MOSI-I2S3_SD/PC12)
- * @note This bit is available only in connectivity line devices and is reserved otherwise.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_SPI3_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_SPI3_REMAP)
-
-/**
- * @brief Disable the remapping of SPI3 alternate functions SPI3_NSS/I2S3_WS, SPI3_SCK/I2S3_CK, SPI3_MISO, SPI3_MOSI/I2S3_SD.
- * @note DISABLE: No remap (SPI3_NSS-I2S3_WS/PA15, SPI3_SCK-I2S3_CK/PB3, SPI3_MISO/PB4, SPI3_MOSI-I2S3_SD/PB5).
- * @note This bit is available only in connectivity line devices and is reserved otherwise.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_SPI3_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_SPI3_REMAP)
-#endif
-
-#if defined(AFIO_MAPR_TIM2ITR1_IREMAP)
-
-/**
- * @brief Control of TIM2_ITR1 internal mapping.
- * @note TO_USB: Connect USB OTG SOF (Start of Frame) output to TIM2_ITR1 for calibration purposes.
- * @note This bit is available only in connectivity line devices and is reserved otherwise.
- * @retval None
- */
-#define __HAL_AFIO_TIM2ITR1_TO_USB() AFIO_REMAP_ENABLE(AFIO_MAPR_TIM2ITR1_IREMAP)
-
-/**
- * @brief Control of TIM2_ITR1 internal mapping.
- * @note TO_ETH: Connect TIM2_ITR1 internally to the Ethernet PTP output for calibration purposes.
- * @note This bit is available only in connectivity line devices and is reserved otherwise.
- * @retval None
- */
-#define __HAL_AFIO_TIM2ITR1_TO_ETH() AFIO_REMAP_DISABLE(AFIO_MAPR_TIM2ITR1_IREMAP)
-#endif
-
-#if defined(AFIO_MAPR_PTP_PPS_REMAP)
-
-/**
- * @brief Enable the remapping of ADC2_ETRGREG (ADC 2 External trigger regular conversion).
- * @note ENABLE: PTP_PPS is output on PB5 pin.
- * @note This bit is available only in connectivity line devices and is reserved otherwise.
- * @retval None
- */
-#define __HAL_AFIO_ETH_PTP_PPS_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_PTP_PPS_REMAP)
-
-/**
- * @brief Disable the remapping of ADC2_ETRGREG (ADC 2 External trigger regular conversion).
- * @note DISABLE: PTP_PPS not output on PB5 pin.
- * @note This bit is available only in connectivity line devices and is reserved otherwise.
- * @retval None
- */
-#define __HAL_AFIO_ETH_PTP_PPS_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_PTP_PPS_REMAP)
-#endif
-
-#if defined(AFIO_MAPR2_TIM9_REMAP)
-
-/**
- * @brief Enable the remapping of TIM9_CH1 and TIM9_CH2.
- * @note ENABLE: Remap (TIM9_CH1 on PE5 and TIM9_CH2 on PE6).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM9_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM9_REMAP)
-
-/**
- * @brief Disable the remapping of TIM9_CH1 and TIM9_CH2.
- * @note DISABLE: No remap (TIM9_CH1 on PA2 and TIM9_CH2 on PA3).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM9_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM9_REMAP)
-#endif
-
-#if defined(AFIO_MAPR2_TIM10_REMAP)
-
-/**
- * @brief Enable the remapping of TIM10_CH1.
- * @note ENABLE: Remap (TIM10_CH1 on PF6).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM10_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM10_REMAP)
-
-/**
- * @brief Disable the remapping of TIM10_CH1.
- * @note DISABLE: No remap (TIM10_CH1 on PB8).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM10_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM10_REMAP)
-#endif
-
-#if defined(AFIO_MAPR2_TIM11_REMAP)
-/**
- * @brief Enable the remapping of TIM11_CH1.
- * @note ENABLE: Remap (TIM11_CH1 on PF7).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM11_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM11_REMAP)
-
-/**
- * @brief Disable the remapping of TIM11_CH1.
- * @note DISABLE: No remap (TIM11_CH1 on PB9).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM11_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM11_REMAP)
-#endif
-
-#if defined(AFIO_MAPR2_TIM13_REMAP)
-
-/**
- * @brief Enable the remapping of TIM13_CH1.
- * @note ENABLE: Remap STM32F100:(TIM13_CH1 on PF8). Others:(TIM13_CH1 on PB0).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM13_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM13_REMAP)
-
-/**
- * @brief Disable the remapping of TIM13_CH1.
- * @note DISABLE: No remap STM32F100:(TIM13_CH1 on PA6). Others:(TIM13_CH1 on PC8).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM13_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM13_REMAP)
-#endif
-
-#if defined(AFIO_MAPR2_TIM14_REMAP)
-
-/**
- * @brief Enable the remapping of TIM14_CH1.
- * @note ENABLE: Remap STM32F100:(TIM14_CH1 on PB1). Others:(TIM14_CH1 on PF9).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM14_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM14_REMAP)
-
-/**
- * @brief Disable the remapping of TIM14_CH1.
- * @note DISABLE: No remap STM32F100:(TIM14_CH1 on PC9). Others:(TIM14_CH1 on PA7).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM14_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM14_REMAP)
-#endif
-
-#if defined(AFIO_MAPR2_FSMC_NADV_REMAP)
-
-/**
- * @brief Controls the use of the optional FSMC_NADV signal.
- * @note DISCONNECTED: The NADV signal is not connected. The I/O pin can be used by another peripheral.
- * @retval None
- */
-#define __HAL_AFIO_FSMCNADV_DISCONNECTED() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_FSMC_NADV_REMAP)
-
-/**
- * @brief Controls the use of the optional FSMC_NADV signal.
- * @note CONNECTED: The NADV signal is connected to the output (default).
- * @retval None
- */
-#define __HAL_AFIO_FSMCNADV_CONNECTED() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_FSMC_NADV_REMAP)
-#endif
-
-#if defined(AFIO_MAPR2_TIM15_REMAP)
-
-/**
- * @brief Enable the remapping of TIM15_CH1 and TIM15_CH2.
- * @note ENABLE: Remap (TIM15_CH1 on PB14 and TIM15_CH2 on PB15).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM15_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM15_REMAP)
-
-/**
- * @brief Disable the remapping of TIM15_CH1 and TIM15_CH2.
- * @note DISABLE: No remap (TIM15_CH1 on PA2 and TIM15_CH2 on PA3).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM15_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM15_REMAP)
-#endif
-
-#if defined(AFIO_MAPR2_TIM16_REMAP)
-
-/**
- * @brief Enable the remapping of TIM16_CH1.
- * @note ENABLE: Remap (TIM16_CH1 on PA6).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM16_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM16_REMAP)
-
-/**
- * @brief Disable the remapping of TIM16_CH1.
- * @note DISABLE: No remap (TIM16_CH1 on PB8).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM16_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM16_REMAP)
-#endif
-
-#if defined(AFIO_MAPR2_TIM17_REMAP)
-
-/**
- * @brief Enable the remapping of TIM17_CH1.
- * @note ENABLE: Remap (TIM17_CH1 on PA7).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM17_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM17_REMAP)
-
-/**
- * @brief Disable the remapping of TIM17_CH1.
- * @note DISABLE: No remap (TIM17_CH1 on PB9).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM17_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM17_REMAP)
-#endif
-
-#if defined(AFIO_MAPR2_CEC_REMAP)
-
-/**
- * @brief Enable the remapping of CEC.
- * @note ENABLE: Remap (CEC on PB10).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_CEC_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_CEC_REMAP)
-
-/**
- * @brief Disable the remapping of CEC.
- * @note DISABLE: No remap (CEC on PB8).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_CEC_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_CEC_REMAP)
-#endif
-
-#if defined(AFIO_MAPR2_TIM1_DMA_REMAP)
-
-/**
- * @brief Controls the mapping of the TIM1_CH1 TIM1_CH2 DMA requests onto the DMA1 channels.
- * @note ENABLE: Remap (TIM1_CH1 DMA request/DMA1 Channel6, TIM1_CH2 DMA request/DMA1 Channel6)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM1DMA_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM1_DMA_REMAP)
-
-/**
- * @brief Controls the mapping of the TIM1_CH1 TIM1_CH2 DMA requests onto the DMA1 channels.
- * @note DISABLE: No remap (TIM1_CH1 DMA request/DMA1 Channel2, TIM1_CH2 DMA request/DMA1 Channel3).
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM1DMA_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM1_DMA_REMAP)
-#endif
-
-#if defined(AFIO_MAPR2_TIM67_DAC_DMA_REMAP)
-
-/**
- * @brief Controls the mapping of the TIM6_DAC1 and TIM7_DAC2 DMA requests onto the DMA1 channels.
- * @note ENABLE: Remap (TIM6_DAC1 DMA request/DMA1 Channel3, TIM7_DAC2 DMA request/DMA1 Channel4)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM67DACDMA_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM67_DAC_DMA_REMAP)
-
-/**
- * @brief Controls the mapping of the TIM6_DAC1 and TIM7_DAC2 DMA requests onto the DMA1 channels.
- * @note DISABLE: No remap (TIM6_DAC1 DMA request/DMA2 Channel3, TIM7_DAC2 DMA request/DMA2 Channel4)
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM67DACDMA_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM67_DAC_DMA_REMAP)
-#endif
-
-#if defined(AFIO_MAPR2_TIM12_REMAP)
-
-/**
- * @brief Enable the remapping of TIM12_CH1 and TIM12_CH2.
- * @note ENABLE: Remap (TIM12_CH1 on PB12 and TIM12_CH2 on PB13).
- * @note This bit is available only in high density value line devices.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM12_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM12_REMAP)
-
-/**
- * @brief Disable the remapping of TIM12_CH1 and TIM12_CH2.
- * @note DISABLE: No remap (TIM12_CH1 on PC4 and TIM12_CH2 on PC5).
- * @note This bit is available only in high density value line devices.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_TIM12_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM12_REMAP)
-#endif
-
-#if defined(AFIO_MAPR2_MISC_REMAP)
-
-/**
- * @brief Miscellaneous features remapping.
- * This bit is set and cleared by software. It controls miscellaneous features.
- * The DMA2 channel 5 interrupt position in the vector table.
- * The timer selection for DAC trigger 3 (TSEL[2:0] = 011, for more details refer to the DAC_CR register).
- * @note ENABLE: DMA2 channel 5 interrupt is mapped separately at position 60 and TIM15 TRGO event is
- * selected as DAC Trigger 3, TIM15 triggers TIM1/3.
- * @note This bit is available only in high density value line devices.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_MISC_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_MISC_REMAP)
-
-/**
- * @brief Miscellaneous features remapping.
- * This bit is set and cleared by software. It controls miscellaneous features.
- * The DMA2 channel 5 interrupt position in the vector table.
- * The timer selection for DAC trigger 3 (TSEL[2:0] = 011, for more details refer to the DAC_CR register).
- * @note DISABLE: DMA2 channel 5 interrupt is mapped with DMA2 channel 4 at position 59, TIM5 TRGO
- * event is selected as DAC Trigger 3, TIM5 triggers TIM1/3.
- * @note This bit is available only in high density value line devices.
- * @retval None
- */
-#define __HAL_AFIO_REMAP_MISC_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_MISC_REMAP)
-#endif
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @defgroup GPIOEx_Private_Macros GPIOEx Private Macros
- * @{
- */
-#if defined(STM32F101x6) || defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)
-#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0U :\
- ((__GPIOx__) == (GPIOB))? 1U :\
- ((__GPIOx__) == (GPIOC))? 2U :3U)
-#elif defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F103xB) || defined(STM32F105xC) || defined(STM32F107xC)
-#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0U :\
- ((__GPIOx__) == (GPIOB))? 1U :\
- ((__GPIOx__) == (GPIOC))? 2U :\
- ((__GPIOx__) == (GPIOD))? 3U :4U)
-#elif defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
-#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0U :\
- ((__GPIOx__) == (GPIOB))? 1U :\
- ((__GPIOx__) == (GPIOC))? 2U :\
- ((__GPIOx__) == (GPIOD))? 3U :\
- ((__GPIOx__) == (GPIOE))? 4U :\
- ((__GPIOx__) == (GPIOF))? 5U :6U)
-#endif
-
-#define AFIO_REMAP_ENABLE(REMAP_PIN) do{ uint32_t tmpreg = AFIO->MAPR; \
- tmpreg |= AFIO_MAPR_SWJ_CFG; \
- tmpreg |= REMAP_PIN; \
- AFIO->MAPR = tmpreg; \
- }while(0U)
-
-#define AFIO_REMAP_DISABLE(REMAP_PIN) do{ uint32_t tmpreg = AFIO->MAPR; \
- tmpreg |= AFIO_MAPR_SWJ_CFG; \
- tmpreg &= ~REMAP_PIN; \
- AFIO->MAPR = tmpreg; \
- }while(0U)
-
-#define AFIO_REMAP_PARTIAL(REMAP_PIN, REMAP_PIN_MASK) do{ uint32_t tmpreg = AFIO->MAPR; \
- tmpreg &= ~REMAP_PIN_MASK; \
- tmpreg |= AFIO_MAPR_SWJ_CFG; \
- tmpreg |= REMAP_PIN; \
- AFIO->MAPR = tmpreg; \
- }while(0U)
-
-#define AFIO_DBGAFR_CONFIG(DBGAFR_SWJCFG) do{ uint32_t tmpreg = AFIO->MAPR; \
- tmpreg &= ~AFIO_MAPR_SWJ_CFG_Msk; \
- tmpreg |= DBGAFR_SWJCFG; \
- AFIO->MAPR = tmpreg; \
- }while(0U)
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-
-/** @addtogroup GPIOEx_Exported_Functions
- * @{
- */
-
-/** @addtogroup GPIOEx_Exported_Functions_Group1
- * @{
- */
-void HAL_GPIOEx_ConfigEventout(uint32_t GPIO_PortSource, uint32_t GPIO_PinSource);
-void HAL_GPIOEx_EnableEventout(void);
-void HAL_GPIOEx_DisableEventout(void);
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_GPIO_EX_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_hcd.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_hcd.h
deleted file mode 100644
index f635e14..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_hcd.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_hcd.h
- * @author MCD Application Team
- * @brief Header file of HCD HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_HCD_H
-#define __STM32F1xx_HAL_HCD_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-#if defined(STM32F105xC) || defined(STM32F107xC)
-
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_usb.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup HCD
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup HCD_Exported_Types HCD Exported Types
- * @{
- */
-
-/**
- * @brief HCD Status structure definition
- */
-typedef enum
-{
- HAL_HCD_STATE_RESET = 0x00U,
- HAL_HCD_STATE_READY = 0x01U,
- HAL_HCD_STATE_ERROR = 0x02U,
- HAL_HCD_STATE_BUSY = 0x03U,
- HAL_HCD_STATE_TIMEOUT = 0x04U
-} HCD_StateTypeDef;
-
-typedef USB_OTG_GlobalTypeDef HCD_TypeDef;
-typedef USB_OTG_CfgTypeDef HCD_InitTypeDef;
-typedef USB_OTG_HCTypeDef HCD_HCTypeDef;
-typedef USB_OTG_URBStateTypeDef HCD_URBStateTypeDef;
-typedef USB_OTG_HCStateTypeDef HCD_HCStateTypeDef;
-
-/**
- * @brief HCD Handle Structure definition
- */
-typedef struct
-{
- HCD_TypeDef *Instance; /*!< Register base address */
- HCD_InitTypeDef Init; /*!< HCD required parameters */
- HCD_HCTypeDef hc[15U]; /*!< Host channels parameters */
- HAL_LockTypeDef Lock; /*!< HCD peripheral status */
- __IO HCD_StateTypeDef State; /*!< HCD communication state */
- void *pData; /*!< Pointer Stack Handler */
-} HCD_HandleTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup HCD_Exported_Constants HCD Exported Constants
- * @{
- */
-/** @defgroup HCD_Speed HCD Speed
- * @{
- */
-#define HCD_SPEED_LOW 2U
-#define HCD_SPEED_FULL 3U
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup HCD_Exported_Macros HCD Exported Macros
- * @brief macros to handle interrupts and specific clock configurations
- * @{
- */
-#define __HAL_HCD_ENABLE(__HANDLE__) USB_EnableGlobalInt ((__HANDLE__)->Instance)
-#define __HAL_HCD_DISABLE(__HANDLE__) USB_DisableGlobalInt ((__HANDLE__)->Instance)
-
-
-#define __HAL_HCD_GET_FLAG(__HANDLE__, __INTERRUPT__) ((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__))
-#define __HAL_HCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->GINTSTS) = (__INTERRUPT__))
-#define __HAL_HCD_IS_INVALID_INTERRUPT(__HANDLE__) (USB_ReadInterrupts((__HANDLE__)->Instance) == 0U)
-
-
-#define __HAL_HCD_CLEAR_HC_INT(chnum, __INTERRUPT__) (USBx_HC(chnum)->HCINT = (__INTERRUPT__))
-#define __HAL_HCD_MASK_HALT_HC_INT(chnum) (USBx_HC(chnum)->HCINTMSK &= ~USB_OTG_HCINTMSK_CHHM)
-#define __HAL_HCD_UNMASK_HALT_HC_INT(chnum) (USBx_HC(chnum)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM)
-#define __HAL_HCD_MASK_ACK_HC_INT(chnum) (USBx_HC(chnum)->HCINTMSK &= ~USB_OTG_HCINTMSK_ACKM)
-#define __HAL_HCD_UNMASK_ACK_HC_INT(chnum) (USBx_HC(chnum)->HCINTMSK |= USB_OTG_HCINTMSK_ACKM)
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup HCD_Exported_Functions HCD Exported Functions
- * @{
- */
-
-/* Initialization/de-initialization functions ********************************/
-/** @addtogroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
- * @{
- */
-HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd);
-HAL_StatusTypeDef HAL_HCD_DeInit (HCD_HandleTypeDef *hhcd);
-HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd,
- uint8_t ch_num,
- uint8_t epnum,
- uint8_t dev_address,
- uint8_t speed,
- uint8_t ep_type,
- uint16_t mps);
-
-HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd,
- uint8_t ch_num);
-
-void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd);
-void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd);
-/**
- * @}
- */
-
-/* I/O operation functions ***************************************************/
-/** @addtogroup HCD_Exported_Functions_Group2 IO operation functions
- * @{
- */
-HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
- uint8_t pipe,
- uint8_t direction,
- uint8_t ep_type,
- uint8_t token,
- uint8_t* pbuff,
- uint16_t length,
- uint8_t do_ping);
-
- /* Non-Blocking mode: Interrupt */
-void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd);
-void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd);
-void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd);
-void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd);
-void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd,
- uint8_t chnum,
- HCD_URBStateTypeDef urb_state);
-/**
- * @}
- */
-/* Peripheral Control functions **********************************************/
-/** @addtogroup HCD_Exported_Functions_Group3 Peripheral Control functions
- * @{
- */
-HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd);
-HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd);
-HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd);
-/**
- * @}
- */
-/* Peripheral State functions ************************************************/
-/** @addtogroup HCD_Exported_Functions_Group4 Peripheral State functions
- * @{
- */
-HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd);
-HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum);
-uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum);
-HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum);
-uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd);
-uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup HCD_Private_Macros HCD Private Macros
- * @{
- */
-/** @defgroup HCD_Instance_definition HCD Instance definition
- * @{
- */
- #define IS_HCD_ALL_INSTANCE(INSTANCE) (((INSTANCE) == USB_OTG_FS))
-/**
- * @}
- */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* STM32F105xC || STM32F107xC */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_HCD_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h
deleted file mode 100644
index f8a6839..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h
+++ /dev/null
@@ -1,650 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_i2c.h
- * @author MCD Application Team
- * @brief Header file of I2C HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_I2C_H
-#define __STM32F1xx_HAL_I2C_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup I2C
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup I2C_Exported_Types I2C Exported Types
- * @{
- */
-
-/**
- * @brief I2C Configuration Structure definition
- */
-typedef struct
-{
- uint32_t ClockSpeed; /*!< Specifies the clock frequency.
- This parameter must be set to a value lower than 400kHz */
-
- uint32_t DutyCycle; /*!< Specifies the I2C fast mode duty cycle.
- This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */
-
- uint32_t OwnAddress1; /*!< Specifies the first device own address.
- This parameter can be a 7-bit or 10-bit address. */
-
- uint32_t AddressingMode; /*!< Specifies if 7-bit or 10-bit addressing mode is selected.
- This parameter can be a value of @ref I2C_addressing_mode */
-
- uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected.
- This parameter can be a value of @ref I2C_dual_addressing_mode */
-
- uint32_t OwnAddress2; /*!< Specifies the second device own address if dual addressing mode is selected
- This parameter can be a 7-bit address. */
-
- uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected.
- This parameter can be a value of @ref I2C_general_call_addressing_mode */
-
- uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected.
- This parameter can be a value of @ref I2C_nostretch_mode */
-
-}I2C_InitTypeDef;
-
-/**
- * @brief HAL State structure definition
- * @note HAL I2C State value coding follow below described bitmap :
- * b7-b6 Error information
- * 00 : No Error
- * 01 : Abort (Abort user request on going)
- * 10 : Timeout
- * 11 : Error
- * b5 IP initilisation status
- * 0 : Reset (IP not initialized)
- * 1 : Init done (IP initialized and ready to use. HAL I2C Init function called)
- * b4 (not used)
- * x : Should be set to 0
- * b3
- * 0 : Ready or Busy (No Listen mode ongoing)
- * 1 : Listen (IP in Address Listen Mode)
- * b2 Intrinsic process state
- * 0 : Ready
- * 1 : Busy (IP busy with some configuration or internal operations)
- * b1 Rx state
- * 0 : Ready (no Rx operation ongoing)
- * 1 : Busy (Rx operation ongoing)
- * b0 Tx state
- * 0 : Ready (no Tx operation ongoing)
- * 1 : Busy (Tx operation ongoing)
- */
-typedef enum
-{
- HAL_I2C_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */
- HAL_I2C_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use */
- HAL_I2C_STATE_BUSY = 0x24U, /*!< An internal process is ongoing */
- HAL_I2C_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing */
- HAL_I2C_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */
- HAL_I2C_STATE_LISTEN = 0x28U, /*!< Address Listen Mode is ongoing */
- HAL_I2C_STATE_BUSY_TX_LISTEN = 0x29U, /*!< Address Listen Mode and Data Transmission
- process is ongoing */
- HAL_I2C_STATE_BUSY_RX_LISTEN = 0x2AU, /*!< Address Listen Mode and Data Reception
- process is ongoing */
- HAL_I2C_STATE_ABORT = 0x60U, /*!< Abort user request ongoing */
- HAL_I2C_STATE_TIMEOUT = 0xA0U, /*!< Timeout state */
- HAL_I2C_STATE_ERROR = 0xE0U /*!< Error */
-
-}HAL_I2C_StateTypeDef;
-
-/**
- * @brief HAL Mode structure definition
- * @note HAL I2C Mode value coding follow below described bitmap :
- * b7 (not used)
- * x : Should be set to 0
- * b6
- * 0 : None
- * 1 : Memory (HAL I2C communication is in Memory Mode)
- * b5
- * 0 : None
- * 1 : Slave (HAL I2C communication is in Slave Mode)
- * b4
- * 0 : None
- * 1 : Master (HAL I2C communication is in Master Mode)
- * b3-b2-b1-b0 (not used)
- * xxxx : Should be set to 0000
- */
-typedef enum
-{
- HAL_I2C_MODE_NONE = 0x00U, /*!< No I2C communication on going */
- HAL_I2C_MODE_MASTER = 0x10U, /*!< I2C communication is in Master Mode */
- HAL_I2C_MODE_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */
- HAL_I2C_MODE_MEM = 0x40U /*!< I2C communication is in Memory Mode */
-
-}HAL_I2C_ModeTypeDef;
-
-/**
- * @brief I2C handle Structure definition
- */
-typedef struct
-{
- I2C_TypeDef *Instance; /*!< I2C registers base address */
-
- I2C_InitTypeDef Init; /*!< I2C communication parameters */
-
- uint8_t *pBuffPtr; /*!< Pointer to I2C transfer buffer */
-
- uint16_t XferSize; /*!< I2C transfer size */
-
- __IO uint16_t XferCount; /*!< I2C transfer counter */
-
- __IO uint32_t XferOptions; /*!< I2C transfer options */
-
- __IO uint32_t PreviousState; /*!< I2C communication Previous state and mode
- context for internal usage */
-
- DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */
-
- DMA_HandleTypeDef *hdmarx; /*!< I2C Rx DMA handle parameters */
-
- HAL_LockTypeDef Lock; /*!< I2C locking object */
-
- __IO HAL_I2C_StateTypeDef State; /*!< I2C communication state */
-
- __IO HAL_I2C_ModeTypeDef Mode; /*!< I2C communication mode */
-
- __IO uint32_t ErrorCode; /*!< I2C Error code */
-
- __IO uint32_t Devaddress; /*!< I2C Target device address */
-
- __IO uint32_t Memaddress; /*!< I2C Target memory address */
-
- __IO uint32_t MemaddSize; /*!< I2C Target memory address size */
-
- __IO uint32_t EventCount; /*!< I2C Event counter */
-
-}I2C_HandleTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup I2C_Exported_Constants I2C Exported Constants
- * @{
- */
-
-/** @defgroup I2C_Error_Code I2C Error Code
- * @brief I2C Error Code
- * @{
- */
-#define HAL_I2C_ERROR_NONE 0x00000000U /*!< No error */
-#define HAL_I2C_ERROR_BERR 0x00000001U /*!< BERR error */
-#define HAL_I2C_ERROR_ARLO 0x00000002U /*!< ARLO error */
-#define HAL_I2C_ERROR_AF 0x00000004U /*!< AF error */
-#define HAL_I2C_ERROR_OVR 0x00000008U /*!< OVR error */
-#define HAL_I2C_ERROR_DMA 0x00000010U /*!< DMA transfer error */
-#define HAL_I2C_ERROR_TIMEOUT 0x00000020U /*!< Timeout Error */
-/**
- * @}
- */
-
-/** @defgroup I2C_duty_cycle_in_fast_mode I2C duty cycle in fast mode
- * @{
- */
-#define I2C_DUTYCYCLE_2 0x00000000U
-#define I2C_DUTYCYCLE_16_9 I2C_CCR_DUTY
-/**
- * @}
- */
-
-/** @defgroup I2C_addressing_mode I2C addressing mode
- * @{
- */
-#define I2C_ADDRESSINGMODE_7BIT 0x00004000U
-#define I2C_ADDRESSINGMODE_10BIT (I2C_OAR1_ADDMODE | 0x00004000U)
-/**
- * @}
- */
-
-/** @defgroup I2C_dual_addressing_mode I2C dual addressing mode
- * @{
- */
-#define I2C_DUALADDRESS_DISABLE 0x00000000U
-#define I2C_DUALADDRESS_ENABLE I2C_OAR2_ENDUAL
-/**
- * @}
- */
-
-/** @defgroup I2C_general_call_addressing_mode I2C general call addressing mode
- * @{
- */
-#define I2C_GENERALCALL_DISABLE 0x00000000U
-#define I2C_GENERALCALL_ENABLE I2C_CR1_ENGC
-/**
- * @}
- */
-
-/** @defgroup I2C_nostretch_mode I2C nostretch mode
- * @{
- */
-#define I2C_NOSTRETCH_DISABLE 0x00000000U
-#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH
-/**
- * @}
- */
-
-/** @defgroup I2C_Memory_Address_Size I2C Memory Address Size
- * @{
- */
-#define I2C_MEMADD_SIZE_8BIT 0x00000001U
-#define I2C_MEMADD_SIZE_16BIT 0x00000010U
-/**
- * @}
- */
-
-/** @defgroup I2C_XferDirection_definition I2C XferDirection definition
- * @{
- */
-#define I2C_DIRECTION_RECEIVE 0x00000000U
-#define I2C_DIRECTION_TRANSMIT 0x00000001U
-/**
- * @}
- */
-
-/** @defgroup I2C_XferOptions_definition I2C XferOptions definition
- * @{
- */
-#define I2C_FIRST_FRAME 0x00000001U
-#define I2C_NEXT_FRAME 0x00000002U
-#define I2C_FIRST_AND_LAST_FRAME 0x00000004U
-#define I2C_LAST_FRAME 0x00000008U
-/**
- * @}
- */
-
-/** @defgroup I2C_Interrupt_configuration_definition I2C Interrupt configuration definition
- * @{
- */
-#define I2C_IT_BUF I2C_CR2_ITBUFEN
-#define I2C_IT_EVT I2C_CR2_ITEVTEN
-#define I2C_IT_ERR I2C_CR2_ITERREN
-/**
- * @}
- */
-
-/** @defgroup I2C_Flag_definition I2C Flag definition
- * @{
- */
-#define I2C_FLAG_SMBALERT 0x00018000U
-#define I2C_FLAG_TIMEOUT 0x00014000U
-#define I2C_FLAG_PECERR 0x00011000U
-#define I2C_FLAG_OVR 0x00010800U
-#define I2C_FLAG_AF 0x00010400U
-#define I2C_FLAG_ARLO 0x00010200U
-#define I2C_FLAG_BERR 0x00010100U
-#define I2C_FLAG_TXE 0x00010080U
-#define I2C_FLAG_RXNE 0x00010040U
-#define I2C_FLAG_STOPF 0x00010010U
-#define I2C_FLAG_ADD10 0x00010008U
-#define I2C_FLAG_BTF 0x00010004U
-#define I2C_FLAG_ADDR 0x00010002U
-#define I2C_FLAG_SB 0x00010001U
-#define I2C_FLAG_DUALF 0x00100080U
-#define I2C_FLAG_SMBHOST 0x00100040U
-#define I2C_FLAG_SMBDEFAULT 0x00100020U
-#define I2C_FLAG_GENCALL 0x00100010U
-#define I2C_FLAG_TRA 0x00100004U
-#define I2C_FLAG_BUSY 0x00100002U
-#define I2C_FLAG_MSL 0x00100001U
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup I2C_Exported_Macros I2C Exported Macros
- * @{
- */
-
-/** @brief Reset I2C handle state
- * @param __HANDLE__: specifies the I2C Handle.
- * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
- * @retval None
- */
-#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2C_STATE_RESET)
-
-/** @brief Enable or disable the specified I2C interrupts.
- * @param __HANDLE__: specifies the I2C Handle.
- * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
- * @param __INTERRUPT__: specifies the interrupt source to enable or disable.
- * This parameter can be one of the following values:
- * @arg I2C_IT_BUF: Buffer interrupt enable
- * @arg I2C_IT_EVT: Event interrupt enable
- * @arg I2C_IT_ERR: Error interrupt enable
- * @retval None
- */
-#define __HAL_I2C_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 |= (__INTERRUPT__))
-#define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 &= (~(__INTERRUPT__)))
-
-/** @brief Checks if the specified I2C interrupt source is enabled or disabled.
- * @param __HANDLE__: specifies the I2C Handle.
- * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
- * @param __INTERRUPT__: specifies the I2C interrupt source to check.
- * This parameter can be one of the following values:
- * @arg I2C_IT_BUF: Buffer interrupt enable
- * @arg I2C_IT_EVT: Event interrupt enable
- * @arg I2C_IT_ERR: Error interrupt enable
- * @retval The new state of __INTERRUPT__ (TRUE or FALSE).
- */
-#define __HAL_I2C_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
-
-/** @brief Checks whether the specified I2C flag is set or not.
- * @param __HANDLE__: specifies the I2C Handle.
- * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be one 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
- * @arg I2C_FLAG_AF: Acknowledge failure flag
- * @arg I2C_FLAG_ARLO: Arbitration lost flag
- * @arg I2C_FLAG_BERR: Bus error flag
- * @arg I2C_FLAG_TXE: Data register empty flag
- * @arg I2C_FLAG_RXNE: Data register not empty flag
- * @arg I2C_FLAG_STOPF: Stop detection flag
- * @arg I2C_FLAG_ADD10: 10-bit header sent flag
- * @arg I2C_FLAG_BTF: Byte transfer finished flag
- * @arg I2C_FLAG_ADDR: Address sent flag
- * Address matched flag
- * @arg I2C_FLAG_SB: Start bit flag
- * @arg I2C_FLAG_DUALF: Dual flag
- * @arg I2C_FLAG_SMBHOST: SMBus host header
- * @arg I2C_FLAG_SMBDEFAULT: SMBus default header
- * @arg I2C_FLAG_GENCALL: General call header flag
- * @arg I2C_FLAG_TRA: Transmitter/Receiver flag
- * @arg I2C_FLAG_BUSY: Bus busy flag
- * @arg I2C_FLAG_MSL: Master/Slave flag
- * @retval The new state of __FLAG__ (TRUE or FALSE).
- */
-#define __HAL_I2C_GET_FLAG(__HANDLE__, __FLAG__) ((((uint8_t)((__FLAG__) >> 16U)) == 0x01U)?((((__HANDLE__)->Instance->SR1) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)): \
- ((((__HANDLE__)->Instance->SR2) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)))
-
-/** @brief Clears the I2C pending flags which are cleared by writing 0 in a specific bit.
- * @param __HANDLE__: specifies the I2C Handle.
- * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
- * @param __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
- * @retval None
- */
-#define __HAL_I2C_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR1 = ~((__FLAG__) & I2C_FLAG_MASK))
-
-/** @brief Clears the I2C ADDR pending flag.
- * @param __HANDLE__: specifies the I2C Handle.
- * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
- * @retval None
- */
-#define __HAL_I2C_CLEAR_ADDRFLAG(__HANDLE__) \
- do{ \
- __IO uint32_t tmpreg = 0x00U; \
- tmpreg = (__HANDLE__)->Instance->SR1; \
- tmpreg = (__HANDLE__)->Instance->SR2; \
- UNUSED(tmpreg); \
- } while(0U)
-
-/** @brief Clears the I2C STOPF pending flag.
- * @param __HANDLE__: specifies the I2C Handle.
- * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
- * @retval None
- */
-#define __HAL_I2C_CLEAR_STOPFLAG(__HANDLE__) \
- do{ \
- __IO uint32_t tmpreg = 0x00U; \
- tmpreg = (__HANDLE__)->Instance->SR1; \
- (__HANDLE__)->Instance->CR1 |= I2C_CR1_PE; \
- UNUSED(tmpreg); \
- } while(0U)
-
-/** @brief Enable the I2C peripheral.
- * @param __HANDLE__: specifies the I2C Handle.
- * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral.
- * @retval None
- */
-#define __HAL_I2C_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= I2C_CR1_PE)
-
-/** @brief Disable the I2C peripheral.
- * @param __HANDLE__: specifies the I2C Handle.
- * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral.
- * @retval None
- */
-#define __HAL_I2C_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~I2C_CR1_PE)
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup I2C_Exported_Functions
- * @{
- */
-
-/** @addtogroup I2C_Exported_Functions_Group1
- * @{
- */
-/* Initialization/de-initialization functions **********************************/
-HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c);
-HAL_StatusTypeDef HAL_I2C_DeInit (I2C_HandleTypeDef *hi2c);
-void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c);
-/**
- * @}
- */
-
-/** @addtogroup I2C_Exported_Functions_Group2
- * @{
- */
-/* I/O operation functions *****************************************************/
-/******* Blocking mode: Polling */
-HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout);
-
-/******* Non-Blocking mode: Interrupt */
-HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
-
-HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
-HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
-HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
-HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
-HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress);
-HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c);
-HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c);
-
-/******* Non-Blocking mode: DMA */
-HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
-
-/******* I2C IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */
-void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode);
-void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c);
-/**
- * @}
- */
-
-/** @addtogroup I2C_Exported_Functions_Group3
- * @{
- */
-/* Peripheral State, Mode and Errors functions *********************************/
-HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c);
-HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c);
-uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c);
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup I2C_Private_Constants I2C Private Constants
- * @{
- */
-#define I2C_FLAG_MASK 0x0000FFFFU
-#define I2C_MIN_PCLK_FREQ_STANDARD 2000000U /*!< 2 MHz */
-#define I2C_MIN_PCLK_FREQ_FAST 4000000U /*!< 4 MHz */
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup I2C_Private_Macros I2C Private Macros
- * @{
- */
-
-#define I2C_MIN_PCLK_FREQ(__PCLK__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__PCLK__) < I2C_MIN_PCLK_FREQ_STANDARD) : ((__PCLK__) < I2C_MIN_PCLK_FREQ_FAST))
-#define I2C_CCR_CALCULATION(__PCLK__, __SPEED__, __COEFF__) (((((__PCLK__) - 1U)/((__SPEED__) * (__COEFF__))) + 1U) & I2C_CCR_CCR)
-#define I2C_FREQRANGE(__PCLK__) ((__PCLK__)/1000000U)
-#define I2C_RISE_TIME(__FREQRANGE__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__FREQRANGE__) + 1U) : ((((__FREQRANGE__) * 300U) / 1000U) + 1U))
-#define I2C_SPEED_STANDARD(__PCLK__, __SPEED__) ((I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 2U) < 4U)? 4U:I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 2U))
-#define I2C_SPEED_FAST(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__DUTYCYCLE__) == I2C_DUTYCYCLE_2)? I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 3U) : (I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 25U) | I2C_DUTYCYCLE_16_9))
-#define I2C_SPEED(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__SPEED__) <= 100000U)? (I2C_SPEED_STANDARD((__PCLK__), (__SPEED__))) : \
- ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__)) & I2C_CCR_CCR) == 0U)? 1U : \
- ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__))) | I2C_CCR_FS))
-
-#define I2C_7BIT_ADD_WRITE(__ADDRESS__) ((uint8_t)((__ADDRESS__) & (~I2C_OAR1_ADD0)))
-#define I2C_7BIT_ADD_READ(__ADDRESS__) ((uint8_t)((__ADDRESS__) | I2C_OAR1_ADD0))
-
-#define I2C_10BIT_ADDRESS(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FFU))))
-#define I2C_10BIT_HEADER_WRITE(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0x0300U))) >> 7U) | (uint16_t)(0x00F0U))))
-#define I2C_10BIT_HEADER_READ(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0x0300U))) >> 7U) | (uint16_t)(0x00F1U))))
-
-#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0xFF00U))) >> 8U)))
-#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FFU))))
-
-/** @defgroup I2C_IS_RTC_Definitions I2C Private macros to check input parameters
- * @{
- */
-#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DUTYCYCLE_2) || \
- ((CYCLE) == I2C_DUTYCYCLE_16_9))
-#define IS_I2C_ADDRESSING_MODE(ADDRESS) (((ADDRESS) == I2C_ADDRESSINGMODE_7BIT) || \
- ((ADDRESS) == I2C_ADDRESSINGMODE_10BIT))
-#define IS_I2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == I2C_DUALADDRESS_DISABLE) || \
- ((ADDRESS) == I2C_DUALADDRESS_ENABLE))
-#define IS_I2C_GENERAL_CALL(CALL) (((CALL) == I2C_GENERALCALL_DISABLE) || \
- ((CALL) == I2C_GENERALCALL_ENABLE))
-#define IS_I2C_NO_STRETCH(STRETCH) (((STRETCH) == I2C_NOSTRETCH_DISABLE) || \
- ((STRETCH) == I2C_NOSTRETCH_ENABLE))
-#define IS_I2C_MEMADD_SIZE(SIZE) (((SIZE) == I2C_MEMADD_SIZE_8BIT) || \
- ((SIZE) == I2C_MEMADD_SIZE_16BIT))
-#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) > 0) && ((SPEED) <= 400000U))
-#define IS_I2C_OWN_ADDRESS1(ADDRESS1) (((ADDRESS1) & (uint32_t)(0xFFFFFC00U)) == 0U)
-#define IS_I2C_OWN_ADDRESS2(ADDRESS2) (((ADDRESS2) & (uint32_t)(0xFFFFFF01U)) == 0U)
-#define IS_I2C_TRANSFER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_FIRST_FRAME) || \
- ((REQUEST) == I2C_NEXT_FRAME) || \
- ((REQUEST) == I2C_FIRST_AND_LAST_FRAME) || \
- ((REQUEST) == I2C_LAST_FRAME))
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private functions ---------------------------------------------------------*/
-/** @defgroup I2C_Private_Functions I2C Private Functions
- * @{
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* __STM32F1xx_HAL_I2C_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2s.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2s.h
deleted file mode 100644
index 787d4ca..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2s.h
+++ /dev/null
@@ -1,491 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_i2s.h
- * @author MCD Application Team
- * @brief Header file of I2S HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_I2S_H
-#define __STM32F1xx_HAL_I2S_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-#if defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup I2S
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup I2S_Exported_Types I2S Exported Types
- * @{
- */
-
-/**
- * @brief I2S Init structure definition
- */
-typedef struct
-{
- uint32_t Mode; /*!< Specifies the I2S operating mode.
- This parameter can be a value of @ref I2S_Mode */
-
- uint32_t Standard; /*!< Specifies the standard used for the I2S communication.
- This parameter can be a value of @ref I2S_Standard */
-
- uint32_t DataFormat; /*!< Specifies the data format for the I2S communication.
- This parameter can be a value of @ref I2S_Data_Format */
-
- uint32_t MCLKOutput; /*!< Specifies whether the I2S MCLK output is enabled or not.
- This parameter can be a value of @ref I2S_MCLK_Output */
-
- uint32_t AudioFreq; /*!< Specifies the frequency selected for the I2S communication.
- This parameter can be a value of @ref I2S_Audio_Frequency */
-
- uint32_t CPOL; /*!< Specifies the idle state of the I2S clock.
- This parameter can be a value of @ref I2S_Clock_Polarity */
-}I2S_InitTypeDef;
-
-/**
- * @brief HAL State structures definition
- */
-typedef enum
-{
- HAL_I2S_STATE_RESET = 0x00U, /*!< I2S not yet initialized or disabled */
- HAL_I2S_STATE_READY = 0x01U, /*!< I2S initialized and ready for use */
- HAL_I2S_STATE_BUSY = 0x02U, /*!< I2S internal process is ongoing */
- HAL_I2S_STATE_BUSY_TX = 0x03U, /*!< Data Transmission process is ongoing */
- HAL_I2S_STATE_BUSY_RX = 0x04U, /*!< Data Reception process is ongoing */
- HAL_I2S_STATE_BUSY_TX_RX = 0x05U, /*!< Data Transmission and Reception process is ongoing */
- HAL_I2S_STATE_TIMEOUT = 0x06U, /*!< I2S timeout state */
- HAL_I2S_STATE_ERROR = 0x07U /*!< I2S error state */
-
-}HAL_I2S_StateTypeDef;
-
-/**
- * @brief I2S handle Structure definition
- */
-typedef struct __I2S_HandleTypeDef
-{
- SPI_TypeDef *Instance; /*!< I2S registers base address */
-
- I2S_InitTypeDef Init; /*!< I2S communication parameters */
-
- uint16_t *pTxBuffPtr; /*!< Pointer to I2S Tx transfer buffer */
-
- __IO uint16_t TxXferSize; /*!< I2S Tx transfer size */
-
- __IO uint16_t TxXferCount; /*!< I2S Tx transfer Counter */
-
- uint16_t *pRxBuffPtr; /*!< Pointer to I2S Rx transfer buffer */
-
- __IO uint16_t RxXferSize; /*!< I2S Rx transfer size */
-
- __IO uint16_t RxXferCount; /*!< I2S Rx transfer counter
- (This field is initialized at the
- same value as transfer size at the
- beginning of the transfer and
- decremented when a sample is received
- NbSamplesReceived = RxBufferSize-RxBufferCount) */
-
- void (*IrqHandlerISR) (struct __I2S_HandleTypeDef *hi2s); /*!< I2S function pointer on IrqHandler */
-
- DMA_HandleTypeDef *hdmatx; /*!< I2S Tx DMA handle parameters */
-
- DMA_HandleTypeDef *hdmarx; /*!< I2S Rx DMA handle parameters */
-
- __IO HAL_LockTypeDef Lock; /*!< I2S locking object */
-
- __IO HAL_I2S_StateTypeDef State; /*!< I2S communication state */
-
- __IO uint32_t ErrorCode; /*!< I2S Error code
- This parameter can be a value of @ref I2S_ErrorCode */
-
-}I2S_HandleTypeDef;
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup I2S_Exported_Constants I2S Exported Constants
- * @{
- */
-/**
- * @defgroup I2S_ErrorCode I2S Error Code
- * @{
- */
-#define HAL_I2S_ERROR_NONE 0x00000000U /*!< No error */
-#define HAL_I2S_ERROR_TIMEOUT 0x00000001U /*!< Timeout error */
-#define HAL_I2S_ERROR_OVR 0x00000002U /*!< OVR error */
-#define HAL_I2S_ERROR_UDR 0x00000004U /*!< UDR error */
-#define HAL_I2S_ERROR_DMA 0x00000008U /*!< DMA transfer error */
-#define HAL_I2S_ERROR_PRESCALER 0x00000010U /*!< Prescaler Calculation error */
-/**
- * @}
- */
-
-/** @defgroup I2S_Mode I2S Mode
- * @{
- */
-#define I2S_MODE_SLAVE_TX 0x00000000U
-#define I2S_MODE_SLAVE_RX ((uint32_t)SPI_I2SCFGR_I2SCFG_0)
-#define I2S_MODE_MASTER_TX ((uint32_t)SPI_I2SCFGR_I2SCFG_1)
-#define I2S_MODE_MASTER_RX ((uint32_t)(SPI_I2SCFGR_I2SCFG_0 | SPI_I2SCFGR_I2SCFG_1))
-/**
- * @}
- */
-
-/** @defgroup I2S_Standard I2S Standard
- * @{
- */
-#define I2S_STANDARD_PHILIPS 0x00000000U
-#define I2S_STANDARD_MSB ((uint32_t)SPI_I2SCFGR_I2SSTD_0)
-#define I2S_STANDARD_LSB ((uint32_t)SPI_I2SCFGR_I2SSTD_1)
-#define I2S_STANDARD_PCM_SHORT ((uint32_t)(SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1))
-#define I2S_STANDARD_PCM_LONG ((uint32_t)(SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1 | SPI_I2SCFGR_PCMSYNC))
-/**
- * @}
- */
-
-/** @defgroup I2S_Data_Format I2S Data Format
- * @{
- */
-#define I2S_DATAFORMAT_16B 0x00000000U
-#define I2S_DATAFORMAT_16B_EXTENDED ((uint32_t)SPI_I2SCFGR_CHLEN)
-#define I2S_DATAFORMAT_24B ((uint32_t)(SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN_0))
-#define I2S_DATAFORMAT_32B ((uint32_t)(SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN_1))
-/**
- * @}
- */
-
-/** @defgroup I2S_MCLK_Output I2S Mclk Output
- * @{
- */
-#define I2S_MCLKOUTPUT_ENABLE ((uint32_t)SPI_I2SPR_MCKOE)
-#define I2S_MCLKOUTPUT_DISABLE 0x00000000U
-/**
- * @}
- */
-
-/** @defgroup I2S_Audio_Frequency I2S Audio Frequency
- * @{
- */
-#define I2S_AUDIOFREQ_192K 192000U
-#define I2S_AUDIOFREQ_96K 96000U
-#define I2S_AUDIOFREQ_48K 48000U
-#define I2S_AUDIOFREQ_44K 44100U
-#define I2S_AUDIOFREQ_32K 32000U
-#define I2S_AUDIOFREQ_22K 22050U
-#define I2S_AUDIOFREQ_16K 16000U
-#define I2S_AUDIOFREQ_11K 11025U
-#define I2S_AUDIOFREQ_8K 8000U
-#define I2S_AUDIOFREQ_DEFAULT 2U
-/**
- * @}
- */
-
-/** @defgroup I2S_Clock_Polarity I2S Clock Polarity
- * @{
- */
-#define I2S_CPOL_LOW 0x00000000U
-#define I2S_CPOL_HIGH ((uint32_t)SPI_I2SCFGR_CKPOL)
-/**
- * @}
- */
-
-/** @defgroup I2S_Interrupts_Definition I2S Interrupts Definition
- * @{
- */
-#define I2S_IT_TXE SPI_CR2_TXEIE
-#define I2S_IT_RXNE SPI_CR2_RXNEIE
-#define I2S_IT_ERR SPI_CR2_ERRIE
-/**
- * @}
- */
-
-/** @defgroup I2S_Flags_Definition I2S Flags Definition
- * @{
- */
-#define I2S_FLAG_TXE SPI_SR_TXE
-#define I2S_FLAG_RXNE SPI_SR_RXNE
-
-#define I2S_FLAG_UDR SPI_SR_UDR
-#define I2S_FLAG_OVR SPI_SR_OVR
-#define I2S_FLAG_FRE SPI_SR_FRE
-
-#define I2S_FLAG_CHSIDE SPI_SR_CHSIDE
-#define I2S_FLAG_BSY SPI_SR_BSY
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup I2S_Exported_Macros I2S Exported Macros
- * @{
- */
-
-/** @brief Reset I2S handle state
- * @param __HANDLE__: specifies the I2S Handle.
- * @retval None
- */
-#define __HAL_I2S_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2S_STATE_RESET)
-
-/** @brief Enable the specified SPI peripheral (in I2S mode).
- * @param __HANDLE__: specifies the I2S Handle.
- * @retval None
- */
-#define __HAL_I2S_ENABLE(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
-
-/** @brief Disable the specified SPI peripheral (in I2S mode).
- * @param __HANDLE__: specifies the I2S Handle.
- * @retval None
- */
-#define __HAL_I2S_DISABLE(__HANDLE__) (CLEAR_BIT((__HANDLE__)->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
-
-/** @brief Enable the specified I2S interrupts.
- * @param __HANDLE__: specifies the I2S Handle.
- * @param __INTERRUPT__: specifies the interrupt source to enable or disable.
- * This parameter can be one of the following values:
- * @arg I2S_IT_TXE: Tx buffer empty interrupt enable
- * @arg I2S_IT_RXNE: RX buffer not empty interrupt enable
- * @arg I2S_IT_ERR: Error interrupt enable
- * @retval None
- */
-#define __HAL_I2S_ENABLE_IT(__HANDLE__, __INTERRUPT__) (SET_BIT((__HANDLE__)->Instance->CR2,(__INTERRUPT__)))
-
-/** @brief Disable the specified I2S interrupts.
- * @param __HANDLE__: specifies the I2S Handle.
- * @param __INTERRUPT__: specifies the interrupt source to enable or disable.
- * This parameter can be one of the following values:
- * @arg I2S_IT_TXE: Tx buffer empty interrupt enable
- * @arg I2S_IT_RXNE: RX buffer not empty interrupt enable
- * @arg I2S_IT_ERR: Error interrupt enable
- * @retval None
- */
-#define __HAL_I2S_DISABLE_IT(__HANDLE__, __INTERRUPT__) (CLEAR_BIT((__HANDLE__)->Instance->CR2,(__INTERRUPT__)))
-
-/** @brief Checks if the specified I2S interrupt source is enabled or disabled.
- * @param __HANDLE__: specifies the I2S Handle.
- * This parameter can be I2S where x: 1, 2, or 3 to select the I2S peripheral.
- * @param __INTERRUPT__: specifies the I2S interrupt source to check.
- * This parameter can be one of the following values:
- * @arg I2S_IT_TXE: Tx buffer empty interrupt enable
- * @arg I2S_IT_RXNE: RX buffer not empty interrupt enable
- * @arg I2S_IT_ERR: Error interrupt enable
- * @retval The new state of __IT__ (TRUE or FALSE).
- */
-#define __HAL_I2S_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
-
-/** @brief Checks whether the specified I2S flag is set or not.
- * @param __HANDLE__: specifies the I2S Handle.
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg I2S_FLAG_RXNE: Receive buffer not empty flag
- * @arg I2S_FLAG_TXE: Transmit buffer empty flag
- * @arg I2S_FLAG_UDR: Underrun flag
- * @arg I2S_FLAG_OVR: Overrun flag
- * @arg I2S_FLAG_FRE: Frame error flag
- * @arg I2S_FLAG_CHSIDE: Channel Side flag
- * @arg I2S_FLAG_BSY: Busy flag
- * @retval The new state of __FLAG__ (TRUE or FALSE).
- */
-#define __HAL_I2S_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__))
-
-/** @brief Clears the I2S OVR pending flag.
- * @param __HANDLE__: specifies the I2S Handle.
- * @retval None
- */
-#define __HAL_I2S_CLEAR_OVRFLAG(__HANDLE__) \
- do{ \
- __IO uint32_t tmpreg = 0x00U; \
- tmpreg = (__HANDLE__)->Instance->DR; \
- tmpreg = (__HANDLE__)->Instance->SR; \
- UNUSED(tmpreg); \
- } while(0U)
-
-/** @brief Clears the I2S UDR pending flag.
- * @param __HANDLE__: specifies the I2S Handle.
- * @retval None
- */
-#define __HAL_I2S_CLEAR_UDRFLAG(__HANDLE__) \
- do{ \
- __IO uint32_t tmpreg = 0x00U; \
- tmpreg = (__HANDLE__)->Instance->SR; \
- UNUSED(tmpreg); \
- } while(0U)
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup I2S_Exported_Functions
- * @{
- */
-
-/** @addtogroup I2S_Exported_Functions_Group1
- * @{
- */
-/* Initialization/de-initialization functions ********************************/
-HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s);
-HAL_StatusTypeDef HAL_I2S_DeInit (I2S_HandleTypeDef *hi2s);
-void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s);
-void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s);
-/**
- * @}
- */
-
-/** @addtogroup I2S_Exported_Functions_Group2
- * @{
- */
-/* I/O operation functions ***************************************************/
-/* Blocking mode: Polling */
-HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout);
-
- /* Non-Blocking mode: Interrupt */
-HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size);
-void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s);
-
-/* Non-Blocking mode: DMA */
-HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size);
-
-HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s);
-HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s);
-HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s);
-
-/* Callbacks used in non blocking modes (Interrupt and DMA) *******************/
-void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s);
-void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s);
-void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s);
-void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s);
-void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s);
-/**
- * @}
- */
-
-/** @addtogroup I2S_Exported_Functions_Group3
- * @{
- */
-/* Peripheral Control and State functions ************************************/
-HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s);
-uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup I2S_Private_Constants I2S Private Constants
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup I2S_Private_Macros I2S Private Macros
- * @{
- */
-#define IS_I2S_MODE(MODE) (((MODE) == I2S_MODE_SLAVE_TX) || \
- ((MODE) == I2S_MODE_SLAVE_RX) || \
- ((MODE) == I2S_MODE_MASTER_TX) || \
- ((MODE) == I2S_MODE_MASTER_RX))
-
-#define IS_I2S_STANDARD(STANDARD) (((STANDARD) == I2S_STANDARD_PHILIPS) || \
- ((STANDARD) == I2S_STANDARD_MSB) || \
- ((STANDARD) == I2S_STANDARD_LSB) || \
- ((STANDARD) == I2S_STANDARD_PCM_SHORT) || \
- ((STANDARD) == I2S_STANDARD_PCM_LONG))
-
-#define IS_I2S_DATA_FORMAT(FORMAT) (((FORMAT) == I2S_DATAFORMAT_16B) || \
- ((FORMAT) == I2S_DATAFORMAT_16B_EXTENDED) || \
- ((FORMAT) == I2S_DATAFORMAT_24B) || \
- ((FORMAT) == I2S_DATAFORMAT_32B))
-
-#define IS_I2S_MCLK_OUTPUT(OUTPUT) (((OUTPUT) == I2S_MCLKOUTPUT_ENABLE) || \
- ((OUTPUT) == I2S_MCLKOUTPUT_DISABLE))
-
-#define IS_I2S_AUDIO_FREQ(FREQ) ((((FREQ) >= I2S_AUDIOFREQ_8K) && \
- ((FREQ) <= I2S_AUDIOFREQ_192K)) || \
- ((FREQ) == I2S_AUDIOFREQ_DEFAULT))
-
-#define IS_I2S_CPOL(CPOL) (((CPOL) == I2S_CPOL_LOW) || \
- ((CPOL) == I2S_CPOL_HIGH))
-/**
- * @}
- */
-
-/* Private Fonctions ---------------------------------------------------------*/
-/** @defgroup I2S_Private_Functions I2S Private Functions
- * @{
- */
-/* Private functions are defined in stm32f1xx_hal_i2s.c file */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-#endif /* STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_I2S_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_irda.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_irda.h
deleted file mode 100644
index 7c64c1e..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_irda.h
+++ /dev/null
@@ -1,597 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_irda.h
- * @author MCD Application Team
- * @brief Header file of IRDA HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_IRDA_H
-#define __STM32F1xx_HAL_IRDA_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup IRDA
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup IRDA_Exported_Types IRDA Exported Types
- * @{
- */
-
-/**
- * @brief IRDA Init Structure definition
- */
-typedef struct
-{
- uint32_t BaudRate; /*!< This member configures the IRDA communication baud rate.
- The baud rate is computed using the following formula:
- - IntegerDivider = ((PCLKx) / (16 * (hirda->Init.BaudRate)))
- - FractionalDivider = ((IntegerDivider - ((uint32_t) IntegerDivider)) * 16) + 0.5 */
-
- uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame.
- This parameter can be a value of @ref IRDA_Word_Length */
-
-
- uint32_t Parity; /*!< Specifies the parity mode.
- This parameter can be a value of @ref IRDA_Parity
- @note When parity is enabled, the computed parity is inserted
- at the MSB position of the transmitted data (9th bit when
- the word length is set to 9 data bits; 8th bit when the
- word length is set to 8 data bits). */
-
- uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.
- This parameter can be a value of @ref IRDA_Transfer_Mode */
-
- uint8_t Prescaler; /*!< Specifies the Prescaler value prescaler value to be programmed
- in the IrDA low-power Baud Register, for defining pulse width on which
- burst acceptance/rejection will be decided. This value is used as divisor
- of system clock to achieve required pulse width. */
-
- uint32_t IrDAMode; /*!< Specifies the IrDA mode
- This parameter can be a value of @ref IRDA_Low_Power */
-}IRDA_InitTypeDef;
-
-/**
- * @brief HAL IRDA State structures definition
- * @note HAL IRDA State value is a combination of 2 different substates: gState and RxState.
- * - gState contains IRDA state information related to global Handle management
- * and also information related to Tx operations.
- * gState value coding follow below described bitmap :
- * b7-b6 Error information
- * 00 : No Error
- * 01 : (Not Used)
- * 10 : Timeout
- * 11 : Error
- * b5 IP initilisation status
- * 0 : Reset (IP not initialized)
- * 1 : Init done (IP not initialized. HAL IRDA Init function already called)
- * b4-b3 (not used)
- * xx : Should be set to 00
- * b2 Intrinsic process state
- * 0 : Ready
- * 1 : Busy (IP busy with some configuration or internal operations)
- * b1 (not used)
- * x : Should be set to 0
- * b0 Tx state
- * 0 : Ready (no Tx operation ongoing)
- * 1 : Busy (Tx operation ongoing)
- * - RxState contains information related to Rx operations.
- * RxState value coding follow below described bitmap :
- * b7-b6 (not used)
- * xx : Should be set to 00
- * b5 IP initilisation status
- * 0 : Reset (IP not initialized)
- * 1 : Init done (IP not initialized)
- * b4-b2 (not used)
- * xxx : Should be set to 000
- * b1 Rx state
- * 0 : Ready (no Rx operation ongoing)
- * 1 : Busy (Rx operation ongoing)
- * b0 (not used)
- * x : Should be set to 0.
- */
-typedef enum
-{
- HAL_IRDA_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized
- Value is allowed for gState and RxState */
- HAL_IRDA_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use
- Value is allowed for gState and RxState */
- HAL_IRDA_STATE_BUSY = 0x24U, /*!< An internal process is ongoing
- Value is allowed for gState only */
- HAL_IRDA_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing
- Value is allowed for gState only */
- HAL_IRDA_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing
- Value is allowed for RxState only */
- HAL_IRDA_STATE_BUSY_TX_RX = 0x23U, /*!< Data Transmission and Reception process is ongoing
- Not to be used for neither gState nor RxState.
- Value is result of combination (Or) between gState and RxState values */
- HAL_IRDA_STATE_TIMEOUT = 0xA0U, /*!< Timeout state
- Value is allowed for gState only */
- HAL_IRDA_STATE_ERROR = 0xE0U /*!< Error
- Value is allowed for gState only */
-}HAL_IRDA_StateTypeDef;
-
-/**
- * @brief IRDA handle Structure definition
- */
-typedef struct
-{
- USART_TypeDef *Instance; /*!< USART registers base address */
-
- IRDA_InitTypeDef Init; /*!< IRDA communication parameters */
-
- uint8_t *pTxBuffPtr; /*!< Pointer to IRDA Tx transfer Buffer */
-
- uint16_t TxXferSize; /*!< IRDA Tx Transfer size */
-
- __IO uint16_t TxXferCount; /*!< IRDA Tx Transfer Counter */
-
- uint8_t *pRxBuffPtr; /*!< Pointer to IRDA Rx transfer Buffer */
-
- uint16_t RxXferSize; /*!< IRDA Rx Transfer size */
-
- __IO uint16_t RxXferCount; /*!< IRDA Rx Transfer Counter */
-
- DMA_HandleTypeDef *hdmatx; /*!< IRDA Tx DMA Handle parameters */
-
- DMA_HandleTypeDef *hdmarx; /*!< IRDA Rx DMA Handle parameters */
-
- HAL_LockTypeDef Lock; /*!< Locking object */
-
- __IO HAL_IRDA_StateTypeDef gState; /*!< IRDA state information related to global Handle management
- and also related to Tx operations.
- This parameter can be a value of @ref HAL_IRDA_StateTypeDef */
-
- __IO HAL_IRDA_StateTypeDef RxState; /*!< IRDA state information related to Rx operations.
- This parameter can be a value of @ref HAL_IRDA_StateTypeDef */
-
- __IO uint32_t ErrorCode; /*!< IRDA Error code */
-}IRDA_HandleTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup IRDA_Exported_Constants IRDA Exported constants
- * @{
- */
-/** @defgroup IRDA_Error_Code IRDA Error Code
- * @{
- */
-#define HAL_IRDA_ERROR_NONE 0x00000000U /*!< No error */
-#define HAL_IRDA_ERROR_PE 0x00000001U /*!< Parity error */
-#define HAL_IRDA_ERROR_NE 0x00000002U /*!< Noise error */
-#define HAL_IRDA_ERROR_FE 0x00000004U /*!< Frame error */
-#define HAL_IRDA_ERROR_ORE 0x00000008U /*!< Overrun error */
-#define HAL_IRDA_ERROR_DMA 0x00000010U /*!< DMA transfer error */
-/**
- * @}
- */
-
-/** @defgroup IRDA_Word_Length IRDA Word Length
- * @{
- */
-#define IRDA_WORDLENGTH_8B 0x00000000U
-#define IRDA_WORDLENGTH_9B ((uint32_t)USART_CR1_M)
-/**
- * @}
- */
-
-/** @defgroup IRDA_Parity IRDA Parity
- * @{
- */
-#define IRDA_PARITY_NONE 0x00000000U
-#define IRDA_PARITY_EVEN ((uint32_t)USART_CR1_PCE)
-#define IRDA_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS))
-/**
- * @}
- */
-
-/** @defgroup IRDA_Transfer_Mode IRDA Transfer Mode
- * @{
- */
-#define IRDA_MODE_RX ((uint32_t)USART_CR1_RE)
-#define IRDA_MODE_TX ((uint32_t)USART_CR1_TE)
-#define IRDA_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE))
-/**
- * @}
- */
-
-/** @defgroup IRDA_Low_Power IRDA Low Power
- * @{
- */
-#define IRDA_POWERMODE_LOWPOWER ((uint32_t)USART_CR3_IRLP)
-#define IRDA_POWERMODE_NORMAL 0x00000000U
-/**
- * @}
- */
-
-/** @defgroup IRDA_Flags IRDA Flags
- * Elements values convention: 0xXXXX
- * - 0xXXXX : Flag mask in the SR register
- * @{
- */
-#define IRDA_FLAG_TXE ((uint32_t)USART_SR_TXE)
-#define IRDA_FLAG_TC ((uint32_t)USART_SR_TC)
-#define IRDA_FLAG_RXNE ((uint32_t)USART_SR_RXNE)
-#define IRDA_FLAG_IDLE ((uint32_t)USART_SR_IDLE)
-#define IRDA_FLAG_ORE ((uint32_t)USART_SR_ORE)
-#define IRDA_FLAG_NE ((uint32_t)USART_SR_NE)
-#define IRDA_FLAG_FE ((uint32_t)USART_SR_FE)
-#define IRDA_FLAG_PE ((uint32_t)USART_SR_PE)
-/**
- * @}
- */
-
-/** @defgroup IRDA_Interrupt_definition IRDA Interrupt Definitions
- * Elements values convention: 0xY000XXXX
- * - XXXX : Interrupt mask in the XX register
- * - Y : Interrupt source register (2bits)
- * - 01: CR1 register
- * - 10: CR2 register
- * - 11: CR3 register
- * @{
- */
-#define IRDA_IT_PE ((uint32_t)(IRDA_CR1_REG_INDEX << 28U | USART_CR1_PEIE))
-#define IRDA_IT_TXE ((uint32_t)(IRDA_CR1_REG_INDEX << 28U | USART_CR1_TXEIE))
-#define IRDA_IT_TC ((uint32_t)(IRDA_CR1_REG_INDEX << 28U | USART_CR1_TCIE))
-#define IRDA_IT_RXNE ((uint32_t)(IRDA_CR1_REG_INDEX << 28U | USART_CR1_RXNEIE))
-#define IRDA_IT_IDLE ((uint32_t)(IRDA_CR1_REG_INDEX << 28U | USART_CR1_IDLEIE))
-
-#define IRDA_IT_LBD ((uint32_t)(IRDA_CR2_REG_INDEX << 28U | USART_CR2_LBDIE))
-
-#define IRDA_IT_CTS ((uint32_t)(IRDA_CR3_REG_INDEX << 28U | USART_CR3_CTSIE))
-#define IRDA_IT_ERR ((uint32_t)(IRDA_CR3_REG_INDEX << 28U | USART_CR3_EIE))
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup IRDA_Exported_Macros IRDA Exported Macros
- * @{
- */
-
-/** @brief Reset IRDA handle gstate & RxState
- * @param __HANDLE__: specifies the IRDA Handle.
- * IRDA Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- */
-#define __HAL_IRDA_RESET_HANDLE_STATE(__HANDLE__) do{ \
- (__HANDLE__)->gState = HAL_IRDA_STATE_RESET; \
- (__HANDLE__)->RxState = HAL_IRDA_STATE_RESET; \
- } while(0U)
-
-/** @brief Flush the IRDA DR register
- * @param __HANDLE__: specifies the USART Handle.
- * IRDA Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- */
-#define __HAL_IRDA_FLUSH_DRREGISTER(__HANDLE__) ((__HANDLE__)->Instance->DR)
-
-/** @brief Check whether the specified IRDA flag is set or not.
- * @param __HANDLE__: specifies the IRDA Handle.
- * IRDA Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg IRDA_FLAG_TXE: Transmit data register empty flag
- * @arg IRDA_FLAG_TC: Transmission Complete flag
- * @arg IRDA_FLAG_RXNE: Receive data register not empty flag
- * @arg IRDA_FLAG_IDLE: Idle Line detection flag
- * @arg IRDA_FLAG_ORE: OverRun Error flag
- * @arg IRDA_FLAG_NE: Noise Error flag
- * @arg IRDA_FLAG_FE: Framing Error flag
- * @arg IRDA_FLAG_PE: Parity Error flag
- * @retval The new state of __FLAG__ (TRUE or FALSE).
- */
-#define __HAL_IRDA_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__))
-
-/** @brief Clear the specified IRDA pending flag.
- * @param __HANDLE__: specifies the IRDA Handle.
- * IRDA Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be any combination of the following values:
- * @arg IRDA_FLAG_TC: Transmission Complete flag.
- * @arg IRDA_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 followed by a read
- * operation to USART_DR register.
- * @note RXNE flag can be also cleared by a read to the USART_DR register.
- * @note TC flag can be also cleared by software sequence: a read operation to
- * USART_SR register followed by a write operation to USART_DR register.
- * @note TXE flag is cleared only by a write to the USART_DR register.
- *
- */
-#define __HAL_IRDA_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__))
-
-/** @brief Clear the IRDA PE pending flag.
- * @param __HANDLE__: specifies the IRDA Handle.
- * IRDA Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- */
-#define __HAL_IRDA_CLEAR_PEFLAG(__HANDLE__) \
-do{ \
- __IO uint32_t tmpreg = 0x00U; \
- tmpreg = (__HANDLE__)->Instance->SR; \
- tmpreg = (__HANDLE__)->Instance->DR; \
- UNUSED(tmpreg); \
- } while(0U)
-
-/** @brief Clear the IRDA FE pending flag.
- * @param __HANDLE__: specifies the IRDA Handle.
- * IRDA Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- */
-#define __HAL_IRDA_CLEAR_FEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_PEFLAG(__HANDLE__)
-
-/** @brief Clear the IRDA NE pending flag.
- * @param __HANDLE__: specifies the IRDA Handle.
- * IRDA Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- */
-#define __HAL_IRDA_CLEAR_NEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_PEFLAG(__HANDLE__)
-
-/** @brief Clear the IRDA ORE pending flag.
- * @param __HANDLE__: specifies the IRDA Handle.
- * IRDA Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- */
-#define __HAL_IRDA_CLEAR_OREFLAG(__HANDLE__) __HAL_IRDA_CLEAR_PEFLAG(__HANDLE__)
-
-/** @brief Clear the IRDA IDLE pending flag.
- * @param __HANDLE__: specifies the IRDA Handle.
- * IRDA Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- */
-#define __HAL_IRDA_CLEAR_IDLEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_PEFLAG(__HANDLE__)
-
-/** @brief Enable the specified IRDA interrupt.
- * @param __HANDLE__: specifies the IRDA Handle.
- * IRDA Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- * @param __INTERRUPT__: specifies the IRDA interrupt source to enable.
- * This parameter can be one of the following values:
- * @arg IRDA_IT_TXE: Transmit Data Register empty interrupt
- * @arg IRDA_IT_TC: Transmission complete interrupt
- * @arg IRDA_IT_RXNE: Receive Data register not empty interrupt
- * @arg IRDA_IT_IDLE: Idle line detection interrupt
- * @arg IRDA_IT_PE: Parity Error interrupt
- * @arg IRDA_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
- */
-#define __HAL_IRDA_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == IRDA_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & IRDA_IT_MASK)): \
- (((__INTERRUPT__) >> 28U) == IRDA_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 |= ((__INTERRUPT__) & IRDA_IT_MASK)): \
- ((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & IRDA_IT_MASK)))
-/** @brief Disable the specified IRDA interrupt.
- * @param __HANDLE__: specifies the IRDA Handle.
- * IRDA Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- * @param __INTERRUPT__: specifies the IRDA interrupt source to disable.
- * This parameter can be one of the following values:
- * @arg IRDA_IT_TXE: Transmit Data Register empty interrupt
- * @arg IRDA_IT_TC: Transmission complete interrupt
- * @arg IRDA_IT_RXNE: Receive Data register not empty interrupt
- * @arg IRDA_IT_IDLE: Idle line detection interrupt
- * @arg IRDA_IT_PE: Parity Error interrupt
- * @arg IRDA_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
- */
-#define __HAL_IRDA_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == IRDA_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 &= ~((__INTERRUPT__) & IRDA_IT_MASK)): \
- (((__INTERRUPT__) >> 28U) == IRDA_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 &= ~((__INTERRUPT__) & IRDA_IT_MASK)): \
- ((__HANDLE__)->Instance->CR3 &= ~ ((__INTERRUPT__) & IRDA_IT_MASK)))
-
-/** @brief Check whether the specified IRDA interrupt has occurred or not.
- * @param __HANDLE__: specifies the IRDA Handle.
- * IRDA Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- * @param __IT__: specifies the IRDA interrupt source to check.
- * This parameter can be one of the following values:
- * @arg IRDA_IT_TXE: Transmit Data Register empty interrupt
- * @arg IRDA_IT_TC: Transmission complete interrupt
- * @arg IRDA_IT_RXNE: Receive Data register not empty interrupt
- * @arg IRDA_IT_IDLE: Idle line detection interrupt
- * @arg IRDA_IT_ERR: Error interrupt
- * @arg IRDA_IT_PE: Parity Error interrupt
- * @retval The new state of __IT__ (TRUE or FALSE).
- */
-#define __HAL_IRDA_GET_IT_SOURCE(__HANDLE__, __IT__) (((((__IT__) >> 28U) == IRDA_CR1_REG_INDEX)? (__HANDLE__)->Instance->CR1:(((((uint32_t)(__IT__)) >> 28U) == IRDA_CR2_REG_INDEX)? \
- (__HANDLE__)->Instance->CR2 : (__HANDLE__)->Instance->CR3)) & (((uint32_t)(__IT__)) & IRDA_IT_MASK))
-
-/** @brief Enable UART/USART associated to IRDA Handle
- * @param __HANDLE__: specifies the IRDA Handle.
- * IRDA Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- */
-#define __HAL_IRDA_ENABLE(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR1, USART_CR1_UE))
-
-/** @brief Disable UART/USART associated to IRDA Handle
- * @param __HANDLE__: specifies the IRDA Handle.
- * IRDA Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- */
-#define __HAL_IRDA_DISABLE(__HANDLE__) (CLEAR_BIT((__HANDLE__)->Instance->CR1, USART_CR1_UE))
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup IRDA_Exported_Functions
- * @{
- */
-
-/** @addtogroup IRDA_Exported_Functions_Group1
- * @{
- */
-/* Initialization/de-initialization functions **********************************/
-HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda);
-HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda);
-void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda);
-void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda);
-/**
- * @}
- */
-
-/** @addtogroup IRDA_Exported_Functions_Group2
- * @{
- */
-/* IO operation functions *******************************************************/
-HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda);
-HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda);
-HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda);
-/* Transfer Abort functions */
-HAL_StatusTypeDef HAL_IRDA_Abort(IRDA_HandleTypeDef *hirda);
-HAL_StatusTypeDef HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef *hirda);
-HAL_StatusTypeDef HAL_IRDA_AbortReceive(IRDA_HandleTypeDef *hirda);
-HAL_StatusTypeDef HAL_IRDA_Abort_IT(IRDA_HandleTypeDef *hirda);
-HAL_StatusTypeDef HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef *hirda);
-HAL_StatusTypeDef HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef *hirda);
-
-void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda);
-void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda);
-void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda);
-void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda);
-void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda);
-void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda);
-void HAL_IRDA_AbortCpltCallback(IRDA_HandleTypeDef *hirda);
-void HAL_IRDA_AbortTransmitCpltCallback(IRDA_HandleTypeDef *hirda);
-void HAL_IRDA_AbortReceiveCpltCallback(IRDA_HandleTypeDef *hirda);
-/**
- * @}
- */
-
-/** @addtogroup IRDA_Exported_Functions_Group3
- * @{
- */
-/* Peripheral State functions **************************************************/
-HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda);
-uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup IRDA_Private_Constants IRDA Private Constants
- * @{
- */
-
-/** @brief IRDA interruptions flag mask
- *
- */
-#define IRDA_IT_MASK 0x0000FFFFU
-
-#define IRDA_CR1_REG_INDEX 1U
-#define IRDA_CR2_REG_INDEX 2U
-#define IRDA_CR3_REG_INDEX 3U
-/**
- * @}
- */
-
-/* Private macros --------------------------------------------------------*/
-/** @defgroup IRDA_Private_Macros IRDA Private Macros
- * @{
- */
-#define IS_IRDA_WORD_LENGTH(LENGTH) (((LENGTH) == IRDA_WORDLENGTH_8B) || \
- ((LENGTH) == IRDA_WORDLENGTH_9B))
-#define IS_IRDA_PARITY(PARITY) (((PARITY) == IRDA_PARITY_NONE) || \
- ((PARITY) == IRDA_PARITY_EVEN) || \
- ((PARITY) == IRDA_PARITY_ODD))
-#define IS_IRDA_MODE(MODE) ((((MODE) & 0x0000FFF3U) == 0x00U) && ((MODE) != 0x00000000U))
-#define IS_IRDA_POWERMODE(MODE) (((MODE) == IRDA_POWERMODE_LOWPOWER) || \
- ((MODE) == IRDA_POWERMODE_NORMAL))
-#define IS_IRDA_BAUDRATE(BAUDRATE) ((BAUDRATE) < 115201U)
-
-#define IRDA_DIV(_PCLK_, _BAUD_) (((_PCLK_)*25U)/(4U*(_BAUD_)))
-#define IRDA_DIVMANT(_PCLK_, _BAUD_) (IRDA_DIV((_PCLK_), (_BAUD_))/100U)
-#define IRDA_DIVFRAQ(_PCLK_, _BAUD_) (((IRDA_DIV((_PCLK_), (_BAUD_)) - (IRDA_DIVMANT((_PCLK_), (_BAUD_)) * 100U)) * 16U + 50U) / 100U)
-/* UART BRR = mantissa + overflow + fraction
- = (UART DIVMANT << 4) + (UART DIVFRAQ & 0xF0) + (UART DIVFRAQ & 0x0FU) */
-#define IRDA_BRR(_PCLK_, _BAUD_) (((IRDA_DIVMANT((_PCLK_), (_BAUD_)) << 4U) + \
- (IRDA_DIVFRAQ((_PCLK_), (_BAUD_)) & 0xF0U)) + \
- (IRDA_DIVFRAQ((_PCLK_), (_BAUD_)) & 0x0FU))
-
-/**
- * @}
- */
-
-/* Private functions ---------------------------------------------------------*/
-/** @defgroup IRDA_Private_Functions IRDA Private Functions
- * @{
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_IRDA_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_iwdg.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_iwdg.h
deleted file mode 100644
index 5a6f395..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_iwdg.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_iwdg.h
- * @author MCD Application Team
- * @brief Header file of IWDG HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_IWDG_H
-#define __STM32F1xx_HAL_IWDG_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup IWDG
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup IWDG_Exported_Types IWDG Exported Types
- * @{
- */
-
-/**
- * @brief IWDG Init structure definition
- */
-typedef struct
-{
- uint32_t Prescaler; /*!< Select the prescaler of the IWDG.
- This parameter can be a value of @ref IWDG_Prescaler */
-
- uint32_t Reload; /*!< Specifies the IWDG down-counter reload value.
- This parameter must be a number between Min_Data = 0 and Max_Data = 0x0FFF */
-
-} IWDG_InitTypeDef;
-
-/**
- * @brief IWDG Handle Structure definition
- */
-typedef struct
-{
- IWDG_TypeDef *Instance; /*!< Register base address */
-
- IWDG_InitTypeDef Init; /*!< IWDG required parameters */
-
-} IWDG_HandleTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup IWDG_Exported_Constants IWDG Exported Constants
- * @{
- */
-
-/** @defgroup IWDG_Prescaler IWDG Prescaler
- * @{
- */
-#define IWDG_PRESCALER_4 0x00000000U /*!< IWDG prescaler set to 4 */
-#define IWDG_PRESCALER_8 IWDG_PR_PR_0 /*!< IWDG prescaler set to 8 */
-#define IWDG_PRESCALER_16 IWDG_PR_PR_1 /*!< IWDG prescaler set to 16 */
-#define IWDG_PRESCALER_32 (IWDG_PR_PR_1 | IWDG_PR_PR_0) /*!< IWDG prescaler set to 32 */
-#define IWDG_PRESCALER_64 IWDG_PR_PR_2 /*!< IWDG prescaler set to 64 */
-#define IWDG_PRESCALER_128 (IWDG_PR_PR_2 | IWDG_PR_PR_0) /*!< IWDG prescaler set to 128 */
-#define IWDG_PRESCALER_256 (IWDG_PR_PR_2 | IWDG_PR_PR_1) /*!< IWDG prescaler set to 256 */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-
-/* Exported macros -----------------------------------------------------------*/
-/** @defgroup IWDG_Exported_Macros IWDG Exported Macros
- * @{
- */
-
-/**
- * @brief Enable the IWDG peripheral.
- * @param __HANDLE__ IWDG handle
- * @retval None
- */
-#define __HAL_IWDG_START(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_ENABLE)
-
-/**
- * @brief Reload IWDG counter with value defined in the reload register
- * (write access to IWDG_PR & IWDG_RLR registers disabled).
- * @param __HANDLE__ IWDG handle
- * @retval None
- */
-#define __HAL_IWDG_RELOAD_COUNTER(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_RELOAD)
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup IWDG_Exported_Functions IWDG Exported Functions
- * @{
- */
-
-/** @defgroup IWDG_Exported_Functions_Group1 Initialization and Start functions
- * @{
- */
-/* Initialization/Start functions ********************************************/
-HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg);
-/**
- * @}
- */
-
-/** @defgroup IWDG_Exported_Functions_Group2 IO operation functions
- * @{
- */
-/* I/O operation functions ****************************************************/
-HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup IWDG_Private_Constants IWDG Private Constants
- * @{
- */
-
-/**
- * @brief IWDG Key Register BitMask
- */
-#define IWDG_KEY_RELOAD 0x0000AAAAU /*!< IWDG Reload Counter Enable */
-#define IWDG_KEY_ENABLE 0x0000CCCCU /*!< IWDG Peripheral Enable */
-#define IWDG_KEY_WRITE_ACCESS_ENABLE 0x00005555U /*!< IWDG KR Write Access Enable */
-#define IWDG_KEY_WRITE_ACCESS_DISABLE 0x00000000U /*!< IWDG KR Write Access Disable */
-
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup IWDG_Private_Macros IWDG Private Macros
- * @{
- */
-
-/**
- * @brief Enable write access to IWDG_PR and IWDG_RLR registers.
- * @param __HANDLE__ IWDG handle
- * @retval None
- */
-#define IWDG_ENABLE_WRITE_ACCESS(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_WRITE_ACCESS_ENABLE)
-
-/**
- * @brief Disable write access to IWDG_PR and IWDG_RLR registers.
- * @param __HANDLE__ IWDG handle
- * @retval None
- */
-#define IWDG_DISABLE_WRITE_ACCESS(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_WRITE_ACCESS_DISABLE)
-
-/**
- * @brief Check IWDG prescaler value.
- * @param __PRESCALER__ IWDG prescaler value
- * @retval None
- */
-#define IS_IWDG_PRESCALER(__PRESCALER__) (((__PRESCALER__) == IWDG_PRESCALER_4) || \
- ((__PRESCALER__) == IWDG_PRESCALER_8) || \
- ((__PRESCALER__) == IWDG_PRESCALER_16) || \
- ((__PRESCALER__) == IWDG_PRESCALER_32) || \
- ((__PRESCALER__) == IWDG_PRESCALER_64) || \
- ((__PRESCALER__) == IWDG_PRESCALER_128)|| \
- ((__PRESCALER__) == IWDG_PRESCALER_256))
-
-/**
- * @brief Check IWDG reload value.
- * @param __RELOAD__ IWDG reload value
- * @retval None
- */
-#define IS_IWDG_RELOAD(__RELOAD__) ((__RELOAD__) <= IWDG_RLR_RL)
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_IWDG_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_mmc.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_mmc.h
deleted file mode 100644
index fe4b8b7..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_mmc.h
+++ /dev/null
@@ -1,716 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_mmc.h
- * @author MCD Application Team
- * @brief Header file of MMC HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_MMC_H
-#define __STM32F1xx_HAL_MMC_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-#if defined(STM32F103xE) || defined(STM32F103xG)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_sdmmc.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup MMC MMC
- * @brief MMC HAL module driver
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup MMC_Exported_Types MMC Exported Types
- * @{
- */
-
-/** @defgroup MMC_Exported_Types_Group1 MMC State enumeration structure
- * @{
- */
-typedef enum
-{
- HAL_MMC_STATE_RESET = 0x00000000U, /*!< MMC not yet initialized or disabled */
- HAL_MMC_STATE_READY = 0x00000001U, /*!< MMC initialized and ready for use */
- HAL_MMC_STATE_TIMEOUT = 0x00000002U, /*!< MMC Timeout state */
- HAL_MMC_STATE_BUSY = 0x00000003U, /*!< MMC process ongoing */
- HAL_MMC_STATE_PROGRAMMING = 0x00000004U, /*!< MMC Programming State */
- HAL_MMC_STATE_RECEIVING = 0x00000005U, /*!< MMC Receinving State */
- HAL_MMC_STATE_TRANSFER = 0x00000006U, /*!< MMC Transfert State */
- HAL_MMC_STATE_ERROR = 0x0000000FU /*!< MMC is in error state */
-}HAL_MMC_StateTypeDef;
-/**
- * @}
- */
-
-/** @defgroup MMC_Exported_Types_Group2 MMC Card State enumeration structure
- * @{
- */
-typedef enum
-{
- HAL_MMC_CARD_READY = 0x00000001U, /*!< Card state is ready */
- HAL_MMC_CARD_IDENTIFICATION = 0x00000002U, /*!< Card is in identification state */
- HAL_MMC_CARD_STANDBY = 0x00000003U, /*!< Card is in standby state */
- HAL_MMC_CARD_TRANSFER = 0x00000004U, /*!< Card is in transfer state */
- HAL_MMC_CARD_SENDING = 0x00000005U, /*!< Card is sending an operation */
- HAL_MMC_CARD_RECEIVING = 0x00000006U, /*!< Card is receiving operation information */
- HAL_MMC_CARD_PROGRAMMING = 0x00000007U, /*!< Card is in programming state */
- HAL_MMC_CARD_DISCONNECTED = 0x00000008U, /*!< Card is disconnected */
- HAL_MMC_CARD_ERROR = 0x000000FFU /*!< Card response Error */
-}HAL_MMC_CardStateTypeDef;
-/**
- * @}
- */
-
-/** @defgroup MMC_Exported_Types_Group3 MMC Handle Structure definition
- * @{
- */
-#define MMC_InitTypeDef SDIO_InitTypeDef
-#define MMC_TypeDef SDIO_TypeDef
-
-/**
- * @brief MMC Card Information Structure definition
- */
-typedef struct
-{
- uint32_t CardType; /*!< Specifies the card Type */
-
- uint32_t Class; /*!< Specifies the class of the card class */
-
- uint32_t RelCardAdd; /*!< Specifies the Relative Card Address */
-
- uint32_t BlockNbr; /*!< Specifies the Card Capacity in blocks */
-
- uint32_t BlockSize; /*!< Specifies one block size in bytes */
-
- uint32_t LogBlockNbr; /*!< Specifies the Card logical Capacity in blocks */
-
- uint32_t LogBlockSize; /*!< Specifies logical block size in bytes */
-
-}HAL_MMC_CardInfoTypeDef;
-
-/**
- * @brief MMC handle Structure definition
- */
-typedef struct
-{
- MMC_TypeDef *Instance; /*!< MMC registers base address */
-
- MMC_InitTypeDef Init; /*!< MMC required parameters */
-
- HAL_LockTypeDef Lock; /*!< MMC locking object */
-
- uint32_t *pTxBuffPtr; /*!< Pointer to MMC Tx transfer Buffer */
-
- uint32_t TxXferSize; /*!< MMC Tx Transfer size */
-
- uint32_t *pRxBuffPtr; /*!< Pointer to MMC Rx transfer Buffer */
-
- uint32_t RxXferSize; /*!< MMC Rx Transfer size */
-
- __IO uint32_t Context; /*!< MMC transfer context */
-
- __IO HAL_MMC_StateTypeDef State; /*!< MMC card State */
-
- __IO uint32_t ErrorCode; /*!< MMC Card Error codes */
-
- DMA_HandleTypeDef *hdmarx; /*!< MMC Rx DMA handle parameters */
-
- DMA_HandleTypeDef *hdmatx; /*!< MMC Tx DMA handle parameters */
-
- HAL_MMC_CardInfoTypeDef MmcCard; /*!< MMC Card information */
-
- uint32_t CSD[4U]; /*!< MMC card specific data table */
-
- uint32_t CID[4U]; /*!< MMC card identification number table */
-
-}MMC_HandleTypeDef;
-
-/**
- * @}
- */
-
-/** @defgroup MMC_Exported_Types_Group4 Card Specific Data: CSD Register
- * @{
- */
-typedef struct
-{
- __IO uint8_t CSDStruct; /*!< CSD structure */
- __IO uint8_t SysSpecVersion; /*!< System specification version */
- __IO uint8_t Reserved1; /*!< Reserved */
- __IO uint8_t TAAC; /*!< Data read access time 1 */
- __IO uint8_t NSAC; /*!< Data read access time 2 in CLK cycles */
- __IO uint8_t MaxBusClkFrec; /*!< Max. bus clock frequency */
- __IO uint16_t CardComdClasses; /*!< Card command classes */
- __IO uint8_t RdBlockLen; /*!< Max. read data block length */
- __IO uint8_t PartBlockRead; /*!< Partial blocks for read allowed */
- __IO uint8_t WrBlockMisalign; /*!< Write block misalignment */
- __IO uint8_t RdBlockMisalign; /*!< Read block misalignment */
- __IO uint8_t DSRImpl; /*!< DSR implemented */
- __IO uint8_t Reserved2; /*!< Reserved */
- __IO uint32_t DeviceSize; /*!< Device Size */
- __IO uint8_t MaxRdCurrentVDDMin; /*!< Max. read current @ VDD min */
- __IO uint8_t MaxRdCurrentVDDMax; /*!< Max. read current @ VDD max */
- __IO uint8_t MaxWrCurrentVDDMin; /*!< Max. write current @ VDD min */
- __IO uint8_t MaxWrCurrentVDDMax; /*!< Max. write current @ VDD max */
- __IO uint8_t DeviceSizeMul; /*!< Device size multiplier */
- __IO uint8_t EraseGrSize; /*!< Erase group size */
- __IO uint8_t EraseGrMul; /*!< Erase group size multiplier */
- __IO uint8_t WrProtectGrSize; /*!< Write protect group size */
- __IO uint8_t WrProtectGrEnable; /*!< Write protect group enable */
- __IO uint8_t ManDeflECC; /*!< Manufacturer default ECC */
- __IO uint8_t WrSpeedFact; /*!< Write speed factor */
- __IO uint8_t MaxWrBlockLen; /*!< Max. write data block length */
- __IO uint8_t WriteBlockPaPartial; /*!< Partial blocks for write allowed */
- __IO uint8_t Reserved3; /*!< Reserved */
- __IO uint8_t ContentProtectAppli; /*!< Content protection application */
- __IO uint8_t FileFormatGrouop; /*!< File format group */
- __IO uint8_t CopyFlag; /*!< Copy flag (OTP) */
- __IO uint8_t PermWrProtect; /*!< Permanent write protection */
- __IO uint8_t TempWrProtect; /*!< Temporary write protection */
- __IO uint8_t FileFormat; /*!< File format */
- __IO uint8_t ECC; /*!< ECC code */
- __IO uint8_t CSD_CRC; /*!< CSD CRC */
- __IO uint8_t Reserved4; /*!< Always 1 */
-
-}HAL_MMC_CardCSDTypeDef;
-/**
- * @}
- */
-
-/** @defgroup MMC_Exported_Types_Group5 Card Identification Data: CID Register
- * @{
- */
-typedef struct
-{
- __IO uint8_t ManufacturerID; /*!< Manufacturer ID */
- __IO uint16_t OEM_AppliID; /*!< OEM/Application ID */
- __IO uint32_t ProdName1; /*!< Product Name part1 */
- __IO uint8_t ProdName2; /*!< Product Name part2 */
- __IO uint8_t ProdRev; /*!< Product Revision */
- __IO uint32_t ProdSN; /*!< Product Serial Number */
- __IO uint8_t Reserved1; /*!< Reserved1 */
- __IO uint16_t ManufactDate; /*!< Manufacturing Date */
- __IO uint8_t CID_CRC; /*!< CID CRC */
- __IO uint8_t Reserved2; /*!< Always 1 */
-
-}HAL_MMC_CardCIDTypeDef;
-/**
- * @}
- */
-
-/** @defgroup MMC_Exported_Types_Group6 MMC Card Status returned by ACMD13
- * @{
- */
-typedef struct
-{
- __IO uint8_t DataBusWidth; /*!< Shows the currently defined data bus width */
- __IO uint8_t SecuredMode; /*!< Card is in secured mode of operation */
- __IO uint16_t CardType; /*!< Carries information about card type */
- __IO uint32_t ProtectedAreaSize; /*!< Carries information about the capacity of protected area */
- __IO uint8_t SpeedClass; /*!< Carries information about the speed class of the card */
- __IO uint8_t PerformanceMove; /*!< Carries information about the card's performance move */
- __IO uint8_t AllocationUnitSize; /*!< Carries information about the card's allocation unit size */
- __IO uint16_t EraseSize; /*!< Determines the number of AUs to be erased in one operation */
- __IO uint8_t EraseTimeout; /*!< Determines the timeout for any number of AU erase */
- __IO uint8_t EraseOffset; /*!< Carries information about the erase offset */
-
-}HAL_MMC_CardStatusTypeDef;
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup MMC_Exported_Constants Exported Constants
- * @{
- */
-
-#define BLOCKSIZE 512U /*!< Block size is 512 bytes */
-
-#define CAPACITY 0x400000U /*!< Log Block Nuumber for 2 G bytes Cards */
-
-/** @defgroup MMC_Exported_Constansts_Group1 MMC Error status enumeration Structure definition
- * @{
- */
-#define HAL_MMC_ERROR_NONE SDMMC_ERROR_NONE /*!< No error */
-#define HAL_MMC_ERROR_CMD_CRC_FAIL SDMMC_ERROR_CMD_CRC_FAIL /*!< Command response received (but CRC check failed) */
-#define HAL_MMC_ERROR_DATA_CRC_FAIL SDMMC_ERROR_DATA_CRC_FAIL /*!< Data block sent/received (CRC check failed) */
-#define HAL_MMC_ERROR_CMD_RSP_TIMEOUT SDMMC_ERROR_CMD_RSP_TIMEOUT /*!< Command response timeout */
-#define HAL_MMC_ERROR_DATA_TIMEOUT SDMMC_ERROR_DATA_TIMEOUT /*!< Data timeout */
-#define HAL_MMC_ERROR_TX_UNDERRUN SDMMC_ERROR_TX_UNDERRUN /*!< Transmit FIFO underrun */
-#define HAL_MMC_ERROR_RX_OVERRUN SDMMC_ERROR_RX_OVERRUN /*!< Receive FIFO overrun */
-#define HAL_MMC_ERROR_ADDR_MISALIGNED SDMMC_ERROR_ADDR_MISALIGNED /*!< Misaligned address */
-#define HAL_MMC_ERROR_BLOCK_LEN_ERR SDMMC_ERROR_BLOCK_LEN_ERR /*!< Transferred block length is not allowed for the card or the
- number of transferred bytes does not match the block length */
-#define HAL_MMC_ERROR_ERASE_SEQ_ERR SDMMC_ERROR_ERASE_SEQ_ERR /*!< An error in the sequence of erase command occurs */
-#define HAL_MMC_ERROR_BAD_ERASE_PARAM SDMMC_ERROR_BAD_ERASE_PARAM /*!< An invalid selection for erase groups */
-#define HAL_MMC_ERROR_WRITE_PROT_VIOLATION SDMMC_ERROR_WRITE_PROT_VIOLATION /*!< Attempt to program a write protect block */
-#define HAL_MMC_ERROR_LOCK_UNLOCK_FAILED SDMMC_ERROR_LOCK_UNLOCK_FAILED /*!< Sequence or password error has been detected in unlock
- command or if there was an attempt to access a locked card */
-#define HAL_MMC_ERROR_COM_CRC_FAILED SDMMC_ERROR_COM_CRC_FAILED /*!< CRC check of the previous command failed */
-#define HAL_MMC_ERROR_ILLEGAL_CMD SDMMC_ERROR_ILLEGAL_CMD /*!< Command is not legal for the card state */
-#define HAL_MMC_ERROR_CARD_ECC_FAILED SDMMC_ERROR_CARD_ECC_FAILED /*!< Card internal ECC was applied but failed to correct the data */
-#define HAL_MMC_ERROR_CC_ERR SDMMC_ERROR_CC_ERR /*!< Internal card controller error */
-#define HAL_MMC_ERROR_GENERAL_UNKNOWN_ERR SDMMC_ERROR_GENERAL_UNKNOWN_ERR /*!< General or unknown error */
-#define HAL_MMC_ERROR_STREAM_READ_UNDERRUN SDMMC_ERROR_STREAM_READ_UNDERRUN /*!< The card could not sustain data reading in stream rmode */
-#define HAL_MMC_ERROR_STREAM_WRITE_OVERRUN SDMMC_ERROR_STREAM_WRITE_OVERRUN /*!< The card could not sustain data programming in stream mode */
-#define HAL_MMC_ERROR_CID_CSD_OVERWRITE SDMMC_ERROR_CID_CSD_OVERWRITE /*!< CID/CSD overwrite error */
-#define HAL_MMC_ERROR_WP_ERASE_SKIP SDMMC_ERROR_WP_ERASE_SKIP /*!< Only partial address space was erased */
-#define HAL_MMC_ERROR_CARD_ECC_DISABLED SDMMC_ERROR_CARD_ECC_DISABLED /*!< Command has been executed without using internal ECC */
-#define HAL_MMC_ERROR_ERASE_RESET SDMMC_ERROR_ERASE_RESET /*!< Erase sequence was cleared before executing because an out
- of erase sequence command was received */
-#define HAL_MMC_ERROR_AKE_SEQ_ERR SDMMC_ERROR_AKE_SEQ_ERR /*!< Error in sequence of authentication */
-#define HAL_MMC_ERROR_INVALID_VOLTRANGE SDMMC_ERROR_INVALID_VOLTRANGE /*!< Error in case of invalid voltage range */
-#define HAL_MMC_ERROR_ADDR_OUT_OF_RANGE SDMMC_ERROR_ADDR_OUT_OF_RANGE /*!< Error when addressed block is out of range */
-#define HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE SDMMC_ERROR_REQUEST_NOT_APPLICABLE /*!< Error when command request is not applicable */
-#define HAL_MMC_ERROR_PARAM SDMMC_ERROR_INVALID_PARAMETER /*!< the used parameter is not valid */
-#define HAL_MMC_ERROR_UNSUPPORTED_FEATURE SDMMC_ERROR_UNSUPPORTED_FEATURE /*!< Error when feature is not insupported */
-#define HAL_MMC_ERROR_BUSY SDMMC_ERROR_BUSY /*!< Error when transfer process is busy */
-#define HAL_MMC_ERROR_DMA SDMMC_ERROR_DMA /*!< Error while DMA transfer */
-#define HAL_MMC_ERROR_TIMEOUT SDMMC_ERROR_TIMEOUT /*!< Timeout error */
-/**
- * @}
- */
-
-/** @defgroup MMC_Exported_Constansts_Group2 MMC context enumeration structure
- * @{
- */
-#define MMC_CONTEXT_NONE 0x00000000U /*!< None */
-#define MMC_CONTEXT_READ_SINGLE_BLOCK 0x00000001U /*!< Read single block operation */
-#define MMC_CONTEXT_READ_MULTIPLE_BLOCK 0x00000002U /*!< Read multiple blocks operation */
-#define MMC_CONTEXT_WRITE_SINGLE_BLOCK 0x00000010U /*!< Write single block operation */
-#define MMC_CONTEXT_WRITE_MULTIPLE_BLOCK 0x00000020U /*!< Write multiple blocks operation */
-#define MMC_CONTEXT_IT 0x00000008U /*!< Process in Interrupt mode */
-#define MMC_CONTEXT_DMA 0x00000080U /*!< Process in DMA mode */
-/**
- * @}
- */
-
-/** @defgroup MMC_Exported_Constansts_Group3 MMC Voltage mode
- * @{
- */
-/**
- * @brief
- */
-#define MMC_HIGH_VOLTAGE_RANGE 0x80FF8000U /*!< VALUE OF ARGUMENT */
-#define MMC_DUAL_VOLTAGE_RANGE 0x80FF8080U /*!< VALUE OF ARGUMENT */
-#define eMMC_HIGH_VOLTAGE_RANGE 0xC0FF8000U /*!< for eMMC > 2Gb sector mode */
-#define eMMC_DUAL_VOLTAGE_RANGE 0xC0FF8080U /*!< for eMMC > 2Gb sector mode */
-#define MMC_INVALID_VOLTAGE_RANGE 0x0001FF01U
-/**
- * @}
- */
-
-/** @defgroup MMC_Exported_Constansts_Group4 MMC Memory Cards
- * @{
- */
-#define MMC_HIGH_VOLTAGE_CARD 0x00000000U
-#define MMC_DUAL_VOLTAGE_CARD 0x00000001U
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup MMC_Exported_macros MMC Exported Macros
- * @brief macros to handle interrupts and specific clock configurations
- * @{
- */
-
-/**
- * @brief Enable the MMC device.
- * @retval None
- */
-#define __HAL_MMC_ENABLE(__HANDLE__) __SDIO_ENABLE((__HANDLE__)->Instance)
-
-/**
- * @brief Disable the MMC device.
- * @retval None
- */
-#define __HAL_MMC_DISABLE(__HANDLE__) __SDIO_DISABLE((__HANDLE__)->Instance)
-
-/**
- * @brief Enable the SDMMC DMA transfer.
- * @retval None
- */
-#define __HAL_MMC_DMA_ENABLE(__HANDLE__) __SDIO_DMA_ENABLE((__HANDLE__)->Instance)
-
-/**
- * @brief Disable the SDMMC DMA transfer.
- * @retval None
- */
-#define __HAL_MMC_DMA_DISABLE(__HANDLE__) __SDIO_DMA_DISABLE((__HANDLE__)->Instance)
-
-/**
- * @brief Enable the MMC device interrupt.
- * @param __HANDLE__: MMC Handle
- * @param __INTERRUPT__: specifies the SDMMC interrupt sources to be enabled.
- * This parameter can be one or a combination of the following values:
- * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
- * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
- * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
- * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
- * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
- * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
- * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
- * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
- * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
- * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
- * @arg SDIO_IT_RXACT: Data receive in progress interrupt
- * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
- * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
- * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
- * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
- * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
- * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
- * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
- * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
- * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
- * @retval None
- */
-#define __HAL_MMC_ENABLE_IT(__HANDLE__, __INTERRUPT__) __SDIO_ENABLE_IT((__HANDLE__)->Instance, (__INTERRUPT__))
-
-/**
- * @brief Disable the MMC device interrupt.
- * @param __HANDLE__: MMC Handle
- * @param __INTERRUPT__: specifies the SDMMC interrupt sources to be disabled.
- * This parameter can be one or a combination of the following values:
- * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
- * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
- * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
- * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
- * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
- * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
- * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
- * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
- * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
- * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
- * @arg SDIO_IT_RXACT: Data receive in progress interrupt
- * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
- * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
- * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
- * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
- * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
- * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
- * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
- * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
- * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
- * @retval None
- */
-#define __HAL_MMC_DISABLE_IT(__HANDLE__, __INTERRUPT__) __SDIO_DISABLE_IT((__HANDLE__)->Instance, (__INTERRUPT__))
-
-/**
- * @brief Check whether the specified MMC flag is set or not.
- * @param __HANDLE__: MMC Handle
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed)
- * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed)
- * @arg SDIO_FLAG_CTIMEOUT: Command response timeout
- * @arg SDIO_FLAG_DTIMEOUT: Data timeout
- * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error
- * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error
- * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed)
- * @arg SDIO_FLAG_CMDSENT: Command sent (no response required)
- * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero)
- * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed)
- * @arg SDIO_FLAG_CMDACT: Command transfer in progress
- * @arg SDIO_FLAG_TXACT: Data transmit in progress
- * @arg SDIO_FLAG_RXACT: Data receive in progress
- * @arg SDIO_FLAG_TXFIFOHE: Transmit FIFO Half Empty
- * @arg SDIO_FLAG_RXFIFOHF: Receive FIFO Half Full
- * @arg SDIO_FLAG_TXFIFOF: Transmit FIFO full
- * @arg SDIO_FLAG_RXFIFOF: Receive FIFO full
- * @arg SDIO_FLAG_TXFIFOE: Transmit FIFO empty
- * @arg SDIO_FLAG_RXFIFOE: Receive FIFO empty
- * @arg SDIO_FLAG_TXDAVL: Data available in transmit FIFO
- * @arg SDIO_FLAG_RXDAVL: Data available in receive FIFO
- * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received
- * @retval The new state of MMC FLAG (SET or RESET).
- */
-#define __HAL_MMC_GET_FLAG(__HANDLE__, __FLAG__) __SDIO_GET_FLAG((__HANDLE__)->Instance, (__FLAG__))
-
-/**
- * @brief Clear the MMC's pending flags.
- * @param __HANDLE__: MMC Handle
- * @param __FLAG__: specifies the flag to clear.
- * This parameter can be one or a combination of the following values:
- * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed)
- * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed)
- * @arg SDIO_FLAG_CTIMEOUT: Command response timeout
- * @arg SDIO_FLAG_DTIMEOUT: Data timeout
- * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error
- * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error
- * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed)
- * @arg SDIO_FLAG_CMDSENT: Command sent (no response required)
- * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero)
- * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed)
- * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received
- * @retval None
- */
-#define __HAL_MMC_CLEAR_FLAG(__HANDLE__, __FLAG__) __SDIO_CLEAR_FLAG((__HANDLE__)->Instance, (__FLAG__))
-
-/**
- * @brief Check whether the specified MMC interrupt has occurred or not.
- * @param __HANDLE__: MMC Handle
- * @param __INTERRUPT__: specifies the SDMMC interrupt source to check.
- * This parameter can be one of the following values:
- * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
- * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
- * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
- * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
- * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
- * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
- * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
- * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
- * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
- * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
- * @arg SDIO_IT_RXACT: Data receive in progress interrupt
- * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
- * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
- * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
- * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
- * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
- * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
- * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
- * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
- * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
- * @retval The new state of MMC IT (SET or RESET).
- */
-#define __HAL_MMC_GET_IT(__HANDLE__, __INTERRUPT__) __SDIO_GET_IT((__HANDLE__)->Instance, (__INTERRUPT__))
-
-/**
- * @brief Clear the MMC's interrupt pending bits.
- * @param __HANDLE__: MMC Handle
- * @param __INTERRUPT__: specifies the interrupt pending bit to clear.
- * This parameter can be one or a combination of the following values:
- * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
- * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
- * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
- * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
- * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
- * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
- * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
- * @arg SDIO_IT_DATAEND: Data end (data counter, SDMMC_DCOUNT, is zero) interrupt
- * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
- * @retval None
- */
-#define __HAL_MMC_CLEAR_IT(__HANDLE__, __INTERRUPT__) __SDIO_CLEAR_IT((__HANDLE__)->Instance, (__INTERRUPT__))
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup MMC_Exported_Functions MMC Exported Functions
- * @{
- */
-
-/** @defgroup MMC_Exported_Functions_Group1 Initialization and de-initialization functions
- * @{
- */
-HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc);
-HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc);
-HAL_StatusTypeDef HAL_MMC_DeInit (MMC_HandleTypeDef *hmmc);
-void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc);
-void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc);
-/**
- * @}
- */
-
-/** @defgroup MMC_Exported_Functions_Group2 Input and Output operation functions
- * @{
- */
-/* Blocking mode: Polling */
-HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout);
-HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout);
-HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd);
-/* Non-Blocking mode: IT */
-HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks);
-HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks);
-/* Non-Blocking mode: DMA */
-HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks);
-HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks);
-
-void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc);
-
-/* Callback in non blocking modes (DMA) */
-void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc);
-void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc);
-void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc);
-void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc);
-/**
- * @}
- */
-
-/** @defgroup MMC_Exported_Functions_Group3 Peripheral Control functions
- * @{
- */
-HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode);
-/**
- * @}
- */
-
-/** @defgroup MMC_Exported_Functions_Group4 MMC card related functions
- * @{
- */
-HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc);
-HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID);
-HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD);
-HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo);
-/**
- * @}
- */
-
-/** @defgroup MMC_Exported_Functions_Group5 Peripheral State and Errors functions
- * @{
- */
-HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc);
-uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc);
-/**
- * @}
- */
-
-/** @defgroup MMC_Exported_Functions_Group6 Perioheral Abort management
- * @{
- */
-HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc);
-HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc);
-/**
- * @}
- */
-
-/* Private types -------------------------------------------------------------*/
-/** @defgroup MMC_Private_Types MMC Private Types
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private defines -----------------------------------------------------------*/
-/** @defgroup MMC_Private_Defines MMC Private Defines
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private variables ---------------------------------------------------------*/
-/** @defgroup MMC_Private_Variables MMC Private Variables
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup MMC_Private_Constants MMC Private Constants
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup MMC_Private_Macros MMC Private Macros
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private functions prototypes ----------------------------------------------*/
-/** @defgroup MMC_Private_Functions_Prototypes MMC Private Functions Prototypes
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private functions ---------------------------------------------------------*/
-/** @defgroup MMC_Private_Functions MMC Private Functions
- * @{
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* STM32F103xE || STM32F103xG */
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* __STM32F1xx_HAL_MMC_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_nand.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_nand.h
deleted file mode 100644
index 0a49689..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_nand.h
+++ /dev/null
@@ -1,345 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_nand.h
- * @author MCD Application Team
- * @brief Header file of NAND HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_NAND_H
-#define __STM32F1xx_HAL_NAND_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_fsmc.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG)
-/** @addtogroup NAND
- * @{
- */
-
-
-/* Exported typedef ----------------------------------------------------------*/
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup NAND_Exported_Types NAND Exported Types
- * @{
- */
-
-/**
- * @brief HAL NAND State structures definition
- */
-typedef enum
-{
- HAL_NAND_STATE_RESET = 0x00U, /*!< NAND not yet initialized or disabled */
- HAL_NAND_STATE_READY = 0x01U, /*!< NAND initialized and ready for use */
- HAL_NAND_STATE_BUSY = 0x02U, /*!< NAND internal process is ongoing */
- HAL_NAND_STATE_ERROR = 0x03U /*!< NAND error state */
-}HAL_NAND_StateTypeDef;
-
-/**
- * @brief NAND Memory electronic signature Structure definition
- */
-typedef struct
-{
- /*State = HAL_NAND_STATE_RESET)
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup NAND_Exported_Functions NAND Exported Functions
- * @{
- */
-
-/** @addtogroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
- * @{
- */
-
-/* Initialization/de-initialization functions ********************************/
-HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FSMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FSMC_NAND_PCC_TimingTypeDef *AttSpace_Timing);
-HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand);
-
-HAL_StatusTypeDef HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig);
-
-HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID);
-
-void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand);
-void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand);
-void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand);
-void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand);
-
-/**
- * @}
- */
-
-/** @addtogroup NAND_Exported_Functions_Group2 Input and Output functions
- * @{
- */
-
-/* IO operation functions ****************************************************/
-
-HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand);
-
-HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead);
-HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite);
-HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead);
-HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite);
-
-HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToRead);
-HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToWrite);
-HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaToRead);
-HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaTowrite);
-
-HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress);
-uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand);
-uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress);
-
-/**
- * @}
- */
-
-/** @addtogroup NAND_Exported_Functions_Group3 Peripheral Control functions
- * @{
- */
-
-/* NAND Control functions ****************************************************/
-HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand);
-HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand);
-HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout);
-
-/**
- * @}
- */
-
-/** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
- * @{
- */
-
-/* NAND State functions *******************************************************/
-HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand);
-uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand);
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/** @addtogroup NAND_Private_Constants
- * @{
- */
-
-#define NAND_DEVICE1 FSMC_BANK2
-#define NAND_DEVICE2 FSMC_BANK3
-#define NAND_WRITE_TIMEOUT 1000U
-
-#define CMD_AREA (1U<<16U) /* A16 = CLE high */
-#define ADDR_AREA (1U<<17U) /* A17 = ALE high */
-
-#define NAND_CMD_AREA_A ((uint8_t)0x00)
-#define NAND_CMD_AREA_B ((uint8_t)0x01)
-#define NAND_CMD_AREA_C ((uint8_t)0x50)
-#define NAND_CMD_AREA_TRUE1 ((uint8_t)0x30)
-
-#define NAND_CMD_WRITE0 ((uint8_t)0x80)
-#define NAND_CMD_WRITE_TRUE1 ((uint8_t)0x10)
-#define NAND_CMD_ERASE0 ((uint8_t)0x60)
-#define NAND_CMD_ERASE1 ((uint8_t)0xD0)
-#define NAND_CMD_READID ((uint8_t)0x90)
-#define NAND_CMD_STATUS ((uint8_t)0x70)
-#define NAND_CMD_LOCK_STATUS ((uint8_t)0x7A)
-#define NAND_CMD_RESET ((uint8_t)0xFF)
-
-/* NAND memory status */
-#define NAND_VALID_ADDRESS 0x00000100U
-#define NAND_INVALID_ADDRESS 0x00000200U
-#define NAND_TIMEOUT_ERROR 0x00000400U
-#define NAND_BUSY 0x00000000U
-#define NAND_ERROR 0x00000001U
-#define NAND_READY 0x00000040U
-
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-/** @addtogroup NAND_Private_Macros
- * @{
- */
-
-/**
- * @brief NAND memory address computation.
- * @param __ADDRESS__: NAND memory address.
- * @param __HANDLE__ : NAND handle.
- * @retval NAND Raw address value
- */
-#define ARRAY_ADDRESS(__ADDRESS__ , __HANDLE__) ((__ADDRESS__)->Page + \
- (((__ADDRESS__)->Block + (((__ADDRESS__)->Plane) * ((__HANDLE__)->Config.PlaneSize)))* ((__HANDLE__)->Config.BlockSize)))
-
-/**
- * @brief NAND memory Column address computation.
- * @param __HANDLE__: NAND handle.
- * @retval NAND Raw address value
- */
-#define COLUMN_ADDRESS( __HANDLE__) ((__HANDLE__)->Config.PageSize)
-
-/**
- * @brief NAND memory address cycling.
- * @param __ADDRESS__: NAND memory address.
- * @retval NAND address cycling value.
- */
-#define ADDR_1ST_CYCLE(__ADDRESS__) (uint8_t)(__ADDRESS__) /* 1st addressing cycle */
-#define ADDR_2ND_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 8U) /* 2nd addressing cycle */
-#define ADDR_3RD_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 16U) /* 3rd addressing cycle */
-#define ADDR_4TH_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 24U) /* 4th addressing cycle */
-
-/**
- * @brief NAND memory Columns cycling.
- * @param __ADDRESS__: NAND memory address.
- * @retval NAND Column address cycling value.
- */
-#define COLUMN_1ST_CYCLE(__ADDRESS__) (uint8_t)(__ADDRESS__) /* 1st Column addressing cycle */
-#define COLUMN_2ND_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 8U) /* 2nd Column addressing cycle */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_NAND_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_nor.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_nor.h
deleted file mode 100644
index 97b492a..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_nor.h
+++ /dev/null
@@ -1,304 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_nor.h
- * @author MCD Application Team
- * @brief Header file of NOR HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_NOR_H
-#define __STM32F1xx_HAL_NOR_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_fsmc.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG) || defined(STM32F100xE)
-/** @addtogroup NOR
- * @{
- */
-
-/** @addtogroup NOR_Private_Constants
- * @{
- */
-
-/* NOR device IDs addresses */
-#define MC_ADDRESS ((uint16_t)0x0000)
-#define DEVICE_CODE1_ADDR ((uint16_t)0x0001)
-#define DEVICE_CODE2_ADDR ((uint16_t)0x000E)
-#define DEVICE_CODE3_ADDR ((uint16_t)0x000F)
-
-/* NOR CFI IDs addresses */
-#define CFI1_ADDRESS ((uint16_t)0x10)
-#define CFI2_ADDRESS ((uint16_t)0x11)
-#define CFI3_ADDRESS ((uint16_t)0x12)
-#define CFI4_ADDRESS ((uint16_t)0x13)
-
-/* NOR operation wait timeout */
-#define NOR_TMEOUT ((uint16_t)0xFFFF)
-
-/* NOR memory data width */
-#define NOR_MEMORY_8B ((uint8_t)0x0)
-#define NOR_MEMORY_16B ((uint8_t)0x1)
-
-/* NOR memory device read/write start address */
-#define NOR_MEMORY_ADRESS1 FSMC_BANK1_1
-#define NOR_MEMORY_ADRESS2 FSMC_BANK1_2
-#define NOR_MEMORY_ADRESS3 FSMC_BANK1_3
-#define NOR_MEMORY_ADRESS4 FSMC_BANK1_4
-
-/**
- * @}
- */
-
-/** @addtogroup NOR_Private_Macros
- * @{
- */
-
-/**
- * @brief NOR memory address shifting.
- * @param __NOR_ADDRESS: NOR base address
- * @param __NOR_MEMORY_WIDTH_: NOR memory width
- * @param __ADDRESS__: NOR memory address
- * @retval NOR shifted address value
- */
-#define NOR_ADDR_SHIFT(__NOR_ADDRESS, __NOR_MEMORY_WIDTH_, __ADDRESS__) \
- ((uint32_t)(((__NOR_MEMORY_WIDTH_) == NOR_MEMORY_16B)? \
- ((uint32_t)((__NOR_ADDRESS) + (2U * (__ADDRESS__)))): \
- ((uint32_t)((__NOR_ADDRESS) + (__ADDRESS__)))))
-
-/**
- * @brief NOR memory write data to specified address.
- * @param __ADDRESS__: NOR memory address
- * @param __DATA__: Data to write
- * @retval None
- */
-#define NOR_WRITE(__ADDRESS__, __DATA__) (*(__IO uint16_t *)((uint32_t)(__ADDRESS__)) = (__DATA__))
-
-/**
- * @}
- */
-
-/* Exported typedef ----------------------------------------------------------*/
-/** @defgroup NOR_Exported_Types NOR Exported Types
- * @{
- */
-
-/**
- * @brief HAL SRAM State structures definition
- */
-typedef enum
-{
- HAL_NOR_STATE_RESET = 0x00U, /*!< NOR not yet initialized or disabled */
- HAL_NOR_STATE_READY = 0x01U, /*!< NOR initialized and ready for use */
- HAL_NOR_STATE_BUSY = 0x02U, /*!< NOR internal processing is ongoing */
- HAL_NOR_STATE_ERROR = 0x03U, /*!< NOR error state */
- HAL_NOR_STATE_PROTECTED = 0x04U /*!< NOR NORSRAM device write protected */
-}HAL_NOR_StateTypeDef;
-
-/**
- * @brief FSMC NOR Status typedef
- */
-typedef enum
-{
- HAL_NOR_STATUS_SUCCESS = 0U,
- HAL_NOR_STATUS_ONGOING,
- HAL_NOR_STATUS_ERROR,
- HAL_NOR_STATUS_TIMEOUT
-}HAL_NOR_StatusTypeDef;
-
-/**
- * @brief FSMC NOR ID typedef
- */
-typedef struct
-{
- uint16_t Manufacturer_Code; /*!< Defines the device's manufacturer code used to identify the memory */
-
- uint16_t Device_Code1;
-
- uint16_t Device_Code2;
-
- uint16_t Device_Code3; /*!< Defines the device's codes used to identify the memory.
- These codes can be accessed by performing read operations with specific
- control signals and addresses set.They can also be accessed by issuing
- an Auto Select command */
-}NOR_IDTypeDef;
-
-/**
- * @brief FSMC NOR CFI typedef
- */
-typedef struct
-{
- /*!< Defines the information stored in the memory's Common flash interface
- which contains a description of various electrical and timing parameters,
- density information and functions supported by the memory */
-
- uint16_t CFI_1;
-
- uint16_t CFI_2;
-
- uint16_t CFI_3;
-
- uint16_t CFI_4;
-}NOR_CFITypeDef;
-
-/**
- * @brief NOR handle Structure definition
- */
-typedef struct
-{
- FSMC_NORSRAM_TypeDef *Instance; /*!< Register base address */
-
- FSMC_NORSRAM_EXTENDED_TypeDef *Extended; /*!< Extended mode register base address */
-
- FSMC_NORSRAM_InitTypeDef Init; /*!< NOR device control configuration parameters */
-
- HAL_LockTypeDef Lock; /*!< NOR locking object */
-
- __IO HAL_NOR_StateTypeDef State; /*!< NOR device access state */
-
-}NOR_HandleTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/* Exported macro ------------------------------------------------------------*/
-
-/** @defgroup NOR_Exported_macro NOR Exported Macros
- * @{
- */
-
-/** @brief Reset NOR handle state
- * @param __HANDLE__: NOR handle
- * @retval None
- */
-#define __HAL_NOR_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_NOR_STATE_RESET)
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup NOR_Exported_Functions NOR Exported Functions
- * @{
- */
-
-/** @addtogroup NOR_Exported_Functions_Group1
- * @{
- */
-
-/* Initialization/de-initialization functions **********************************/
-HAL_StatusTypeDef HAL_NOR_Init(NOR_HandleTypeDef *hnor, FSMC_NORSRAM_TimingTypeDef *Timing, FSMC_NORSRAM_TimingTypeDef *ExtTiming);
-HAL_StatusTypeDef HAL_NOR_DeInit(NOR_HandleTypeDef *hnor);
-void HAL_NOR_MspInit(NOR_HandleTypeDef *hnor);
-void HAL_NOR_MspDeInit(NOR_HandleTypeDef *hnor);
-void HAL_NOR_MspWait(NOR_HandleTypeDef *hnor, uint32_t Timeout);
-
-/**
- * @}
- */
-
-/** @addtogroup NOR_Exported_Functions_Group2
- * @{
- */
-
-/* I/O operation functions ***************************************************/
-HAL_StatusTypeDef HAL_NOR_Read_ID(NOR_HandleTypeDef *hnor, NOR_IDTypeDef *pNOR_ID);
-HAL_StatusTypeDef HAL_NOR_ReturnToReadMode(NOR_HandleTypeDef *hnor);
-HAL_StatusTypeDef HAL_NOR_Read(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData);
-HAL_StatusTypeDef HAL_NOR_Program(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData);
-
-HAL_StatusTypeDef HAL_NOR_ReadBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize);
-HAL_StatusTypeDef HAL_NOR_ProgramBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize);
-
-HAL_StatusTypeDef HAL_NOR_Erase_Block(NOR_HandleTypeDef *hnor, uint32_t BlockAddress, uint32_t Address);
-HAL_StatusTypeDef HAL_NOR_Erase_Chip(NOR_HandleTypeDef *hnor, uint32_t Address);
-HAL_StatusTypeDef HAL_NOR_Read_CFI(NOR_HandleTypeDef *hnor, NOR_CFITypeDef *pNOR_CFI);
-
-/**
- * @}
- */
-
-/** @addtogroup NOR_Exported_Functions_Group3
- * @{
- */
-
-/* NOR Control functions *****************************************************/
-HAL_StatusTypeDef HAL_NOR_WriteOperation_Enable(NOR_HandleTypeDef *hnor);
-HAL_StatusTypeDef HAL_NOR_WriteOperation_Disable(NOR_HandleTypeDef *hnor);
-
-/**
- * @}
- */
-
-/** @addtogroup NOR_Exported_Functions_Group4
- * @{
- */
-
-/* NOR State functions ********************************************************/
-HAL_NOR_StateTypeDef HAL_NOR_GetState(NOR_HandleTypeDef *hnor);
-HAL_NOR_StatusTypeDef HAL_NOR_GetStatus(NOR_HandleTypeDef *hnor, uint32_t Address, uint32_t Timeout);
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-
-/**
- * @}
- */
-
-#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG || STM32F100xE */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_NOR_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pccard.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pccard.h
deleted file mode 100644
index 7429fb6..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pccard.h
+++ /dev/null
@@ -1,246 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_pccard.h
- * @author MCD Application Team
- * @brief Header file of PCCARD HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_PCCARD_H
-#define __STM32F1xx_HAL_PCCARD_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_fsmc.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG)
-/** @addtogroup PCCARD
- * @{
- */
-
-/** @addtogroup PCCARD_Private_Constants
- * @{
- */
-
-#define PCCARD_DEVICE_ADDRESS FSMC_BANK4
-#define PCCARD_ATTRIBUTE_SPACE_ADDRESS ((uint32_t)(FSMC_BANK4 + 0x08000000U)) /* Attribute space size to @0x9BFF FFFF */
-#define PCCARD_COMMON_SPACE_ADDRESS PCCARD_DEVICE_ADDRESS /* Common space size to @0x93FF FFFF */
-#define PCCARD_IO_SPACE_ADDRESS ((uint32_t)(FSMC_BANK4 + 0x0C000000U)) /* IO space size to @0x9FFF FFFF */
-#define PCCARD_IO_SPACE_PRIMARY_ADDR ((uint32_t)(FSMC_BANK4 + 0x0C0001F0U)) /* IO space size to @0x9FFF FFFF */
-
-/* Compact Flash-ATA registers description */
-#define ATA_DATA ((uint8_t)0x00) /* Data register */
-#define ATA_SECTOR_COUNT ((uint8_t)0x02) /* Sector Count register */
-#define ATA_SECTOR_NUMBER ((uint8_t)0x03) /* Sector Number register */
-#define ATA_CYLINDER_LOW ((uint8_t)0x04) /* Cylinder low register */
-#define ATA_CYLINDER_HIGH ((uint8_t)0x05) /* Cylinder high register */
-#define ATA_CARD_HEAD ((uint8_t)0x06) /* Card/Head register */
-#define ATA_STATUS_CMD ((uint8_t)0x07) /* Status(read)/Command(write) register */
-#define ATA_STATUS_CMD_ALTERNATE ((uint8_t)0x0E) /* Alternate Status(read)/Command(write) register */
-#define ATA_COMMON_DATA_AREA ((uint16_t)0x0400) /* Start of data area (for Common access only!) */
-#define ATA_CARD_CONFIGURATION ((uint16_t)0x0202) /* Card Configuration and Status Register */
-
-/* Compact Flash-ATA commands */
-#define ATA_READ_SECTOR_CMD ((uint8_t)0x20)
-#define ATA_WRITE_SECTOR_CMD ((uint8_t)0x30)
-#define ATA_ERASE_SECTOR_CMD ((uint8_t)0xC0)
-#define ATA_IDENTIFY_CMD ((uint8_t)0xEC)
-
-/* Compact Flash status */
-#define PCCARD_TIMEOUT_ERROR ((uint8_t)0x60)
-#define PCCARD_BUSY ((uint8_t)0x80)
-#define PCCARD_PROGR ((uint8_t)0x01)
-#define PCCARD_READY ((uint8_t)0x40)
-
-#define PCCARD_SECTOR_SIZE 255U /* In half words */
-
-
-/* Compact Flash redefinition */
-#define HAL_CF_Read_ID HAL_PCCARD_Read_ID
-#define HAL_CF_Write_Sector HAL_PCCARD_Write_Sector
-#define HAL_CF_Read_Sector HAL_PCCARD_Read_Sector
-#define HAL_CF_Erase_Sector HAL_PCCARD_Erase_Sector
-#define HAL_CF_Reset HAL_PCCARD_Reset
-
-#define HAL_CF_GetStatus HAL_PCCARD_GetStatus
-#define HAL_CF_ReadStatus HAL_PCCARD_ReadStatus
-
-#define CF_SUCCESS HAL_PCCARD_STATUS_SUCCESS
-#define CF_ONGOING HAL_PCCARD_STATUS_ONGOING
-#define CF_ERROR HAL_PCCARD_STATUS_ERROR
-#define CF_TIMEOUT HAL_PCCARD_STATUS_TIMEOUT
-#define CF_StatusTypedef HAL_PCCARD_StatusTypeDef
-
-#define CF_DEVICE_ADDRESS PCCARD_DEVICE_ADDRESS
-#define CF_ATTRIBUTE_SPACE_ADDRESS PCCARD_ATTRIBUTE_SPACE_ADDRESS
-#define CF_COMMON_SPACE_ADDRESS PCCARD_COMMON_SPACE_ADDRESS
-#define CF_IO_SPACE_ADDRESS PCCARD_IO_SPACE_ADDRESS
-#define CF_IO_SPACE_PRIMARY_ADDR PCCARD_IO_SPACE_PRIMARY_ADDR
-
-#define CF_TIMEOUT_ERROR PCCARD_TIMEOUT_ERROR
-#define CF_BUSY PCCARD_BUSY
-#define CF_PROGR PCCARD_PROGR
-#define CF_READY PCCARD_READY
-
-#define CF_SECTOR_SIZE PCCARD_SECTOR_SIZE
-
-/**
- * @}
- */
-
-/* Exported typedef ----------------------------------------------------------*/
-/** @defgroup PCCARD_Exported_Types PCCARD Exported Types
- * @{
- */
-
-/**
- * @brief HAL PCCARD State structures definition
- */
-typedef enum
-{
- HAL_PCCARD_STATE_RESET = 0x00U, /*!< PCCARD peripheral not yet initialized or disabled */
- HAL_PCCARD_STATE_READY = 0x01U, /*!< PCCARD peripheral ready */
- HAL_PCCARD_STATE_BUSY = 0x02U, /*!< PCCARD peripheral busy */
- HAL_PCCARD_STATE_ERROR = 0x04U /*!< PCCARD peripheral error */
-}HAL_PCCARD_StateTypeDef;
-
-typedef enum
-{
- HAL_PCCARD_STATUS_SUCCESS = 0U,
- HAL_PCCARD_STATUS_ONGOING,
- HAL_PCCARD_STATUS_ERROR,
- HAL_PCCARD_STATUS_TIMEOUT
-}HAL_PCCARD_StatusTypeDef;
-
-/**
- * @brief FSMC_PCCARD handle Structure definition
- */
-typedef struct
-{
- FSMC_PCCARD_TypeDef *Instance; /*!< Register base address for PCCARD device */
-
- FSMC_PCCARD_InitTypeDef Init; /*!< PCCARD device control configuration parameters */
-
- __IO HAL_PCCARD_StateTypeDef State; /*!< PCCARD device access state */
-
- HAL_LockTypeDef Lock; /*!< PCCARD Lock */
-
-}PCCARD_HandleTypeDef;
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup PCCARD_Exported_Macros PCCARD Exported Macros
- * @{
- */
-
-/** @brief Reset PCCARD handle state
- * @param __HANDLE__: specifies the PCCARD handle.
- * @retval None
- */
-#define __HAL_PCCARD_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_PCCARD_STATE_RESET)
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup PCCARD_Exported_Functions PCCARD Exported Functions
- * @{
- */
-
-/** @addtogroup PCCARD_Exported_Functions_Group1 Initialization and de-initialization functions
- * @{
- */
-/* Initialization/de-initialization functions **********************************/
-HAL_StatusTypeDef HAL_PCCARD_Init(PCCARD_HandleTypeDef *hpccard, FSMC_NAND_PCC_TimingTypeDef *ComSpaceTiming, FSMC_NAND_PCC_TimingTypeDef *AttSpaceTiming, FSMC_NAND_PCC_TimingTypeDef *IOSpaceTiming);
-HAL_StatusTypeDef HAL_PCCARD_DeInit(PCCARD_HandleTypeDef *hpccard);
-void HAL_PCCARD_MspInit(PCCARD_HandleTypeDef *hpccard);
-void HAL_PCCARD_MspDeInit(PCCARD_HandleTypeDef *hpccard);
-/**
- * @}
- */
-
-/** @addtogroup PCCARD_Exported_Functions_Group2 Input Output and memory functions
- * @{
- */
-/* IO operation functions *****************************************************/
-HAL_StatusTypeDef HAL_PCCARD_Read_ID(PCCARD_HandleTypeDef *hpccard, uint8_t CompactFlash_ID[], uint8_t *pStatus);
-HAL_StatusTypeDef HAL_PCCARD_Write_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress, uint8_t *pStatus);
-HAL_StatusTypeDef HAL_PCCARD_Read_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress, uint8_t *pStatus);
-HAL_StatusTypeDef HAL_PCCARD_Erase_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t SectorAddress, uint8_t *pStatus);
-HAL_StatusTypeDef HAL_PCCARD_Reset(PCCARD_HandleTypeDef *hpccard);
-void HAL_PCCARD_IRQHandler(PCCARD_HandleTypeDef *hpccard);
-void HAL_PCCARD_ITCallback(PCCARD_HandleTypeDef *hpccard);
-
-/**
- * @}
- */
-
-/** @defgroup PCCARD_Exported_Functions_Group3 Peripheral State functions
- * @{
- */
-/* PCCARD State functions *******************************************************/
-HAL_PCCARD_StateTypeDef HAL_PCCARD_GetState(PCCARD_HandleTypeDef *hpccard);
-HAL_PCCARD_StatusTypeDef HAL_PCCARD_GetStatus(PCCARD_HandleTypeDef *hpccard);
-HAL_PCCARD_StatusTypeDef HAL_PCCARD_ReadStatus(PCCARD_HandleTypeDef *hpccard);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_PCCARD_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd.h
deleted file mode 100644
index 1c8c0b2..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd.h
+++ /dev/null
@@ -1,851 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_pcd.h
- * @author MCD Application Team
- * @brief Header file of PCD HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_PCD_H
-#define __STM32F1xx_HAL_PCD_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-#if defined(STM32F102x6) || defined(STM32F102xB) || \
- defined(STM32F103x6) || defined(STM32F103xB) || \
- defined(STM32F103xE) || defined(STM32F103xG) || \
- defined(STM32F105xC) || defined(STM32F107xC)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_usb.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup PCD
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup PCD_Exported_Types PCD Exported Types
- * @{
- */
-
-/**
- * @brief PCD State structure definition
- */
-typedef enum
-{
- HAL_PCD_STATE_RESET = 0x00U,
- HAL_PCD_STATE_READY = 0x01U,
- HAL_PCD_STATE_ERROR = 0x02U,
- HAL_PCD_STATE_BUSY = 0x03U,
- HAL_PCD_STATE_TIMEOUT = 0x04U
-} PCD_StateTypeDef;
-
-#if defined (USB)
-/**
- * @brief PCD double buffered endpoint direction
- */
-typedef enum
-{
- PCD_EP_DBUF_OUT,
- PCD_EP_DBUF_IN,
- PCD_EP_DBUF_ERR,
-}PCD_EP_DBUF_DIR;
-
-/**
- * @brief PCD endpoint buffer number
- */
-typedef enum
-{
- PCD_EP_NOBUF,
- PCD_EP_BUF0,
- PCD_EP_BUF1
-}PCD_EP_BUF_NUM;
-#endif /* USB */
-
-#if defined (USB_OTG_FS)
-typedef USB_OTG_GlobalTypeDef PCD_TypeDef;
-typedef USB_OTG_CfgTypeDef PCD_InitTypeDef;
-typedef USB_OTG_EPTypeDef PCD_EPTypeDef;
-#endif /* USB_OTG_FS */
-
-#if defined (USB)
-typedef USB_TypeDef PCD_TypeDef;
-typedef USB_CfgTypeDef PCD_InitTypeDef;
-typedef USB_EPTypeDef PCD_EPTypeDef;
-#endif /* USB */
-
-/**
- * @brief PCD Handle Structure definition
- */
-typedef struct
-{
- PCD_TypeDef *Instance; /*!< Register base address */
- PCD_InitTypeDef Init; /*!< PCD required parameters */
- __IO uint8_t USB_Address; /*!< USB Address: not used by USB OTG FS */
- PCD_EPTypeDef IN_ep[16]; /*!< IN endpoint parameters */
- PCD_EPTypeDef OUT_ep[16]; /*!< OUT endpoint parameters */
- HAL_LockTypeDef Lock; /*!< PCD peripheral status */
- __IO PCD_StateTypeDef State; /*!< PCD communication state */
- uint32_t Setup[12U]; /*!< Setup packet buffer */
- void *pData; /*!< Pointer to upper stack Handler */
-} PCD_HandleTypeDef;
-
-/**
- * @}
- */
-
-/* Include PCD HAL Extension module */
-#include "stm32f1xx_hal_pcd_ex.h"
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup PCD_Exported_Constants PCD Exported Constants
- * @{
- */
-
-/** @defgroup PCD_Speed PCD Speed
- * @{
- */
-#define PCD_SPEED_HIGH 0U /* Not Supported */
-#define PCD_SPEED_HIGH_IN_FULL 1U /* Not Supported */
-#define PCD_SPEED_FULL 2U
-/**
- * @}
- */
-
-/** @defgroup PCD_PHY_Module PCD PHY Module
- * @{
- */
-#define PCD_PHY_EMBEDDED 2U
-/**
- * @}
- */
-
-/** @defgroup PCD_Turnaround_Timeout Turnaround Timeout Value
- * @{
- */
-#ifndef USBD_FS_TRDT_VALUE
- #define USBD_FS_TRDT_VALUE 5U
-#endif /* USBD_FS_TRDT_VALUE */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macros -----------------------------------------------------------*/
-/** @defgroup PCD_Exported_Macros PCD Exported Macros
- * @brief macros to handle interrupts and specific clock configurations
- * @{
- */
-#if defined (USB_OTG_FS)
-
-#define __HAL_PCD_ENABLE(__HANDLE__) USB_EnableGlobalInt ((__HANDLE__)->Instance)
-#define __HAL_PCD_DISABLE(__HANDLE__) USB_DisableGlobalInt ((__HANDLE__)->Instance)
-
-#define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__) ((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__))
-#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->GINTSTS) = (__INTERRUPT__))
-#define __HAL_PCD_IS_INVALID_INTERRUPT(__HANDLE__) (USB_ReadInterrupts((__HANDLE__)->Instance) == 0U)
-
-#define __HAL_PCD_UNGATE_PHYCLOCK(__HANDLE__) *(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) &= \
- ~(USB_OTG_PCGCCTL_STOPCLK)
-
-#define __HAL_PCD_GATE_PHYCLOCK(__HANDLE__) *(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) |= USB_OTG_PCGCCTL_STOPCLK
-
-#define __HAL_PCD_IS_PHY_SUSPENDED(__HANDLE__) ((*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE)) & 0x10U)
-
-#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= USB_OTG_FS_WAKEUP_EXTI_LINE
-#define __HAL_USB_OTG_FS_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE)
-#define __HAL_USB_OTG_FS_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (USB_OTG_FS_WAKEUP_EXTI_LINE)
-#define __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = USB_OTG_FS_WAKEUP_EXTI_LINE
-
-#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE() \
- do{ \
- EXTI->FTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE); \
- EXTI->RTSR |= USB_OTG_FS_WAKEUP_EXTI_LINE; \
- } while(0U)
-
-#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_FALLING_EDGE() \
- do{ \
- EXTI->FTSR |= (USB_OTG_FS_WAKEUP_EXTI_LINE); \
- EXTI->RTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE); \
- } while(0U)
-
-#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE() \
- do{ \
- EXTI->RTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE); \
- EXTI->FTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE); \
- EXTI->RTSR |= USB_OTG_FS_WAKEUP_EXTI_LINE; \
- EXTI->FTSR |= USB_OTG_FS_WAKEUP_EXTI_LINE; \
- } while(0U)
-
-#define __HAL_USB_OTG_FS_WAKEUP_EXTI_GENERATE_SWIT() (EXTI->SWIER |= USB_OTG_FS_WAKEUP_EXTI_LINE)
-#endif /* USB_OTG_FS */
-
-#if defined (USB)
-#define __HAL_PCD_ENABLE(__HANDLE__) USB_EnableGlobalInt ((__HANDLE__)->Instance)
-#define __HAL_PCD_DISABLE(__HANDLE__) USB_DisableGlobalInt ((__HANDLE__)->Instance)
-#define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__) ((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__))
-#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->ISTR) &= ~(__INTERRUPT__))
-
-#define __HAL_USB_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= USB_WAKEUP_EXTI_LINE
-#define __HAL_USB_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(USB_WAKEUP_EXTI_LINE)
-#define __HAL_USB_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (USB_WAKEUP_EXTI_LINE)
-#define __HAL_USB_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = USB_WAKEUP_EXTI_LINE
-
-#define __HAL_USB_WAKEUP_EXTI_ENABLE_RISING_EDGE() \
- do{ \
- EXTI->FTSR &= ~(USB_WAKEUP_EXTI_LINE); \
- EXTI->RTSR |= USB_WAKEUP_EXTI_LINE; \
- } while(0U)
-
-#define __HAL_USB_WAKEUP_EXTI_ENABLE_FALLING_EDGE() \
- do{ \
- EXTI->FTSR |= (USB_WAKEUP_EXTI_LINE); \
- EXTI->RTSR &= ~(USB_WAKEUP_EXTI_LINE); \
- } while(0U)
-
-#define __HAL_USB_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE() \
- do{ \
- EXTI->RTSR &= ~(USB_WAKEUP_EXTI_LINE); \
- EXTI->FTSR &= ~(USB_WAKEUP_EXTI_LINE); \
- EXTI->RTSR |= USB_WAKEUP_EXTI_LINE; \
- EXTI->FTSR |= USB_WAKEUP_EXTI_LINE; \
- } while(0U)
-#endif /* USB */
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup PCD_Exported_Functions PCD Exported Functions
- * @{
- */
-
-/* Initialization/de-initialization functions ********************************/
-/** @addtogroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
- * @{
- */
-HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd);
-HAL_StatusTypeDef HAL_PCD_DeInit (PCD_HandleTypeDef *hpcd);
-void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd);
-void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd);
-/**
- * @}
- */
-
-/* I/O operation functions ***************************************************/
-/* Non-Blocking mode: Interrupt */
-/** @addtogroup PCD_Exported_Functions_Group2 IO operation functions
- * @{
- */
-HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd);
-HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd);
-void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd);
-
-void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
-void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
-void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd);
-void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd);
-void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd);
-void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd);
-void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd);
-void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
-void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
-void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd);
-void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd);
-/**
- * @}
- */
-
-/* Peripheral Control functions **********************************************/
-/** @addtogroup PCD_Exported_Functions_Group3 Peripheral Control functions
- * @{
- */
-HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd);
-HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd);
-HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address);
-HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type);
-HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
-HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len);
-HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len);
-uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
-HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
-HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
-HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
-HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
-HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
-/**
- * @}
- */
-
-/* Peripheral State functions ************************************************/
-/** @addtogroup PCD_Exported_Functions_Group4 Peripheral State functions
- * @{
- */
-PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup PCD_Private_Constants PCD Private Constants
- * @{
- */
-/** @defgroup USB_EXTI_Line_Interrupt USB EXTI line interrupt
- * @{
- */
-#if defined (USB_OTG_FS)
-#define USB_OTG_FS_WAKEUP_EXTI_RISING_EDGE 0x08U
-#define USB_OTG_FS_WAKEUP_EXTI_FALLING_EDGE 0x0CU
-#define USB_OTG_FS_WAKEUP_EXTI_RISING_FALLING_EDGE 0x10U
-
-#define USB_OTG_FS_WAKEUP_EXTI_LINE 0x00040000U /*!< External interrupt line 18 Connected to the USB EXTI Line */
-#endif /* USB_OTG_FS */
-
-#if defined (USB)
-#define USB_WAKEUP_EXTI_LINE 0x00040000U /*!< External interrupt line 18 Connected to the USB EXTI Line */
-#endif /* USB */
-/**
- * @}
- */
-
-#if defined (USB)
-/** @defgroup PCD_EP0_MPS PCD EP0 MPS
- * @{
- */
-#define PCD_EP0MPS_64 DEP0CTL_MPS_64
-#define PCD_EP0MPS_32 DEP0CTL_MPS_32
-#define PCD_EP0MPS_16 DEP0CTL_MPS_16
-#define PCD_EP0MPS_08 DEP0CTL_MPS_8
-/**
- * @}
- */
-
-/** @defgroup PCD_ENDP PCD ENDP
- * @{
- */
-#define PCD_ENDP0 ((uint8_t)0)
-#define PCD_ENDP1 ((uint8_t)1)
-#define PCD_ENDP2 ((uint8_t)2)
-#define PCD_ENDP3 ((uint8_t)3)
-#define PCD_ENDP4 ((uint8_t)4)
-#define PCD_ENDP5 ((uint8_t)5)
-#define PCD_ENDP6 ((uint8_t)6)
-#define PCD_ENDP7 ((uint8_t)7)
-/**
- * @}
- */
-
-/** @defgroup PCD_ENDP_Kind PCD Endpoint Kind
- * @{
- */
-#define PCD_SNG_BUF 0U
-#define PCD_DBL_BUF 1U
-/**
- * @}
- */
-#endif /* USB */
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-/** @addtogroup PCD_Private_Macros PCD Private Macros
- * @{
- */
-#if defined (USB)
-/* SetENDPOINT */
-#define PCD_SET_ENDPOINT(USBx, bEpNum,wRegValue) (*(&(USBx)->EP0R + (bEpNum) * 2U)= (uint16_t)(wRegValue))
-
-/* GetENDPOINT */
-#define PCD_GET_ENDPOINT(USBx, bEpNum) (*(&(USBx)->EP0R + (bEpNum) * 2U))
-
-/* ENDPOINT transfer */
-#define USB_EP0StartXfer USB_EPStartXfer
-
-/**
- * @brief sets the type in the endpoint register(bits EP_TYPE[1:0])
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @param wType: Endpoint Type.
- * @retval None
- */
-#define PCD_SET_EPTYPE(USBx, bEpNum,wType) (PCD_SET_ENDPOINT((USBx), (bEpNum),\
- ((PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_T_MASK) | (wType) )))
-
-/**
- * @brief gets the type in the endpoint register(bits EP_TYPE[1:0])
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @retval Endpoint Type
- */
-#define PCD_GET_EPTYPE(USBx, bEpNum) (PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_T_FIELD)
-
-/**
- * @brief free buffer used from the application realizing it to the line
- toggles bit SW_BUF in the double buffered endpoint register
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @param bDir: Direction
- * @retval None
- */
-#define PCD_FreeUserBuffer(USBx, bEpNum, bDir)\
-{\
- if ((bDir) == PCD_EP_DBUF_OUT)\
- { /* OUT double buffered endpoint */\
- PCD_TX_DTOG((USBx), (bEpNum));\
- }\
- else if ((bDir) == PCD_EP_DBUF_IN)\
- { /* IN double buffered endpoint */\
- PCD_RX_DTOG((USBx), (bEpNum));\
- }\
-}
-
-/**
- * @brief gets direction of the double buffered endpoint
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @retval EP_DBUF_OUT, EP_DBUF_IN,
- * EP_DBUF_ERR if the endpoint counter not yet programmed.
- */
-#define PCD_GET_DB_DIR(USBx, bEpNum)\
-{\
- if ((uint16_t)(*PCD_EP_RX_CNT((USBx), (bEpNum)) & 0xFC00) != 0)\
- return(PCD_EP_DBUF_OUT);\
- else if (((uint16_t)(*PCD_EP_TX_CNT((USBx), (bEpNum))) & 0x03FF) != 0)\
- return(PCD_EP_DBUF_IN);\
- else\
- return(PCD_EP_DBUF_ERR);\
-}
-
-/**
- * @brief sets the status for tx transfer (bits STAT_TX[1:0]).
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @param wState: new state
- * @retval None
- */
-#define PCD_SET_EP_TX_STATUS(USBx, bEpNum, wState) { register uint16_t _wRegVal;\
- \
- _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPTX_DTOGMASK;\
- /* toggle first bit ? */ \
- if((USB_EPTX_DTOG1 & (wState))!= 0U)\
- { \
- _wRegVal ^= USB_EPTX_DTOG1; \
- } \
- /* toggle second bit ? */ \
- if((USB_EPTX_DTOG2 & (wState))!= 0U) \
- { \
- _wRegVal ^= USB_EPTX_DTOG2; \
- } \
- PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX|USB_EP_CTR_TX));\
- } /* PCD_SET_EP_TX_STATUS */
-
-/**
- * @brief sets the status for rx transfer (bits STAT_TX[1:0])
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @param wState: new state
- * @retval None
- */
-#define PCD_SET_EP_RX_STATUS(USBx, bEpNum,wState) {\
- register uint16_t _wRegVal; \
- \
- _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPRX_DTOGMASK;\
- /* toggle first bit ? */ \
- if((USB_EPRX_DTOG1 & (wState))!= 0U) \
- { \
- _wRegVal ^= USB_EPRX_DTOG1; \
- } \
- /* toggle second bit ? */ \
- if((USB_EPRX_DTOG2 & (wState))!= 0U) \
- { \
- _wRegVal ^= USB_EPRX_DTOG2; \
- } \
- PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX|USB_EP_CTR_TX)); \
- } /* PCD_SET_EP_RX_STATUS */
-
-/**
- * @brief sets the status for rx & tx (bits STAT_TX[1:0] & STAT_RX[1:0])
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @param wStaterx: new state.
- * @param wStatetx: new state.
- * @retval None
- */
-#define PCD_SET_EP_TXRX_STATUS(USBx,bEpNum,wStaterx,wStatetx) {\
- register uint32_t _wRegVal; \
- \
- _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (USB_EPRX_DTOGMASK |USB_EPTX_STAT) ;\
- /* toggle first bit ? */ \
- if((USB_EPRX_DTOG1 & ((wStaterx)))!= 0U) \
- { \
- _wRegVal ^= USB_EPRX_DTOG1; \
- } \
- /* toggle second bit ? */ \
- if((USB_EPRX_DTOG2 & (wStaterx))!= 0U) \
- { \
- _wRegVal ^= USB_EPRX_DTOG2; \
- } \
- /* toggle first bit ? */ \
- if((USB_EPTX_DTOG1 & (wStatetx))!= 0U) \
- { \
- _wRegVal ^= USB_EPTX_DTOG1; \
- } \
- /* toggle second bit ? */ \
- if((USB_EPTX_DTOG2 & (wStatetx))!= 0U) \
- { \
- _wRegVal ^= USB_EPTX_DTOG2; \
- } \
- PCD_SET_ENDPOINT((USBx), (bEpNum), _wRegVal | USB_EP_CTR_RX|USB_EP_CTR_TX); \
- } /* PCD_SET_EP_TXRX_STATUS */
-
-/**
- * @brief gets the status for tx/rx transfer (bits STAT_TX[1:0]
- * /STAT_RX[1:0])
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @retval status
- */
-#define PCD_GET_EP_TX_STATUS(USBx, bEpNum) ((uint16_t)PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPTX_STAT)
-#define PCD_GET_EP_RX_STATUS(USBx, bEpNum) ((uint16_t)PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPRX_STAT)
-
-/**
- * @brief sets directly the VALID tx/rx-status into the endpoint register
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @retval None
- */
-#define PCD_SET_EP_TX_VALID(USBx, bEpNum) (PCD_SET_EP_TX_STATUS((USBx), (bEpNum), USB_EP_TX_VALID))
-#define PCD_SET_EP_RX_VALID(USBx, bEpNum) (PCD_SET_EP_RX_STATUS((USBx), (bEpNum), USB_EP_RX_VALID))
-
-/**
- * @brief checks stall condition in an endpoint.
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @retval TRUE = endpoint in stall condition.
- */
-#define PCD_GET_EP_TX_STALL_STATUS(USBx, bEpNum) (PCD_GET_EP_TX_STATUS((USBx), (bEpNum)) \
- == USB_EP_TX_STALL)
-#define PCD_GET_EP_RX_STALL_STATUS(USBx, bEpNum) (PCD_GET_EP_RX_STATUS((USBx), (bEpNum)) \
- == USB_EP_RX_STALL)
-
-/**
- * @brief set & clear EP_KIND bit.
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @retval None
- */
-#define PCD_SET_EP_KIND(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum), \
- (USB_EP_CTR_RX|USB_EP_CTR_TX|((PCD_GET_ENDPOINT((USBx), (bEpNum)) | USB_EP_KIND) & USB_EPREG_MASK))))
-#define PCD_CLEAR_EP_KIND(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum), \
- (USB_EP_CTR_RX|USB_EP_CTR_TX|(PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPKIND_MASK))))
-
-/**
- * @brief Sets/clears directly STATUS_OUT bit in the endpoint register.
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @retval None
- */
-#define PCD_SET_OUT_STATUS(USBx, bEpNum) PCD_SET_EP_KIND((USBx), (bEpNum))
-#define PCD_CLEAR_OUT_STATUS(USBx, bEpNum) PCD_CLEAR_EP_KIND((USBx), (bEpNum))
-
-/**
- * @brief Sets/clears directly EP_KIND bit in the endpoint register.
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @retval None
- */
-#define PCD_SET_EP_DBUF(USBx, bEpNum) PCD_SET_EP_KIND((USBx), (bEpNum))
-#define PCD_CLEAR_EP_DBUF(USBx, bEpNum) PCD_CLEAR_EP_KIND((USBx), (bEpNum))
-
-/**
- * @brief Clears bit CTR_RX / CTR_TX in the endpoint register.
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @retval None
- */
-#define PCD_CLEAR_RX_EP_CTR(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum),\
- PCD_GET_ENDPOINT((USBx), (bEpNum)) & 0x7FFFU & USB_EPREG_MASK))
-#define PCD_CLEAR_TX_EP_CTR(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum),\
- PCD_GET_ENDPOINT((USBx), (bEpNum)) & 0xFF7FU & USB_EPREG_MASK))
-
-/**
- * @brief Toggles DTOG_RX / DTOG_TX bit in the endpoint register.
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @retval None
- */
-#define PCD_RX_DTOG(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum), \
- USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX | (PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK)))
-#define PCD_TX_DTOG(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum), \
- USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX | (PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK)))
-
-/**
- * @brief Clears DTOG_RX / DTOG_TX bit in the endpoint register.
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @retval None
- */
-#define PCD_CLEAR_RX_DTOG(USBx, bEpNum) if((PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_DTOG_RX) != 0U)\
- { \
- PCD_RX_DTOG((USBx), (bEpNum)); \
- }
-#define PCD_CLEAR_TX_DTOG(USBx, bEpNum) if((PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_DTOG_TX) != 0U)\
- { \
- PCD_TX_DTOG((USBx), (bEpNum)); \
- }
-
-/**
- * @brief Sets address in an endpoint register.
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @param bAddr: Address.
- * @retval None
- */
-#define PCD_SET_EP_ADDRESS(USBx, bEpNum,bAddr) PCD_SET_ENDPOINT((USBx), (bEpNum),\
- USB_EP_CTR_RX|USB_EP_CTR_TX|(PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK) | (bAddr))
-
-#define PCD_GET_EP_ADDRESS(USBx, bEpNum) ((uint8_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPADDR_FIELD))
-
-#define PCD_EP_TX_ADDRESS(USBx, bEpNum) ((uint32_t *)(((USBx)->BTABLE+(bEpNum)*8U)*2U+ ((uint32_t)(USBx) + 0x400U)))
-#define PCD_EP_TX_CNT(USBx, bEpNum) ((uint32_t *)(((USBx)->BTABLE+(bEpNum)*8U+2U)*2U+ ((uint32_t)(USBx) + 0x400U)))
-#define PCD_EP_RX_ADDRESS(USBx, bEpNum) ((uint32_t *)(((USBx)->BTABLE+(bEpNum)*8U+4U)*2U+ ((uint32_t)(USBx) + 0x400U)))
-#define PCD_EP_RX_CNT(USBx, bEpNum) ((uint32_t *)(((USBx)->BTABLE+(bEpNum)*8U+6U)*2U+ ((uint32_t)(USBx) + 0x400U)))
-
-#define PCD_SET_EP_RX_CNT(USBx, bEpNum,wCount) {\
- uint32_t *pdwReg = PCD_EP_RX_CNT((USBx), (bEpNum)); \
- PCD_SET_EP_CNT_RX_REG(pdwReg, (wCount));\
- }
-
-/**
- * @brief sets address of the tx/rx buffer.
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @param wAddr: address to be set (must be word aligned).
- * @retval None
- */
-#define PCD_SET_EP_TX_ADDRESS(USBx, bEpNum,wAddr) (*PCD_EP_TX_ADDRESS((USBx), (bEpNum)) = (((wAddr) >> 1U) << 1U))
-#define PCD_SET_EP_RX_ADDRESS(USBx, bEpNum,wAddr) (*PCD_EP_RX_ADDRESS((USBx), (bEpNum)) = (((wAddr) >> 1U) << 1U))
-
-/**
- * @brief Gets address of the tx/rx buffer.
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @retval address of the buffer.
- */
-#define PCD_GET_EP_TX_ADDRESS(USBx, bEpNum) ((uint16_t)*PCD_EP_TX_ADDRESS((USBx), (bEpNum)))
-#define PCD_GET_EP_RX_ADDRESS(USBx, bEpNum) ((uint16_t)*PCD_EP_RX_ADDRESS((USBx), (bEpNum)))
-
-/**
- * @brief Sets counter of rx buffer with no. of blocks.
- * @param dwReg: Register
- * @param wCount: Counter.
- * @param wNBlocks: no. of Blocks.
- * @retval None
- */
-#define PCD_CALC_BLK32(dwReg,wCount,wNBlocks) {\
- (wNBlocks) = (wCount) >> 5U;\
- if(((wCount) & 0x1FU) == 0U)\
- { \
- (wNBlocks)--;\
- } \
- *pdwReg = (uint16_t)((uint16_t)((wNBlocks) << 10U) | 0x8000U); \
- }/* PCD_CALC_BLK32 */
-
-#define PCD_CALC_BLK2(dwReg,wCount,wNBlocks) {\
- (wNBlocks) = (wCount) >> 1U;\
- if(((wCount) & 0x01U) != 0U)\
- { \
- (wNBlocks)++;\
- } \
- *pdwReg = (uint16_t)((wNBlocks) << 10U);\
- }/* PCD_CALC_BLK2 */
-
-#define PCD_SET_EP_CNT_RX_REG(dwReg,wCount) {\
- uint16_t wNBlocks;\
- if((wCount) > 62U) \
- { \
- PCD_CALC_BLK32((dwReg),(wCount),wNBlocks); \
- } \
- else \
- { \
- PCD_CALC_BLK2((dwReg),(wCount),wNBlocks); \
- } \
- }/* PCD_SET_EP_CNT_RX_REG */
-
-#define PCD_SET_EP_RX_DBUF0_CNT(USBx, bEpNum,wCount) {\
- uint32_t *pdwReg = PCD_EP_TX_CNT((USBx), (bEpNum)); \
- PCD_SET_EP_CNT_RX_REG(pdwReg, (wCount));\
- }
-
-/**
- * @brief sets counter for the tx/rx buffer.
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @param wCount: Counter value.
- * @retval None
- */
-#define PCD_SET_EP_TX_CNT(USBx, bEpNum,wCount) (*PCD_EP_TX_CNT((USBx), (bEpNum)) = (wCount))
-
-
-/**
- * @brief gets counter of the tx buffer.
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @retval Counter value
- */
-#define PCD_GET_EP_TX_CNT(USBx, bEpNum) ((uint16_t)(*PCD_EP_TX_CNT((USBx), (bEpNum))) & 0x3FFU)
-#define PCD_GET_EP_RX_CNT(USBx, bEpNum) ((uint16_t)(*PCD_EP_RX_CNT((USBx), (bEpNum))) & 0x3FFU)
-
-/**
- * @brief Sets buffer 0/1 address in a double buffer endpoint.
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @param wBuf0Addr: buffer 0 address.
- * @retval Counter value
- */
-#define PCD_SET_EP_DBUF0_ADDR(USBx, bEpNum,wBuf0Addr) {PCD_SET_EP_TX_ADDRESS((USBx), (bEpNum), (wBuf0Addr));}
-#define PCD_SET_EP_DBUF1_ADDR(USBx, bEpNum,wBuf1Addr) {PCD_SET_EP_RX_ADDRESS((USBx), (bEpNum), (wBuf1Addr));}
-
-/**
- * @brief Sets addresses in a double buffer endpoint.
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @param wBuf0Addr: buffer 0 address.
- * @param wBuf1Addr = buffer 1 address.
- * @retval None
- */
-#define PCD_SET_EP_DBUF_ADDR(USBx, bEpNum,wBuf0Addr,wBuf1Addr) { \
- PCD_SET_EP_DBUF0_ADDR((USBx), (bEpNum), (wBuf0Addr));\
- PCD_SET_EP_DBUF1_ADDR((USBx), (bEpNum), (wBuf1Addr));\
- } /* PCD_SET_EP_DBUF_ADDR */
-
-/**
- * @brief Gets buffer 0/1 address of a double buffer endpoint.
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @retval None
- */
-#define PCD_GET_EP_DBUF0_ADDR(USBx, bEpNum) (PCD_GET_EP_TX_ADDRESS((USBx), (bEpNum)))
-#define PCD_GET_EP_DBUF1_ADDR(USBx, bEpNum) (PCD_GET_EP_RX_ADDRESS((USBx), (bEpNum)))
-
-/**
- * @brief Gets buffer 0/1 address of a double buffer endpoint.
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @param bDir: endpoint dir EP_DBUF_OUT = OUT
- * EP_DBUF_IN = IN
- * @param wCount: Counter value
- * @retval None
- */
-#define PCD_SET_EP_DBUF0_CNT(USBx, bEpNum, bDir, wCount) { \
- if((bDir) == PCD_EP_DBUF_OUT)\
- /* OUT endpoint */ \
- {PCD_SET_EP_RX_DBUF0_CNT((USBx), (bEpNum),(wCount));} \
- else if((bDir) == PCD_EP_DBUF_IN)\
- /* IN endpoint */ \
- *PCD_EP_TX_CNT((USBx), (bEpNum)) = (uint32_t)(wCount); \
- } /* SetEPDblBuf0Count*/
-
-#define PCD_SET_EP_DBUF1_CNT(USBx, bEpNum, bDir, wCount) { \
- if((bDir) == PCD_EP_DBUF_OUT)\
- {/* OUT endpoint */ \
- PCD_SET_EP_RX_CNT((USBx), (bEpNum),(wCount)); \
- } \
- else if((bDir) == PCD_EP_DBUF_IN)\
- {/* IN endpoint */ \
- *PCD_EP_TX_CNT((USBx), (bEpNum)) = (uint32_t)(wCount); \
- } \
- } /* SetEPDblBuf1Count */
-
-#define PCD_SET_EP_DBUF_CNT(USBx, bEpNum, bDir, wCount) {\
- PCD_SET_EP_DBUF0_CNT((USBx), (bEpNum), (bDir), (wCount)); \
- PCD_SET_EP_DBUF1_CNT((USBx), (bEpNum), (bDir), (wCount)); \
- } /* PCD_SET_EP_DBUF_CNT */
-
-/**
- * @brief Gets buffer 0/1 rx/tx counter for double buffering.
- * @param USBx: USB peripheral instance register address.
- * @param bEpNum: Endpoint Number.
- * @retval None
- */
-#define PCD_GET_EP_DBUF0_CNT(USBx, bEpNum) (PCD_GET_EP_TX_CNT((USBx), (bEpNum)))
-#define PCD_GET_EP_DBUF1_CNT(USBx, bEpNum) (PCD_GET_EP_RX_CNT((USBx), (bEpNum)))
-
-#endif /* USB */
-
-/** @defgroup PCD_Instance_definition PCD Instance definition
- * @{
- */
-#define IS_PCD_ALL_INSTANCE IS_USB_ALL_INSTANCE
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* STM32F102x6 || STM32F102xB || */
- /* STM32F103x6 || STM32F103xB || */
- /* STM32F103xE || STM32F103xG || */
- /* STM32F105xC || STM32F107xC */
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* __STM32F1xx_HAL_PCD_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd_ex.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd_ex.h
deleted file mode 100644
index f2ca4b8..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd_ex.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_pcd_ex.h
- * @author MCD Application Team
- * @brief Header file of Extended PCD HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_PCD_EX_H
-#define __STM32F1xx_HAL_PCD_EX_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-#if defined(STM32F102x6) || defined(STM32F102xB) || \
- defined(STM32F103x6) || defined(STM32F103xB) || \
- defined(STM32F103xE) || defined(STM32F103xG) || \
- defined(STM32F105xC) || defined(STM32F107xC)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup PCDEx
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/* Exported constants --------------------------------------------------------*/
-/* Exported macros -----------------------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup PCDEx_Exported_Functions PCDEx Exported Functions
- * @{
- */
-/** @addtogroup PCDEx_Exported_Functions_Group1 Peripheral Control functions
- * @{
- */
-#if defined (USB_OTG_FS)
-HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size);
-HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size);
-#endif /* USB_OTG_FS */
-
-#if defined (USB)
-HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd,
- uint16_t ep_addr,
- uint16_t ep_kind,
- uint32_t pmaadress);
-#endif /* USB */
-/**
- * @}
- */
-
-/** @addtogroup PCDEx_Exported_Functions_Group2 Peripheral State functions
- * @{
- */
-void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state);
-/**
- * @}
- */
-/**
- * @}
- */
-/**
- * @}
- */
-
-/**
- * @}
- */
-#endif /* STM32F102x6 || STM32F102xB || */
- /* STM32F103x6 || STM32F103xB || */
- /* STM32F103xE || STM32F103xG || */
- /* STM32F105xC || STM32F107xC */
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* __STM32F1xx_HAL_PCD_EX_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h
deleted file mode 100644
index 8499c7f..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h
+++ /dev/null
@@ -1,404 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_pwr.h
- * @author MCD Application Team
- * @brief Header file of PWR HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_PWR_H
-#define __STM32F1xx_HAL_PWR_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup PWR
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-
-/** @defgroup PWR_Exported_Types PWR Exported Types
- * @{
- */
-
-/**
- * @brief PWR PVD configuration structure definition
- */
-typedef struct
-{
- uint32_t PVDLevel; /*!< PVDLevel: Specifies the PVD detection level.
- This parameter can be a value of @ref PWR_PVD_detection_level */
-
- uint32_t Mode; /*!< Mode: Specifies the operating mode for the selected pins.
- This parameter can be a value of @ref PWR_PVD_Mode */
-}PWR_PVDTypeDef;
-
-
-/**
- * @}
- */
-
-
-/* Internal constants --------------------------------------------------------*/
-
-/** @addtogroup PWR_Private_Constants
- * @{
- */
-
-#define PWR_EXTI_LINE_PVD ((uint32_t)0x00010000) /*!< External interrupt line 16 Connected to the PVD EXTI Line */
-
-/**
- * @}
- */
-
-
-/* Exported constants --------------------------------------------------------*/
-
-/** @defgroup PWR_Exported_Constants PWR Exported Constants
- * @{
- */
-
-/** @defgroup PWR_PVD_detection_level PWR PVD detection level
- * @{
- */
-#define PWR_PVDLEVEL_0 PWR_CR_PLS_2V2
-#define PWR_PVDLEVEL_1 PWR_CR_PLS_2V3
-#define PWR_PVDLEVEL_2 PWR_CR_PLS_2V4
-#define PWR_PVDLEVEL_3 PWR_CR_PLS_2V5
-#define PWR_PVDLEVEL_4 PWR_CR_PLS_2V6
-#define PWR_PVDLEVEL_5 PWR_CR_PLS_2V7
-#define PWR_PVDLEVEL_6 PWR_CR_PLS_2V8
-#define PWR_PVDLEVEL_7 PWR_CR_PLS_2V9
-
-/**
- * @}
- */
-
-/** @defgroup PWR_PVD_Mode PWR PVD Mode
- * @{
- */
-#define PWR_PVD_MODE_NORMAL 0x00000000U /*!< basic mode is used */
-#define PWR_PVD_MODE_IT_RISING 0x00010001U /*!< External Interrupt Mode with Rising edge trigger detection */
-#define PWR_PVD_MODE_IT_FALLING 0x00010002U /*!< External Interrupt Mode with Falling edge trigger detection */
-#define PWR_PVD_MODE_IT_RISING_FALLING 0x00010003U /*!< External Interrupt Mode with Rising/Falling edge trigger detection */
-#define PWR_PVD_MODE_EVENT_RISING 0x00020001U /*!< Event Mode with Rising edge trigger detection */
-#define PWR_PVD_MODE_EVENT_FALLING 0x00020002U /*!< Event Mode with Falling edge trigger detection */
-#define PWR_PVD_MODE_EVENT_RISING_FALLING 0x00020003U /*!< Event Mode with Rising/Falling edge trigger detection */
-
-/**
- * @}
- */
-
-
-/** @defgroup PWR_WakeUp_Pins PWR WakeUp Pins
- * @{
- */
-
-#define PWR_WAKEUP_PIN1 PWR_CSR_EWUP
-
-/**
- * @}
- */
-
-/** @defgroup PWR_Regulator_state_in_SLEEP_STOP_mode PWR Regulator state in SLEEP/STOP mode
- * @{
- */
-#define PWR_MAINREGULATOR_ON 0x00000000U
-#define PWR_LOWPOWERREGULATOR_ON PWR_CR_LPDS
-
-/**
- * @}
- */
-
-/** @defgroup PWR_SLEEP_mode_entry PWR SLEEP mode entry
- * @{
- */
-#define PWR_SLEEPENTRY_WFI ((uint8_t)0x01)
-#define PWR_SLEEPENTRY_WFE ((uint8_t)0x02)
-
-/**
- * @}
- */
-
-/** @defgroup PWR_STOP_mode_entry PWR STOP mode entry
- * @{
- */
-#define PWR_STOPENTRY_WFI ((uint8_t)0x01)
-#define PWR_STOPENTRY_WFE ((uint8_t)0x02)
-
-/**
- * @}
- */
-
-/** @defgroup PWR_Flag PWR Flag
- * @{
- */
-#define PWR_FLAG_WU PWR_CSR_WUF
-#define PWR_FLAG_SB PWR_CSR_SBF
-#define PWR_FLAG_PVDO PWR_CSR_PVDO
-
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup PWR_Exported_Macros PWR Exported Macros
- * @{
- */
-
-/** @brief Check PWR flag is set or not.
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg PWR_FLAG_WU: Wake Up flag. This flag indicates that a wakeup event
- * was received from the WKUP pin or from the RTC alarm
- * An additional wakeup event is detected if the WKUP pin is enabled
- * (by setting the EWUP bit) when the WKUP pin level is already high.
- * @arg PWR_FLAG_SB: StandBy flag. This flag indicates that the system was
- * resumed from StandBy mode.
- * @arg PWR_FLAG_PVDO: PVD Output. This flag is valid only if PVD is enabled
- * by the HAL_PWR_EnablePVD() function. The PVD is stopped by Standby mode
- * For this reason, this bit is equal to 0 after Standby or reset
- * until the PVDE bit is set.
- * @retval The new state of __FLAG__ (TRUE or FALSE).
- */
-#define __HAL_PWR_GET_FLAG(__FLAG__) ((PWR->CSR & (__FLAG__)) == (__FLAG__))
-
-/** @brief Clear the PWR's pending flags.
- * @param __FLAG__: specifies the flag to clear.
- * This parameter can be one of the following values:
- * @arg PWR_FLAG_WU: Wake Up flag
- * @arg PWR_FLAG_SB: StandBy flag
- */
-#define __HAL_PWR_CLEAR_FLAG(__FLAG__) SET_BIT(PWR->CR, ((__FLAG__) << 2))
-
-/**
- * @brief Enable interrupt on PVD Exti Line 16.
- * @retval None.
- */
-#define __HAL_PWR_PVD_EXTI_ENABLE_IT() SET_BIT(EXTI->IMR, PWR_EXTI_LINE_PVD)
-
-/**
- * @brief Disable interrupt on PVD Exti Line 16.
- * @retval None.
- */
-#define __HAL_PWR_PVD_EXTI_DISABLE_IT() CLEAR_BIT(EXTI->IMR, PWR_EXTI_LINE_PVD)
-
-/**
- * @brief Enable event on PVD Exti Line 16.
- * @retval None.
- */
-#define __HAL_PWR_PVD_EXTI_ENABLE_EVENT() SET_BIT(EXTI->EMR, PWR_EXTI_LINE_PVD)
-
-/**
- * @brief Disable event on PVD Exti Line 16.
- * @retval None.
- */
-#define __HAL_PWR_PVD_EXTI_DISABLE_EVENT() CLEAR_BIT(EXTI->EMR, PWR_EXTI_LINE_PVD)
-
-
-/**
- * @brief PVD EXTI line configuration: set falling edge trigger.
- * @retval None.
- */
-#define __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE() SET_BIT(EXTI->FTSR, PWR_EXTI_LINE_PVD)
-
-
-/**
- * @brief Disable the PVD Extended Interrupt Falling Trigger.
- * @retval None.
- */
-#define __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE() CLEAR_BIT(EXTI->FTSR, PWR_EXTI_LINE_PVD)
-
-
-/**
- * @brief PVD EXTI line configuration: set rising edge trigger.
- * @retval None.
- */
-#define __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE() SET_BIT(EXTI->RTSR, PWR_EXTI_LINE_PVD)
-
-/**
- * @brief Disable the PVD Extended Interrupt Rising Trigger.
- * This parameter can be:
- * @retval None.
- */
-#define __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE() CLEAR_BIT(EXTI->RTSR, PWR_EXTI_LINE_PVD)
-
-/**
- * @brief PVD EXTI line configuration: set rising & falling edge trigger.
- * @retval None.
- */
-#define __HAL_PWR_PVD_EXTI_ENABLE_RISING_FALLING_EDGE() __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE();__HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE();
-
-/**
- * @brief Disable the PVD Extended Interrupt Rising & Falling Trigger.
- * This parameter can be:
- * @retval None.
- */
-#define __HAL_PWR_PVD_EXTI_DISABLE_RISING_FALLING_EDGE() __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();__HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE();
-
-
-
-/**
- * @brief Check whether the specified PVD EXTI interrupt flag is set or not.
- * @retval EXTI PVD Line Status.
- */
-#define __HAL_PWR_PVD_EXTI_GET_FLAG() (EXTI->PR & (PWR_EXTI_LINE_PVD))
-
-/**
- * @brief Clear the PVD EXTI flag.
- * @retval None.
- */
-#define __HAL_PWR_PVD_EXTI_CLEAR_FLAG() (EXTI->PR = (PWR_EXTI_LINE_PVD))
-
-/**
- * @brief Generate a Software interrupt on selected EXTI line.
- * @retval None.
- */
-#define __HAL_PWR_PVD_EXTI_GENERATE_SWIT() SET_BIT(EXTI->SWIER, PWR_EXTI_LINE_PVD)
-/**
- * @}
- */
-
-/* Private macro -------------------------------------------------------------*/
-/** @defgroup PWR_Private_Macros PWR Private Macros
- * @{
- */
-#define IS_PWR_PVD_LEVEL(LEVEL) (((LEVEL) == PWR_PVDLEVEL_0) || ((LEVEL) == PWR_PVDLEVEL_1)|| \
- ((LEVEL) == PWR_PVDLEVEL_2) || ((LEVEL) == PWR_PVDLEVEL_3)|| \
- ((LEVEL) == PWR_PVDLEVEL_4) || ((LEVEL) == PWR_PVDLEVEL_5)|| \
- ((LEVEL) == PWR_PVDLEVEL_6) || ((LEVEL) == PWR_PVDLEVEL_7))
-
-
-#define IS_PWR_PVD_MODE(MODE) (((MODE) == PWR_PVD_MODE_IT_RISING)|| ((MODE) == PWR_PVD_MODE_IT_FALLING) || \
- ((MODE) == PWR_PVD_MODE_IT_RISING_FALLING) || ((MODE) == PWR_PVD_MODE_EVENT_RISING) || \
- ((MODE) == PWR_PVD_MODE_EVENT_FALLING) || ((MODE) == PWR_PVD_MODE_EVENT_RISING_FALLING) || \
- ((MODE) == PWR_PVD_MODE_NORMAL))
-
-#define IS_PWR_WAKEUP_PIN(PIN) (((PIN) == PWR_WAKEUP_PIN1))
-
-#define IS_PWR_REGULATOR(REGULATOR) (((REGULATOR) == PWR_MAINREGULATOR_ON) || \
- ((REGULATOR) == PWR_LOWPOWERREGULATOR_ON))
-
-#define IS_PWR_SLEEP_ENTRY(ENTRY) (((ENTRY) == PWR_SLEEPENTRY_WFI) || ((ENTRY) == PWR_SLEEPENTRY_WFE))
-
-#define IS_PWR_STOP_ENTRY(ENTRY) (((ENTRY) == PWR_STOPENTRY_WFI) || ((ENTRY) == PWR_STOPENTRY_WFE))
-
-/**
- * @}
- */
-
-
-
-/* Exported functions --------------------------------------------------------*/
-
-/** @addtogroup PWR_Exported_Functions PWR Exported Functions
- * @{
- */
-
-/** @addtogroup PWR_Exported_Functions_Group1 Initialization and de-initialization functions
- * @{
- */
-
-/* Initialization and de-initialization functions *******************************/
-void HAL_PWR_DeInit(void);
-void HAL_PWR_EnableBkUpAccess(void);
-void HAL_PWR_DisableBkUpAccess(void);
-
-/**
- * @}
- */
-
-/** @addtogroup PWR_Exported_Functions_Group2 Peripheral Control functions
- * @{
- */
-
-/* Peripheral Control functions ************************************************/
-void HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD);
-/* #define HAL_PWR_ConfigPVD 12*/
-void HAL_PWR_EnablePVD(void);
-void HAL_PWR_DisablePVD(void);
-
-/* WakeUp pins configuration functions ****************************************/
-void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinx);
-void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx);
-
-/* Low Power modes configuration functions ************************************/
-void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry);
-void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry);
-void HAL_PWR_EnterSTANDBYMode(void);
-
-void HAL_PWR_EnableSleepOnExit(void);
-void HAL_PWR_DisableSleepOnExit(void);
-void HAL_PWR_EnableSEVOnPend(void);
-void HAL_PWR_DisableSEVOnPend(void);
-
-
-
-void HAL_PWR_PVD_IRQHandler(void);
-void HAL_PWR_PVDCallback(void);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* __STM32F1xx_HAL_PWR_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h
deleted file mode 100644
index 0e3bdfc..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h
+++ /dev/null
@@ -1,1393 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_rcc.h
- * @author MCD Application Team
- * @brief Header file of RCC HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_RCC_H
-#define __STM32F1xx_HAL_RCC_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup RCC
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-
-/** @defgroup RCC_Exported_Types RCC Exported Types
- * @{
- */
-
-/**
- * @brief RCC PLL configuration structure definition
- */
-typedef struct
-{
- uint32_t PLLState; /*!< PLLState: The new state of the PLL.
- This parameter can be a value of @ref RCC_PLL_Config */
-
- uint32_t PLLSource; /*!< PLLSource: PLL entry clock source.
- This parameter must be a value of @ref RCC_PLL_Clock_Source */
-
- uint32_t PLLMUL; /*!< PLLMUL: Multiplication factor for PLL VCO input clock
- This parameter must be a value of @ref RCCEx_PLL_Multiplication_Factor */
-} RCC_PLLInitTypeDef;
-
-/**
- * @brief RCC System, AHB and APB busses clock configuration structure definition
- */
-typedef struct
-{
- uint32_t ClockType; /*!< The clock to be configured.
- This parameter can be a value of @ref RCC_System_Clock_Type */
-
- uint32_t SYSCLKSource; /*!< The clock source (SYSCLKS) used as system clock.
- This parameter can be a value of @ref RCC_System_Clock_Source */
-
- uint32_t AHBCLKDivider; /*!< The AHB clock (HCLK) divider. This clock is derived from the system clock (SYSCLK).
- This parameter can be a value of @ref RCC_AHB_Clock_Source */
-
- uint32_t APB1CLKDivider; /*!< The APB1 clock (PCLK1) divider. This clock is derived from the AHB clock (HCLK).
- This parameter can be a value of @ref RCC_APB1_APB2_Clock_Source */
-
- uint32_t APB2CLKDivider; /*!< The APB2 clock (PCLK2) divider. This clock is derived from the AHB clock (HCLK).
- This parameter can be a value of @ref RCC_APB1_APB2_Clock_Source */
-} RCC_ClkInitTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup RCC_Exported_Constants RCC Exported Constants
- * @{
- */
-
-/** @defgroup RCC_PLL_Clock_Source PLL Clock Source
- * @{
- */
-
-#define RCC_PLLSOURCE_HSI_DIV2 0x00000000U /*!< HSI clock divided by 2 selected as PLL entry clock source */
-#define RCC_PLLSOURCE_HSE RCC_CFGR_PLLSRC /*!< HSE clock selected as PLL entry clock source */
-
-/**
- * @}
- */
-
-/** @defgroup RCC_Oscillator_Type Oscillator Type
- * @{
- */
-#define RCC_OSCILLATORTYPE_NONE 0x00000000U
-#define RCC_OSCILLATORTYPE_HSE 0x00000001U
-#define RCC_OSCILLATORTYPE_HSI 0x00000002U
-#define RCC_OSCILLATORTYPE_LSE 0x00000004U
-#define RCC_OSCILLATORTYPE_LSI 0x00000008U
-/**
- * @}
- */
-
-/** @defgroup RCC_HSE_Config HSE Config
- * @{
- */
-#define RCC_HSE_OFF 0x00000000U /*!< HSE clock deactivation */
-#define RCC_HSE_ON RCC_CR_HSEON /*!< HSE clock activation */
-#define RCC_HSE_BYPASS ((uint32_t)(RCC_CR_HSEBYP | RCC_CR_HSEON)) /*!< External clock source for HSE clock */
-/**
- * @}
- */
-
-/** @defgroup RCC_LSE_Config LSE Config
- * @{
- */
-#define RCC_LSE_OFF 0x00000000U /*!< LSE clock deactivation */
-#define RCC_LSE_ON RCC_BDCR_LSEON /*!< LSE clock activation */
-#define RCC_LSE_BYPASS ((uint32_t)(RCC_BDCR_LSEBYP | RCC_BDCR_LSEON)) /*!< External clock source for LSE clock */
-
-/**
- * @}
- */
-
-/** @defgroup RCC_HSI_Config HSI Config
- * @{
- */
-#define RCC_HSI_OFF 0x00000000U /*!< HSI clock deactivation */
-#define RCC_HSI_ON RCC_CR_HSION /*!< HSI clock activation */
-
-#define RCC_HSICALIBRATION_DEFAULT 0x10U /* Default HSI calibration trimming value */
-
-/**
- * @}
- */
-
-/** @defgroup RCC_LSI_Config LSI Config
- * @{
- */
-#define RCC_LSI_OFF 0x00000000U /*!< LSI clock deactivation */
-#define RCC_LSI_ON RCC_CSR_LSION /*!< LSI clock activation */
-
-/**
- * @}
- */
-
-/** @defgroup RCC_PLL_Config PLL Config
- * @{
- */
-#define RCC_PLL_NONE 0x00000000U /*!< PLL is not configured */
-#define RCC_PLL_OFF 0x00000001U /*!< PLL deactivation */
-#define RCC_PLL_ON 0x00000002U /*!< PLL activation */
-
-/**
- * @}
- */
-
-/** @defgroup RCC_System_Clock_Type System Clock Type
- * @{
- */
-#define RCC_CLOCKTYPE_SYSCLK 0x00000001U /*!< SYSCLK to configure */
-#define RCC_CLOCKTYPE_HCLK 0x00000002U /*!< HCLK to configure */
-#define RCC_CLOCKTYPE_PCLK1 0x00000004U /*!< PCLK1 to configure */
-#define RCC_CLOCKTYPE_PCLK2 0x00000008U /*!< PCLK2 to configure */
-
-/**
- * @}
- */
-
-/** @defgroup RCC_System_Clock_Source System Clock Source
- * @{
- */
-#define RCC_SYSCLKSOURCE_HSI RCC_CFGR_SW_HSI /*!< HSI selected as system clock */
-#define RCC_SYSCLKSOURCE_HSE RCC_CFGR_SW_HSE /*!< HSE selected as system clock */
-#define RCC_SYSCLKSOURCE_PLLCLK RCC_CFGR_SW_PLL /*!< PLL selected as system clock */
-
-/**
- * @}
- */
-
-/** @defgroup RCC_System_Clock_Source_Status System Clock Source Status
- * @{
- */
-#define RCC_SYSCLKSOURCE_STATUS_HSI RCC_CFGR_SWS_HSI /*!< HSI used as system clock */
-#define RCC_SYSCLKSOURCE_STATUS_HSE RCC_CFGR_SWS_HSE /*!< HSE used as system clock */
-#define RCC_SYSCLKSOURCE_STATUS_PLLCLK RCC_CFGR_SWS_PLL /*!< PLL used as system clock */
-
-/**
- * @}
- */
-
-/** @defgroup RCC_AHB_Clock_Source AHB Clock Source
- * @{
- */
-#define RCC_SYSCLK_DIV1 RCC_CFGR_HPRE_DIV1 /*!< SYSCLK not divided */
-#define RCC_SYSCLK_DIV2 RCC_CFGR_HPRE_DIV2 /*!< SYSCLK divided by 2 */
-#define RCC_SYSCLK_DIV4 RCC_CFGR_HPRE_DIV4 /*!< SYSCLK divided by 4 */
-#define RCC_SYSCLK_DIV8 RCC_CFGR_HPRE_DIV8 /*!< SYSCLK divided by 8 */
-#define RCC_SYSCLK_DIV16 RCC_CFGR_HPRE_DIV16 /*!< SYSCLK divided by 16 */
-#define RCC_SYSCLK_DIV64 RCC_CFGR_HPRE_DIV64 /*!< SYSCLK divided by 64 */
-#define RCC_SYSCLK_DIV128 RCC_CFGR_HPRE_DIV128 /*!< SYSCLK divided by 128 */
-#define RCC_SYSCLK_DIV256 RCC_CFGR_HPRE_DIV256 /*!< SYSCLK divided by 256 */
-#define RCC_SYSCLK_DIV512 RCC_CFGR_HPRE_DIV512 /*!< SYSCLK divided by 512 */
-
-/**
- * @}
- */
-
-/** @defgroup RCC_APB1_APB2_Clock_Source APB1 APB2 Clock Source
- * @{
- */
-#define RCC_HCLK_DIV1 RCC_CFGR_PPRE1_DIV1 /*!< HCLK not divided */
-#define RCC_HCLK_DIV2 RCC_CFGR_PPRE1_DIV2 /*!< HCLK divided by 2 */
-#define RCC_HCLK_DIV4 RCC_CFGR_PPRE1_DIV4 /*!< HCLK divided by 4 */
-#define RCC_HCLK_DIV8 RCC_CFGR_PPRE1_DIV8 /*!< HCLK divided by 8 */
-#define RCC_HCLK_DIV16 RCC_CFGR_PPRE1_DIV16 /*!< HCLK divided by 16 */
-
-/**
- * @}
- */
-
-/** @defgroup RCC_RTC_Clock_Source RTC Clock Source
- * @{
- */
-#define RCC_RTCCLKSOURCE_NO_CLK 0x00000000U /*!< No clock */
-#define RCC_RTCCLKSOURCE_LSE RCC_BDCR_RTCSEL_LSE /*!< LSE oscillator clock used as RTC clock */
-#define RCC_RTCCLKSOURCE_LSI RCC_BDCR_RTCSEL_LSI /*!< LSI oscillator clock used as RTC clock */
-#define RCC_RTCCLKSOURCE_HSE_DIV128 RCC_BDCR_RTCSEL_HSE /*!< HSE oscillator clock divided by 128 used as RTC clock */
-/**
- * @}
- */
-
-
-/** @defgroup RCC_MCO_Index MCO Index
- * @{
- */
-#define RCC_MCO1 0x00000000U
-#define RCC_MCO RCC_MCO1 /*!< MCO1 to be compliant with other families with 2 MCOs*/
-
-/**
- * @}
- */
-
-/** @defgroup RCC_MCOx_Clock_Prescaler MCO Clock Prescaler
- * @{
- */
-#define RCC_MCODIV_1 0x00000000U
-
-/**
- * @}
- */
-
-/** @defgroup RCC_Interrupt Interrupts
- * @{
- */
-#define RCC_IT_LSIRDY ((uint8_t)RCC_CIR_LSIRDYF) /*!< LSI Ready Interrupt flag */
-#define RCC_IT_LSERDY ((uint8_t)RCC_CIR_LSERDYF) /*!< LSE Ready Interrupt flag */
-#define RCC_IT_HSIRDY ((uint8_t)RCC_CIR_HSIRDYF) /*!< HSI Ready Interrupt flag */
-#define RCC_IT_HSERDY ((uint8_t)RCC_CIR_HSERDYF) /*!< HSE Ready Interrupt flag */
-#define RCC_IT_PLLRDY ((uint8_t)RCC_CIR_PLLRDYF) /*!< PLL Ready Interrupt flag */
-#define RCC_IT_CSS ((uint8_t)RCC_CIR_CSSF) /*!< Clock Security System Interrupt flag */
-/**
- * @}
- */
-
-/** @defgroup RCC_Flag Flags
- * Elements values convention: XXXYYYYYb
- * - YYYYY : Flag position in the register
- * - XXX : Register index
- * - 001: CR register
- * - 010: BDCR register
- * - 011: CSR register
- * @{
- */
-/* Flags in the CR register */
-#define RCC_FLAG_HSIRDY ((uint8_t)((CR_REG_INDEX << 5U) | RCC_CR_HSIRDY_Pos)) /*!< Internal High Speed clock ready flag */
-#define RCC_FLAG_HSERDY ((uint8_t)((CR_REG_INDEX << 5U) | RCC_CR_HSERDY_Pos)) /*!< External High Speed clock ready flag */
-#define RCC_FLAG_PLLRDY ((uint8_t)((CR_REG_INDEX << 5U) | RCC_CR_PLLRDY_Pos)) /*!< PLL clock ready flag */
-
-/* Flags in the CSR register */
-#define RCC_FLAG_LSIRDY ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_LSIRDY_Pos)) /*!< Internal Low Speed oscillator Ready */
-#define RCC_FLAG_PINRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_PINRSTF_Pos)) /*!< PIN reset flag */
-#define RCC_FLAG_PORRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_PORRSTF_Pos)) /*!< POR/PDR reset flag */
-#define RCC_FLAG_SFTRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_SFTRSTF_Pos)) /*!< Software Reset flag */
-#define RCC_FLAG_IWDGRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_IWDGRSTF_Pos)) /*!< Independent Watchdog reset flag */
-#define RCC_FLAG_WWDGRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_WWDGRSTF_Pos)) /*!< Window watchdog reset flag */
-#define RCC_FLAG_LPWRRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_LPWRRSTF_Pos)) /*!< Low-Power reset flag */
-
-/* Flags in the BDCR register */
-#define RCC_FLAG_LSERDY ((uint8_t)((BDCR_REG_INDEX << 5U) | RCC_BDCR_LSERDY_Pos)) /*!< External Low Speed oscillator Ready */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-
-/** @defgroup RCC_Exported_Macros RCC Exported Macros
- * @{
- */
-
-/** @defgroup RCC_Peripheral_Clock_Enable_Disable Peripheral Clock Enable Disable
- * @brief Enable or disable the AHB1 peripheral clock.
- * @note After reset, the peripheral clock (used for registers read/write access)
- * is disabled and the application software has to enable this clock before
- * using it.
- * @{
- */
-#define __HAL_RCC_DMA1_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->AHBENR, RCC_AHBENR_DMA1EN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_DMA1EN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_SRAM_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->AHBENR, RCC_AHBENR_SRAMEN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_SRAMEN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_FLITF_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->AHBENR, RCC_AHBENR_FLITFEN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FLITFEN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_CRC_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->AHBENR, RCC_AHBENR_CRCEN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_CRCEN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_DMA1_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_DMA1EN))
-#define __HAL_RCC_SRAM_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_SRAMEN))
-#define __HAL_RCC_FLITF_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_FLITFEN))
-#define __HAL_RCC_CRC_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_CRCEN))
-
-/**
- * @}
- */
-
-/** @defgroup RCC_AHB_Peripheral_Clock_Enable_Disable_Status AHB Peripheral Clock Enable Disable Status
- * @brief Get the enable or disable status of the AHB peripheral clock.
- * @note After reset, the peripheral clock (used for registers read/write access)
- * is disabled and the application software has to enable this clock before
- * using it.
- * @{
- */
-
-#define __HAL_RCC_DMA1_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_DMA1EN)) != RESET)
-#define __HAL_RCC_DMA1_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_DMA1EN)) == RESET)
-#define __HAL_RCC_SRAM_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_SRAMEN)) != RESET)
-#define __HAL_RCC_SRAM_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_SRAMEN)) == RESET)
-#define __HAL_RCC_FLITF_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_FLITFEN)) != RESET)
-#define __HAL_RCC_FLITF_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_FLITFEN)) == RESET)
-#define __HAL_RCC_CRC_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_CRCEN)) != RESET)
-#define __HAL_RCC_CRC_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_CRCEN)) == RESET)
-
-/**
- * @}
- */
-
-/** @defgroup RCC_APB1_Clock_Enable_Disable APB1 Clock Enable Disable
- * @brief Enable or disable the Low Speed APB (APB1) peripheral clock.
- * @note After reset, the peripheral clock (used for registers read/write access)
- * is disabled and the application software has to enable this clock before
- * using it.
- * @{
- */
-#define __HAL_RCC_TIM2_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_TIM3_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM3EN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM3EN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_WWDG_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->APB1ENR, RCC_APB1ENR_WWDGEN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_WWDGEN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_USART2_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_I2C1_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_BKP_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->APB1ENR, RCC_APB1ENR_BKPEN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_BKPEN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_PWR_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_TIM2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM2EN))
-#define __HAL_RCC_TIM3_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM3EN))
-#define __HAL_RCC_WWDG_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_WWDGEN))
-#define __HAL_RCC_USART2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_USART2EN))
-#define __HAL_RCC_I2C1_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_I2C1EN))
-
-#define __HAL_RCC_BKP_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_BKPEN))
-#define __HAL_RCC_PWR_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_PWREN))
-
-/**
- * @}
- */
-
-/** @defgroup RCC_APB1_Peripheral_Clock_Enable_Disable_Status APB1 Peripheral Clock Enable Disable Status
- * @brief Get the enable or disable status of the APB1 peripheral clock.
- * @note After reset, the peripheral clock (used for registers read/write access)
- * is disabled and the application software has to enable this clock before
- * using it.
- * @{
- */
-
-#define __HAL_RCC_TIM2_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM2EN)) != RESET)
-#define __HAL_RCC_TIM2_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM2EN)) == RESET)
-#define __HAL_RCC_TIM3_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM3EN)) != RESET)
-#define __HAL_RCC_TIM3_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM3EN)) == RESET)
-#define __HAL_RCC_WWDG_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_WWDGEN)) != RESET)
-#define __HAL_RCC_WWDG_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_WWDGEN)) == RESET)
-#define __HAL_RCC_USART2_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_USART2EN)) != RESET)
-#define __HAL_RCC_USART2_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_USART2EN)) == RESET)
-#define __HAL_RCC_I2C1_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_I2C1EN)) != RESET)
-#define __HAL_RCC_I2C1_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_I2C1EN)) == RESET)
-#define __HAL_RCC_BKP_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_BKPEN)) != RESET)
-#define __HAL_RCC_BKP_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_BKPEN)) == RESET)
-#define __HAL_RCC_PWR_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_PWREN)) != RESET)
-#define __HAL_RCC_PWR_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_PWREN)) == RESET)
-
-/**
- * @}
- */
-
-/** @defgroup RCC_APB2_Clock_Enable_Disable APB2 Clock Enable Disable
- * @brief Enable or disable the High Speed APB (APB2) peripheral clock.
- * @note After reset, the peripheral clock (used for registers read/write access)
- * is disabled and the application software has to enable this clock before
- * using it.
- * @{
- */
-#define __HAL_RCC_AFIO_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->APB2ENR, RCC_APB2ENR_AFIOEN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_AFIOEN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_GPIOA_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_GPIOB_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPBEN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPBEN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_GPIOC_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPCEN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPCEN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_GPIOD_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_ADC1_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_TIM1_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_SPI1_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_USART1_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN);\
- /* Delay after an RCC peripheral clock enabling */\
- tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN);\
- UNUSED(tmpreg); \
- } while(0U)
-
-#define __HAL_RCC_AFIO_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_AFIOEN))
-#define __HAL_RCC_GPIOA_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_IOPAEN))
-#define __HAL_RCC_GPIOB_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_IOPBEN))
-#define __HAL_RCC_GPIOC_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_IOPCEN))
-#define __HAL_RCC_GPIOD_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_IOPDEN))
-#define __HAL_RCC_ADC1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN))
-
-#define __HAL_RCC_TIM1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_TIM1EN))
-#define __HAL_RCC_SPI1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_SPI1EN))
-#define __HAL_RCC_USART1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_USART1EN))
-
-/**
- * @}
- */
-
-/** @defgroup RCC_APB2_Peripheral_Clock_Enable_Disable_Status APB2 Peripheral Clock Enable Disable Status
- * @brief Get the enable or disable status of the APB2 peripheral clock.
- * @note After reset, the peripheral clock (used for registers read/write access)
- * is disabled and the application software has to enable this clock before
- * using it.
- * @{
- */
-
-#define __HAL_RCC_AFIO_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_AFIOEN)) != RESET)
-#define __HAL_RCC_AFIO_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_AFIOEN)) == RESET)
-#define __HAL_RCC_GPIOA_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_IOPAEN)) != RESET)
-#define __HAL_RCC_GPIOA_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_IOPAEN)) == RESET)
-#define __HAL_RCC_GPIOB_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_IOPBEN)) != RESET)
-#define __HAL_RCC_GPIOB_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_IOPBEN)) == RESET)
-#define __HAL_RCC_GPIOC_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_IOPCEN)) != RESET)
-#define __HAL_RCC_GPIOC_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_IOPCEN)) == RESET)
-#define __HAL_RCC_GPIOD_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_IOPDEN)) != RESET)
-#define __HAL_RCC_GPIOD_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_IOPDEN)) == RESET)
-#define __HAL_RCC_ADC1_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_ADC1EN)) != RESET)
-#define __HAL_RCC_ADC1_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_ADC1EN)) == RESET)
-#define __HAL_RCC_TIM1_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_TIM1EN)) != RESET)
-#define __HAL_RCC_TIM1_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_TIM1EN)) == RESET)
-#define __HAL_RCC_SPI1_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_SPI1EN)) != RESET)
-#define __HAL_RCC_SPI1_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_SPI1EN)) == RESET)
-#define __HAL_RCC_USART1_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_USART1EN)) != RESET)
-#define __HAL_RCC_USART1_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_USART1EN)) == RESET)
-
-/**
- * @}
- */
-
-/** @defgroup RCC_APB1_Force_Release_Reset APB1 Force Release Reset
- * @brief Force or release APB1 peripheral reset.
- * @{
- */
-#define __HAL_RCC_APB1_FORCE_RESET() (RCC->APB2RSTR = 0xFFFFFFFFU)
-#define __HAL_RCC_TIM2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM2RST))
-#define __HAL_RCC_TIM3_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM3RST))
-#define __HAL_RCC_WWDG_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_WWDGRST))
-#define __HAL_RCC_USART2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_USART2RST))
-#define __HAL_RCC_I2C1_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_I2C1RST))
-
-#define __HAL_RCC_BKP_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_BKPRST))
-#define __HAL_RCC_PWR_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_PWRRST))
-
-#define __HAL_RCC_APB1_RELEASE_RESET() (RCC->APB1RSTR = 0x00)
-#define __HAL_RCC_TIM2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM2RST))
-#define __HAL_RCC_TIM3_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM3RST))
-#define __HAL_RCC_WWDG_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_WWDGRST))
-#define __HAL_RCC_USART2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_USART2RST))
-#define __HAL_RCC_I2C1_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_I2C1RST))
-
-#define __HAL_RCC_BKP_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_BKPRST))
-#define __HAL_RCC_PWR_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_PWRRST))
-
-/**
- * @}
- */
-
-/** @defgroup RCC_APB2_Force_Release_Reset APB2 Force Release Reset
- * @brief Force or release APB2 peripheral reset.
- * @{
- */
-#define __HAL_RCC_APB2_FORCE_RESET() (RCC->APB2RSTR = 0xFFFFFFFFU)
-#define __HAL_RCC_AFIO_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_AFIORST))
-#define __HAL_RCC_GPIOA_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_IOPARST))
-#define __HAL_RCC_GPIOB_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_IOPBRST))
-#define __HAL_RCC_GPIOC_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_IOPCRST))
-#define __HAL_RCC_GPIOD_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_IOPDRST))
-#define __HAL_RCC_ADC1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_ADC1RST))
-
-#define __HAL_RCC_TIM1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_TIM1RST))
-#define __HAL_RCC_SPI1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_SPI1RST))
-#define __HAL_RCC_USART1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_USART1RST))
-
-#define __HAL_RCC_APB2_RELEASE_RESET() (RCC->APB2RSTR = 0x00)
-#define __HAL_RCC_AFIO_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_AFIORST))
-#define __HAL_RCC_GPIOA_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_IOPARST))
-#define __HAL_RCC_GPIOB_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_IOPBRST))
-#define __HAL_RCC_GPIOC_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_IOPCRST))
-#define __HAL_RCC_GPIOD_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_IOPDRST))
-#define __HAL_RCC_ADC1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_ADC1RST))
-
-#define __HAL_RCC_TIM1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_TIM1RST))
-#define __HAL_RCC_SPI1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_SPI1RST))
-#define __HAL_RCC_USART1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_USART1RST))
-
-/**
- * @}
- */
-
-/** @defgroup RCC_HSI_Configuration HSI Configuration
- * @{
- */
-
-/** @brief Macros to enable or disable the Internal High Speed oscillator (HSI).
- * @note The HSI is stopped by hardware when entering STOP and STANDBY modes.
- * @note HSI can not be stopped if it is used as system clock source. In this case,
- * you have to select another source of the system clock then stop the HSI.
- * @note After enabling the HSI, the application software should wait on HSIRDY
- * flag to be set indicating that HSI clock is stable and can be used as
- * system clock source.
- * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator
- * clock cycles.
- */
-#define __HAL_RCC_HSI_ENABLE() (*(__IO uint32_t *) RCC_CR_HSION_BB = ENABLE)
-#define __HAL_RCC_HSI_DISABLE() (*(__IO uint32_t *) RCC_CR_HSION_BB = DISABLE)
-
-/** @brief Macro to adjust the Internal High Speed oscillator (HSI) calibration value.
- * @note The calibration is used to compensate for the variations in voltage
- * and temperature that influence the frequency of the internal HSI RC.
- * @param _HSICALIBRATIONVALUE_ specifies the calibration trimming value.
- * (default is RCC_HSICALIBRATION_DEFAULT).
- * This parameter must be a number between 0 and 0x1F.
- */
-#define __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(_HSICALIBRATIONVALUE_) \
- (MODIFY_REG(RCC->CR, RCC_CR_HSITRIM, (uint32_t)(_HSICALIBRATIONVALUE_) << RCC_CR_HSITRIM_Pos))
-
-/**
- * @}
- */
-
-/** @defgroup RCC_LSI_Configuration LSI Configuration
- * @{
- */
-
-/** @brief Macro to enable the Internal Low Speed oscillator (LSI).
- * @note After enabling the LSI, the application software should wait on
- * LSIRDY flag to be set indicating that LSI clock is stable and can
- * be used to clock the IWDG and/or the RTC.
- */
-#define __HAL_RCC_LSI_ENABLE() (*(__IO uint32_t *) RCC_CSR_LSION_BB = ENABLE)
-
-/** @brief Macro to disable the Internal Low Speed oscillator (LSI).
- * @note LSI can not be disabled if the IWDG is running.
- * @note When the LSI is stopped, LSIRDY flag goes low after 6 LSI oscillator
- * clock cycles.
- */
-#define __HAL_RCC_LSI_DISABLE() (*(__IO uint32_t *) RCC_CSR_LSION_BB = DISABLE)
-
-/**
- * @}
- */
-
-/** @defgroup RCC_HSE_Configuration HSE Configuration
- * @{
- */
-
-/**
- * @brief Macro to configure the External High Speed oscillator (HSE).
- * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
- * supported by this macro. User should request a transition to HSE Off
- * first and then HSE On or HSE Bypass.
- * @note After enabling the HSE (RCC_HSE_ON or RCC_HSE_Bypass), the application
- * software should wait on HSERDY flag to be set indicating that HSE clock
- * is stable and can be used to clock the PLL and/or system clock.
- * @note HSE state can not be changed if it is used directly or through the
- * PLL as system clock. In this case, you have to select another source
- * of the system clock then change the HSE state (ex. disable it).
- * @note The HSE is stopped by hardware when entering STOP and STANDBY modes.
- * @note This function reset the CSSON bit, so if the clock security system(CSS)
- * was previously enabled you have to enable it again after calling this
- * function.
- * @param __STATE__ specifies the new state of the HSE.
- * This parameter can be one of the following values:
- * @arg @ref RCC_HSE_OFF turn OFF the HSE oscillator, HSERDY flag goes low after
- * 6 HSE oscillator clock cycles.
- * @arg @ref RCC_HSE_ON turn ON the HSE oscillator
- * @arg @ref RCC_HSE_BYPASS HSE oscillator bypassed with external clock
- */
-#define __HAL_RCC_HSE_CONFIG(__STATE__) \
- do{ \
- if ((__STATE__) == RCC_HSE_ON) \
- { \
- SET_BIT(RCC->CR, RCC_CR_HSEON); \
- } \
- else if ((__STATE__) == RCC_HSE_OFF) \
- { \
- CLEAR_BIT(RCC->CR, RCC_CR_HSEON); \
- CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); \
- } \
- else if ((__STATE__) == RCC_HSE_BYPASS) \
- { \
- SET_BIT(RCC->CR, RCC_CR_HSEBYP); \
- SET_BIT(RCC->CR, RCC_CR_HSEON); \
- } \
- else \
- { \
- CLEAR_BIT(RCC->CR, RCC_CR_HSEON); \
- CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); \
- } \
- }while(0U)
-
-/**
- * @}
- */
-
-/** @defgroup RCC_LSE_Configuration LSE Configuration
- * @{
- */
-
-/**
- * @brief Macro to configure the External Low Speed oscillator (LSE).
- * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not supported by this macro.
- * @note As the LSE is in the Backup domain and write access is denied to
- * this domain after reset, you have to enable write access using
- * @ref HAL_PWR_EnableBkUpAccess() function before to configure the LSE
- * (to be done once after reset).
- * @note After enabling the LSE (RCC_LSE_ON or RCC_LSE_BYPASS), the application
- * software should wait on LSERDY flag to be set indicating that LSE clock
- * is stable and can be used to clock the RTC.
- * @param __STATE__ specifies the new state of the LSE.
- * This parameter can be one of the following values:
- * @arg @ref RCC_LSE_OFF turn OFF the LSE oscillator, LSERDY flag goes low after
- * 6 LSE oscillator clock cycles.
- * @arg @ref RCC_LSE_ON turn ON the LSE oscillator.
- * @arg @ref RCC_LSE_BYPASS LSE oscillator bypassed with external clock.
- */
-#define __HAL_RCC_LSE_CONFIG(__STATE__) \
- do{ \
- if ((__STATE__) == RCC_LSE_ON) \
- { \
- SET_BIT(RCC->BDCR, RCC_BDCR_LSEON); \
- } \
- else if ((__STATE__) == RCC_LSE_OFF) \
- { \
- CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON); \
- CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); \
- } \
- else if ((__STATE__) == RCC_LSE_BYPASS) \
- { \
- SET_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); \
- SET_BIT(RCC->BDCR, RCC_BDCR_LSEON); \
- } \
- else \
- { \
- CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON); \
- CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); \
- } \
- }while(0U)
-
-/**
- * @}
- */
-
-/** @defgroup RCC_PLL_Configuration PLL Configuration
- * @{
- */
-
-/** @brief Macro to enable the main PLL.
- * @note After enabling the main PLL, the application software should wait on
- * PLLRDY flag to be set indicating that PLL clock is stable and can
- * be used as system clock source.
- * @note The main PLL is disabled by hardware when entering STOP and STANDBY modes.
- */
-#define __HAL_RCC_PLL_ENABLE() (*(__IO uint32_t *) RCC_CR_PLLON_BB = ENABLE)
-
-/** @brief Macro to disable the main PLL.
- * @note The main PLL can not be disabled if it is used as system clock source
- */
-#define __HAL_RCC_PLL_DISABLE() (*(__IO uint32_t *) RCC_CR_PLLON_BB = DISABLE)
-
-/** @brief Macro to configure the main PLL clock source and multiplication factors.
- * @note This function must be used only when the main PLL is disabled.
- *
- * @param __RCC_PLLSOURCE__ specifies the PLL entry clock source.
- * This parameter can be one of the following values:
- * @arg @ref RCC_PLLSOURCE_HSI_DIV2 HSI oscillator clock selected as PLL clock entry
- * @arg @ref RCC_PLLSOURCE_HSE HSE oscillator clock selected as PLL clock entry
- * @param __PLLMUL__ specifies the multiplication factor for PLL VCO output clock
- * This parameter can be one of the following values:
- * @arg @ref RCC_PLL_MUL4 PLLVCO = PLL clock entry x 4
- * @arg @ref RCC_PLL_MUL6 PLLVCO = PLL clock entry x 6
- @if STM32F105xC
- * @arg @ref RCC_PLL_MUL6_5 PLLVCO = PLL clock entry x 6.5
- @elseif STM32F107xC
- * @arg @ref RCC_PLL_MUL6_5 PLLVCO = PLL clock entry x 6.5
- @else
- * @arg @ref RCC_PLL_MUL2 PLLVCO = PLL clock entry x 2
- * @arg @ref RCC_PLL_MUL3 PLLVCO = PLL clock entry x 3
- * @arg @ref RCC_PLL_MUL10 PLLVCO = PLL clock entry x 10
- * @arg @ref RCC_PLL_MUL11 PLLVCO = PLL clock entry x 11
- * @arg @ref RCC_PLL_MUL12 PLLVCO = PLL clock entry x 12
- * @arg @ref RCC_PLL_MUL13 PLLVCO = PLL clock entry x 13
- * @arg @ref RCC_PLL_MUL14 PLLVCO = PLL clock entry x 14
- * @arg @ref RCC_PLL_MUL15 PLLVCO = PLL clock entry x 15
- * @arg @ref RCC_PLL_MUL16 PLLVCO = PLL clock entry x 16
- @endif
- * @arg @ref RCC_PLL_MUL8 PLLVCO = PLL clock entry x 8
- * @arg @ref RCC_PLL_MUL9 PLLVCO = PLL clock entry x 9
- *
- */
-#define __HAL_RCC_PLL_CONFIG(__RCC_PLLSOURCE__, __PLLMUL__)\
- MODIFY_REG(RCC->CFGR, (RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL),((__RCC_PLLSOURCE__) | (__PLLMUL__) ))
-
-/** @brief Get oscillator clock selected as PLL input clock
- * @retval The clock source used for PLL entry. The returned value can be one
- * of the following:
- * @arg @ref RCC_PLLSOURCE_HSI_DIV2 HSI oscillator clock selected as PLL input clock
- * @arg @ref RCC_PLLSOURCE_HSE HSE oscillator clock selected as PLL input clock
- */
-#define __HAL_RCC_GET_PLL_OSCSOURCE() ((uint32_t)(READ_BIT(RCC->CFGR, RCC_CFGR_PLLSRC)))
-
-/**
- * @}
- */
-
-/** @defgroup RCC_Get_Clock_source Get Clock source
- * @{
- */
-
-/**
- * @brief Macro to configure the system clock source.
- * @param __SYSCLKSOURCE__ specifies the system clock source.
- * This parameter can be one of the following values:
- * @arg @ref RCC_SYSCLKSOURCE_HSI HSI oscillator is used as system clock source.
- * @arg @ref RCC_SYSCLKSOURCE_HSE HSE oscillator is used as system clock source.
- * @arg @ref RCC_SYSCLKSOURCE_PLLCLK PLL output is used as system clock source.
- */
-#define __HAL_RCC_SYSCLK_CONFIG(__SYSCLKSOURCE__) \
- MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, (__SYSCLKSOURCE__))
-
-/** @brief Macro to get the clock source used as system clock.
- * @retval The clock source used as system clock. The returned value can be one
- * of the following:
- * @arg @ref RCC_SYSCLKSOURCE_STATUS_HSI HSI used as system clock
- * @arg @ref RCC_SYSCLKSOURCE_STATUS_HSE HSE used as system clock
- * @arg @ref RCC_SYSCLKSOURCE_STATUS_PLLCLK PLL used as system clock
- */
-#define __HAL_RCC_GET_SYSCLK_SOURCE() ((uint32_t)(READ_BIT(RCC->CFGR,RCC_CFGR_SWS)))
-
-/**
- * @}
- */
-
-/** @defgroup RCCEx_MCOx_Clock_Config RCC Extended MCOx Clock Config
- * @{
- */
-
-#if defined(RCC_CFGR_MCO_3)
-/** @brief Macro to configure the MCO clock.
- * @param __MCOCLKSOURCE__ specifies the MCO clock source.
- * This parameter can be one of the following values:
- * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected as MCO clock
- * @arg @ref RCC_MCO1SOURCE_SYSCLK System clock (SYSCLK) selected as MCO clock
- * @arg @ref RCC_MCO1SOURCE_HSI HSI selected as MCO clock
- * @arg @ref RCC_MCO1SOURCE_HSE HSE selected as MCO clock
- * @arg @ref RCC_MCO1SOURCE_PLLCLK PLL clock divided by 2 selected as MCO clock
- * @arg @ref RCC_MCO1SOURCE_PLL2CLK PLL2 clock selected by 2 selected as MCO clock
- * @arg @ref RCC_MCO1SOURCE_PLL3CLK_DIV2 PLL3 clock divided by 2 selected as MCO clock
- * @arg @ref RCC_MCO1SOURCE_EXT_HSE XT1 external 3-25 MHz oscillator clock selected (for Ethernet) as MCO clock
- * @arg @ref RCC_MCO1SOURCE_PLL3CLK PLL3 clock selected (for Ethernet) as MCO clock
- * @param __MCODIV__ specifies the MCO clock prescaler.
- * This parameter can be one of the following values:
- * @arg @ref RCC_MCODIV_1 No division applied on MCO clock source
- */
-#else
-/** @brief Macro to configure the MCO clock.
- * @param __MCOCLKSOURCE__ specifies the MCO clock source.
- * This parameter can be one of the following values:
- * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected as MCO clock
- * @arg @ref RCC_MCO1SOURCE_SYSCLK System clock (SYSCLK) selected as MCO clock
- * @arg @ref RCC_MCO1SOURCE_HSI HSI selected as MCO clock
- * @arg @ref RCC_MCO1SOURCE_HSE HSE selected as MCO clock
- * @arg @ref RCC_MCO1SOURCE_PLLCLK PLL clock divided by 2 selected as MCO clock
- * @param __MCODIV__ specifies the MCO clock prescaler.
- * This parameter can be one of the following values:
- * @arg @ref RCC_MCODIV_1 No division applied on MCO clock source
- */
-#endif
-
-#define __HAL_RCC_MCO1_CONFIG(__MCOCLKSOURCE__, __MCODIV__) \
- MODIFY_REG(RCC->CFGR, RCC_CFGR_MCO, (__MCOCLKSOURCE__))
-
-
-/**
- * @}
- */
-
- /** @defgroup RCC_RTC_Clock_Configuration RCC RTC Clock Configuration
- * @{
- */
-
-/** @brief Macro to configure the RTC clock (RTCCLK).
- * @note As the RTC clock configuration bits are in the Backup domain and write
- * access is denied to this domain after reset, you have to enable write
- * access using the Power Backup Access macro before to configure
- * the RTC clock source (to be done once after reset).
- * @note Once the RTC clock is configured it can't be changed unless the
- * Backup domain is reset using @ref __HAL_RCC_BACKUPRESET_FORCE() macro, or by
- * a Power On Reset (POR).
- *
- * @param __RTC_CLKSOURCE__ specifies the RTC clock source.
- * This parameter can be one of the following values:
- * @arg @ref RCC_RTCCLKSOURCE_NO_CLK No clock selected as RTC clock
- * @arg @ref RCC_RTCCLKSOURCE_LSE LSE selected as RTC clock
- * @arg @ref RCC_RTCCLKSOURCE_LSI LSI selected as RTC clock
- * @arg @ref RCC_RTCCLKSOURCE_HSE_DIV128 HSE divided by 128 selected as RTC clock
- * @note If the LSE or LSI is used as RTC clock source, the RTC continues to
- * work in STOP and STANDBY modes, and can be used as wakeup source.
- * However, when the HSE clock is used as RTC clock source, the RTC
- * cannot be used in STOP and STANDBY modes.
- * @note The maximum input clock frequency for RTC is 1MHz (when using HSE as
- * RTC clock source).
- */
-#define __HAL_RCC_RTC_CONFIG(__RTC_CLKSOURCE__) MODIFY_REG(RCC->BDCR, RCC_BDCR_RTCSEL, (__RTC_CLKSOURCE__))
-
-/** @brief Macro to get the RTC clock source.
- * @retval The clock source can be one of the following values:
- * @arg @ref RCC_RTCCLKSOURCE_NO_CLK No clock selected as RTC clock
- * @arg @ref RCC_RTCCLKSOURCE_LSE LSE selected as RTC clock
- * @arg @ref RCC_RTCCLKSOURCE_LSI LSI selected as RTC clock
- * @arg @ref RCC_RTCCLKSOURCE_HSE_DIV128 HSE divided by 128 selected as RTC clock
- */
-#define __HAL_RCC_GET_RTC_SOURCE() (READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL))
-
-/** @brief Macro to enable the the RTC clock.
- * @note These macros must be used only after the RTC clock source was selected.
- */
-#define __HAL_RCC_RTC_ENABLE() (*(__IO uint32_t *) RCC_BDCR_RTCEN_BB = ENABLE)
-
-/** @brief Macro to disable the the RTC clock.
- * @note These macros must be used only after the RTC clock source was selected.
- */
-#define __HAL_RCC_RTC_DISABLE() (*(__IO uint32_t *) RCC_BDCR_RTCEN_BB = DISABLE)
-
-/** @brief Macro to force the Backup domain reset.
- * @note This function resets the RTC peripheral (including the backup registers)
- * and the RTC clock source selection in RCC_BDCR register.
- */
-#define __HAL_RCC_BACKUPRESET_FORCE() (*(__IO uint32_t *) RCC_BDCR_BDRST_BB = ENABLE)
-
-/** @brief Macros to release the Backup domain reset.
- */
-#define __HAL_RCC_BACKUPRESET_RELEASE() (*(__IO uint32_t *) RCC_BDCR_BDRST_BB = DISABLE)
-
-/**
- * @}
- */
-
-/** @defgroup RCC_Flags_Interrupts_Management Flags Interrupts Management
- * @brief macros to manage the specified RCC Flags and interrupts.
- * @{
- */
-
-/** @brief Enable RCC interrupt.
- * @param __INTERRUPT__ specifies the RCC interrupt sources to be enabled.
- * This parameter can be any combination of the following values:
- * @arg @ref RCC_IT_LSIRDY LSI ready interrupt
- * @arg @ref RCC_IT_LSERDY LSE ready interrupt
- * @arg @ref RCC_IT_HSIRDY HSI ready interrupt
- * @arg @ref RCC_IT_HSERDY HSE ready interrupt
- * @arg @ref RCC_IT_PLLRDY main PLL ready interrupt
- @if STM32F105xx
- * @arg @ref RCC_IT_PLL2RDY Main PLL2 ready interrupt.
- * @arg @ref RCC_IT_PLLI2S2RDY Main PLLI2S ready interrupt.
- @elsif STM32F107xx
- * @arg @ref RCC_IT_PLL2RDY Main PLL2 ready interrupt.
- * @arg @ref RCC_IT_PLLI2S2RDY Main PLLI2S ready interrupt.
- @endif
- */
-#define __HAL_RCC_ENABLE_IT(__INTERRUPT__) (*(__IO uint8_t *) RCC_CIR_BYTE1_ADDRESS |= (__INTERRUPT__))
-
-/** @brief Disable RCC interrupt.
- * @param __INTERRUPT__ specifies the RCC interrupt sources to be disabled.
- * This parameter can be any combination of the following values:
- * @arg @ref RCC_IT_LSIRDY LSI ready interrupt
- * @arg @ref RCC_IT_LSERDY LSE ready interrupt
- * @arg @ref RCC_IT_HSIRDY HSI ready interrupt
- * @arg @ref RCC_IT_HSERDY HSE ready interrupt
- * @arg @ref RCC_IT_PLLRDY main PLL ready interrupt
- @if STM32F105xx
- * @arg @ref RCC_IT_PLL2RDY Main PLL2 ready interrupt.
- * @arg @ref RCC_IT_PLLI2S2RDY Main PLLI2S ready interrupt.
- @elsif STM32F107xx
- * @arg @ref RCC_IT_PLL2RDY Main PLL2 ready interrupt.
- * @arg @ref RCC_IT_PLLI2S2RDY Main PLLI2S ready interrupt.
- @endif
- */
-#define __HAL_RCC_DISABLE_IT(__INTERRUPT__) (*(__IO uint8_t *) RCC_CIR_BYTE1_ADDRESS &= (uint8_t)(~(__INTERRUPT__)))
-
-/** @brief Clear the RCC's interrupt pending bits.
- * @param __INTERRUPT__ specifies the interrupt pending bit to clear.
- * This parameter can be any combination of the following values:
- * @arg @ref RCC_IT_LSIRDY LSI ready interrupt.
- * @arg @ref RCC_IT_LSERDY LSE ready interrupt.
- * @arg @ref RCC_IT_HSIRDY HSI ready interrupt.
- * @arg @ref RCC_IT_HSERDY HSE ready interrupt.
- * @arg @ref RCC_IT_PLLRDY Main PLL ready interrupt.
- @if STM32F105xx
- * @arg @ref RCC_IT_PLL2RDY Main PLL2 ready interrupt.
- * @arg @ref RCC_IT_PLLI2S2RDY Main PLLI2S ready interrupt.
- @elsif STM32F107xx
- * @arg @ref RCC_IT_PLL2RDY Main PLL2 ready interrupt.
- * @arg @ref RCC_IT_PLLI2S2RDY Main PLLI2S ready interrupt.
- @endif
- * @arg @ref RCC_IT_CSS Clock Security System interrupt
- */
-#define __HAL_RCC_CLEAR_IT(__INTERRUPT__) (*(__IO uint8_t *) RCC_CIR_BYTE2_ADDRESS = (__INTERRUPT__))
-
-/** @brief Check the RCC's interrupt has occurred or not.
- * @param __INTERRUPT__ specifies the RCC interrupt source to check.
- * This parameter can be one of the following values:
- * @arg @ref RCC_IT_LSIRDY LSI ready interrupt.
- * @arg @ref RCC_IT_LSERDY LSE ready interrupt.
- * @arg @ref RCC_IT_HSIRDY HSI ready interrupt.
- * @arg @ref RCC_IT_HSERDY HSE ready interrupt.
- * @arg @ref RCC_IT_PLLRDY Main PLL ready interrupt.
- @if STM32F105xx
- * @arg @ref RCC_IT_PLL2RDY Main PLL2 ready interrupt.
- * @arg @ref RCC_IT_PLLI2S2RDY Main PLLI2S ready interrupt.
- @elsif STM32F107xx
- * @arg @ref RCC_IT_PLL2RDY Main PLL2 ready interrupt.
- * @arg @ref RCC_IT_PLLI2S2RDY Main PLLI2S ready interrupt.
- @endif
- * @arg @ref RCC_IT_CSS Clock Security System interrupt
- * @retval The new state of __INTERRUPT__ (TRUE or FALSE).
- */
-#define __HAL_RCC_GET_IT(__INTERRUPT__) ((RCC->CIR & (__INTERRUPT__)) == (__INTERRUPT__))
-
-/** @brief Set RMVF bit to clear the reset flags.
- * The reset flags are RCC_FLAG_PINRST, RCC_FLAG_PORRST, RCC_FLAG_SFTRST,
- * RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST, RCC_FLAG_LPWRRST
- */
-#define __HAL_RCC_CLEAR_RESET_FLAGS() (*(__IO uint32_t *)RCC_CSR_RMVF_BB = ENABLE)
-
-/** @brief Check RCC flag is set or not.
- * @param __FLAG__ specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg @ref RCC_FLAG_HSIRDY HSI oscillator clock ready.
- * @arg @ref RCC_FLAG_HSERDY HSE oscillator clock ready.
- * @arg @ref RCC_FLAG_PLLRDY Main PLL clock ready.
- @if STM32F105xx
- * @arg @ref RCC_FLAG_PLL2RDY Main PLL2 clock ready.
- * @arg @ref RCC_FLAG_PLLI2SRDY Main PLLI2S clock ready.
- @elsif STM32F107xx
- * @arg @ref RCC_FLAG_PLL2RDY Main PLL2 clock ready.
- * @arg @ref RCC_FLAG_PLLI2SRDY Main PLLI2S clock ready.
- @endif
- * @arg @ref RCC_FLAG_LSERDY LSE oscillator clock ready.
- * @arg @ref RCC_FLAG_LSIRDY LSI oscillator clock ready.
- * @arg @ref RCC_FLAG_PINRST Pin reset.
- * @arg @ref RCC_FLAG_PORRST POR/PDR reset.
- * @arg @ref RCC_FLAG_SFTRST Software reset.
- * @arg @ref RCC_FLAG_IWDGRST Independent Watchdog reset.
- * @arg @ref RCC_FLAG_WWDGRST Window Watchdog reset.
- * @arg @ref RCC_FLAG_LPWRRST Low Power reset.
- * @retval The new state of __FLAG__ (TRUE or FALSE).
- */
-#define __HAL_RCC_GET_FLAG(__FLAG__) (((((__FLAG__) >> 5U) == CR_REG_INDEX)? RCC->CR : \
- ((((__FLAG__) >> 5U) == BDCR_REG_INDEX)? RCC->BDCR : \
- RCC->CSR)) & (1U << ((__FLAG__) & RCC_FLAG_MASK)))
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Include RCC HAL Extension module */
-#include "stm32f1xx_hal_rcc_ex.h"
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup RCC_Exported_Functions
- * @{
- */
-
-/** @addtogroup RCC_Exported_Functions_Group1
- * @{
- */
-
-/* Initialization and de-initialization functions ******************************/
-HAL_StatusTypeDef HAL_RCC_DeInit(void);
-HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct);
-HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency);
-
-/**
- * @}
- */
-
-/** @addtogroup RCC_Exported_Functions_Group2
- * @{
- */
-
-/* Peripheral Control functions ************************************************/
-void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv);
-void HAL_RCC_EnableCSS(void);
-void HAL_RCC_DisableCSS(void);
-uint32_t HAL_RCC_GetSysClockFreq(void);
-uint32_t HAL_RCC_GetHCLKFreq(void);
-uint32_t HAL_RCC_GetPCLK1Freq(void);
-uint32_t HAL_RCC_GetPCLK2Freq(void);
-void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct);
-void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency);
-
-/* CSS NMI IRQ handler */
-void HAL_RCC_NMI_IRQHandler(void);
-
-/* User Callbacks in non blocking mode (IT mode) */
-void HAL_RCC_CSSCallback(void);
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup RCC_Private_Constants
- * @{
- */
-
-/** @defgroup RCC_Timeout RCC Timeout
- * @{
- */
-
-/* Disable Backup domain write protection state change timeout */
-#define RCC_DBP_TIMEOUT_VALUE 100U /* 100 ms */
-/* LSE state change timeout */
-#define RCC_LSE_TIMEOUT_VALUE LSE_STARTUP_TIMEOUT
-#define CLOCKSWITCH_TIMEOUT_VALUE 5000 /* 5 s */
-#define HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT
-#define HSI_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
-#define LSI_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
-#define PLL_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
-
-/**
- * @}
- */
-
-/** @defgroup RCC_Register_Offset Register offsets
- * @{
- */
-#define RCC_OFFSET (RCC_BASE - PERIPH_BASE)
-#define RCC_CR_OFFSET 0x00U
-#define RCC_CFGR_OFFSET 0x04U
-#define RCC_CIR_OFFSET 0x08U
-#define RCC_BDCR_OFFSET 0x20U
-#define RCC_CSR_OFFSET 0x24U
-
-/**
- * @}
- */
-
-/** @defgroup RCC_BitAddress_AliasRegion BitAddress AliasRegion
- * @brief RCC registers bit address in the alias region
- * @{
- */
-#define RCC_CR_OFFSET_BB (RCC_OFFSET + RCC_CR_OFFSET)
-#define RCC_CFGR_OFFSET_BB (RCC_OFFSET + RCC_CFGR_OFFSET)
-#define RCC_CIR_OFFSET_BB (RCC_OFFSET + RCC_CIR_OFFSET)
-#define RCC_BDCR_OFFSET_BB (RCC_OFFSET + RCC_BDCR_OFFSET)
-#define RCC_CSR_OFFSET_BB (RCC_OFFSET + RCC_CSR_OFFSET)
-
-/* --- CR Register ---*/
-/* Alias word address of HSION bit */
-#define RCC_HSION_BIT_NUMBER RCC_CR_HSION_Pos
-#define RCC_CR_HSION_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_CR_OFFSET_BB * 32U) + (RCC_HSION_BIT_NUMBER * 4U)))
-/* Alias word address of HSEON bit */
-#define RCC_HSEON_BIT_NUMBER RCC_CR_HSEON_Pos
-#define RCC_CR_HSEON_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_CR_OFFSET_BB * 32U) + (RCC_HSEON_BIT_NUMBER * 4U)))
-/* Alias word address of CSSON bit */
-#define RCC_CSSON_BIT_NUMBER RCC_CR_CSSON_Pos
-#define RCC_CR_CSSON_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_CR_OFFSET_BB * 32U) + (RCC_CSSON_BIT_NUMBER * 4U)))
-/* Alias word address of PLLON bit */
-#define RCC_PLLON_BIT_NUMBER RCC_CR_PLLON_Pos
-#define RCC_CR_PLLON_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_CR_OFFSET_BB * 32U) + (RCC_PLLON_BIT_NUMBER * 4U)))
-
-/* --- CSR Register ---*/
-/* Alias word address of LSION bit */
-#define RCC_LSION_BIT_NUMBER RCC_CSR_LSION_Pos
-#define RCC_CSR_LSION_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_CSR_OFFSET_BB * 32U) + (RCC_LSION_BIT_NUMBER * 4U)))
-
-/* Alias word address of RMVF bit */
-#define RCC_RMVF_BIT_NUMBER RCC_CSR_RMVF_Pos
-#define RCC_CSR_RMVF_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_CSR_OFFSET_BB * 32U) + (RCC_RMVF_BIT_NUMBER * 4U)))
-
-/* --- BDCR Registers ---*/
-/* Alias word address of LSEON bit */
-#define RCC_LSEON_BIT_NUMBER RCC_BDCR_LSEON_Pos
-#define RCC_BDCR_LSEON_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_BDCR_OFFSET_BB * 32U) + (RCC_LSEON_BIT_NUMBER * 4U)))
-
-/* Alias word address of LSEON bit */
-#define RCC_LSEBYP_BIT_NUMBER RCC_BDCR_LSEBYP_Pos
-#define RCC_BDCR_LSEBYP_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_BDCR_OFFSET_BB * 32U) + (RCC_LSEBYP_BIT_NUMBER * 4U)))
-
-/* Alias word address of RTCEN bit */
-#define RCC_RTCEN_BIT_NUMBER RCC_BDCR_RTCEN_Pos
-#define RCC_BDCR_RTCEN_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_BDCR_OFFSET_BB * 32U) + (RCC_RTCEN_BIT_NUMBER * 4U)))
-
-/* Alias word address of BDRST bit */
-#define RCC_BDRST_BIT_NUMBER RCC_BDCR_BDRST_Pos
-#define RCC_BDCR_BDRST_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_BDCR_OFFSET_BB * 32U) + (RCC_BDRST_BIT_NUMBER * 4U)))
-
-/**
- * @}
- */
-
-/* CR register byte 2 (Bits[23:16]) base address */
-#define RCC_CR_BYTE2_ADDRESS ((uint32_t)(RCC_BASE + RCC_CR_OFFSET + 0x02U))
-
-/* CIR register byte 1 (Bits[15:8]) base address */
-#define RCC_CIR_BYTE1_ADDRESS ((uint32_t)(RCC_BASE + RCC_CIR_OFFSET + 0x01U))
-
-/* CIR register byte 2 (Bits[23:16]) base address */
-#define RCC_CIR_BYTE2_ADDRESS ((uint32_t)(RCC_BASE + RCC_CIR_OFFSET + 0x02U))
-
-/* Defines used for Flags */
-#define CR_REG_INDEX ((uint8_t)1)
-#define BDCR_REG_INDEX ((uint8_t)2)
-#define CSR_REG_INDEX ((uint8_t)3)
-
-#define RCC_FLAG_MASK ((uint8_t)0x1F)
-
-/**
- * @}
- */
-
-/** @addtogroup RCC_Private_Macros
- * @{
- */
-/** @defgroup RCC_Alias_For_Legacy Alias define maintained for legacy
- * @{
- */
-#define __HAL_RCC_SYSCFG_CLK_DISABLE __HAL_RCC_AFIO_CLK_DISABLE
-#define __HAL_RCC_SYSCFG_CLK_ENABLE __HAL_RCC_AFIO_CLK_ENABLE
-#define __HAL_RCC_SYSCFG_FORCE_RESET __HAL_RCC_AFIO_FORCE_RESET
-#define __HAL_RCC_SYSCFG_RELEASE_RESET __HAL_RCC_AFIO_RELEASE_RESET
-/**
- * @}
- */
-
-#define IS_RCC_PLLSOURCE(__SOURCE__) (((__SOURCE__) == RCC_PLLSOURCE_HSI_DIV2) || \
- ((__SOURCE__) == RCC_PLLSOURCE_HSE))
-#define IS_RCC_OSCILLATORTYPE(__OSCILLATOR__) (((__OSCILLATOR__) == RCC_OSCILLATORTYPE_NONE) || \
- (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) || \
- (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) || \
- (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) || \
- (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE))
-#define IS_RCC_HSE(__HSE__) (((__HSE__) == RCC_HSE_OFF) || ((__HSE__) == RCC_HSE_ON) || \
- ((__HSE__) == RCC_HSE_BYPASS))
-#define IS_RCC_LSE(__LSE__) (((__LSE__) == RCC_LSE_OFF) || ((__LSE__) == RCC_LSE_ON) || \
- ((__LSE__) == RCC_LSE_BYPASS))
-#define IS_RCC_HSI(__HSI__) (((__HSI__) == RCC_HSI_OFF) || ((__HSI__) == RCC_HSI_ON))
-#define IS_RCC_CALIBRATION_VALUE(__VALUE__) ((__VALUE__) <= 0x1FU)
-#define IS_RCC_LSI(__LSI__) (((__LSI__) == RCC_LSI_OFF) || ((__LSI__) == RCC_LSI_ON))
-#define IS_RCC_PLL(__PLL__) (((__PLL__) == RCC_PLL_NONE) || ((__PLL__) == RCC_PLL_OFF) || \
- ((__PLL__) == RCC_PLL_ON))
-
-#define IS_RCC_CLOCKTYPE(CLK) ((((CLK) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK) || \
- (((CLK) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) || \
- (((CLK) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) || \
- (((CLK) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2))
-#define IS_RCC_SYSCLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_SYSCLKSOURCE_HSI) || \
- ((__SOURCE__) == RCC_SYSCLKSOURCE_HSE) || \
- ((__SOURCE__) == RCC_SYSCLKSOURCE_PLLCLK))
-#define IS_RCC_SYSCLKSOURCE_STATUS(__SOURCE__) (((__SOURCE__) == RCC_SYSCLKSOURCE_STATUS_HSI) || \
- ((__SOURCE__) == RCC_SYSCLKSOURCE_STATUS_HSE) || \
- ((__SOURCE__) == RCC_SYSCLKSOURCE_STATUS_PLLCLK))
-#define IS_RCC_HCLK(__HCLK__) (((__HCLK__) == RCC_SYSCLK_DIV1) || ((__HCLK__) == RCC_SYSCLK_DIV2) || \
- ((__HCLK__) == RCC_SYSCLK_DIV4) || ((__HCLK__) == RCC_SYSCLK_DIV8) || \
- ((__HCLK__) == RCC_SYSCLK_DIV16) || ((__HCLK__) == RCC_SYSCLK_DIV64) || \
- ((__HCLK__) == RCC_SYSCLK_DIV128) || ((__HCLK__) == RCC_SYSCLK_DIV256) || \
- ((__HCLK__) == RCC_SYSCLK_DIV512))
-#define IS_RCC_PCLK(__PCLK__) (((__PCLK__) == RCC_HCLK_DIV1) || ((__PCLK__) == RCC_HCLK_DIV2) || \
- ((__PCLK__) == RCC_HCLK_DIV4) || ((__PCLK__) == RCC_HCLK_DIV8) || \
- ((__PCLK__) == RCC_HCLK_DIV16))
-#define IS_RCC_MCO(__MCO__) ((__MCO__) == RCC_MCO)
-#define IS_RCC_MCODIV(__DIV__) (((__DIV__) == RCC_MCODIV_1))
-#define IS_RCC_RTCCLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_RTCCLKSOURCE_NO_CLK) || \
- ((__SOURCE__) == RCC_RTCCLKSOURCE_LSE) || \
- ((__SOURCE__) == RCC_RTCCLKSOURCE_LSI) || \
- ((__SOURCE__) == RCC_RTCCLKSOURCE_HSE_DIV128))
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_RCC_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc.h
deleted file mode 100644
index 11e1793..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc.h
+++ /dev/null
@@ -1,576 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_rtc.h
- * @author MCD Application Team
- * @brief Header file of RTC HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_RTC_H
-#define __STM32F1xx_HAL_RTC_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup RTC
- * @{
- */
-
-/** @addtogroup RTC_Private_Macros
- * @{
- */
-
-#define IS_RTC_ASYNCH_PREDIV(PREDIV) (((PREDIV) <= 0xFFFFFU) || ((PREDIV) == RTC_AUTO_1_SECOND))
-#define IS_RTC_HOUR24(HOUR) ((HOUR) <= 23U)
-#define IS_RTC_MINUTES(MINUTES) ((MINUTES) <= 59U)
-#define IS_RTC_SECONDS(SECONDS) ((SECONDS) <= 59U)
-#define IS_RTC_FORMAT(FORMAT) (((FORMAT) == RTC_FORMAT_BIN) || ((FORMAT) == RTC_FORMAT_BCD))
-#define IS_RTC_YEAR(YEAR) ((YEAR) <= 99U)
-#define IS_RTC_MONTH(MONTH) (((MONTH) >= 1U) && ((MONTH) <= 12U))
-#define IS_RTC_DATE(DATE) (((DATE) >= 1U) && ((DATE) <= 31U))
-#define IS_RTC_ALARM(ALARM) ((ALARM) == RTC_ALARM_A)
-#define IS_RTC_CALIB_OUTPUT(__OUTPUT__) (((__OUTPUT__) == RTC_OUTPUTSOURCE_NONE) || \
- ((__OUTPUT__) == RTC_OUTPUTSOURCE_CALIBCLOCK) || \
- ((__OUTPUT__) == RTC_OUTPUTSOURCE_ALARM) || \
- ((__OUTPUT__) == RTC_OUTPUTSOURCE_SECOND))
-
-
-/**
- * @}
- */
-
-/** @addtogroup RTC_Private_Constants
- * @{
- */
-/** @defgroup RTC_Timeout_Value Default Timeout Value
- * @{
- */
-#define RTC_TIMEOUT_VALUE 1000U
-/**
- * @}
- */
-
-/** @defgroup RTC_EXTI_Line_Event RTC EXTI Line event
- * @{
- */
-#define RTC_EXTI_LINE_ALARM_EVENT ((uint32_t)EXTI_IMR_MR17) /*!< External interrupt line 17 Connected to the RTC Alarm event */
-/**
- * @}
- */
-
-
-/**
- * @}
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup RTC_Exported_Types RTC Exported Types
- * @{
- */
-/**
- * @brief RTC Time structure definition
- */
-typedef struct
-{
- uint8_t Hours; /*!< Specifies the RTC Time Hour.
- This parameter must be a number between Min_Data = 0 and Max_Data = 23 */
-
- uint8_t Minutes; /*!< Specifies the RTC Time Minutes.
- This parameter must be a number between Min_Data = 0 and Max_Data = 59 */
-
- uint8_t Seconds; /*!< Specifies the RTC Time Seconds.
- This parameter must be a number between Min_Data = 0 and Max_Data = 59 */
-
-}RTC_TimeTypeDef;
-
-/**
- * @brief RTC Alarm structure definition
- */
-typedef struct
-{
- RTC_TimeTypeDef AlarmTime; /*!< Specifies the RTC Alarm Time members */
-
- uint32_t Alarm; /*!< Specifies the alarm ID (only 1 alarm ID for STM32F1).
- This parameter can be a value of @ref RTC_Alarms_Definitions */
-}RTC_AlarmTypeDef;
-
-/**
- * @brief HAL State structures definition
- */
-typedef enum
-{
- HAL_RTC_STATE_RESET = 0x00U, /*!< RTC not yet initialized or disabled */
- HAL_RTC_STATE_READY = 0x01U, /*!< RTC initialized and ready for use */
- HAL_RTC_STATE_BUSY = 0x02U, /*!< RTC process is ongoing */
- HAL_RTC_STATE_TIMEOUT = 0x03U, /*!< RTC timeout state */
- HAL_RTC_STATE_ERROR = 0x04U /*!< RTC error state */
-
-}HAL_RTCStateTypeDef;
-
-/**
- * @brief RTC Configuration Structure definition
- */
-typedef struct
-{
- uint32_t AsynchPrediv; /*!< Specifies the RTC Asynchronous Predivider value.
- This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFFFFF or RTC_AUTO_1_SECOND
- If RTC_AUTO_1_SECOND is selected, AsynchPrediv will be set automatically to get 1sec timebase */
-
- uint32_t OutPut; /*!< Specifies which signal will be routed to the RTC Tamper pin.
- This parameter can be a value of @ref RTC_output_source_to_output_on_the_Tamper_pin */
-
-}RTC_InitTypeDef;
-
-/**
- * @brief RTC Date structure definition
- */
-typedef struct
-{
- uint8_t WeekDay; /*!< Specifies the RTC Date WeekDay (not necessary for HAL_RTC_SetDate).
- This parameter can be a value of @ref RTC_WeekDay_Definitions */
-
- uint8_t Month; /*!< Specifies the RTC Date Month (in BCD format).
- This parameter can be a value of @ref RTC_Month_Date_Definitions */
-
- uint8_t Date; /*!< Specifies the RTC Date.
- This parameter must be a number between Min_Data = 1 and Max_Data = 31 */
-
- uint8_t Year; /*!< Specifies the RTC Date Year.
- This parameter must be a number between Min_Data = 0 and Max_Data = 99 */
-
-}RTC_DateTypeDef;
-
-/**
- * @brief Time Handle Structure definition
- */
-typedef struct
-{
- RTC_TypeDef *Instance; /*!< Register base address */
-
- RTC_InitTypeDef Init; /*!< RTC required parameters */
-
- RTC_DateTypeDef DateToUpdate; /*!< Current date set by user and updated automatically */
-
- HAL_LockTypeDef Lock; /*!< RTC locking object */
-
- __IO HAL_RTCStateTypeDef State; /*!< Time communication state */
-
-}RTC_HandleTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup RTC_Exported_Constants RTC Exported Constants
- * @{
- */
-
-/** @defgroup RTC_Automatic_Prediv_1_Second Automatic calculation of prediv for 1sec timebase
- * @{
- */
-#define RTC_AUTO_1_SECOND 0xFFFFFFFFU
-
-/**
- * @}
- */
-
-/** @defgroup RTC_Input_parameter_format_definitions Input Parameter Format
- * @{
- */
-#define RTC_FORMAT_BIN 0x000000000U
-#define RTC_FORMAT_BCD 0x000000001U
-
-/**
- * @}
- */
-
-/** @defgroup RTC_Month_Date_Definitions Month Definitions
- * @{
- */
-
-/* Coded in BCD format */
-#define RTC_MONTH_JANUARY ((uint8_t)0x01)
-#define RTC_MONTH_FEBRUARY ((uint8_t)0x02)
-#define RTC_MONTH_MARCH ((uint8_t)0x03)
-#define RTC_MONTH_APRIL ((uint8_t)0x04)
-#define RTC_MONTH_MAY ((uint8_t)0x05)
-#define RTC_MONTH_JUNE ((uint8_t)0x06)
-#define RTC_MONTH_JULY ((uint8_t)0x07)
-#define RTC_MONTH_AUGUST ((uint8_t)0x08)
-#define RTC_MONTH_SEPTEMBER ((uint8_t)0x09)
-#define RTC_MONTH_OCTOBER ((uint8_t)0x10)
-#define RTC_MONTH_NOVEMBER ((uint8_t)0x11)
-#define RTC_MONTH_DECEMBER ((uint8_t)0x12)
-
-/**
- * @}
- */
-
-/** @defgroup RTC_WeekDay_Definitions WeekDay Definitions
- * @{
- */
-#define RTC_WEEKDAY_MONDAY ((uint8_t)0x01)
-#define RTC_WEEKDAY_TUESDAY ((uint8_t)0x02)
-#define RTC_WEEKDAY_WEDNESDAY ((uint8_t)0x03)
-#define RTC_WEEKDAY_THURSDAY ((uint8_t)0x04)
-#define RTC_WEEKDAY_FRIDAY ((uint8_t)0x05)
-#define RTC_WEEKDAY_SATURDAY ((uint8_t)0x06)
-#define RTC_WEEKDAY_SUNDAY ((uint8_t)0x00)
-
-/**
- * @}
- */
-
-/** @defgroup RTC_Alarms_Definitions Alarms Definitions
- * @{
- */
-#define RTC_ALARM_A 0U /*!< Specify alarm ID (mainly for legacy purposes) */
-
-/**
- * @}
- */
-
-
-/** @defgroup RTC_output_source_to_output_on_the_Tamper_pin Output source to output on the Tamper pin
- * @{
- */
-
-#define RTC_OUTPUTSOURCE_NONE 0x00000000U /*!< No output on the TAMPER pin */
-#define RTC_OUTPUTSOURCE_CALIBCLOCK BKP_RTCCR_CCO /*!< RTC clock with a frequency divided by 64 on the TAMPER pin */
-#define RTC_OUTPUTSOURCE_ALARM BKP_RTCCR_ASOE /*!< Alarm pulse signal on the TAMPER pin */
-#define RTC_OUTPUTSOURCE_SECOND (BKP_RTCCR_ASOS | BKP_RTCCR_ASOE) /*!< Second pulse signal on the TAMPER pin */
-
-/**
- * @}
- */
-
-/** @defgroup RTC_Interrupts_Definitions Interrupts Definitions
- * @{
- */
-#define RTC_IT_OW RTC_CRH_OWIE /*!< Overflow interrupt */
-#define RTC_IT_ALRA RTC_CRH_ALRIE /*!< Alarm interrupt */
-#define RTC_IT_SEC RTC_CRH_SECIE /*!< Second interrupt */
-#define RTC_IT_TAMP1 BKP_CSR_TPIE /*!< TAMPER Pin interrupt enable */
-/**
- * @}
- */
-
-/** @defgroup RTC_Flags_Definitions Flags Definitions
- * @{
- */
-#define RTC_FLAG_RTOFF RTC_CRL_RTOFF /*!< RTC Operation OFF flag */
-#define RTC_FLAG_RSF RTC_CRL_RSF /*!< Registers Synchronized flag */
-#define RTC_FLAG_OW RTC_CRL_OWF /*!< Overflow flag */
-#define RTC_FLAG_ALRAF RTC_CRL_ALRF /*!< Alarm flag */
-#define RTC_FLAG_SEC RTC_CRL_SECF /*!< Second flag */
-#define RTC_FLAG_TAMP1F BKP_CSR_TEF /*!< Tamper Interrupt Flag */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup RTC_Exported_macros RTC Exported Macros
- * @{
- */
-
-/** @brief Reset RTC handle state
- * @param __HANDLE__: RTC handle.
- * @retval None
- */
-#define __HAL_RTC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_RTC_STATE_RESET)
-
-/**
- * @brief Disable the write protection for RTC registers.
- * @param __HANDLE__: specifies the RTC handle.
- * @retval None
- */
-#define __HAL_RTC_WRITEPROTECTION_DISABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CRL, RTC_CRL_CNF)
-
-/**
- * @brief Enable the write protection for RTC registers.
- * @param __HANDLE__: specifies the RTC handle.
- * @retval None
- */
-#define __HAL_RTC_WRITEPROTECTION_ENABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CRL, RTC_CRL_CNF)
-
-/**
- * @brief Enable the RTC Alarm interrupt.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __INTERRUPT__: specifies the RTC Alarm interrupt sources to be enabled or disabled.
- * This parameter can be any combination of the following values:
- * @arg RTC_IT_ALRA: Alarm A interrupt
- * @retval None
- */
-#define __HAL_RTC_ALARM_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->CRH, (__INTERRUPT__))
-
-/**
- * @brief Disable the RTC Alarm interrupt.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __INTERRUPT__: specifies the RTC Alarm interrupt sources to be enabled or disabled.
- * This parameter can be any combination of the following values:
- * @arg RTC_IT_ALRA: Alarm A interrupt
- * @retval None
- */
-#define __HAL_RTC_ALARM_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT((__HANDLE__)->Instance->CRH, (__INTERRUPT__))
-
-/**
- * @brief Check whether the specified RTC Alarm interrupt has been enabled or not.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __INTERRUPT__: specifies the RTC Alarm interrupt sources to be checked
- * This parameter can be:
- * @arg RTC_IT_ALRA: Alarm A interrupt
- * @retval None
- */
-#define __HAL_RTC_ALARM_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((((__HANDLE__)->Instance->CRH)& ((__INTERRUPT__)))) != RESET)? SET : RESET)
-
-/**
- * @brief Get the selected RTC Alarm's flag status.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __FLAG__: specifies the RTC Alarm Flag sources to be enabled or disabled.
- * This parameter can be:
- * @arg RTC_FLAG_ALRAF
- * @retval None
- */
-#define __HAL_RTC_ALARM_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->CRL) & (__FLAG__)) != RESET)? SET : RESET)
-
-/**
- * @brief Check whether the specified RTC Alarm interrupt has occurred or not.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __INTERRUPT__: specifies the RTC Alarm interrupt sources to check.
- * This parameter can be:
- * @arg RTC_IT_ALRA: Alarm A interrupt
- * @retval None
- */
-#define __HAL_RTC_ALARM_GET_IT(__HANDLE__, __INTERRUPT__) (((((__HANDLE__)->Instance->CRL) & (__INTERRUPT__)) != RESET)? SET : RESET)
-
-/**
- * @brief Clear the RTC Alarm's pending flags.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __FLAG__: specifies the RTC Alarm Flag sources to be enabled or disabled.
- * This parameter can be:
- * @arg RTC_FLAG_ALRAF
- * @retval None
- */
-#define __HAL_RTC_ALARM_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->CRL) = ~(__FLAG__)
-
-/**
- * @brief Enable interrupt on ALARM Exti Line 17.
- * @retval None.
- */
-#define __HAL_RTC_ALARM_EXTI_ENABLE_IT() SET_BIT(EXTI->IMR, RTC_EXTI_LINE_ALARM_EVENT)
-
-/**
- * @brief Disable interrupt on ALARM Exti Line 17.
- * @retval None.
- */
-#define __HAL_RTC_ALARM_EXTI_DISABLE_IT() CLEAR_BIT(EXTI->IMR, RTC_EXTI_LINE_ALARM_EVENT)
-
-/**
- * @brief Enable event on ALARM Exti Line 17.
- * @retval None.
- */
-#define __HAL_RTC_ALARM_EXTI_ENABLE_EVENT() SET_BIT(EXTI->EMR, RTC_EXTI_LINE_ALARM_EVENT)
-
-/**
- * @brief Disable event on ALARM Exti Line 17.
- * @retval None.
- */
-#define __HAL_RTC_ALARM_EXTI_DISABLE_EVENT() CLEAR_BIT(EXTI->EMR, RTC_EXTI_LINE_ALARM_EVENT)
-
-
-/**
- * @brief ALARM EXTI line configuration: set falling edge trigger.
- * @retval None.
- */
-#define __HAL_RTC_ALARM_EXTI_ENABLE_FALLING_EDGE() SET_BIT(EXTI->FTSR, RTC_EXTI_LINE_ALARM_EVENT)
-
-
-/**
- * @brief Disable the ALARM Extended Interrupt Falling Trigger.
- * @retval None.
- */
-#define __HAL_RTC_ALARM_EXTI_DISABLE_FALLING_EDGE() CLEAR_BIT(EXTI->FTSR, RTC_EXTI_LINE_ALARM_EVENT)
-
-
-/**
- * @brief ALARM EXTI line configuration: set rising edge trigger.
- * @retval None.
- */
-#define __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE() SET_BIT(EXTI->RTSR, RTC_EXTI_LINE_ALARM_EVENT)
-
-/**
- * @brief Disable the ALARM Extended Interrupt Rising Trigger.
- * This parameter can be:
- * @retval None.
- */
-#define __HAL_RTC_ALARM_EXTI_DISABLE_RISING_EDGE() CLEAR_BIT(EXTI->RTSR, RTC_EXTI_LINE_ALARM_EVENT)
-
-/**
- * @brief ALARM EXTI line configuration: set rising & falling edge trigger.
- * @retval None.
- */
-#define __HAL_RTC_ALARM_EXTI_ENABLE_RISING_FALLING_EDGE() \
-do{ \
- __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE(); \
- __HAL_RTC_ALARM_EXTI_ENABLE_FALLING_EDGE(); \
- } while(0U)
-
-/**
- * @brief Disable the ALARM Extended Interrupt Rising & Falling Trigger.
- * This parameter can be:
- * @retval None.
- */
-#define __HAL_RTC_ALARM_EXTI_DISABLE_RISING_FALLING_EDGE() \
-do{ \
- __HAL_RTC_ALARM_EXTI_DISABLE_RISING_EDGE(); \
- __HAL_RTC_ALARM_EXTI_DISABLE_FALLING_EDGE(); \
- } while(0U)
-
-/**
- * @brief Check whether the specified ALARM EXTI interrupt flag is set or not.
- * @retval EXTI ALARM Line Status.
- */
-#define __HAL_RTC_ALARM_EXTI_GET_FLAG() (EXTI->PR & (RTC_EXTI_LINE_ALARM_EVENT))
-
-/**
- * @brief Clear the ALARM EXTI flag.
- * @retval None.
- */
-#define __HAL_RTC_ALARM_EXTI_CLEAR_FLAG() (EXTI->PR = (RTC_EXTI_LINE_ALARM_EVENT))
-
-/**
- * @brief Generate a Software interrupt on selected EXTI line.
- * @retval None.
- */
-#define __HAL_RTC_ALARM_EXTI_GENERATE_SWIT() SET_BIT(EXTI->SWIER, RTC_EXTI_LINE_ALARM_EVENT)
-/**
- * @}
- */
-
-/* Include RTC HAL Extension module */
-#include "stm32f1xx_hal_rtc_ex.h"
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup RTC_Exported_Functions
- * @{
- */
-
-
-/* Initialization and de-initialization functions ****************************/
-/** @addtogroup RTC_Exported_Functions_Group1
- * @{
- */
-HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc);
-HAL_StatusTypeDef HAL_RTC_DeInit(RTC_HandleTypeDef *hrtc);
-void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc);
-void HAL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc);
-/**
- * @}
- */
-
-/* RTC Time and Date functions ************************************************/
-/** @addtogroup RTC_Exported_Functions_Group2
- * @{
- */
-HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format);
-HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format);
-HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format);
-HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format);
-/**
- * @}
- */
-
-/* RTC Alarm functions ********************************************************/
-/** @addtogroup RTC_Exported_Functions_Group3
- * @{
- */
-HAL_StatusTypeDef HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format);
-HAL_StatusTypeDef HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format);
-HAL_StatusTypeDef HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef *hrtc, uint32_t Alarm);
-HAL_StatusTypeDef HAL_RTC_GetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Alarm, uint32_t Format);
-void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef *hrtc);
-HAL_StatusTypeDef HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout);
-void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc);
-/**
- * @}
- */
-
-/* Peripheral State functions *************************************************/
-/** @addtogroup RTC_Exported_Functions_Group4
- * @{
- */
-HAL_RTCStateTypeDef HAL_RTC_GetState(RTC_HandleTypeDef *hrtc);
-/**
- * @}
- */
-
-/* Peripheral Control functions ***********************************************/
-/** @addtogroup RTC_Exported_Functions_Group5
- * @{
- */
-HAL_StatusTypeDef HAL_RTC_WaitForSynchro(RTC_HandleTypeDef* hrtc);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_RTC_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc_ex.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc_ex.h
deleted file mode 100644
index e02f47e..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc_ex.h
+++ /dev/null
@@ -1,428 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_rtc_ex.h
- * @author MCD Application Team
- * @brief Header file of RTC HAL Extension module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_RTC_EX_H
-#define __STM32F1xx_HAL_RTC_EX_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup RTCEx
- * @{
- */
-
-/** @addtogroup RTCEx_Private_Macros
- * @{
- */
-
-/** @defgroup RTCEx_Alias_For_Legacy Alias define maintained for legacy
- * @{
- */
-#define HAL_RTCEx_TamperTimeStampIRQHandler HAL_RTCEx_TamperIRQHandler
-
-/**
- * @}
- */
-
-/** @defgroup RTCEx_IS_RTC_Definitions Private macros to check input parameters
- * @{
- */
-#define IS_RTC_TAMPER(__TAMPER__) ((__TAMPER__) == RTC_TAMPER_1)
-
-#define IS_RTC_TAMPER_TRIGGER(__TRIGGER__) (((__TRIGGER__) == RTC_TAMPERTRIGGER_LOWLEVEL) || \
- ((__TRIGGER__) == RTC_TAMPERTRIGGER_HIGHLEVEL))
-
-#if RTC_BKP_NUMBER > 10U
-#define IS_RTC_BKP(BKP) (((BKP) <= (uint32_t)RTC_BKP_DR10) || (((BKP) >= (uint32_t)RTC_BKP_DR11) && ((BKP) <= (uint32_t)RTC_BKP_DR42)))
-#else
-#define IS_RTC_BKP(BKP) ((BKP) <= (uint32_t)RTC_BKP_NUMBER)
-#endif
-#define IS_RTC_SMOOTH_CALIB_MINUS(__VALUE__) ((__VALUE__) <= 0x0000007FU)
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup RTCEx_Exported_Types RTCEx Exported Types
- * @{
- */
-/**
- * @brief RTC Tamper structure definition
- */
-typedef struct
-{
- uint32_t Tamper; /*!< Specifies the Tamper Pin.
- This parameter can be a value of @ref RTCEx_Tamper_Pins_Definitions */
-
- uint32_t Trigger; /*!< Specifies the Tamper Trigger.
- This parameter can be a value of @ref RTCEx_Tamper_Trigger_Definitions */
-
-}RTC_TamperTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup RTCEx_Exported_Constants RTCEx Exported Constants
- * @{
- */
-
-/** @defgroup RTCEx_Tamper_Pins_Definitions Tamper Pins Definitions
- * @{
- */
-#define RTC_TAMPER_1 BKP_CR_TPE /*!< Select tamper to be enabled (mainly for legacy purposes) */
-
-/**
- * @}
- */
-
-/** @defgroup RTCEx_Tamper_Trigger_Definitions Tamper Trigger Definitions
- * @{
- */
-#define RTC_TAMPERTRIGGER_LOWLEVEL BKP_CR_TPAL /*!< A high level on the TAMPER pin resets all data backup registers (if TPE bit is set) */
-#define RTC_TAMPERTRIGGER_HIGHLEVEL 0x00000000U /*!< A low level on the TAMPER pin resets all data backup registers (if TPE bit is set) */
-
-/**
- * @}
- */
-
-/** @defgroup RTCEx_Backup_Registers_Definitions Backup Registers Definitions
- * @{
- */
-#if RTC_BKP_NUMBER > 0U
-#define RTC_BKP_DR1 0x00000001U
-#define RTC_BKP_DR2 0x00000002U
-#define RTC_BKP_DR3 0x00000003U
-#define RTC_BKP_DR4 0x00000004U
-#define RTC_BKP_DR5 0x00000005U
-#define RTC_BKP_DR6 0x00000006U
-#define RTC_BKP_DR7 0x00000007U
-#define RTC_BKP_DR8 0x00000008U
-#define RTC_BKP_DR9 0x00000009U
-#define RTC_BKP_DR10 0x0000000AU
-#endif /* RTC_BKP_NUMBER > 0 */
-
-#if RTC_BKP_NUMBER > 10U
-#define RTC_BKP_DR11 0x00000010U
-#define RTC_BKP_DR12 0x00000011U
-#define RTC_BKP_DR13 0x00000012U
-#define RTC_BKP_DR14 0x00000013U
-#define RTC_BKP_DR15 0x00000014U
-#define RTC_BKP_DR16 0x00000015U
-#define RTC_BKP_DR17 0x00000016U
-#define RTC_BKP_DR18 0x00000017U
-#define RTC_BKP_DR19 0x00000018U
-#define RTC_BKP_DR20 0x00000019U
-#define RTC_BKP_DR21 0x0000001AU
-#define RTC_BKP_DR22 0x0000001BU
-#define RTC_BKP_DR23 0x0000001CU
-#define RTC_BKP_DR24 0x0000001DU
-#define RTC_BKP_DR25 0x0000001EU
-#define RTC_BKP_DR26 0x0000001FU
-#define RTC_BKP_DR27 0x00000020U
-#define RTC_BKP_DR28 0x00000021U
-#define RTC_BKP_DR29 0x00000022U
-#define RTC_BKP_DR30 0x00000023U
-#define RTC_BKP_DR31 0x00000024U
-#define RTC_BKP_DR32 0x00000025U
-#define RTC_BKP_DR33 0x00000026U
-#define RTC_BKP_DR34 0x00000027U
-#define RTC_BKP_DR35 0x00000028U
-#define RTC_BKP_DR36 0x00000029U
-#define RTC_BKP_DR37 0x0000002AU
-#define RTC_BKP_DR38 0x0000002BU
-#define RTC_BKP_DR39 0x0000002CU
-#define RTC_BKP_DR40 0x0000002DU
-#define RTC_BKP_DR41 0x0000002EU
-#define RTC_BKP_DR42 0x0000002FU
-#endif /* RTC_BKP_NUMBER > 10 */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup RTCEx_Exported_Macros RTCEx Exported Macros
- * @{
- */
-
-/**
- * @brief Enable the RTC Tamper interrupt.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __INTERRUPT__: specifies the RTC Tamper interrupt sources to be enabled
- * This parameter can be any combination of the following values:
- * @arg RTC_IT_TAMP1: Tamper A interrupt
- * @retval None
- */
-#define __HAL_RTC_TAMPER_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT(BKP->CSR, (__INTERRUPT__))
-
-/**
- * @brief Disable the RTC Tamper interrupt.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __INTERRUPT__: specifies the RTC Tamper interrupt sources to be disabled.
- * This parameter can be any combination of the following values:
- * @arg RTC_IT_TAMP1: Tamper A interrupt
- * @retval None
- */
-#define __HAL_RTC_TAMPER_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT(BKP->CSR, (__INTERRUPT__))
-
-/**
- * @brief Check whether the specified RTC Tamper interrupt has been enabled or not.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __INTERRUPT__: specifies the RTC Tamper interrupt sources to be checked.
- * This parameter can be:
- * @arg RTC_IT_TAMP1
- * @retval None
- */
-#define __HAL_RTC_TAMPER_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((BKP->CSR) & ((__INTERRUPT__))) != RESET)? SET : RESET)
-
-/**
- * @brief Get the selected RTC Tamper's flag status.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __FLAG__: specifies the RTC Tamper Flag sources to be enabled or disabled.
- * This parameter can be:
- * @arg RTC_FLAG_TAMP1F
- * @retval None
- */
-#define __HAL_RTC_TAMPER_GET_FLAG(__HANDLE__, __FLAG__) ((((BKP->CSR) & (__FLAG__)) != RESET)? SET : RESET)
-
-/**
- * @brief Get the selected RTC Tamper's flag status.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __INTERRUPT__: specifies the RTC Tamper interrupt sources to be checked.
- * This parameter can be:
- * @arg RTC_IT_TAMP1
- * @retval None
- */
-#define __HAL_RTC_TAMPER_GET_IT(__HANDLE__, __INTERRUPT__) ((((BKP->CSR) & (BKP_CSR_TEF)) != RESET)? SET : RESET)
-
-/**
- * @brief Clear the RTC Tamper's pending flags.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __FLAG__: specifies the RTC Tamper Flag sources to be enabled or disabled.
- * This parameter can be:
- * @arg RTC_FLAG_TAMP1F
- * @retval None
- */
-#define __HAL_RTC_TAMPER_CLEAR_FLAG(__HANDLE__, __FLAG__) SET_BIT(BKP->CSR, BKP_CSR_CTE | BKP_CSR_CTI)
-
-/**
- * @brief Enable the RTC Second interrupt.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __INTERRUPT__: specifies the RTC Second interrupt sources to be enabled
- * This parameter can be any combination of the following values:
- * @arg RTC_IT_SEC: Second A interrupt
- * @retval None
- */
-#define __HAL_RTC_SECOND_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->CRH, (__INTERRUPT__))
-
-/**
- * @brief Disable the RTC Second interrupt.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __INTERRUPT__: specifies the RTC Second interrupt sources to be disabled.
- * This parameter can be any combination of the following values:
- * @arg RTC_IT_SEC: Second A interrupt
- * @retval None
- */
-#define __HAL_RTC_SECOND_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT((__HANDLE__)->Instance->CRH, (__INTERRUPT__))
-
-/**
- * @brief Check whether the specified RTC Second interrupt has occurred or not.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __INTERRUPT__: specifies the RTC Second interrupt sources to be enabled or disabled.
- * This parameter can be:
- * @arg RTC_IT_SEC: Second A interrupt
- * @retval None
- */
-#define __HAL_RTC_SECOND_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((((__HANDLE__)->Instance->CRH)& ((__INTERRUPT__)))) != RESET)? SET : RESET)
-
-/**
- * @brief Get the selected RTC Second's flag status.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __FLAG__: specifies the RTC Second Flag sources to be enabled or disabled.
- * This parameter can be:
- * @arg RTC_FLAG_SEC
- * @retval None
- */
-#define __HAL_RTC_SECOND_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->CRL) & (__FLAG__)) != RESET)? SET : RESET)
-
-/**
- * @brief Clear the RTC Second's pending flags.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __FLAG__: specifies the RTC Second Flag sources to be enabled or disabled.
- * This parameter can be:
- * @arg RTC_FLAG_SEC
- * @retval None
- */
-#define __HAL_RTC_SECOND_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->CRL) = ~(__FLAG__)
-
-/**
- * @brief Enable the RTC Overflow interrupt.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __INTERRUPT__: specifies the RTC Overflow interrupt sources to be enabled
- * This parameter can be any combination of the following values:
- * @arg RTC_IT_OW: Overflow A interrupt
- * @retval None
- */
-#define __HAL_RTC_OVERFLOW_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->CRH, (__INTERRUPT__))
-
-/**
- * @brief Disable the RTC Overflow interrupt.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __INTERRUPT__: specifies the RTC Overflow interrupt sources to be disabled.
- * This parameter can be any combination of the following values:
- * @arg RTC_IT_OW: Overflow A interrupt
- * @retval None
- */
-#define __HAL_RTC_OVERFLOW_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT((__HANDLE__)->Instance->CRH, (__INTERRUPT__))
-
-/**
- * @brief Check whether the specified RTC Overflow interrupt has occurred or not.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __INTERRUPT__: specifies the RTC Overflow interrupt sources to be enabled or disabled.
- * This parameter can be:
- * @arg RTC_IT_OW: Overflow A interrupt
- * @retval None
- */
-#define __HAL_RTC_OVERFLOW_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((((__HANDLE__)->Instance->CRH)& ((__INTERRUPT__))) ) != RESET)? SET : RESET)
-
-/**
- * @brief Get the selected RTC Overflow's flag status.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __FLAG__: specifies the RTC Overflow Flag sources to be enabled or disabled.
- * This parameter can be:
- * @arg RTC_FLAG_OW
- * @retval None
- */
-#define __HAL_RTC_OVERFLOW_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->CRL) & (__FLAG__)) != RESET)? SET : RESET)
-
-/**
- * @brief Clear the RTC Overflow's pending flags.
- * @param __HANDLE__: specifies the RTC handle.
- * @param __FLAG__: specifies the RTC Overflow Flag sources to be enabled or disabled.
- * This parameter can be:
- * @arg RTC_FLAG_OW
- * @retval None
- */
-#define __HAL_RTC_OVERFLOW_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->CRL) = ~(__FLAG__)
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup RTCEx_Exported_Functions
- * @{
- */
-
-/* RTC Tamper functions *****************************************/
-/** @addtogroup RTCEx_Exported_Functions_Group1
- * @{
- */
-HAL_StatusTypeDef HAL_RTCEx_SetTamper(RTC_HandleTypeDef *hrtc, RTC_TamperTypeDef* sTamper);
-HAL_StatusTypeDef HAL_RTCEx_SetTamper_IT(RTC_HandleTypeDef *hrtc, RTC_TamperTypeDef* sTamper);
-HAL_StatusTypeDef HAL_RTCEx_DeactivateTamper(RTC_HandleTypeDef *hrtc, uint32_t Tamper);
-void HAL_RTCEx_TamperIRQHandler(RTC_HandleTypeDef *hrtc);
-void HAL_RTCEx_Tamper1EventCallback(RTC_HandleTypeDef *hrtc);
-HAL_StatusTypeDef HAL_RTCEx_PollForTamper1Event(RTC_HandleTypeDef *hrtc, uint32_t Timeout);
-
-/**
- * @}
- */
-
-/* RTC Second functions *****************************************/
-/** @addtogroup RTCEx_Exported_Functions_Group2
- * @{
- */
-HAL_StatusTypeDef HAL_RTCEx_SetSecond_IT(RTC_HandleTypeDef *hrtc);
-HAL_StatusTypeDef HAL_RTCEx_DeactivateSecond(RTC_HandleTypeDef *hrtc);
-void HAL_RTCEx_RTCIRQHandler(RTC_HandleTypeDef* hrtc);
-void HAL_RTCEx_RTCEventCallback(RTC_HandleTypeDef *hrtc);
-void HAL_RTCEx_RTCEventErrorCallback(RTC_HandleTypeDef *hrtc);
-
-/**
- * @}
- */
-
-/* Extension Control functions ************************************************/
-/** @addtogroup RTCEx_Exported_Functions_Group3
- * @{
- */
-void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data);
-uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister);
-
-HAL_StatusTypeDef HAL_RTCEx_SetSmoothCalib(RTC_HandleTypeDef* hrtc, uint32_t SmoothCalibPeriod, uint32_t SmoothCalibPlusPulses, uint32_t SmouthCalibMinusPulsesValue);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_RTC_EX_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sd.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sd.h
deleted file mode 100644
index 770ec0c..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sd.h
+++ /dev/null
@@ -1,715 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_sd.h
- * @author MCD Application Team
- * @brief Header file of SD HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_SD_H
-#define __STM32F1xx_HAL_SD_H
-
-#if defined(STM32F103xE) || defined(STM32F103xG)
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_sdmmc.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup SD SD
- * @brief SD HAL module driver
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup SD_Exported_Types SD Exported Types
- * @{
- */
-
-/** @defgroup SD_Exported_Types_Group1 SD State enumeration structure
- * @{
- */
-typedef enum
-{
- HAL_SD_STATE_RESET = 0x00000000U, /*!< SD not yet initialized or disabled */
- HAL_SD_STATE_READY = 0x00000001U, /*!< SD initialized and ready for use */
- HAL_SD_STATE_TIMEOUT = 0x00000002U, /*!< SD Timeout state */
- HAL_SD_STATE_BUSY = 0x00000003U, /*!< SD process ongoing */
- HAL_SD_STATE_PROGRAMMING = 0x00000004U, /*!< SD Programming State */
- HAL_SD_STATE_RECEIVING = 0x00000005U, /*!< SD Receinving State */
- HAL_SD_STATE_TRANSFER = 0x00000006U, /*!< SD Transfert State */
- HAL_SD_STATE_ERROR = 0x0000000FU /*!< SD is in error state */
-}HAL_SD_StateTypeDef;
-/**
- * @}
- */
-
-/** @defgroup SD_Exported_Types_Group2 SD Card State enumeration structure
- * @{
- */
-typedef enum
-{
- HAL_SD_CARD_READY = 0x00000001U, /*!< Card state is ready */
- HAL_SD_CARD_IDENTIFICATION = 0x00000002U, /*!< Card is in identification state */
- HAL_SD_CARD_STANDBY = 0x00000003U, /*!< Card is in standby state */
- HAL_SD_CARD_TRANSFER = 0x00000004U, /*!< Card is in transfer state */
- HAL_SD_CARD_SENDING = 0x00000005U, /*!< Card is sending an operation */
- HAL_SD_CARD_RECEIVING = 0x00000006U, /*!< Card is receiving operation information */
- HAL_SD_CARD_PROGRAMMING = 0x00000007U, /*!< Card is in programming state */
- HAL_SD_CARD_DISCONNECTED = 0x00000008U, /*!< Card is disconnected */
- HAL_SD_CARD_ERROR = 0x000000FFU /*!< Card response Error */
-}HAL_SD_CardStateTypeDef;
-/**
- * @}
- */
-
-/** @defgroup SD_Exported_Types_Group3 SD Handle Structure definition
- * @{
- */
-#define SD_InitTypeDef SDIO_InitTypeDef
-#define SD_TypeDef SDIO_TypeDef
-
-/**
- * @brief SD Card Information Structure definition
- */
-typedef struct
-{
- uint32_t CardType; /*!< Specifies the card Type */
-
- uint32_t CardVersion; /*!< Specifies the card version */
-
- uint32_t Class; /*!< Specifies the class of the card class */
-
- uint32_t RelCardAdd; /*!< Specifies the Relative Card Address */
-
- uint32_t BlockNbr; /*!< Specifies the Card Capacity in blocks */
-
- uint32_t BlockSize; /*!< Specifies one block size in bytes */
-
- uint32_t LogBlockNbr; /*!< Specifies the Card logical Capacity in blocks */
-
- uint32_t LogBlockSize; /*!< Specifies logical block size in bytes */
-
-}HAL_SD_CardInfoTypeDef;
-
-/**
- * @brief SD handle Structure definition
- */
-typedef struct
-{
- SD_TypeDef *Instance; /*!< SD registers base address */
-
- SD_InitTypeDef Init; /*!< SD required parameters */
-
- HAL_LockTypeDef Lock; /*!< SD locking object */
-
- uint32_t *pTxBuffPtr; /*!< Pointer to SD Tx transfer Buffer */
-
- uint32_t TxXferSize; /*!< SD Tx Transfer size */
-
- uint32_t *pRxBuffPtr; /*!< Pointer to SD Rx transfer Buffer */
-
- uint32_t RxXferSize; /*!< SD Rx Transfer size */
-
- __IO uint32_t Context; /*!< SD transfer context */
-
- __IO HAL_SD_StateTypeDef State; /*!< SD card State */
-
- __IO uint32_t ErrorCode; /*!< SD Card Error codes */
-
- DMA_HandleTypeDef *hdmarx; /*!< SD Rx DMA handle parameters */
-
- DMA_HandleTypeDef *hdmatx; /*!< SD Tx DMA handle parameters */
-
- HAL_SD_CardInfoTypeDef SdCard; /*!< SD Card information */
-
- uint32_t CSD[4]; /*!< SD card specific data table */
-
- uint32_t CID[4]; /*!< SD card identification number table */
-
-}SD_HandleTypeDef;
-
-/**
- * @}
- */
-
-/** @defgroup SD_Exported_Types_Group4 Card Specific Data: CSD Register
- * @{
- */
-typedef struct
-{
- __IO uint8_t CSDStruct; /*!< CSD structure */
- __IO uint8_t SysSpecVersion; /*!< System specification version */
- __IO uint8_t Reserved1; /*!< Reserved */
- __IO uint8_t TAAC; /*!< Data read access time 1 */
- __IO uint8_t NSAC; /*!< Data read access time 2 in CLK cycles */
- __IO uint8_t MaxBusClkFrec; /*!< Max. bus clock frequency */
- __IO uint16_t CardComdClasses; /*!< Card command classes */
- __IO uint8_t RdBlockLen; /*!< Max. read data block length */
- __IO uint8_t PartBlockRead; /*!< Partial blocks for read allowed */
- __IO uint8_t WrBlockMisalign; /*!< Write block misalignment */
- __IO uint8_t RdBlockMisalign; /*!< Read block misalignment */
- __IO uint8_t DSRImpl; /*!< DSR implemented */
- __IO uint8_t Reserved2; /*!< Reserved */
- __IO uint32_t DeviceSize; /*!< Device Size */
- __IO uint8_t MaxRdCurrentVDDMin; /*!< Max. read current @ VDD min */
- __IO uint8_t MaxRdCurrentVDDMax; /*!< Max. read current @ VDD max */
- __IO uint8_t MaxWrCurrentVDDMin; /*!< Max. write current @ VDD min */
- __IO uint8_t MaxWrCurrentVDDMax; /*!< Max. write current @ VDD max */
- __IO uint8_t DeviceSizeMul; /*!< Device size multiplier */
- __IO uint8_t EraseGrSize; /*!< Erase group size */
- __IO uint8_t EraseGrMul; /*!< Erase group size multiplier */
- __IO uint8_t WrProtectGrSize; /*!< Write protect group size */
- __IO uint8_t WrProtectGrEnable; /*!< Write protect group enable */
- __IO uint8_t ManDeflECC; /*!< Manufacturer default ECC */
- __IO uint8_t WrSpeedFact; /*!< Write speed factor */
- __IO uint8_t MaxWrBlockLen; /*!< Max. write data block length */
- __IO uint8_t WriteBlockPaPartial; /*!< Partial blocks for write allowed */
- __IO uint8_t Reserved3; /*!< Reserved */
- __IO uint8_t ContentProtectAppli; /*!< Content protection application */
- __IO uint8_t FileFormatGrouop; /*!< File format group */
- __IO uint8_t CopyFlag; /*!< Copy flag (OTP) */
- __IO uint8_t PermWrProtect; /*!< Permanent write protection */
- __IO uint8_t TempWrProtect; /*!< Temporary write protection */
- __IO uint8_t FileFormat; /*!< File format */
- __IO uint8_t ECC; /*!< ECC code */
- __IO uint8_t CSD_CRC; /*!< CSD CRC */
- __IO uint8_t Reserved4; /*!< Always 1 */
-
-}HAL_SD_CardCSDTypeDef;
-/**
- * @}
- */
-
-/** @defgroup SD_Exported_Types_Group5 Card Identification Data: CID Register
- * @{
- */
-typedef struct
-{
- __IO uint8_t ManufacturerID; /*!< Manufacturer ID */
- __IO uint16_t OEM_AppliID; /*!< OEM/Application ID */
- __IO uint32_t ProdName1; /*!< Product Name part1 */
- __IO uint8_t ProdName2; /*!< Product Name part2 */
- __IO uint8_t ProdRev; /*!< Product Revision */
- __IO uint32_t ProdSN; /*!< Product Serial Number */
- __IO uint8_t Reserved1; /*!< Reserved1 */
- __IO uint16_t ManufactDate; /*!< Manufacturing Date */
- __IO uint8_t CID_CRC; /*!< CID CRC */
- __IO uint8_t Reserved2; /*!< Always 1 */
-
-}HAL_SD_CardCIDTypeDef;
-/**
- * @}
- */
-
-/** @defgroup SD_Exported_Types_Group6 SD Card Status returned by ACMD13
- * @{
- */
-typedef struct
-{
- __IO uint8_t DataBusWidth; /*!< Shows the currently defined data bus width */
- __IO uint8_t SecuredMode; /*!< Card is in secured mode of operation */
- __IO uint16_t CardType; /*!< Carries information about card type */
- __IO uint32_t ProtectedAreaSize; /*!< Carries information about the capacity of protected area */
- __IO uint8_t SpeedClass; /*!< Carries information about the speed class of the card */
- __IO uint8_t PerformanceMove; /*!< Carries information about the card's performance move */
- __IO uint8_t AllocationUnitSize; /*!< Carries information about the card's allocation unit size */
- __IO uint16_t EraseSize; /*!< Determines the number of AUs to be erased in one operation */
- __IO uint8_t EraseTimeout; /*!< Determines the timeout for any number of AU erase */
- __IO uint8_t EraseOffset; /*!< Carries information about the erase offset */
-
-}HAL_SD_CardStatusTypeDef;
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup SD_Exported_Constants Exported Constants
- * @{
- */
-
-#define BLOCKSIZE 512U /*!< Block size is 512 bytes */
-
-/** @defgroup SD_Exported_Constansts_Group1 SD Error status enumeration Structure definition
- * @{
- */
-#define HAL_SD_ERROR_NONE SDMMC_ERROR_NONE /*!< No error */
-#define HAL_SD_ERROR_CMD_CRC_FAIL SDMMC_ERROR_CMD_CRC_FAIL /*!< Command response received (but CRC check failed) */
-#define HAL_SD_ERROR_DATA_CRC_FAIL SDMMC_ERROR_DATA_CRC_FAIL /*!< Data block sent/received (CRC check failed) */
-#define HAL_SD_ERROR_CMD_RSP_TIMEOUT SDMMC_ERROR_CMD_RSP_TIMEOUT /*!< Command response timeout */
-#define HAL_SD_ERROR_DATA_TIMEOUT SDMMC_ERROR_DATA_TIMEOUT /*!< Data timeout */
-#define HAL_SD_ERROR_TX_UNDERRUN SDMMC_ERROR_TX_UNDERRUN /*!< Transmit FIFO underrun */
-#define HAL_SD_ERROR_RX_OVERRUN SDMMC_ERROR_RX_OVERRUN /*!< Receive FIFO overrun */
-#define HAL_SD_ERROR_ADDR_MISALIGNED SDMMC_ERROR_ADDR_MISALIGNED /*!< Misaligned address */
-#define HAL_SD_ERROR_BLOCK_LEN_ERR SDMMC_ERROR_BLOCK_LEN_ERR /*!< Transferred block length is not allowed for the card or the
- number of transferred bytes does not match the block length */
-#define HAL_SD_ERROR_ERASE_SEQ_ERR SDMMC_ERROR_ERASE_SEQ_ERR /*!< An error in the sequence of erase command occurs */
-#define HAL_SD_ERROR_BAD_ERASE_PARAM SDMMC_ERROR_BAD_ERASE_PARAM /*!< An invalid selection for erase groups */
-#define HAL_SD_ERROR_WRITE_PROT_VIOLATION SDMMC_ERROR_WRITE_PROT_VIOLATION /*!< Attempt to program a write protect block */
-#define HAL_SD_ERROR_LOCK_UNLOCK_FAILED SDMMC_ERROR_LOCK_UNLOCK_FAILED /*!< Sequence or password error has been detected in unlock
- command or if there was an attempt to access a locked card */
-#define HAL_SD_ERROR_COM_CRC_FAILED SDMMC_ERROR_COM_CRC_FAILED /*!< CRC check of the previous command failed */
-#define HAL_SD_ERROR_ILLEGAL_CMD SDMMC_ERROR_ILLEGAL_CMD /*!< Command is not legal for the card state */
-#define HAL_SD_ERROR_CARD_ECC_FAILED SDMMC_ERROR_CARD_ECC_FAILED /*!< Card internal ECC was applied but failed to correct the data */
-#define HAL_SD_ERROR_CC_ERR SDMMC_ERROR_CC_ERR /*!< Internal card controller error */
-#define HAL_SD_ERROR_GENERAL_UNKNOWN_ERR SDMMC_ERROR_GENERAL_UNKNOWN_ERR /*!< General or unknown error */
-#define HAL_SD_ERROR_STREAM_READ_UNDERRUN SDMMC_ERROR_STREAM_READ_UNDERRUN /*!< The card could not sustain data reading in stream rmode */
-#define HAL_SD_ERROR_STREAM_WRITE_OVERRUN SDMMC_ERROR_STREAM_WRITE_OVERRUN /*!< The card could not sustain data programming in stream mode */
-#define HAL_SD_ERROR_CID_CSD_OVERWRITE SDMMC_ERROR_CID_CSD_OVERWRITE /*!< CID/CSD overwrite error */
-#define HAL_SD_ERROR_WP_ERASE_SKIP SDMMC_ERROR_WP_ERASE_SKIP /*!< Only partial address space was erased */
-#define HAL_SD_ERROR_CARD_ECC_DISABLED SDMMC_ERROR_CARD_ECC_DISABLED /*!< Command has been executed without using internal ECC */
-#define HAL_SD_ERROR_ERASE_RESET SDMMC_ERROR_ERASE_RESET /*!< Erase sequence was cleared before executing because an out
- of erase sequence command was received */
-#define HAL_SD_ERROR_AKE_SEQ_ERR SDMMC_ERROR_AKE_SEQ_ERR /*!< Error in sequence of authentication */
-#define HAL_SD_ERROR_INVALID_VOLTRANGE SDMMC_ERROR_INVALID_VOLTRANGE /*!< Error in case of invalid voltage range */
-#define HAL_SD_ERROR_ADDR_OUT_OF_RANGE SDMMC_ERROR_ADDR_OUT_OF_RANGE /*!< Error when addressed block is out of range */
-#define HAL_SD_ERROR_REQUEST_NOT_APPLICABLE SDMMC_ERROR_REQUEST_NOT_APPLICABLE /*!< Error when command request is not applicable */
-#define HAL_SD_ERROR_PARAM SDMMC_ERROR_INVALID_PARAMETER /*!< the used parameter is not valid */
-#define HAL_SD_ERROR_UNSUPPORTED_FEATURE SDMMC_ERROR_UNSUPPORTED_FEATURE /*!< Error when feature is not insupported */
-#define HAL_SD_ERROR_BUSY SDMMC_ERROR_BUSY /*!< Error when transfer process is busy */
-#define HAL_SD_ERROR_DMA SDMMC_ERROR_DMA /*!< Error while DMA transfer */
-#define HAL_SD_ERROR_TIMEOUT SDMMC_ERROR_TIMEOUT /*!< Timeout error */
-
-/**
- * @}
- */
-
-/** @defgroup SD_Exported_Constansts_Group2 SD context enumeration
- * @{
- */
-#define SD_CONTEXT_NONE 0x00000000U /*!< None */
-#define SD_CONTEXT_READ_SINGLE_BLOCK 0x00000001U /*!< Read single block operation */
-#define SD_CONTEXT_READ_MULTIPLE_BLOCK 0x00000002U /*!< Read multiple blocks operation */
-#define SD_CONTEXT_WRITE_SINGLE_BLOCK 0x00000010U /*!< Write single block operation */
-#define SD_CONTEXT_WRITE_MULTIPLE_BLOCK 0x00000020U /*!< Write multiple blocks operation */
-#define SD_CONTEXT_IT 0x00000008U /*!< Process in Interrupt mode */
-#define SD_CONTEXT_DMA 0x00000080U /*!< Process in DMA mode */
-
-/**
- * @}
- */
-
-/** @defgroup SD_Exported_Constansts_Group3 SD Supported Memory Cards
- * @{
- */
-#define CARD_SDSC 0x00000000U
-#define CARD_SDHC_SDXC 0x00000001U
-#define CARD_SECURED 0x00000003U
-
-/**
- * @}
- */
-
-/** @defgroup SD_Exported_Constansts_Group4 SD Supported Version
- * @{
- */
-#define CARD_V1_X 0x00000000U
-#define CARD_V2_X 0x00000001U
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup SD_Exported_macros SD Exported Macros
- * @brief macros to handle interrupts and specific clock configurations
- * @{
- */
-
-/**
- * @brief Enable the SD device.
- * @retval None
- */
-#define __HAL_SD_ENABLE(__HANDLE__) __SDIO_ENABLE((__HANDLE__)->Instance)
-
-/**
- * @brief Disable the SD device.
- * @retval None
- */
-#define __HAL_SD_DISABLE(__HANDLE__) __SDIO_DISABLE((__HANDLE__)->Instance)
-
-/**
- * @brief Enable the SDMMC DMA transfer.
- * @retval None
- */
-#define __HAL_SD_DMA_ENABLE(__HANDLE__) __SDIO_DMA_ENABLE((__HANDLE__)->Instance)
-
-/**
- * @brief Disable the SDMMC DMA transfer.
- * @retval None
- */
-#define __HAL_SD_DMA_DISABLE(__HANDLE__) __SDIO_DMA_DISABLE((__HANDLE__)->Instance)
-
-/**
- * @brief Enable the SD device interrupt.
- * @param __HANDLE__: SD Handle
- * @param __INTERRUPT__: specifies the SDMMC interrupt sources to be enabled.
- * This parameter can be one or a combination of the following values:
- * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
- * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
- * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
- * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
- * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
- * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
- * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
- * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
- * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
- * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
- * @arg SDIO_IT_RXACT: Data receive in progress interrupt
- * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
- * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
- * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
- * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
- * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
- * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
- * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
- * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
- * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
- * @retval None
- */
-#define __HAL_SD_ENABLE_IT(__HANDLE__, __INTERRUPT__) __SDIO_ENABLE_IT((__HANDLE__)->Instance, (__INTERRUPT__))
-
-/**
- * @brief Disable the SD device interrupt.
- * @param __HANDLE__: SD Handle
- * @param __INTERRUPT__: specifies the SDMMC interrupt sources to be disabled.
- * This parameter can be one or a combination of the following values:
- * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
- * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
- * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
- * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
- * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
- * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
- * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
- * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
- * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
- * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
- * @arg SDIO_IT_RXACT: Data receive in progress interrupt
- * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
- * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
- * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
- * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
- * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
- * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
- * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
- * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
- * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
- * @retval None
- */
-#define __HAL_SD_DISABLE_IT(__HANDLE__, __INTERRUPT__) __SDIO_DISABLE_IT((__HANDLE__)->Instance, (__INTERRUPT__))
-
-/**
- * @brief Check whether the specified SD flag is set or not.
- * @param __HANDLE__: SD Handle
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed)
- * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed)
- * @arg SDIO_FLAG_CTIMEOUT: Command response timeout
- * @arg SDIO_FLAG_DTIMEOUT: Data timeout
- * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error
- * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error
- * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed)
- * @arg SDIO_FLAG_CMDSENT: Command sent (no response required)
- * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero)
- * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed)
- * @arg SDIO_FLAG_CMDACT: Command transfer in progress
- * @arg SDIO_FLAG_TXACT: Data transmit in progress
- * @arg SDIO_FLAG_RXACT: Data receive in progress
- * @arg SDIO_FLAG_TXFIFOHE: Transmit FIFO Half Empty
- * @arg SDIO_FLAG_RXFIFOHF: Receive FIFO Half Full
- * @arg SDIO_FLAG_TXFIFOF: Transmit FIFO full
- * @arg SDIO_FLAG_RXFIFOF: Receive FIFO full
- * @arg SDIO_FLAG_TXFIFOE: Transmit FIFO empty
- * @arg SDIO_FLAG_RXFIFOE: Receive FIFO empty
- * @arg SDIO_FLAG_TXDAVL: Data available in transmit FIFO
- * @arg SDIO_FLAG_RXDAVL: Data available in receive FIFO
- * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received
- * @retval The new state of SD FLAG (SET or RESET).
- */
-#define __HAL_SD_GET_FLAG(__HANDLE__, __FLAG__) __SDIO_GET_FLAG((__HANDLE__)->Instance, (__FLAG__))
-
-/**
- * @brief Clear the SD's pending flags.
- * @param __HANDLE__: SD Handle
- * @param __FLAG__: specifies the flag to clear.
- * This parameter can be one or a combination of the following values:
- * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed)
- * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed)
- * @arg SDIO_FLAG_CTIMEOUT: Command response timeout
- * @arg SDIO_FLAG_DTIMEOUT: Data timeout
- * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error
- * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error
- * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed)
- * @arg SDIO_FLAG_CMDSENT: Command sent (no response required)
- * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero)
- * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed)
- * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received
- * @retval None
- */
-#define __HAL_SD_CLEAR_FLAG(__HANDLE__, __FLAG__) __SDIO_CLEAR_FLAG((__HANDLE__)->Instance, (__FLAG__))
-
-/**
- * @brief Check whether the specified SD interrupt has occurred or not.
- * @param __HANDLE__: SD Handle
- * @param __INTERRUPT__: specifies the SDMMC interrupt source to check.
- * This parameter can be one of the following values:
- * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
- * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
- * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
- * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
- * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
- * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
- * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
- * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
- * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
- * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
- * @arg SDIO_IT_RXACT: Data receive in progress interrupt
- * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
- * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
- * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
- * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
- * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
- * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
- * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
- * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
- * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
- * @retval The new state of SD IT (SET or RESET).
- */
-#define __HAL_SD_GET_IT(__HANDLE__, __INTERRUPT__) __SDIO_GET_IT((__HANDLE__)->Instance, (__INTERRUPT__))
-
-/**
- * @brief Clear the SD's interrupt pending bits.
- * @param __HANDLE__: SD Handle
- * @param __INTERRUPT__: specifies the interrupt pending bit to clear.
- * This parameter can be one or a combination of the following values:
- * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
- * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
- * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
- * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
- * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
- * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
- * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
- * @arg SDIO_IT_DATAEND: Data end (data counter, SDMMC_DCOUNT, is zero) interrupt
- * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
- * @retval None
- */
-#define __HAL_SD_CLEAR_IT(__HANDLE__, __INTERRUPT__) __SDIO_CLEAR_IT((__HANDLE__)->Instance, (__INTERRUPT__))
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup SD_Exported_Functions SD Exported Functions
- * @{
- */
-
-/** @defgroup SD_Exported_Functions_Group1 Initialization and de-initialization functions
- * @{
- */
-HAL_StatusTypeDef HAL_SD_Init(SD_HandleTypeDef *hsd);
-HAL_StatusTypeDef HAL_SD_InitCard(SD_HandleTypeDef *hsd);
-HAL_StatusTypeDef HAL_SD_DeInit (SD_HandleTypeDef *hsd);
-void HAL_SD_MspInit(SD_HandleTypeDef *hsd);
-void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd);
-/**
- * @}
- */
-
-/** @defgroup SD_Exported_Functions_Group2 Input and Output operation functions
- * @{
- */
-/* Blocking mode: Polling */
-HAL_StatusTypeDef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout);
-HAL_StatusTypeDef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout);
-HAL_StatusTypeDef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint32_t BlockStartAdd, uint32_t BlockEndAdd);
-/* Non-Blocking mode: IT */
-HAL_StatusTypeDef HAL_SD_ReadBlocks_IT(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks);
-HAL_StatusTypeDef HAL_SD_WriteBlocks_IT(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks);
-/* Non-Blocking mode: DMA */
-HAL_StatusTypeDef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks);
-HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks);
-
-void HAL_SD_IRQHandler(SD_HandleTypeDef *hsd);
-
-/* Callback in non blocking modes (DMA) */
-void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd);
-void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd);
-void HAL_SD_ErrorCallback(SD_HandleTypeDef *hsd);
-void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd);
-/**
- * @}
- */
-
-/** @defgroup SD_Exported_Functions_Group3 Peripheral Control functions
- * @{
- */
-HAL_StatusTypeDef HAL_SD_ConfigWideBusOperation(SD_HandleTypeDef *hsd, uint32_t WideMode);
-/**
- * @}
- */
-
-/** @defgroup SD_Exported_Functions_Group4 SD card related functions
- * @{
- */
-HAL_StatusTypeDef HAL_SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus);
-HAL_SD_CardStateTypeDef HAL_SD_GetCardState(SD_HandleTypeDef *hsd);
-HAL_StatusTypeDef HAL_SD_GetCardCID(SD_HandleTypeDef *hsd, HAL_SD_CardCIDTypeDef *pCID);
-HAL_StatusTypeDef HAL_SD_GetCardCSD(SD_HandleTypeDef *hsd, HAL_SD_CardCSDTypeDef *pCSD);
-HAL_StatusTypeDef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypeDef *pStatus);
-HAL_StatusTypeDef HAL_SD_GetCardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypeDef *pCardInfo);
-/**
- * @}
- */
-
-/** @defgroup SD_Exported_Functions_Group5 Peripheral State and Errors functions
- * @{
- */
-HAL_SD_StateTypeDef HAL_SD_GetState(SD_HandleTypeDef *hsd);
-uint32_t HAL_SD_GetError(SD_HandleTypeDef *hsd);
-/**
- * @}
- */
-
-/** @defgroup SD_Exported_Functions_Group6 Perioheral Abort management
- * @{
- */
-HAL_StatusTypeDef HAL_SD_Abort(SD_HandleTypeDef *hsd);
-HAL_StatusTypeDef HAL_SD_Abort_IT(SD_HandleTypeDef *hsd);
-/**
- * @}
- */
-
-/* Private types -------------------------------------------------------------*/
-/** @defgroup SD_Private_Types SD Private Types
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private defines -----------------------------------------------------------*/
-/** @defgroup SD_Private_Defines SD Private Defines
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private variables ---------------------------------------------------------*/
-/** @defgroup SD_Private_Variables SD Private Variables
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup SD_Private_Constants SD Private Constants
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup SD_Private_Macros SD Private Macros
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private functions prototypes ----------------------------------------------*/
-/** @defgroup SD_Private_Functions_Prototypes SD Private Functions Prototypes
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private functions ---------------------------------------------------------*/
-/** @defgroup SD_Private_Functions SD Private Functions
- * @{
- */
-
-/**
- * @}
- */
-
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32F103xE || STM32F103xG */
-
-#endif /* __STM32F1xx_HAL_SD_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_smartcard.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_smartcard.h
deleted file mode 100644
index 44e3133..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_smartcard.h
+++ /dev/null
@@ -1,683 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_smartcard.h
- * @author MCD Application Team
- * @brief Header file of SMARTCARD HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_SMARTCARD_H
-#define __STM32F1xx_HAL_SMARTCARD_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup SMARTCARD
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup SMARTCARD_Exported_Types SMARTCARD Exported Types
- * @{
- */
-
-/**
- * @brief SMARTCARD Init Structure definition
- */
-typedef struct
-{
- uint32_t BaudRate; /*!< This member configures the SmartCard communication baud rate.
- The baud rate is computed using the following formula:
- - IntegerDivider = ((PCLKx) / (16 * (hsmartcard->Init.BaudRate)))
- - FractionalDivider = ((IntegerDivider - ((uint32_t) IntegerDivider)) * 16) + 0.5 */
-
- uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame.
- This parameter can be a value of @ref SMARTCARD_Word_Length */
-
- uint32_t StopBits; /*!< Specifies the number of stop bits transmitted.
- This parameter can be a value of @ref SMARTCARD_Stop_Bits */
-
- uint32_t Parity; /*!< Specifies the parity mode.
- This parameter can be a value of @ref SMARTCARD_Parity
- @note When parity is enabled, the computed parity is inserted
- at the MSB position of the transmitted data (9th bit when
- the word length is set to 9 data bits; 8th bit when the
- word length is set to 8 data bits).*/
-
- uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.
- This parameter can be a value of @ref SMARTCARD_Mode */
-
- uint32_t CLKPolarity; /*!< Specifies the steady state of the serial clock.
- This parameter can be a value of @ref SMARTCARD_Clock_Polarity */
-
- uint32_t CLKPhase; /*!< Specifies the clock transition on which the bit capture is made.
- This parameter can be a value of @ref SMARTCARD_Clock_Phase */
-
- uint32_t CLKLastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted
- data bit (MSB) has to be output on the SCLK pin in synchronous mode.
- This parameter can be a value of @ref SMARTCARD_Last_Bit */
-
- uint32_t Prescaler; /*!< Specifies the SmartCard Prescaler value used for dividing the system clock
- to provide the smartcard clock. The value given in the register (5 significant bits)
- is multiplied by 2 to give the division factor of the source clock frequency.
- This parameter can be a value of @ref SMARTCARD_Prescaler */
-
- uint32_t GuardTime; /*!< Specifies the SmartCard Guard Time value in terms of number of baud clocks */
-
- uint32_t NACKState; /*!< Specifies the SmartCard NACK Transmission state
- This parameter can be a value of @ref SMARTCARD_NACK_State */
-} SMARTCARD_InitTypeDef;
-
-/**
- * @brief HAL SMARTCARD State structures definition
- * @note HAL SMARTCARD State value is a combination of 2 different substates: gState and RxState.
- * - gState contains SMARTCARD state information related to global Handle management
- * and also information related to Tx operations.
- * gState value coding follow below described bitmap :
- * b7-b6 Error information
- * 00 : No Error
- * 01 : (Not Used)
- * 10 : Timeout
- * 11 : Error
- * b5 IP initilisation status
- * 0 : Reset (IP not initialized)
- * 1 : Init done (IP not initialized. HAL SMARTCARD Init function already called)
- * b4-b3 (not used)
- * xx : Should be set to 00
- * b2 Intrinsic process state
- * 0 : Ready
- * 1 : Busy (IP busy with some configuration or internal operations)
- * b1 (not used)
- * x : Should be set to 0
- * b0 Tx state
- * 0 : Ready (no Tx operation ongoing)
- * 1 : Busy (Tx operation ongoing)
- * - RxState contains information related to Rx operations.
- * RxState value coding follow below described bitmap :
- * b7-b6 (not used)
- * xx : Should be set to 00
- * b5 IP initilisation status
- * 0 : Reset (IP not initialized)
- * 1 : Init done (IP not initialized)
- * b4-b2 (not used)
- * xxx : Should be set to 000
- * b1 Rx state
- * 0 : Ready (no Rx operation ongoing)
- * 1 : Busy (Rx operation ongoing)
- * b0 (not used)
- * x : Should be set to 0.
- */
-typedef enum
-{
- HAL_SMARTCARD_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized
- Value is allowed for gState and RxState */
- HAL_SMARTCARD_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use
- Value is allowed for gState and RxState */
- HAL_SMARTCARD_STATE_BUSY = 0x24U, /*!< an internal process is ongoing
- Value is allowed for gState only */
- HAL_SMARTCARD_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing
- Value is allowed for gState only */
- HAL_SMARTCARD_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing
- Value is allowed for RxState only */
- HAL_SMARTCARD_STATE_BUSY_TX_RX = 0x23U, /*!< Data Transmission and Reception process is ongoing
- Not to be used for neither gState nor RxState.
- Value is result of combination (Or) between gState and RxState values */
- HAL_SMARTCARD_STATE_TIMEOUT = 0xA0U, /*!< Timeout state
- Value is allowed for gState only */
- HAL_SMARTCARD_STATE_ERROR = 0xE0U /*!< Error
- Value is allowed for gState only */
-} HAL_SMARTCARD_StateTypeDef;
-
-/**
- * @brief SMARTCARD handle Structure definition
- */
-typedef struct
-{
- USART_TypeDef *Instance; /*!< USART registers base address */
-
- SMARTCARD_InitTypeDef Init; /*!< SmartCard communication parameters */
-
- uint8_t *pTxBuffPtr; /*!< Pointer to SmartCard Tx transfer Buffer */
-
- uint16_t TxXferSize; /*!< SmartCard Tx Transfer size */
-
- __IO uint16_t TxXferCount; /*!< SmartCard Tx Transfer Counter */
-
- uint8_t *pRxBuffPtr; /*!< Pointer to SmartCard Rx transfer Buffer */
-
- uint16_t RxXferSize; /*!< SmartCard Rx Transfer size */
-
- __IO uint16_t RxXferCount; /*!< SmartCard Rx Transfer Counter */
-
- DMA_HandleTypeDef *hdmatx; /*!< SmartCard Tx DMA Handle parameters */
-
- DMA_HandleTypeDef *hdmarx; /*!< SmartCard Rx DMA Handle parameters */
-
- HAL_LockTypeDef Lock; /*!< Locking object */
-
- __IO HAL_SMARTCARD_StateTypeDef gState; /*!< SmartCard state information related to global Handle management
- and also related to Tx operations.
- This parameter can be a value of @ref HAL_SMARTCARD_StateTypeDef */
-
- __IO HAL_SMARTCARD_StateTypeDef RxState; /*!< SmartCard state information related to Rx operations.
- This parameter can be a value of @ref HAL_SMARTCARD_StateTypeDef */
-
- __IO uint32_t ErrorCode; /*!< SmartCard Error code */
-} SMARTCARD_HandleTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup SMARTCARD_Exported_Constants SMARTCARD Exported constants
- * @{
- */
-
-/** @defgroup SMARTCARD_Error_Code SMARTCARD Error Code
- * @{
- */
-#define HAL_SMARTCARD_ERROR_NONE 0x00000000U /*!< No error */
-#define HAL_SMARTCARD_ERROR_PE 0x00000001U /*!< Parity error */
-#define HAL_SMARTCARD_ERROR_NE 0x00000002U /*!< Noise error */
-#define HAL_SMARTCARD_ERROR_FE 0x00000004U /*!< Frame error */
-#define HAL_SMARTCARD_ERROR_ORE 0x00000008U /*!< OverRun error */
-#define HAL_SMARTCARD_ERROR_DMA 0x00000010U /*!< DMA transfer error */
-/**
- * @}
- */
-
-/** @defgroup SMARTCARD_Word_Length SMARTCARD Word Length
- * @{
- */
-#define SMARTCARD_WORDLENGTH_9B ((uint32_t)USART_CR1_M)
-/**
- * @}
- */
-
-/** @defgroup SMARTCARD_Stop_Bits SMARTCARD Number of Stop Bits
- * @{
- */
-#define SMARTCARD_STOPBITS_0_5 ((uint32_t)USART_CR2_STOP_0)
-#define SMARTCARD_STOPBITS_1_5 ((uint32_t)(USART_CR2_STOP_0 | USART_CR2_STOP_1))
-/**
- * @}
- */
-
-/** @defgroup SMARTCARD_Parity SMARTCARD Parity
- * @{
- */
-#define SMARTCARD_PARITY_EVEN ((uint32_t)USART_CR1_PCE)
-#define SMARTCARD_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS))
-/**
- * @}
- */
-
-/** @defgroup SMARTCARD_Mode SMARTCARD Mode
- * @{
- */
-#define SMARTCARD_MODE_RX ((uint32_t)USART_CR1_RE)
-#define SMARTCARD_MODE_TX ((uint32_t)USART_CR1_TE)
-#define SMARTCARD_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE))
-/**
- * @}
- */
-
-/** @defgroup SMARTCARD_Clock_Polarity SMARTCARD Clock Polarity
- * @{
- */
-#define SMARTCARD_POLARITY_LOW 0x00000000U
-#define SMARTCARD_POLARITY_HIGH ((uint32_t)USART_CR2_CPOL)
-/**
- * @}
- */
-
-/** @defgroup SMARTCARD_Clock_Phase SMARTCARD Clock Phase
- * @{
- */
-#define SMARTCARD_PHASE_1EDGE 0x00000000U
-#define SMARTCARD_PHASE_2EDGE ((uint32_t)USART_CR2_CPHA)
-/**
- * @}
- */
-
-/** @defgroup SMARTCARD_Last_Bit SMARTCARD Last Bit
- * @{
- */
-#define SMARTCARD_LASTBIT_DISABLE 0x00000000U
-#define SMARTCARD_LASTBIT_ENABLE ((uint32_t)USART_CR2_LBCL)
-/**
- * @}
- */
-
-/** @defgroup SMARTCARD_NACK_State SMARTCARD NACK State
- * @{
- */
-#define SMARTCARD_NACK_ENABLE ((uint32_t)USART_CR3_NACK)
-#define SMARTCARD_NACK_DISABLE 0x00000000U
-/**
- * @}
- */
-
-/** @defgroup SMARTCARD_DMA_Requests SMARTCARD DMA requests
- * @{
- */
-#define SMARTCARD_DMAREQ_TX ((uint32_t)USART_CR3_DMAT)
-#define SMARTCARD_DMAREQ_RX ((uint32_t)USART_CR3_DMAR)
-/**
- * @}
- */
-
-/** @defgroup SMARTCARD_Prescaler SMARTCARD Prescaler
- * @{
- */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV2 0x00000001U /*!< SYSCLK divided by 2 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV4 0x00000002U /*!< SYSCLK divided by 4 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV6 0x00000003U /*!< SYSCLK divided by 6 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV8 0x00000004U /*!< SYSCLK divided by 8 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV10 0x00000005U /*!< SYSCLK divided by 10 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV12 0x00000006U /*!< SYSCLK divided by 12 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV14 0x00000007U /*!< SYSCLK divided by 14 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV16 0x00000008U /*!< SYSCLK divided by 16 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV18 0x00000009U /*!< SYSCLK divided by 18 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV20 0x0000000AU /*!< SYSCLK divided by 20 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV22 0x0000000BU /*!< SYSCLK divided by 22 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV24 0x0000000CU /*!< SYSCLK divided by 24 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV26 0x0000000DU /*!< SYSCLK divided by 26 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV28 0x0000000EU /*!< SYSCLK divided by 28 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV30 0x0000000FU /*!< SYSCLK divided by 30 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV32 0x00000010U /*!< SYSCLK divided by 32 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV34 0x00000011U /*!< SYSCLK divided by 34 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV36 0x00000012U /*!< SYSCLK divided by 36 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV38 0x00000013U /*!< SYSCLK divided by 38 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV40 0x00000014U /*!< SYSCLK divided by 40 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV42 0x00000015U /*!< SYSCLK divided by 42 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV44 0x00000016U /*!< SYSCLK divided by 44 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV46 0x00000017U /*!< SYSCLK divided by 46 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV48 0x00000018U /*!< SYSCLK divided by 48 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV50 0x00000019U /*!< SYSCLK divided by 50 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV52 0x0000001AU /*!< SYSCLK divided by 52 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV54 0x0000001BU /*!< SYSCLK divided by 54 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV56 0x0000001CU /*!< SYSCLK divided by 56 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV58 0x0000001DU /*!< SYSCLK divided by 58 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV60 0x0000001EU /*!< SYSCLK divided by 60 */
-#define SMARTCARD_PRESCALER_SYSCLK_DIV62 0x0000001FU /*!< SYSCLK divided by 62 */
-/**
- * @}
- */
-
-/** @defgroup SmartCard_Flags SMARTCARD Flags
- * Elements values convention: 0xXXXX
- * - 0xXXXX : Flag mask in the SR register
- * @{
- */
-#define SMARTCARD_FLAG_TXE ((uint32_t)USART_SR_TXE)
-#define SMARTCARD_FLAG_TC ((uint32_t)USART_SR_TC)
-#define SMARTCARD_FLAG_RXNE ((uint32_t)USART_SR_RXNE)
-#define SMARTCARD_FLAG_IDLE ((uint32_t)USART_SR_IDLE)
-#define SMARTCARD_FLAG_ORE ((uint32_t)USART_SR_ORE)
-#define SMARTCARD_FLAG_NE ((uint32_t)USART_SR_NE)
-#define SMARTCARD_FLAG_FE ((uint32_t)USART_SR_FE)
-#define SMARTCARD_FLAG_PE ((uint32_t)USART_SR_PE)
-/**
- * @}
- */
-
-/** @defgroup SmartCard_Interrupt_definition SMARTCARD Interrupts Definition
- * Elements values convention: 0xY000XXXX
- * - XXXX : Interrupt mask in the XX register
- * - Y : Interrupt source register (2bits)
- * - 01: CR1 register
- * - 11: CR3 register
- * @{
- */
-#define SMARTCARD_IT_PE ((uint32_t)(SMARTCARD_CR1_REG_INDEX << 28U | USART_CR1_PEIE))
-#define SMARTCARD_IT_TXE ((uint32_t)(SMARTCARD_CR1_REG_INDEX << 28U | USART_CR1_TXEIE))
-#define SMARTCARD_IT_TC ((uint32_t)(SMARTCARD_CR1_REG_INDEX << 28U | USART_CR1_TCIE))
-#define SMARTCARD_IT_RXNE ((uint32_t)(SMARTCARD_CR1_REG_INDEX << 28U | USART_CR1_RXNEIE))
-#define SMARTCARD_IT_IDLE ((uint32_t)(SMARTCARD_CR1_REG_INDEX << 28U | USART_CR1_IDLEIE))
-#define SMARTCARD_IT_ERR ((uint32_t)(SMARTCARD_CR3_REG_INDEX << 28U | USART_CR3_EIE))
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup SMARTCARD_Exported_Macros SMARTCARD Exported Macros
- * @{
- */
-
-/** @brief Reset SMARTCARD handle gstate & RxState
- * @param __HANDLE__: specifies the SMARTCARD Handle.
- * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
- */
-#define __HAL_SMARTCARD_RESET_HANDLE_STATE(__HANDLE__) do{ \
- (__HANDLE__)->gState = HAL_SMARTCARD_STATE_RESET; \
- (__HANDLE__)->RxState = HAL_SMARTCARD_STATE_RESET; \
- } while(0U)
-
-/** @brief Flush the Smartcard DR register
- * @param __HANDLE__: specifies the SMARTCARD Handle.
- * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
- */
-#define __HAL_SMARTCARD_FLUSH_DRREGISTER(__HANDLE__) ((__HANDLE__)->Instance->DR)
-
-/** @brief Check whether the specified Smartcard flag is set or not.
- * @param __HANDLE__: specifies the SMARTCARD Handle.
- * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg SMARTCARD_FLAG_TXE: Transmit data register empty flag
- * @arg SMARTCARD_FLAG_TC: Transmission Complete flag
- * @arg SMARTCARD_FLAG_RXNE: Receive data register not empty flag
- * @arg SMARTCARD_FLAG_IDLE: Idle Line detection flag
- * @arg SMARTCARD_FLAG_ORE: OverRun Error flag
- * @arg SMARTCARD_FLAG_NE: Noise Error flag
- * @arg SMARTCARD_FLAG_FE: Framing Error flag
- * @arg SMARTCARD_FLAG_PE: Parity Error flag
- * @retval The new state of __FLAG__ (TRUE or FALSE).
- */
-#define __HAL_SMARTCARD_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__))
-
-/** @brief Clear the specified Smartcard pending flags.
- * @param __HANDLE__: specifies the SMARTCARD Handle.
- * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be any combination of the following values:
- * @arg SMARTCARD_FLAG_TC: Transmission Complete flag.
- * @arg SMARTCARD_FLAG_RXNE: Receive data register not empty flag.
- *
- * @note PE (Parity error), FE (Framing error), NE (Noise error) and ORE (OverRun
- * error) flags are cleared by software sequence: a read operation to
- * USART_SR register followed by a read operation to USART_DR register.
- * @note RXNE flag can be also cleared by a read to the USART_DR register.
- * @note TC flag can be also cleared by software sequence: a read operation to
- * USART_SR register followed by a write operation to USART_DR register.
- * @note TXE flag is cleared only by a write to the USART_DR register.
- */
-#define __HAL_SMARTCARD_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__))
-
-/** @brief Clear the SMARTCARD PE pending flag.
- * @param __HANDLE__: specifies the USART Handle.
- * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
- */
-#define __HAL_SMARTCARD_CLEAR_PEFLAG(__HANDLE__) \
- do{ \
- __IO uint32_t tmpreg = 0x00U; \
- tmpreg = (__HANDLE__)->Instance->SR; \
- tmpreg = (__HANDLE__)->Instance->DR; \
- UNUSED(tmpreg); \
- } while(0U)
-
-/** @brief Clear the SMARTCARD FE pending flag.
- * @param __HANDLE__: specifies the USART Handle.
- * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
- */
-#define __HAL_SMARTCARD_CLEAR_FEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_PEFLAG(__HANDLE__)
-
-/** @brief Clear the SMARTCARD NE pending flag.
- * @param __HANDLE__: specifies the USART Handle.
- * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
- */
-#define __HAL_SMARTCARD_CLEAR_NEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_PEFLAG(__HANDLE__)
-
-/** @brief Clear the SMARTCARD ORE pending flag.
- * @param __HANDLE__: specifies the USART Handle.
- * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
- */
-#define __HAL_SMARTCARD_CLEAR_OREFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_PEFLAG(__HANDLE__)
-
-/** @brief Clear the SMARTCARD IDLE pending flag.
- * @param __HANDLE__: specifies the USART Handle.
- * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
- */
-#define __HAL_SMARTCARD_CLEAR_IDLEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_PEFLAG(__HANDLE__)
-
-/** @brief Enable the specified SmartCard interrupt.
- * @param __HANDLE__: specifies the SMARTCARD Handle.
- * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
- * @param __INTERRUPT__: specifies the SMARTCARD interrupt to enable.
- * This parameter can be one of the following values:
- * @arg SMARTCARD_IT_TXE: Transmit Data Register empty interrupt
- * @arg SMARTCARD_IT_TC: Transmission complete interrupt
- * @arg SMARTCARD_IT_RXNE: Receive Data register not empty interrupt
- * @arg SMARTCARD_IT_IDLE: Idle line detection interrupt
- * @arg SMARTCARD_IT_PE: Parity Error interrupt
- * @arg SMARTCARD_IT_ERR: Error interrupt(Frame error, noise error, overRun error)
- */
-#define __HAL_SMARTCARD_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == SMARTCARD_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & SMARTCARD_IT_MASK)): \
- ((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & SMARTCARD_IT_MASK)))
-
-/** @brief Disable the specified SmartCard interrupt.
- * @param __HANDLE__: specifies the SMARTCARD Handle.
- * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
- * @param __INTERRUPT__: specifies the SMARTCARD interrupt to disable.
- * This parameter can be one of the following values:
- * @arg SMARTCARD_IT_TXE: Transmit Data Register empty interrupt
- * @arg SMARTCARD_IT_TC: Transmission complete interrupt
- * @arg SMARTCARD_IT_RXNE: Receive Data register not empty interrupt
- * @arg SMARTCARD_IT_IDLE: Idle line detection interrupt
- * @arg SMARTCARD_IT_PE: Parity Error interrupt
- * @arg SMARTCARD_IT_ERR: Error interrupt(Frame error, noise error, overRun error)
- */
-#define __HAL_SMARTCARD_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == SMARTCARD_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 &= ~((__INTERRUPT__) & SMARTCARD_IT_MASK)): \
- ((__HANDLE__)->Instance->CR3 &= ~ ((__INTERRUPT__) & SMARTCARD_IT_MASK)))
-
-/** @brief Checks whether the specified SmartCard interrupt has occurred or not.
- * @param __HANDLE__: specifies the SmartCard Handle.
- * @param __IT__: specifies the SMARTCARD interrupt source to check.
- * This parameter can be one of the following values:
- * @arg SMARTCARD_IT_TXE: Transmit Data Register empty interrupt
- * @arg SMARTCARD_IT_TC: Transmission complete interrupt
- * @arg SMARTCARD_IT_RXNE: Receive Data register not empty interrupt
- * @arg SMARTCARD_IT_IDLE: Idle line detection interrupt
- * @arg SMARTCARD_IT_ERR: Error interrupt
- * @arg SMARTCARD_IT_PE: Parity Error interrupt
- * @retval The new state of __IT__ (TRUE or FALSE).
- */
-#define __HAL_SMARTCARD_GET_IT_SOURCE(__HANDLE__, __IT__) (((((__IT__) >> 28U) == SMARTCARD_CR1_REG_INDEX)? (__HANDLE__)->Instance->CR1: (__HANDLE__)->Instance->CR3) & (((uint32_t)(__IT__)) & SMARTCARD_IT_MASK))
-
-/** @brief Enable the USART associated to the SMARTCARD Handle
- * @param __HANDLE__: specifies the SMARTCARD Handle.
- * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
- */
-#define __HAL_SMARTCARD_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE)
-
-/** @brief Disable the USART associated to the SMARTCARD Handle
- * @param __HANDLE__: specifies the SMARTCARD Handle.
- * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
- */
-#define __HAL_SMARTCARD_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE)
-
-/** @brief Macros to enable the SmartCard DMA request.
- * @param __HANDLE__: specifies the SmartCard Handle.
- * @param __REQUEST__: specifies the SmartCard DMA request.
- * This parameter can be one of the following values:
- * @arg SMARTCARD_DMAREQ_TX: SmartCard DMA transmit request
- * @arg SMARTCARD_DMAREQ_RX: SmartCard DMA receive request
- */
-#define __HAL_SMARTCARD_DMA_REQUEST_ENABLE(__HANDLE__, __REQUEST__) ((__HANDLE__)->Instance->CR3 |= (__REQUEST__))
-
-/** @brief Macros to disable the SmartCard DMA request.
- * @param __HANDLE__: specifies the SmartCard Handle.
- * @param __REQUEST__: specifies the SmartCard DMA request.
- * This parameter can be one of the following values:
- * @arg SMARTCARD_DMAREQ_TX: SmartCard DMA transmit request
- * @arg SMARTCARD_DMAREQ_RX: SmartCard DMA receive request
- */
-#define __HAL_SMARTCARD_DMA_REQUEST_DISABLE(__HANDLE__, __REQUEST__) ((__HANDLE__)->Instance->CR3 &= ~(__REQUEST__))
-
-/**
- * @}
- */
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup SMARTCARD_Exported_Functions
- * @{
- */
-
-/** @addtogroup SMARTCARD_Exported_Functions_Group1
- * @{
- */
-/* Initialization/de-initialization functions **********************************/
-HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc);
-HAL_StatusTypeDef HAL_SMARTCARD_ReInit(SMARTCARD_HandleTypeDef *hsc);
-HAL_StatusTypeDef HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef *hsc);
-void HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef *hsc);
-void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsc);
-/**
- * @}
- */
-
-/** @addtogroup SMARTCARD_Exported_Functions_Group2
- * @{
- */
-/* IO operation functions *******************************************************/
-HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size);
-/* Transfer Abort functions */
-HAL_StatusTypeDef HAL_SMARTCARD_Abort(SMARTCARD_HandleTypeDef *hsc);
-HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit(SMARTCARD_HandleTypeDef *hsc);
-HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive(SMARTCARD_HandleTypeDef *hsc);
-HAL_StatusTypeDef HAL_SMARTCARD_Abort_IT(SMARTCARD_HandleTypeDef *hsc);
-HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit_IT(SMARTCARD_HandleTypeDef *hsc);
-HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive_IT(SMARTCARD_HandleTypeDef *hsc);
-
-void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc);
-void HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef *hsc);
-void HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef *hsc);
-void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsc);
-void HAL_SMARTCARD_AbortCpltCallback(SMARTCARD_HandleTypeDef *hsc);
-void HAL_SMARTCARD_AbortTransmitCpltCallback(SMARTCARD_HandleTypeDef *hsc);
-void HAL_SMARTCARD_AbortReceiveCpltCallback(SMARTCARD_HandleTypeDef *hsc);
-/**
- * @}
- */
-
-/** @addtogroup SMARTCARD_Exported_Functions_Group3
- * @{
- */
-/* Peripheral State functions **************************************************/
-HAL_SMARTCARD_StateTypeDef HAL_SMARTCARD_GetState(SMARTCARD_HandleTypeDef *hsc);
-uint32_t HAL_SMARTCARD_GetError(SMARTCARD_HandleTypeDef *hsc);
-/**
- * @}
- */
-
-/**
- * @}
- */
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup SMARTCARD_Private_Constants SMARTCARD Private Constants
- * @{
- */
-
-/** @brief SMARTCARD interruptions flag mask
- *
- */
-#define SMARTCARD_IT_MASK 0x0000FFFFU
-
-#define SMARTCARD_CR1_REG_INDEX 1U
-#define SMARTCARD_CR3_REG_INDEX 3U
-/**
- * @}
- */
-
-/* Private macros --------------------------------------------------------*/
-/** @defgroup SMARTCARD_Private_Macros SMARTCARD Private Macros
- * @{
- */
-#define IS_SMARTCARD_WORD_LENGTH(LENGTH) ((LENGTH) == SMARTCARD_WORDLENGTH_9B)
-#define IS_SMARTCARD_STOPBITS(STOPBITS) (((STOPBITS) == SMARTCARD_STOPBITS_0_5) || \
- ((STOPBITS) == SMARTCARD_STOPBITS_1_5))
-#define IS_SMARTCARD_PARITY(PARITY) (((PARITY) == SMARTCARD_PARITY_EVEN) || \
- ((PARITY) == SMARTCARD_PARITY_ODD))
-#define IS_SMARTCARD_MODE(MODE) ((((MODE) & 0x0000FFF3U) == 0x00U) && ((MODE) != 0x000000U))
-#define IS_SMARTCARD_POLARITY(CPOL) (((CPOL) == SMARTCARD_POLARITY_LOW) || ((CPOL) == SMARTCARD_POLARITY_HIGH))
-#define IS_SMARTCARD_PHASE(CPHA) (((CPHA) == SMARTCARD_PHASE_1EDGE) || ((CPHA) == SMARTCARD_PHASE_2EDGE))
-#define IS_SMARTCARD_LASTBIT(LASTBIT) (((LASTBIT) == SMARTCARD_LASTBIT_DISABLE) || \
- ((LASTBIT) == SMARTCARD_LASTBIT_ENABLE))
-#define IS_SMARTCARD_NACK_STATE(NACK) (((NACK) == SMARTCARD_NACK_ENABLE) || \
- ((NACK) == SMARTCARD_NACK_DISABLE))
-#define IS_SMARTCARD_BAUDRATE(BAUDRATE) ((BAUDRATE) < 4500001U)
-
-#define SMARTCARD_DIV(_PCLK_, _BAUD_) (((_PCLK_)*25U)/(4U*(_BAUD_)))
-#define SMARTCARD_DIVMANT(_PCLK_, _BAUD_) (SMARTCARD_DIV((_PCLK_), (_BAUD_))/100U)
-#define SMARTCARD_DIVFRAQ(_PCLK_, _BAUD_) (((SMARTCARD_DIV((_PCLK_), (_BAUD_)) - (SMARTCARD_DIVMANT((_PCLK_), (_BAUD_)) * 100U)) * 16U + 50U) / 100U)
-/* SMARTCARD BRR = mantissa + overflow + fraction
- = (SMARTCARD DIVMANT << 4) + (SMARTCARD DIVFRAQ & 0xF0) + (SMARTCARD DIVFRAQ & 0x0FU) */
-#define SMARTCARD_BRR(_PCLK_, _BAUD_) (((SMARTCARD_DIVMANT((_PCLK_), (_BAUD_)) << 4U) + \
- (SMARTCARD_DIVFRAQ((_PCLK_), (_BAUD_)) & 0xF0U)) + \
- (SMARTCARD_DIVFRAQ((_PCLK_), (_BAUD_)) & 0x0FU))
-/**
- * @}
- */
-
-/* Private functions ---------------------------------------------------------*/
-/** @defgroup SMARTCARD_Private_Functions SMARTCARD Private Functions
- * @{
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_SMARTCARD_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h
deleted file mode 100644
index 668d573..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h
+++ /dev/null
@@ -1,587 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_spi.h
- * @author MCD Application Team
- * @brief Header file of SPI HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_SPI_H
-#define __STM32F1xx_HAL_SPI_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup SPI
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup SPI_Exported_Types SPI Exported Types
- * @{
- */
-
-/**
- * @brief SPI Configuration Structure definition
- */
-typedef struct
-{
- uint32_t Mode; /*!< Specifies the SPI operating mode.
- This parameter can be a value of @ref SPI_Mode */
-
- uint32_t Direction; /*!< Specifies the SPI Directional mode state.
- This parameter can be a value of @ref SPI_Direction */
-
- uint32_t DataSize; /*!< Specifies the SPI data size.
- This parameter can be a value of @ref SPI_Data_Size */
-
- uint32_t CLKPolarity; /*!< Specifies the serial clock steady state.
- This parameter can be a value of @ref SPI_Clock_Polarity */
-
- uint32_t CLKPhase; /*!< Specifies the clock active edge for the bit capture.
- This parameter can be a value of @ref SPI_Clock_Phase */
-
- uint32_t NSS; /*!< Specifies whether the NSS signal is managed by
- hardware (NSS pin) or by software using the SSI bit.
- This parameter can be a value of @ref SPI_Slave_Select_management */
-
- uint32_t BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be
- used to configure the transmit and receive SCK clock.
- This parameter can be a value of @ref SPI_BaudRate_Prescaler
- @note The communication clock is derived from the master
- clock. The slave clock does not need to be set. */
-
- uint32_t FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit.
- This parameter can be a value of @ref SPI_MSB_LSB_transmission */
-
- uint32_t TIMode; /*!< Specifies if the TI mode is enabled or not.
- This parameter can be a value of @ref SPI_TI_mode */
-
- uint32_t CRCCalculation; /*!< Specifies if the CRC calculation is enabled or not.
- This parameter can be a value of @ref SPI_CRC_Calculation */
-
- uint32_t CRCPolynomial; /*!< Specifies the polynomial used for the CRC calculation.
- This parameter must be a number between Min_Data = 0 and Max_Data = 65535 */
-}SPI_InitTypeDef;
-
-/**
- * @brief HAL SPI State structure definition
- */
-typedef enum
-{
- HAL_SPI_STATE_RESET = 0x00U, /*!< Peripheral not Initialized */
- HAL_SPI_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */
- HAL_SPI_STATE_BUSY = 0x02U, /*!< an internal process is ongoing */
- HAL_SPI_STATE_BUSY_TX = 0x03U, /*!< Data Transmission process is ongoing */
- HAL_SPI_STATE_BUSY_RX = 0x04U, /*!< Data Reception process is ongoing */
- HAL_SPI_STATE_BUSY_TX_RX = 0x05U, /*!< Data Transmission and Reception process is ongoing */
- HAL_SPI_STATE_ERROR = 0x06U /*!< SPI error state */
-}HAL_SPI_StateTypeDef;
-
-/**
- * @brief SPI handle Structure definition
- */
-typedef struct __SPI_HandleTypeDef
-{
- SPI_TypeDef *Instance; /*!< SPI registers base address */
-
- SPI_InitTypeDef Init; /*!< SPI communication parameters */
-
- uint8_t *pTxBuffPtr; /*!< Pointer to SPI Tx transfer Buffer */
-
- uint16_t TxXferSize; /*!< SPI Tx Transfer size */
-
- __IO uint16_t TxXferCount; /*!< SPI Tx Transfer Counter */
-
- uint8_t *pRxBuffPtr; /*!< Pointer to SPI Rx transfer Buffer */
-
- uint16_t RxXferSize; /*!< SPI Rx Transfer size */
-
- __IO uint16_t RxXferCount; /*!< SPI Rx Transfer Counter */
-
- void (*RxISR)(struct __SPI_HandleTypeDef * hspi); /*!< function pointer on Rx ISR */
-
- void (*TxISR)(struct __SPI_HandleTypeDef * hspi); /*!< function pointer on Tx ISR */
-
- DMA_HandleTypeDef *hdmatx; /*!< SPI Tx DMA Handle parameters */
-
- DMA_HandleTypeDef *hdmarx; /*!< SPI Rx DMA Handle parameters */
-
- HAL_LockTypeDef Lock; /*!< Locking object */
-
- __IO HAL_SPI_StateTypeDef State; /*!< SPI communication state */
-
- __IO uint32_t ErrorCode; /*!< SPI Error code */
-
-}SPI_HandleTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup SPI_Exported_Constants SPI Exported Constants
- * @{
- */
-
-/** @defgroup SPI_Error_Code SPI Error Code
- * @{
- */
-#define HAL_SPI_ERROR_NONE 0x00000000U /*!< No error */
-#define HAL_SPI_ERROR_MODF 0x00000001U /*!< MODF error */
-#define HAL_SPI_ERROR_CRC 0x00000002U /*!< CRC error */
-#define HAL_SPI_ERROR_OVR 0x00000004U /*!< OVR error */
-#define HAL_SPI_ERROR_FRE 0x00000008U /*!< FRE error */
-#define HAL_SPI_ERROR_DMA 0x00000010U /*!< DMA transfer error */
-#define HAL_SPI_ERROR_FLAG 0x00000020U /*!< Flag: RXNE,TXE, BSY */
-/**
- * @}
- */
-
-/** @defgroup SPI_Mode SPI Mode
- * @{
- */
-#define SPI_MODE_SLAVE 0x00000000U
-#define SPI_MODE_MASTER (SPI_CR1_MSTR | SPI_CR1_SSI)
-/**
- * @}
- */
-
-/** @defgroup SPI_Direction SPI Direction Mode
- * @{
- */
-#define SPI_DIRECTION_2LINES 0x00000000U
-#define SPI_DIRECTION_2LINES_RXONLY SPI_CR1_RXONLY
-#define SPI_DIRECTION_1LINE SPI_CR1_BIDIMODE
-/**
- * @}
- */
-
-/** @defgroup SPI_Data_Size SPI Data Size
- * @{
- */
-#define SPI_DATASIZE_8BIT 0x00000000U
-#define SPI_DATASIZE_16BIT SPI_CR1_DFF
-/**
- * @}
- */
-
-/** @defgroup SPI_Clock_Polarity SPI Clock Polarity
- * @{
- */
-#define SPI_POLARITY_LOW 0x00000000U
-#define SPI_POLARITY_HIGH SPI_CR1_CPOL
-/**
- * @}
- */
-
-/** @defgroup SPI_Clock_Phase SPI Clock Phase
- * @{
- */
-#define SPI_PHASE_1EDGE 0x00000000U
-#define SPI_PHASE_2EDGE SPI_CR1_CPHA
-/**
- * @}
- */
-
-/** @defgroup SPI_Slave_Select_management SPI Slave Select Management
- * @{
- */
-#define SPI_NSS_SOFT SPI_CR1_SSM
-#define SPI_NSS_HARD_INPUT 0x00000000U
-#define SPI_NSS_HARD_OUTPUT ((uint32_t)(SPI_CR2_SSOE << 16))
-/**
- * @}
- */
-
-/** @defgroup SPI_BaudRate_Prescaler SPI BaudRate Prescaler
- * @{
- */
-#define SPI_BAUDRATEPRESCALER_2 0x00000000U
-#define SPI_BAUDRATEPRESCALER_4 SPI_CR1_BR_0
-#define SPI_BAUDRATEPRESCALER_8 SPI_CR1_BR_1
-#define SPI_BAUDRATEPRESCALER_16 (uint32_t)(SPI_CR1_BR_1 | SPI_CR1_BR_0)
-#define SPI_BAUDRATEPRESCALER_32 SPI_CR1_BR_2
-#define SPI_BAUDRATEPRESCALER_64 (uint32_t)(SPI_CR1_BR_2 | SPI_CR1_BR_0)
-#define SPI_BAUDRATEPRESCALER_128 (uint32_t)(SPI_CR1_BR_2 | SPI_CR1_BR_1)
-#define SPI_BAUDRATEPRESCALER_256 (uint32_t)(SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0)
-
-/**
- * @}
- */
-
-/** @defgroup SPI_MSB_LSB_transmission SPI MSB LSB Transmission
- * @{
- */
-#define SPI_FIRSTBIT_MSB 0x00000000U
-#define SPI_FIRSTBIT_LSB SPI_CR1_LSBFIRST
-/**
- * @}
- */
-
-/** @defgroup SPI_TI_mode SPI TI Mode
- * @{
- */
-#define SPI_TIMODE_DISABLE 0x00000000U
-/**
- * @}
- */
-
-/** @defgroup SPI_CRC_Calculation SPI CRC Calculation
- * @{
- */
-#define SPI_CRCCALCULATION_DISABLE 0x00000000U
-#define SPI_CRCCALCULATION_ENABLE SPI_CR1_CRCEN
-/**
- * @}
- */
-
-/** @defgroup SPI_Interrupt_definition SPI Interrupt Definition
- * @{
- */
-#define SPI_IT_TXE SPI_CR2_TXEIE
-#define SPI_IT_RXNE SPI_CR2_RXNEIE
-#define SPI_IT_ERR SPI_CR2_ERRIE
-/**
- * @}
- */
-
-/** @defgroup SPI_Flags_definition SPI Flags Definition
- * @{
- */
-#define SPI_FLAG_RXNE SPI_SR_RXNE /* SPI status flag: Rx buffer not empty flag */
-#define SPI_FLAG_TXE SPI_SR_TXE /* SPI status flag: Tx buffer empty flag */
-#define SPI_FLAG_BSY SPI_SR_BSY /* SPI status flag: Busy flag */
-#define SPI_FLAG_CRCERR SPI_SR_CRCERR /* SPI Error flag: CRC error flag */
-#define SPI_FLAG_MODF SPI_SR_MODF /* SPI Error flag: Mode fault flag */
-#define SPI_FLAG_OVR SPI_SR_OVR /* SPI Error flag: Overrun flag */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup SPI_Exported_Macros SPI Exported Macros
- * @{
- */
-
-/** @brief Reset SPI handle state.
- * @param __HANDLE__: specifies the SPI Handle.
- * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
- * @retval None
- */
-#define __HAL_SPI_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SPI_STATE_RESET)
-
-/** @brief Enable the specified SPI interrupts.
- * @param __HANDLE__: specifies the SPI handle.
- * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
- * @param __INTERRUPT__: specifies the interrupt source to enable.
- * This parameter can be one of the following values:
- * @arg SPI_IT_TXE: Tx buffer empty interrupt enable
- * @arg SPI_IT_RXNE: RX buffer not empty interrupt enable
- * @arg SPI_IT_ERR: Error interrupt enable
- * @retval None
- */
-#define __HAL_SPI_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 |= (__INTERRUPT__))
-
-/** @brief Disable the specified SPI interrupts.
- * @param __HANDLE__: specifies the SPI handle.
- * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
- * @param __INTERRUPT__: specifies the interrupt source to disable.
- * This parameter can be one of the following values:
- * @arg SPI_IT_TXE: Tx buffer empty interrupt enable
- * @arg SPI_IT_RXNE: RX buffer not empty interrupt enable
- * @arg SPI_IT_ERR: Error interrupt enable
- * @retval None
- */
-#define __HAL_SPI_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 &= (~(__INTERRUPT__)))
-
-/** @brief Check whether the specified SPI interrupt source is enabled or not.
- * @param __HANDLE__: specifies the SPI Handle.
- * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
- * @param __INTERRUPT__: specifies the SPI interrupt source to check.
- * This parameter can be one of the following values:
- * @arg SPI_IT_TXE: Tx buffer empty interrupt enable
- * @arg SPI_IT_RXNE: RX buffer not empty interrupt enable
- * @arg SPI_IT_ERR: Error interrupt enable
- * @retval The new state of __IT__ (TRUE or FALSE).
- */
-#define __HAL_SPI_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
-
-/** @brief Check whether the specified SPI flag is set or not.
- * @param __HANDLE__: specifies the SPI Handle.
- * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg SPI_FLAG_RXNE: Receive buffer not empty flag
- * @arg SPI_FLAG_TXE: Transmit buffer empty flag
- * @arg SPI_FLAG_CRCERR: CRC error flag
- * @arg SPI_FLAG_MODF: Mode fault flag
- * @arg SPI_FLAG_OVR: Overrun flag
- * @arg SPI_FLAG_BSY: Busy flag
- * @retval The new state of __FLAG__ (TRUE or FALSE).
- */
-#define __HAL_SPI_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__))
-
-/** @brief Clear the SPI CRCERR pending flag.
- * @param __HANDLE__: specifies the SPI Handle.
- * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
- * @retval None
- */
-#define __HAL_SPI_CLEAR_CRCERRFLAG(__HANDLE__) ((__HANDLE__)->Instance->SR = (uint16_t)(~SPI_FLAG_CRCERR))
-
-/** @brief Clear the SPI MODF pending flag.
- * @param __HANDLE__: specifies the SPI Handle.
- * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
- * @retval None
- */
-#define __HAL_SPI_CLEAR_MODFFLAG(__HANDLE__) \
-do{ \
- __IO uint32_t tmpreg_modf = 0x00U; \
- tmpreg_modf = (__HANDLE__)->Instance->SR; \
- (__HANDLE__)->Instance->CR1 &= (~SPI_CR1_SPE); \
- UNUSED(tmpreg_modf); \
- } while(0U)
-
-/** @brief Clear the SPI OVR pending flag.
- * @param __HANDLE__: specifies the SPI Handle.
- * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
- * @retval None
- */
-#define __HAL_SPI_CLEAR_OVRFLAG(__HANDLE__) \
-do{ \
- __IO uint32_t tmpreg_ovr = 0x00U; \
- tmpreg_ovr = (__HANDLE__)->Instance->DR; \
- tmpreg_ovr = (__HANDLE__)->Instance->SR; \
- UNUSED(tmpreg_ovr); \
- } while(0U)
-
-
-/** @brief Enable the SPI peripheral.
- * @param __HANDLE__: specifies the SPI Handle.
- * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
- * @retval None
- */
-#define __HAL_SPI_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= SPI_CR1_SPE)
-
-/** @brief Disable the SPI peripheral.
- * @param __HANDLE__: specifies the SPI Handle.
- * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
- * @retval None
- */
-#define __HAL_SPI_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= (~SPI_CR1_SPE))
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup SPI_Exported_Functions
- * @{
- */
-
-/** @addtogroup SPI_Exported_Functions_Group1
- * @{
- */
-/* Initialization/de-initialization functions **********************************/
-HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi);
-HAL_StatusTypeDef HAL_SPI_DeInit (SPI_HandleTypeDef *hspi);
-void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi);
-void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi);
-/**
- * @}
- */
-
-/** @addtogroup SPI_Exported_Functions_Group2
- * @{
- */
-/* I/O operation functions *****************************************************/
-HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size);
-HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size);
-HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi);
-HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi);
-HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi);
-/* Transfer Abort functions */
-HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi);
-HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi);
-
-void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi);
-void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi);
-void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi);
-void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi);
-void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi);
-void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi);
-void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi);
-void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi);
-void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi);
-/**
- * @}
- */
-
-/** @addtogroup SPI_Exported_Functions_Group3
- * @{
- */
-/* Peripheral State and Error functions ***************************************/
-HAL_SPI_StateTypeDef HAL_SPI_GetState(SPI_HandleTypeDef *hspi);
-uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup SPI_Private_Constants SPI Private Constants
- * @{
- */
-#define SPI_INVALID_CRC_ERROR 0U /* CRC error wrongly detected */
-#define SPI_VALID_CRC_ERROR 1U /* CRC error is true */
-/**
- * @}
- */
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup SPI_Private_Macros SPI Private Macros
- * @{
- */
-
-/** @brief Set the SPI transmit-only mode.
- * @param __HANDLE__: specifies the SPI Handle.
- * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
- * @retval None
- */
-#define SPI_1LINE_TX(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= SPI_CR1_BIDIOE)
-
-/** @brief Set the SPI receive-only mode.
- * @param __HANDLE__: specifies the SPI Handle.
- * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
- * @retval None
- */
-#define SPI_1LINE_RX(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= (~SPI_CR1_BIDIOE))
-
-/** @brief Reset the CRC calculation of the SPI.
- * @param __HANDLE__: specifies the SPI Handle.
- * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
- * @retval None
- */
-#define SPI_RESET_CRC(__HANDLE__) do{(__HANDLE__)->Instance->CR1 &= (uint16_t)(~SPI_CR1_CRCEN);\
- (__HANDLE__)->Instance->CR1 |= SPI_CR1_CRCEN;}while(0U)
-
-#define IS_SPI_MODE(MODE) (((MODE) == SPI_MODE_SLAVE) || \
- ((MODE) == SPI_MODE_MASTER))
-
-#define IS_SPI_DIRECTION(MODE) (((MODE) == SPI_DIRECTION_2LINES) || \
- ((MODE) == SPI_DIRECTION_2LINES_RXONLY) || \
- ((MODE) == SPI_DIRECTION_1LINE))
-
-#define IS_SPI_DIRECTION_2LINES(MODE) ((MODE) == SPI_DIRECTION_2LINES)
-
-#define IS_SPI_DIRECTION_2LINES_OR_1LINE(MODE) (((MODE) == SPI_DIRECTION_2LINES) || \
- ((MODE) == SPI_DIRECTION_1LINE))
-
-#define IS_SPI_DATASIZE(DATASIZE) (((DATASIZE) == SPI_DATASIZE_16BIT) || \
- ((DATASIZE) == SPI_DATASIZE_8BIT))
-
-#define IS_SPI_CPOL(CPOL) (((CPOL) == SPI_POLARITY_LOW) || \
- ((CPOL) == SPI_POLARITY_HIGH))
-
-#define IS_SPI_CPHA(CPHA) (((CPHA) == SPI_PHASE_1EDGE) || \
- ((CPHA) == SPI_PHASE_2EDGE))
-
-#define IS_SPI_NSS(NSS) (((NSS) == SPI_NSS_SOFT) || \
- ((NSS) == SPI_NSS_HARD_INPUT) || \
- ((NSS) == SPI_NSS_HARD_OUTPUT))
-
-#define IS_SPI_BAUDRATE_PRESCALER(PRESCALER) (((PRESCALER) == SPI_BAUDRATEPRESCALER_2) || \
- ((PRESCALER) == SPI_BAUDRATEPRESCALER_4) || \
- ((PRESCALER) == SPI_BAUDRATEPRESCALER_8) || \
- ((PRESCALER) == SPI_BAUDRATEPRESCALER_16) || \
- ((PRESCALER) == SPI_BAUDRATEPRESCALER_32) || \
- ((PRESCALER) == SPI_BAUDRATEPRESCALER_64) || \
- ((PRESCALER) == SPI_BAUDRATEPRESCALER_128) || \
- ((PRESCALER) == SPI_BAUDRATEPRESCALER_256))
-
-#define IS_SPI_FIRST_BIT(BIT) (((BIT) == SPI_FIRSTBIT_MSB) || \
- ((BIT) == SPI_FIRSTBIT_LSB))
-
-#define IS_SPI_CRC_CALCULATION(CALCULATION) (((CALCULATION) == SPI_CRCCALCULATION_DISABLE) || \
- ((CALCULATION) == SPI_CRCCALCULATION_ENABLE))
-
-#define IS_SPI_CRC_POLYNOMIAL(POLYNOMIAL) (((POLYNOMIAL) >= 0x01U) && ((POLYNOMIAL) <= 0xFFFFU))
-
-/**
- * @}
- */
-
-/* Private functions ---------------------------------------------------------*/
-/** @defgroup SPI_Private_Functions SPI Private Functions
- * @{
- */
-uint8_t SPI_ISCRCErrorValid(SPI_HandleTypeDef *hspi);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_SPI_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sram.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sram.h
deleted file mode 100644
index 6c8d489..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sram.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_sram.h
- * @author MCD Application Team
- * @brief Header file of SRAM HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_SRAM_H
-#define __STM32F1xx_HAL_SRAM_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_fsmc.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG) || defined(STM32F100xE)
-
-/** @addtogroup SRAM
- * @{
- */
-
-/* Exported typedef ----------------------------------------------------------*/
-
-/** @defgroup SRAM_Exported_Types SRAM Exported Types
- * @{
- */
-/**
- * @brief HAL SRAM State structures definition
- */
-typedef enum
-{
- HAL_SRAM_STATE_RESET = 0x00U, /*!< SRAM not yet initialized or disabled */
- HAL_SRAM_STATE_READY = 0x01U, /*!< SRAM initialized and ready for use */
- HAL_SRAM_STATE_BUSY = 0x02U, /*!< SRAM internal process is ongoing */
- HAL_SRAM_STATE_ERROR = 0x03U, /*!< SRAM error state */
- HAL_SRAM_STATE_PROTECTED = 0x04U /*!< SRAM peripheral NORSRAM device write protected */
-
-}HAL_SRAM_StateTypeDef;
-
-/**
- * @brief SRAM handle Structure definition
- */
-typedef struct
-{
- FSMC_NORSRAM_TypeDef *Instance; /*!< Register base address */
-
- FSMC_NORSRAM_EXTENDED_TypeDef *Extended; /*!< Extended mode register base address */
-
- FSMC_NORSRAM_InitTypeDef Init; /*!< SRAM device control configuration parameters */
-
- HAL_LockTypeDef Lock; /*!< SRAM locking object */
-
- __IO HAL_SRAM_StateTypeDef State; /*!< SRAM device access state */
-
- DMA_HandleTypeDef *hdma; /*!< Pointer DMA handler */
-
-}SRAM_HandleTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/* Exported macro ------------------------------------------------------------*/
-
-/** @defgroup SRAM_Exported_Macros SRAM Exported Macros
- * @{
- */
-
-/** @brief Reset SRAM handle state
- * @param __HANDLE__: SRAM handle
- * @retval None
- */
-#define __HAL_SRAM_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SRAM_STATE_RESET)
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-
-/** @addtogroup SRAM_Exported_Functions
- * @{
- */
-
-/** @addtogroup SRAM_Exported_Functions_Group1
- * @{
- */
-
-/* Initialization/de-initialization functions **********************************/
-HAL_StatusTypeDef HAL_SRAM_Init(SRAM_HandleTypeDef *hsram, FSMC_NORSRAM_TimingTypeDef *Timing, FSMC_NORSRAM_TimingTypeDef *ExtTiming);
-HAL_StatusTypeDef HAL_SRAM_DeInit(SRAM_HandleTypeDef *hsram);
-void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram);
-void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef *hsram);
-
-void HAL_SRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma);
-void HAL_SRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma);
-
-/**
- * @}
- */
-
-/** @addtogroup SRAM_Exported_Functions_Group2
- * @{
- */
-
-/* I/O operation functions *****************************************************/
-HAL_StatusTypeDef HAL_SRAM_Read_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pDstBuffer, uint32_t BufferSize);
-HAL_StatusTypeDef HAL_SRAM_Write_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pSrcBuffer, uint32_t BufferSize);
-HAL_StatusTypeDef HAL_SRAM_Read_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pDstBuffer, uint32_t BufferSize);
-HAL_StatusTypeDef HAL_SRAM_Write_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pSrcBuffer, uint32_t BufferSize);
-HAL_StatusTypeDef HAL_SRAM_Read_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize);
-HAL_StatusTypeDef HAL_SRAM_Write_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize);
-HAL_StatusTypeDef HAL_SRAM_Read_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize);
-HAL_StatusTypeDef HAL_SRAM_Write_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize);
-
-/**
- * @}
- */
-
-/** @addtogroup SRAM_Exported_Functions_Group3
- * @{
- */
-
-/* SRAM Control functions ******************************************************/
-HAL_StatusTypeDef HAL_SRAM_WriteOperation_Enable(SRAM_HandleTypeDef *hsram);
-HAL_StatusTypeDef HAL_SRAM_WriteOperation_Disable(SRAM_HandleTypeDef *hsram);
-
-/**
- * @}
- */
-
-/** @addtogroup SRAM_Exported_Functions_Group4
- * @{
- */
-
-/* SRAM State functions *********************************************************/
-HAL_SRAM_StateTypeDef HAL_SRAM_GetState(SRAM_HandleTypeDef *hsram);
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG || STM32F100xE */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_SRAM_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h
deleted file mode 100644
index 3ad03bf..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h
+++ /dev/null
@@ -1,343 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_tim_ex.h
- * @author MCD Application Team
- * @brief Header file of TIM HAL Extension module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_TIM_EX_H
-#define __STM32F1xx_HAL_TIM_EX_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup TIMEx
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup TIMEx_Exported_Types TIMEx Exported Types
- * @{
- */
-
-
-/**
- * @brief TIM Hall sensor Configuration Structure definition
- */
-
-typedef struct
-{
-
- uint32_t IC1Polarity; /*!< Specifies the active edge of the input signal.
- This parameter can be a value of @ref TIM_Input_Capture_Polarity */
-
- uint32_t IC1Prescaler; /*!< Specifies the Input Capture Prescaler.
- This parameter can be a value of @ref TIM_Input_Capture_Prescaler */
-
- uint32_t IC1Filter; /*!< Specifies the input capture filter.
- This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
- uint32_t Commutation_Delay; /*!< Specifies the pulse value to be loaded into the Capture Compare Register.
- This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */
-} TIM_HallSensor_InitTypeDef;
-
-
-#if defined (STM32F100xB) || defined (STM32F100xE) || \
- defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
- defined (STM32F105xC) || defined (STM32F107xC)
-
-/**
- * @brief TIM Break and Dead time configuration Structure definition
- */
-typedef struct
-{
- uint32_t OffStateRunMode; /*!< TIM off state in run mode
- This parameter can be a value of @ref TIM_OSSR_Off_State_Selection_for_Run_mode_state */
- uint32_t OffStateIDLEMode; /*!< TIM off state in IDLE mode
- This parameter can be a value of @ref TIM_OSSI_Off_State_Selection_for_Idle_mode_state */
- uint32_t LockLevel; /*!< TIM Lock level
- This parameter can be a value of @ref TIM_Lock_level */
- uint32_t DeadTime; /*!< TIM dead Time
- This parameter can be a number between Min_Data = 0x00 and Max_Data = 0xFF */
- uint32_t BreakState; /*!< TIM Break State
- This parameter can be a value of @ref TIM_Break_Input_enable_disable */
- uint32_t BreakPolarity; /*!< TIM Break input polarity
- This parameter can be a value of @ref TIM_Break_Polarity */
- uint32_t AutomaticOutput; /*!< TIM Automatic Output Enable state
- This parameter can be a value of @ref TIM_AOE_Bit_Set_Reset */
-} TIM_BreakDeadTimeConfigTypeDef;
-
-#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
- /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
- /* defined(STM32F105xC) || defined(STM32F107xC) */
-
-/**
- * @brief TIM Master configuration Structure definition
- */
-typedef struct {
- uint32_t MasterOutputTrigger; /*!< Trigger output (TRGO) selection
- This parameter can be a value of @ref TIM_Master_Mode_Selection */
- uint32_t MasterSlaveMode; /*!< Master/slave mode selection
- This parameter can be a value of @ref TIM_Master_Slave_Mode */
-}TIM_MasterConfigTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-#if defined (STM32F100xB) || defined (STM32F100xE) || \
- defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
- defined (STM32F105xC) || defined (STM32F107xC)
-/** @defgroup TIMEx_Exported_Constants TIMEx Exported Constants
- * @{
- */
-
-/** @defgroup TIMEx_Clock_Filter TIMEx Clock Filter
- * @{
- */
-#define IS_TIM_DEADTIME(DEADTIME) ((DEADTIME) <= 0xFFU) /*!< BreakDead Time */
-/**
- * @}
- */
-
-/**
- * @}
- */
-#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
- /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
- /* defined(STM32F105xC) || defined(STM32F107xC) */
-
-/* Exported macro ------------------------------------------------------------*/
-/**
- * @brief Sets the TIM Output compare preload.
- * @param __HANDLE__: TIM handle.
- * @param __CHANNEL__: TIM Channels to be configured.
- * This parameter can be one of the following values:
- * @arg TIM_CHANNEL_1: TIM Channel 1 selected
- * @arg TIM_CHANNEL_2: TIM Channel 2 selected
- * @arg TIM_CHANNEL_3: TIM Channel 3 selected
- * @arg TIM_CHANNEL_4: TIM Channel 4 selected
- * @retval None
- */
-#define __HAL_TIM_ENABLE_OCxPRELOAD(__HANDLE__, __CHANNEL__) \
- (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC1PE) :\
- ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC2PE) :\
- ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC3PE) :\
- ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC4PE))
-
-/**
- * @brief Resets the TIM Output compare preload.
- * @param __HANDLE__: TIM handle.
- * @param __CHANNEL__: TIM Channels to be configured.
- * This parameter can be one of the following values:
- * @arg TIM_CHANNEL_1: TIM Channel 1 selected
- * @arg TIM_CHANNEL_2: TIM Channel 2 selected
- * @arg TIM_CHANNEL_3: TIM Channel 3 selected
- * @arg TIM_CHANNEL_4: TIM Channel 4 selected
- * @retval None
- */
-#define __HAL_TIM_DISABLE_OCxPRELOAD(__HANDLE__, __CHANNEL__) \
- (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 &= (uint16_t)~TIM_CCMR1_OC1PE) :\
- ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 &= (uint16_t)~TIM_CCMR1_OC2PE) :\
- ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 &= (uint16_t)~TIM_CCMR2_OC3PE) :\
- ((__HANDLE__)->Instance->CCMR2 &= (uint16_t)~TIM_CCMR2_OC4PE))
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup TIMEx_Exported_Functions
- * @{
- */
-
-/** @addtogroup TIMEx_Exported_Functions_Group1
- * @{
- */
-/* Timer Hall Sensor functions **********************************************/
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, TIM_HallSensor_InitTypeDef* sConfig);
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim);
-
-void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim);
-void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim);
-
- /* Blocking mode: Polling */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim);
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim);
-/* Non-Blocking mode: Interrupt */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim);
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim);
-/* Non-Blocking mode: DMA */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length);
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim);
-/**
- * @}
- */
-
-#if defined (STM32F100xB) || defined (STM32F100xE) || \
- defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
- defined (STM32F105xC) || defined (STM32F107xC)
-
-/** @addtogroup TIMEx_Exported_Functions_Group2
- * @{
- */
-/* Timer Complementary Output Compare functions *****************************/
-/* Blocking mode: Polling */
-HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
-HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
-
-/* Non-Blocking mode: Interrupt */
-HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
-HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
-
-/* Non-Blocking mode: DMA */
-HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length);
-HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel);
-/**
- * @}
- */
-
-/** @addtogroup TIMEx_Exported_Functions_Group3
- * @{
- */
-/* Timer Complementary PWM functions ****************************************/
-/* Blocking mode: Polling */
-HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
-HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
-
-/* Non-Blocking mode: Interrupt */
-HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
-HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
-/* Non-Blocking mode: DMA */
-HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length);
-HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel);
-/**
- * @}
- */
-
-/** @addtogroup TIMEx_Exported_Functions_Group4
- * @{
- */
-/* Timer Complementary One Pulse functions **********************************/
-/* Blocking mode: Polling */
-HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
-HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
-
-/* Non-Blocking mode: Interrupt */
-HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
-HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
-/**
- * @}
- */
-#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
- /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
- /* defined(STM32F105xC) || defined(STM32F107xC) */
-
-/** @addtogroup TIMEx_Exported_Functions_Group5
- * @{
- */
-/* Extended Control functions ************************************************/
-#if defined (STM32F100xB) || defined (STM32F100xE) || \
- defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
- defined (STM32F105xC) || defined (STM32F107xC)
-HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource);
-HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent_IT(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource);
-HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent_DMA(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource);
-HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim, TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig);
-#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
- /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
- /* defined(STM32F105xC) || defined(STM32F107xC) */
-HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim, TIM_MasterConfigTypeDef * sMasterConfig);
-/**
- * @}
- */
-
-/** @addtogroup TIMEx_Exported_Functions_Group6
- * @{
- */
-/* Extension Callback *********************************************************/
-void HAL_TIMEx_CommutationCallback(TIM_HandleTypeDef *htim);
-void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim);
-/**
- * @}
- */
-
-#if defined (STM32F100xB) || defined (STM32F100xE) || \
- defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
- defined (STM32F105xC) || defined (STM32F107xC)
-/** @addtogroup TIMEx_Exported_Functions_Group7
- * @{
- */
-/* Extension Peripheral State functions **************************************/
-HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(TIM_HandleTypeDef *htim);
-/**
- * @}
- */
-#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
- /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
- /* defined(STM32F105xC) || defined(STM32F107xC) */
-
-/**
- * @}
- */
-/* End of exported functions -------------------------------------------------*/
-
-/* Private functions----------------------------------------------------------*/
-/** @defgroup TIMEx_Private_Functions TIMEx Private Functions
-* @{
-*/
-void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma);
-/**
-* @}
-*/
-/* End of private functions --------------------------------------------------*/
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* __STM32F1xx_HAL_TIM_EX_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h
deleted file mode 100644
index 8e2b2ed..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h
+++ /dev/null
@@ -1,785 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_uart.h
- * @author MCD Application Team
- * @brief Header file of UART HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_UART_H
-#define __STM32F1xx_HAL_UART_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup UART
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup UART_Exported_Types UART Exported Types
- * @{
- */
-
-/**
- * @brief UART Init Structure definition
- */
-typedef struct
-{
- uint32_t BaudRate; /*!< This member configures the UART communication baud rate.
- The baud rate is computed using the following formula:
- - IntegerDivider = ((PCLKx) / (16 * (huart->Init.BaudRate)))
- - FractionalDivider = ((IntegerDivider - ((uint32_t) IntegerDivider)) * 16) + 0.5 */
-
- uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame.
- This parameter can be a value of @ref UART_Word_Length */
-
- uint32_t StopBits; /*!< Specifies the number of stop bits transmitted.
- This parameter can be a value of @ref UART_Stop_Bits */
-
- uint32_t Parity; /*!< Specifies the parity mode.
- This parameter can be a value of @ref UART_Parity
- @note When parity is enabled, the computed parity is inserted
- at the MSB position of the transmitted data (9th bit when
- the word length is set to 9 data bits; 8th bit when the
- word length is set to 8 data bits). */
-
- uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.
- This parameter can be a value of @ref UART_Mode */
-
- uint32_t HwFlowCtl; /*!< Specifies whether the hardware flow control mode is enabled or disabled.
- This parameter can be a value of @ref UART_Hardware_Flow_Control */
-
- uint32_t OverSampling; /*!< Specifies whether the Over sampling 8 is enabled or disabled, to achieve higher speed (up to fPCLK/8).
- This parameter can be a value of @ref UART_Over_Sampling. This feature is only available
- on STM32F100xx family, so OverSampling parameter should always be set to 16. */
-}UART_InitTypeDef;
-
-/**
- * @brief HAL UART State structures definition
- * @note HAL UART State value is a combination of 2 different substates: gState and RxState.
- * - gState contains UART state information related to global Handle management
- * and also information related to Tx operations.
- * gState value coding follow below described bitmap :
- * b7-b6 Error information
- * 00 : No Error
- * 01 : (Not Used)
- * 10 : Timeout
- * 11 : Error
- * b5 IP initilisation status
- * 0 : Reset (IP not initialized)
- * 1 : Init done (IP not initialized. HAL UART Init function already called)
- * b4-b3 (not used)
- * xx : Should be set to 00
- * b2 Intrinsic process state
- * 0 : Ready
- * 1 : Busy (IP busy with some configuration or internal operations)
- * b1 (not used)
- * x : Should be set to 0
- * b0 Tx state
- * 0 : Ready (no Tx operation ongoing)
- * 1 : Busy (Tx operation ongoing)
- * - RxState contains information related to Rx operations.
- * RxState value coding follow below described bitmap :
- * b7-b6 (not used)
- * xx : Should be set to 00
- * b5 IP initilisation status
- * 0 : Reset (IP not initialized)
- * 1 : Init done (IP not initialized)
- * b4-b2 (not used)
- * xxx : Should be set to 000
- * b1 Rx state
- * 0 : Ready (no Rx operation ongoing)
- * 1 : Busy (Rx operation ongoing)
- * b0 (not used)
- * x : Should be set to 0.
- */
-typedef enum
-{
- HAL_UART_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized
- Value is allowed for gState and RxState */
- HAL_UART_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use
- Value is allowed for gState and RxState */
- HAL_UART_STATE_BUSY = 0x24U, /*!< an internal process is ongoing
- Value is allowed for gState only */
- HAL_UART_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing
- Value is allowed for gState only */
- HAL_UART_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing
- Value is allowed for RxState only */
- HAL_UART_STATE_BUSY_TX_RX = 0x23U, /*!< Data Transmission and Reception process is ongoing
- Not to be used for neither gState nor RxState.
- Value is result of combination (Or) between gState and RxState values */
- HAL_UART_STATE_TIMEOUT = 0xA0U, /*!< Timeout state
- Value is allowed for gState only */
- HAL_UART_STATE_ERROR = 0xE0U /*!< Error
- Value is allowed for gState only */
-}HAL_UART_StateTypeDef;
-
-/**
- * @brief UART handle Structure definition
- */
-typedef struct
-{
- USART_TypeDef *Instance; /*!< UART registers base address */
-
- UART_InitTypeDef Init; /*!< UART communication parameters */
-
- uint8_t *pTxBuffPtr; /*!< Pointer to UART Tx transfer Buffer */
-
- uint16_t TxXferSize; /*!< UART Tx Transfer size */
-
- __IO uint16_t TxXferCount; /*!< UART Tx Transfer Counter */
-
- uint8_t *pRxBuffPtr; /*!< Pointer to UART Rx transfer Buffer */
-
- uint16_t RxXferSize; /*!< UART Rx Transfer size */
-
- __IO uint16_t RxXferCount; /*!< UART Rx Transfer Counter */
-
- DMA_HandleTypeDef *hdmatx; /*!< UART Tx DMA Handle parameters */
-
- DMA_HandleTypeDef *hdmarx; /*!< UART Rx DMA Handle parameters */
-
- HAL_LockTypeDef Lock; /*!< Locking object */
-
- __IO HAL_UART_StateTypeDef gState; /*!< UART state information related to global Handle management
- and also related to Tx operations.
- This parameter can be a value of @ref HAL_UART_StateTypeDef */
-
- __IO HAL_UART_StateTypeDef RxState; /*!< UART state information related to Rx operations.
- This parameter can be a value of @ref HAL_UART_StateTypeDef */
-
- __IO uint32_t ErrorCode; /*!< UART Error code */
-}UART_HandleTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup UART_Exported_Constants UART Exported constants
- * @{
- */
-
-/** @defgroup UART_Error_Code UART Error Code
- * @{
- */
-#define HAL_UART_ERROR_NONE 0x00000000U /*!< No error */
-#define HAL_UART_ERROR_PE 0x00000001U /*!< Parity error */
-#define HAL_UART_ERROR_NE 0x00000002U /*!< Noise error */
-#define HAL_UART_ERROR_FE 0x00000004U /*!< Frame error */
-#define HAL_UART_ERROR_ORE 0x00000008U /*!< Overrun error */
-#define HAL_UART_ERROR_DMA 0x00000010U /*!< DMA transfer error */
-/**
- * @}
- */
-
-/** @defgroup UART_Word_Length UART Word Length
- * @{
- */
-#define UART_WORDLENGTH_8B 0x00000000U
-#define UART_WORDLENGTH_9B ((uint32_t)USART_CR1_M)
-/**
- * @}
- */
-
-/** @defgroup UART_Stop_Bits UART Number of Stop Bits
- * @{
- */
-#define UART_STOPBITS_1 0x00000000U
-#define UART_STOPBITS_2 ((uint32_t)USART_CR2_STOP_1)
-/**
- * @}
- */
-
-/** @defgroup UART_Parity UART Parity
- * @{
- */
-#define UART_PARITY_NONE 0x00000000U
-#define UART_PARITY_EVEN ((uint32_t)USART_CR1_PCE)
-#define UART_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS))
-/**
- * @}
- */
-
-/** @defgroup UART_Hardware_Flow_Control UART Hardware Flow Control
- * @{
- */
-#define UART_HWCONTROL_NONE 0x00000000U
-#define UART_HWCONTROL_RTS ((uint32_t)USART_CR3_RTSE)
-#define UART_HWCONTROL_CTS ((uint32_t)USART_CR3_CTSE)
-#define UART_HWCONTROL_RTS_CTS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE))
-/**
- * @}
- */
-
-/** @defgroup UART_Mode UART Transfer Mode
- * @{
- */
-#define UART_MODE_RX ((uint32_t)USART_CR1_RE)
-#define UART_MODE_TX ((uint32_t)USART_CR1_TE)
-#define UART_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE))
-/**
- * @}
- */
-
-/** @defgroup UART_State UART State
- * @{
- */
-#define UART_STATE_DISABLE 0x00000000U
-#define UART_STATE_ENABLE ((uint32_t)USART_CR1_UE)
-/**
- * @}
- */
-
-
-/** @defgroup UART_Over_Sampling UART Over Sampling
- * @{
- */
-#define UART_OVERSAMPLING_16 0x00000000U
-#if defined(USART_CR1_OVER8)
-#define UART_OVERSAMPLING_8 ((uint32_t)USART_CR1_OVER8)
-#endif /* USART_CR1_OVER8 */
-/**
- * @}
- */
-
-
-/** @defgroup UART_LIN_Break_Detection_Length UART LIN Break Detection Length
- * @{
- */
-#define UART_LINBREAKDETECTLENGTH_10B 0x00000000U
-#define UART_LINBREAKDETECTLENGTH_11B ((uint32_t)USART_CR2_LBDL)
-/**
- * @}
- */
-/** @defgroup UART_WakeUp_functions UART Wakeup Functions
- * @{
- */
-#define UART_WAKEUPMETHOD_IDLELINE 0x00000000U
-#define UART_WAKEUPMETHOD_ADDRESSMARK ((uint32_t)USART_CR1_WAKE)
-/**
- * @}
- */
-
-/** @defgroup UART_Flags UART FLags
- * Elements values convention: 0xXXXX
- * - 0xXXXX : Flag mask in the SR register
- * @{
- */
-#define UART_FLAG_CTS ((uint32_t)USART_SR_CTS)
-#define UART_FLAG_LBD ((uint32_t)USART_SR_LBD)
-#define UART_FLAG_TXE ((uint32_t)USART_SR_TXE)
-#define UART_FLAG_TC ((uint32_t)USART_SR_TC)
-#define UART_FLAG_RXNE ((uint32_t)USART_SR_RXNE)
-#define UART_FLAG_IDLE ((uint32_t)USART_SR_IDLE)
-#define UART_FLAG_ORE ((uint32_t)USART_SR_ORE)
-#define UART_FLAG_NE ((uint32_t)USART_SR_NE)
-#define UART_FLAG_FE ((uint32_t)USART_SR_FE)
-#define UART_FLAG_PE ((uint32_t)USART_SR_PE)
-/**
- * @}
- */
-
-/** @defgroup UART_Interrupt_definition UART Interrupt Definitions
- * Elements values convention: 0xY000XXXX
- * - XXXX : Interrupt mask (16 bits) in the Y register
- * - Y : Interrupt source register (2bits)
- * - 01: CR1 register
- * - 10: CR2 register
- * - 11: CR3 register
- * @{
- */
-
-#define UART_IT_PE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_PEIE))
-#define UART_IT_TXE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_TXEIE))
-#define UART_IT_TC ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_TCIE))
-#define UART_IT_RXNE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_RXNEIE))
-#define UART_IT_IDLE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_IDLEIE))
-
-#define UART_IT_LBD ((uint32_t)(UART_CR2_REG_INDEX << 28U | USART_CR2_LBDIE))
-
-#define UART_IT_CTS ((uint32_t)(UART_CR3_REG_INDEX << 28U | USART_CR3_CTSIE))
-#define UART_IT_ERR ((uint32_t)(UART_CR3_REG_INDEX << 28U | USART_CR3_EIE))
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup UART_Exported_Macros UART Exported Macros
- * @{
- */
-
-/** @brief Reset UART handle gstate & RxState
- * @param __HANDLE__: specifies the UART Handle.
- * UART Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- */
-#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__) do{ \
- (__HANDLE__)->gState = HAL_UART_STATE_RESET; \
- (__HANDLE__)->RxState = HAL_UART_STATE_RESET; \
- } while(0U)
-
-/** @brief Flushs the UART DR register
- * @param __HANDLE__: specifies the UART Handle.
- * UART Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- */
-#define __HAL_UART_FLUSH_DRREGISTER(__HANDLE__) ((__HANDLE__)->Instance->DR)
-
-/** @brief Checks whether the specified UART flag is set or not.
- * @param __HANDLE__: specifies the UART Handle.
- * This parameter can be UARTx where x: 1, 2, 3, 4 or 5 to select the USART or
- * UART peripheral.
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg UART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5)
- * @arg UART_FLAG_LBD: LIN Break detection flag
- * @arg UART_FLAG_TXE: Transmit data register empty flag
- * @arg UART_FLAG_TC: Transmission Complete flag
- * @arg UART_FLAG_RXNE: Receive data register not empty flag
- * @arg UART_FLAG_IDLE: Idle Line detection flag
- * @arg UART_FLAG_ORE: OverRun Error flag
- * @arg UART_FLAG_NE: Noise Error flag
- * @arg UART_FLAG_FE: Framing Error flag
- * @arg UART_FLAG_PE: Parity Error flag
- * @retval The new state of __FLAG__ (TRUE or FALSE).
- */
-#define __HAL_UART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__))
-
-/** @brief Clears the specified UART pending flag.
- * @param __HANDLE__: specifies the UART Handle.
- * UART Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be any combination of the following values:
- * @arg UART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5).
- * @arg UART_FLAG_LBD: LIN Break detection flag.
- * @arg UART_FLAG_TC: Transmission Complete flag.
- * @arg UART_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 followed by a read
- * operation to USART_DR register.
- * @note RXNE flag can be also cleared by a read to the USART_DR register.
- * @note TC flag can be also cleared by software sequence: a read operation to
- * USART_SR register followed by a write operation to USART_DR register.
- * @note TXE flag is cleared only by a write to the USART_DR register.
- *
- */
-#define __HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__))
-
-/** @brief Clears the UART PE pending flag.
- * @param __HANDLE__: specifies the UART Handle.
- * UART Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- */
-#define __HAL_UART_CLEAR_PEFLAG(__HANDLE__) \
- do{ \
- __IO uint32_t tmpreg = 0x00U; \
- tmpreg = (__HANDLE__)->Instance->SR; \
- tmpreg = (__HANDLE__)->Instance->DR; \
- UNUSED(tmpreg); \
- } while(0U)
-
-/** @brief Clears the UART FE pending flag.
- * @param __HANDLE__: specifies the UART Handle.
- * UART Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- */
-#define __HAL_UART_CLEAR_FEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
-
-/** @brief Clears the UART NE pending flag.
- * @param __HANDLE__: specifies the UART Handle.
- * UART Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- */
-#define __HAL_UART_CLEAR_NEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
-
-/** @brief Clears the UART ORE pending flag.
- * @param __HANDLE__: specifies the UART Handle.
- * UART Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- */
-#define __HAL_UART_CLEAR_OREFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
-
-/** @brief Clears the UART IDLE pending flag.
- * @param __HANDLE__: specifies the UART Handle.
- * UART Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- */
-#define __HAL_UART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
-
-/** @brief Enable the specified UART interrupt.
- * @param __HANDLE__: specifies the UART Handle.
- * UART Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- * @param __INTERRUPT__: specifies the UART interrupt source to enable.
- * This parameter can be one of the following values:
- * @arg UART_IT_CTS: CTS change interrupt
- * @arg UART_IT_LBD: LIN Break detection interrupt
- * @arg UART_IT_TXE: Transmit Data Register empty interrupt
- * @arg UART_IT_TC: Transmission complete interrupt
- * @arg UART_IT_RXNE: Receive Data register not empty interrupt
- * @arg UART_IT_IDLE: Idle line detection interrupt
- * @arg UART_IT_PE: Parity Error interrupt
- * @arg UART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
- */
-#define __HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == UART_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & UART_IT_MASK)): \
- (((__INTERRUPT__) >> 28U) == UART_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 |= ((__INTERRUPT__) & UART_IT_MASK)): \
- ((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & UART_IT_MASK)))
-
-/** @brief Disable the specified UART interrupt.
- * @param __HANDLE__: specifies the UART Handle.
- * UART Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- * @param __INTERRUPT__: specifies the UART interrupt source to disable.
- * This parameter can be one of the following values:
- * @arg UART_IT_CTS: CTS change interrupt
- * @arg UART_IT_LBD: LIN Break detection interrupt
- * @arg UART_IT_TXE: Transmit Data Register empty interrupt
- * @arg UART_IT_TC: Transmission complete interrupt
- * @arg UART_IT_RXNE: Receive Data register not empty interrupt
- * @arg UART_IT_IDLE: Idle line detection interrupt
- * @arg UART_IT_PE: Parity Error interrupt
- * @arg UART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
- */
-#define __HAL_UART_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == UART_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 &= ~((__INTERRUPT__) & UART_IT_MASK)): \
- (((__INTERRUPT__) >> 28U) == UART_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 &= ~((__INTERRUPT__) & UART_IT_MASK)): \
- ((__HANDLE__)->Instance->CR3 &= ~ ((__INTERRUPT__) & UART_IT_MASK)))
-
-/** @brief Checks whether the specified UART interrupt has occurred or not.
- * @param __HANDLE__: specifies the UART Handle.
- * UART Handle selects the USARTx or UARTy peripheral
- * (USART,UART availability and x,y values depending on device).
- * @param __IT__: specifies the UART interrupt source to check.
- * This parameter can be one of the following values:
- * @arg UART_IT_CTS: CTS change interrupt (not available for UART4 and UART5)
- * @arg UART_IT_LBD: LIN Break detection interrupt
- * @arg UART_IT_TXE: Transmit Data Register empty interrupt
- * @arg UART_IT_TC: Transmission complete interrupt
- * @arg UART_IT_RXNE: Receive Data register not empty interrupt
- * @arg UART_IT_IDLE: Idle line detection interrupt
- * @arg UART_IT_ERR: Error interrupt
- * @retval The new state of __IT__ (TRUE or FALSE).
- */
-#define __HAL_UART_GET_IT_SOURCE(__HANDLE__, __IT__) (((((__IT__) >> 28U) == UART_CR1_REG_INDEX)? (__HANDLE__)->Instance->CR1:(((((uint32_t)(__IT__)) >> 28U) == UART_CR2_REG_INDEX)? \
- (__HANDLE__)->Instance->CR2 : (__HANDLE__)->Instance->CR3)) & (((uint32_t)(__IT__)) & UART_IT_MASK))
-
-/** @brief Enable CTS flow control
- * This macro allows to enable CTS hardware flow control for a given UART instance,
- * without need to call HAL_UART_Init() function.
- * As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
- * @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need
- * for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
- * - UART instance should have already been initialised (through call of HAL_UART_Init() )
- * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
- * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
- * @param __HANDLE__: specifies the UART Handle.
- * The Handle Instance can be any USARTx (supporting the HW Flow control feature).
- * It is used to select the USART peripheral (USART availability and x value depending on device).
- */
-#define __HAL_UART_HWCONTROL_CTS_ENABLE(__HANDLE__) \
- do{ \
- SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \
- (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_CTSE; \
- } while(0U)
-
-/** @brief Disable CTS flow control
- * This macro allows to disable CTS hardware flow control for a given UART instance,
- * without need to call HAL_UART_Init() function.
- * As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
- * @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need
- * for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
- * - UART instance should have already been initialised (through call of HAL_UART_Init() )
- * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
- * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
- * @param __HANDLE__: specifies the UART Handle.
- * The Handle Instance can be any USARTx (supporting the HW Flow control feature).
- * It is used to select the USART peripheral (USART availability and x value depending on device).
- */
-#define __HAL_UART_HWCONTROL_CTS_DISABLE(__HANDLE__) \
- do{ \
- CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \
- (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_CTSE); \
- } while(0U)
-
-/** @brief Enable RTS flow control
- * This macro allows to enable RTS hardware flow control for a given UART instance,
- * without need to call HAL_UART_Init() function.
- * As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
- * @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need
- * for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
- * - UART instance should have already been initialised (through call of HAL_UART_Init() )
- * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
- * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
- * @param __HANDLE__: specifies the UART Handle.
- * The Handle Instance can be any USARTx (supporting the HW Flow control feature).
- * It is used to select the USART peripheral (USART availability and x value depending on device).
- */
-#define __HAL_UART_HWCONTROL_RTS_ENABLE(__HANDLE__) \
- do{ \
- SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE); \
- (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_RTSE; \
- } while(0U)
-
-/** @brief Disable RTS flow control
- * This macro allows to disable RTS hardware flow control for a given UART instance,
- * without need to call HAL_UART_Init() function.
- * As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
- * @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need
- * for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
- * - UART instance should have already been initialised (through call of HAL_UART_Init() )
- * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
- * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
- * @param __HANDLE__: specifies the UART Handle.
- * The Handle Instance can be any USARTx (supporting the HW Flow control feature).
- * It is used to select the USART peripheral (USART availability and x value depending on device).
- */
-#define __HAL_UART_HWCONTROL_RTS_DISABLE(__HANDLE__) \
- do{ \
- CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE);\
- (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_RTSE); \
- } while(0U)
-
-#if defined(USART_CR3_ONEBIT)
-/** @brief macros to enables the UART's one bit sample method
- * @param __HANDLE__: specifies the UART Handle.
- */
-#define __HAL_UART_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT)
-
-/** @brief macros to disables the UART's one bit sample method
- * @param __HANDLE__: specifies the UART Handle.
- * @retval None
- */
-#define __HAL_UART_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_ONEBIT))
-#endif /* USART_CR3_ONEBIT */
-
-/** @brief Enable UART
- * @param __HANDLE__: specifies the UART Handle.
- */
-#define __HAL_UART_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE)
-
-/** @brief Disable UART
- * @param __HANDLE__: specifies the UART Handle.
- */
-#define __HAL_UART_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE)
-/**
- * @}
- */
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup UART_Exported_Functions
- * @{
- */
-
-/** @addtogroup UART_Exported_Functions_Group1
- * @{
- */
-/* Initialization/de-initialization functions **********************************/
-HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);
-HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart);
-HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength);
-HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod);
-HAL_StatusTypeDef HAL_UART_DeInit (UART_HandleTypeDef *huart);
-void HAL_UART_MspInit(UART_HandleTypeDef *huart);
-void HAL_UART_MspDeInit(UART_HandleTypeDef *huart);
-/**
- * @}
- */
-
-/** @addtogroup UART_Exported_Functions_Group2
- * @{
- */
-/* IO operation functions *******************************************************/
-HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart);
-HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart);
-HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart);
-/* Transfer Abort functions */
-HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart);
-HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart);
-HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart);
-HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart);
-HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart);
-HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart);
-
-void HAL_UART_IRQHandler(UART_HandleTypeDef *huart);
-void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);
-void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);
-void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
-void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);
-void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart);
-void HAL_UART_AbortCpltCallback (UART_HandleTypeDef *huart);
-void HAL_UART_AbortTransmitCpltCallback (UART_HandleTypeDef *huart);
-void HAL_UART_AbortReceiveCpltCallback (UART_HandleTypeDef *huart);
-/**
- * @}
- */
-
-/** @addtogroup UART_Exported_Functions_Group3
- * @{
- */
-/* Peripheral Control functions ************************************************/
-HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart);
-HAL_StatusTypeDef HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart);
-HAL_StatusTypeDef HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef *huart);
-HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart);
-HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart);
-/**
- * @}
- */
-
-/** @addtogroup UART_Exported_Functions_Group4
- * @{
- */
-/* Peripheral State functions **************************************************/
-HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart);
-uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart);
-/**
- * @}
- */
-
-/**
- * @}
- */
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup UART_Private_Constants UART Private Constants
- * @{
- */
-/** @brief UART interruptions flag mask
- *
- */
-#define UART_IT_MASK 0x0000FFFFU
-
-#define UART_CR1_REG_INDEX 1U
-#define UART_CR2_REG_INDEX 2U
-#define UART_CR3_REG_INDEX 3U
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup UART_Private_Macros UART Private Macros
- * @{
- */
-#define IS_UART_WORD_LENGTH(LENGTH) (((LENGTH) == UART_WORDLENGTH_8B) || \
- ((LENGTH) == UART_WORDLENGTH_9B))
-#define IS_UART_LIN_WORD_LENGTH(LENGTH) (((LENGTH) == UART_WORDLENGTH_8B))
-#define IS_UART_STOPBITS(STOPBITS) (((STOPBITS) == UART_STOPBITS_1) || \
- ((STOPBITS) == UART_STOPBITS_2))
-#define IS_UART_PARITY(PARITY) (((PARITY) == UART_PARITY_NONE) || \
- ((PARITY) == UART_PARITY_EVEN) || \
- ((PARITY) == UART_PARITY_ODD))
-#define IS_UART_HARDWARE_FLOW_CONTROL(CONTROL)\
- (((CONTROL) == UART_HWCONTROL_NONE) || \
- ((CONTROL) == UART_HWCONTROL_RTS) || \
- ((CONTROL) == UART_HWCONTROL_CTS) || \
- ((CONTROL) == UART_HWCONTROL_RTS_CTS))
-#define IS_UART_MODE(MODE) ((((MODE) & 0x0000FFF3U) == 0x00U) && ((MODE) != 0x00U))
-#define IS_UART_STATE(STATE) (((STATE) == UART_STATE_DISABLE) || \
- ((STATE) == UART_STATE_ENABLE))
-#if defined(USART_CR1_OVER8)
-#define IS_UART_OVERSAMPLING(SAMPLING) (((SAMPLING) == UART_OVERSAMPLING_16) || \
- ((SAMPLING) == UART_OVERSAMPLING_8))
-#endif /* USART_CR1_OVER8 */
-#define IS_UART_LIN_OVERSAMPLING(SAMPLING) (((SAMPLING) == UART_OVERSAMPLING_16))
-#define IS_UART_LIN_BREAK_DETECT_LENGTH(LENGTH) (((LENGTH) == UART_LINBREAKDETECTLENGTH_10B) || \
- ((LENGTH) == UART_LINBREAKDETECTLENGTH_11B))
-#define IS_UART_WAKEUPMETHOD(WAKEUP) (((WAKEUP) == UART_WAKEUPMETHOD_IDLELINE) || \
- ((WAKEUP) == UART_WAKEUPMETHOD_ADDRESSMARK))
-#define IS_UART_BAUDRATE(BAUDRATE) ((BAUDRATE) < 4500001U)
-#define IS_UART_ADDRESS(ADDRESS) ((ADDRESS) <= 0x0FU)
-
-#define UART_DIV_SAMPLING16(_PCLK_, _BAUD_) (((_PCLK_)*25U)/(4U*(_BAUD_)))
-#define UART_DIVMANT_SAMPLING16(_PCLK_, _BAUD_) (UART_DIV_SAMPLING16((_PCLK_), (_BAUD_))/100U)
-#define UART_DIVFRAQ_SAMPLING16(_PCLK_, _BAUD_) (((UART_DIV_SAMPLING16((_PCLK_), (_BAUD_)) - (UART_DIVMANT_SAMPLING16((_PCLK_), (_BAUD_)) * 100U)) * 16U + 50U) / 100U)
-/* UART BRR = mantissa + overflow + fraction
- = (UART DIVMANT << 4) + (UART DIVFRAQ & 0xF0) + (UART DIVFRAQ & 0x0FU) */
-#define UART_BRR_SAMPLING16(_PCLK_, _BAUD_) (((UART_DIVMANT_SAMPLING16((_PCLK_), (_BAUD_)) << 4U) + \
- (UART_DIVFRAQ_SAMPLING16((_PCLK_), (_BAUD_)) & 0xF0U)) + \
- (UART_DIVFRAQ_SAMPLING16((_PCLK_), (_BAUD_)) & 0x0FU))
-
-#define UART_DIV_SAMPLING8(_PCLK_, _BAUD_) (((_PCLK_)*25U)/(2U*(_BAUD_)))
-#define UART_DIVMANT_SAMPLING8(_PCLK_, _BAUD_) (UART_DIV_SAMPLING8((_PCLK_), (_BAUD_))/100U)
-#define UART_DIVFRAQ_SAMPLING8(_PCLK_, _BAUD_) (((UART_DIV_SAMPLING8((_PCLK_), (_BAUD_)) - (UART_DIVMANT_SAMPLING8((_PCLK_), (_BAUD_)) * 100U)) * 8U + 50U) / 100U)
-/* UART BRR = mantissa + overflow + fraction
- = (UART DIVMANT << 4) + ((UART DIVFRAQ & 0xF8) << 1) + (UART DIVFRAQ & 0x07U) */
-#define UART_BRR_SAMPLING8(_PCLK_, _BAUD_) (((UART_DIVMANT_SAMPLING8((_PCLK_), (_BAUD_)) << 4U) + \
- ((UART_DIVFRAQ_SAMPLING8((_PCLK_), (_BAUD_)) & 0xF8U) << 1U)) + \
- (UART_DIVFRAQ_SAMPLING8((_PCLK_), (_BAUD_)) & 0x07U))
-/**
- * @}
- */
-
-/* Private functions ---------------------------------------------------------*/
-/** @defgroup UART_Private_Functions UART Private Functions
- * @{
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_UART_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_usart.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_usart.h
deleted file mode 100644
index 2aed913..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_usart.h
+++ /dev/null
@@ -1,593 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_usart.h
- * @author MCD Application Team
- * @brief Header file of USART HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_USART_H
-#define __STM32F1xx_HAL_USART_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup USART
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup USART_Exported_Types USART Exported Types
- * @{
- */
-
-/**
- * @brief USART Init Structure definition
- */
-typedef struct
-{
- uint32_t BaudRate; /*!< This member configures the Usart communication baud rate.
- The baud rate is computed using the following formula:
- - IntegerDivider = ((PCLKx) / (16 * (husart->Init.BaudRate)))
- - FractionalDivider = ((IntegerDivider - ((uint32_t) IntegerDivider)) * 16) + 0.5 */
-
- uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame.
- This parameter can be a value of @ref USART_Word_Length */
-
- uint32_t StopBits; /*!< Specifies the number of stop bits transmitted.
- This parameter can be a value of @ref USART_Stop_Bits */
-
- uint32_t Parity; /*!< Specifies the parity mode.
- This parameter can be a value of @ref USART_Parity
- @note When parity is enabled, the computed parity is inserted
- at the MSB position of the transmitted data (9th bit when
- the word length is set to 9 data bits; 8th bit when the
- word length is set to 8 data bits). */
-
- uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.
- This parameter can be a value of @ref USART_Mode */
-
- uint32_t CLKPolarity; /*!< Specifies the steady state of the serial clock.
- This parameter can be a value of @ref USART_Clock_Polarity */
-
- uint32_t CLKPhase; /*!< Specifies the clock transition on which the bit capture is made.
- This parameter can be a value of @ref USART_Clock_Phase */
-
- uint32_t CLKLastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted
- data bit (MSB) has to be output on the SCLK pin in synchronous mode.
- This parameter can be a value of @ref USART_Last_Bit */
-}USART_InitTypeDef;
-
-/**
- * @brief HAL State structures definition
- */
-typedef enum
-{
- HAL_USART_STATE_RESET = 0x00U, /*!< Peripheral is not yet initialized */
- HAL_USART_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */
- HAL_USART_STATE_BUSY = 0x02U, /*!< an internal process is ongoing */
- HAL_USART_STATE_BUSY_TX = 0x12U, /*!< Data Transmission process is ongoing */
- HAL_USART_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */
- HAL_USART_STATE_BUSY_TX_RX = 0x32U, /*!< Data Transmission Reception process is ongoing */
- HAL_USART_STATE_TIMEOUT = 0x03U, /*!< Timeout state */
- HAL_USART_STATE_ERROR = 0x04U /*!< Error */
-}HAL_USART_StateTypeDef;
-
-/**
- * @brief USART handle Structure definition
- */
-typedef struct
-{
- USART_TypeDef *Instance; /*!< USART registers base address */
-
- USART_InitTypeDef Init; /*!< Usart communication parameters */
-
- uint8_t *pTxBuffPtr; /*!< Pointer to Usart Tx transfer Buffer */
-
- uint16_t TxXferSize; /*!< Usart Tx Transfer size */
-
- __IO uint16_t TxXferCount; /*!< Usart Tx Transfer Counter */
-
- uint8_t *pRxBuffPtr; /*!< Pointer to Usart Rx transfer Buffer */
-
- uint16_t RxXferSize; /*!< Usart Rx Transfer size */
-
- __IO uint16_t RxXferCount; /*!< Usart Rx Transfer Counter */
-
- DMA_HandleTypeDef *hdmatx; /*!< Usart Tx DMA Handle parameters */
-
- DMA_HandleTypeDef *hdmarx; /*!< Usart Rx DMA Handle parameters */
-
- HAL_LockTypeDef Lock; /*!< Locking object */
-
- __IO HAL_USART_StateTypeDef State; /*!< Usart communication state */
-
- __IO uint32_t ErrorCode; /*!< USART Error code */
-}USART_HandleTypeDef;
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup USART_Exported_Constants USART Exported Constants
- * @{
- */
-
-/** @defgroup USART_Error_Code USART Error Code
- * @brief USART Error Code
- * @{
- */
-#define HAL_USART_ERROR_NONE 0x00000000U /*!< No error */
-#define HAL_USART_ERROR_PE 0x00000001U /*!< Parity error */
-#define HAL_USART_ERROR_NE 0x00000002U /*!< Noise error */
-#define HAL_USART_ERROR_FE 0x00000004U /*!< Frame error */
-#define HAL_USART_ERROR_ORE 0x00000008U /*!< Overrun error */
-#define HAL_USART_ERROR_DMA 0x00000010U /*!< DMA transfer error */
-/**
- * @}
- */
-
-/** @defgroup USART_Word_Length USART Word Length
- * @{
- */
-#define USART_WORDLENGTH_8B 0x00000000U
-#define USART_WORDLENGTH_9B ((uint32_t)USART_CR1_M)
-/**
- * @}
- */
-
-/** @defgroup USART_Stop_Bits USART Number of Stop Bits
- * @{
- */
-#define USART_STOPBITS_1 0x00000000U
-#define USART_STOPBITS_0_5 ((uint32_t)USART_CR2_STOP_0)
-#define USART_STOPBITS_2 ((uint32_t)USART_CR2_STOP_1)
-#define USART_STOPBITS_1_5 ((uint32_t)(USART_CR2_STOP_0 | USART_CR2_STOP_1))
-/**
- * @}
- */
-
-/** @defgroup USART_Parity USART Parity
- * @{
- */
-#define USART_PARITY_NONE 0x00000000U
-#define USART_PARITY_EVEN ((uint32_t)USART_CR1_PCE)
-#define USART_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS))
-/**
- * @}
- */
-
-/** @defgroup USART_Mode USART Mode
- * @{
- */
-#define USART_MODE_RX ((uint32_t)USART_CR1_RE)
-#define USART_MODE_TX ((uint32_t)USART_CR1_TE)
-#define USART_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE))
-/**
- * @}
- */
-
-/** @defgroup USART_Clock USART Clock
- * @{
- */
-#define USART_CLOCK_DISABLE 0x00000000U
-#define USART_CLOCK_ENABLE ((uint32_t)USART_CR2_CLKEN)
-/**
- * @}
- */
-
-/** @defgroup USART_Clock_Polarity USART Clock Polarity
- * @{
- */
-#define USART_POLARITY_LOW 0x00000000U
-#define USART_POLARITY_HIGH ((uint32_t)USART_CR2_CPOL)
-/**
- * @}
- */
-
-/** @defgroup USART_Clock_Phase USART Clock Phase
- * @{
- */
-#define USART_PHASE_1EDGE 0x00000000U
-#define USART_PHASE_2EDGE ((uint32_t)USART_CR2_CPHA)
-/**
- * @}
- */
-
-/** @defgroup USART_Last_Bit USART Last Bit
- * @{
- */
-#define USART_LASTBIT_DISABLE 0x00000000U
-#define USART_LASTBIT_ENABLE ((uint32_t)USART_CR2_LBCL)
-/**
- * @}
- */
-
-/** @defgroup USART_NACK_State USART NACK State
- * @{
- */
-#define USART_NACK_ENABLE ((uint32_t)USART_CR3_NACK)
-#define USART_NACK_DISABLE 0x00000000U
-/**
- * @}
- */
-
-/** @defgroup USART_Flags USART Flags
- * Elements values convention: 0xXXXX
- * - 0xXXXX : Flag mask in the SR register
- * @{
- */
-#define USART_FLAG_TXE ((uint32_t)USART_SR_TXE)
-#define USART_FLAG_TC ((uint32_t)USART_SR_TC)
-#define USART_FLAG_RXNE ((uint32_t)USART_SR_RXNE)
-#define USART_FLAG_IDLE ((uint32_t)USART_SR_IDLE)
-#define USART_FLAG_ORE ((uint32_t)USART_SR_ORE)
-#define USART_FLAG_NE ((uint32_t)USART_SR_NE)
-#define USART_FLAG_FE ((uint32_t)USART_SR_FE)
-#define USART_FLAG_PE ((uint32_t)USART_SR_PE)
-/**
- * @}
- */
-
-/** @defgroup USART_Interrupt_definition USART Interrupts Definition
- * Elements values convention: 0xY000XXXX
- * - XXXX : Interrupt mask in the XX register
- * - Y : Interrupt source register (2bits)
- * - 01: CR1 register
- * - 10: CR2 register
- * - 11: CR3 register
- *
- * @{
- */
-
-#define USART_IT_PE ((uint32_t)(USART_CR1_REG_INDEX << 28U | USART_CR1_PEIE))
-#define USART_IT_TXE ((uint32_t)(USART_CR1_REG_INDEX << 28U | USART_CR1_TXEIE))
-#define USART_IT_TC ((uint32_t)(USART_CR1_REG_INDEX << 28U | USART_CR1_TCIE))
-#define USART_IT_RXNE ((uint32_t)(USART_CR1_REG_INDEX << 28U | USART_CR1_RXNEIE))
-#define USART_IT_IDLE ((uint32_t)(USART_CR1_REG_INDEX << 28U | USART_CR1_IDLEIE))
-
-#define USART_IT_LBD ((uint32_t)(USART_CR2_REG_INDEX << 28U | USART_CR2_LBDIE))
-
-#define USART_IT_CTS ((uint32_t)(USART_CR3_REG_INDEX << 28U | USART_CR3_CTSIE))
-#define USART_IT_ERR ((uint32_t)(USART_CR3_REG_INDEX << 28U | USART_CR3_EIE))
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup USART_Exported_Macros USART Exported Macros
- * @{
- */
-
-/** @brief Reset USART handle state
- * @param __HANDLE__: specifies the USART Handle.
- * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
- */
-#define __HAL_USART_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_USART_STATE_RESET)
-
-/** @brief Checks whether the specified USART flag is set or not.
- * @param __HANDLE__: specifies the USART Handle.
- * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be one of the following values:
- * @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 __FLAG__ (TRUE or FALSE).
- */
-#define __HAL_USART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__))
-
-/** @brief Clears the specified USART pending flags.
- * @param __HANDLE__: specifies the USART Handle.
- * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be any combination of the following values:
- * @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 followed by a read
- * operation to USART_DR register.
- * @note RXNE flag can be also cleared by a read to the USART_DR register.
- * @note TC flag can be also cleared by software sequence: a read operation to
- * USART_SR register followed by a write operation to USART_DR register
- * @note TXE flag is cleared only by a write to the USART_DR register
- *
- */
-#define __HAL_USART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__))
-
-/** @brief Clear the USART PE pending flag.
- * @param __HANDLE__: specifies the USART Handle.
- * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
- */
-#define __HAL_USART_CLEAR_PEFLAG(__HANDLE__) \
- do{ \
- __IO uint32_t tmpreg = 0x00U; \
- tmpreg = (__HANDLE__)->Instance->SR; \
- tmpreg = (__HANDLE__)->Instance->DR; \
- UNUSED(tmpreg); \
- } while(0U)
-
-/** @brief Clear the USART FE pending flag.
- * @param __HANDLE__: specifies the USART Handle.
- * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
- */
-#define __HAL_USART_CLEAR_FEFLAG(__HANDLE__) __HAL_USART_CLEAR_PEFLAG(__HANDLE__)
-
-/** @brief Clear the USART NE pending flag.
- * @param __HANDLE__: specifies the USART Handle.
- * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
- */
-#define __HAL_USART_CLEAR_NEFLAG(__HANDLE__) __HAL_USART_CLEAR_PEFLAG(__HANDLE__)
-
-/** @brief Clear the USART ORE pending flag.
- * @param __HANDLE__: specifies the USART Handle.
- * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
-
- */
-#define __HAL_USART_CLEAR_OREFLAG(__HANDLE__) __HAL_USART_CLEAR_PEFLAG(__HANDLE__)
-
-/** @brief Clear the USART IDLE pending flag.
- * @param __HANDLE__: specifies the USART Handle.
- * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
- */
-#define __HAL_USART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_USART_CLEAR_PEFLAG(__HANDLE__)
-
-/** @brief Enable the specified USART interrupts.
- * @param __HANDLE__: specifies the USART Handle.
- * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
- * @param __INTERRUPT__: specifies the USART interrupt source to enable.
- * This parameter can be one of the following values:
- * @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)
- * This parameter can be: ENABLE or DISABLE.
- */
-#define __HAL_USART_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == USART_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & USART_IT_MASK)): \
- (((__INTERRUPT__) >> 28U) == USART_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 |= ((__INTERRUPT__) & USART_IT_MASK)): \
- ((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & USART_IT_MASK)))
-
-/** @brief Disable the specified USART interrupts.
- * @param __HANDLE__: specifies the USART Handle.
- * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
- * @param __INTERRUPT__: specifies the USART interrupt source to disable.
- * This parameter can be one of the following values:
- * @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)
- * This parameter can be: ENABLE or DISABLE.
- */
-#define __HAL_USART_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == USART_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 &= ~((__INTERRUPT__) & USART_IT_MASK)): \
- (((__INTERRUPT__) >> 28U) == USART_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 &= ~((__INTERRUPT__) & USART_IT_MASK)): \
- ((__HANDLE__)->Instance->CR3 &= ~ ((__INTERRUPT__) & USART_IT_MASK)))
-
-/** @brief Checks whether the specified USART interrupt has occurred or not.
- * @param __HANDLE__: specifies the USART Handle.
- * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
- * @param __IT__: specifies the USART interrupt source to check.
- * This parameter can be one of the following values:
- * @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_ERR: Error interrupt
- * @arg USART_IT_PE: Parity Error interrupt
- * @retval The new state of __IT__ (TRUE or FALSE).
- */
-#define __HAL_USART_GET_IT_SOURCE(__HANDLE__, __IT__) (((((__IT__) >> 28U) == USART_CR1_REG_INDEX)? (__HANDLE__)->Instance->CR1:(((((uint32_t)(__IT__)) >> 28U) == USART_CR2_REG_INDEX)? \
- (__HANDLE__)->Instance->CR2 : (__HANDLE__)->Instance->CR3)) & (((uint32_t)(__IT__)) & USART_IT_MASK))
-
-/** @brief Enable USART
- * @param __HANDLE__: specifies the USART Handle.
- * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
- */
-#define __HAL_USART_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR1,(USART_CR1_UE))
-
-/** @brief Disable USART
- * @param __HANDLE__: specifies the USART Handle.
- * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
- */
-#define __HAL_USART_DISABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CR1,(USART_CR1_UE))
-/**
- * @}
- */
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup USART_Exported_Functions
- * @{
- */
-
-/** @addtogroup USART_Exported_Functions_Group1
- * @{
- */
-/* Initialization/de-initialization functions **********************************/
-HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart);
-HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart);
-void HAL_USART_MspInit(USART_HandleTypeDef *husart);
-void HAL_USART_MspDeInit(USART_HandleTypeDef *husart);
-/**
- * @}
- */
-
-/** @addtogroup USART_Exported_Functions_Group2
- * @{
- */
-/* IO operation functions *******************************************************/
-HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size);
-HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size);
-HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size);
-HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size);
-HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size);
-HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size);
-HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart);
-HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart);
-HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart);
-/* Transfer Abort functions */
-HAL_StatusTypeDef HAL_USART_Abort(USART_HandleTypeDef *husart);
-HAL_StatusTypeDef HAL_USART_Abort_IT(USART_HandleTypeDef *husart);
-
-void HAL_USART_IRQHandler(USART_HandleTypeDef *husart);
-void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart);
-void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart);
-void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart);
-void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart);
-void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart);
-void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart);
-void HAL_USART_AbortCpltCallback (USART_HandleTypeDef *husart);
-/**
- * @}
- */
-
-/** @addtogroup USART_Exported_Functions_Group3
- * @{
- */
-/* Peripheral State functions ************************************************/
-HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart);
-uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart);
-/**
- * @}
- */
-
-/**
- * @}
- */
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup USART_Private_Constants USART Private Constants
- * @{
- */
-/** @brief USART interruptions flag mask
- *
- */
-#define USART_IT_MASK 0x0000FFFFU
-
-#define USART_CR1_REG_INDEX 1U
-#define USART_CR2_REG_INDEX 2U
-#define USART_CR3_REG_INDEX 3U
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup USART_Private_Macros USART Private Macros
- * @{
- */
-#define IS_USART_NACK_STATE(NACK) (((NACK) == USART_NACK_ENABLE) || \
- ((NACK) == USART_NACK_DISABLE))
-
-#define IS_USART_LASTBIT(LASTBIT) (((LASTBIT) == USART_LASTBIT_DISABLE) || \
- ((LASTBIT) == USART_LASTBIT_ENABLE))
-
-#define IS_USART_PHASE(CPHA) (((CPHA) == USART_PHASE_1EDGE) || ((CPHA) == USART_PHASE_2EDGE))
-
-#define IS_USART_POLARITY(CPOL) (((CPOL) == USART_POLARITY_LOW) || ((CPOL) == USART_POLARITY_HIGH))
-
-#define IS_USART_CLOCK(CLOCK) (((CLOCK) == USART_CLOCK_DISABLE) || \
- ((CLOCK) == USART_CLOCK_ENABLE))
-
-#define IS_USART_WORD_LENGTH(LENGTH) (((LENGTH) == USART_WORDLENGTH_8B) || \
- ((LENGTH) == USART_WORDLENGTH_9B))
-
-#define IS_USART_STOPBITS(STOPBITS) (((STOPBITS) == USART_STOPBITS_1) || \
- ((STOPBITS) == USART_STOPBITS_0_5) || \
- ((STOPBITS) == USART_STOPBITS_1_5) || \
- ((STOPBITS) == USART_STOPBITS_2))
-
-#define IS_USART_PARITY(PARITY) (((PARITY) == USART_PARITY_NONE) || \
- ((PARITY) == USART_PARITY_EVEN) || \
- ((PARITY) == USART_PARITY_ODD))
-
-#define IS_USART_MODE(MODE) ((((MODE) & 0xFFF3U) == 0x00U) && ((MODE) != 0x00U))
-
-#define IS_USART_BAUDRATE(BAUDRATE) ((BAUDRATE) < 4500001U)
-
-#define USART_DIV(_PCLK_, _BAUD_) (((_PCLK_)*25U)/(2U*(_BAUD_)))
-
-#define USART_DIVMANT(_PCLK_, _BAUD_) (USART_DIV((_PCLK_), (_BAUD_))/100U)
-
-#define USART_DIVFRAQ(_PCLK_, _BAUD_) (((USART_DIV((_PCLK_), (_BAUD_)) - (USART_DIVMANT((_PCLK_), (_BAUD_)) * 100U)) * 16U + 50U) / 100U)
-
-#define USART_BRR(_PCLK_, _BAUD_) ((USART_DIVMANT((_PCLK_), (_BAUD_)) << 4U)|(USART_DIVFRAQ((_PCLK_), (_BAUD_)) & 0x0FU))
-/**
- * @}
- */
-
-/* Private functions ---------------------------------------------------------*/
-/** @defgroup USART_Private_Functions USART Private Functions
- * @{
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_USART_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_wwdg.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_wwdg.h
deleted file mode 100644
index 70f3ca1..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_wwdg.h
+++ /dev/null
@@ -1,281 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_wwdg.h
- * @author MCD Application Team
- * @brief Header file of WWDG HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_HAL_WWDG_H
-#define __STM32F1xx_HAL_WWDG_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup WWDG
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup WWDG_Exported_Types WWDG Exported Types
- * @{
- */
-
-/**
- * @brief WWDG Init structure definition
- */
-typedef struct
-{
- uint32_t Prescaler; /*!< Specifies the prescaler value of the WWDG.
- This parameter can be a value of @ref WWDG_Prescaler */
-
- uint32_t Window; /*!< Specifies the WWDG window value to be compared to the downcounter.
- This parameter must be a number Min_Data = 0x40 and Max_Data = 0x7F */
-
- uint32_t Counter; /*!< Specifies the WWDG free-running downcounter value.
- This parameter must be a number between Min_Data = 0x40 and Max_Data = 0x7F */
-
- uint32_t EWIMode ; /*!< Specifies if WWDG Early Wakeup Interupt is enable or not.
- This parameter can be a value of @ref WWDG_EWI_Mode */
-
-} WWDG_InitTypeDef;
-
-/**
- * @brief WWDG handle Structure definition
- */
-typedef struct
-{
- WWDG_TypeDef *Instance; /*!< Register base address */
-
- WWDG_InitTypeDef Init; /*!< WWDG required parameters */
-
-} WWDG_HandleTypeDef;
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-
-/** @defgroup WWDG_Exported_Constants WWDG Exported Constants
- * @{
- */
-
-/** @defgroup WWDG_Interrupt_definition WWDG Interrupt definition
- * @{
- */
-#define WWDG_IT_EWI WWDG_CFR_EWI /*!< Early wakeup interrupt */
-/**
- * @}
- */
-
-/** @defgroup WWDG_Flag_definition WWDG Flag definition
- * @brief WWDG Flag definition
- * @{
- */
-#define WWDG_FLAG_EWIF WWDG_SR_EWIF /*!< Early wakeup interrupt flag */
-/**
- * @}
- */
-
-/** @defgroup WWDG_Prescaler WWDG Prescaler
- * @{
- */
-#define WWDG_PRESCALER_1 0x00000000U /*!< WWDG counter clock = (PCLK1/4096)/1 */
-#define WWDG_PRESCALER_2 WWDG_CFR_WDGTB0 /*!< WWDG counter clock = (PCLK1/4096)/2 */
-#define WWDG_PRESCALER_4 WWDG_CFR_WDGTB1 /*!< WWDG counter clock = (PCLK1/4096)/4 */
-#define WWDG_PRESCALER_8 WWDG_CFR_WDGTB /*!< WWDG counter clock = (PCLK1/4096)/8 */
-/**
- * @}
- */
-
-/** @defgroup WWDG_EWI_Mode WWDG Early Wakeup Interrupt Mode
- * @{
- */
-#define WWDG_EWI_DISABLE 0x00000000U /*!< EWI Disable */
-#define WWDG_EWI_ENABLE WWDG_CFR_EWI /*!< EWI Enable */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-
-/** @defgroup WWDG_Private_Macros WWDG Private Macros
- * @{
- */
-#define IS_WWDG_PRESCALER(__PRESCALER__) (((__PRESCALER__) == WWDG_PRESCALER_1) || \
- ((__PRESCALER__) == WWDG_PRESCALER_2) || \
- ((__PRESCALER__) == WWDG_PRESCALER_4) || \
- ((__PRESCALER__) == WWDG_PRESCALER_8))
-
-#define IS_WWDG_WINDOW(__WINDOW__) (((__WINDOW__) >= WWDG_CFR_W_6) && ((__WINDOW__) <= WWDG_CFR_W))
-
-#define IS_WWDG_COUNTER(__COUNTER__) (((__COUNTER__) >= WWDG_CR_T_6) && ((__COUNTER__) <= WWDG_CR_T))
-
-#define IS_WWDG_EWI_MODE(__MODE__) (((__MODE__) == WWDG_EWI_ENABLE) || \
- ((__MODE__) == WWDG_EWI_DISABLE))
-/**
- * @}
- */
-
-
-/* Exported macros ------------------------------------------------------------*/
-
-/** @defgroup WWDG_Exported_Macros WWDG Exported Macros
- * @{
- */
-
-/**
- * @brief Enables the WWDG peripheral.
- * @param __HANDLE__: WWDG handle
- * @retval None
- */
-#define __HAL_WWDG_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR, WWDG_CR_WDGA)
-
-/**
- * @brief Enables the WWDG early wakeup interrupt.
- * @param __HANDLE__: WWDG handle
- * @param __INTERRUPT__ specifies the interrupt to enable.
- * This parameter can be one of the following values:
- * @arg WWDG_IT_EWI: Early wakeup interrupt
- * @note Once enabled this interrupt cannot be disabled except by a system reset.
- * @retval None
- */
-#define __HAL_WWDG_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->CFR, (__INTERRUPT__))
-
-/**
- * @brief Checks whether the selected WWDG interrupt has occurred or not.
- * @param __HANDLE__ WWDG handle
- * @param __INTERRUPT__ specifies the it to check.
- * This parameter can be one of the following values:
- * @arg WWDG_FLAG_EWIF: Early wakeup interrupt IT
- * @retval The new state of WWDG_FLAG (SET or RESET).
- */
-#define __HAL_WWDG_GET_IT(__HANDLE__, __INTERRUPT__) __HAL_WWDG_GET_FLAG((__HANDLE__),(__INTERRUPT__))
-
-/** @brief Clear the WWDG's interrupt pending bits
- * bits to clear the selected interrupt pending bits.
- * @param __HANDLE__: WWDG handle
- * @param __INTERRUPT__: specifies the interrupt pending bit to clear.
- * This parameter can be one of the following values:
- * @arg WWDG_FLAG_EWIF: Early wakeup interrupt flag
- */
-#define __HAL_WWDG_CLEAR_IT(__HANDLE__, __INTERRUPT__) __HAL_WWDG_CLEAR_FLAG((__HANDLE__), (__INTERRUPT__))
-
-/**
- * @brief Check whether the specified WWDG flag is set or not.
- * @param __HANDLE__ WWDG handle
- * @param __FLAG__ specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg WWDG_FLAG_EWIF: Early wakeup interrupt flag
- * @retval The new state of WWDG_FLAG (SET or RESET).
- */
-#define __HAL_WWDG_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__))
-
-/**
- * @brief Clears the WWDG's pending flags.
- * @param __HANDLE__: WWDG handle
- * @param __FLAG__: specifies the flag to clear.
- * This parameter can be one of the following values:
- * @arg WWDG_FLAG_EWIF: Early wakeup interrupt flag
- * @retval None
- */
-#define __HAL_WWDG_CLEAR_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR) = ~(__FLAG__))
-
-/** @brief Checks if the specified WWDG interrupt source is enabled or disabled.
- * @param __HANDLE__: WWDG Handle.
- * @param __INTERRUPT__: specifies the WWDG interrupt source to check.
- * This parameter can be one of the following values:
- * @arg WWDG_IT_EWI: Early Wakeup Interrupt
- * @retval state of __INTERRUPT__ (TRUE or FALSE).
- */
-#define __HAL_WWDG_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CFR & (__INTERRUPT__)) == (__INTERRUPT__))
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup WWDG_Exported_Functions
- * @{
- */
-
-/** @addtogroup WWDG_Exported_Functions_Group1
- * @{
- */
-/* Initialization/de-initialization functions **********************************/
-HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg);
-void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg);
-/**
- * @}
- */
-
-/** @addtogroup WWDG_Exported_Functions_Group2
- * @{
- */
-/* I/O operation functions ******************************************************/
-HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg);
-void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg);
-void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_HAL_WWDG_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_bus.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_bus.h
deleted file mode 100644
index e5b054a..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_bus.h
+++ /dev/null
@@ -1,1031 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_bus.h
- * @author MCD Application Team
- * @brief Header file of BUS LL module.
-
- @verbatim
- ##### RCC Limitations #####
- ==============================================================================
- [..]
- A delay between an RCC peripheral clock enable and the effective peripheral
- enabling should be taken into account in order to manage the peripheral read/write
- from/to registers.
- (+) This delay depends on the peripheral mapping.
- (++) AHB & APB peripherals, 1 dummy read is necessary
-
- [..]
- Workarounds:
- (#) For AHB & APB peripherals, a dummy read to the peripheral register has been
- inserted in each LL_{BUS}_GRP{x}_EnableClock() function.
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_LL_BUS_H
-#define __STM32F1xx_LL_BUS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx.h"
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined(RCC)
-
-/** @defgroup BUS_LL BUS
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-
-/* Private constants ---------------------------------------------------------*/
-#if defined(RCC_AHBRSTR_OTGFSRST) || defined(RCC_AHBRSTR_ETHMACRST)
-#define RCC_AHBRSTR_SUPPORT
-#endif /* RCC_AHBRSTR_OTGFSRST || RCC_AHBRSTR_ETHMACRST */
-
-/* Private macros ------------------------------------------------------------*/
-
-/* Exported types ------------------------------------------------------------*/
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup BUS_LL_Exported_Constants BUS Exported Constants
- * @{
- */
-
-/** @defgroup BUS_LL_EC_AHB1_GRP1_PERIPH AHB1 GRP1 PERIPH
- * @{
- */
-#define LL_AHB1_GRP1_PERIPH_ALL (uint32_t)0xFFFFFFFFU
-#define LL_AHB1_GRP1_PERIPH_CRC RCC_AHBENR_CRCEN
-#define LL_AHB1_GRP1_PERIPH_DMA1 RCC_AHBENR_DMA1EN
-#if defined(DMA2)
-#define LL_AHB1_GRP1_PERIPH_DMA2 RCC_AHBENR_DMA2EN
-#endif /*DMA2*/
-#if defined(ETH)
-#define LL_AHB1_GRP1_PERIPH_ETHMAC RCC_AHBENR_ETHMACEN
-#define LL_AHB1_GRP1_PERIPH_ETHMACRX RCC_AHBENR_ETHMACRXEN
-#define LL_AHB1_GRP1_PERIPH_ETHMACTX RCC_AHBENR_ETHMACTXEN
-#endif /*ETH*/
-#define LL_AHB1_GRP1_PERIPH_FLASH RCC_AHBENR_FLITFEN
-#if defined(FSMC_Bank1)
-#define LL_AHB1_GRP1_PERIPH_FSMC RCC_AHBENR_FSMCEN
-#endif /*FSMC_Bank1*/
-#if defined(USB_OTG_FS)
-#define LL_AHB1_GRP1_PERIPH_OTGFS RCC_AHBENR_OTGFSEN
-#endif /*USB_OTG_FS*/
-#if defined(SDIO)
-#define LL_AHB1_GRP1_PERIPH_SDIO RCC_AHBENR_SDIOEN
-#endif /*SDIO*/
-#define LL_AHB1_GRP1_PERIPH_SRAM RCC_AHBENR_SRAMEN
-/**
- * @}
- */
-
-/** @defgroup BUS_LL_EC_APB1_GRP1_PERIPH APB1 GRP1 PERIPH
- * @{
- */
-#define LL_APB1_GRP1_PERIPH_ALL (uint32_t)0xFFFFFFFFU
-#define LL_APB1_GRP1_PERIPH_BKP RCC_APB1ENR_BKPEN
-#if defined(CAN1)
-#define LL_APB1_GRP1_PERIPH_CAN1 RCC_APB1ENR_CAN1EN
-#endif /*CAN1*/
-#if defined(CAN2)
-#define LL_APB1_GRP1_PERIPH_CAN2 RCC_APB1ENR_CAN2EN
-#endif /*CAN2*/
-#if defined(CEC)
-#define LL_APB1_GRP1_PERIPH_CEC RCC_APB1ENR_CECEN
-#endif /*CEC*/
-#if defined(DAC)
-#define LL_APB1_GRP1_PERIPH_DAC1 RCC_APB1ENR_DACEN
-#endif /*DAC*/
-#define LL_APB1_GRP1_PERIPH_I2C1 RCC_APB1ENR_I2C1EN
-#if defined(I2C2)
-#define LL_APB1_GRP1_PERIPH_I2C2 RCC_APB1ENR_I2C2EN
-#endif /*I2C2*/
-#define LL_APB1_GRP1_PERIPH_PWR RCC_APB1ENR_PWREN
-#if defined(SPI2)
-#define LL_APB1_GRP1_PERIPH_SPI2 RCC_APB1ENR_SPI2EN
-#endif /*SPI2*/
-#if defined(SPI3)
-#define LL_APB1_GRP1_PERIPH_SPI3 RCC_APB1ENR_SPI3EN
-#endif /*SPI3*/
-#if defined(TIM12)
-#define LL_APB1_GRP1_PERIPH_TIM12 RCC_APB1ENR_TIM12EN
-#endif /*TIM12*/
-#if defined(TIM13)
-#define LL_APB1_GRP1_PERIPH_TIM13 RCC_APB1ENR_TIM13EN
-#endif /*TIM13*/
-#if defined(TIM14)
-#define LL_APB1_GRP1_PERIPH_TIM14 RCC_APB1ENR_TIM14EN
-#endif /*TIM14*/
-#define LL_APB1_GRP1_PERIPH_TIM2 RCC_APB1ENR_TIM2EN
-#define LL_APB1_GRP1_PERIPH_TIM3 RCC_APB1ENR_TIM3EN
-#if defined(TIM4)
-#define LL_APB1_GRP1_PERIPH_TIM4 RCC_APB1ENR_TIM4EN
-#endif /*TIM4*/
-#if defined(TIM5)
-#define LL_APB1_GRP1_PERIPH_TIM5 RCC_APB1ENR_TIM5EN
-#endif /*TIM5*/
-#if defined(TIM6)
-#define LL_APB1_GRP1_PERIPH_TIM6 RCC_APB1ENR_TIM6EN
-#endif /*TIM6*/
-#if defined(TIM7)
-#define LL_APB1_GRP1_PERIPH_TIM7 RCC_APB1ENR_TIM7EN
-#endif /*TIM7*/
-#if defined(UART4)
-#define LL_APB1_GRP1_PERIPH_UART4 RCC_APB1ENR_UART4EN
-#endif /*UART4*/
-#if defined(UART5)
-#define LL_APB1_GRP1_PERIPH_UART5 RCC_APB1ENR_UART5EN
-#endif /*UART5*/
-#define LL_APB1_GRP1_PERIPH_USART2 RCC_APB1ENR_USART2EN
-#if defined(USART3)
-#define LL_APB1_GRP1_PERIPH_USART3 RCC_APB1ENR_USART3EN
-#endif /*USART3*/
-#if defined(USB)
-#define LL_APB1_GRP1_PERIPH_USB RCC_APB1ENR_USBEN
-#endif /*USB*/
-#define LL_APB1_GRP1_PERIPH_WWDG RCC_APB1ENR_WWDGEN
-/**
- * @}
- */
-
-/** @defgroup BUS_LL_EC_APB2_GRP1_PERIPH APB2 GRP1 PERIPH
- * @{
- */
-#define LL_APB2_GRP1_PERIPH_ALL (uint32_t)0xFFFFFFFFU
-#define LL_APB2_GRP1_PERIPH_ADC1 RCC_APB2ENR_ADC1EN
-#if defined(ADC2)
-#define LL_APB2_GRP1_PERIPH_ADC2 RCC_APB2ENR_ADC2EN
-#endif /*ADC2*/
-#if defined(ADC3)
-#define LL_APB2_GRP1_PERIPH_ADC3 RCC_APB2ENR_ADC3EN
-#endif /*ADC3*/
-#define LL_APB2_GRP1_PERIPH_AFIO RCC_APB2ENR_AFIOEN
-#define LL_APB2_GRP1_PERIPH_GPIOA RCC_APB2ENR_IOPAEN
-#define LL_APB2_GRP1_PERIPH_GPIOB RCC_APB2ENR_IOPBEN
-#define LL_APB2_GRP1_PERIPH_GPIOC RCC_APB2ENR_IOPCEN
-#define LL_APB2_GRP1_PERIPH_GPIOD RCC_APB2ENR_IOPDEN
-#if defined(GPIOE)
-#define LL_APB2_GRP1_PERIPH_GPIOE RCC_APB2ENR_IOPEEN
-#endif /*GPIOE*/
-#if defined(GPIOF)
-#define LL_APB2_GRP1_PERIPH_GPIOF RCC_APB2ENR_IOPFEN
-#endif /*GPIOF*/
-#if defined(GPIOG)
-#define LL_APB2_GRP1_PERIPH_GPIOG RCC_APB2ENR_IOPGEN
-#endif /*GPIOG*/
-#define LL_APB2_GRP1_PERIPH_SPI1 RCC_APB2ENR_SPI1EN
-#if defined(TIM10)
-#define LL_APB2_GRP1_PERIPH_TIM10 RCC_APB2ENR_TIM10EN
-#endif /*TIM10*/
-#if defined(TIM11)
-#define LL_APB2_GRP1_PERIPH_TIM11 RCC_APB2ENR_TIM11EN
-#endif /*TIM11*/
-#if defined(TIM15)
-#define LL_APB2_GRP1_PERIPH_TIM15 RCC_APB2ENR_TIM15EN
-#endif /*TIM15*/
-#if defined(TIM16)
-#define LL_APB2_GRP1_PERIPH_TIM16 RCC_APB2ENR_TIM16EN
-#endif /*TIM16*/
-#if defined(TIM17)
-#define LL_APB2_GRP1_PERIPH_TIM17 RCC_APB2ENR_TIM17EN
-#endif /*TIM17*/
-#define LL_APB2_GRP1_PERIPH_TIM1 RCC_APB2ENR_TIM1EN
-#if defined(TIM8)
-#define LL_APB2_GRP1_PERIPH_TIM8 RCC_APB2ENR_TIM8EN
-#endif /*TIM8*/
-#if defined(TIM9)
-#define LL_APB2_GRP1_PERIPH_TIM9 RCC_APB2ENR_TIM9EN
-#endif /*TIM9*/
-#define LL_APB2_GRP1_PERIPH_USART1 RCC_APB2ENR_USART1EN
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup BUS_LL_Exported_Functions BUS Exported Functions
- * @{
- */
-
-/** @defgroup BUS_LL_EF_AHB1 AHB1
- * @{
- */
-
-/**
- * @brief Enable AHB1 peripherals clock.
- * @rmtoll AHBENR CRCEN LL_AHB1_GRP1_EnableClock\n
- * AHBENR DMA1EN LL_AHB1_GRP1_EnableClock\n
- * AHBENR DMA2EN LL_AHB1_GRP1_EnableClock\n
- * AHBENR ETHMACEN LL_AHB1_GRP1_EnableClock\n
- * AHBENR ETHMACRXEN LL_AHB1_GRP1_EnableClock\n
- * AHBENR ETHMACTXEN LL_AHB1_GRP1_EnableClock\n
- * AHBENR FLITFEN LL_AHB1_GRP1_EnableClock\n
- * AHBENR FSMCEN LL_AHB1_GRP1_EnableClock\n
- * AHBENR OTGFSEN LL_AHB1_GRP1_EnableClock\n
- * AHBENR SDIOEN LL_AHB1_GRP1_EnableClock\n
- * AHBENR SRAMEN LL_AHB1_GRP1_EnableClock
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_AHB1_GRP1_PERIPH_CRC
- * @arg @ref LL_AHB1_GRP1_PERIPH_DMA1
- * @arg @ref LL_AHB1_GRP1_PERIPH_DMA2 (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMAC (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMACRX (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMACTX (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_FLASH
- * @arg @ref LL_AHB1_GRP1_PERIPH_FSMC (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_OTGFS (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_SDIO (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_SRAM
- *
- * (*) value not defined in all devices.
- * @retval None
-*/
-__STATIC_INLINE void LL_AHB1_GRP1_EnableClock(uint32_t Periphs)
-{
- __IO uint32_t tmpreg;
- SET_BIT(RCC->AHBENR, Periphs);
- /* Delay after an RCC peripheral clock enabling */
- tmpreg = READ_BIT(RCC->AHBENR, Periphs);
- (void)tmpreg;
-}
-
-/**
- * @brief Check if AHB1 peripheral clock is enabled or not
- * @rmtoll AHBENR CRCEN LL_AHB1_GRP1_IsEnabledClock\n
- * AHBENR DMA1EN LL_AHB1_GRP1_IsEnabledClock\n
- * AHBENR DMA2EN LL_AHB1_GRP1_IsEnabledClock\n
- * AHBENR ETHMACEN LL_AHB1_GRP1_IsEnabledClock\n
- * AHBENR ETHMACRXEN LL_AHB1_GRP1_IsEnabledClock\n
- * AHBENR ETHMACTXEN LL_AHB1_GRP1_IsEnabledClock\n
- * AHBENR FLITFEN LL_AHB1_GRP1_IsEnabledClock\n
- * AHBENR FSMCEN LL_AHB1_GRP1_IsEnabledClock\n
- * AHBENR OTGFSEN LL_AHB1_GRP1_IsEnabledClock\n
- * AHBENR SDIOEN LL_AHB1_GRP1_IsEnabledClock\n
- * AHBENR SRAMEN LL_AHB1_GRP1_IsEnabledClock
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_AHB1_GRP1_PERIPH_CRC
- * @arg @ref LL_AHB1_GRP1_PERIPH_DMA1
- * @arg @ref LL_AHB1_GRP1_PERIPH_DMA2 (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMAC (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMACRX (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMACTX (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_FLASH
- * @arg @ref LL_AHB1_GRP1_PERIPH_FSMC (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_OTGFS (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_SDIO (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_SRAM
- *
- * (*) value not defined in all devices.
- * @retval State of Periphs (1 or 0).
-*/
-__STATIC_INLINE uint32_t LL_AHB1_GRP1_IsEnabledClock(uint32_t Periphs)
-{
- return (READ_BIT(RCC->AHBENR, Periphs) == Periphs);
-}
-
-/**
- * @brief Disable AHB1 peripherals clock.
- * @rmtoll AHBENR CRCEN LL_AHB1_GRP1_DisableClock\n
- * AHBENR DMA1EN LL_AHB1_GRP1_DisableClock\n
- * AHBENR DMA2EN LL_AHB1_GRP1_DisableClock\n
- * AHBENR ETHMACEN LL_AHB1_GRP1_DisableClock\n
- * AHBENR ETHMACRXEN LL_AHB1_GRP1_DisableClock\n
- * AHBENR ETHMACTXEN LL_AHB1_GRP1_DisableClock\n
- * AHBENR FLITFEN LL_AHB1_GRP1_DisableClock\n
- * AHBENR FSMCEN LL_AHB1_GRP1_DisableClock\n
- * AHBENR OTGFSEN LL_AHB1_GRP1_DisableClock\n
- * AHBENR SDIOEN LL_AHB1_GRP1_DisableClock\n
- * AHBENR SRAMEN LL_AHB1_GRP1_DisableClock
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_AHB1_GRP1_PERIPH_CRC
- * @arg @ref LL_AHB1_GRP1_PERIPH_DMA1
- * @arg @ref LL_AHB1_GRP1_PERIPH_DMA2 (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMAC (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMACRX (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMACTX (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_FLASH
- * @arg @ref LL_AHB1_GRP1_PERIPH_FSMC (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_OTGFS (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_SDIO (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_SRAM
- *
- * (*) value not defined in all devices.
- * @retval None
-*/
-__STATIC_INLINE void LL_AHB1_GRP1_DisableClock(uint32_t Periphs)
-{
- CLEAR_BIT(RCC->AHBENR, Periphs);
-}
-
-#if defined(RCC_AHBRSTR_SUPPORT)
-/**
- * @brief Force AHB1 peripherals reset.
- * @rmtoll AHBRSTR ETHMACRST LL_AHB1_GRP1_ForceReset\n
- * AHBRSTR OTGFSRST LL_AHB1_GRP1_ForceReset
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_AHB1_GRP1_PERIPH_ALL
- * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMAC (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_OTGFS (*)
- *
- * (*) value not defined in all devices.
- * @retval None
-*/
-__STATIC_INLINE void LL_AHB1_GRP1_ForceReset(uint32_t Periphs)
-{
- SET_BIT(RCC->AHBRSTR, Periphs);
-}
-
-/**
- * @brief Release AHB1 peripherals reset.
- * @rmtoll AHBRSTR ETHMACRST LL_AHB1_GRP1_ReleaseReset\n
- * AHBRSTR OTGFSRST LL_AHB1_GRP1_ReleaseReset
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_AHB1_GRP1_PERIPH_ALL
- * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMAC (*)
- * @arg @ref LL_AHB1_GRP1_PERIPH_OTGFS (*)
- *
- * (*) value not defined in all devices.
- * @retval None
-*/
-__STATIC_INLINE void LL_AHB1_GRP1_ReleaseReset(uint32_t Periphs)
-{
- CLEAR_BIT(RCC->AHBRSTR, Periphs);
-}
-#endif /* RCC_AHBRSTR_SUPPORT */
-
-/**
- * @}
- */
-
-/** @defgroup BUS_LL_EF_APB1 APB1
- * @{
- */
-
-/**
- * @brief Enable APB1 peripherals clock.
- * @rmtoll APB1ENR BKPEN LL_APB1_GRP1_EnableClock\n
- * APB1ENR CAN1EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR CAN2EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR CECEN LL_APB1_GRP1_EnableClock\n
- * APB1ENR DACEN LL_APB1_GRP1_EnableClock\n
- * APB1ENR I2C1EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR I2C2EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR PWREN LL_APB1_GRP1_EnableClock\n
- * APB1ENR SPI2EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR SPI3EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR TIM12EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR TIM13EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR TIM14EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR TIM2EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR TIM3EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR TIM4EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR TIM5EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR TIM6EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR TIM7EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR UART4EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR UART5EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR USART2EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR USART3EN LL_APB1_GRP1_EnableClock\n
- * APB1ENR USBEN LL_APB1_GRP1_EnableClock\n
- * APB1ENR WWDGEN LL_APB1_GRP1_EnableClock
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_APB1_GRP1_PERIPH_BKP
- * @arg @ref LL_APB1_GRP1_PERIPH_CAN1 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_CAN2 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_DAC1 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_I2C1
- * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_PWR
- * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM12 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM13 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM2
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM3
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM4 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM5 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_UART4 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_UART5 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_USART2
- * @arg @ref LL_APB1_GRP1_PERIPH_USART3 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_USB (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_WWDG
- *
- * (*) value not defined in all devices.
- * @retval None
-*/
-__STATIC_INLINE void LL_APB1_GRP1_EnableClock(uint32_t Periphs)
-{
- __IO uint32_t tmpreg;
- SET_BIT(RCC->APB1ENR, Periphs);
- /* Delay after an RCC peripheral clock enabling */
- tmpreg = READ_BIT(RCC->APB1ENR, Periphs);
- (void)tmpreg;
-}
-
-/**
- * @brief Check if APB1 peripheral clock is enabled or not
- * @rmtoll APB1ENR BKPEN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR CAN1EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR CAN2EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR CECEN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR DACEN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR I2C1EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR I2C2EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR PWREN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR SPI2EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR SPI3EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR TIM12EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR TIM13EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR TIM14EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR TIM2EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR TIM3EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR TIM4EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR TIM5EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR TIM6EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR TIM7EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR UART4EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR UART5EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR USART2EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR USART3EN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR USBEN LL_APB1_GRP1_IsEnabledClock\n
- * APB1ENR WWDGEN LL_APB1_GRP1_IsEnabledClock
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_APB1_GRP1_PERIPH_BKP
- * @arg @ref LL_APB1_GRP1_PERIPH_CAN1 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_CAN2 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_DAC1 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_I2C1
- * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_PWR
- * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM12 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM13 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM2
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM3
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM4 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM5 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_UART4 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_UART5 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_USART2
- * @arg @ref LL_APB1_GRP1_PERIPH_USART3 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_USB (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_WWDG
- *
- * (*) value not defined in all devices.
- * @retval State of Periphs (1 or 0).
-*/
-__STATIC_INLINE uint32_t LL_APB1_GRP1_IsEnabledClock(uint32_t Periphs)
-{
- return (READ_BIT(RCC->APB1ENR, Periphs) == Periphs);
-}
-
-/**
- * @brief Disable APB1 peripherals clock.
- * @rmtoll APB1ENR BKPEN LL_APB1_GRP1_DisableClock\n
- * APB1ENR CAN1EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR CAN2EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR CECEN LL_APB1_GRP1_DisableClock\n
- * APB1ENR DACEN LL_APB1_GRP1_DisableClock\n
- * APB1ENR I2C1EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR I2C2EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR PWREN LL_APB1_GRP1_DisableClock\n
- * APB1ENR SPI2EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR SPI3EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR TIM12EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR TIM13EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR TIM14EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR TIM2EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR TIM3EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR TIM4EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR TIM5EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR TIM6EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR TIM7EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR UART4EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR UART5EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR USART2EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR USART3EN LL_APB1_GRP1_DisableClock\n
- * APB1ENR USBEN LL_APB1_GRP1_DisableClock\n
- * APB1ENR WWDGEN LL_APB1_GRP1_DisableClock
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_APB1_GRP1_PERIPH_BKP
- * @arg @ref LL_APB1_GRP1_PERIPH_CAN1 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_CAN2 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_DAC1 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_I2C1
- * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_PWR
- * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM12 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM13 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM2
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM3
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM4 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM5 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_UART4 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_UART5 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_USART2
- * @arg @ref LL_APB1_GRP1_PERIPH_USART3 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_USB (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_WWDG
- *
- * (*) value not defined in all devices.
- * @retval None
-*/
-__STATIC_INLINE void LL_APB1_GRP1_DisableClock(uint32_t Periphs)
-{
- CLEAR_BIT(RCC->APB1ENR, Periphs);
-}
-
-/**
- * @brief Force APB1 peripherals reset.
- * @rmtoll APB1RSTR BKPRST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR CAN1RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR CAN2RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR CECRST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR DACRST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR I2C1RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR I2C2RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR PWRRST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR SPI2RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR SPI3RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR TIM12RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR TIM13RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR TIM14RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR TIM2RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR TIM3RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR TIM4RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR TIM5RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR TIM6RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR TIM7RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR UART4RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR UART5RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR USART2RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR USART3RST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR USBRST LL_APB1_GRP1_ForceReset\n
- * APB1RSTR WWDGRST LL_APB1_GRP1_ForceReset
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_APB1_GRP1_PERIPH_ALL
- * @arg @ref LL_APB1_GRP1_PERIPH_BKP
- * @arg @ref LL_APB1_GRP1_PERIPH_CAN1 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_CAN2 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_DAC1 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_I2C1
- * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_PWR
- * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM12 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM13 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM2
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM3
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM4 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM5 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_UART4 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_UART5 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_USART2
- * @arg @ref LL_APB1_GRP1_PERIPH_USART3 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_USB (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_WWDG
- *
- * (*) value not defined in all devices.
- * @retval None
-*/
-__STATIC_INLINE void LL_APB1_GRP1_ForceReset(uint32_t Periphs)
-{
- SET_BIT(RCC->APB1RSTR, Periphs);
-}
-
-/**
- * @brief Release APB1 peripherals reset.
- * @rmtoll APB1RSTR BKPRST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR CAN1RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR CAN2RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR CECRST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR DACRST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR I2C1RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR I2C2RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR PWRRST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR SPI2RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR SPI3RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR TIM12RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR TIM13RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR TIM14RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR TIM2RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR TIM3RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR TIM4RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR TIM5RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR TIM6RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR TIM7RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR UART4RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR UART5RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR USART2RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR USART3RST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR USBRST LL_APB1_GRP1_ReleaseReset\n
- * APB1RSTR WWDGRST LL_APB1_GRP1_ReleaseReset
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_APB1_GRP1_PERIPH_ALL
- * @arg @ref LL_APB1_GRP1_PERIPH_BKP
- * @arg @ref LL_APB1_GRP1_PERIPH_CAN1 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_CAN2 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_DAC1 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_I2C1
- * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_PWR
- * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM12 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM13 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM2
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM3
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM4 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM5 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_UART4 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_UART5 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_USART2
- * @arg @ref LL_APB1_GRP1_PERIPH_USART3 (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_USB (*)
- * @arg @ref LL_APB1_GRP1_PERIPH_WWDG
- *
- * (*) value not defined in all devices.
- * @retval None
-*/
-__STATIC_INLINE void LL_APB1_GRP1_ReleaseReset(uint32_t Periphs)
-{
- CLEAR_BIT(RCC->APB1RSTR, Periphs);
-}
-
-/**
- * @}
- */
-
-/** @defgroup BUS_LL_EF_APB2 APB2
- * @{
- */
-
-/**
- * @brief Enable APB2 peripherals clock.
- * @rmtoll APB2ENR ADC1EN LL_APB2_GRP1_EnableClock\n
- * APB2ENR ADC2EN LL_APB2_GRP1_EnableClock\n
- * APB2ENR ADC3EN LL_APB2_GRP1_EnableClock\n
- * APB2ENR AFIOEN LL_APB2_GRP1_EnableClock\n
- * APB2ENR IOPAEN LL_APB2_GRP1_EnableClock\n
- * APB2ENR IOPBEN LL_APB2_GRP1_EnableClock\n
- * APB2ENR IOPCEN LL_APB2_GRP1_EnableClock\n
- * APB2ENR IOPDEN LL_APB2_GRP1_EnableClock\n
- * APB2ENR IOPEEN LL_APB2_GRP1_EnableClock\n
- * APB2ENR IOPFEN LL_APB2_GRP1_EnableClock\n
- * APB2ENR IOPGEN LL_APB2_GRP1_EnableClock\n
- * APB2ENR SPI1EN LL_APB2_GRP1_EnableClock\n
- * APB2ENR TIM10EN LL_APB2_GRP1_EnableClock\n
- * APB2ENR TIM11EN LL_APB2_GRP1_EnableClock\n
- * APB2ENR TIM15EN LL_APB2_GRP1_EnableClock\n
- * APB2ENR TIM16EN LL_APB2_GRP1_EnableClock\n
- * APB2ENR TIM17EN LL_APB2_GRP1_EnableClock\n
- * APB2ENR TIM1EN LL_APB2_GRP1_EnableClock\n
- * APB2ENR TIM8EN LL_APB2_GRP1_EnableClock\n
- * APB2ENR TIM9EN LL_APB2_GRP1_EnableClock\n
- * APB2ENR USART1EN LL_APB2_GRP1_EnableClock
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_APB2_GRP1_PERIPH_ADC1
- * @arg @ref LL_APB2_GRP1_PERIPH_ADC2 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_ADC3 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_AFIO
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOA
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOB
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOC
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOD
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOE (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOF (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOG (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_SPI1
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM10 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM11 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM15 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM16 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM17 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM1
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM8 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM9 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_USART1
- *
- * (*) value not defined in all devices.
- * @retval None
-*/
-__STATIC_INLINE void LL_APB2_GRP1_EnableClock(uint32_t Periphs)
-{
- __IO uint32_t tmpreg;
- SET_BIT(RCC->APB2ENR, Periphs);
- /* Delay after an RCC peripheral clock enabling */
- tmpreg = READ_BIT(RCC->APB2ENR, Periphs);
- (void)tmpreg;
-}
-
-/**
- * @brief Check if APB2 peripheral clock is enabled or not
- * @rmtoll APB2ENR ADC1EN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR ADC2EN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR ADC3EN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR AFIOEN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR IOPAEN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR IOPBEN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR IOPCEN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR IOPDEN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR IOPEEN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR IOPFEN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR IOPGEN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR SPI1EN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR TIM10EN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR TIM11EN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR TIM15EN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR TIM16EN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR TIM17EN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR TIM1EN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR TIM8EN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR TIM9EN LL_APB2_GRP1_IsEnabledClock\n
- * APB2ENR USART1EN LL_APB2_GRP1_IsEnabledClock
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_APB2_GRP1_PERIPH_ADC1
- * @arg @ref LL_APB2_GRP1_PERIPH_ADC2 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_ADC3 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_AFIO
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOA
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOB
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOC
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOD
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOE (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOF (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOG (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_SPI1
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM10 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM11 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM15 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM16 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM17 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM1
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM8 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM9 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_USART1
- *
- * (*) value not defined in all devices.
- * @retval State of Periphs (1 or 0).
-*/
-__STATIC_INLINE uint32_t LL_APB2_GRP1_IsEnabledClock(uint32_t Periphs)
-{
- return (READ_BIT(RCC->APB2ENR, Periphs) == Periphs);
-}
-
-/**
- * @brief Disable APB2 peripherals clock.
- * @rmtoll APB2ENR ADC1EN LL_APB2_GRP1_DisableClock\n
- * APB2ENR ADC2EN LL_APB2_GRP1_DisableClock\n
- * APB2ENR ADC3EN LL_APB2_GRP1_DisableClock\n
- * APB2ENR AFIOEN LL_APB2_GRP1_DisableClock\n
- * APB2ENR IOPAEN LL_APB2_GRP1_DisableClock\n
- * APB2ENR IOPBEN LL_APB2_GRP1_DisableClock\n
- * APB2ENR IOPCEN LL_APB2_GRP1_DisableClock\n
- * APB2ENR IOPDEN LL_APB2_GRP1_DisableClock\n
- * APB2ENR IOPEEN LL_APB2_GRP1_DisableClock\n
- * APB2ENR IOPFEN LL_APB2_GRP1_DisableClock\n
- * APB2ENR IOPGEN LL_APB2_GRP1_DisableClock\n
- * APB2ENR SPI1EN LL_APB2_GRP1_DisableClock\n
- * APB2ENR TIM10EN LL_APB2_GRP1_DisableClock\n
- * APB2ENR TIM11EN LL_APB2_GRP1_DisableClock\n
- * APB2ENR TIM15EN LL_APB2_GRP1_DisableClock\n
- * APB2ENR TIM16EN LL_APB2_GRP1_DisableClock\n
- * APB2ENR TIM17EN LL_APB2_GRP1_DisableClock\n
- * APB2ENR TIM1EN LL_APB2_GRP1_DisableClock\n
- * APB2ENR TIM8EN LL_APB2_GRP1_DisableClock\n
- * APB2ENR TIM9EN LL_APB2_GRP1_DisableClock\n
- * APB2ENR USART1EN LL_APB2_GRP1_DisableClock
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_APB2_GRP1_PERIPH_ADC1
- * @arg @ref LL_APB2_GRP1_PERIPH_ADC2 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_ADC3 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_AFIO
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOA
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOB
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOC
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOD
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOE (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOF (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOG (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_SPI1
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM10 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM11 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM15 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM16 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM17 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM1
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM8 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM9 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_USART1
- *
- * (*) value not defined in all devices.
- * @retval None
-*/
-__STATIC_INLINE void LL_APB2_GRP1_DisableClock(uint32_t Periphs)
-{
- CLEAR_BIT(RCC->APB2ENR, Periphs);
-}
-
-/**
- * @brief Force APB2 peripherals reset.
- * @rmtoll APB2RSTR ADC1RST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR ADC2RST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR ADC3RST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR AFIORST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR IOPARST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR IOPBRST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR IOPCRST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR IOPDRST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR IOPERST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR IOPFRST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR IOPGRST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR SPI1RST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR TIM10RST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR TIM11RST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR TIM15RST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR TIM16RST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR TIM17RST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR TIM1RST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR TIM8RST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR TIM9RST LL_APB2_GRP1_ForceReset\n
- * APB2RSTR USART1RST LL_APB2_GRP1_ForceReset
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_APB2_GRP1_PERIPH_ALL
- * @arg @ref LL_APB2_GRP1_PERIPH_ADC1
- * @arg @ref LL_APB2_GRP1_PERIPH_ADC2 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_ADC3 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_AFIO
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOA
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOB
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOC
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOD
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOE (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOF (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOG (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_SPI1
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM10 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM11 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM15 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM16 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM17 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM1
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM8 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM9 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_USART1
- *
- * (*) value not defined in all devices.
- * @retval None
-*/
-__STATIC_INLINE void LL_APB2_GRP1_ForceReset(uint32_t Periphs)
-{
- SET_BIT(RCC->APB2RSTR, Periphs);
-}
-
-/**
- * @brief Release APB2 peripherals reset.
- * @rmtoll APB2RSTR ADC1RST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR ADC2RST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR ADC3RST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR AFIORST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR IOPARST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR IOPBRST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR IOPCRST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR IOPDRST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR IOPERST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR IOPFRST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR IOPGRST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR SPI1RST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR TIM10RST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR TIM11RST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR TIM15RST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR TIM16RST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR TIM17RST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR TIM1RST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR TIM8RST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR TIM9RST LL_APB2_GRP1_ReleaseReset\n
- * APB2RSTR USART1RST LL_APB2_GRP1_ReleaseReset
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_APB2_GRP1_PERIPH_ALL
- * @arg @ref LL_APB2_GRP1_PERIPH_ADC1
- * @arg @ref LL_APB2_GRP1_PERIPH_ADC2 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_ADC3 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_AFIO
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOA
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOB
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOC
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOD
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOE (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOF (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_GPIOG (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_SPI1
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM10 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM11 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM15 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM16 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM17 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM1
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM8 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_TIM9 (*)
- * @arg @ref LL_APB2_GRP1_PERIPH_USART1
- *
- * (*) value not defined in all devices.
- * @retval None
-*/
-__STATIC_INLINE void LL_APB2_GRP1_ReleaseReset(uint32_t Periphs)
-{
- CLEAR_BIT(RCC->APB2RSTR, Periphs);
-}
-
-/**
- * @}
- */
-
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* defined(RCC) */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_LL_BUS_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_cortex.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_cortex.h
deleted file mode 100644
index 50604aa..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_cortex.h
+++ /dev/null
@@ -1,656 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_cortex.h
- * @author MCD Application Team
- * @brief Header file of CORTEX LL module.
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- The LL CORTEX driver contains a set of generic APIs that can be
- used by user:
- (+) SYSTICK configuration used by @ref LL_mDelay and @ref LL_Init1msTick
- functions
- (+) Low power mode configuration (SCB register of Cortex-MCU)
- (+) MPU API to configure and enable regions
- (MPU services provided only on some devices)
- (+) API to access to MCU info (CPUID register)
- (+) API to enable fault handler (SHCSR accesses)
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_LL_CORTEX_H
-#define __STM32F1xx_LL_CORTEX_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx.h"
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-/** @defgroup CORTEX_LL CORTEX
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-
-/* Private constants ---------------------------------------------------------*/
-
-/* Private macros ------------------------------------------------------------*/
-
-/* Exported types ------------------------------------------------------------*/
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup CORTEX_LL_Exported_Constants CORTEX Exported Constants
- * @{
- */
-
-/** @defgroup CORTEX_LL_EC_CLKSOURCE_HCLK SYSTICK Clock Source
- * @{
- */
-#define LL_SYSTICK_CLKSOURCE_HCLK_DIV8 0x00000000U /*!< AHB clock divided by 8 selected as SysTick clock source.*/
-#define LL_SYSTICK_CLKSOURCE_HCLK SysTick_CTRL_CLKSOURCE_Msk /*!< AHB clock selected as SysTick clock source. */
-/**
- * @}
- */
-
-/** @defgroup CORTEX_LL_EC_FAULT Handler Fault type
- * @{
- */
-#define LL_HANDLER_FAULT_USG SCB_SHCSR_USGFAULTENA_Msk /*!< Usage fault */
-#define LL_HANDLER_FAULT_BUS SCB_SHCSR_BUSFAULTENA_Msk /*!< Bus fault */
-#define LL_HANDLER_FAULT_MEM SCB_SHCSR_MEMFAULTENA_Msk /*!< Memory management fault */
-/**
- * @}
- */
-
-#if __MPU_PRESENT
-
-/** @defgroup CORTEX_LL_EC_CTRL_HFNMI_PRIVDEF MPU Control
- * @{
- */
-#define LL_MPU_CTRL_HFNMI_PRIVDEF_NONE 0x00000000U /*!< Disable NMI and privileged SW access */
-#define LL_MPU_CTRL_HARDFAULT_NMI MPU_CTRL_HFNMIENA_Msk /*!< Enables the operation of MPU during hard fault, NMI, and FAULTMASK handlers */
-#define LL_MPU_CTRL_PRIVILEGED_DEFAULT MPU_CTRL_PRIVDEFENA_Msk /*!< Enable privileged software access to default memory map */
-#define LL_MPU_CTRL_HFNMI_PRIVDEF (MPU_CTRL_HFNMIENA_Msk | MPU_CTRL_PRIVDEFENA_Msk) /*!< Enable NMI and privileged SW access */
-/**
- * @}
- */
-
-/** @defgroup CORTEX_LL_EC_REGION MPU Region Number
- * @{
- */
-#define LL_MPU_REGION_NUMBER0 0x00U /*!< REGION Number 0 */
-#define LL_MPU_REGION_NUMBER1 0x01U /*!< REGION Number 1 */
-#define LL_MPU_REGION_NUMBER2 0x02U /*!< REGION Number 2 */
-#define LL_MPU_REGION_NUMBER3 0x03U /*!< REGION Number 3 */
-#define LL_MPU_REGION_NUMBER4 0x04U /*!< REGION Number 4 */
-#define LL_MPU_REGION_NUMBER5 0x05U /*!< REGION Number 5 */
-#define LL_MPU_REGION_NUMBER6 0x06U /*!< REGION Number 6 */
-#define LL_MPU_REGION_NUMBER7 0x07U /*!< REGION Number 7 */
-/**
- * @}
- */
-
-/** @defgroup CORTEX_LL_EC_REGION_SIZE MPU Region Size
- * @{
- */
-#define LL_MPU_REGION_SIZE_32B (0x04U << MPU_RASR_SIZE_Pos) /*!< 32B Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_64B (0x05U << MPU_RASR_SIZE_Pos) /*!< 64B Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_128B (0x06U << MPU_RASR_SIZE_Pos) /*!< 128B Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_256B (0x07U << MPU_RASR_SIZE_Pos) /*!< 256B Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_512B (0x08U << MPU_RASR_SIZE_Pos) /*!< 512B Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_1KB (0x09U << MPU_RASR_SIZE_Pos) /*!< 1KB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_2KB (0x0AU << MPU_RASR_SIZE_Pos) /*!< 2KB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_4KB (0x0BU << MPU_RASR_SIZE_Pos) /*!< 4KB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_8KB (0x0CU << MPU_RASR_SIZE_Pos) /*!< 8KB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_16KB (0x0DU << MPU_RASR_SIZE_Pos) /*!< 16KB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_32KB (0x0EU << MPU_RASR_SIZE_Pos) /*!< 32KB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_64KB (0x0FU << MPU_RASR_SIZE_Pos) /*!< 64KB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_128KB (0x10U << MPU_RASR_SIZE_Pos) /*!< 128KB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_256KB (0x11U << MPU_RASR_SIZE_Pos) /*!< 256KB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_512KB (0x12U << MPU_RASR_SIZE_Pos) /*!< 512KB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_1MB (0x13U << MPU_RASR_SIZE_Pos) /*!< 1MB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_2MB (0x14U << MPU_RASR_SIZE_Pos) /*!< 2MB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_4MB (0x15U << MPU_RASR_SIZE_Pos) /*!< 4MB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_8MB (0x16U << MPU_RASR_SIZE_Pos) /*!< 8MB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_16MB (0x17U << MPU_RASR_SIZE_Pos) /*!< 16MB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_32MB (0x18U << MPU_RASR_SIZE_Pos) /*!< 32MB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_64MB (0x19U << MPU_RASR_SIZE_Pos) /*!< 64MB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_128MB (0x1AU << MPU_RASR_SIZE_Pos) /*!< 128MB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_256MB (0x1BU << MPU_RASR_SIZE_Pos) /*!< 256MB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_512MB (0x1CU << MPU_RASR_SIZE_Pos) /*!< 512MB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_1GB (0x1DU << MPU_RASR_SIZE_Pos) /*!< 1GB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_2GB (0x1EU << MPU_RASR_SIZE_Pos) /*!< 2GB Size of the MPU protection region */
-#define LL_MPU_REGION_SIZE_4GB (0x1FU << MPU_RASR_SIZE_Pos) /*!< 4GB Size of the MPU protection region */
-/**
- * @}
- */
-
-/** @defgroup CORTEX_LL_EC_REGION_PRIVILEDGES MPU Region Privileges
- * @{
- */
-#define LL_MPU_REGION_NO_ACCESS (0x00U << MPU_RASR_AP_Pos) /*!< No access*/
-#define LL_MPU_REGION_PRIV_RW (0x01U << MPU_RASR_AP_Pos) /*!< RW privileged (privileged access only)*/
-#define LL_MPU_REGION_PRIV_RW_URO (0x02U << MPU_RASR_AP_Pos) /*!< RW privileged - RO user (Write in a user program generates a fault) */
-#define LL_MPU_REGION_FULL_ACCESS (0x03U << MPU_RASR_AP_Pos) /*!< RW privileged & user (Full access) */
-#define LL_MPU_REGION_PRIV_RO (0x05U << MPU_RASR_AP_Pos) /*!< RO privileged (privileged read only)*/
-#define LL_MPU_REGION_PRIV_RO_URO (0x06U << MPU_RASR_AP_Pos) /*!< RO privileged & user (read only) */
-/**
- * @}
- */
-
-/** @defgroup CORTEX_LL_EC_TEX MPU TEX Level
- * @{
- */
-#define LL_MPU_TEX_LEVEL0 (0x00U << MPU_RASR_TEX_Pos) /*!< b000 for TEX bits */
-#define LL_MPU_TEX_LEVEL1 (0x01U << MPU_RASR_TEX_Pos) /*!< b001 for TEX bits */
-#define LL_MPU_TEX_LEVEL2 (0x02U << MPU_RASR_TEX_Pos) /*!< b010 for TEX bits */
-#define LL_MPU_TEX_LEVEL4 (0x04U << MPU_RASR_TEX_Pos) /*!< b100 for TEX bits */
-/**
- * @}
- */
-
-/** @defgroup CORTEX_LL_EC_INSTRUCTION_ACCESS MPU Instruction Access
- * @{
- */
-#define LL_MPU_INSTRUCTION_ACCESS_ENABLE 0x00U /*!< Instruction fetches enabled */
-#define LL_MPU_INSTRUCTION_ACCESS_DISABLE MPU_RASR_XN_Msk /*!< Instruction fetches disabled*/
-/**
- * @}
- */
-
-/** @defgroup CORTEX_LL_EC_SHAREABLE_ACCESS MPU Shareable Access
- * @{
- */
-#define LL_MPU_ACCESS_SHAREABLE MPU_RASR_S_Msk /*!< Shareable memory attribute */
-#define LL_MPU_ACCESS_NOT_SHAREABLE 0x00U /*!< Not Shareable memory attribute */
-/**
- * @}
- */
-
-/** @defgroup CORTEX_LL_EC_CACHEABLE_ACCESS MPU Cacheable Access
- * @{
- */
-#define LL_MPU_ACCESS_CACHEABLE MPU_RASR_C_Msk /*!< Cacheable memory attribute */
-#define LL_MPU_ACCESS_NOT_CACHEABLE 0x00U /*!< Not Cacheable memory attribute */
-/**
- * @}
- */
-
-/** @defgroup CORTEX_LL_EC_BUFFERABLE_ACCESS MPU Bufferable Access
- * @{
- */
-#define LL_MPU_ACCESS_BUFFERABLE MPU_RASR_B_Msk /*!< Bufferable memory attribute */
-#define LL_MPU_ACCESS_NOT_BUFFERABLE 0x00U /*!< Not Bufferable memory attribute */
-/**
- * @}
- */
-#endif /* __MPU_PRESENT */
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup CORTEX_LL_Exported_Functions CORTEX Exported Functions
- * @{
- */
-
-/** @defgroup CORTEX_LL_EF_SYSTICK SYSTICK
- * @{
- */
-
-/**
- * @brief This function checks if the Systick counter flag is active or not.
- * @note It can be used in timeout function on application side.
- * @rmtoll STK_CTRL COUNTFLAG LL_SYSTICK_IsActiveCounterFlag
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_SYSTICK_IsActiveCounterFlag(void)
-{
- return ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == (SysTick_CTRL_COUNTFLAG_Msk));
-}
-
-/**
- * @brief Configures the SysTick clock source
- * @rmtoll STK_CTRL CLKSOURCE LL_SYSTICK_SetClkSource
- * @param Source This parameter can be one of the following values:
- * @arg @ref LL_SYSTICK_CLKSOURCE_HCLK_DIV8
- * @arg @ref LL_SYSTICK_CLKSOURCE_HCLK
- * @retval None
- */
-__STATIC_INLINE void LL_SYSTICK_SetClkSource(uint32_t Source)
-{
- if (Source == LL_SYSTICK_CLKSOURCE_HCLK)
- {
- SET_BIT(SysTick->CTRL, LL_SYSTICK_CLKSOURCE_HCLK);
- }
- else
- {
- CLEAR_BIT(SysTick->CTRL, LL_SYSTICK_CLKSOURCE_HCLK);
- }
-}
-
-/**
- * @brief Get the SysTick clock source
- * @rmtoll STK_CTRL CLKSOURCE LL_SYSTICK_GetClkSource
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_SYSTICK_CLKSOURCE_HCLK_DIV8
- * @arg @ref LL_SYSTICK_CLKSOURCE_HCLK
- */
-__STATIC_INLINE uint32_t LL_SYSTICK_GetClkSource(void)
-{
- return READ_BIT(SysTick->CTRL, LL_SYSTICK_CLKSOURCE_HCLK);
-}
-
-/**
- * @brief Enable SysTick exception request
- * @rmtoll STK_CTRL TICKINT LL_SYSTICK_EnableIT
- * @retval None
- */
-__STATIC_INLINE void LL_SYSTICK_EnableIT(void)
-{
- SET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
-}
-
-/**
- * @brief Disable SysTick exception request
- * @rmtoll STK_CTRL TICKINT LL_SYSTICK_DisableIT
- * @retval None
- */
-__STATIC_INLINE void LL_SYSTICK_DisableIT(void)
-{
- CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
-}
-
-/**
- * @brief Checks if the SYSTICK interrupt is enabled or disabled.
- * @rmtoll STK_CTRL TICKINT LL_SYSTICK_IsEnabledIT
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_SYSTICK_IsEnabledIT(void)
-{
- return (READ_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk) == (SysTick_CTRL_TICKINT_Msk));
-}
-
-/**
- * @}
- */
-
-/** @defgroup CORTEX_LL_EF_LOW_POWER_MODE LOW POWER MODE
- * @{
- */
-
-/**
- * @brief Processor uses sleep as its low power mode
- * @rmtoll SCB_SCR SLEEPDEEP LL_LPM_EnableSleep
- * @retval None
- */
-__STATIC_INLINE void LL_LPM_EnableSleep(void)
-{
- /* Clear SLEEPDEEP bit of Cortex System Control Register */
- CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
-}
-
-/**
- * @brief Processor uses deep sleep as its low power mode
- * @rmtoll SCB_SCR SLEEPDEEP LL_LPM_EnableDeepSleep
- * @retval None
- */
-__STATIC_INLINE void LL_LPM_EnableDeepSleep(void)
-{
- /* Set SLEEPDEEP bit of Cortex System Control Register */
- SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
-}
-
-/**
- * @brief Configures sleep-on-exit when returning from Handler mode to Thread mode.
- * @note Setting this bit to 1 enables an interrupt-driven application to avoid returning to an
- * empty main application.
- * @rmtoll SCB_SCR SLEEPONEXIT LL_LPM_EnableSleepOnExit
- * @retval None
- */
-__STATIC_INLINE void LL_LPM_EnableSleepOnExit(void)
-{
- /* Set SLEEPONEXIT bit of Cortex System Control Register */
- SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
-}
-
-/**
- * @brief Do not sleep when returning to Thread mode.
- * @rmtoll SCB_SCR SLEEPONEXIT LL_LPM_DisableSleepOnExit
- * @retval None
- */
-__STATIC_INLINE void LL_LPM_DisableSleepOnExit(void)
-{
- /* Clear SLEEPONEXIT bit of Cortex System Control Register */
- CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
-}
-
-/**
- * @brief Enabled events and all interrupts, including disabled interrupts, can wakeup the
- * processor.
- * @rmtoll SCB_SCR SEVEONPEND LL_LPM_EnableEventOnPend
- * @retval None
- */
-__STATIC_INLINE void LL_LPM_EnableEventOnPend(void)
-{
- /* Set SEVEONPEND bit of Cortex System Control Register */
- SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
-}
-
-/**
- * @brief Only enabled interrupts or events can wakeup the processor, disabled interrupts are
- * excluded
- * @rmtoll SCB_SCR SEVEONPEND LL_LPM_DisableEventOnPend
- * @retval None
- */
-__STATIC_INLINE void LL_LPM_DisableEventOnPend(void)
-{
- /* Clear SEVEONPEND bit of Cortex System Control Register */
- CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
-}
-
-/**
- * @}
- */
-
-/** @defgroup CORTEX_LL_EF_HANDLER HANDLER
- * @{
- */
-
-/**
- * @brief Enable a fault in System handler control register (SHCSR)
- * @rmtoll SCB_SHCSR MEMFAULTENA LL_HANDLER_EnableFault
- * @param Fault This parameter can be a combination of the following values:
- * @arg @ref LL_HANDLER_FAULT_USG
- * @arg @ref LL_HANDLER_FAULT_BUS
- * @arg @ref LL_HANDLER_FAULT_MEM
- * @retval None
- */
-__STATIC_INLINE void LL_HANDLER_EnableFault(uint32_t Fault)
-{
- /* Enable the system handler fault */
- SET_BIT(SCB->SHCSR, Fault);
-}
-
-/**
- * @brief Disable a fault in System handler control register (SHCSR)
- * @rmtoll SCB_SHCSR MEMFAULTENA LL_HANDLER_DisableFault
- * @param Fault This parameter can be a combination of the following values:
- * @arg @ref LL_HANDLER_FAULT_USG
- * @arg @ref LL_HANDLER_FAULT_BUS
- * @arg @ref LL_HANDLER_FAULT_MEM
- * @retval None
- */
-__STATIC_INLINE void LL_HANDLER_DisableFault(uint32_t Fault)
-{
- /* Disable the system handler fault */
- CLEAR_BIT(SCB->SHCSR, Fault);
-}
-
-/**
- * @}
- */
-
-/** @defgroup CORTEX_LL_EF_MCU_INFO MCU INFO
- * @{
- */
-
-/**
- * @brief Get Implementer code
- * @rmtoll SCB_CPUID IMPLEMENTER LL_CPUID_GetImplementer
- * @retval Value should be equal to 0x41 for ARM
- */
-__STATIC_INLINE uint32_t LL_CPUID_GetImplementer(void)
-{
- return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_IMPLEMENTER_Msk) >> SCB_CPUID_IMPLEMENTER_Pos);
-}
-
-/**
- * @brief Get Variant number (The r value in the rnpn product revision identifier)
- * @rmtoll SCB_CPUID VARIANT LL_CPUID_GetVariant
- * @retval Value between 0 and 255 (0x1: revision 1, 0x2: revision 2)
- */
-__STATIC_INLINE uint32_t LL_CPUID_GetVariant(void)
-{
- return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_VARIANT_Msk) >> SCB_CPUID_VARIANT_Pos);
-}
-
-/**
- * @brief Get Constant number
- * @rmtoll SCB_CPUID ARCHITECTURE LL_CPUID_GetConstant
- * @retval Value should be equal to 0xF for Cortex-M3 devices
- */
-__STATIC_INLINE uint32_t LL_CPUID_GetConstant(void)
-{
- return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_ARCHITECTURE_Msk) >> SCB_CPUID_ARCHITECTURE_Pos);
-}
-
-/**
- * @brief Get Part number
- * @rmtoll SCB_CPUID PARTNO LL_CPUID_GetParNo
- * @retval Value should be equal to 0xC23 for Cortex-M3
- */
-__STATIC_INLINE uint32_t LL_CPUID_GetParNo(void)
-{
- return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_PARTNO_Msk) >> SCB_CPUID_PARTNO_Pos);
-}
-
-/**
- * @brief Get Revision number (The p value in the rnpn product revision identifier, indicates patch release)
- * @rmtoll SCB_CPUID REVISION LL_CPUID_GetRevision
- * @retval Value between 0 and 255 (0x0: patch 0, 0x1: patch 1)
- */
-__STATIC_INLINE uint32_t LL_CPUID_GetRevision(void)
-{
- return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_REVISION_Msk) >> SCB_CPUID_REVISION_Pos);
-}
-
-/**
- * @}
- */
-
-#if __MPU_PRESENT
-/** @defgroup CORTEX_LL_EF_MPU MPU
- * @{
- */
-
-/**
- * @brief Enable MPU with input options
- * @rmtoll MPU_CTRL ENABLE LL_MPU_Enable
- * @param Options This parameter can be one of the following values:
- * @arg @ref LL_MPU_CTRL_HFNMI_PRIVDEF_NONE
- * @arg @ref LL_MPU_CTRL_HARDFAULT_NMI
- * @arg @ref LL_MPU_CTRL_PRIVILEGED_DEFAULT
- * @arg @ref LL_MPU_CTRL_HFNMI_PRIVDEF
- * @retval None
- */
-__STATIC_INLINE void LL_MPU_Enable(uint32_t Options)
-{
- /* Enable the MPU*/
- WRITE_REG(MPU->CTRL, (MPU_CTRL_ENABLE_Msk | Options));
- /* Ensure MPU settings take effects */
- __DSB();
- /* Sequence instruction fetches using update settings */
- __ISB();
-}
-
-/**
- * @brief Disable MPU
- * @rmtoll MPU_CTRL ENABLE LL_MPU_Disable
- * @retval None
- */
-__STATIC_INLINE void LL_MPU_Disable(void)
-{
- /* Make sure outstanding transfers are done */
- __DMB();
- /* Disable MPU*/
- WRITE_REG(MPU->CTRL, 0U);
-}
-
-/**
- * @brief Check if MPU is enabled or not
- * @rmtoll MPU_CTRL ENABLE LL_MPU_IsEnabled
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_MPU_IsEnabled(void)
-{
- return (READ_BIT(MPU->CTRL, MPU_CTRL_ENABLE_Msk) == (MPU_CTRL_ENABLE_Msk));
-}
-
-/**
- * @brief Enable a MPU region
- * @rmtoll MPU_RASR ENABLE LL_MPU_EnableRegion
- * @param Region This parameter can be one of the following values:
- * @arg @ref LL_MPU_REGION_NUMBER0
- * @arg @ref LL_MPU_REGION_NUMBER1
- * @arg @ref LL_MPU_REGION_NUMBER2
- * @arg @ref LL_MPU_REGION_NUMBER3
- * @arg @ref LL_MPU_REGION_NUMBER4
- * @arg @ref LL_MPU_REGION_NUMBER5
- * @arg @ref LL_MPU_REGION_NUMBER6
- * @arg @ref LL_MPU_REGION_NUMBER7
- * @retval None
- */
-__STATIC_INLINE void LL_MPU_EnableRegion(uint32_t Region)
-{
- /* Set Region number */
- WRITE_REG(MPU->RNR, Region);
- /* Enable the MPU region */
- SET_BIT(MPU->RASR, MPU_RASR_ENABLE_Msk);
-}
-
-/**
- * @brief Configure and enable a region
- * @rmtoll MPU_RNR REGION LL_MPU_ConfigRegion\n
- * MPU_RBAR REGION LL_MPU_ConfigRegion\n
- * MPU_RBAR ADDR LL_MPU_ConfigRegion\n
- * MPU_RASR XN LL_MPU_ConfigRegion\n
- * MPU_RASR AP LL_MPU_ConfigRegion\n
- * MPU_RASR S LL_MPU_ConfigRegion\n
- * MPU_RASR C LL_MPU_ConfigRegion\n
- * MPU_RASR B LL_MPU_ConfigRegion\n
- * MPU_RASR SIZE LL_MPU_ConfigRegion
- * @param Region This parameter can be one of the following values:
- * @arg @ref LL_MPU_REGION_NUMBER0
- * @arg @ref LL_MPU_REGION_NUMBER1
- * @arg @ref LL_MPU_REGION_NUMBER2
- * @arg @ref LL_MPU_REGION_NUMBER3
- * @arg @ref LL_MPU_REGION_NUMBER4
- * @arg @ref LL_MPU_REGION_NUMBER5
- * @arg @ref LL_MPU_REGION_NUMBER6
- * @arg @ref LL_MPU_REGION_NUMBER7
- * @param Address Value of region base address
- * @param SubRegionDisable Sub-region disable value between Min_Data = 0x00 and Max_Data = 0xFF
- * @param Attributes This parameter can be a combination of the following values:
- * @arg @ref LL_MPU_REGION_SIZE_32B or @ref LL_MPU_REGION_SIZE_64B or @ref LL_MPU_REGION_SIZE_128B or @ref LL_MPU_REGION_SIZE_256B or @ref LL_MPU_REGION_SIZE_512B
- * or @ref LL_MPU_REGION_SIZE_1KB or @ref LL_MPU_REGION_SIZE_2KB or @ref LL_MPU_REGION_SIZE_4KB or @ref LL_MPU_REGION_SIZE_8KB or @ref LL_MPU_REGION_SIZE_16KB
- * or @ref LL_MPU_REGION_SIZE_32KB or @ref LL_MPU_REGION_SIZE_64KB or @ref LL_MPU_REGION_SIZE_128KB or @ref LL_MPU_REGION_SIZE_256KB or @ref LL_MPU_REGION_SIZE_512KB
- * or @ref LL_MPU_REGION_SIZE_1MB or @ref LL_MPU_REGION_SIZE_2MB or @ref LL_MPU_REGION_SIZE_4MB or @ref LL_MPU_REGION_SIZE_8MB or @ref LL_MPU_REGION_SIZE_16MB
- * or @ref LL_MPU_REGION_SIZE_32MB or @ref LL_MPU_REGION_SIZE_64MB or @ref LL_MPU_REGION_SIZE_128MB or @ref LL_MPU_REGION_SIZE_256MB or @ref LL_MPU_REGION_SIZE_512MB
- * or @ref LL_MPU_REGION_SIZE_1GB or @ref LL_MPU_REGION_SIZE_2GB or @ref LL_MPU_REGION_SIZE_4GB
- * @arg @ref LL_MPU_REGION_NO_ACCESS or @ref LL_MPU_REGION_PRIV_RW or @ref LL_MPU_REGION_PRIV_RW_URO or @ref LL_MPU_REGION_FULL_ACCESS
- * or @ref LL_MPU_REGION_PRIV_RO or @ref LL_MPU_REGION_PRIV_RO_URO
- * @arg @ref LL_MPU_TEX_LEVEL0 or @ref LL_MPU_TEX_LEVEL1 or @ref LL_MPU_TEX_LEVEL2 or @ref LL_MPU_TEX_LEVEL4
- * @arg @ref LL_MPU_INSTRUCTION_ACCESS_ENABLE or @ref LL_MPU_INSTRUCTION_ACCESS_DISABLE
- * @arg @ref LL_MPU_ACCESS_SHAREABLE or @ref LL_MPU_ACCESS_NOT_SHAREABLE
- * @arg @ref LL_MPU_ACCESS_CACHEABLE or @ref LL_MPU_ACCESS_NOT_CACHEABLE
- * @arg @ref LL_MPU_ACCESS_BUFFERABLE or @ref LL_MPU_ACCESS_NOT_BUFFERABLE
- * @retval None
- */
-__STATIC_INLINE void LL_MPU_ConfigRegion(uint32_t Region, uint32_t SubRegionDisable, uint32_t Address, uint32_t Attributes)
-{
- /* Set Region number */
- WRITE_REG(MPU->RNR, Region);
- /* Set base address */
- WRITE_REG(MPU->RBAR, (Address & 0xFFFFFFE0U));
- /* Configure MPU */
- WRITE_REG(MPU->RASR, (MPU_RASR_ENABLE_Msk | Attributes | SubRegionDisable << MPU_RASR_SRD_Pos));
-}
-
-/**
- * @brief Disable a region
- * @rmtoll MPU_RNR REGION LL_MPU_DisableRegion\n
- * MPU_RASR ENABLE LL_MPU_DisableRegion
- * @param Region This parameter can be one of the following values:
- * @arg @ref LL_MPU_REGION_NUMBER0
- * @arg @ref LL_MPU_REGION_NUMBER1
- * @arg @ref LL_MPU_REGION_NUMBER2
- * @arg @ref LL_MPU_REGION_NUMBER3
- * @arg @ref LL_MPU_REGION_NUMBER4
- * @arg @ref LL_MPU_REGION_NUMBER5
- * @arg @ref LL_MPU_REGION_NUMBER6
- * @arg @ref LL_MPU_REGION_NUMBER7
- * @retval None
- */
-__STATIC_INLINE void LL_MPU_DisableRegion(uint32_t Region)
-{
- /* Set Region number */
- WRITE_REG(MPU->RNR, Region);
- /* Disable the MPU region */
- CLEAR_BIT(MPU->RASR, MPU_RASR_ENABLE_Msk);
-}
-
-/**
- * @}
- */
-
-#endif /* __MPU_PRESENT */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_LL_CORTEX_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_crc.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_crc.h
deleted file mode 100644
index dafbe9d..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_crc.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_crc.h
- * @author MCD Application Team
- * @brief Header file of CRC LL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_LL_CRC_H
-#define __STM32F1xx_LL_CRC_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx.h"
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined(CRC)
-
-/** @defgroup CRC_LL CRC
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-
-/* Exported types ------------------------------------------------------------*/
-/* Exported constants --------------------------------------------------------*/
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup CRC_LL_Exported_Macros CRC Exported Macros
- * @{
- */
-
-/** @defgroup CRC_LL_EM_WRITE_READ Common Write and read registers Macros
- * @{
- */
-
-/**
- * @brief Write a value in CRC register
- * @param __INSTANCE__ CRC Instance
- * @param __REG__ Register to be written
- * @param __VALUE__ Value to be written in the register
- * @retval None
- */
-#define LL_CRC_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
-
-/**
- * @brief Read a value in CRC register
- * @param __INSTANCE__ CRC Instance
- * @param __REG__ Register to be read
- * @retval Register value
- */
-#define LL_CRC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup CRC_LL_Exported_Functions CRC Exported Functions
- * @{
- */
-
-/** @defgroup CRC_LL_EF_Configuration CRC Configuration functions
- * @{
- */
-
-/**
- * @brief Reset the CRC calculation unit.
- * @rmtoll CR RESET LL_CRC_ResetCRCCalculationUnit
- * @param CRCx CRC Instance
- * @retval None
- */
-__STATIC_INLINE void LL_CRC_ResetCRCCalculationUnit(CRC_TypeDef *CRCx)
-{
- WRITE_REG(CRCx->CR, CRC_CR_RESET);
-}
-
-/**
- * @}
- */
-
-/** @defgroup CRC_LL_EF_Data_Management Data_Management
- * @{
- */
-
-/**
- * @brief Write given 32-bit data to the CRC calculator
- * @rmtoll DR DR LL_CRC_FeedData32
- * @param CRCx CRC Instance
- * @param InData value to be provided to CRC calculator between between Min_Data=0 and Max_Data=0xFFFFFFFF
- * @retval None
- */
-__STATIC_INLINE void LL_CRC_FeedData32(CRC_TypeDef *CRCx, uint32_t InData)
-{
- WRITE_REG(CRCx->DR, InData);
-}
-
-/**
- * @brief Return current CRC calculation result. 32 bits value is returned.
- * @rmtoll DR DR LL_CRC_ReadData32
- * @param CRCx CRC Instance
- * @retval Current CRC calculation result as stored in CRC_DR register (32 bits).
- */
-__STATIC_INLINE uint32_t LL_CRC_ReadData32(CRC_TypeDef *CRCx)
-{
- return (uint32_t)(READ_REG(CRCx->DR));
-}
-
-/**
- * @brief Return data stored in the Independent Data(IDR) register.
- * @note This register can be used as a temporary storage location for one byte.
- * @rmtoll IDR IDR LL_CRC_Read_IDR
- * @param CRCx CRC Instance
- * @retval Value stored in CRC_IDR register (General-purpose 8-bit data register).
- */
-__STATIC_INLINE uint32_t LL_CRC_Read_IDR(CRC_TypeDef *CRCx)
-{
- return (uint32_t)(READ_REG(CRCx->IDR));
-}
-
-/**
- * @brief Store data in the Independent Data(IDR) register.
- * @note This register can be used as a temporary storage location for one byte.
- * @rmtoll IDR IDR LL_CRC_Write_IDR
- * @param CRCx CRC Instance
- * @param InData value to be stored in CRC_IDR register (8-bit) between between Min_Data=0 and Max_Data=0xFF
- * @retval None
- */
-__STATIC_INLINE void LL_CRC_Write_IDR(CRC_TypeDef *CRCx, uint32_t InData)
-{
- *((uint8_t __IO *)(&CRCx->IDR)) = (uint8_t) InData;
-}
-/**
- * @}
- */
-
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup CRC_LL_EF_Init Initialization and de-initialization functions
- * @{
- */
-
-ErrorStatus LL_CRC_DeInit(CRC_TypeDef *CRCx);
-
-/**
- * @}
- */
-#endif /* USE_FULL_LL_DRIVER */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* defined(CRC) */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_LL_CRC_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_dac.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_dac.h
deleted file mode 100644
index 1008ab1..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_dac.h
+++ /dev/null
@@ -1,1347 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_dac.h
- * @author MCD Application Team
- * @brief Header file of DAC LL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_LL_DAC_H
-#define __STM32F1xx_LL_DAC_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx.h"
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined (DAC)
-
-/** @defgroup DAC_LL DAC
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup DAC_LL_Private_Constants DAC Private Constants
- * @{
- */
-
-/* Internal masks for DAC channels definition */
-/* To select into literal LL_DAC_CHANNEL_x the relevant bits for: */
-/* - channel bits position into register CR */
-/* - channel bits position into register SWTRIG */
-/* - channel register offset of data holding register DHRx */
-/* - channel register offset of data output register DORx */
-#define DAC_CR_CH1_BITOFFSET 0U /* Position of channel bits into registers CR, MCR, CCR, SHHR, SHRR of channel 1 */
-#define DAC_CR_CH2_BITOFFSET 16U /* Position of channel bits into registers CR, MCR, CCR, SHHR, SHRR of channel 2 */
-#define DAC_CR_CHX_BITOFFSET_MASK (DAC_CR_CH1_BITOFFSET | DAC_CR_CH2_BITOFFSET)
-
-#define DAC_SWTR_CH1 (DAC_SWTRIGR_SWTRIG1) /* Channel bit into register SWTRIGR of channel 1. This bit is into area of LL_DAC_CR_CHx_BITOFFSET but excluded by mask DAC_CR_CHX_BITOFFSET_MASK (done to be enable to trig SW start of both DAC channels simultaneously). */
-#define DAC_SWTR_CH2 (DAC_SWTRIGR_SWTRIG2) /* Channel bit into register SWTRIGR of channel 2. This bit is into area of LL_DAC_CR_CHx_BITOFFSET but excluded by mask DAC_CR_CHX_BITOFFSET_MASK (done to be enable to trig SW start of both DAC channels simultaneously). */
-#define DAC_SWTR_CHX_MASK (DAC_SWTR_CH1 | DAC_SWTR_CH2)
-
-#define DAC_REG_DHR12R1_REGOFFSET 0x00000000U /* Register DHR12Rx channel 1 taken as reference */
-#define DAC_REG_DHR12L1_REGOFFSET 0x00100000U /* Register offset of DHR12Lx channel 1 versus DHR12Rx channel 1 (shifted left of 20 bits) */
-#define DAC_REG_DHR8R1_REGOFFSET 0x02000000U /* Register offset of DHR8Rx channel 1 versus DHR12Rx channel 1 (shifted left of 24 bits) */
-#define DAC_REG_DHR12R2_REGOFFSET 0x00030000U /* Register offset of DHR12Rx channel 2 versus DHR12Rx channel 1 (shifted left of 16 bits) */
-#define DAC_REG_DHR12L2_REGOFFSET 0x00400000U /* Register offset of DHR12Lx channel 2 versus DHR12Rx channel 1 (shifted left of 20 bits) */
-#define DAC_REG_DHR8R2_REGOFFSET 0x05000000U /* Register offset of DHR8Rx channel 2 versus DHR12Rx channel 1 (shifted left of 24 bits) */
-#define DAC_REG_DHR12RX_REGOFFSET_MASK 0x000F0000U
-#define DAC_REG_DHR12LX_REGOFFSET_MASK 0x00F00000U
-#define DAC_REG_DHR8RX_REGOFFSET_MASK 0x0F000000U
-#define DAC_REG_DHRX_REGOFFSET_MASK (DAC_REG_DHR12RX_REGOFFSET_MASK | DAC_REG_DHR12LX_REGOFFSET_MASK | DAC_REG_DHR8RX_REGOFFSET_MASK)
-
-#define DAC_REG_DOR1_REGOFFSET 0x00000000U /* Register DORx channel 1 taken as reference */
-#define DAC_REG_DOR2_REGOFFSET 0x10000000U /* Register offset of DORx channel 1 versus DORx channel 2 (shifted left of 28 bits) */
-#define DAC_REG_DORX_REGOFFSET_MASK (DAC_REG_DOR1_REGOFFSET | DAC_REG_DOR2_REGOFFSET)
-
-/* DAC registers bits positions */
-#define DAC_DHR12RD_DACC2DHR_BITOFFSET_POS 16U /* Value equivalent to POSITION_VAL(DAC_DHR12RD_DACC2DHR) */
-#define DAC_DHR12LD_DACC2DHR_BITOFFSET_POS 20U /* Value equivalent to POSITION_VAL(DAC_DHR12LD_DACC2DHR) */
-#define DAC_DHR8RD_DACC2DHR_BITOFFSET_POS 8U /* Value equivalent to POSITION_VAL(DAC_DHR8RD_DACC2DHR) */
-
-/* Miscellaneous data */
-#define DAC_DIGITAL_SCALE_12BITS 4095U /* Full-scale digital value with a resolution of 12 bits (voltage range determined by analog voltage references Vref+ and Vref-, refer to reference manual) */
-
-/**
- * @}
- */
-
-
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup DAC_LL_Private_Macros DAC Private Macros
- * @{
- */
-
-/**
- * @brief Driver macro reserved for internal use: isolate bits with the
- * selected mask and shift them to the register LSB
- * (shift mask on register position bit 0).
- * @param __BITS__ Bits in register 32 bits
- * @param __MASK__ Mask in register 32 bits
- * @retval Bits in register 32 bits
-*/
-#define __DAC_MASK_SHIFT(__BITS__, __MASK__) \
- (((__BITS__) & (__MASK__)) >> POSITION_VAL((__MASK__)))
-
-/**
- * @brief Driver macro reserved for internal use: set a pointer to
- * a register from a register basis from which an offset
- * is applied.
- * @param __REG__ Register basis from which the offset is applied.
- * @param __REG_OFFFSET__ Offset to be applied (unit: number of registers).
- * @retval Pointer to register address
-*/
-#define __DAC_PTR_REG_OFFSET(__REG__, __REG_OFFFSET__) \
- ((uint32_t *)((uint32_t) ((uint32_t)(&(__REG__)) + ((__REG_OFFFSET__) << 2U))))
-
-/**
- * @}
- */
-
-
-/* Exported types ------------------------------------------------------------*/
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup DAC_LL_ES_INIT DAC Exported Init structure
- * @{
- */
-
-/**
- * @brief Structure definition of some features of DAC instance.
- */
-typedef struct
-{
- uint32_t TriggerSource; /*!< Set the conversion trigger source for the selected DAC channel: internal (SW start) or from external IP (timer event, external interrupt line).
- This parameter can be a value of @ref DAC_LL_EC_TRIGGER_SOURCE
-
- This feature can be modified afterwards using unitary function @ref LL_DAC_SetTriggerSource(). */
-
- uint32_t WaveAutoGeneration; /*!< Set the waveform automatic generation mode for the selected DAC channel.
- This parameter can be a value of @ref DAC_LL_EC_WAVE_AUTO_GENERATION_MODE
-
- This feature can be modified afterwards using unitary function @ref LL_DAC_SetWaveAutoGeneration(). */
-
- uint32_t WaveAutoGenerationConfig; /*!< Set the waveform automatic generation mode for the selected DAC channel.
- If waveform automatic generation mode is set to noise, this parameter can be a value of @ref DAC_LL_EC_WAVE_NOISE_LFSR_UNMASK_BITS
- If waveform automatic generation mode is set to triangle, this parameter can be a value of @ref DAC_LL_EC_WAVE_TRIANGLE_AMPLITUDE
- @note If waveform automatic generation mode is disabled, this parameter is discarded.
-
- This feature can be modified afterwards using unitary function @ref LL_DAC_SetWaveNoiseLFSR() or @ref LL_DAC_SetWaveTriangleAmplitude(), depending on the wave automatic generation selected. */
-
- uint32_t OutputBuffer; /*!< Set the output buffer for the selected DAC channel.
- This parameter can be a value of @ref DAC_LL_EC_OUTPUT_BUFFER
-
- This feature can be modified afterwards using unitary function @ref LL_DAC_SetOutputBuffer(). */
-
-} LL_DAC_InitTypeDef;
-
-/**
- * @}
- */
-#endif /* USE_FULL_LL_DRIVER */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup DAC_LL_Exported_Constants DAC Exported Constants
- * @{
- */
-
-/** @defgroup DAC_LL_EC_GET_FLAG DAC flags
- * @brief Flags defines which can be used with LL_DAC_ReadReg function
- * @{
- */
-/* DAC channel 1 flags */
-#if defined(DAC_SR_DMAUDR1)
-#define LL_DAC_FLAG_DMAUDR1 (DAC_SR_DMAUDR1) /*!< DAC channel 1 flag DMA underrun */
-#endif /* DAC_SR_DMAUDR1 */
-
-/* DAC channel 2 flags */
-#if defined(DAC_SR_DMAUDR2)
-#define LL_DAC_FLAG_DMAUDR2 (DAC_SR_DMAUDR2) /*!< DAC channel 2 flag DMA underrun */
-#endif /* DAC_SR_DMAUDR2 */
-/**
- * @}
- */
-
-/** @defgroup DAC_LL_EC_IT DAC interruptions
- * @brief IT defines which can be used with LL_DAC_ReadReg and LL_DAC_WriteReg functions
- * @{
- */
-#if defined(DAC_CR_DMAUDRIE1)
-#define LL_DAC_IT_DMAUDRIE1 (DAC_CR_DMAUDRIE1) /*!< DAC channel 1 interruption DMA underrun */
-#endif /* DAC_CR_DMAUDRIE1 */
-#if defined(DAC_CR_DMAUDRIE2)
-#define LL_DAC_IT_DMAUDRIE2 (DAC_CR_DMAUDRIE2) /*!< DAC channel 2 interruption DMA underrun */
-#endif /* DAC_CR_DMAUDRIE2 */
-/**
- * @}
- */
-
-/** @defgroup DAC_LL_EC_CHANNEL DAC channels
- * @{
- */
-#define LL_DAC_CHANNEL_1 (DAC_REG_DOR1_REGOFFSET | DAC_REG_DHR12R1_REGOFFSET | DAC_REG_DHR12L1_REGOFFSET | DAC_REG_DHR8R1_REGOFFSET | DAC_CR_CH1_BITOFFSET | DAC_SWTR_CH1) /*!< DAC channel 1 */
-#define LL_DAC_CHANNEL_2 (DAC_REG_DOR2_REGOFFSET | DAC_REG_DHR12R2_REGOFFSET | DAC_REG_DHR12L2_REGOFFSET | DAC_REG_DHR8R2_REGOFFSET | DAC_CR_CH2_BITOFFSET | DAC_SWTR_CH2) /*!< DAC channel 2 */
-/**
- * @}
- */
-
-/** @defgroup DAC_LL_EC_TRIGGER_SOURCE DAC trigger source
- * @{
- */
-#define LL_DAC_TRIG_SOFTWARE (DAC_CR_TSEL1_2 | DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger internal (SW start) */
-#define LL_DAC_TRIG_EXT_TIM3_TRGO ( DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external IP: TIM3 TRGO. */
-#define LL_DAC_TRIG_EXT_TIM15_TRGO ( DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external IP: TIM15 TRGO. */
-#define LL_DAC_TRIG_EXT_TIM2_TRGO (DAC_CR_TSEL1_2 ) /*!< DAC channel conversion trigger from external IP: TIM2 TRGO. */
-#define LL_DAC_TRIG_EXT_TIM8_TRGO ( DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external IP: TIM8 TRGO. */
-#define LL_DAC_TRIG_EXT_TIM4_TRGO (DAC_CR_TSEL1_2 | DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external IP: TIM4 TRGO. */
-#define LL_DAC_TRIG_EXT_TIM6_TRGO 0x00000000U /*!< DAC channel conversion trigger from external IP: TIM6 TRGO. */
-#define LL_DAC_TRIG_EXT_TIM7_TRGO ( DAC_CR_TSEL1_1 ) /*!< DAC channel conversion trigger from external IP: TIM7 TRGO. */
-#define LL_DAC_TRIG_EXT_TIM5_TRGO ( DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external IP: TIM5 TRGO. */
-#define LL_DAC_TRIG_EXT_EXTI_LINE9 (DAC_CR_TSEL1_2 | DAC_CR_TSEL1_1 ) /*!< DAC channel conversion trigger from external IP: external interrupt line 9. */
-/**
- * @}
- */
-
-/** @defgroup DAC_LL_EC_WAVE_AUTO_GENERATION_MODE DAC waveform automatic generation mode
- * @{
- */
-#define LL_DAC_WAVE_AUTO_GENERATION_NONE 0x00000000U /*!< DAC channel wave auto generation mode disabled. */
-#define LL_DAC_WAVE_AUTO_GENERATION_NOISE (DAC_CR_WAVE1_0) /*!< DAC channel wave auto generation mode enabled, set generated noise waveform. */
-#define LL_DAC_WAVE_AUTO_GENERATION_TRIANGLE (DAC_CR_WAVE1_1) /*!< DAC channel wave auto generation mode enabled, set generated triangle waveform. */
-/**
- * @}
- */
-
-/** @defgroup DAC_LL_EC_WAVE_NOISE_LFSR_UNMASK_BITS DAC wave generation - Noise LFSR unmask bits
- * @{
- */
-#define LL_DAC_NOISE_LFSR_UNMASK_BIT0 0x00000000U /*!< Noise wave generation, unmask LFSR bit0, for the selected DAC channel */
-#define LL_DAC_NOISE_LFSR_UNMASK_BITS1_0 ( DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[1:0], for the selected DAC channel */
-#define LL_DAC_NOISE_LFSR_UNMASK_BITS2_0 ( DAC_CR_MAMP1_1 ) /*!< Noise wave generation, unmask LFSR bits[2:0], for the selected DAC channel */
-#define LL_DAC_NOISE_LFSR_UNMASK_BITS3_0 ( DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[3:0], for the selected DAC channel */
-#define LL_DAC_NOISE_LFSR_UNMASK_BITS4_0 ( DAC_CR_MAMP1_2 ) /*!< Noise wave generation, unmask LFSR bits[4:0], for the selected DAC channel */
-#define LL_DAC_NOISE_LFSR_UNMASK_BITS5_0 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[5:0], for the selected DAC channel */
-#define LL_DAC_NOISE_LFSR_UNMASK_BITS6_0 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 ) /*!< Noise wave generation, unmask LFSR bits[6:0], for the selected DAC channel */
-#define LL_DAC_NOISE_LFSR_UNMASK_BITS7_0 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[7:0], for the selected DAC channel */
-#define LL_DAC_NOISE_LFSR_UNMASK_BITS8_0 (DAC_CR_MAMP1_3 ) /*!< Noise wave generation, unmask LFSR bits[8:0], for the selected DAC channel */
-#define LL_DAC_NOISE_LFSR_UNMASK_BITS9_0 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[9:0], for the selected DAC channel */
-#define LL_DAC_NOISE_LFSR_UNMASK_BITS10_0 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 ) /*!< Noise wave generation, unmask LFSR bits[10:0], for the selected DAC channel */
-#define LL_DAC_NOISE_LFSR_UNMASK_BITS11_0 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[11:0], for the selected DAC channel */
-/**
- * @}
- */
-
-/** @defgroup DAC_LL_EC_WAVE_TRIANGLE_AMPLITUDE DAC wave generation - Triangle amplitude
- * @{
- */
-#define LL_DAC_TRIANGLE_AMPLITUDE_1 0x00000000U /*!< Triangle wave generation, amplitude of 1 LSB of DAC output range, for the selected DAC channel */
-#define LL_DAC_TRIANGLE_AMPLITUDE_3 ( DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 3 LSB of DAC output range, for the selected DAC channel */
-#define LL_DAC_TRIANGLE_AMPLITUDE_7 ( DAC_CR_MAMP1_1 ) /*!< Triangle wave generation, amplitude of 7 LSB of DAC output range, for the selected DAC channel */
-#define LL_DAC_TRIANGLE_AMPLITUDE_15 ( DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 15 LSB of DAC output range, for the selected DAC channel */
-#define LL_DAC_TRIANGLE_AMPLITUDE_31 ( DAC_CR_MAMP1_2 ) /*!< Triangle wave generation, amplitude of 31 LSB of DAC output range, for the selected DAC channel */
-#define LL_DAC_TRIANGLE_AMPLITUDE_63 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 63 LSB of DAC output range, for the selected DAC channel */
-#define LL_DAC_TRIANGLE_AMPLITUDE_127 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 ) /*!< Triangle wave generation, amplitude of 127 LSB of DAC output range, for the selected DAC channel */
-#define LL_DAC_TRIANGLE_AMPLITUDE_255 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 255 LSB of DAC output range, for the selected DAC channel */
-#define LL_DAC_TRIANGLE_AMPLITUDE_511 (DAC_CR_MAMP1_3 ) /*!< Triangle wave generation, amplitude of 512 LSB of DAC output range, for the selected DAC channel */
-#define LL_DAC_TRIANGLE_AMPLITUDE_1023 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 1023 LSB of DAC output range, for the selected DAC channel */
-#define LL_DAC_TRIANGLE_AMPLITUDE_2047 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 ) /*!< Triangle wave generation, amplitude of 2047 LSB of DAC output range, for the selected DAC channel */
-#define LL_DAC_TRIANGLE_AMPLITUDE_4095 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 4095 LSB of DAC output range, for the selected DAC channel */
-/**
- * @}
- */
-
-/** @defgroup DAC_LL_EC_OUTPUT_BUFFER DAC channel output buffer
- * @{
- */
-#define LL_DAC_OUTPUT_BUFFER_ENABLE 0x00000000U /*!< The selected DAC channel output is buffered: higher drive current capability, but also higher current consumption */
-#define LL_DAC_OUTPUT_BUFFER_DISABLE (DAC_CR_BOFF1) /*!< The selected DAC channel output is not buffered: lower drive current capability, but also lower current consumption */
-/**
- * @}
- */
-
-
-/** @defgroup DAC_LL_EC_RESOLUTION DAC channel output resolution
- * @{
- */
-#define LL_DAC_RESOLUTION_12B 0x00000000U /*!< DAC channel resolution 12 bits */
-#define LL_DAC_RESOLUTION_8B 0x00000002U /*!< DAC channel resolution 8 bits */
-/**
- * @}
- */
-
-/** @defgroup DAC_LL_EC_REGISTERS DAC registers compliant with specific purpose
- * @{
- */
-/* List of DAC registers intended to be used (most commonly) with */
-/* DMA transfer. */
-/* Refer to function @ref LL_DAC_DMA_GetRegAddr(). */
-#define LL_DAC_DMA_REG_DATA_12BITS_RIGHT_ALIGNED DAC_REG_DHR12RX_REGOFFSET_MASK /*!< DAC channel data holding register 12 bits right aligned */
-#define LL_DAC_DMA_REG_DATA_12BITS_LEFT_ALIGNED DAC_REG_DHR12LX_REGOFFSET_MASK /*!< DAC channel data holding register 12 bits left aligned */
-#define LL_DAC_DMA_REG_DATA_8BITS_RIGHT_ALIGNED DAC_REG_DHR8RX_REGOFFSET_MASK /*!< DAC channel data holding register 8 bits right aligned */
-/**
- * @}
- */
-
-/** @defgroup DAC_LL_EC_HW_DELAYS Definitions of DAC hardware constraints delays
- * @note Only DAC IP HW delays are defined in DAC LL driver driver,
- * not timeout values.
- * For details on delays values, refer to descriptions in source code
- * above each literal definition.
- * @{
- */
-
-/* Delay for DAC channel voltage settling time from DAC channel startup */
-/* (transition from disable to enable). */
-/* Note: DAC channel startup time depends on board application environment: */
-/* impedance connected to DAC channel output. */
-/* The delay below is specified under conditions: */
-/* - voltage maximum transition (lowest to highest value) */
-/* - until voltage reaches final value +-1LSB */
-/* - DAC channel output buffer enabled */
-/* - load impedance of 5kOhm (min), 50pF (max) */
-/* Literal set to maximum value (refer to device datasheet, */
-/* parameter "tWAKEUP"). */
-/* Unit: us */
-#define LL_DAC_DELAY_STARTUP_VOLTAGE_SETTLING_US 15U /*!< Delay for DAC channel voltage settling time from DAC channel startup (transition from disable to enable) */
-
-/* Delay for DAC channel voltage settling time. */
-/* Note: DAC channel startup time depends on board application environment: */
-/* impedance connected to DAC channel output. */
-/* The delay below is specified under conditions: */
-/* - voltage maximum transition (lowest to highest value) */
-/* - until voltage reaches final value +-1LSB */
-/* - DAC channel output buffer enabled */
-/* - load impedance of 5kOhm min, 50pF max */
-/* Literal set to maximum value (refer to device datasheet, */
-/* parameter "tSETTLING"). */
-/* Unit: us */
-#define LL_DAC_DELAY_VOLTAGE_SETTLING_US 12U /*!< Delay for DAC channel voltage settling time */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup DAC_LL_Exported_Macros DAC Exported Macros
- * @{
- */
-
-/** @defgroup DAC_LL_EM_WRITE_READ Common write and read registers macros
- * @{
- */
-
-/**
- * @brief Write a value in DAC register
- * @param __INSTANCE__ DAC Instance
- * @param __REG__ Register to be written
- * @param __VALUE__ Value to be written in the register
- * @retval None
- */
-#define LL_DAC_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
-
-/**
- * @brief Read a value in DAC register
- * @param __INSTANCE__ DAC Instance
- * @param __REG__ Register to be read
- * @retval Register value
- */
-#define LL_DAC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
-
-/**
- * @}
- */
-
-/** @defgroup DAC_LL_EM_HELPER_MACRO DAC helper macro
- * @{
- */
-
-/**
- * @brief Helper macro to get DAC channel number in decimal format
- * from literals LL_DAC_CHANNEL_x.
- * Example:
- * __LL_DAC_CHANNEL_TO_DECIMAL_NB(LL_DAC_CHANNEL_1)
- * will return decimal number "1".
- * @note The input can be a value from functions where a channel
- * number is returned.
- * @param __CHANNEL__ This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @retval 1...2
- */
-#define __LL_DAC_CHANNEL_TO_DECIMAL_NB(__CHANNEL__) \
- ((__CHANNEL__) & DAC_SWTR_CHX_MASK)
-
-/**
- * @brief Helper macro to get DAC channel in literal format LL_DAC_CHANNEL_x
- * from number in decimal format.
- * Example:
- * __LL_DAC_DECIMAL_NB_TO_CHANNEL(1)
- * will return a data equivalent to "LL_DAC_CHANNEL_1".
- * @note If the input parameter does not correspond to a DAC channel,
- * this macro returns value '0'.
- * @param __DECIMAL_NB__ 1...2
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- */
-#define __LL_DAC_DECIMAL_NB_TO_CHANNEL(__DECIMAL_NB__) \
- (((__DECIMAL_NB__) == 1U) \
- ? ( \
- LL_DAC_CHANNEL_1 \
- ) \
- : \
- (((__DECIMAL_NB__) == 2U) \
- ? ( \
- LL_DAC_CHANNEL_2 \
- ) \
- : \
- ( \
- 0 \
- ) \
- ) \
- )
-
-/**
- * @brief Helper macro to define the DAC conversion data full-scale digital
- * value corresponding to the selected DAC resolution.
- * @note DAC conversion data full-scale corresponds to voltage range
- * determined by analog voltage references Vref+ and Vref-
- * (refer to reference manual).
- * @param __DAC_RESOLUTION__ This parameter can be one of the following values:
- * @arg @ref LL_DAC_RESOLUTION_12B
- * @arg @ref LL_DAC_RESOLUTION_8B
- * @retval ADC conversion data equivalent voltage value (unit: mVolt)
- */
-#define __LL_DAC_DIGITAL_SCALE(__DAC_RESOLUTION__) \
- ((0x00000FFFU) >> ((__DAC_RESOLUTION__) << 1U))
-
-/**
- * @brief Helper macro to calculate the DAC conversion data (unit: digital
- * value) corresponding to a voltage (unit: mVolt).
- * @note This helper macro is intended to provide input data in voltage
- * rather than digital value,
- * to be used with LL DAC functions such as
- * @ref LL_DAC_ConvertData12RightAligned().
- * @note Analog reference voltage (Vref+) must be either known from
- * user board environment or can be calculated using ADC measurement
- * and ADC helper macro @ref __LL_ADC_CALC_VREFANALOG_VOLTAGE().
- * @param __VREFANALOG_VOLTAGE__ Analog reference voltage (unit: mV)
- * @param __DAC_VOLTAGE__ Voltage to be generated by DAC channel
- * (unit: mVolt).
- * @param __DAC_RESOLUTION__ This parameter can be one of the following values:
- * @arg @ref LL_DAC_RESOLUTION_12B
- * @arg @ref LL_DAC_RESOLUTION_8B
- * @retval DAC conversion data (unit: digital value)
- */
-#define __LL_DAC_CALC_VOLTAGE_TO_DATA(__VREFANALOG_VOLTAGE__,\
- __DAC_VOLTAGE__,\
- __DAC_RESOLUTION__) \
- ((__DAC_VOLTAGE__) * __LL_DAC_DIGITAL_SCALE(__DAC_RESOLUTION__) \
- / (__VREFANALOG_VOLTAGE__) \
- )
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup DAC_LL_Exported_Functions DAC Exported Functions
- * @{
- */
-/** @defgroup DAC_LL_EF_Configuration Configuration of DAC channels
- * @{
- */
-
-/**
- * @brief Set the conversion trigger source for the selected DAC channel.
- * @note For conversion trigger source to be effective, DAC trigger
- * must be enabled using function @ref LL_DAC_EnableTrigger().
- * @note To set conversion trigger source, DAC channel must be disabled.
- * Otherwise, the setting is discarded.
- * @note Availability of parameters of trigger sources from timer
- * depends on timers availability on the selected device.
- * @rmtoll CR TSEL1 LL_DAC_SetTriggerSource\n
- * CR TSEL2 LL_DAC_SetTriggerSource
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @param TriggerSource This parameter can be one of the following values:
- * @arg @ref LL_DAC_TRIG_SOFTWARE
- * @arg @ref LL_DAC_TRIG_EXT_TIM3_TRGO
- * @arg @ref LL_DAC_TRIG_EXT_TIM15_TRGO
- * @arg @ref LL_DAC_TRIG_EXT_TIM8_TRGO
- * @arg @ref LL_DAC_TRIG_EXT_TIM7_TRGO
- * @arg @ref LL_DAC_TRIG_EXT_TIM6_TRGO
- * @arg @ref LL_DAC_TRIG_EXT_TIM5_TRGO
- * @arg @ref LL_DAC_TRIG_EXT_TIM4_TRGO
- * @arg @ref LL_DAC_TRIG_EXT_TIM2_TRGO
- * @arg @ref LL_DAC_TRIG_EXT_EXTI_LINE9
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_SetTriggerSource(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t TriggerSource)
-{
- MODIFY_REG(DACx->CR,
- DAC_CR_TSEL1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK),
- TriggerSource << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
-}
-
-/**
- * @brief Get the conversion trigger source for the selected DAC channel.
- * @note For conversion trigger source to be effective, DAC trigger
- * must be enabled using function @ref LL_DAC_EnableTrigger().
- * @note Availability of parameters of trigger sources from timer
- * depends on timers availability on the selected device.
- * @rmtoll CR TSEL1 LL_DAC_GetTriggerSource\n
- * CR TSEL2 LL_DAC_GetTriggerSource
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_DAC_TRIG_SOFTWARE
- * @arg @ref LL_DAC_TRIG_EXT_TIM3_TRGO
- * @arg @ref LL_DAC_TRIG_EXT_TIM15_TRGO
- * @arg @ref LL_DAC_TRIG_EXT_TIM8_TRGO
- * @arg @ref LL_DAC_TRIG_EXT_TIM7_TRGO
- * @arg @ref LL_DAC_TRIG_EXT_TIM6_TRGO
- * @arg @ref LL_DAC_TRIG_EXT_TIM5_TRGO
- * @arg @ref LL_DAC_TRIG_EXT_TIM4_TRGO
- * @arg @ref LL_DAC_TRIG_EXT_TIM2_TRGO
- * @arg @ref LL_DAC_TRIG_EXT_EXTI_LINE9
- */
-__STATIC_INLINE uint32_t LL_DAC_GetTriggerSource(DAC_TypeDef *DACx, uint32_t DAC_Channel)
-{
- return (uint32_t)(READ_BIT(DACx->CR, DAC_CR_TSEL1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))
- >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)
- );
-}
-
-/**
- * @brief Set the waveform automatic generation mode
- * for the selected DAC channel.
- * @rmtoll CR WAVE1 LL_DAC_SetWaveAutoGeneration\n
- * CR WAVE2 LL_DAC_SetWaveAutoGeneration
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @param WaveAutoGeneration This parameter can be one of the following values:
- * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_NONE
- * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_NOISE
- * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_TRIANGLE
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_SetWaveAutoGeneration(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t WaveAutoGeneration)
-{
- MODIFY_REG(DACx->CR,
- DAC_CR_WAVE1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK),
- WaveAutoGeneration << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
-}
-
-/**
- * @brief Get the waveform automatic generation mode
- * for the selected DAC channel.
- * @rmtoll CR WAVE1 LL_DAC_GetWaveAutoGeneration\n
- * CR WAVE2 LL_DAC_GetWaveAutoGeneration
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_NONE
- * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_NOISE
- * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_TRIANGLE
- */
-__STATIC_INLINE uint32_t LL_DAC_GetWaveAutoGeneration(DAC_TypeDef *DACx, uint32_t DAC_Channel)
-{
- return (uint32_t)(READ_BIT(DACx->CR, DAC_CR_WAVE1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))
- >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)
- );
-}
-
-/**
- * @brief Set the noise waveform generation for the selected DAC channel:
- * Noise mode and parameters LFSR (linear feedback shift register).
- * @note For wave generation to be effective, DAC channel
- * wave generation mode must be enabled using
- * function @ref LL_DAC_SetWaveAutoGeneration().
- * @note This setting can be set when the selected DAC channel is disabled
- * (otherwise, the setting operation is ignored).
- * @rmtoll CR MAMP1 LL_DAC_SetWaveNoiseLFSR\n
- * CR MAMP2 LL_DAC_SetWaveNoiseLFSR
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @param NoiseLFSRMask This parameter can be one of the following values:
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BIT0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS1_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS2_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS3_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS4_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS5_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS6_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS7_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS8_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS9_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS10_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS11_0
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_SetWaveNoiseLFSR(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t NoiseLFSRMask)
-{
- MODIFY_REG(DACx->CR,
- DAC_CR_MAMP1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK),
- NoiseLFSRMask << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
-}
-
-/**
- * @brief Set the noise waveform generation for the selected DAC channel:
- * Noise mode and parameters LFSR (linear feedback shift register).
- * @rmtoll CR MAMP1 LL_DAC_GetWaveNoiseLFSR\n
- * CR MAMP2 LL_DAC_GetWaveNoiseLFSR
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BIT0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS1_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS2_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS3_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS4_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS5_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS6_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS7_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS8_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS9_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS10_0
- * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS11_0
- */
-__STATIC_INLINE uint32_t LL_DAC_GetWaveNoiseLFSR(DAC_TypeDef *DACx, uint32_t DAC_Channel)
-{
- return (uint32_t)(READ_BIT(DACx->CR, DAC_CR_MAMP1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))
- >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)
- );
-}
-
-/**
- * @brief Set the triangle waveform generation for the selected DAC channel:
- * triangle mode and amplitude.
- * @note For wave generation to be effective, DAC channel
- * wave generation mode must be enabled using
- * function @ref LL_DAC_SetWaveAutoGeneration().
- * @note This setting can be set when the selected DAC channel is disabled
- * (otherwise, the setting operation is ignored).
- * @rmtoll CR MAMP1 LL_DAC_SetWaveTriangleAmplitude\n
- * CR MAMP2 LL_DAC_SetWaveTriangleAmplitude
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @param TriangleAmplitude This parameter can be one of the following values:
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_1
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_3
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_7
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_15
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_31
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_63
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_127
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_255
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_511
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_1023
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_2047
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_4095
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_SetWaveTriangleAmplitude(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t TriangleAmplitude)
-{
- MODIFY_REG(DACx->CR,
- DAC_CR_MAMP1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK),
- TriangleAmplitude << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
-}
-
-/**
- * @brief Set the triangle waveform generation for the selected DAC channel:
- * triangle mode and amplitude.
- * @rmtoll CR MAMP1 LL_DAC_GetWaveTriangleAmplitude\n
- * CR MAMP2 LL_DAC_GetWaveTriangleAmplitude
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_1
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_3
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_7
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_15
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_31
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_63
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_127
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_255
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_511
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_1023
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_2047
- * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_4095
- */
-__STATIC_INLINE uint32_t LL_DAC_GetWaveTriangleAmplitude(DAC_TypeDef *DACx, uint32_t DAC_Channel)
-{
- return (uint32_t)(READ_BIT(DACx->CR, DAC_CR_MAMP1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))
- >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)
- );
-}
-
-/**
- * @brief Set the output buffer for the selected DAC channel.
- * @rmtoll CR BOFF1 LL_DAC_SetOutputBuffer\n
- * CR BOFF2 LL_DAC_SetOutputBuffer
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @param OutputBuffer This parameter can be one of the following values:
- * @arg @ref LL_DAC_OUTPUT_BUFFER_ENABLE
- * @arg @ref LL_DAC_OUTPUT_BUFFER_DISABLE
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_SetOutputBuffer(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t OutputBuffer)
-{
- MODIFY_REG(DACx->CR,
- DAC_CR_BOFF1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK),
- OutputBuffer << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
-}
-
-/**
- * @brief Get the output buffer state for the selected DAC channel.
- * @rmtoll CR BOFF1 LL_DAC_GetOutputBuffer\n
- * CR BOFF2 LL_DAC_GetOutputBuffer
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_DAC_OUTPUT_BUFFER_ENABLE
- * @arg @ref LL_DAC_OUTPUT_BUFFER_DISABLE
- */
-__STATIC_INLINE uint32_t LL_DAC_GetOutputBuffer(DAC_TypeDef *DACx, uint32_t DAC_Channel)
-{
- return (uint32_t)(READ_BIT(DACx->CR, DAC_CR_BOFF1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))
- >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)
- );
-}
-
-/**
- * @}
- */
-
-/** @defgroup DAC_LL_EF_DMA_Management DMA Management
- * @{
- */
-
-/**
- * @brief Enable DAC DMA transfer request of the selected channel.
- * @note To configure DMA source address (peripheral address),
- * use function @ref LL_DAC_DMA_GetRegAddr().
- * @rmtoll CR DMAEN1 LL_DAC_EnableDMAReq\n
- * CR DMAEN2 LL_DAC_EnableDMAReq
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_EnableDMAReq(DAC_TypeDef *DACx, uint32_t DAC_Channel)
-{
- SET_BIT(DACx->CR,
- DAC_CR_DMAEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
-}
-
-/**
- * @brief Disable DAC DMA transfer request of the selected channel.
- * @note To configure DMA source address (peripheral address),
- * use function @ref LL_DAC_DMA_GetRegAddr().
- * @rmtoll CR DMAEN1 LL_DAC_DisableDMAReq\n
- * CR DMAEN2 LL_DAC_DisableDMAReq
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_DisableDMAReq(DAC_TypeDef *DACx, uint32_t DAC_Channel)
-{
- CLEAR_BIT(DACx->CR,
- DAC_CR_DMAEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
-}
-
-/**
- * @brief Get DAC DMA transfer request state of the selected channel.
- * (0: DAC DMA transfer request is disabled, 1: DAC DMA transfer request is enabled)
- * @rmtoll CR DMAEN1 LL_DAC_IsDMAReqEnabled\n
- * CR DMAEN2 LL_DAC_IsDMAReqEnabled
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DAC_IsDMAReqEnabled(DAC_TypeDef *DACx, uint32_t DAC_Channel)
-{
- return (READ_BIT(DACx->CR,
- DAC_CR_DMAEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))
- == (DAC_CR_DMAEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)));
-}
-
-/**
- * @brief Function to help to configure DMA transfer to DAC: retrieve the
- * DAC register address from DAC instance and a list of DAC registers
- * intended to be used (most commonly) with DMA transfer.
- * @note These DAC registers are data holding registers:
- * when DAC conversion is requested, DAC generates a DMA transfer
- * request to have data available in DAC data holding registers.
- * @note This macro is intended to be used with LL DMA driver, refer to
- * function "LL_DMA_ConfigAddresses()".
- * Example:
- * LL_DMA_ConfigAddresses(DMA1,
- * LL_DMA_CHANNEL_1,
- * (uint32_t)&< array or variable >,
- * LL_DAC_DMA_GetRegAddr(DAC1, LL_DAC_CHANNEL_1, LL_DAC_DMA_REG_DATA_12BITS_RIGHT_ALIGNED),
- * LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
- * @rmtoll DHR12R1 DACC1DHR LL_DAC_DMA_GetRegAddr\n
- * DHR12L1 DACC1DHR LL_DAC_DMA_GetRegAddr\n
- * DHR8R1 DACC1DHR LL_DAC_DMA_GetRegAddr\n
- * DHR12R2 DACC2DHR LL_DAC_DMA_GetRegAddr\n
- * DHR12L2 DACC2DHR LL_DAC_DMA_GetRegAddr\n
- * DHR8R2 DACC2DHR LL_DAC_DMA_GetRegAddr
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @param Register This parameter can be one of the following values:
- * @arg @ref LL_DAC_DMA_REG_DATA_12BITS_RIGHT_ALIGNED
- * @arg @ref LL_DAC_DMA_REG_DATA_12BITS_LEFT_ALIGNED
- * @arg @ref LL_DAC_DMA_REG_DATA_8BITS_RIGHT_ALIGNED
- * @retval DAC register address
- */
-__STATIC_INLINE uint32_t LL_DAC_DMA_GetRegAddr(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t Register)
-{
- /* Retrieve address of register DHR12Rx, DHR12Lx or DHR8Rx depending on */
- /* DAC channel selected. */
- return ((uint32_t)(__DAC_PTR_REG_OFFSET((DACx)->DHR12R1, __DAC_MASK_SHIFT(DAC_Channel, Register))));
-}
-/**
- * @}
- */
-
-/** @defgroup DAC_LL_EF_Operation Operation on DAC channels
- * @{
- */
-
-/**
- * @brief Enable DAC selected channel.
- * @rmtoll CR EN1 LL_DAC_Enable\n
- * CR EN2 LL_DAC_Enable
- * @note After enable from off state, DAC channel requires a delay
- * for output voltage to reach accuracy +/- 1 LSB.
- * Refer to device datasheet, parameter "tWAKEUP".
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_Enable(DAC_TypeDef *DACx, uint32_t DAC_Channel)
-{
- SET_BIT(DACx->CR,
- DAC_CR_EN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
-}
-
-/**
- * @brief Disable DAC selected channel.
- * @rmtoll CR EN1 LL_DAC_Disable\n
- * CR EN2 LL_DAC_Disable
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_Disable(DAC_TypeDef *DACx, uint32_t DAC_Channel)
-{
- CLEAR_BIT(DACx->CR,
- DAC_CR_EN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
-}
-
-/**
- * @brief Get DAC enable state of the selected channel.
- * (0: DAC channel is disabled, 1: DAC channel is enabled)
- * @rmtoll CR EN1 LL_DAC_IsEnabled\n
- * CR EN2 LL_DAC_IsEnabled
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DAC_IsEnabled(DAC_TypeDef *DACx, uint32_t DAC_Channel)
-{
- return (READ_BIT(DACx->CR,
- DAC_CR_EN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))
- == (DAC_CR_EN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)));
-}
-
-/**
- * @brief Enable DAC trigger of the selected channel.
- * @note - If DAC trigger is disabled, DAC conversion is performed
- * automatically once the data holding register is updated,
- * using functions "LL_DAC_ConvertData{8; 12}{Right; Left} Aligned()":
- * @ref LL_DAC_ConvertData12RightAligned(), ...
- * - If DAC trigger is enabled, DAC conversion is performed
- * only when a hardware of software trigger event is occurring.
- * Select trigger source using
- * function @ref LL_DAC_SetTriggerSource().
- * @rmtoll CR TEN1 LL_DAC_EnableTrigger\n
- * CR TEN2 LL_DAC_EnableTrigger
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_EnableTrigger(DAC_TypeDef *DACx, uint32_t DAC_Channel)
-{
- SET_BIT(DACx->CR,
- DAC_CR_TEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
-}
-
-/**
- * @brief Disable DAC trigger of the selected channel.
- * @rmtoll CR TEN1 LL_DAC_DisableTrigger\n
- * CR TEN2 LL_DAC_DisableTrigger
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_DisableTrigger(DAC_TypeDef *DACx, uint32_t DAC_Channel)
-{
- CLEAR_BIT(DACx->CR,
- DAC_CR_TEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
-}
-
-/**
- * @brief Get DAC trigger state of the selected channel.
- * (0: DAC trigger is disabled, 1: DAC trigger is enabled)
- * @rmtoll CR TEN1 LL_DAC_IsTriggerEnabled\n
- * CR TEN2 LL_DAC_IsTriggerEnabled
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DAC_IsTriggerEnabled(DAC_TypeDef *DACx, uint32_t DAC_Channel)
-{
- return (READ_BIT(DACx->CR,
- DAC_CR_TEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))
- == (DAC_CR_TEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)));
-}
-
-/**
- * @brief Trig DAC conversion by software for the selected DAC channel.
- * @note Preliminarily, DAC trigger must be set to software trigger
- * using function @ref LL_DAC_SetTriggerSource()
- * with parameter "LL_DAC_TRIGGER_SOFTWARE".
- * and DAC trigger must be enabled using
- * function @ref LL_DAC_EnableTrigger().
- * @note For devices featuring DAC with 2 channels: this function
- * can perform a SW start of both DAC channels simultaneously.
- * Two channels can be selected as parameter.
- * Example: (LL_DAC_CHANNEL_1 | LL_DAC_CHANNEL_2)
- * @rmtoll SWTRIGR SWTRIG1 LL_DAC_TrigSWConversion\n
- * SWTRIGR SWTRIG2 LL_DAC_TrigSWConversion
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can a combination of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_TrigSWConversion(DAC_TypeDef *DACx, uint32_t DAC_Channel)
-{
- SET_BIT(DACx->SWTRIGR,
- (DAC_Channel & DAC_SWTR_CHX_MASK));
-}
-
-/**
- * @brief Set the data to be loaded in the data holding register
- * in format 12 bits left alignment (LSB aligned on bit 0),
- * for the selected DAC channel.
- * @rmtoll DHR12R1 DACC1DHR LL_DAC_ConvertData12RightAligned\n
- * DHR12R2 DACC2DHR LL_DAC_ConvertData12RightAligned
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @param Data Value between Min_Data=0x000 and Max_Data=0xFFF
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_ConvertData12RightAligned(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t Data)
-{
- register uint32_t *preg = __DAC_PTR_REG_OFFSET(DACx->DHR12R1, __DAC_MASK_SHIFT(DAC_Channel, DAC_REG_DHR12RX_REGOFFSET_MASK));
-
- MODIFY_REG(*preg,
- DAC_DHR12R1_DACC1DHR,
- Data);
-}
-
-/**
- * @brief Set the data to be loaded in the data holding register
- * in format 12 bits left alignment (MSB aligned on bit 15),
- * for the selected DAC channel.
- * @rmtoll DHR12L1 DACC1DHR LL_DAC_ConvertData12LeftAligned\n
- * DHR12L2 DACC2DHR LL_DAC_ConvertData12LeftAligned
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @param Data Value between Min_Data=0x000 and Max_Data=0xFFF
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_ConvertData12LeftAligned(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t Data)
-{
- register uint32_t *preg = __DAC_PTR_REG_OFFSET(DACx->DHR12R1, __DAC_MASK_SHIFT(DAC_Channel, DAC_REG_DHR12LX_REGOFFSET_MASK));
-
- MODIFY_REG(*preg,
- DAC_DHR12L1_DACC1DHR,
- Data);
-}
-
-/**
- * @brief Set the data to be loaded in the data holding register
- * in format 8 bits left alignment (LSB aligned on bit 0),
- * for the selected DAC channel.
- * @rmtoll DHR8R1 DACC1DHR LL_DAC_ConvertData8RightAligned\n
- * DHR8R2 DACC2DHR LL_DAC_ConvertData8RightAligned
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @param Data Value between Min_Data=0x00 and Max_Data=0xFF
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_ConvertData8RightAligned(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t Data)
-{
- register uint32_t *preg = __DAC_PTR_REG_OFFSET(DACx->DHR12R1, __DAC_MASK_SHIFT(DAC_Channel, DAC_REG_DHR8RX_REGOFFSET_MASK));
-
- MODIFY_REG(*preg,
- DAC_DHR8R1_DACC1DHR,
- Data);
-}
-
-/**
- * @brief Set the data to be loaded in the data holding register
- * in format 12 bits left alignment (LSB aligned on bit 0),
- * for both DAC channels.
- * @rmtoll DHR12RD DACC1DHR LL_DAC_ConvertDualData12RightAligned\n
- * DHR12RD DACC2DHR LL_DAC_ConvertDualData12RightAligned
- * @param DACx DAC instance
- * @param DataChannel1 Value between Min_Data=0x000 and Max_Data=0xFFF
- * @param DataChannel2 Value between Min_Data=0x000 and Max_Data=0xFFF
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_ConvertDualData12RightAligned(DAC_TypeDef *DACx, uint32_t DataChannel1, uint32_t DataChannel2)
-{
- MODIFY_REG(DACx->DHR12RD,
- (DAC_DHR12RD_DACC2DHR | DAC_DHR12RD_DACC1DHR),
- ((DataChannel2 << DAC_DHR12RD_DACC2DHR_BITOFFSET_POS) | DataChannel1));
-}
-
-/**
- * @brief Set the data to be loaded in the data holding register
- * in format 12 bits left alignment (MSB aligned on bit 15),
- * for both DAC channels.
- * @rmtoll DHR12LD DACC1DHR LL_DAC_ConvertDualData12LeftAligned\n
- * DHR12LD DACC2DHR LL_DAC_ConvertDualData12LeftAligned
- * @param DACx DAC instance
- * @param DataChannel1 Value between Min_Data=0x000 and Max_Data=0xFFF
- * @param DataChannel2 Value between Min_Data=0x000 and Max_Data=0xFFF
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_ConvertDualData12LeftAligned(DAC_TypeDef *DACx, uint32_t DataChannel1, uint32_t DataChannel2)
-{
- /* Note: Data of DAC channel 2 shift value subtracted of 4 because */
- /* data on 16 bits and DAC channel 2 bits field is on the 12 MSB, */
- /* the 4 LSB must be taken into account for the shift value. */
- MODIFY_REG(DACx->DHR12LD,
- (DAC_DHR12LD_DACC2DHR | DAC_DHR12LD_DACC1DHR),
- ((DataChannel2 << (DAC_DHR12LD_DACC2DHR_BITOFFSET_POS - 4U)) | DataChannel1));
-}
-
-/**
- * @brief Set the data to be loaded in the data holding register
- * in format 8 bits left alignment (LSB aligned on bit 0),
- * for both DAC channels.
- * @rmtoll DHR8RD DACC1DHR LL_DAC_ConvertDualData8RightAligned\n
- * DHR8RD DACC2DHR LL_DAC_ConvertDualData8RightAligned
- * @param DACx DAC instance
- * @param DataChannel1 Value between Min_Data=0x00 and Max_Data=0xFF
- * @param DataChannel2 Value between Min_Data=0x00 and Max_Data=0xFF
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_ConvertDualData8RightAligned(DAC_TypeDef *DACx, uint32_t DataChannel1, uint32_t DataChannel2)
-{
- MODIFY_REG(DACx->DHR8RD,
- (DAC_DHR8RD_DACC2DHR | DAC_DHR8RD_DACC1DHR),
- ((DataChannel2 << DAC_DHR8RD_DACC2DHR_BITOFFSET_POS) | DataChannel1));
-}
-
-/**
- * @brief Retrieve output data currently generated for the selected DAC channel.
- * @note Whatever alignment and resolution settings
- * (using functions "LL_DAC_ConvertData{8; 12}{Right; Left} Aligned()":
- * @ref LL_DAC_ConvertData12RightAligned(), ...),
- * output data format is 12 bits right aligned (LSB aligned on bit 0).
- * @rmtoll DOR1 DACC1DOR LL_DAC_RetrieveOutputData\n
- * DOR2 DACC2DOR LL_DAC_RetrieveOutputData
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @retval Value between Min_Data=0x000 and Max_Data=0xFFF
- */
-__STATIC_INLINE uint32_t LL_DAC_RetrieveOutputData(DAC_TypeDef *DACx, uint32_t DAC_Channel)
-{
- register uint32_t *preg = __DAC_PTR_REG_OFFSET(DACx->DOR1, __DAC_MASK_SHIFT(DAC_Channel, DAC_REG_DORX_REGOFFSET_MASK));
-
- return (uint16_t) READ_BIT(*preg, DAC_DOR1_DACC1DOR);
-}
-
-/**
- * @}
- */
-
-/** @defgroup DAC_LL_EF_FLAG_Management FLAG Management
- * @{
- */
-#if defined(DAC_SR_DMAUDR1)
-/**
- * @brief Get DAC underrun flag for DAC channel 1
- * @rmtoll SR DMAUDR1 LL_DAC_IsActiveFlag_DMAUDR1
- * @param DACx DAC instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DAC_IsActiveFlag_DMAUDR1(DAC_TypeDef *DACx)
-{
- return (READ_BIT(DACx->SR, LL_DAC_FLAG_DMAUDR1) == (LL_DAC_FLAG_DMAUDR1));
-}
-#endif /* DAC_SR_DMAUDR1 */
-
-#if defined(DAC_SR_DMAUDR2)
-/**
- * @brief Get DAC underrun flag for DAC channel 2
- * @rmtoll SR DMAUDR2 LL_DAC_IsActiveFlag_DMAUDR2
- * @param DACx DAC instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DAC_IsActiveFlag_DMAUDR2(DAC_TypeDef *DACx)
-{
- return (READ_BIT(DACx->SR, LL_DAC_FLAG_DMAUDR2) == (LL_DAC_FLAG_DMAUDR2));
-}
-#endif /* DAC_SR_DMAUDR2 */
-
-#if defined(DAC_SR_DMAUDR1)
-/**
- * @brief Clear DAC underrun flag for DAC channel 1
- * @rmtoll SR DMAUDR1 LL_DAC_ClearFlag_DMAUDR1
- * @param DACx DAC instance
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_ClearFlag_DMAUDR1(DAC_TypeDef *DACx)
-{
- WRITE_REG(DACx->SR, LL_DAC_FLAG_DMAUDR1);
-}
-#endif /* DAC_SR_DMAUDR1 */
-
-#if defined(DAC_SR_DMAUDR2)
-/**
- * @brief Clear DAC underrun flag for DAC channel 2
- * @rmtoll SR DMAUDR2 LL_DAC_ClearFlag_DMAUDR2
- * @param DACx DAC instance
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_ClearFlag_DMAUDR2(DAC_TypeDef *DACx)
-{
- WRITE_REG(DACx->SR, LL_DAC_FLAG_DMAUDR2);
-}
-#endif /* DAC_SR_DMAUDR2 */
-
-/**
- * @}
- */
-/** @defgroup DAC_LL_EF_IT_Management IT management
- * @{
- */
-
-#if defined(DAC_CR_DMAUDRIE1)
-/**
- * @brief Enable DMA underrun interrupt for DAC channel 1
- * @rmtoll CR DMAUDRIE1 LL_DAC_EnableIT_DMAUDR1
- * @param DACx DAC instance
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_EnableIT_DMAUDR1(DAC_TypeDef *DACx)
-{
- SET_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE1);
-}
-#endif /* DAC_CR_DMAUDRIE1 */
-
-#if defined(DAC_CR_DMAUDRIE2)
-/**
- * @brief Enable DMA underrun interrupt for DAC channel 2
- * @rmtoll CR DMAUDRIE2 LL_DAC_EnableIT_DMAUDR2
- * @param DACx DAC instance
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_EnableIT_DMAUDR2(DAC_TypeDef *DACx)
-{
- SET_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE2);
-}
-#endif /* DAC_CR_DMAUDRIE2 */
-
-#if defined(DAC_CR_DMAUDRIE1)
-/**
- * @brief Disable DMA underrun interrupt for DAC channel 1
- * @rmtoll CR DMAUDRIE1 LL_DAC_DisableIT_DMAUDR1
- * @param DACx DAC instance
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_DisableIT_DMAUDR1(DAC_TypeDef *DACx)
-{
- CLEAR_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE1);
-}
-#endif /* DAC_CR_DMAUDRIE1 */
-
-#if defined(DAC_CR_DMAUDRIE2)
-/**
- * @brief Disable DMA underrun interrupt for DAC channel 2
- * @rmtoll CR DMAUDRIE2 LL_DAC_DisableIT_DMAUDR2
- * @param DACx DAC instance
- * @retval None
- */
-__STATIC_INLINE void LL_DAC_DisableIT_DMAUDR2(DAC_TypeDef *DACx)
-{
- CLEAR_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE2);
-}
-#endif /* DAC_CR_DMAUDRIE2 */
-
-#if defined(DAC_CR_DMAUDRIE1)
-/**
- * @brief Get DMA underrun interrupt for DAC channel 1
- * @rmtoll CR DMAUDRIE1 LL_DAC_IsEnabledIT_DMAUDR1
- * @param DACx DAC instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DAC_IsEnabledIT_DMAUDR1(DAC_TypeDef *DACx)
-{
- return (READ_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE1) == (LL_DAC_IT_DMAUDRIE1));
-}
-#endif /* DAC_CR_DMAUDRIE1 */
-
-#if defined(DAC_CR_DMAUDRIE2)
-/**
- * @brief Get DMA underrun interrupt for DAC channel 2
- * @rmtoll CR DMAUDRIE2 LL_DAC_IsEnabledIT_DMAUDR2
- * @param DACx DAC instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DAC_IsEnabledIT_DMAUDR2(DAC_TypeDef *DACx)
-{
- return (READ_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE2) == (LL_DAC_IT_DMAUDRIE2));
-}
-#endif /* DAC_CR_DMAUDRIE2 */
-
-/**
- * @}
- */
-
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup DAC_LL_EF_Init Initialization and de-initialization functions
- * @{
- */
-
-ErrorStatus LL_DAC_DeInit(DAC_TypeDef* DACx);
-ErrorStatus LL_DAC_Init(DAC_TypeDef* DACx, uint32_t DAC_Channel, LL_DAC_InitTypeDef* DAC_InitStruct);
-void LL_DAC_StructInit(LL_DAC_InitTypeDef* DAC_InitStruct);
-
-/**
- * @}
- */
-#endif /* USE_FULL_LL_DRIVER */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* DAC */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_LL_DAC_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_dma.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_dma.h
deleted file mode 100644
index b1bf5b9..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_dma.h
+++ /dev/null
@@ -1,1976 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_dma.h
- * @author MCD Application Team
- * @brief Header file of DMA LL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_LL_DMA_H
-#define __STM32F1xx_LL_DMA_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx.h"
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined (DMA1) || defined (DMA2)
-
-/** @defgroup DMA_LL DMA
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/** @defgroup DMA_LL_Private_Variables DMA Private Variables
- * @{
- */
-/* Array used to get the DMA channel register offset versus channel index LL_DMA_CHANNEL_x */
-static const uint8_t CHANNEL_OFFSET_TAB[] =
-{
- (uint8_t)(DMA1_Channel1_BASE - DMA1_BASE),
- (uint8_t)(DMA1_Channel2_BASE - DMA1_BASE),
- (uint8_t)(DMA1_Channel3_BASE - DMA1_BASE),
- (uint8_t)(DMA1_Channel4_BASE - DMA1_BASE),
- (uint8_t)(DMA1_Channel5_BASE - DMA1_BASE),
- (uint8_t)(DMA1_Channel6_BASE - DMA1_BASE),
- (uint8_t)(DMA1_Channel7_BASE - DMA1_BASE)
-};
-/**
- * @}
- */
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup DMA_LL_Private_Macros DMA Private Macros
- * @{
- */
-/**
- * @}
- */
-#endif /*USE_FULL_LL_DRIVER*/
-
-/* Exported types ------------------------------------------------------------*/
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup DMA_LL_ES_INIT DMA Exported Init structure
- * @{
- */
-typedef struct
-{
- uint32_t PeriphOrM2MSrcAddress; /*!< Specifies the peripheral base address for DMA transfer
- or as Source base address in case of memory to memory transfer direction.
-
- This parameter must be a value between Min_Data = 0 and Max_Data = 0xFFFFFFFF. */
-
- uint32_t MemoryOrM2MDstAddress; /*!< Specifies the memory base address for DMA transfer
- or as Destination base address in case of memory to memory transfer direction.
-
- This parameter must be a value between Min_Data = 0 and Max_Data = 0xFFFFFFFF. */
-
- uint32_t Direction; /*!< Specifies if the data will be transferred from memory to peripheral,
- from memory to memory or from peripheral to memory.
- This parameter can be a value of @ref DMA_LL_EC_DIRECTION
-
- This feature can be modified afterwards using unitary function @ref LL_DMA_SetDataTransferDirection(). */
-
- uint32_t Mode; /*!< Specifies the normal or circular operation mode.
- This parameter can be a value of @ref DMA_LL_EC_MODE
- @note: The circular buffer mode cannot be used if the memory to memory
- data transfer direction is configured on the selected Channel
-
- This feature can be modified afterwards using unitary function @ref LL_DMA_SetMode(). */
-
- uint32_t PeriphOrM2MSrcIncMode; /*!< Specifies whether the Peripheral address or Source address in case of memory to memory transfer direction
- is incremented or not.
- This parameter can be a value of @ref DMA_LL_EC_PERIPH
-
- This feature can be modified afterwards using unitary function @ref LL_DMA_SetPeriphIncMode(). */
-
- uint32_t MemoryOrM2MDstIncMode; /*!< Specifies whether the Memory address or Destination address in case of memory to memory transfer direction
- is incremented or not.
- This parameter can be a value of @ref DMA_LL_EC_MEMORY
-
- This feature can be modified afterwards using unitary function @ref LL_DMA_SetMemoryIncMode(). */
-
- uint32_t PeriphOrM2MSrcDataSize; /*!< Specifies the Peripheral data size alignment or Source data size alignment (byte, half word, word)
- in case of memory to memory transfer direction.
- This parameter can be a value of @ref DMA_LL_EC_PDATAALIGN
-
- This feature can be modified afterwards using unitary function @ref LL_DMA_SetPeriphSize(). */
-
- uint32_t MemoryOrM2MDstDataSize; /*!< Specifies the Memory data size alignment or Destination data size alignment (byte, half word, word)
- in case of memory to memory transfer direction.
- This parameter can be a value of @ref DMA_LL_EC_MDATAALIGN
-
- This feature can be modified afterwards using unitary function @ref LL_DMA_SetMemorySize(). */
-
- uint32_t NbData; /*!< Specifies the number of data to transfer, in data unit.
- The data unit is equal to the source buffer configuration set in PeripheralSize
- or MemorySize parameters depending in the transfer direction.
- This parameter must be a value between Min_Data = 0 and Max_Data = 0x0000FFFF
-
- This feature can be modified afterwards using unitary function @ref LL_DMA_SetDataLength(). */
-
- uint32_t Priority; /*!< Specifies the channel priority level.
- This parameter can be a value of @ref DMA_LL_EC_PRIORITY
-
- This feature can be modified afterwards using unitary function @ref LL_DMA_SetChannelPriorityLevel(). */
-
-} LL_DMA_InitTypeDef;
-/**
- * @}
- */
-#endif /*USE_FULL_LL_DRIVER*/
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup DMA_LL_Exported_Constants DMA Exported Constants
- * @{
- */
-/** @defgroup DMA_LL_EC_CLEAR_FLAG Clear Flags Defines
- * @brief Flags defines which can be used with LL_DMA_WriteReg function
- * @{
- */
-#define LL_DMA_IFCR_CGIF1 DMA_IFCR_CGIF1 /*!< Channel 1 global flag */
-#define LL_DMA_IFCR_CTCIF1 DMA_IFCR_CTCIF1 /*!< Channel 1 transfer complete flag */
-#define LL_DMA_IFCR_CHTIF1 DMA_IFCR_CHTIF1 /*!< Channel 1 half transfer flag */
-#define LL_DMA_IFCR_CTEIF1 DMA_IFCR_CTEIF1 /*!< Channel 1 transfer error flag */
-#define LL_DMA_IFCR_CGIF2 DMA_IFCR_CGIF2 /*!< Channel 2 global flag */
-#define LL_DMA_IFCR_CTCIF2 DMA_IFCR_CTCIF2 /*!< Channel 2 transfer complete flag */
-#define LL_DMA_IFCR_CHTIF2 DMA_IFCR_CHTIF2 /*!< Channel 2 half transfer flag */
-#define LL_DMA_IFCR_CTEIF2 DMA_IFCR_CTEIF2 /*!< Channel 2 transfer error flag */
-#define LL_DMA_IFCR_CGIF3 DMA_IFCR_CGIF3 /*!< Channel 3 global flag */
-#define LL_DMA_IFCR_CTCIF3 DMA_IFCR_CTCIF3 /*!< Channel 3 transfer complete flag */
-#define LL_DMA_IFCR_CHTIF3 DMA_IFCR_CHTIF3 /*!< Channel 3 half transfer flag */
-#define LL_DMA_IFCR_CTEIF3 DMA_IFCR_CTEIF3 /*!< Channel 3 transfer error flag */
-#define LL_DMA_IFCR_CGIF4 DMA_IFCR_CGIF4 /*!< Channel 4 global flag */
-#define LL_DMA_IFCR_CTCIF4 DMA_IFCR_CTCIF4 /*!< Channel 4 transfer complete flag */
-#define LL_DMA_IFCR_CHTIF4 DMA_IFCR_CHTIF4 /*!< Channel 4 half transfer flag */
-#define LL_DMA_IFCR_CTEIF4 DMA_IFCR_CTEIF4 /*!< Channel 4 transfer error flag */
-#define LL_DMA_IFCR_CGIF5 DMA_IFCR_CGIF5 /*!< Channel 5 global flag */
-#define LL_DMA_IFCR_CTCIF5 DMA_IFCR_CTCIF5 /*!< Channel 5 transfer complete flag */
-#define LL_DMA_IFCR_CHTIF5 DMA_IFCR_CHTIF5 /*!< Channel 5 half transfer flag */
-#define LL_DMA_IFCR_CTEIF5 DMA_IFCR_CTEIF5 /*!< Channel 5 transfer error flag */
-#define LL_DMA_IFCR_CGIF6 DMA_IFCR_CGIF6 /*!< Channel 6 global flag */
-#define LL_DMA_IFCR_CTCIF6 DMA_IFCR_CTCIF6 /*!< Channel 6 transfer complete flag */
-#define LL_DMA_IFCR_CHTIF6 DMA_IFCR_CHTIF6 /*!< Channel 6 half transfer flag */
-#define LL_DMA_IFCR_CTEIF6 DMA_IFCR_CTEIF6 /*!< Channel 6 transfer error flag */
-#define LL_DMA_IFCR_CGIF7 DMA_IFCR_CGIF7 /*!< Channel 7 global flag */
-#define LL_DMA_IFCR_CTCIF7 DMA_IFCR_CTCIF7 /*!< Channel 7 transfer complete flag */
-#define LL_DMA_IFCR_CHTIF7 DMA_IFCR_CHTIF7 /*!< Channel 7 half transfer flag */
-#define LL_DMA_IFCR_CTEIF7 DMA_IFCR_CTEIF7 /*!< Channel 7 transfer error flag */
-/**
- * @}
- */
-
-/** @defgroup DMA_LL_EC_GET_FLAG Get Flags Defines
- * @brief Flags defines which can be used with LL_DMA_ReadReg function
- * @{
- */
-#define LL_DMA_ISR_GIF1 DMA_ISR_GIF1 /*!< Channel 1 global flag */
-#define LL_DMA_ISR_TCIF1 DMA_ISR_TCIF1 /*!< Channel 1 transfer complete flag */
-#define LL_DMA_ISR_HTIF1 DMA_ISR_HTIF1 /*!< Channel 1 half transfer flag */
-#define LL_DMA_ISR_TEIF1 DMA_ISR_TEIF1 /*!< Channel 1 transfer error flag */
-#define LL_DMA_ISR_GIF2 DMA_ISR_GIF2 /*!< Channel 2 global flag */
-#define LL_DMA_ISR_TCIF2 DMA_ISR_TCIF2 /*!< Channel 2 transfer complete flag */
-#define LL_DMA_ISR_HTIF2 DMA_ISR_HTIF2 /*!< Channel 2 half transfer flag */
-#define LL_DMA_ISR_TEIF2 DMA_ISR_TEIF2 /*!< Channel 2 transfer error flag */
-#define LL_DMA_ISR_GIF3 DMA_ISR_GIF3 /*!< Channel 3 global flag */
-#define LL_DMA_ISR_TCIF3 DMA_ISR_TCIF3 /*!< Channel 3 transfer complete flag */
-#define LL_DMA_ISR_HTIF3 DMA_ISR_HTIF3 /*!< Channel 3 half transfer flag */
-#define LL_DMA_ISR_TEIF3 DMA_ISR_TEIF3 /*!< Channel 3 transfer error flag */
-#define LL_DMA_ISR_GIF4 DMA_ISR_GIF4 /*!< Channel 4 global flag */
-#define LL_DMA_ISR_TCIF4 DMA_ISR_TCIF4 /*!< Channel 4 transfer complete flag */
-#define LL_DMA_ISR_HTIF4 DMA_ISR_HTIF4 /*!< Channel 4 half transfer flag */
-#define LL_DMA_ISR_TEIF4 DMA_ISR_TEIF4 /*!< Channel 4 transfer error flag */
-#define LL_DMA_ISR_GIF5 DMA_ISR_GIF5 /*!< Channel 5 global flag */
-#define LL_DMA_ISR_TCIF5 DMA_ISR_TCIF5 /*!< Channel 5 transfer complete flag */
-#define LL_DMA_ISR_HTIF5 DMA_ISR_HTIF5 /*!< Channel 5 half transfer flag */
-#define LL_DMA_ISR_TEIF5 DMA_ISR_TEIF5 /*!< Channel 5 transfer error flag */
-#define LL_DMA_ISR_GIF6 DMA_ISR_GIF6 /*!< Channel 6 global flag */
-#define LL_DMA_ISR_TCIF6 DMA_ISR_TCIF6 /*!< Channel 6 transfer complete flag */
-#define LL_DMA_ISR_HTIF6 DMA_ISR_HTIF6 /*!< Channel 6 half transfer flag */
-#define LL_DMA_ISR_TEIF6 DMA_ISR_TEIF6 /*!< Channel 6 transfer error flag */
-#define LL_DMA_ISR_GIF7 DMA_ISR_GIF7 /*!< Channel 7 global flag */
-#define LL_DMA_ISR_TCIF7 DMA_ISR_TCIF7 /*!< Channel 7 transfer complete flag */
-#define LL_DMA_ISR_HTIF7 DMA_ISR_HTIF7 /*!< Channel 7 half transfer flag */
-#define LL_DMA_ISR_TEIF7 DMA_ISR_TEIF7 /*!< Channel 7 transfer error flag */
-/**
- * @}
- */
-
-/** @defgroup DMA_LL_EC_IT IT Defines
- * @brief IT defines which can be used with LL_DMA_ReadReg and LL_DMA_WriteReg functions
- * @{
- */
-#define LL_DMA_CCR_TCIE DMA_CCR_TCIE /*!< Transfer complete interrupt */
-#define LL_DMA_CCR_HTIE DMA_CCR_HTIE /*!< Half Transfer interrupt */
-#define LL_DMA_CCR_TEIE DMA_CCR_TEIE /*!< Transfer error interrupt */
-/**
- * @}
- */
-
-/** @defgroup DMA_LL_EC_CHANNEL CHANNEL
- * @{
- */
-#define LL_DMA_CHANNEL_1 0x00000001U /*!< DMA Channel 1 */
-#define LL_DMA_CHANNEL_2 0x00000002U /*!< DMA Channel 2 */
-#define LL_DMA_CHANNEL_3 0x00000003U /*!< DMA Channel 3 */
-#define LL_DMA_CHANNEL_4 0x00000004U /*!< DMA Channel 4 */
-#define LL_DMA_CHANNEL_5 0x00000005U /*!< DMA Channel 5 */
-#define LL_DMA_CHANNEL_6 0x00000006U /*!< DMA Channel 6 */
-#define LL_DMA_CHANNEL_7 0x00000007U /*!< DMA Channel 7 */
-#if defined(USE_FULL_LL_DRIVER)
-#define LL_DMA_CHANNEL_ALL 0xFFFF0000U /*!< DMA Channel all (used only for function @ref LL_DMA_DeInit(). */
-#endif /*USE_FULL_LL_DRIVER*/
-/**
- * @}
- */
-
-/** @defgroup DMA_LL_EC_DIRECTION Transfer Direction
- * @{
- */
-#define LL_DMA_DIRECTION_PERIPH_TO_MEMORY 0x00000000U /*!< Peripheral to memory direction */
-#define LL_DMA_DIRECTION_MEMORY_TO_PERIPH DMA_CCR_DIR /*!< Memory to peripheral direction */
-#define LL_DMA_DIRECTION_MEMORY_TO_MEMORY DMA_CCR_MEM2MEM /*!< Memory to memory direction */
-/**
- * @}
- */
-
-/** @defgroup DMA_LL_EC_MODE Transfer mode
- * @{
- */
-#define LL_DMA_MODE_NORMAL 0x00000000U /*!< Normal Mode */
-#define LL_DMA_MODE_CIRCULAR DMA_CCR_CIRC /*!< Circular Mode */
-/**
- * @}
- */
-
-/** @defgroup DMA_LL_EC_PERIPH Peripheral increment mode
- * @{
- */
-#define LL_DMA_PERIPH_INCREMENT DMA_CCR_PINC /*!< Peripheral increment mode Enable */
-#define LL_DMA_PERIPH_NOINCREMENT 0x00000000U /*!< Peripheral increment mode Disable */
-/**
- * @}
- */
-
-/** @defgroup DMA_LL_EC_MEMORY Memory increment mode
- * @{
- */
-#define LL_DMA_MEMORY_INCREMENT DMA_CCR_MINC /*!< Memory increment mode Enable */
-#define LL_DMA_MEMORY_NOINCREMENT 0x00000000U /*!< Memory increment mode Disable */
-/**
- * @}
- */
-
-/** @defgroup DMA_LL_EC_PDATAALIGN Peripheral data alignment
- * @{
- */
-#define LL_DMA_PDATAALIGN_BYTE 0x00000000U /*!< Peripheral data alignment : Byte */
-#define LL_DMA_PDATAALIGN_HALFWORD DMA_CCR_PSIZE_0 /*!< Peripheral data alignment : HalfWord */
-#define LL_DMA_PDATAALIGN_WORD DMA_CCR_PSIZE_1 /*!< Peripheral data alignment : Word */
-/**
- * @}
- */
-
-/** @defgroup DMA_LL_EC_MDATAALIGN Memory data alignment
- * @{
- */
-#define LL_DMA_MDATAALIGN_BYTE 0x00000000U /*!< Memory data alignment : Byte */
-#define LL_DMA_MDATAALIGN_HALFWORD DMA_CCR_MSIZE_0 /*!< Memory data alignment : HalfWord */
-#define LL_DMA_MDATAALIGN_WORD DMA_CCR_MSIZE_1 /*!< Memory data alignment : Word */
-/**
- * @}
- */
-
-/** @defgroup DMA_LL_EC_PRIORITY Transfer Priority level
- * @{
- */
-#define LL_DMA_PRIORITY_LOW 0x00000000U /*!< Priority level : Low */
-#define LL_DMA_PRIORITY_MEDIUM DMA_CCR_PL_0 /*!< Priority level : Medium */
-#define LL_DMA_PRIORITY_HIGH DMA_CCR_PL_1 /*!< Priority level : High */
-#define LL_DMA_PRIORITY_VERYHIGH DMA_CCR_PL /*!< Priority level : Very_High */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup DMA_LL_Exported_Macros DMA Exported Macros
- * @{
- */
-
-/** @defgroup DMA_LL_EM_WRITE_READ Common Write and read registers macros
- * @{
- */
-/**
- * @brief Write a value in DMA register
- * @param __INSTANCE__ DMA Instance
- * @param __REG__ Register to be written
- * @param __VALUE__ Value to be written in the register
- * @retval None
- */
-#define LL_DMA_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
-
-/**
- * @brief Read a value in DMA register
- * @param __INSTANCE__ DMA Instance
- * @param __REG__ Register to be read
- * @retval Register value
- */
-#define LL_DMA_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
-/**
- * @}
- */
-
-/** @defgroup DMA_LL_EM_CONVERT_DMAxCHANNELy Convert DMAxChannely
- * @{
- */
-
-/**
- * @brief Convert DMAx_Channely into DMAx
- * @param __CHANNEL_INSTANCE__ DMAx_Channely
- * @retval DMAx
- */
-#if defined(DMA2)
-#define __LL_DMA_GET_INSTANCE(__CHANNEL_INSTANCE__) \
-(((uint32_t)(__CHANNEL_INSTANCE__) > ((uint32_t)DMA1_Channel7)) ? DMA2 : DMA1)
-#else
-#define __LL_DMA_GET_INSTANCE(__CHANNEL_INSTANCE__) (DMA1)
-#endif
-
-/**
- * @brief Convert DMAx_Channely into LL_DMA_CHANNEL_y
- * @param __CHANNEL_INSTANCE__ DMAx_Channely
- * @retval LL_DMA_CHANNEL_y
- */
-#if defined (DMA2)
-#define __LL_DMA_GET_CHANNEL(__CHANNEL_INSTANCE__) \
-(((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel1)) ? LL_DMA_CHANNEL_1 : \
- ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel1)) ? LL_DMA_CHANNEL_1 : \
- ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel2)) ? LL_DMA_CHANNEL_2 : \
- ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel2)) ? LL_DMA_CHANNEL_2 : \
- ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel3)) ? LL_DMA_CHANNEL_3 : \
- ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel3)) ? LL_DMA_CHANNEL_3 : \
- ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel4)) ? LL_DMA_CHANNEL_4 : \
- ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel4)) ? LL_DMA_CHANNEL_4 : \
- ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel5)) ? LL_DMA_CHANNEL_5 : \
- ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel5)) ? LL_DMA_CHANNEL_5 : \
- ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel6)) ? LL_DMA_CHANNEL_6 : \
- LL_DMA_CHANNEL_7)
-#else
-#define __LL_DMA_GET_CHANNEL(__CHANNEL_INSTANCE__) \
-(((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel1)) ? LL_DMA_CHANNEL_1 : \
- ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel2)) ? LL_DMA_CHANNEL_2 : \
- ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel3)) ? LL_DMA_CHANNEL_3 : \
- ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel4)) ? LL_DMA_CHANNEL_4 : \
- ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel5)) ? LL_DMA_CHANNEL_5 : \
- ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel6)) ? LL_DMA_CHANNEL_6 : \
- LL_DMA_CHANNEL_7)
-#endif
-
-/**
- * @brief Convert DMA Instance DMAx and LL_DMA_CHANNEL_y into DMAx_Channely
- * @param __DMA_INSTANCE__ DMAx
- * @param __CHANNEL__ LL_DMA_CHANNEL_y
- * @retval DMAx_Channely
- */
-#if defined (DMA2)
-#define __LL_DMA_GET_CHANNEL_INSTANCE(__DMA_INSTANCE__, __CHANNEL__) \
-((((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_1))) ? DMA1_Channel1 : \
- (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_1))) ? DMA2_Channel1 : \
- (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_2))) ? DMA1_Channel2 : \
- (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_2))) ? DMA2_Channel2 : \
- (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_3))) ? DMA1_Channel3 : \
- (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_3))) ? DMA2_Channel3 : \
- (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_4))) ? DMA1_Channel4 : \
- (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_4))) ? DMA2_Channel4 : \
- (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_5))) ? DMA1_Channel5 : \
- (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_5))) ? DMA2_Channel5 : \
- (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_6))) ? DMA1_Channel6 : \
- DMA1_Channel7)
-#else
-#define __LL_DMA_GET_CHANNEL_INSTANCE(__DMA_INSTANCE__, __CHANNEL__) \
-((((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_1))) ? DMA1_Channel1 : \
- (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_2))) ? DMA1_Channel2 : \
- (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_3))) ? DMA1_Channel3 : \
- (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_4))) ? DMA1_Channel4 : \
- (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_5))) ? DMA1_Channel5 : \
- (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_6))) ? DMA1_Channel6 : \
- DMA1_Channel7)
-#endif
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup DMA_LL_Exported_Functions DMA Exported Functions
- * @{
- */
-
-/** @defgroup DMA_LL_EF_Configuration Configuration
- * @{
- */
-/**
- * @brief Enable DMA channel.
- * @rmtoll CCR EN LL_DMA_EnableChannel
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_EnableChannel(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- SET_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_EN);
-}
-
-/**
- * @brief Disable DMA channel.
- * @rmtoll CCR EN LL_DMA_DisableChannel
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_DisableChannel(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- CLEAR_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_EN);
-}
-
-/**
- * @brief Check if DMA channel is enabled or disabled.
- * @rmtoll CCR EN LL_DMA_IsEnabledChannel
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsEnabledChannel(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
- DMA_CCR_EN) == (DMA_CCR_EN));
-}
-
-/**
- * @brief Configure all parameters link to DMA transfer.
- * @rmtoll CCR DIR LL_DMA_ConfigTransfer\n
- * CCR MEM2MEM LL_DMA_ConfigTransfer\n
- * CCR CIRC LL_DMA_ConfigTransfer\n
- * CCR PINC LL_DMA_ConfigTransfer\n
- * CCR MINC LL_DMA_ConfigTransfer\n
- * CCR PSIZE LL_DMA_ConfigTransfer\n
- * CCR MSIZE LL_DMA_ConfigTransfer\n
- * CCR PL LL_DMA_ConfigTransfer
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @param Configuration This parameter must be a combination of all the following values:
- * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_MEMORY or @ref LL_DMA_DIRECTION_MEMORY_TO_PERIPH or @ref LL_DMA_DIRECTION_MEMORY_TO_MEMORY
- * @arg @ref LL_DMA_MODE_NORMAL or @ref LL_DMA_MODE_CIRCULAR
- * @arg @ref LL_DMA_PERIPH_INCREMENT or @ref LL_DMA_PERIPH_NOINCREMENT
- * @arg @ref LL_DMA_MEMORY_INCREMENT or @ref LL_DMA_MEMORY_NOINCREMENT
- * @arg @ref LL_DMA_PDATAALIGN_BYTE or @ref LL_DMA_PDATAALIGN_HALFWORD or @ref LL_DMA_PDATAALIGN_WORD
- * @arg @ref LL_DMA_MDATAALIGN_BYTE or @ref LL_DMA_MDATAALIGN_HALFWORD or @ref LL_DMA_MDATAALIGN_WORD
- * @arg @ref LL_DMA_PRIORITY_LOW or @ref LL_DMA_PRIORITY_MEDIUM or @ref LL_DMA_PRIORITY_HIGH or @ref LL_DMA_PRIORITY_VERYHIGH
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ConfigTransfer(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t Configuration)
-{
- MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
- DMA_CCR_DIR | DMA_CCR_MEM2MEM | DMA_CCR_CIRC | DMA_CCR_PINC | DMA_CCR_MINC | DMA_CCR_PSIZE | DMA_CCR_MSIZE | DMA_CCR_PL,
- Configuration);
-}
-
-/**
- * @brief Set Data transfer direction (read from peripheral or from memory).
- * @rmtoll CCR DIR LL_DMA_SetDataTransferDirection\n
- * CCR MEM2MEM LL_DMA_SetDataTransferDirection
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @param Direction This parameter can be one of the following values:
- * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_MEMORY
- * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_PERIPH
- * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_MEMORY
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_SetDataTransferDirection(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t Direction)
-{
- MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
- DMA_CCR_DIR | DMA_CCR_MEM2MEM, Direction);
-}
-
-/**
- * @brief Get Data transfer direction (read from peripheral or from memory).
- * @rmtoll CCR DIR LL_DMA_GetDataTransferDirection\n
- * CCR MEM2MEM LL_DMA_GetDataTransferDirection
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_MEMORY
- * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_PERIPH
- * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_MEMORY
- */
-__STATIC_INLINE uint32_t LL_DMA_GetDataTransferDirection(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
- DMA_CCR_DIR | DMA_CCR_MEM2MEM));
-}
-
-/**
- * @brief Set DMA mode circular or normal.
- * @note The circular buffer mode cannot be used if the memory-to-memory
- * data transfer is configured on the selected Channel.
- * @rmtoll CCR CIRC LL_DMA_SetMode
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @param Mode This parameter can be one of the following values:
- * @arg @ref LL_DMA_MODE_NORMAL
- * @arg @ref LL_DMA_MODE_CIRCULAR
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_SetMode(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t Mode)
-{
- MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_CIRC,
- Mode);
-}
-
-/**
- * @brief Get DMA mode circular or normal.
- * @rmtoll CCR CIRC LL_DMA_GetMode
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_DMA_MODE_NORMAL
- * @arg @ref LL_DMA_MODE_CIRCULAR
- */
-__STATIC_INLINE uint32_t LL_DMA_GetMode(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
- DMA_CCR_CIRC));
-}
-
-/**
- * @brief Set Peripheral increment mode.
- * @rmtoll CCR PINC LL_DMA_SetPeriphIncMode
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @param PeriphOrM2MSrcIncMode This parameter can be one of the following values:
- * @arg @ref LL_DMA_PERIPH_INCREMENT
- * @arg @ref LL_DMA_PERIPH_NOINCREMENT
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_SetPeriphIncMode(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t PeriphOrM2MSrcIncMode)
-{
- MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_PINC,
- PeriphOrM2MSrcIncMode);
-}
-
-/**
- * @brief Get Peripheral increment mode.
- * @rmtoll CCR PINC LL_DMA_GetPeriphIncMode
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_DMA_PERIPH_INCREMENT
- * @arg @ref LL_DMA_PERIPH_NOINCREMENT
- */
-__STATIC_INLINE uint32_t LL_DMA_GetPeriphIncMode(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
- DMA_CCR_PINC));
-}
-
-/**
- * @brief Set Memory increment mode.
- * @rmtoll CCR MINC LL_DMA_SetMemoryIncMode
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @param MemoryOrM2MDstIncMode This parameter can be one of the following values:
- * @arg @ref LL_DMA_MEMORY_INCREMENT
- * @arg @ref LL_DMA_MEMORY_NOINCREMENT
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_SetMemoryIncMode(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t MemoryOrM2MDstIncMode)
-{
- MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_MINC,
- MemoryOrM2MDstIncMode);
-}
-
-/**
- * @brief Get Memory increment mode.
- * @rmtoll CCR MINC LL_DMA_GetMemoryIncMode
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_DMA_MEMORY_INCREMENT
- * @arg @ref LL_DMA_MEMORY_NOINCREMENT
- */
-__STATIC_INLINE uint32_t LL_DMA_GetMemoryIncMode(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
- DMA_CCR_MINC));
-}
-
-/**
- * @brief Set Peripheral size.
- * @rmtoll CCR PSIZE LL_DMA_SetPeriphSize
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @param PeriphOrM2MSrcDataSize This parameter can be one of the following values:
- * @arg @ref LL_DMA_PDATAALIGN_BYTE
- * @arg @ref LL_DMA_PDATAALIGN_HALFWORD
- * @arg @ref LL_DMA_PDATAALIGN_WORD
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_SetPeriphSize(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t PeriphOrM2MSrcDataSize)
-{
- MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_PSIZE,
- PeriphOrM2MSrcDataSize);
-}
-
-/**
- * @brief Get Peripheral size.
- * @rmtoll CCR PSIZE LL_DMA_GetPeriphSize
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_DMA_PDATAALIGN_BYTE
- * @arg @ref LL_DMA_PDATAALIGN_HALFWORD
- * @arg @ref LL_DMA_PDATAALIGN_WORD
- */
-__STATIC_INLINE uint32_t LL_DMA_GetPeriphSize(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
- DMA_CCR_PSIZE));
-}
-
-/**
- * @brief Set Memory size.
- * @rmtoll CCR MSIZE LL_DMA_SetMemorySize
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @param MemoryOrM2MDstDataSize This parameter can be one of the following values:
- * @arg @ref LL_DMA_MDATAALIGN_BYTE
- * @arg @ref LL_DMA_MDATAALIGN_HALFWORD
- * @arg @ref LL_DMA_MDATAALIGN_WORD
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_SetMemorySize(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t MemoryOrM2MDstDataSize)
-{
- MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_MSIZE,
- MemoryOrM2MDstDataSize);
-}
-
-/**
- * @brief Get Memory size.
- * @rmtoll CCR MSIZE LL_DMA_GetMemorySize
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_DMA_MDATAALIGN_BYTE
- * @arg @ref LL_DMA_MDATAALIGN_HALFWORD
- * @arg @ref LL_DMA_MDATAALIGN_WORD
- */
-__STATIC_INLINE uint32_t LL_DMA_GetMemorySize(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
- DMA_CCR_MSIZE));
-}
-
-/**
- * @brief Set Channel priority level.
- * @rmtoll CCR PL LL_DMA_SetChannelPriorityLevel
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @param Priority This parameter can be one of the following values:
- * @arg @ref LL_DMA_PRIORITY_LOW
- * @arg @ref LL_DMA_PRIORITY_MEDIUM
- * @arg @ref LL_DMA_PRIORITY_HIGH
- * @arg @ref LL_DMA_PRIORITY_VERYHIGH
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_SetChannelPriorityLevel(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t Priority)
-{
- MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_PL,
- Priority);
-}
-
-/**
- * @brief Get Channel priority level.
- * @rmtoll CCR PL LL_DMA_GetChannelPriorityLevel
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_DMA_PRIORITY_LOW
- * @arg @ref LL_DMA_PRIORITY_MEDIUM
- * @arg @ref LL_DMA_PRIORITY_HIGH
- * @arg @ref LL_DMA_PRIORITY_VERYHIGH
- */
-__STATIC_INLINE uint32_t LL_DMA_GetChannelPriorityLevel(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
- DMA_CCR_PL));
-}
-
-/**
- * @brief Set Number of data to transfer.
- * @note This action has no effect if
- * channel is enabled.
- * @rmtoll CNDTR NDT LL_DMA_SetDataLength
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @param NbData Between Min_Data = 0 and Max_Data = 0x0000FFFF
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_SetDataLength(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t NbData)
-{
- MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CNDTR,
- DMA_CNDTR_NDT, NbData);
-}
-
-/**
- * @brief Get Number of data to transfer.
- * @note Once the channel is enabled, the return value indicate the
- * remaining bytes to be transmitted.
- * @rmtoll CNDTR NDT LL_DMA_GetDataLength
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
- */
-__STATIC_INLINE uint32_t LL_DMA_GetDataLength(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CNDTR,
- DMA_CNDTR_NDT));
-}
-
-/**
- * @brief Configure the Source and Destination addresses.
- * @note This API must not be called when the DMA channel is enabled.
- * @note Each IP using DMA provides an API to get directly the register adress (LL_PPP_DMA_GetRegAddr).
- * @rmtoll CPAR PA LL_DMA_ConfigAddresses\n
- * CMAR MA LL_DMA_ConfigAddresses
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @param SrcAddress Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
- * @param DstAddress Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
- * @param Direction This parameter can be one of the following values:
- * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_MEMORY
- * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_PERIPH
- * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_MEMORY
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ConfigAddresses(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t SrcAddress,
- uint32_t DstAddress, uint32_t Direction)
-{
- /* Direction Memory to Periph */
- if (Direction == LL_DMA_DIRECTION_MEMORY_TO_PERIPH)
- {
- WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CMAR, SrcAddress);
- WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CPAR, DstAddress);
- }
- /* Direction Periph to Memory and Memory to Memory */
- else
- {
- WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CPAR, SrcAddress);
- WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CMAR, DstAddress);
- }
-}
-
-/**
- * @brief Set the Memory address.
- * @note Interface used for direction LL_DMA_DIRECTION_PERIPH_TO_MEMORY or LL_DMA_DIRECTION_MEMORY_TO_PERIPH only.
- * @note This API must not be called when the DMA channel is enabled.
- * @rmtoll CMAR MA LL_DMA_SetMemoryAddress
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @param MemoryAddress Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_SetMemoryAddress(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t MemoryAddress)
-{
- WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CMAR, MemoryAddress);
-}
-
-/**
- * @brief Set the Peripheral address.
- * @note Interface used for direction LL_DMA_DIRECTION_PERIPH_TO_MEMORY or LL_DMA_DIRECTION_MEMORY_TO_PERIPH only.
- * @note This API must not be called when the DMA channel is enabled.
- * @rmtoll CPAR PA LL_DMA_SetPeriphAddress
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @param PeriphAddress Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_SetPeriphAddress(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t PeriphAddress)
-{
- WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CPAR, PeriphAddress);
-}
-
-/**
- * @brief Get Memory address.
- * @note Interface used for direction LL_DMA_DIRECTION_PERIPH_TO_MEMORY or LL_DMA_DIRECTION_MEMORY_TO_PERIPH only.
- * @rmtoll CMAR MA LL_DMA_GetMemoryAddress
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
- */
-__STATIC_INLINE uint32_t LL_DMA_GetMemoryAddress(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- return (READ_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CMAR));
-}
-
-/**
- * @brief Get Peripheral address.
- * @note Interface used for direction LL_DMA_DIRECTION_PERIPH_TO_MEMORY or LL_DMA_DIRECTION_MEMORY_TO_PERIPH only.
- * @rmtoll CPAR PA LL_DMA_GetPeriphAddress
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
- */
-__STATIC_INLINE uint32_t LL_DMA_GetPeriphAddress(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- return (READ_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CPAR));
-}
-
-/**
- * @brief Set the Memory to Memory Source address.
- * @note Interface used for direction LL_DMA_DIRECTION_MEMORY_TO_MEMORY only.
- * @note This API must not be called when the DMA channel is enabled.
- * @rmtoll CPAR PA LL_DMA_SetM2MSrcAddress
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @param MemoryAddress Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_SetM2MSrcAddress(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t MemoryAddress)
-{
- WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CPAR, MemoryAddress);
-}
-
-/**
- * @brief Set the Memory to Memory Destination address.
- * @note Interface used for direction LL_DMA_DIRECTION_MEMORY_TO_MEMORY only.
- * @note This API must not be called when the DMA channel is enabled.
- * @rmtoll CMAR MA LL_DMA_SetM2MDstAddress
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @param MemoryAddress Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_SetM2MDstAddress(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t MemoryAddress)
-{
- WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CMAR, MemoryAddress);
-}
-
-/**
- * @brief Get the Memory to Memory Source address.
- * @note Interface used for direction LL_DMA_DIRECTION_MEMORY_TO_MEMORY only.
- * @rmtoll CPAR PA LL_DMA_GetM2MSrcAddress
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
- */
-__STATIC_INLINE uint32_t LL_DMA_GetM2MSrcAddress(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- return (READ_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CPAR));
-}
-
-/**
- * @brief Get the Memory to Memory Destination address.
- * @note Interface used for direction LL_DMA_DIRECTION_MEMORY_TO_MEMORY only.
- * @rmtoll CMAR MA LL_DMA_GetM2MDstAddress
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
- */
-__STATIC_INLINE uint32_t LL_DMA_GetM2MDstAddress(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- return (READ_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CMAR));
-}
-
-/**
- * @}
- */
-
-/** @defgroup DMA_LL_EF_FLAG_Management FLAG_Management
- * @{
- */
-
-/**
- * @brief Get Channel 1 global interrupt flag.
- * @rmtoll ISR GIF1 LL_DMA_IsActiveFlag_GI1
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI1(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_GIF1) == (DMA_ISR_GIF1));
-}
-
-/**
- * @brief Get Channel 2 global interrupt flag.
- * @rmtoll ISR GIF2 LL_DMA_IsActiveFlag_GI2
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI2(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_GIF2) == (DMA_ISR_GIF2));
-}
-
-/**
- * @brief Get Channel 3 global interrupt flag.
- * @rmtoll ISR GIF3 LL_DMA_IsActiveFlag_GI3
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI3(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_GIF3) == (DMA_ISR_GIF3));
-}
-
-/**
- * @brief Get Channel 4 global interrupt flag.
- * @rmtoll ISR GIF4 LL_DMA_IsActiveFlag_GI4
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI4(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_GIF4) == (DMA_ISR_GIF4));
-}
-
-/**
- * @brief Get Channel 5 global interrupt flag.
- * @rmtoll ISR GIF5 LL_DMA_IsActiveFlag_GI5
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI5(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_GIF5) == (DMA_ISR_GIF5));
-}
-
-/**
- * @brief Get Channel 6 global interrupt flag.
- * @rmtoll ISR GIF6 LL_DMA_IsActiveFlag_GI6
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI6(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_GIF6) == (DMA_ISR_GIF6));
-}
-
-/**
- * @brief Get Channel 7 global interrupt flag.
- * @rmtoll ISR GIF7 LL_DMA_IsActiveFlag_GI7
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI7(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_GIF7) == (DMA_ISR_GIF7));
-}
-
-/**
- * @brief Get Channel 1 transfer complete flag.
- * @rmtoll ISR TCIF1 LL_DMA_IsActiveFlag_TC1
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC1(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF1) == (DMA_ISR_TCIF1));
-}
-
-/**
- * @brief Get Channel 2 transfer complete flag.
- * @rmtoll ISR TCIF2 LL_DMA_IsActiveFlag_TC2
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC2(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF2) == (DMA_ISR_TCIF2));
-}
-
-/**
- * @brief Get Channel 3 transfer complete flag.
- * @rmtoll ISR TCIF3 LL_DMA_IsActiveFlag_TC3
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC3(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF3) == (DMA_ISR_TCIF3));
-}
-
-/**
- * @brief Get Channel 4 transfer complete flag.
- * @rmtoll ISR TCIF4 LL_DMA_IsActiveFlag_TC4
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC4(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF4) == (DMA_ISR_TCIF4));
-}
-
-/**
- * @brief Get Channel 5 transfer complete flag.
- * @rmtoll ISR TCIF5 LL_DMA_IsActiveFlag_TC5
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC5(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF5) == (DMA_ISR_TCIF5));
-}
-
-/**
- * @brief Get Channel 6 transfer complete flag.
- * @rmtoll ISR TCIF6 LL_DMA_IsActiveFlag_TC6
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC6(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF6) == (DMA_ISR_TCIF6));
-}
-
-/**
- * @brief Get Channel 7 transfer complete flag.
- * @rmtoll ISR TCIF7 LL_DMA_IsActiveFlag_TC7
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC7(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF7) == (DMA_ISR_TCIF7));
-}
-
-/**
- * @brief Get Channel 1 half transfer flag.
- * @rmtoll ISR HTIF1 LL_DMA_IsActiveFlag_HT1
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT1(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF1) == (DMA_ISR_HTIF1));
-}
-
-/**
- * @brief Get Channel 2 half transfer flag.
- * @rmtoll ISR HTIF2 LL_DMA_IsActiveFlag_HT2
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT2(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF2) == (DMA_ISR_HTIF2));
-}
-
-/**
- * @brief Get Channel 3 half transfer flag.
- * @rmtoll ISR HTIF3 LL_DMA_IsActiveFlag_HT3
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT3(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF3) == (DMA_ISR_HTIF3));
-}
-
-/**
- * @brief Get Channel 4 half transfer flag.
- * @rmtoll ISR HTIF4 LL_DMA_IsActiveFlag_HT4
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT4(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF4) == (DMA_ISR_HTIF4));
-}
-
-/**
- * @brief Get Channel 5 half transfer flag.
- * @rmtoll ISR HTIF5 LL_DMA_IsActiveFlag_HT5
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT5(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF5) == (DMA_ISR_HTIF5));
-}
-
-/**
- * @brief Get Channel 6 half transfer flag.
- * @rmtoll ISR HTIF6 LL_DMA_IsActiveFlag_HT6
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT6(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF6) == (DMA_ISR_HTIF6));
-}
-
-/**
- * @brief Get Channel 7 half transfer flag.
- * @rmtoll ISR HTIF7 LL_DMA_IsActiveFlag_HT7
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT7(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF7) == (DMA_ISR_HTIF7));
-}
-
-/**
- * @brief Get Channel 1 transfer error flag.
- * @rmtoll ISR TEIF1 LL_DMA_IsActiveFlag_TE1
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE1(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF1) == (DMA_ISR_TEIF1));
-}
-
-/**
- * @brief Get Channel 2 transfer error flag.
- * @rmtoll ISR TEIF2 LL_DMA_IsActiveFlag_TE2
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE2(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF2) == (DMA_ISR_TEIF2));
-}
-
-/**
- * @brief Get Channel 3 transfer error flag.
- * @rmtoll ISR TEIF3 LL_DMA_IsActiveFlag_TE3
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE3(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF3) == (DMA_ISR_TEIF3));
-}
-
-/**
- * @brief Get Channel 4 transfer error flag.
- * @rmtoll ISR TEIF4 LL_DMA_IsActiveFlag_TE4
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE4(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF4) == (DMA_ISR_TEIF4));
-}
-
-/**
- * @brief Get Channel 5 transfer error flag.
- * @rmtoll ISR TEIF5 LL_DMA_IsActiveFlag_TE5
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE5(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF5) == (DMA_ISR_TEIF5));
-}
-
-/**
- * @brief Get Channel 6 transfer error flag.
- * @rmtoll ISR TEIF6 LL_DMA_IsActiveFlag_TE6
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE6(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF6) == (DMA_ISR_TEIF6));
-}
-
-/**
- * @brief Get Channel 7 transfer error flag.
- * @rmtoll ISR TEIF7 LL_DMA_IsActiveFlag_TE7
- * @param DMAx DMAx Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE7(DMA_TypeDef *DMAx)
-{
- return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF7) == (DMA_ISR_TEIF7));
-}
-
-/**
- * @brief Clear Channel 1 global interrupt flag.
- * @rmtoll IFCR CGIF1 LL_DMA_ClearFlag_GI1
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_GI1(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF1);
-}
-
-/**
- * @brief Clear Channel 2 global interrupt flag.
- * @rmtoll IFCR CGIF2 LL_DMA_ClearFlag_GI2
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_GI2(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF2);
-}
-
-/**
- * @brief Clear Channel 3 global interrupt flag.
- * @rmtoll IFCR CGIF3 LL_DMA_ClearFlag_GI3
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_GI3(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF3);
-}
-
-/**
- * @brief Clear Channel 4 global interrupt flag.
- * @rmtoll IFCR CGIF4 LL_DMA_ClearFlag_GI4
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_GI4(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF4);
-}
-
-/**
- * @brief Clear Channel 5 global interrupt flag.
- * @rmtoll IFCR CGIF5 LL_DMA_ClearFlag_GI5
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_GI5(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF5);
-}
-
-/**
- * @brief Clear Channel 6 global interrupt flag.
- * @rmtoll IFCR CGIF6 LL_DMA_ClearFlag_GI6
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_GI6(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF6);
-}
-
-/**
- * @brief Clear Channel 7 global interrupt flag.
- * @rmtoll IFCR CGIF7 LL_DMA_ClearFlag_GI7
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_GI7(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF7);
-}
-
-/**
- * @brief Clear Channel 1 transfer complete flag.
- * @rmtoll IFCR CTCIF1 LL_DMA_ClearFlag_TC1
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_TC1(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF1);
-}
-
-/**
- * @brief Clear Channel 2 transfer complete flag.
- * @rmtoll IFCR CTCIF2 LL_DMA_ClearFlag_TC2
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_TC2(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF2);
-}
-
-/**
- * @brief Clear Channel 3 transfer complete flag.
- * @rmtoll IFCR CTCIF3 LL_DMA_ClearFlag_TC3
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_TC3(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF3);
-}
-
-/**
- * @brief Clear Channel 4 transfer complete flag.
- * @rmtoll IFCR CTCIF4 LL_DMA_ClearFlag_TC4
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_TC4(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF4);
-}
-
-/**
- * @brief Clear Channel 5 transfer complete flag.
- * @rmtoll IFCR CTCIF5 LL_DMA_ClearFlag_TC5
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_TC5(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF5);
-}
-
-/**
- * @brief Clear Channel 6 transfer complete flag.
- * @rmtoll IFCR CTCIF6 LL_DMA_ClearFlag_TC6
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_TC6(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF6);
-}
-
-/**
- * @brief Clear Channel 7 transfer complete flag.
- * @rmtoll IFCR CTCIF7 LL_DMA_ClearFlag_TC7
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_TC7(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF7);
-}
-
-/**
- * @brief Clear Channel 1 half transfer flag.
- * @rmtoll IFCR CHTIF1 LL_DMA_ClearFlag_HT1
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_HT1(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF1);
-}
-
-/**
- * @brief Clear Channel 2 half transfer flag.
- * @rmtoll IFCR CHTIF2 LL_DMA_ClearFlag_HT2
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_HT2(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF2);
-}
-
-/**
- * @brief Clear Channel 3 half transfer flag.
- * @rmtoll IFCR CHTIF3 LL_DMA_ClearFlag_HT3
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_HT3(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF3);
-}
-
-/**
- * @brief Clear Channel 4 half transfer flag.
- * @rmtoll IFCR CHTIF4 LL_DMA_ClearFlag_HT4
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_HT4(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF4);
-}
-
-/**
- * @brief Clear Channel 5 half transfer flag.
- * @rmtoll IFCR CHTIF5 LL_DMA_ClearFlag_HT5
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_HT5(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF5);
-}
-
-/**
- * @brief Clear Channel 6 half transfer flag.
- * @rmtoll IFCR CHTIF6 LL_DMA_ClearFlag_HT6
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_HT6(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF6);
-}
-
-/**
- * @brief Clear Channel 7 half transfer flag.
- * @rmtoll IFCR CHTIF7 LL_DMA_ClearFlag_HT7
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_HT7(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF7);
-}
-
-/**
- * @brief Clear Channel 1 transfer error flag.
- * @rmtoll IFCR CTEIF1 LL_DMA_ClearFlag_TE1
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_TE1(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF1);
-}
-
-/**
- * @brief Clear Channel 2 transfer error flag.
- * @rmtoll IFCR CTEIF2 LL_DMA_ClearFlag_TE2
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_TE2(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF2);
-}
-
-/**
- * @brief Clear Channel 3 transfer error flag.
- * @rmtoll IFCR CTEIF3 LL_DMA_ClearFlag_TE3
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_TE3(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF3);
-}
-
-/**
- * @brief Clear Channel 4 transfer error flag.
- * @rmtoll IFCR CTEIF4 LL_DMA_ClearFlag_TE4
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_TE4(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF4);
-}
-
-/**
- * @brief Clear Channel 5 transfer error flag.
- * @rmtoll IFCR CTEIF5 LL_DMA_ClearFlag_TE5
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_TE5(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF5);
-}
-
-/**
- * @brief Clear Channel 6 transfer error flag.
- * @rmtoll IFCR CTEIF6 LL_DMA_ClearFlag_TE6
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_TE6(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF6);
-}
-
-/**
- * @brief Clear Channel 7 transfer error flag.
- * @rmtoll IFCR CTEIF7 LL_DMA_ClearFlag_TE7
- * @param DMAx DMAx Instance
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_ClearFlag_TE7(DMA_TypeDef *DMAx)
-{
- WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF7);
-}
-
-/**
- * @}
- */
-
-/** @defgroup DMA_LL_EF_IT_Management IT_Management
- * @{
- */
-
-/**
- * @brief Enable Transfer complete interrupt.
- * @rmtoll CCR TCIE LL_DMA_EnableIT_TC
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_EnableIT_TC(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- SET_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_TCIE);
-}
-
-/**
- * @brief Enable Half transfer interrupt.
- * @rmtoll CCR HTIE LL_DMA_EnableIT_HT
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_EnableIT_HT(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- SET_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_HTIE);
-}
-
-/**
- * @brief Enable Transfer error interrupt.
- * @rmtoll CCR TEIE LL_DMA_EnableIT_TE
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_EnableIT_TE(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- SET_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_TEIE);
-}
-
-/**
- * @brief Disable Transfer complete interrupt.
- * @rmtoll CCR TCIE LL_DMA_DisableIT_TC
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_DisableIT_TC(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- CLEAR_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_TCIE);
-}
-
-/**
- * @brief Disable Half transfer interrupt.
- * @rmtoll CCR HTIE LL_DMA_DisableIT_HT
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_DisableIT_HT(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- CLEAR_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_HTIE);
-}
-
-/**
- * @brief Disable Transfer error interrupt.
- * @rmtoll CCR TEIE LL_DMA_DisableIT_TE
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval None
- */
-__STATIC_INLINE void LL_DMA_DisableIT_TE(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- CLEAR_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_TEIE);
-}
-
-/**
- * @brief Check if Transfer complete Interrupt is enabled.
- * @rmtoll CCR TCIE LL_DMA_IsEnabledIT_TC
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsEnabledIT_TC(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
- DMA_CCR_TCIE) == (DMA_CCR_TCIE));
-}
-
-/**
- * @brief Check if Half transfer Interrupt is enabled.
- * @rmtoll CCR HTIE LL_DMA_IsEnabledIT_HT
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsEnabledIT_HT(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
- DMA_CCR_HTIE) == (DMA_CCR_HTIE));
-}
-
-/**
- * @brief Check if Transfer error Interrupt is enabled.
- * @rmtoll CCR TEIE LL_DMA_IsEnabledIT_TE
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_DMA_IsEnabledIT_TE(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
- DMA_CCR_TEIE) == (DMA_CCR_TEIE));
-}
-
-/**
- * @}
- */
-
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup DMA_LL_EF_Init Initialization and de-initialization functions
- * @{
- */
-
-uint32_t LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Channel, LL_DMA_InitTypeDef *DMA_InitStruct);
-uint32_t LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Channel);
-void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct);
-
-/**
- * @}
- */
-#endif /* USE_FULL_LL_DRIVER */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* DMA1 || DMA2 */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_LL_DMA_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_exti.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_exti.h
deleted file mode 100644
index fd17bcc..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_exti.h
+++ /dev/null
@@ -1,904 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_exti.h
- * @author MCD Application Team
- * @brief Header file of EXTI LL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_LL_EXTI_H
-#define __STM32F1xx_LL_EXTI_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx.h"
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined (EXTI)
-
-/** @defgroup EXTI_LL EXTI
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private Macros ------------------------------------------------------------*/
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup EXTI_LL_Private_Macros EXTI Private Macros
- * @{
- */
-/**
- * @}
- */
-#endif /*USE_FULL_LL_DRIVER*/
-/* Exported types ------------------------------------------------------------*/
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup EXTI_LL_ES_INIT EXTI Exported Init structure
- * @{
- */
-typedef struct
-{
-
- uint32_t Line_0_31; /*!< Specifies the EXTI lines to be enabled or disabled for Lines in range 0 to 31
- This parameter can be any combination of @ref EXTI_LL_EC_LINE */
-
- FunctionalState LineCommand; /*!< Specifies the new state of the selected EXTI lines.
- This parameter can be set either to ENABLE or DISABLE */
-
- uint8_t Mode; /*!< Specifies the mode for the EXTI lines.
- This parameter can be a value of @ref EXTI_LL_EC_MODE. */
-
- uint8_t Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.
- This parameter can be a value of @ref EXTI_LL_EC_TRIGGER. */
-} LL_EXTI_InitTypeDef;
-
-/**
- * @}
- */
-#endif /*USE_FULL_LL_DRIVER*/
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup EXTI_LL_Exported_Constants EXTI Exported Constants
- * @{
- */
-
-/** @defgroup EXTI_LL_EC_LINE LINE
- * @{
- */
-#define LL_EXTI_LINE_0 EXTI_IMR_IM0 /*!< Extended line 0 */
-#define LL_EXTI_LINE_1 EXTI_IMR_IM1 /*!< Extended line 1 */
-#define LL_EXTI_LINE_2 EXTI_IMR_IM2 /*!< Extended line 2 */
-#define LL_EXTI_LINE_3 EXTI_IMR_IM3 /*!< Extended line 3 */
-#define LL_EXTI_LINE_4 EXTI_IMR_IM4 /*!< Extended line 4 */
-#define LL_EXTI_LINE_5 EXTI_IMR_IM5 /*!< Extended line 5 */
-#define LL_EXTI_LINE_6 EXTI_IMR_IM6 /*!< Extended line 6 */
-#define LL_EXTI_LINE_7 EXTI_IMR_IM7 /*!< Extended line 7 */
-#define LL_EXTI_LINE_8 EXTI_IMR_IM8 /*!< Extended line 8 */
-#define LL_EXTI_LINE_9 EXTI_IMR_IM9 /*!< Extended line 9 */
-#define LL_EXTI_LINE_10 EXTI_IMR_IM10 /*!< Extended line 10 */
-#define LL_EXTI_LINE_11 EXTI_IMR_IM11 /*!< Extended line 11 */
-#define LL_EXTI_LINE_12 EXTI_IMR_IM12 /*!< Extended line 12 */
-#define LL_EXTI_LINE_13 EXTI_IMR_IM13 /*!< Extended line 13 */
-#define LL_EXTI_LINE_14 EXTI_IMR_IM14 /*!< Extended line 14 */
-#define LL_EXTI_LINE_15 EXTI_IMR_IM15 /*!< Extended line 15 */
-#if defined(EXTI_IMR_IM16)
-#define LL_EXTI_LINE_16 EXTI_IMR_IM16 /*!< Extended line 16 */
-#endif
-#define LL_EXTI_LINE_17 EXTI_IMR_IM17 /*!< Extended line 17 */
-#if defined(EXTI_IMR_IM18)
-#define LL_EXTI_LINE_18 EXTI_IMR_IM18 /*!< Extended line 18 */
-#endif
-#if defined(EXTI_IMR_IM19)
-#define LL_EXTI_LINE_19 EXTI_IMR_IM19 /*!< Extended line 19 */
-#endif
-#if defined(EXTI_IMR_IM20)
-#define LL_EXTI_LINE_20 EXTI_IMR_IM20 /*!< Extended line 20 */
-#endif
-#if defined(EXTI_IMR_IM21)
-#define LL_EXTI_LINE_21 EXTI_IMR_IM21 /*!< Extended line 21 */
-#endif
-#if defined(EXTI_IMR_IM22)
-#define LL_EXTI_LINE_22 EXTI_IMR_IM22 /*!< Extended line 22 */
-#endif
-#if defined(EXTI_IMR_IM23)
-#define LL_EXTI_LINE_23 EXTI_IMR_IM23 /*!< Extended line 23 */
-#endif
-#if defined(EXTI_IMR_IM24)
-#define LL_EXTI_LINE_24 EXTI_IMR_IM24 /*!< Extended line 24 */
-#endif
-#if defined(EXTI_IMR_IM25)
-#define LL_EXTI_LINE_25 EXTI_IMR_IM25 /*!< Extended line 25 */
-#endif
-#if defined(EXTI_IMR_IM26)
-#define LL_EXTI_LINE_26 EXTI_IMR_IM26 /*!< Extended line 26 */
-#endif
-#if defined(EXTI_IMR_IM27)
-#define LL_EXTI_LINE_27 EXTI_IMR_IM27 /*!< Extended line 27 */
-#endif
-#if defined(EXTI_IMR_IM28)
-#define LL_EXTI_LINE_28 EXTI_IMR_IM28 /*!< Extended line 28 */
-#endif
-#if defined(EXTI_IMR_IM29)
-#define LL_EXTI_LINE_29 EXTI_IMR_IM29 /*!< Extended line 29 */
-#endif
-#if defined(EXTI_IMR_IM30)
-#define LL_EXTI_LINE_30 EXTI_IMR_IM30 /*!< Extended line 30 */
-#endif
-#if defined(EXTI_IMR_IM31)
-#define LL_EXTI_LINE_31 EXTI_IMR_IM31 /*!< Extended line 31 */
-#endif
-#define LL_EXTI_LINE_ALL_0_31 EXTI_IMR_IM /*!< All Extended line not reserved*/
-
-
-#define LL_EXTI_LINE_ALL (0xFFFFFFFFU) /*!< All Extended line */
-
-#if defined(USE_FULL_LL_DRIVER)
-#define LL_EXTI_LINE_NONE (0x00000000U) /*!< None Extended line */
-#endif /*USE_FULL_LL_DRIVER*/
-
-/**
- * @}
- */
-#if defined(USE_FULL_LL_DRIVER)
-
-/** @defgroup EXTI_LL_EC_MODE Mode
- * @{
- */
-#define LL_EXTI_MODE_IT ((uint8_t)0x00) /*!< Interrupt Mode */
-#define LL_EXTI_MODE_EVENT ((uint8_t)0x01) /*!< Event Mode */
-#define LL_EXTI_MODE_IT_EVENT ((uint8_t)0x02) /*!< Interrupt & Event Mode */
-/**
- * @}
- */
-
-/** @defgroup EXTI_LL_EC_TRIGGER Edge Trigger
- * @{
- */
-#define LL_EXTI_TRIGGER_NONE ((uint8_t)0x00) /*!< No Trigger Mode */
-#define LL_EXTI_TRIGGER_RISING ((uint8_t)0x01) /*!< Trigger Rising Mode */
-#define LL_EXTI_TRIGGER_FALLING ((uint8_t)0x02) /*!< Trigger Falling Mode */
-#define LL_EXTI_TRIGGER_RISING_FALLING ((uint8_t)0x03) /*!< Trigger Rising & Falling Mode */
-
-/**
- * @}
- */
-
-
-#endif /*USE_FULL_LL_DRIVER*/
-
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup EXTI_LL_Exported_Macros EXTI Exported Macros
- * @{
- */
-
-/** @defgroup EXTI_LL_EM_WRITE_READ Common Write and read registers Macros
- * @{
- */
-
-/**
- * @brief Write a value in EXTI register
- * @param __REG__ Register to be written
- * @param __VALUE__ Value to be written in the register
- * @retval None
- */
-#define LL_EXTI_WriteReg(__REG__, __VALUE__) WRITE_REG(EXTI->__REG__, (__VALUE__))
-
-/**
- * @brief Read a value in EXTI register
- * @param __REG__ Register to be read
- * @retval Register value
- */
-#define LL_EXTI_ReadReg(__REG__) READ_REG(EXTI->__REG__)
-/**
- * @}
- */
-
-
-/**
- * @}
- */
-
-
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup EXTI_LL_Exported_Functions EXTI Exported Functions
- * @{
- */
-/** @defgroup EXTI_LL_EF_IT_Management IT_Management
- * @{
- */
-
-/**
- * @brief Enable ExtiLine Interrupt request for Lines in range 0 to 31
- * @note The reset value for the direct or internal lines (see RM)
- * is set to 1 in order to enable the interrupt by default.
- * Bits are set automatically at Power on.
- * @rmtoll IMR IMx LL_EXTI_EnableIT_0_31
- * @param ExtiLine This parameter can be one of the following values:
- * @arg @ref LL_EXTI_LINE_0
- * @arg @ref LL_EXTI_LINE_1
- * @arg @ref LL_EXTI_LINE_2
- * @arg @ref LL_EXTI_LINE_3
- * @arg @ref LL_EXTI_LINE_4
- * @arg @ref LL_EXTI_LINE_5
- * @arg @ref LL_EXTI_LINE_6
- * @arg @ref LL_EXTI_LINE_7
- * @arg @ref LL_EXTI_LINE_8
- * @arg @ref LL_EXTI_LINE_9
- * @arg @ref LL_EXTI_LINE_10
- * @arg @ref LL_EXTI_LINE_11
- * @arg @ref LL_EXTI_LINE_12
- * @arg @ref LL_EXTI_LINE_13
- * @arg @ref LL_EXTI_LINE_14
- * @arg @ref LL_EXTI_LINE_15
- * @arg @ref LL_EXTI_LINE_16
- * @arg @ref LL_EXTI_LINE_17
- * @arg @ref LL_EXTI_LINE_18
- * @arg @ref LL_EXTI_LINE_19
- * @arg @ref LL_EXTI_LINE_ALL_0_31
- * @note Please check each device line mapping for EXTI Line availability
- * @retval None
- */
-__STATIC_INLINE void LL_EXTI_EnableIT_0_31(uint32_t ExtiLine)
-{
- SET_BIT(EXTI->IMR, ExtiLine);
-}
-
-/**
- * @brief Disable ExtiLine Interrupt request for Lines in range 0 to 31
- * @note The reset value for the direct or internal lines (see RM)
- * is set to 1 in order to enable the interrupt by default.
- * Bits are set automatically at Power on.
- * @rmtoll IMR IMx LL_EXTI_DisableIT_0_31
- * @param ExtiLine This parameter can be one of the following values:
- * @arg @ref LL_EXTI_LINE_0
- * @arg @ref LL_EXTI_LINE_1
- * @arg @ref LL_EXTI_LINE_2
- * @arg @ref LL_EXTI_LINE_3
- * @arg @ref LL_EXTI_LINE_4
- * @arg @ref LL_EXTI_LINE_5
- * @arg @ref LL_EXTI_LINE_6
- * @arg @ref LL_EXTI_LINE_7
- * @arg @ref LL_EXTI_LINE_8
- * @arg @ref LL_EXTI_LINE_9
- * @arg @ref LL_EXTI_LINE_10
- * @arg @ref LL_EXTI_LINE_11
- * @arg @ref LL_EXTI_LINE_12
- * @arg @ref LL_EXTI_LINE_13
- * @arg @ref LL_EXTI_LINE_14
- * @arg @ref LL_EXTI_LINE_15
- * @arg @ref LL_EXTI_LINE_16
- * @arg @ref LL_EXTI_LINE_17
- * @arg @ref LL_EXTI_LINE_18
- * @arg @ref LL_EXTI_LINE_19
- * @arg @ref LL_EXTI_LINE_ALL_0_31
- * @note Please check each device line mapping for EXTI Line availability
- * @retval None
- */
-__STATIC_INLINE void LL_EXTI_DisableIT_0_31(uint32_t ExtiLine)
-{
- CLEAR_BIT(EXTI->IMR, ExtiLine);
-}
-
-
-/**
- * @brief Indicate if ExtiLine Interrupt request is enabled for Lines in range 0 to 31
- * @note The reset value for the direct or internal lines (see RM)
- * is set to 1 in order to enable the interrupt by default.
- * Bits are set automatically at Power on.
- * @rmtoll IMR IMx LL_EXTI_IsEnabledIT_0_31
- * @param ExtiLine This parameter can be one of the following values:
- * @arg @ref LL_EXTI_LINE_0
- * @arg @ref LL_EXTI_LINE_1
- * @arg @ref LL_EXTI_LINE_2
- * @arg @ref LL_EXTI_LINE_3
- * @arg @ref LL_EXTI_LINE_4
- * @arg @ref LL_EXTI_LINE_5
- * @arg @ref LL_EXTI_LINE_6
- * @arg @ref LL_EXTI_LINE_7
- * @arg @ref LL_EXTI_LINE_8
- * @arg @ref LL_EXTI_LINE_9
- * @arg @ref LL_EXTI_LINE_10
- * @arg @ref LL_EXTI_LINE_11
- * @arg @ref LL_EXTI_LINE_12
- * @arg @ref LL_EXTI_LINE_13
- * @arg @ref LL_EXTI_LINE_14
- * @arg @ref LL_EXTI_LINE_15
- * @arg @ref LL_EXTI_LINE_16
- * @arg @ref LL_EXTI_LINE_17
- * @arg @ref LL_EXTI_LINE_18
- * @arg @ref LL_EXTI_LINE_19
- * @arg @ref LL_EXTI_LINE_ALL_0_31
- * @note Please check each device line mapping for EXTI Line availability
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_EXTI_IsEnabledIT_0_31(uint32_t ExtiLine)
-{
- return (READ_BIT(EXTI->IMR, ExtiLine) == (ExtiLine));
-}
-
-
-/**
- * @}
- */
-
-/** @defgroup EXTI_LL_EF_Event_Management Event_Management
- * @{
- */
-
-/**
- * @brief Enable ExtiLine Event request for Lines in range 0 to 31
- * @rmtoll EMR EMx LL_EXTI_EnableEvent_0_31
- * @param ExtiLine This parameter can be one of the following values:
- * @arg @ref LL_EXTI_LINE_0
- * @arg @ref LL_EXTI_LINE_1
- * @arg @ref LL_EXTI_LINE_2
- * @arg @ref LL_EXTI_LINE_3
- * @arg @ref LL_EXTI_LINE_4
- * @arg @ref LL_EXTI_LINE_5
- * @arg @ref LL_EXTI_LINE_6
- * @arg @ref LL_EXTI_LINE_7
- * @arg @ref LL_EXTI_LINE_8
- * @arg @ref LL_EXTI_LINE_9
- * @arg @ref LL_EXTI_LINE_10
- * @arg @ref LL_EXTI_LINE_11
- * @arg @ref LL_EXTI_LINE_12
- * @arg @ref LL_EXTI_LINE_13
- * @arg @ref LL_EXTI_LINE_14
- * @arg @ref LL_EXTI_LINE_15
- * @arg @ref LL_EXTI_LINE_16
- * @arg @ref LL_EXTI_LINE_17
- * @arg @ref LL_EXTI_LINE_18
- * @arg @ref LL_EXTI_LINE_19
- * @arg @ref LL_EXTI_LINE_ALL_0_31
- * @note Please check each device line mapping for EXTI Line availability
- * @retval None
- */
-__STATIC_INLINE void LL_EXTI_EnableEvent_0_31(uint32_t ExtiLine)
-{
- SET_BIT(EXTI->EMR, ExtiLine);
-
-}
-
-
-/**
- * @brief Disable ExtiLine Event request for Lines in range 0 to 31
- * @rmtoll EMR EMx LL_EXTI_DisableEvent_0_31
- * @param ExtiLine This parameter can be one of the following values:
- * @arg @ref LL_EXTI_LINE_0
- * @arg @ref LL_EXTI_LINE_1
- * @arg @ref LL_EXTI_LINE_2
- * @arg @ref LL_EXTI_LINE_3
- * @arg @ref LL_EXTI_LINE_4
- * @arg @ref LL_EXTI_LINE_5
- * @arg @ref LL_EXTI_LINE_6
- * @arg @ref LL_EXTI_LINE_7
- * @arg @ref LL_EXTI_LINE_8
- * @arg @ref LL_EXTI_LINE_9
- * @arg @ref LL_EXTI_LINE_10
- * @arg @ref LL_EXTI_LINE_11
- * @arg @ref LL_EXTI_LINE_12
- * @arg @ref LL_EXTI_LINE_13
- * @arg @ref LL_EXTI_LINE_14
- * @arg @ref LL_EXTI_LINE_15
- * @arg @ref LL_EXTI_LINE_16
- * @arg @ref LL_EXTI_LINE_17
- * @arg @ref LL_EXTI_LINE_18
- * @arg @ref LL_EXTI_LINE_19
- * @arg @ref LL_EXTI_LINE_ALL_0_31
- * @note Please check each device line mapping for EXTI Line availability
- * @retval None
- */
-__STATIC_INLINE void LL_EXTI_DisableEvent_0_31(uint32_t ExtiLine)
-{
- CLEAR_BIT(EXTI->EMR, ExtiLine);
-}
-
-
-/**
- * @brief Indicate if ExtiLine Event request is enabled for Lines in range 0 to 31
- * @rmtoll EMR EMx LL_EXTI_IsEnabledEvent_0_31
- * @param ExtiLine This parameter can be one of the following values:
- * @arg @ref LL_EXTI_LINE_0
- * @arg @ref LL_EXTI_LINE_1
- * @arg @ref LL_EXTI_LINE_2
- * @arg @ref LL_EXTI_LINE_3
- * @arg @ref LL_EXTI_LINE_4
- * @arg @ref LL_EXTI_LINE_5
- * @arg @ref LL_EXTI_LINE_6
- * @arg @ref LL_EXTI_LINE_7
- * @arg @ref LL_EXTI_LINE_8
- * @arg @ref LL_EXTI_LINE_9
- * @arg @ref LL_EXTI_LINE_10
- * @arg @ref LL_EXTI_LINE_11
- * @arg @ref LL_EXTI_LINE_12
- * @arg @ref LL_EXTI_LINE_13
- * @arg @ref LL_EXTI_LINE_14
- * @arg @ref LL_EXTI_LINE_15
- * @arg @ref LL_EXTI_LINE_16
- * @arg @ref LL_EXTI_LINE_17
- * @arg @ref LL_EXTI_LINE_18
- * @arg @ref LL_EXTI_LINE_19
- * @arg @ref LL_EXTI_LINE_ALL_0_31
- * @note Please check each device line mapping for EXTI Line availability
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_EXTI_IsEnabledEvent_0_31(uint32_t ExtiLine)
-{
- return (READ_BIT(EXTI->EMR, ExtiLine) == (ExtiLine));
-
-}
-
-
-/**
- * @}
- */
-
-/** @defgroup EXTI_LL_EF_Rising_Trigger_Management Rising_Trigger_Management
- * @{
- */
-
-/**
- * @brief Enable ExtiLine Rising Edge Trigger for Lines in range 0 to 31
- * @note The configurable wakeup lines are edge-triggered. No glitch must be
- * generated on these lines. If a rising edge on a configurable interrupt
- * line occurs during a write operation in the EXTI_RTSR register, the
- * pending bit is not set.
- * Rising and falling edge triggers can be set for
- * the same interrupt line. In this case, both generate a trigger
- * condition.
- * @rmtoll RTSR RTx LL_EXTI_EnableRisingTrig_0_31
- * @param ExtiLine This parameter can be a combination of the following values:
- * @arg @ref LL_EXTI_LINE_0
- * @arg @ref LL_EXTI_LINE_1
- * @arg @ref LL_EXTI_LINE_2
- * @arg @ref LL_EXTI_LINE_3
- * @arg @ref LL_EXTI_LINE_4
- * @arg @ref LL_EXTI_LINE_5
- * @arg @ref LL_EXTI_LINE_6
- * @arg @ref LL_EXTI_LINE_7
- * @arg @ref LL_EXTI_LINE_8
- * @arg @ref LL_EXTI_LINE_9
- * @arg @ref LL_EXTI_LINE_10
- * @arg @ref LL_EXTI_LINE_11
- * @arg @ref LL_EXTI_LINE_12
- * @arg @ref LL_EXTI_LINE_13
- * @arg @ref LL_EXTI_LINE_14
- * @arg @ref LL_EXTI_LINE_15
- * @arg @ref LL_EXTI_LINE_16
- * @arg @ref LL_EXTI_LINE_18
- * @arg @ref LL_EXTI_LINE_19
- * @note Please check each device line mapping for EXTI Line availability
- * @retval None
- */
-__STATIC_INLINE void LL_EXTI_EnableRisingTrig_0_31(uint32_t ExtiLine)
-{
- SET_BIT(EXTI->RTSR, ExtiLine);
-
-}
-
-
-/**
- * @brief Disable ExtiLine Rising Edge Trigger for Lines in range 0 to 31
- * @note The configurable wakeup lines are edge-triggered. No glitch must be
- * generated on these lines. If a rising edge on a configurable interrupt
- * line occurs during a write operation in the EXTI_RTSR register, the
- * pending bit is not set.
- * Rising and falling edge triggers can be set for
- * the same interrupt line. In this case, both generate a trigger
- * condition.
- * @rmtoll RTSR RTx LL_EXTI_DisableRisingTrig_0_31
- * @param ExtiLine This parameter can be a combination of the following values:
- * @arg @ref LL_EXTI_LINE_0
- * @arg @ref LL_EXTI_LINE_1
- * @arg @ref LL_EXTI_LINE_2
- * @arg @ref LL_EXTI_LINE_3
- * @arg @ref LL_EXTI_LINE_4
- * @arg @ref LL_EXTI_LINE_5
- * @arg @ref LL_EXTI_LINE_6
- * @arg @ref LL_EXTI_LINE_7
- * @arg @ref LL_EXTI_LINE_8
- * @arg @ref LL_EXTI_LINE_9
- * @arg @ref LL_EXTI_LINE_10
- * @arg @ref LL_EXTI_LINE_11
- * @arg @ref LL_EXTI_LINE_12
- * @arg @ref LL_EXTI_LINE_13
- * @arg @ref LL_EXTI_LINE_14
- * @arg @ref LL_EXTI_LINE_15
- * @arg @ref LL_EXTI_LINE_16
- * @arg @ref LL_EXTI_LINE_18
- * @arg @ref LL_EXTI_LINE_19
- * @note Please check each device line mapping for EXTI Line availability
- * @retval None
- */
-__STATIC_INLINE void LL_EXTI_DisableRisingTrig_0_31(uint32_t ExtiLine)
-{
- CLEAR_BIT(EXTI->RTSR, ExtiLine);
-
-}
-
-
-/**
- * @brief Check if rising edge trigger is enabled for Lines in range 0 to 31
- * @rmtoll RTSR RTx LL_EXTI_IsEnabledRisingTrig_0_31
- * @param ExtiLine This parameter can be a combination of the following values:
- * @arg @ref LL_EXTI_LINE_0
- * @arg @ref LL_EXTI_LINE_1
- * @arg @ref LL_EXTI_LINE_2
- * @arg @ref LL_EXTI_LINE_3
- * @arg @ref LL_EXTI_LINE_4
- * @arg @ref LL_EXTI_LINE_5
- * @arg @ref LL_EXTI_LINE_6
- * @arg @ref LL_EXTI_LINE_7
- * @arg @ref LL_EXTI_LINE_8
- * @arg @ref LL_EXTI_LINE_9
- * @arg @ref LL_EXTI_LINE_10
- * @arg @ref LL_EXTI_LINE_11
- * @arg @ref LL_EXTI_LINE_12
- * @arg @ref LL_EXTI_LINE_13
- * @arg @ref LL_EXTI_LINE_14
- * @arg @ref LL_EXTI_LINE_15
- * @arg @ref LL_EXTI_LINE_16
- * @arg @ref LL_EXTI_LINE_18
- * @arg @ref LL_EXTI_LINE_19
- * @note Please check each device line mapping for EXTI Line availability
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_EXTI_IsEnabledRisingTrig_0_31(uint32_t ExtiLine)
-{
- return (READ_BIT(EXTI->RTSR, ExtiLine) == (ExtiLine));
-}
-
-
-/**
- * @}
- */
-
-/** @defgroup EXTI_LL_EF_Falling_Trigger_Management Falling_Trigger_Management
- * @{
- */
-
-/**
- * @brief Enable ExtiLine Falling Edge Trigger for Lines in range 0 to 31
- * @note The configurable wakeup lines are edge-triggered. No glitch must be
- * generated on these lines. If a falling edge on a configurable interrupt
- * line occurs during a write operation in the EXTI_FTSR register, the
- * pending bit is not set.
- * Rising and falling edge triggers can be set for
- * the same interrupt line. In this case, both generate a trigger
- * condition.
- * @rmtoll FTSR FTx LL_EXTI_EnableFallingTrig_0_31
- * @param ExtiLine This parameter can be a combination of the following values:
- * @arg @ref LL_EXTI_LINE_0
- * @arg @ref LL_EXTI_LINE_1
- * @arg @ref LL_EXTI_LINE_2
- * @arg @ref LL_EXTI_LINE_3
- * @arg @ref LL_EXTI_LINE_4
- * @arg @ref LL_EXTI_LINE_5
- * @arg @ref LL_EXTI_LINE_6
- * @arg @ref LL_EXTI_LINE_7
- * @arg @ref LL_EXTI_LINE_8
- * @arg @ref LL_EXTI_LINE_9
- * @arg @ref LL_EXTI_LINE_10
- * @arg @ref LL_EXTI_LINE_11
- * @arg @ref LL_EXTI_LINE_12
- * @arg @ref LL_EXTI_LINE_13
- * @arg @ref LL_EXTI_LINE_14
- * @arg @ref LL_EXTI_LINE_15
- * @arg @ref LL_EXTI_LINE_16
- * @arg @ref LL_EXTI_LINE_18
- * @arg @ref LL_EXTI_LINE_19
- * @note Please check each device line mapping for EXTI Line availability
- * @retval None
- */
-__STATIC_INLINE void LL_EXTI_EnableFallingTrig_0_31(uint32_t ExtiLine)
-{
- SET_BIT(EXTI->FTSR, ExtiLine);
-}
-
-
-/**
- * @brief Disable ExtiLine Falling Edge Trigger for Lines in range 0 to 31
- * @note The configurable wakeup lines are edge-triggered. No glitch must be
- * generated on these lines. If a Falling edge on a configurable interrupt
- * line occurs during a write operation in the EXTI_FTSR register, the
- * pending bit is not set.
- * Rising and falling edge triggers can be set for the same interrupt line.
- * In this case, both generate a trigger condition.
- * @rmtoll FTSR FTx LL_EXTI_DisableFallingTrig_0_31
- * @param ExtiLine This parameter can be a combination of the following values:
- * @arg @ref LL_EXTI_LINE_0
- * @arg @ref LL_EXTI_LINE_1
- * @arg @ref LL_EXTI_LINE_2
- * @arg @ref LL_EXTI_LINE_3
- * @arg @ref LL_EXTI_LINE_4
- * @arg @ref LL_EXTI_LINE_5
- * @arg @ref LL_EXTI_LINE_6
- * @arg @ref LL_EXTI_LINE_7
- * @arg @ref LL_EXTI_LINE_8
- * @arg @ref LL_EXTI_LINE_9
- * @arg @ref LL_EXTI_LINE_10
- * @arg @ref LL_EXTI_LINE_11
- * @arg @ref LL_EXTI_LINE_12
- * @arg @ref LL_EXTI_LINE_13
- * @arg @ref LL_EXTI_LINE_14
- * @arg @ref LL_EXTI_LINE_15
- * @arg @ref LL_EXTI_LINE_16
- * @arg @ref LL_EXTI_LINE_18
- * @arg @ref LL_EXTI_LINE_19
- * @note Please check each device line mapping for EXTI Line availability
- * @retval None
- */
-__STATIC_INLINE void LL_EXTI_DisableFallingTrig_0_31(uint32_t ExtiLine)
-{
- CLEAR_BIT(EXTI->FTSR, ExtiLine);
-}
-
-
-/**
- * @brief Check if falling edge trigger is enabled for Lines in range 0 to 31
- * @rmtoll FTSR FTx LL_EXTI_IsEnabledFallingTrig_0_31
- * @param ExtiLine This parameter can be a combination of the following values:
- * @arg @ref LL_EXTI_LINE_0
- * @arg @ref LL_EXTI_LINE_1
- * @arg @ref LL_EXTI_LINE_2
- * @arg @ref LL_EXTI_LINE_3
- * @arg @ref LL_EXTI_LINE_4
- * @arg @ref LL_EXTI_LINE_5
- * @arg @ref LL_EXTI_LINE_6
- * @arg @ref LL_EXTI_LINE_7
- * @arg @ref LL_EXTI_LINE_8
- * @arg @ref LL_EXTI_LINE_9
- * @arg @ref LL_EXTI_LINE_10
- * @arg @ref LL_EXTI_LINE_11
- * @arg @ref LL_EXTI_LINE_12
- * @arg @ref LL_EXTI_LINE_13
- * @arg @ref LL_EXTI_LINE_14
- * @arg @ref LL_EXTI_LINE_15
- * @arg @ref LL_EXTI_LINE_16
- * @arg @ref LL_EXTI_LINE_18
- * @arg @ref LL_EXTI_LINE_19
- * @note Please check each device line mapping for EXTI Line availability
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_EXTI_IsEnabledFallingTrig_0_31(uint32_t ExtiLine)
-{
- return (READ_BIT(EXTI->FTSR, ExtiLine) == (ExtiLine));
-}
-
-
-/**
- * @}
- */
-
-/** @defgroup EXTI_LL_EF_Software_Interrupt_Management Software_Interrupt_Management
- * @{
- */
-
-/**
- * @brief Generate a software Interrupt Event for Lines in range 0 to 31
- * @note If the interrupt is enabled on this line in the EXTI_IMR, writing a 1 to
- * this bit when it is at '0' sets the corresponding pending bit in EXTI_PR
- * resulting in an interrupt request generation.
- * This bit is cleared by clearing the corresponding bit in the EXTI_PR
- * register (by writing a 1 into the bit)
- * @rmtoll SWIER SWIx LL_EXTI_GenerateSWI_0_31
- * @param ExtiLine This parameter can be a combination of the following values:
- * @arg @ref LL_EXTI_LINE_0
- * @arg @ref LL_EXTI_LINE_1
- * @arg @ref LL_EXTI_LINE_2
- * @arg @ref LL_EXTI_LINE_3
- * @arg @ref LL_EXTI_LINE_4
- * @arg @ref LL_EXTI_LINE_5
- * @arg @ref LL_EXTI_LINE_6
- * @arg @ref LL_EXTI_LINE_7
- * @arg @ref LL_EXTI_LINE_8
- * @arg @ref LL_EXTI_LINE_9
- * @arg @ref LL_EXTI_LINE_10
- * @arg @ref LL_EXTI_LINE_11
- * @arg @ref LL_EXTI_LINE_12
- * @arg @ref LL_EXTI_LINE_13
- * @arg @ref LL_EXTI_LINE_14
- * @arg @ref LL_EXTI_LINE_15
- * @arg @ref LL_EXTI_LINE_16
- * @arg @ref LL_EXTI_LINE_18
- * @arg @ref LL_EXTI_LINE_19
- * @note Please check each device line mapping for EXTI Line availability
- * @retval None
- */
-__STATIC_INLINE void LL_EXTI_GenerateSWI_0_31(uint32_t ExtiLine)
-{
- SET_BIT(EXTI->SWIER, ExtiLine);
-}
-
-
-/**
- * @}
- */
-
-/** @defgroup EXTI_LL_EF_Flag_Management Flag_Management
- * @{
- */
-
-/**
- * @brief Check if the ExtLine Flag is set or not for Lines in range 0 to 31
- * @note This bit is set when the selected edge event arrives on the interrupt
- * line. This bit is cleared by writing a 1 to the bit.
- * @rmtoll PR PIFx LL_EXTI_IsActiveFlag_0_31
- * @param ExtiLine This parameter can be a combination of the following values:
- * @arg @ref LL_EXTI_LINE_0
- * @arg @ref LL_EXTI_LINE_1
- * @arg @ref LL_EXTI_LINE_2
- * @arg @ref LL_EXTI_LINE_3
- * @arg @ref LL_EXTI_LINE_4
- * @arg @ref LL_EXTI_LINE_5
- * @arg @ref LL_EXTI_LINE_6
- * @arg @ref LL_EXTI_LINE_7
- * @arg @ref LL_EXTI_LINE_8
- * @arg @ref LL_EXTI_LINE_9
- * @arg @ref LL_EXTI_LINE_10
- * @arg @ref LL_EXTI_LINE_11
- * @arg @ref LL_EXTI_LINE_12
- * @arg @ref LL_EXTI_LINE_13
- * @arg @ref LL_EXTI_LINE_14
- * @arg @ref LL_EXTI_LINE_15
- * @arg @ref LL_EXTI_LINE_16
- * @arg @ref LL_EXTI_LINE_18
- * @arg @ref LL_EXTI_LINE_19
- * @note Please check each device line mapping for EXTI Line availability
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_EXTI_IsActiveFlag_0_31(uint32_t ExtiLine)
-{
- return (READ_BIT(EXTI->PR, ExtiLine) == (ExtiLine));
-}
-
-
-/**
- * @brief Read ExtLine Combination Flag for Lines in range 0 to 31
- * @note This bit is set when the selected edge event arrives on the interrupt
- * line. This bit is cleared by writing a 1 to the bit.
- * @rmtoll PR PIFx LL_EXTI_ReadFlag_0_31
- * @param ExtiLine This parameter can be a combination of the following values:
- * @arg @ref LL_EXTI_LINE_0
- * @arg @ref LL_EXTI_LINE_1
- * @arg @ref LL_EXTI_LINE_2
- * @arg @ref LL_EXTI_LINE_3
- * @arg @ref LL_EXTI_LINE_4
- * @arg @ref LL_EXTI_LINE_5
- * @arg @ref LL_EXTI_LINE_6
- * @arg @ref LL_EXTI_LINE_7
- * @arg @ref LL_EXTI_LINE_8
- * @arg @ref LL_EXTI_LINE_9
- * @arg @ref LL_EXTI_LINE_10
- * @arg @ref LL_EXTI_LINE_11
- * @arg @ref LL_EXTI_LINE_12
- * @arg @ref LL_EXTI_LINE_13
- * @arg @ref LL_EXTI_LINE_14
- * @arg @ref LL_EXTI_LINE_15
- * @arg @ref LL_EXTI_LINE_16
- * @arg @ref LL_EXTI_LINE_18
- * @arg @ref LL_EXTI_LINE_19
- * @note Please check each device line mapping for EXTI Line availability
- * @retval @note This bit is set when the selected edge event arrives on the interrupt
- */
-__STATIC_INLINE uint32_t LL_EXTI_ReadFlag_0_31(uint32_t ExtiLine)
-{
- return (uint32_t)(READ_BIT(EXTI->PR, ExtiLine));
-}
-
-
-/**
- * @brief Clear ExtLine Flags for Lines in range 0 to 31
- * @note This bit is set when the selected edge event arrives on the interrupt
- * line. This bit is cleared by writing a 1 to the bit.
- * @rmtoll PR PIFx LL_EXTI_ClearFlag_0_31
- * @param ExtiLine This parameter can be a combination of the following values:
- * @arg @ref LL_EXTI_LINE_0
- * @arg @ref LL_EXTI_LINE_1
- * @arg @ref LL_EXTI_LINE_2
- * @arg @ref LL_EXTI_LINE_3
- * @arg @ref LL_EXTI_LINE_4
- * @arg @ref LL_EXTI_LINE_5
- * @arg @ref LL_EXTI_LINE_6
- * @arg @ref LL_EXTI_LINE_7
- * @arg @ref LL_EXTI_LINE_8
- * @arg @ref LL_EXTI_LINE_9
- * @arg @ref LL_EXTI_LINE_10
- * @arg @ref LL_EXTI_LINE_11
- * @arg @ref LL_EXTI_LINE_12
- * @arg @ref LL_EXTI_LINE_13
- * @arg @ref LL_EXTI_LINE_14
- * @arg @ref LL_EXTI_LINE_15
- * @arg @ref LL_EXTI_LINE_16
- * @arg @ref LL_EXTI_LINE_18
- * @arg @ref LL_EXTI_LINE_19
- * @note Please check each device line mapping for EXTI Line availability
- * @retval None
- */
-__STATIC_INLINE void LL_EXTI_ClearFlag_0_31(uint32_t ExtiLine)
-{
- WRITE_REG(EXTI->PR, ExtiLine);
-}
-
-
-/**
- * @}
- */
-
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup EXTI_LL_EF_Init Initialization and de-initialization functions
- * @{
- */
-
-uint32_t LL_EXTI_Init(LL_EXTI_InitTypeDef *EXTI_InitStruct);
-uint32_t LL_EXTI_DeInit(void);
-void LL_EXTI_StructInit(LL_EXTI_InitTypeDef *EXTI_InitStruct);
-
-
-/**
- * @}
- */
-#endif /* USE_FULL_LL_DRIVER */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* EXTI */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_LL_EXTI_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_fsmc.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_fsmc.h
deleted file mode 100644
index 2db50da..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_fsmc.h
+++ /dev/null
@@ -1,1079 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_fsmc.h
- * @author MCD Application Team
- * @brief Header file of FSMC HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_LL_FSMC_H
-#define __STM32F1xx_LL_FSMC_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#if defined(FSMC_BANK1)
-
-/** @addtogroup FSMC_LL
- * @{
- */
-
-
-/* Exported typedef ----------------------------------------------------------*/
-
-/** @defgroup FSMC_NORSRAM_Exported_typedef FSMC Low Layer Exported Types
- * @{
- */
-
-/**
- * @brief FSMC NORSRAM Configuration Structure definition
- */
-typedef struct
-{
- uint32_t NSBank; /*!< Specifies the NORSRAM memory device that will be used.
- This parameter can be a value of @ref FSMC_NORSRAM_Bank */
-
- uint32_t DataAddressMux; /*!< Specifies whether the address and data values are
- multiplexed on the data bus or not.
- This parameter can be a value of @ref FSMC_Data_Address_Bus_Multiplexing */
-
- uint32_t MemoryType; /*!< Specifies the type of external memory attached to
- the corresponding memory device.
- This parameter can be a value of @ref FSMC_Memory_Type */
-
- uint32_t MemoryDataWidth; /*!< Specifies the external memory device width.
- This parameter can be a value of @ref FSMC_NORSRAM_Data_Width */
-
- uint32_t 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 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 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 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 WriteOperation; /*!< Enables or disables the write operation in the selected device by the FSMC.
- This parameter can be a value of @ref FSMC_Write_Operation */
-
- uint32_t 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 ExtendedMode; /*!< Enables or disables the extended mode.
- This parameter can be a value of @ref FSMC_Extended_Mode */
-
- uint32_t 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 WriteBurst; /*!< Enables or disables the write burst operation.
- This parameter can be a value of @ref FSMC_Write_Burst */
-
-}FSMC_NORSRAM_InitTypeDef;
-
-/**
- * @brief FSMC NORSRAM Timing parameters structure definition
- */
-typedef struct
-{
- uint32_t AddressSetupTime; /*!< Defines the number of HCLK cycles to configure
- the duration of the address setup time.
- This parameter can be a value between Min_Data = 0 and Max_Data = 15.
- @note This parameter is not used with synchronous NOR Flash memories. */
-
- uint32_t AddressHoldTime; /*!< Defines the number of HCLK cycles to configure
- the duration of the address hold time.
- This parameter can be a value between Min_Data = 1 and Max_Data = 15.
- @note This parameter is not used with synchronous NOR Flash memories. */
-
- uint32_t DataSetupTime; /*!< Defines the number of HCLK cycles to configure
- the duration of the data setup time.
- This parameter can be a value between Min_Data = 1 and Max_Data = 255.
- @note This parameter is used for SRAMs, ROMs and asynchronous multiplexed
- NOR Flash memories. */
-
- uint32_t BusTurnAroundDuration; /*!< Defines the number of HCLK cycles to configure
- the duration of the bus turnaround.
- This parameter can be a value between Min_Data = 0 and Max_Data = 15.
- @note This parameter is only used for multiplexed NOR Flash memories. */
-
- uint32_t CLKDivision; /*!< Defines the period of CLK clock output signal, expressed in number of
- HCLK cycles. This parameter can be a value between Min_Data = 2 and Max_Data = 16.
- @note This parameter is not used for asynchronous NOR Flash, SRAM or ROM
- accesses. */
-
- uint32_t DataLatency; /*!< Defines the number of memory clock cycles to issue
- to the memory before getting the first data.
- The parameter value 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 Min_Data = 2 and Max_Data = 17 in NOR Flash memories
- with synchronous burst mode enable */
-
- uint32_t AccessMode; /*!< Specifies the asynchronous access mode.
- This parameter can be a value of @ref FSMC_Access_Mode */
-
-}FSMC_NORSRAM_TimingTypeDef;
-
-#if (defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
-/**
- * @brief FSMC NAND Configuration Structure definition
- */
-typedef struct
-{
- uint32_t NandBank; /*!< Specifies the NAND memory device that will be used.
- This parameter can be a value of @ref FSMC_NAND_Bank */
-
- uint32_t Waitfeature; /*!< Enables or disables the Wait feature for the NAND Memory device.
- This parameter can be any value of @ref FSMC_Wait_feature */
-
- uint32_t MemoryDataWidth; /*!< Specifies the external memory device width.
- This parameter can be any value of @ref FSMC_NAND_Data_Width */
-
- uint32_t EccComputation; /*!< Enables or disables the ECC computation.
- This parameter can be any value of @ref FSMC_ECC */
-
- uint32_t ECCPageSize; /*!< Defines the page size for the extended ECC.
- This parameter can be any value of @ref FSMC_ECC_Page_Size */
-
- uint32_t TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the
- delay between CLE low and RE low.
- This parameter can be a value between Min_Data = 0 and Max_Data = 255 */
-
- uint32_t TARSetupTime; /*!< Defines the number of HCLK cycles to configure the
- delay between ALE low and RE low.
- This parameter can be a number between Min_Data = 0 and Max_Data = 255 */
-
-}FSMC_NAND_InitTypeDef;
-
-/**
- * @brief FSMC NAND/PCCARD Timing parameters structure definition
- */
-typedef struct
-{
- uint32_t 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 Min_Data = 0 and Max_Data = 255 */
-
- uint32_t 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 Min_Data = 0 and Max_Data = 255 */
-
- uint32_t HoldSetupTime; /*!< Defines the number of HCLK clock cycles to hold address
- (and data for write access) after the command de-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 number between Min_Data = 0 and Max_Data = 255 */
-
- uint32_t HiZSetupTime; /*!< Defines the number of HCLK clock cycles during which the
- data bus 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 Min_Data = 0 and Max_Data = 255 */
-
-}FSMC_NAND_PCC_TimingTypeDef;
-
-/**
- * @brief FSMC NAND Configuration Structure definition
- */
-typedef struct
-{
- uint32_t Waitfeature; /*!< Enables or disables the Wait feature for the PCCARD Memory device.
- This parameter can be any value of @ref FSMC_Wait_feature */
-
- uint32_t TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the
- delay between CLE low and RE low.
- This parameter can be a value between Min_Data = 0 and Max_Data = 255 */
-
- uint32_t TARSetupTime; /*!< Defines the number of HCLK cycles to configure the
- delay between ALE low and RE low.
- This parameter can be a number between Min_Data = 0 and Max_Data = 255 */
-
-}FSMC_PCCARD_InitTypeDef;
-#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-
-/** @defgroup FSMC_Exported_Constants FSMC Low Layer Exported Constants
- * @{
- */
-
-/** @defgroup FSMC_NORSRAM_Exported_constants FSMC NOR/SRAM Exported constants
- * @{
- */
-/** @defgroup FSMC_NORSRAM_Bank FSMC NOR/SRAM Bank
- * @{
- */
-#define FSMC_NORSRAM_BANK1 0x00000000U
-#define FSMC_NORSRAM_BANK2 0x00000002U
-#define FSMC_NORSRAM_BANK3 0x00000004U
-#define FSMC_NORSRAM_BANK4 0x00000006U
-/**
- * @}
- */
-
-/** @defgroup FSMC_Data_Address_Bus_Multiplexing FSMC Data Address Bus Multiplexing
- * @{
- */
-#define FSMC_DATA_ADDRESS_MUX_DISABLE 0x00000000U
-#define FSMC_DATA_ADDRESS_MUX_ENABLE ((uint32_t)FSMC_BCRx_MUXEN)
-/**
- * @}
- */
-
-/** @defgroup FSMC_Memory_Type FSMC Memory Type
- * @{
- */
-#define FSMC_MEMORY_TYPE_SRAM 0x00000000U
-#define FSMC_MEMORY_TYPE_PSRAM ((uint32_t)FSMC_BCRx_MTYP_0)
-#define FSMC_MEMORY_TYPE_NOR ((uint32_t)FSMC_BCRx_MTYP_1)
-/**
- * @}
- */
-
-/** @defgroup FSMC_NORSRAM_Data_Width FSMC NOR/SRAM Data Width
- * @{
- */
-#define FSMC_NORSRAM_MEM_BUS_WIDTH_8 0x00000000U
-#define FSMC_NORSRAM_MEM_BUS_WIDTH_16 ((uint32_t)FSMC_BCRx_MWID_0)
-#define FSMC_NORSRAM_MEM_BUS_WIDTH_32 ((uint32_t)FSMC_BCRx_MWID_1)
-/**
- * @}
- */
-
-/** @defgroup FSMC_NORSRAM_Flash_Access FSMC NOR/SRAM Flash Access
- * @{
- */
-#define FSMC_NORSRAM_FLASH_ACCESS_ENABLE ((uint32_t)FSMC_BCRx_FACCEN)
-#define FSMC_NORSRAM_FLASH_ACCESS_DISABLE 0x00000000U
-/**
- * @}
- */
-
-/** @defgroup FSMC_Burst_Access_Mode FSMC Burst Access Mode
- * @{
- */
-#define FSMC_BURST_ACCESS_MODE_DISABLE 0x00000000U
-#define FSMC_BURST_ACCESS_MODE_ENABLE ((uint32_t)FSMC_BCRx_BURSTEN)
-/**
- * @}
- */
-
-/** @defgroup FSMC_Wait_Signal_Polarity FSMC Wait Signal Polarity
- * @{
- */
-#define FSMC_WAIT_SIGNAL_POLARITY_LOW 0x00000000U
-#define FSMC_WAIT_SIGNAL_POLARITY_HIGH ((uint32_t)FSMC_BCRx_WAITPOL)
-/**
- * @}
- */
-
-/** @defgroup FSMC_Wrap_Mode FSMC Wrap Mode
- * @{
- */
-#define FSMC_WRAP_MODE_DISABLE 0x00000000U
-#define FSMC_WRAP_MODE_ENABLE ((uint32_t)FSMC_BCRx_WRAPMOD)
-/**
- * @}
- */
-
-/** @defgroup FSMC_Wait_Timing FSMC Wait Timing
- * @{
- */
-#define FSMC_WAIT_TIMING_BEFORE_WS 0x00000000U
-#define FSMC_WAIT_TIMING_DURING_WS ((uint32_t)FSMC_BCRx_WAITCFG)
-/**
- * @}
- */
-
-/** @defgroup FSMC_Write_Operation FSMC Write Operation
- * @{
- */
-#define FSMC_WRITE_OPERATION_DISABLE 0x00000000U
-#define FSMC_WRITE_OPERATION_ENABLE ((uint32_t)FSMC_BCRx_WREN)
-/**
- * @}
- */
-
-/** @defgroup FSMC_Wait_Signal FSMC Wait Signal
- * @{
- */
-#define FSMC_WAIT_SIGNAL_DISABLE 0x00000000U
-#define FSMC_WAIT_SIGNAL_ENABLE ((uint32_t)FSMC_BCRx_WAITEN)
-/**
- * @}
- */
-
-/** @defgroup FSMC_Extended_Mode FSMC Extended Mode
- * @{
- */
-#define FSMC_EXTENDED_MODE_DISABLE 0x00000000U
-#define FSMC_EXTENDED_MODE_ENABLE ((uint32_t)FSMC_BCRx_EXTMOD)
-/**
- * @}
- */
-
-/** @defgroup FSMC_AsynchronousWait FSMC Asynchronous Wait
- * @{
- */
-#define FSMC_ASYNCHRONOUS_WAIT_DISABLE 0x00000000U
-#define FSMC_ASYNCHRONOUS_WAIT_ENABLE ((uint32_t)FSMC_BCRx_ASYNCWAIT)
-/**
- * @}
- */
-
-/** @defgroup FSMC_Write_Burst FSMC Write Burst
- * @{
- */
-#define FSMC_WRITE_BURST_DISABLE 0x00000000U
-#define FSMC_WRITE_BURST_ENABLE ((uint32_t)FSMC_BCRx_CBURSTRW)
-/**
- * @}
- */
-
-/** @defgroup FSMC_Access_Mode FSMC Access Mode
- * @{
- */
-#define FSMC_ACCESS_MODE_A 0x00000000U
-#define FSMC_ACCESS_MODE_B ((uint32_t)FSMC_BTRx_ACCMOD_0)
-#define FSMC_ACCESS_MODE_C ((uint32_t)FSMC_BTRx_ACCMOD_1)
-#define FSMC_ACCESS_MODE_D ((uint32_t)(FSMC_BTRx_ACCMOD_0 | FSMC_BTRx_ACCMOD_1))
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#if (defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
-/** @defgroup FSMC_NAND_Controller FSMC NAND and PCCARD Controller
- * @{
- */
-/** @defgroup FSMC_NAND_Bank FSMC NAND Bank
- * @{
- */
-#define FSMC_NAND_BANK2 0x00000010U
-#define FSMC_NAND_BANK3 0x00000100U
-/**
- * @}
- */
-
-/** @defgroup FSMC_Wait_feature FSMC Wait feature
- * @{
- */
-#define FSMC_NAND_PCC_WAIT_FEATURE_DISABLE 0x00000000U
-#define FSMC_NAND_PCC_WAIT_FEATURE_ENABLE ((uint32_t)FSMC_PCRx_PWAITEN)
-/**
- * @}
- */
-
-/** @defgroup FSMC_PCR_Memory_Type FSMC PCR Memory Type
- * @{
- */
-#define FSMC_PCR_MEMORY_TYPE_PCCARD 0x00000000U
-#define FSMC_PCR_MEMORY_TYPE_NAND ((uint32_t)FSMC_PCRx_PTYP)
-/**
- * @}
- */
-
-/** @defgroup FSMC_NAND_Data_Width FSMC NAND Data Width
- * @{
- */
-#define FSMC_NAND_PCC_MEM_BUS_WIDTH_8 0x00000000U
-#define FSMC_NAND_PCC_MEM_BUS_WIDTH_16 ((uint32_t)FSMC_PCRx_PWID_0)
-/**
- * @}
- */
-
-/** @defgroup FSMC_ECC FSMC NAND ECC
- * @{
- */
-#define FSMC_NAND_ECC_DISABLE 0x00000000U
-#define FSMC_NAND_ECC_ENABLE ((uint32_t)FSMC_PCRx_ECCEN)
-/**
- * @}
- */
-
-/** @defgroup FSMC_ECC_Page_Size FSMC ECC Page Size
- * @{
- */
-#define FSMC_NAND_ECC_PAGE_SIZE_256BYTE 0x00000000U
-#define FSMC_NAND_ECC_PAGE_SIZE_512BYTE ((uint32_t)FSMC_PCRx_ECCPS_0)
-#define FSMC_NAND_ECC_PAGE_SIZE_1024BYTE ((uint32_t)FSMC_PCRx_ECCPS_1)
-#define FSMC_NAND_ECC_PAGE_SIZE_2048BYTE ((uint32_t)FSMC_PCRx_ECCPS_0|FSMC_PCRx_ECCPS_1)
-#define FSMC_NAND_ECC_PAGE_SIZE_4096BYTE ((uint32_t)FSMC_PCRx_ECCPS_2)
-#define FSMC_NAND_ECC_PAGE_SIZE_8192BYTE ((uint32_t)FSMC_PCRx_ECCPS_0|FSMC_PCRx_ECCPS_2)
-/**
- * @}
- */
-
-/**
- * @}
- */
-#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
-
-/** @defgroup FSMC_LL_Interrupt_definition FSMC Interrupt definition
- * @brief FSMC Interrupt definition
- * @{
- */
-#define FSMC_IT_RISING_EDGE ((uint32_t)FSMC_SRx_IREN)
-#define FSMC_IT_LEVEL ((uint32_t)FSMC_SRx_ILEN)
-#define FSMC_IT_FALLING_EDGE ((uint32_t)FSMC_SRx_IFEN)
-/**
- * @}
- */
-
-/** @defgroup FSMC_LL_Flag_definition FSMC Flag definition
- * @brief FSMC Flag definition
- * @{
- */
-#define FSMC_FLAG_RISING_EDGE ((uint32_t)FSMC_SRx_IRS)
-#define FSMC_FLAG_LEVEL ((uint32_t)FSMC_SRx_ILS)
-#define FSMC_FLAG_FALLING_EDGE ((uint32_t)FSMC_SRx_IFS)
-#define FSMC_FLAG_FEMPT ((uint32_t)FSMC_SRx_FEMPT)
-/**
- * @}
- */
-
-/** @defgroup FSMC_LL_Alias_definition FSMC Alias definition
- * @{
- */
-#define FSMC_NORSRAM_TypeDef FSMC_Bank1_TypeDef
-#define FSMC_NORSRAM_EXTENDED_TypeDef FSMC_Bank1E_TypeDef
-#define FSMC_NAND_TypeDef FSMC_Bank2_3_TypeDef
-#define FSMC_PCCARD_TypeDef FSMC_Bank4_TypeDef
-
-#define FSMC_NORSRAM_DEVICE FSMC_Bank1
-#define FSMC_NORSRAM_EXTENDED_DEVICE FSMC_Bank1E
-#define FSMC_NAND_DEVICE FSMC_Bank2_3
-#define FSMC_PCCARD_DEVICE FSMC_Bank4
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup FSMC_Exported_Macros FSMC Low Layer Exported Macros
- * @{
- */
-
-/** @defgroup FSMC_LL_NOR_Macros FSMC NOR/SRAM Exported Macros
- * @brief macros to handle NOR device enable/disable and read/write operations
- * @{
- */
-
-/**
- * @brief Enable the NORSRAM device access.
- * @param __INSTANCE__: FSMC_NORSRAM Instance
- * @param __BANK__: FSMC_NORSRAM Bank
- * @retval none
- */
-#define __FSMC_NORSRAM_ENABLE(__INSTANCE__, __BANK__) SET_BIT((__INSTANCE__)->BTCR[(__BANK__)], FSMC_BCRx_MBKEN)
-
-/**
- * @brief Disable the NORSRAM device access.
- * @param __INSTANCE__: FSMC_NORSRAM Instance
- * @param __BANK__: FSMC_NORSRAM Bank
- * @retval none
- */
-#define __FSMC_NORSRAM_DISABLE(__INSTANCE__, __BANK__) CLEAR_BIT((__INSTANCE__)->BTCR[(__BANK__)], FSMC_BCRx_MBKEN)
-
-/**
- * @}
- */
-
-#if (defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
-/** @defgroup FSMC_LL_NAND_Macros FSMC NAND Macros
- * @brief macros to handle NAND device enable/disable
- * @{
- */
-
-/**
- * @brief Enable the NAND device access.
- * @param __INSTANCE__: FSMC_NAND Instance
- * @param __BANK__: FSMC_NAND Bank
- * @retval None
- */
-#define __FSMC_NAND_ENABLE(__INSTANCE__, __BANK__) (((__BANK__) == FSMC_NAND_BANK2)? SET_BIT((__INSTANCE__)->PCR2, FSMC_PCRx_PBKEN): \
- SET_BIT((__INSTANCE__)->PCR3, FSMC_PCRx_PBKEN))
-
-/**
- * @brief Disable the NAND device access.
- * @param __INSTANCE__: FSMC_NAND Instance
- * @param __BANK__: FSMC_NAND Bank
- * @retval None
- */
-#define __FSMC_NAND_DISABLE(__INSTANCE__, __BANK__) (((__BANK__) == FSMC_NAND_BANK2)? CLEAR_BIT((__INSTANCE__)->PCR2, FSMC_PCRx_PBKEN): \
- CLEAR_BIT((__INSTANCE__)->PCR3, FSMC_PCRx_PBKEN))
-/**
- * @}
- */
-
-/** @defgroup FSMC_LL_PCCARD_Macros FSMC PCCARD Macros
- * @brief macros to handle PCCARD read/write operations
- * @{
- */
-/**
- * @brief Enable the PCCARD device access.
- * @param __INSTANCE__: FSMC_PCCARD Instance
- * @retval None
- */
-#define __FSMC_PCCARD_ENABLE(__INSTANCE__) SET_BIT((__INSTANCE__)->PCR4, FSMC_PCRx_PBKEN)
-
-/**
- * @brief Disable the PCCARD device access.
- * @param __INSTANCE__: FSMC_PCCARD Instance
- * @retval None
- */
-#define __FSMC_PCCARD_DISABLE(__INSTANCE__) CLEAR_BIT((__INSTANCE__)->PCR4, FSMC_PCRx_PBKEN)
-/**
- * @}
- */
-
-/** @defgroup FSMC_LL_Flag_Interrupt_Macros FSMC Flag&Interrupt Macros
- * @brief macros to handle FSMC flags and interrupts
- * @{
- */
-
-/**
- * @brief Enable the NAND device interrupt.
- * @param __INSTANCE__: FSMC_NAND Instance
- * @param __BANK__: FSMC_NAND Bank
- * @param __INTERRUPT__: FSMC_NAND interrupt
- * This parameter can be any combination of the following values:
- * @arg FSMC_IT_RISING_EDGE: Interrupt rising edge.
- * @arg FSMC_IT_LEVEL: Interrupt level.
- * @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge.
- * @retval None
- */
-#define __FSMC_NAND_ENABLE_IT(__INSTANCE__, __BANK__, __INTERRUPT__) (((__BANK__) == FSMC_NAND_BANK2)? SET_BIT((__INSTANCE__)->SR2, (__INTERRUPT__)): \
- SET_BIT((__INSTANCE__)->SR3, (__INTERRUPT__)))
-
-/**
- * @brief Disable the NAND device interrupt.
- * @param __INSTANCE__: FSMC_NAND Instance
- * @param __BANK__: FSMC_NAND Bank
- * @param __INTERRUPT__: FSMC_NAND interrupt
- * This parameter can be any combination of the following values:
- * @arg FSMC_IT_RISING_EDGE: Interrupt rising edge.
- * @arg FSMC_IT_LEVEL: Interrupt level.
- * @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge.
- * @retval None
- */
-#define __FSMC_NAND_DISABLE_IT(__INSTANCE__, __BANK__, __INTERRUPT__) (((__BANK__) == FSMC_NAND_BANK2)? CLEAR_BIT((__INSTANCE__)->SR2, (__INTERRUPT__)): \
- CLEAR_BIT((__INSTANCE__)->SR3, (__INTERRUPT__)))
-
-/**
- * @brief Get flag status of the NAND device.
- * @param __INSTANCE__: FSMC_NAND Instance
- * @param __BANK__ : FSMC_NAND Bank
- * @param __FLAG__ : FSMC_NAND flag
- * This parameter can be any combination of the following values:
- * @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag.
- * @arg FSMC_FLAG_LEVEL: Interrupt level edge flag.
- * @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag.
- * @arg FSMC_FLAG_FEMPT: FIFO empty flag.
- * @retval The state of FLAG (SET or RESET).
- */
-#define __FSMC_NAND_GET_FLAG(__INSTANCE__, __BANK__, __FLAG__) (((__BANK__) == FSMC_NAND_BANK2)? (((__INSTANCE__)->SR2 &(__FLAG__)) == (__FLAG__)): \
- (((__INSTANCE__)->SR3 &(__FLAG__)) == (__FLAG__)))
-/**
- * @brief Clear flag status of the NAND device.
- * @param __INSTANCE__: FSMC_NAND Instance
- * @param __BANK__: FSMC_NAND Bank
- * @param __FLAG__: FSMC_NAND flag
- * This parameter can be any combination of the following values:
- * @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag.
- * @arg FSMC_FLAG_LEVEL: Interrupt level edge flag.
- * @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag.
- * @arg FSMC_FLAG_FEMPT: FIFO empty flag.
- * @retval None
- */
-#define __FSMC_NAND_CLEAR_FLAG(__INSTANCE__, __BANK__, __FLAG__) (((__BANK__) == FSMC_NAND_BANK2)? CLEAR_BIT((__INSTANCE__)->SR2, (__FLAG__)): \
- CLEAR_BIT((__INSTANCE__)->SR3, (__FLAG__)))
-
-/**
- * @brief Enable the PCCARD device interrupt.
- * @param __INSTANCE__: FSMC_PCCARD Instance
- * @param __INTERRUPT__: FSMC_PCCARD interrupt
- * This parameter can be any combination of the following values:
- * @arg FSMC_IT_RISING_EDGE: Interrupt rising edge.
- * @arg FSMC_IT_LEVEL: Interrupt level.
- * @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge.
- * @retval None
- */
-#define __FSMC_PCCARD_ENABLE_IT(__INSTANCE__, __INTERRUPT__) SET_BIT((__INSTANCE__)->SR4, (__INTERRUPT__))
-
-/**
- * @brief Disable the PCCARD device interrupt.
- * @param __INSTANCE__: FSMC_PCCARD Instance
- * @param __INTERRUPT__: FSMC_PCCARD interrupt
- * This parameter can be any combination of the following values:
- * @arg FSMC_IT_RISING_EDGE: Interrupt rising edge.
- * @arg FSMC_IT_LEVEL: Interrupt level.
- * @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge.
- * @retval None
- */
-#define __FSMC_PCCARD_DISABLE_IT(__INSTANCE__, __INTERRUPT__) CLEAR_BIT((__INSTANCE__)->SR4, (__INTERRUPT__))
-
-/**
- * @brief Get flag status of the PCCARD device.
- * @param __INSTANCE__: FSMC_PCCARD Instance
- * @param __FLAG__: FSMC_PCCARD flag
- * This parameter can be any combination of the following values:
- * @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag.
- * @arg FSMC_FLAG_LEVEL: Interrupt level edge flag.
- * @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag.
- * @arg FSMC_FLAG_FEMPT: FIFO empty flag.
- * @retval The state of FLAG (SET or RESET).
- */
-#define __FSMC_PCCARD_GET_FLAG(__INSTANCE__, __FLAG__) (((__INSTANCE__)->SR4 &(__FLAG__)) == (__FLAG__))
-
-/**
- * @brief Clear flag status of the PCCARD device.
- * @param __INSTANCE__: FSMC_PCCARD Instance
- * @param __FLAG__: FSMC_PCCARD flag
- * This parameter can be any combination of the following values:
- * @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag.
- * @arg FSMC_FLAG_LEVEL: Interrupt level edge flag.
- * @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag.
- * @arg FSMC_FLAG_FEMPT: FIFO empty flag.
- * @retval None
- */
-#define __FSMC_PCCARD_CLEAR_FLAG(__INSTANCE__, __FLAG__) CLEAR_BIT((__INSTANCE__)->SR4, (__FLAG__))
-
-/**
- * @}
- */
-#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
-
-/**
- * @}
- */
-
-/** @defgroup FSMC_LL_Private_Macros FSMC Low Layer Private Macros
- * @{
- */
-#define IS_FSMC_NORSRAM_BANK(__BANK__) (((__BANK__) == FSMC_NORSRAM_BANK1) || \
- ((__BANK__) == FSMC_NORSRAM_BANK2) || \
- ((__BANK__) == FSMC_NORSRAM_BANK3) || \
- ((__BANK__) == FSMC_NORSRAM_BANK4))
-
-#define IS_FSMC_MUX(__MUX__) (((__MUX__) == FSMC_DATA_ADDRESS_MUX_DISABLE) || \
- ((__MUX__) == FSMC_DATA_ADDRESS_MUX_ENABLE))
-
-#define IS_FSMC_MEMORY(__MEMORY__) (((__MEMORY__) == FSMC_MEMORY_TYPE_SRAM) || \
- ((__MEMORY__) == FSMC_MEMORY_TYPE_PSRAM)|| \
- ((__MEMORY__) == FSMC_MEMORY_TYPE_NOR))
-
-#define IS_FSMC_NORSRAM_MEMORY_WIDTH(__WIDTH__) (((__WIDTH__) == FSMC_NORSRAM_MEM_BUS_WIDTH_8) || \
- ((__WIDTH__) == FSMC_NORSRAM_MEM_BUS_WIDTH_16) || \
- ((__WIDTH__) == FSMC_NORSRAM_MEM_BUS_WIDTH_32))
-
-#define IS_FSMC_WRITE_BURST(__BURST__) (((__BURST__) == FSMC_WRITE_BURST_DISABLE) || \
- ((__BURST__) == FSMC_WRITE_BURST_ENABLE))
-
-#define IS_FSMC_ACCESS_MODE(__MODE__) (((__MODE__) == FSMC_ACCESS_MODE_A) || \
- ((__MODE__) == FSMC_ACCESS_MODE_B) || \
- ((__MODE__) == FSMC_ACCESS_MODE_C) || \
- ((__MODE__) == FSMC_ACCESS_MODE_D))
-
-#define IS_FSMC_NAND_BANK(__BANK__) (((__BANK__) == FSMC_NAND_BANK2) || \
- ((__BANK__) == FSMC_NAND_BANK3))
-
-#define IS_FSMC_WAIT_FEATURE(__FEATURE__) (((__FEATURE__) == FSMC_NAND_PCC_WAIT_FEATURE_DISABLE) || \
- ((__FEATURE__) == FSMC_NAND_PCC_WAIT_FEATURE_ENABLE))
-
-#define IS_FSMC_NAND_MEMORY_WIDTH(__WIDTH__) (((__WIDTH__) == FSMC_NAND_PCC_MEM_BUS_WIDTH_8) || \
- ((__WIDTH__) == FSMC_NAND_PCC_MEM_BUS_WIDTH_16))
-
-#define IS_FSMC_ECC_STATE(__STATE__) (((__STATE__) == FSMC_NAND_ECC_DISABLE) || \
- ((__STATE__) == FSMC_NAND_ECC_ENABLE))
-
-#define IS_FSMC_ECCPAGE_SIZE(__SIZE__) (((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_256BYTE) || \
- ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_512BYTE) || \
- ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_1024BYTE) || \
- ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_2048BYTE) || \
- ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_4096BYTE) || \
- ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_8192BYTE))
-
-/** @defgroup FSMC_TCLR_Setup_Time FSMC_TCLR_Setup_Time
- * @{
- */
-#define IS_FSMC_TCLR_TIME(__TIME__) ((__TIME__) <= 255U)
-/**
- * @}
- */
-
-/** @defgroup FSMC_TAR_Setup_Time FSMC_TAR_Setup_Time
- * @{
- */
-#define IS_FSMC_TAR_TIME(__TIME__) ((__TIME__) <= 255U)
-/**
- * @}
- */
-
-/** @defgroup FSMC_Setup_Time FSMC_Setup_Time
- * @{
- */
-#define IS_FSMC_SETUP_TIME(__TIME__) ((__TIME__) <= 255U)
-/**
- * @}
- */
-
-/** @defgroup FSMC_Wait_Setup_Time FSMC_Wait_Setup_Time
- * @{
- */
-#define IS_FSMC_WAIT_TIME(__TIME__) ((__TIME__) <= 255U)
-/**
- * @}
- */
-
-/** @defgroup FSMC_Hold_Setup_Time FSMC_Hold_Setup_Time
- * @{
- */
-#define IS_FSMC_HOLD_TIME(__TIME__) ((__TIME__) <= 255U)
-/**
- * @}
- */
-
-/** @defgroup FSMC_HiZ_Setup_Time FSMC_HiZ_Setup_Time
- * @{
- */
-#define IS_FSMC_HIZ_TIME(__TIME__) ((__TIME__) <= 255U)
-/**
- * @}
- */
-
-/** @defgroup FSMC_NORSRAM_Device_Instance FSMC NOR/SRAM Device Instance
- * @{
- */
-#define IS_FSMC_NORSRAM_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_NORSRAM_DEVICE)
-/**
- * @}
- */
-
-/** @defgroup FSMC_NORSRAM_EXTENDED_Device_Instance FSMC NOR/SRAM EXTENDED Device Instance
- * @{
- */
-#define IS_FSMC_NORSRAM_EXTENDED_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_NORSRAM_EXTENDED_DEVICE)
-/**
- * @}
- */
-
-/** @defgroup FSMC_NAND_Device_Instance FSMC NAND Device Instance
- * @{
- */
-#define IS_FSMC_NAND_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_NAND_DEVICE)
-/**
- * @}
- */
-
-/** @defgroup FSMC_PCCARD_Device_Instance FSMC PCCARD Device Instance
- * @{
- */
-#define IS_FSMC_PCCARD_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_PCCARD_DEVICE)
-
-/**
- * @}
- */
-#define IS_FSMC_BURSTMODE(__STATE__) (((__STATE__) == FSMC_BURST_ACCESS_MODE_DISABLE) || \
- ((__STATE__) == FSMC_BURST_ACCESS_MODE_ENABLE))
-
-#define IS_FSMC_WAIT_POLARITY(__POLARITY__) (((__POLARITY__) == FSMC_WAIT_SIGNAL_POLARITY_LOW) || \
- ((__POLARITY__) == FSMC_WAIT_SIGNAL_POLARITY_HIGH))
-
-#define IS_FSMC_WRAP_MODE(__MODE__) (((__MODE__) == FSMC_WRAP_MODE_DISABLE) || \
- ((__MODE__) == FSMC_WRAP_MODE_ENABLE))
-
-#define IS_FSMC_WAIT_SIGNAL_ACTIVE(__ACTIVE__) (((__ACTIVE__) == FSMC_WAIT_TIMING_BEFORE_WS) || \
- ((__ACTIVE__) == FSMC_WAIT_TIMING_DURING_WS))
-
-#define IS_FSMC_WRITE_OPERATION(__OPERATION__) (((__OPERATION__) == FSMC_WRITE_OPERATION_DISABLE) || \
- ((__OPERATION__) == FSMC_WRITE_OPERATION_ENABLE))
-
-#define IS_FSMC_WAITE_SIGNAL(__SIGNAL__) (((__SIGNAL__) == FSMC_WAIT_SIGNAL_DISABLE) || \
- ((__SIGNAL__) == FSMC_WAIT_SIGNAL_ENABLE))
-
-#define IS_FSMC_EXTENDED_MODE(__MODE__) (((__MODE__) == FSMC_EXTENDED_MODE_DISABLE) || \
- ((__MODE__) == FSMC_EXTENDED_MODE_ENABLE))
-
-#define IS_FSMC_ASYNWAIT(__STATE__) (((__STATE__) == FSMC_ASYNCHRONOUS_WAIT_DISABLE) || \
- ((__STATE__) == FSMC_ASYNCHRONOUS_WAIT_ENABLE))
-
-#define IS_FSMC_CLK_DIV(__DIV__) (((__DIV__) > 1U) && ((__DIV__) <= 16U))
-
-/** @defgroup FSMC_Data_Latency FSMC Data Latency
- * @{
- */
-#define IS_FSMC_DATA_LATENCY(__LATENCY__) (((__LATENCY__) > 1U) && ((__LATENCY__) <= 17U))
-/**
- * @}
- */
-
-/** @defgroup FSMC_Address_Setup_Time FSMC Address Setup Time
- * @{
- */
-#define IS_FSMC_ADDRESS_SETUP_TIME(__TIME__) ((__TIME__) <= 15U)
-/**
- * @}
- */
-
-/** @defgroup FSMC_Address_Hold_Time FSMC Address Hold Time
- * @{
- */
-#define IS_FSMC_ADDRESS_HOLD_TIME(__TIME__) (((__TIME__) > 0U) && ((__TIME__) <= 15U))
-/**
- * @}
- */
-
-/** @defgroup FSMC_Data_Setup_Time FSMC Data Setup Time
- * @{
- */
-#define IS_FSMC_DATASETUP_TIME(__TIME__) (((__TIME__) > 0U) && ((__TIME__) <= 255U))
-/**
- * @}
- */
-
-/** @defgroup FSMC_Bus_Turn_around_Duration FSMC Bus Turn around Duration
- * @{
- */
-#define IS_FSMC_TURNAROUND_TIME(__TIME__) ((__TIME__) <= 15U)
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @defgroup FSMC_LL_Private_Constants FSMC Low Layer Private Constants
- * @{
- */
-
-/* ----------------------- FSMC registers bit mask --------------------------- */
-#if (defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
-/* --- PCR Register ---*/
-/* PCR register clear mask */
-#define PCR_CLEAR_MASK ((uint32_t)(FSMC_PCRx_PWAITEN | FSMC_PCRx_PBKEN | \
- FSMC_PCRx_PTYP | FSMC_PCRx_PWID | \
- FSMC_PCRx_ECCEN | FSMC_PCRx_TCLR | \
- FSMC_PCRx_TAR | FSMC_PCRx_ECCPS))
-
-/* --- PMEM Register ---*/
-/* PMEM register clear mask */
-#define PMEM_CLEAR_MASK ((uint32_t)(FSMC_PMEMx_MEMSETx | FSMC_PMEMx_MEMWAITx |\
- FSMC_PMEMx_MEMHOLDx | FSMC_PMEMx_MEMHIZx))
-
-/* --- PATT Register ---*/
-/* PATT register clear mask */
-#define PATT_CLEAR_MASK ((uint32_t)(FSMC_PATTx_ATTSETx | FSMC_PATTx_ATTWAITx |\
- FSMC_PATTx_ATTHOLDx | FSMC_PATTx_ATTHIZx))
-
-#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
-/* --- BCR Register ---*/
-/* BCR register clear mask */
-#define BCR_CLEAR_MASK ((uint32_t)(FSMC_BCRx_FACCEN | FSMC_BCRx_MUXEN | \
- FSMC_BCRx_MTYP | FSMC_BCRx_MWID | \
- FSMC_BCRx_BURSTEN | FSMC_BCRx_WAITPOL | \
- FSMC_BCRx_WRAPMOD | FSMC_BCRx_WAITCFG | \
- FSMC_BCRx_WREN | FSMC_BCRx_WAITEN | \
- FSMC_BCRx_EXTMOD | FSMC_BCRx_ASYNCWAIT | \
- FSMC_BCRx_CBURSTRW))
-/* --- BTR Register ---*/
-/* BTR register clear mask */
-#define BTR_CLEAR_MASK ((uint32_t)(FSMC_BTRx_ADDSET | FSMC_BTRx_ADDHLD |\
- FSMC_BTRx_DATAST | FSMC_BTRx_BUSTURN |\
- FSMC_BTRx_CLKDIV | FSMC_BTRx_DATLAT |\
- FSMC_BTRx_ACCMOD))
-
-/* --- BWTR Register ---*/
-/* BWTR register clear mask */
-#if (defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
-#define BWTR_CLEAR_MASK ((uint32_t)(FSMC_BWTRx_ADDSET | FSMC_BWTRx_ADDHLD | \
- FSMC_BWTRx_DATAST | FSMC_BWTRx_ACCMOD | \
- FSMC_BWTRx_BUSTURN))
-#else
-#define BWTR_CLEAR_MASK ((uint32_t)(FSMC_BWTRx_ADDSET | FSMC_BWTRx_ADDHLD | \
- FSMC_BWTRx_DATAST | FSMC_BWTRx_ACCMOD | \
- FSMC_BWTRx_CLKDIV | FSMC_BWTRx_DATLAT))
-#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
-
-/* --- PIO4 Register ---*/
-/* PIO4 register clear mask */
-#define PIO4_CLEAR_MASK ((uint32_t)(FSMC_PIO4_IOSET4 | FSMC_PIO4_IOWAIT4 | \
- FSMC_PIO4_IOHOLD4 | FSMC_PIO4_IOHIZ4))
-/**
- * @}
- */
-/* Exported functions --------------------------------------------------------*/
-
-/** @addtogroup FSMC_LL_Exported_Functions
- * @{
- */
-
-/** @addtogroup FSMC_NORSRAM
- * @{
- */
-
-/** @addtogroup FSMC_NORSRAM_Group1
- * @{
- */
-/* FSMC_NORSRAM Controller functions ******************************************/
-/* Initialization/de-initialization functions */
-HAL_StatusTypeDef FSMC_NORSRAM_Init(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_InitTypeDef *Init);
-HAL_StatusTypeDef FSMC_NORSRAM_Timing_Init(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank);
-HAL_StatusTypeDef FSMC_NORSRAM_Extended_Timing_Init(FSMC_NORSRAM_EXTENDED_TypeDef *Device, FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, uint32_t ExtendedMode);
-HAL_StatusTypeDef FSMC_NORSRAM_DeInit(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank);
-/**
- * @}
- */
-
-/** @addtogroup FSMC_NORSRAM_Group2
- * @{
- */
-/* FSMC_NORSRAM Control functions */
-HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Enable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank);
-HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Disable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#if (defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
-/** @addtogroup FSMC_NAND
- * @{
- */
-
-/* FSMC_NAND Controller functions **********************************************/
-/* Initialization/de-initialization functions */
-/** @addtogroup FSMC_NAND_Exported_Functions_Group1
- * @{
- */
-HAL_StatusTypeDef FSMC_NAND_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_InitTypeDef *Init);
-HAL_StatusTypeDef FSMC_NAND_CommonSpace_Timing_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank);
-HAL_StatusTypeDef FSMC_NAND_AttributeSpace_Timing_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank);
-HAL_StatusTypeDef FSMC_NAND_DeInit(FSMC_NAND_TypeDef *Device, uint32_t Bank);
-/**
- * @}
- */
-
-/* FSMC_NAND Control functions */
-/** @addtogroup FSMC_NAND_Exported_Functions_Group2
- * @{
- */
-HAL_StatusTypeDef FSMC_NAND_ECC_Enable(FSMC_NAND_TypeDef *Device, uint32_t Bank);
-HAL_StatusTypeDef FSMC_NAND_ECC_Disable(FSMC_NAND_TypeDef *Device, uint32_t Bank);
-HAL_StatusTypeDef FSMC_NAND_GetECC(FSMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank, uint32_t Timeout);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup FSMC_PCCARD
- * @{
- */
-
-/* FSMC_PCCARD Controller functions ********************************************/
-/* Initialization/de-initialization functions */
-/** @addtogroup FSMC_PCCARD_Exported_Functions_Group1
- * @{
- */
-HAL_StatusTypeDef FSMC_PCCARD_Init(FSMC_PCCARD_TypeDef *Device, FSMC_PCCARD_InitTypeDef *Init);
-HAL_StatusTypeDef FSMC_PCCARD_CommonSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing);
-HAL_StatusTypeDef FSMC_PCCARD_AttributeSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing);
-HAL_StatusTypeDef FSMC_PCCARD_IOSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing);
-HAL_StatusTypeDef FSMC_PCCARD_DeInit(FSMC_PCCARD_TypeDef *Device);
-/**
- * @}
- */
-
-/**
- * @}
- */
-#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-#endif /* FSMC_BANK1 */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_LL_FSMC_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_i2c.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_i2c.h
deleted file mode 100644
index c4e3e53..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_i2c.h
+++ /dev/null
@@ -1,1800 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_i2c.h
- * @author MCD Application Team
- * @brief Header file of I2C LL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_LL_I2C_H
-#define __STM32F1xx_LL_I2C_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx.h"
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined (I2C1) || defined (I2C2)
-
-/** @defgroup I2C_LL I2C
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup I2C_LL_Private_Constants I2C Private Constants
- * @{
- */
-
-/* Defines used to perform compute and check in the macros */
-#define LL_I2C_MAX_SPEED_STANDARD 100000U
-#define LL_I2C_MAX_SPEED_FAST 400000U
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup I2C_LL_Private_Macros I2C Private Macros
- * @{
- */
-/**
- * @}
- */
-#endif /*USE_FULL_LL_DRIVER*/
-
-/* Exported types ------------------------------------------------------------*/
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup I2C_LL_ES_INIT I2C Exported Init structure
- * @{
- */
-typedef struct
-{
- uint32_t PeripheralMode; /*!< Specifies the peripheral mode.
- This parameter can be a value of @ref I2C_LL_EC_PERIPHERAL_MODE
-
- This feature can be modified afterwards using unitary function @ref LL_I2C_SetMode(). */
-
- uint32_t ClockSpeed; /*!< Specifies the clock frequency.
- This parameter must be set to a value lower than 400kHz (in Hz)
-
- This feature can be modified afterwards using unitary function @ref LL_I2C_SetClockPeriod()
- or @ref LL_I2C_SetDutyCycle() or @ref LL_I2C_SetClockSpeedMode() or @ref LL_I2C_ConfigSpeed(). */
-
- uint32_t DutyCycle; /*!< Specifies the I2C fast mode duty cycle.
- This parameter can be a value of @ref I2C_LL_EC_DUTYCYCLE
-
- This feature can be modified afterwards using unitary function @ref LL_I2C_SetDutyCycle(). */
-
- uint32_t OwnAddress1; /*!< Specifies the device own address 1.
- This parameter must be a value between Min_Data = 0x00 and Max_Data = 0x3FF
-
- This feature can be modified afterwards using unitary function @ref LL_I2C_SetOwnAddress1(). */
-
- uint32_t TypeAcknowledge; /*!< Specifies the ACKnowledge or Non ACKnowledge condition after the address receive match code or next received byte.
- This parameter can be a value of @ref I2C_LL_EC_I2C_ACKNOWLEDGE
-
- This feature can be modified afterwards using unitary function @ref LL_I2C_AcknowledgeNextData(). */
-
- uint32_t OwnAddrSize; /*!< Specifies the device own address 1 size (7-bit or 10-bit).
- This parameter can be a value of @ref I2C_LL_EC_OWNADDRESS1
-
- This feature can be modified afterwards using unitary function @ref LL_I2C_SetOwnAddress1(). */
-} LL_I2C_InitTypeDef;
-/**
- * @}
- */
-#endif /*USE_FULL_LL_DRIVER*/
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup I2C_LL_Exported_Constants I2C Exported Constants
- * @{
- */
-
-/** @defgroup I2C_LL_EC_GET_FLAG Get Flags Defines
- * @brief Flags defines which can be used with LL_I2C_ReadReg function
- * @{
- */
-#define LL_I2C_SR1_SB I2C_SR1_SB /*!< Start Bit (master mode) */
-#define LL_I2C_SR1_ADDR I2C_SR1_ADDR /*!< Address sent (master mode) or
- Address matched flag (slave mode) */
-#define LL_I2C_SR1_BTF I2C_SR1_BTF /*!< Byte Transfer Finished flag */
-#define LL_I2C_SR1_ADD10 I2C_SR1_ADD10 /*!< 10-bit header sent (master mode) */
-#define LL_I2C_SR1_STOPF I2C_SR1_STOPF /*!< Stop detection flag (slave mode) */
-#define LL_I2C_SR1_RXNE I2C_SR1_RXNE /*!< Data register not empty (receivers) */
-#define LL_I2C_SR1_TXE I2C_SR1_TXE /*!< Data register empty (transmitters) */
-#define LL_I2C_SR1_BERR I2C_SR1_BERR /*!< Bus error */
-#define LL_I2C_SR1_ARLO I2C_SR1_ARLO /*!< Arbitration lost */
-#define LL_I2C_SR1_AF I2C_SR1_AF /*!< Acknowledge failure flag */
-#define LL_I2C_SR1_OVR I2C_SR1_OVR /*!< Overrun/Underrun */
-#define LL_I2C_SR1_PECERR I2C_ISR_PECERR /*!< PEC Error in reception (SMBus mode) */
-#define LL_I2C_SR1_TIMEOUT I2C_ISR_TIMEOUT /*!< Timeout detection flag (SMBus mode) */
-#define LL_I2C_SR1_SMALERT I2C_ISR_SMALERT /*!< SMBus alert (SMBus mode) */
-#define LL_I2C_SR2_MSL I2C_SR2_MSL /*!< Master/Slave flag */
-#define LL_I2C_SR2_BUSY I2C_SR2_BUSY /*!< Bus busy flag */
-#define LL_I2C_SR2_TRA I2C_SR2_TRA /*!< Transmitter/receiver direction */
-#define LL_I2C_SR2_GENCALL I2C_SR2_GENCALL /*!< General call address (Slave mode) */
-#define LL_I2C_SR2_SMBDEFAULT I2C_SR2_SMBDEFAULT /*!< SMBus Device default address (Slave mode) */
-#define LL_I2C_SR2_SMBHOST I2C_SR2_SMBHOST /*!< SMBus Host address (Slave mode) */
-#define LL_I2C_SR2_DUALF I2C_SR2_DUALF /*!< Dual flag (Slave mode) */
-/**
- * @}
- */
-
-/** @defgroup I2C_LL_EC_IT IT Defines
- * @brief IT defines which can be used with LL_I2C_ReadReg and LL_I2C_WriteReg functions
- * @{
- */
-#define LL_I2C_CR2_ITEVTEN I2C_CR2_ITEVTEN /*!< Events interrupts enable */
-#define LL_I2C_CR2_ITBUFEN I2C_CR2_ITBUFEN /*!< Buffer interrupts enable */
-#define LL_I2C_CR2_ITERREN I2C_CR2_ITERREN /*!< Error interrupts enable */
-/**
- * @}
- */
-
-/** @defgroup I2C_LL_EC_OWNADDRESS1 Own Address 1 Length
- * @{
- */
-#define LL_I2C_OWNADDRESS1_7BIT 0x00004000U /*!< Own address 1 is a 7-bit address. */
-#define LL_I2C_OWNADDRESS1_10BIT (uint32_t)(I2C_OAR1_ADDMODE | 0x00004000U) /*!< Own address 1 is a 10-bit address. */
-/**
- * @}
- */
-
-/** @defgroup I2C_LL_EC_DUTYCYCLE Fast Mode Duty Cycle
- * @{
- */
-#define LL_I2C_DUTYCYCLE_2 0x00000000U /*!< I2C fast mode Tlow/Thigh = 2 */
-#define LL_I2C_DUTYCYCLE_16_9 I2C_CCR_DUTY /*!< I2C fast mode Tlow/Thigh = 16/9 */
-/**
- * @}
- */
-
-/** @defgroup I2C_LL_EC_CLOCK_SPEED_MODE Master Clock Speed Mode
- * @{
- */
-#define LL_I2C_CLOCK_SPEED_STANDARD_MODE 0x00000000U /*!< Master clock speed range is standard mode */
-#define LL_I2C_CLOCK_SPEED_FAST_MODE I2C_CCR_FS /*!< Master clock speed range is fast mode */
-/**
- * @}
- */
-
-/** @defgroup I2C_LL_EC_PERIPHERAL_MODE Peripheral Mode
- * @{
- */
-#define LL_I2C_MODE_I2C 0x00000000U /*!< I2C Master or Slave mode */
-#define LL_I2C_MODE_SMBUS_HOST (uint32_t)(I2C_CR1_SMBUS | I2C_CR1_SMBTYPE | I2C_CR1_ENARP) /*!< SMBus Host address acknowledge */
-#define LL_I2C_MODE_SMBUS_DEVICE I2C_CR1_SMBUS /*!< SMBus Device default mode (Default address not acknowledge) */
-#define LL_I2C_MODE_SMBUS_DEVICE_ARP (uint32_t)(I2C_CR1_SMBUS | I2C_CR1_ENARP) /*!< SMBus Device Default address acknowledge */
-/**
- * @}
- */
-
-/** @defgroup I2C_LL_EC_I2C_ACKNOWLEDGE Acknowledge Generation
- * @{
- */
-#define LL_I2C_ACK I2C_CR1_ACK /*!< ACK is sent after current received byte. */
-#define LL_I2C_NACK 0x00000000U /*!< NACK is sent after current received byte.*/
-/**
- * @}
- */
-
-/** @defgroup I2C_LL_EC_DIRECTION Read Write Direction
- * @{
- */
-#define LL_I2C_DIRECTION_WRITE I2C_SR2_TRA /*!< Bus is in write transfer */
-#define LL_I2C_DIRECTION_READ 0x00000000U /*!< Bus is in read transfer */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup I2C_LL_Exported_Macros I2C Exported Macros
- * @{
- */
-
-/** @defgroup I2C_LL_EM_WRITE_READ Common Write and read registers Macros
- * @{
- */
-
-/**
- * @brief Write a value in I2C register
- * @param __INSTANCE__ I2C Instance
- * @param __REG__ Register to be written
- * @param __VALUE__ Value to be written in the register
- * @retval None
- */
-#define LL_I2C_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
-
-/**
- * @brief Read a value in I2C register
- * @param __INSTANCE__ I2C Instance
- * @param __REG__ Register to be read
- * @retval Register value
- */
-#define LL_I2C_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
-/**
- * @}
- */
-
-/** @defgroup I2C_LL_EM_Exported_Macros_Helper Exported_Macros_Helper
- * @{
- */
-
-/**
- * @brief Convert Peripheral Clock Frequency in Mhz.
- * @param __PCLK__ This parameter must be a value of peripheral clock (in Hz).
- * @retval Value of peripheral clock (in Mhz)
- */
-#define __LL_I2C_FREQ_HZ_TO_MHZ(__PCLK__) (uint32_t)((__PCLK__)/1000000U)
-
-/**
- * @brief Convert Peripheral Clock Frequency in Hz.
- * @param __PCLK__ This parameter must be a value of peripheral clock (in Mhz).
- * @retval Value of peripheral clock (in Hz)
- */
-#define __LL_I2C_FREQ_MHZ_TO_HZ(__PCLK__) (uint32_t)((__PCLK__)*1000000U)
-
-/**
- * @brief Compute I2C Clock rising time.
- * @param __FREQRANGE__ This parameter must be a value of peripheral clock (in Mhz).
- * @param __SPEED__ This parameter must be a value lower than 400kHz (in Hz).
- * @retval Value between Min_Data=0x02 and Max_Data=0x3F
- */
-#define __LL_I2C_RISE_TIME(__FREQRANGE__, __SPEED__) (uint32_t)(((__SPEED__) <= LL_I2C_MAX_SPEED_STANDARD) ? ((__FREQRANGE__) + 1U) : ((((__FREQRANGE__) * 300U) / 1000U) + 1U))
-
-/**
- * @brief Compute Speed clock range to a Clock Control Register (I2C_CCR_CCR) value.
- * @param __PCLK__ This parameter must be a value of peripheral clock (in Hz).
- * @param __SPEED__ This parameter must be a value lower than 400kHz (in Hz).
- * @param __DUTYCYCLE__ This parameter can be one of the following values:
- * @arg @ref LL_I2C_DUTYCYCLE_2
- * @arg @ref LL_I2C_DUTYCYCLE_16_9
- * @retval Value between Min_Data=0x004 and Max_Data=0xFFF, except in FAST DUTY mode where Min_Data=0x001.
- */
-#define __LL_I2C_SPEED_TO_CCR(__PCLK__, __SPEED__, __DUTYCYCLE__) (uint32_t)(((__SPEED__) <= LL_I2C_MAX_SPEED_STANDARD)? \
- (__LL_I2C_SPEED_STANDARD_TO_CCR((__PCLK__), (__SPEED__))) : \
- (__LL_I2C_SPEED_FAST_TO_CCR((__PCLK__), (__SPEED__), (__DUTYCYCLE__))))
-
-/**
- * @brief Compute Speed Standard clock range to a Clock Control Register (I2C_CCR_CCR) value.
- * @param __PCLK__ This parameter must be a value of peripheral clock (in Hz).
- * @param __SPEED__ This parameter must be a value lower than 100kHz (in Hz).
- * @retval Value between Min_Data=0x004 and Max_Data=0xFFF.
- */
-#define __LL_I2C_SPEED_STANDARD_TO_CCR(__PCLK__, __SPEED__) (uint32_t)(((((__PCLK__)/((__SPEED__) << 1U)) & I2C_CCR_CCR) < 4U)? 4U:((__PCLK__) / ((__SPEED__) << 1U)))
-
-/**
- * @brief Compute Speed Fast clock range to a Clock Control Register (I2C_CCR_CCR) value.
- * @param __PCLK__ This parameter must be a value of peripheral clock (in Hz).
- * @param __SPEED__ This parameter must be a value between Min_Data=100Khz and Max_Data=400Khz (in Hz).
- * @param __DUTYCYCLE__ This parameter can be one of the following values:
- * @arg @ref LL_I2C_DUTYCYCLE_2
- * @arg @ref LL_I2C_DUTYCYCLE_16_9
- * @retval Value between Min_Data=0x001 and Max_Data=0xFFF
- */
-#define __LL_I2C_SPEED_FAST_TO_CCR(__PCLK__, __SPEED__, __DUTYCYCLE__) (uint32_t)(((__DUTYCYCLE__) == LL_I2C_DUTYCYCLE_2)? \
- (((((__PCLK__) / ((__SPEED__) * 3U)) & I2C_CCR_CCR) == 0U)? 1U:((__PCLK__) / ((__SPEED__) * 3U))) : \
- (((((__PCLK__) / ((__SPEED__) * 25U)) & I2C_CCR_CCR) == 0U)? 1U:((__PCLK__) / ((__SPEED__) * 25U))))
-
-/**
- * @brief Get the Least significant bits of a 10-Bits address.
- * @param __ADDRESS__ This parameter must be a value of a 10-Bits slave address.
- * @retval Value between Min_Data=0x00 and Max_Data=0xFF
- */
-#define __LL_I2C_10BIT_ADDRESS(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FF))))
-
-/**
- * @brief Convert a 10-Bits address to a 10-Bits header with Write direction.
- * @param __ADDRESS__ This parameter must be a value of a 10-Bits slave address.
- * @retval Value between Min_Data=0xF0 and Max_Data=0xF6
- */
-#define __LL_I2C_10BIT_HEADER_WRITE(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0x0300))) >> 7) | (uint16_t)(0xF0))))
-
-/**
- * @brief Convert a 10-Bits address to a 10-Bits header with Read direction.
- * @param __ADDRESS__ This parameter must be a value of a 10-Bits slave address.
- * @retval Value between Min_Data=0xF1 and Max_Data=0xF7
- */
-#define __LL_I2C_10BIT_HEADER_READ(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0x0300))) >> 7) | (uint16_t)(0xF1))))
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-
-/** @defgroup I2C_LL_Exported_Functions I2C Exported Functions
- * @{
- */
-
-/** @defgroup I2C_LL_EF_Configuration Configuration
- * @{
- */
-
-/**
- * @brief Enable I2C peripheral (PE = 1).
- * @rmtoll CR1 PE LL_I2C_Enable
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_Enable(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->CR1, I2C_CR1_PE);
-}
-
-/**
- * @brief Disable I2C peripheral (PE = 0).
- * @rmtoll CR1 PE LL_I2C_Disable
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_Disable(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->CR1, I2C_CR1_PE);
-}
-
-/**
- * @brief Check if the I2C peripheral is enabled or disabled.
- * @rmtoll CR1 PE LL_I2C_IsEnabled
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsEnabled(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->CR1, I2C_CR1_PE) == (I2C_CR1_PE));
-}
-
-
-/**
- * @brief Enable DMA transmission requests.
- * @rmtoll CR2 DMAEN LL_I2C_EnableDMAReq_TX
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_EnableDMAReq_TX(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->CR2, I2C_CR2_DMAEN);
-}
-
-/**
- * @brief Disable DMA transmission requests.
- * @rmtoll CR2 DMAEN LL_I2C_DisableDMAReq_TX
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_DisableDMAReq_TX(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->CR2, I2C_CR2_DMAEN);
-}
-
-/**
- * @brief Check if DMA transmission requests are enabled or disabled.
- * @rmtoll CR2 DMAEN LL_I2C_IsEnabledDMAReq_TX
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsEnabledDMAReq_TX(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->CR2, I2C_CR2_DMAEN) == (I2C_CR2_DMAEN));
-}
-
-/**
- * @brief Enable DMA reception requests.
- * @rmtoll CR2 DMAEN LL_I2C_EnableDMAReq_RX
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_EnableDMAReq_RX(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->CR2, I2C_CR2_DMAEN);
-}
-
-/**
- * @brief Disable DMA reception requests.
- * @rmtoll CR2 DMAEN LL_I2C_DisableDMAReq_RX
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_DisableDMAReq_RX(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->CR2, I2C_CR2_DMAEN);
-}
-
-/**
- * @brief Check if DMA reception requests are enabled or disabled.
- * @rmtoll CR2 DMAEN LL_I2C_IsEnabledDMAReq_RX
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsEnabledDMAReq_RX(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->CR2, I2C_CR2_DMAEN) == (I2C_CR2_DMAEN));
-}
-
-/**
- * @brief Get the data register address used for DMA transfer.
- * @rmtoll DR DR LL_I2C_DMA_GetRegAddr
- * @param I2Cx I2C Instance.
- * @retval Address of data register
- */
-__STATIC_INLINE uint32_t LL_I2C_DMA_GetRegAddr(I2C_TypeDef *I2Cx)
-{
- return (uint32_t) & (I2Cx->DR);
-}
-
-/**
- * @brief Enable Clock stretching.
- * @note This bit can only be programmed when the I2C is disabled (PE = 0).
- * @rmtoll CR1 NOSTRETCH LL_I2C_EnableClockStretching
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_EnableClockStretching(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->CR1, I2C_CR1_NOSTRETCH);
-}
-
-/**
- * @brief Disable Clock stretching.
- * @note This bit can only be programmed when the I2C is disabled (PE = 0).
- * @rmtoll CR1 NOSTRETCH LL_I2C_DisableClockStretching
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_DisableClockStretching(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->CR1, I2C_CR1_NOSTRETCH);
-}
-
-/**
- * @brief Check if Clock stretching is enabled or disabled.
- * @rmtoll CR1 NOSTRETCH LL_I2C_IsEnabledClockStretching
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsEnabledClockStretching(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->CR1, I2C_CR1_NOSTRETCH) != (I2C_CR1_NOSTRETCH));
-}
-
-/**
- * @brief Enable General Call.
- * @note When enabled the Address 0x00 is ACKed.
- * @rmtoll CR1 ENGC LL_I2C_EnableGeneralCall
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_EnableGeneralCall(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->CR1, I2C_CR1_ENGC);
-}
-
-/**
- * @brief Disable General Call.
- * @note When disabled the Address 0x00 is NACKed.
- * @rmtoll CR1 ENGC LL_I2C_DisableGeneralCall
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_DisableGeneralCall(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->CR1, I2C_CR1_ENGC);
-}
-
-/**
- * @brief Check if General Call is enabled or disabled.
- * @rmtoll CR1 ENGC LL_I2C_IsEnabledGeneralCall
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsEnabledGeneralCall(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->CR1, I2C_CR1_ENGC) == (I2C_CR1_ENGC));
-}
-
-/**
- * @brief Set the Own Address1.
- * @rmtoll OAR1 ADD0 LL_I2C_SetOwnAddress1\n
- * OAR1 ADD1_7 LL_I2C_SetOwnAddress1\n
- * OAR1 ADD8_9 LL_I2C_SetOwnAddress1\n
- * OAR1 ADDMODE LL_I2C_SetOwnAddress1
- * @param I2Cx I2C Instance.
- * @param OwnAddress1 This parameter must be a value between Min_Data=0 and Max_Data=0x3FF.
- * @param OwnAddrSize This parameter can be one of the following values:
- * @arg @ref LL_I2C_OWNADDRESS1_7BIT
- * @arg @ref LL_I2C_OWNADDRESS1_10BIT
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_SetOwnAddress1(I2C_TypeDef *I2Cx, uint32_t OwnAddress1, uint32_t OwnAddrSize)
-{
- MODIFY_REG(I2Cx->OAR1, I2C_OAR1_ADD0 | I2C_OAR1_ADD1_7 | I2C_OAR1_ADD8_9 | I2C_OAR1_ADDMODE, OwnAddress1 | OwnAddrSize);
-}
-
-/**
- * @brief Set the 7bits Own Address2.
- * @note This action has no effect if own address2 is enabled.
- * @rmtoll OAR2 ADD2 LL_I2C_SetOwnAddress2
- * @param I2Cx I2C Instance.
- * @param OwnAddress2 This parameter must be a value between Min_Data=0 and Max_Data=0x7F.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_SetOwnAddress2(I2C_TypeDef *I2Cx, uint32_t OwnAddress2)
-{
- MODIFY_REG(I2Cx->OAR2, I2C_OAR2_ADD2, OwnAddress2);
-}
-
-/**
- * @brief Enable acknowledge on Own Address2 match address.
- * @rmtoll OAR2 ENDUAL LL_I2C_EnableOwnAddress2
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_EnableOwnAddress2(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->OAR2, I2C_OAR2_ENDUAL);
-}
-
-/**
- * @brief Disable acknowledge on Own Address2 match address.
- * @rmtoll OAR2 ENDUAL LL_I2C_DisableOwnAddress2
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_DisableOwnAddress2(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->OAR2, I2C_OAR2_ENDUAL);
-}
-
-/**
- * @brief Check if Own Address1 acknowledge is enabled or disabled.
- * @rmtoll OAR2 ENDUAL LL_I2C_IsEnabledOwnAddress2
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsEnabledOwnAddress2(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->OAR2, I2C_OAR2_ENDUAL) == (I2C_OAR2_ENDUAL));
-}
-
-/**
- * @brief Configure the Peripheral clock frequency.
- * @rmtoll CR2 FREQ LL_I2C_SetPeriphClock
- * @param I2Cx I2C Instance.
- * @param PeriphClock Peripheral Clock (in Hz)
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_SetPeriphClock(I2C_TypeDef *I2Cx, uint32_t PeriphClock)
-{
- MODIFY_REG(I2Cx->CR2, I2C_CR2_FREQ, __LL_I2C_FREQ_HZ_TO_MHZ(PeriphClock));
-}
-
-/**
- * @brief Get the Peripheral clock frequency.
- * @rmtoll CR2 FREQ LL_I2C_GetPeriphClock
- * @param I2Cx I2C Instance.
- * @retval Value of Peripheral Clock (in Hz)
- */
-__STATIC_INLINE uint32_t LL_I2C_GetPeriphClock(I2C_TypeDef *I2Cx)
-{
- return (uint32_t)(__LL_I2C_FREQ_MHZ_TO_HZ(READ_BIT(I2Cx->CR2, I2C_CR2_FREQ)));
-}
-
-/**
- * @brief Configure the Duty cycle (Fast mode only).
- * @rmtoll CCR DUTY LL_I2C_SetDutyCycle
- * @param I2Cx I2C Instance.
- * @param DutyCycle This parameter can be one of the following values:
- * @arg @ref LL_I2C_DUTYCYCLE_2
- * @arg @ref LL_I2C_DUTYCYCLE_16_9
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_SetDutyCycle(I2C_TypeDef *I2Cx, uint32_t DutyCycle)
-{
- MODIFY_REG(I2Cx->CCR, I2C_CCR_DUTY, DutyCycle);
-}
-
-/**
- * @brief Get the Duty cycle (Fast mode only).
- * @rmtoll CCR DUTY LL_I2C_GetDutyCycle
- * @param I2Cx I2C Instance.
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_I2C_DUTYCYCLE_2
- * @arg @ref LL_I2C_DUTYCYCLE_16_9
- */
-__STATIC_INLINE uint32_t LL_I2C_GetDutyCycle(I2C_TypeDef *I2Cx)
-{
- return (uint32_t)(READ_BIT(I2Cx->CCR, I2C_CCR_DUTY));
-}
-
-/**
- * @brief Configure the I2C master clock speed mode.
- * @rmtoll CCR FS LL_I2C_SetClockSpeedMode
- * @param I2Cx I2C Instance.
- * @param ClockSpeedMode This parameter can be one of the following values:
- * @arg @ref LL_I2C_CLOCK_SPEED_STANDARD_MODE
- * @arg @ref LL_I2C_CLOCK_SPEED_FAST_MODE
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_SetClockSpeedMode(I2C_TypeDef *I2Cx, uint32_t ClockSpeedMode)
-{
- MODIFY_REG(I2Cx->CCR, I2C_CCR_FS, ClockSpeedMode);
-}
-
-/**
- * @brief Get the the I2C master speed mode.
- * @rmtoll CCR FS LL_I2C_GetClockSpeedMode
- * @param I2Cx I2C Instance.
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_I2C_CLOCK_SPEED_STANDARD_MODE
- * @arg @ref LL_I2C_CLOCK_SPEED_FAST_MODE
- */
-__STATIC_INLINE uint32_t LL_I2C_GetClockSpeedMode(I2C_TypeDef *I2Cx)
-{
- return (uint32_t)(READ_BIT(I2Cx->CCR, I2C_CCR_FS));
-}
-
-/**
- * @brief Configure the SCL, SDA rising time.
- * @note This bit can only be programmed when the I2C is disabled (PE = 0).
- * @rmtoll TRISE TRISE LL_I2C_SetRiseTime
- * @param I2Cx I2C Instance.
- * @param RiseTime This parameter must be a value between Min_Data=0x02 and Max_Data=0x3F.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_SetRiseTime(I2C_TypeDef *I2Cx, uint32_t RiseTime)
-{
- MODIFY_REG(I2Cx->TRISE, I2C_TRISE_TRISE, RiseTime);
-}
-
-/**
- * @brief Get the SCL, SDA rising time.
- * @rmtoll TRISE TRISE LL_I2C_GetRiseTime
- * @param I2Cx I2C Instance.
- * @retval Value between Min_Data=0x02 and Max_Data=0x3F
- */
-__STATIC_INLINE uint32_t LL_I2C_GetRiseTime(I2C_TypeDef *I2Cx)
-{
- return (uint32_t)(READ_BIT(I2Cx->TRISE, I2C_TRISE_TRISE));
-}
-
-/**
- * @brief Configure the SCL high and low period.
- * @note This bit can only be programmed when the I2C is disabled (PE = 0).
- * @rmtoll CCR CCR LL_I2C_SetClockPeriod
- * @param I2Cx I2C Instance.
- * @param ClockPeriod This parameter must be a value between Min_Data=0x004 and Max_Data=0xFFF, except in FAST DUTY mode where Min_Data=0x001.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_SetClockPeriod(I2C_TypeDef *I2Cx, uint32_t ClockPeriod)
-{
- MODIFY_REG(I2Cx->CCR, I2C_CCR_CCR, ClockPeriod);
-}
-
-/**
- * @brief Get the SCL high and low period.
- * @rmtoll CCR CCR LL_I2C_GetClockPeriod
- * @param I2Cx I2C Instance.
- * @retval Value between Min_Data=0x004 and Max_Data=0xFFF, except in FAST DUTY mode where Min_Data=0x001.
- */
-__STATIC_INLINE uint32_t LL_I2C_GetClockPeriod(I2C_TypeDef *I2Cx)
-{
- return (uint32_t)(READ_BIT(I2Cx->CCR, I2C_CCR_CCR));
-}
-
-/**
- * @brief Configure the SCL speed.
- * @note This bit can only be programmed when the I2C is disabled (PE = 0).
- * @rmtoll CR2 FREQ LL_I2C_ConfigSpeed\n
- * TRISE TRISE LL_I2C_ConfigSpeed\n
- * CCR FS LL_I2C_ConfigSpeed\n
- * CCR DUTY LL_I2C_ConfigSpeed\n
- * CCR CCR LL_I2C_ConfigSpeed
- * @param I2Cx I2C Instance.
- * @param PeriphClock Peripheral Clock (in Hz)
- * @param ClockSpeed This parameter must be a value lower than 400kHz (in Hz).
- * @param DutyCycle This parameter can be one of the following values:
- * @arg @ref LL_I2C_DUTYCYCLE_2
- * @arg @ref LL_I2C_DUTYCYCLE_16_9
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_ConfigSpeed(I2C_TypeDef *I2Cx, uint32_t PeriphClock, uint32_t ClockSpeed,
- uint32_t DutyCycle)
-{
- register uint32_t freqrange = 0x0U;
- register uint32_t clockconfig = 0x0U;
-
- /* Compute frequency range */
- freqrange = __LL_I2C_FREQ_HZ_TO_MHZ(PeriphClock);
-
- /* Configure I2Cx: Frequency range register */
- MODIFY_REG(I2Cx->CR2, I2C_CR2_FREQ, freqrange);
-
- /* Configure I2Cx: Rise Time register */
- MODIFY_REG(I2Cx->TRISE, I2C_TRISE_TRISE, __LL_I2C_RISE_TIME(freqrange, ClockSpeed));
-
- /* Configure Speed mode, Duty Cycle and Clock control register value */
- if (ClockSpeed > LL_I2C_MAX_SPEED_STANDARD)
- {
- /* Set Speed mode at fast and duty cycle for Clock Speed request in fast clock range */
- clockconfig = LL_I2C_CLOCK_SPEED_FAST_MODE | \
- __LL_I2C_SPEED_FAST_TO_CCR(PeriphClock, ClockSpeed, DutyCycle) | \
- DutyCycle;
- }
- else
- {
- /* Set Speed mode at standard for Clock Speed request in standard clock range */
- clockconfig = LL_I2C_CLOCK_SPEED_STANDARD_MODE | \
- __LL_I2C_SPEED_STANDARD_TO_CCR(PeriphClock, ClockSpeed);
- }
-
- /* Configure I2Cx: Clock control register */
- MODIFY_REG(I2Cx->CCR, (I2C_CCR_FS | I2C_CCR_DUTY | I2C_CCR_CCR), clockconfig);
-}
-
-/**
- * @brief Configure peripheral mode.
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @rmtoll CR1 SMBUS LL_I2C_SetMode\n
- * CR1 SMBTYPE LL_I2C_SetMode\n
- * CR1 ENARP LL_I2C_SetMode
- * @param I2Cx I2C Instance.
- * @param PeripheralMode This parameter can be one of the following values:
- * @arg @ref LL_I2C_MODE_I2C
- * @arg @ref LL_I2C_MODE_SMBUS_HOST
- * @arg @ref LL_I2C_MODE_SMBUS_DEVICE
- * @arg @ref LL_I2C_MODE_SMBUS_DEVICE_ARP
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_SetMode(I2C_TypeDef *I2Cx, uint32_t PeripheralMode)
-{
- MODIFY_REG(I2Cx->CR1, I2C_CR1_SMBUS | I2C_CR1_SMBTYPE | I2C_CR1_ENARP, PeripheralMode);
-}
-
-/**
- * @brief Get peripheral mode.
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @rmtoll CR1 SMBUS LL_I2C_GetMode\n
- * CR1 SMBTYPE LL_I2C_GetMode\n
- * CR1 ENARP LL_I2C_GetMode
- * @param I2Cx I2C Instance.
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_I2C_MODE_I2C
- * @arg @ref LL_I2C_MODE_SMBUS_HOST
- * @arg @ref LL_I2C_MODE_SMBUS_DEVICE
- * @arg @ref LL_I2C_MODE_SMBUS_DEVICE_ARP
- */
-__STATIC_INLINE uint32_t LL_I2C_GetMode(I2C_TypeDef *I2Cx)
-{
- return (uint32_t)(READ_BIT(I2Cx->CR1, I2C_CR1_SMBUS | I2C_CR1_SMBTYPE | I2C_CR1_ENARP));
-}
-
-/**
- * @brief Enable SMBus alert (Host or Device mode)
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @note SMBus Device mode:
- * - SMBus Alert pin is drived low and
- * Alert Response Address Header acknowledge is enabled.
- * SMBus Host mode:
- * - SMBus Alert pin management is supported.
- * @rmtoll CR1 ALERT LL_I2C_EnableSMBusAlert
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_EnableSMBusAlert(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->CR1, I2C_CR1_ALERT);
-}
-
-/**
- * @brief Disable SMBus alert (Host or Device mode)
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @note SMBus Device mode:
- * - SMBus Alert pin is not drived (can be used as a standard GPIO) and
- * Alert Response Address Header acknowledge is disabled.
- * SMBus Host mode:
- * - SMBus Alert pin management is not supported.
- * @rmtoll CR1 ALERT LL_I2C_DisableSMBusAlert
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_DisableSMBusAlert(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->CR1, I2C_CR1_ALERT);
-}
-
-/**
- * @brief Check if SMBus alert (Host or Device mode) is enabled or disabled.
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @rmtoll CR1 ALERT LL_I2C_IsEnabledSMBusAlert
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsEnabledSMBusAlert(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->CR1, I2C_CR1_ALERT) == (I2C_CR1_ALERT));
-}
-
-/**
- * @brief Enable SMBus Packet Error Calculation (PEC).
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @rmtoll CR1 ENPEC LL_I2C_EnableSMBusPEC
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_EnableSMBusPEC(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->CR1, I2C_CR1_ENPEC);
-}
-
-/**
- * @brief Disable SMBus Packet Error Calculation (PEC).
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @rmtoll CR1 ENPEC LL_I2C_DisableSMBusPEC
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_DisableSMBusPEC(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->CR1, I2C_CR1_ENPEC);
-}
-
-/**
- * @brief Check if SMBus Packet Error Calculation (PEC) is enabled or disabled.
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @rmtoll CR1 ENPEC LL_I2C_IsEnabledSMBusPEC
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsEnabledSMBusPEC(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->CR1, I2C_CR1_ENPEC) == (I2C_CR1_ENPEC));
-}
-
-/**
- * @}
- */
-
-/** @defgroup I2C_LL_EF_IT_Management IT_Management
- * @{
- */
-
-/**
- * @brief Enable TXE interrupt.
- * @rmtoll CR2 ITEVTEN LL_I2C_EnableIT_TX\n
- * CR2 ITBUFEN LL_I2C_EnableIT_TX
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_EnableIT_TX(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
-}
-
-/**
- * @brief Disable TXE interrupt.
- * @rmtoll CR2 ITEVTEN LL_I2C_DisableIT_TX\n
- * CR2 ITBUFEN LL_I2C_DisableIT_TX
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_DisableIT_TX(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
-}
-
-/**
- * @brief Check if the TXE Interrupt is enabled or disabled.
- * @rmtoll CR2 ITEVTEN LL_I2C_IsEnabledIT_TX\n
- * CR2 ITBUFEN LL_I2C_IsEnabledIT_TX
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_TX(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN) == (I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN));
-}
-
-/**
- * @brief Enable RXNE interrupt.
- * @rmtoll CR2 ITEVTEN LL_I2C_EnableIT_RX\n
- * CR2 ITBUFEN LL_I2C_EnableIT_RX
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_EnableIT_RX(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
-}
-
-/**
- * @brief Disable RXNE interrupt.
- * @rmtoll CR2 ITEVTEN LL_I2C_DisableIT_RX\n
- * CR2 ITBUFEN LL_I2C_DisableIT_RX
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_DisableIT_RX(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
-}
-
-/**
- * @brief Check if the RXNE Interrupt is enabled or disabled.
- * @rmtoll CR2 ITEVTEN LL_I2C_IsEnabledIT_RX\n
- * CR2 ITBUFEN LL_I2C_IsEnabledIT_RX
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_RX(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN) == (I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN));
-}
-
-/**
- * @brief Enable Events interrupts.
- * @note Any of these events will generate interrupt :
- * Start Bit (SB)
- * Address sent, Address matched (ADDR)
- * 10-bit header sent (ADD10)
- * Stop detection (STOPF)
- * Byte transfer finished (BTF)
- *
- * @note Any of these events will generate interrupt if Buffer interrupts are enabled too(using unitary function @ref LL_I2C_EnableIT_BUF()) :
- * Receive buffer not empty (RXNE)
- * Transmit buffer empty (TXE)
- * @rmtoll CR2 ITEVTEN LL_I2C_EnableIT_EVT
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_EnableIT_EVT(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN);
-}
-
-/**
- * @brief Disable Events interrupts.
- * @note Any of these events will generate interrupt :
- * Start Bit (SB)
- * Address sent, Address matched (ADDR)
- * 10-bit header sent (ADD10)
- * Stop detection (STOPF)
- * Byte transfer finished (BTF)
- * Receive buffer not empty (RXNE)
- * Transmit buffer empty (TXE)
- * @rmtoll CR2 ITEVTEN LL_I2C_DisableIT_EVT
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_DisableIT_EVT(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN);
-}
-
-/**
- * @brief Check if Events interrupts are enabled or disabled.
- * @rmtoll CR2 ITEVTEN LL_I2C_IsEnabledIT_EVT
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_EVT(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN) == (I2C_CR2_ITEVTEN));
-}
-
-/**
- * @brief Enable Buffer interrupts.
- * @note Any of these Buffer events will generate interrupt if Events interrupts are enabled too(using unitary function @ref LL_I2C_EnableIT_EVT()) :
- * Receive buffer not empty (RXNE)
- * Transmit buffer empty (TXE)
- * @rmtoll CR2 ITBUFEN LL_I2C_EnableIT_BUF
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_EnableIT_BUF(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->CR2, I2C_CR2_ITBUFEN);
-}
-
-/**
- * @brief Disable Buffer interrupts.
- * @note Any of these Buffer events will generate interrupt :
- * Receive buffer not empty (RXNE)
- * Transmit buffer empty (TXE)
- * @rmtoll CR2 ITBUFEN LL_I2C_DisableIT_BUF
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_DisableIT_BUF(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->CR2, I2C_CR2_ITBUFEN);
-}
-
-/**
- * @brief Check if Buffer interrupts are enabled or disabled.
- * @rmtoll CR2 ITBUFEN LL_I2C_IsEnabledIT_BUF
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_BUF(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->CR2, I2C_CR2_ITBUFEN) == (I2C_CR2_ITBUFEN));
-}
-
-/**
- * @brief Enable Error interrupts.
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @note Any of these errors will generate interrupt :
- * Bus Error detection (BERR)
- * Arbitration Loss (ARLO)
- * Acknowledge Failure(AF)
- * Overrun/Underrun (OVR)
- * SMBus Timeout detection (TIMEOUT)
- * SMBus PEC error detection (PECERR)
- * SMBus Alert pin event detection (SMBALERT)
- * @rmtoll CR2 ITERREN LL_I2C_EnableIT_ERR
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_EnableIT_ERR(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->CR2, I2C_CR2_ITERREN);
-}
-
-/**
- * @brief Disable Error interrupts.
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @note Any of these errors will generate interrupt :
- * Bus Error detection (BERR)
- * Arbitration Loss (ARLO)
- * Acknowledge Failure(AF)
- * Overrun/Underrun (OVR)
- * SMBus Timeout detection (TIMEOUT)
- * SMBus PEC error detection (PECERR)
- * SMBus Alert pin event detection (SMBALERT)
- * @rmtoll CR2 ITERREN LL_I2C_DisableIT_ERR
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_DisableIT_ERR(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->CR2, I2C_CR2_ITERREN);
-}
-
-/**
- * @brief Check if Error interrupts are enabled or disabled.
- * @rmtoll CR2 ITERREN LL_I2C_IsEnabledIT_ERR
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_ERR(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->CR2, I2C_CR2_ITERREN) == (I2C_CR2_ITERREN));
-}
-
-/**
- * @}
- */
-
-/** @defgroup I2C_LL_EF_FLAG_management FLAG_management
- * @{
- */
-
-/**
- * @brief Indicate the status of Transmit data register empty flag.
- * @note RESET: When next data is written in Transmit data register.
- * SET: When Transmit data register is empty.
- * @rmtoll SR1 TXE LL_I2C_IsActiveFlag_TXE
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_TXE(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR1, I2C_SR1_TXE) == (I2C_SR1_TXE));
-}
-
-/**
- * @brief Indicate the status of Byte Transfer Finished flag.
- * RESET: When Data byte transfer not done.
- * SET: When Data byte transfer succeeded.
- * @rmtoll SR1 BTF LL_I2C_IsActiveFlag_BTF
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_BTF(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR1, I2C_SR1_BTF) == (I2C_SR1_BTF));
-}
-
-/**
- * @brief Indicate the status of Receive data register not empty flag.
- * @note RESET: When Receive data register is read.
- * SET: When the received data is copied in Receive data register.
- * @rmtoll SR1 RXNE LL_I2C_IsActiveFlag_RXNE
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_RXNE(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR1, I2C_SR1_RXNE) == (I2C_SR1_RXNE));
-}
-
-/**
- * @brief Indicate the status of Start Bit (master mode).
- * @note RESET: When No Start condition.
- * SET: When Start condition is generated.
- * @rmtoll SR1 SB LL_I2C_IsActiveFlag_SB
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_SB(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR1, I2C_SR1_SB) == (I2C_SR1_SB));
-}
-
-/**
- * @brief Indicate the status of Address sent (master mode) or Address matched flag (slave mode).
- * @note RESET: Clear default value.
- * SET: When the address is fully sent (master mode) or when the received slave address matched with one of the enabled slave address (slave mode).
- * @rmtoll SR1 ADDR LL_I2C_IsActiveFlag_ADDR
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_ADDR(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR1, I2C_SR1_ADDR) == (I2C_SR1_ADDR));
-}
-
-/**
- * @brief Indicate the status of 10-bit header sent (master mode).
- * @note RESET: When no ADD10 event occured.
- * SET: When the master has sent the first address byte (header).
- * @rmtoll SR1 ADD10 LL_I2C_IsActiveFlag_ADD10
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_ADD10(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR1, I2C_SR1_ADD10) == (I2C_SR1_ADD10));
-}
-
-/**
- * @brief Indicate the status of Acknowledge failure flag.
- * @note RESET: No acknowledge failure.
- * SET: When an acknowledge failure is received after a byte transmission.
- * @rmtoll SR1 AF LL_I2C_IsActiveFlag_AF
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_AF(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR1, I2C_SR1_AF) == (I2C_SR1_AF));
-}
-
-/**
- * @brief Indicate the status of Stop detection flag (slave mode).
- * @note RESET: Clear default value.
- * SET: When a Stop condition is detected.
- * @rmtoll SR1 STOPF LL_I2C_IsActiveFlag_STOP
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_STOP(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR1, I2C_SR1_STOPF) == (I2C_SR1_STOPF));
-}
-
-/**
- * @brief Indicate the status of Bus error flag.
- * @note RESET: Clear default value.
- * SET: When a misplaced Start or Stop condition is detected.
- * @rmtoll SR1 BERR LL_I2C_IsActiveFlag_BERR
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_BERR(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR1, I2C_SR1_BERR) == (I2C_SR1_BERR));
-}
-
-/**
- * @brief Indicate the status of Arbitration lost flag.
- * @note RESET: Clear default value.
- * SET: When arbitration lost.
- * @rmtoll SR1 ARLO LL_I2C_IsActiveFlag_ARLO
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_ARLO(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR1, I2C_SR1_ARLO) == (I2C_SR1_ARLO));
-}
-
-/**
- * @brief Indicate the status of Overrun/Underrun flag.
- * @note RESET: Clear default value.
- * SET: When an overrun/underrun error occurs (Clock Stretching Disabled).
- * @rmtoll SR1 OVR LL_I2C_IsActiveFlag_OVR
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_OVR(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR1, I2C_SR1_OVR) == (I2C_SR1_OVR));
-}
-
-/**
- * @brief Indicate the status of SMBus PEC error flag in reception.
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @rmtoll SR1 PECERR LL_I2C_IsActiveSMBusFlag_PECERR
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_PECERR(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR1, I2C_SR1_PECERR) == (I2C_SR1_PECERR));
-}
-
-/**
- * @brief Indicate the status of SMBus Timeout detection flag.
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @rmtoll SR1 TIMEOUT LL_I2C_IsActiveSMBusFlag_TIMEOUT
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_TIMEOUT(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR1, I2C_SR1_TIMEOUT) == (I2C_SR1_TIMEOUT));
-}
-
-/**
- * @brief Indicate the status of SMBus alert flag.
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @rmtoll SR1 SMBALERT LL_I2C_IsActiveSMBusFlag_ALERT
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_ALERT(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR1, I2C_SR1_SMBALERT) == (I2C_SR1_SMBALERT));
-}
-
-/**
- * @brief Indicate the status of Bus Busy flag.
- * @note RESET: Clear default value.
- * SET: When a Start condition is detected.
- * @rmtoll SR2 BUSY LL_I2C_IsActiveFlag_BUSY
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_BUSY(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR2, I2C_SR2_BUSY) == (I2C_SR2_BUSY));
-}
-
-/**
- * @brief Indicate the status of Dual flag.
- * @note RESET: Received address matched with OAR1.
- * SET: Received address matched with OAR2.
- * @rmtoll SR2 DUALF LL_I2C_IsActiveFlag_DUAL
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_DUAL(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR2, I2C_SR2_DUALF) == (I2C_SR2_DUALF));
-}
-
-/**
- * @brief Indicate the status of SMBus Host address reception (Slave mode).
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @note RESET: No SMBus Host address
- * SET: SMBus Host address received.
- * @note This status is cleared by hardware after a STOP condition or repeated START condition.
- * @rmtoll SR2 SMBHOST LL_I2C_IsActiveSMBusFlag_SMBHOST
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_SMBHOST(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR2, I2C_SR2_SMBHOST) == (I2C_SR2_SMBHOST));
-}
-
-/**
- * @brief Indicate the status of SMBus Device default address reception (Slave mode).
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @note RESET: No SMBus Device default address
- * SET: SMBus Device default address received.
- * @note This status is cleared by hardware after a STOP condition or repeated START condition.
- * @rmtoll SR2 SMBDEFAULT LL_I2C_IsActiveSMBusFlag_SMBDEFAULT
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_SMBDEFAULT(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR2, I2C_SR2_SMBDEFAULT) == (I2C_SR2_SMBDEFAULT));
-}
-
-/**
- * @brief Indicate the status of General call address reception (Slave mode).
- * @note RESET: No Generall call address
- * SET: General call address received.
- * @note This status is cleared by hardware after a STOP condition or repeated START condition.
- * @rmtoll SR2 GENCALL LL_I2C_IsActiveFlag_GENCALL
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_GENCALL(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR2, I2C_SR2_GENCALL) == (I2C_SR2_GENCALL));
-}
-
-/**
- * @brief Indicate the status of Master/Slave flag.
- * @note RESET: Slave Mode.
- * SET: Master Mode.
- * @rmtoll SR2 MSL LL_I2C_IsActiveFlag_MSL
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_MSL(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->SR2, I2C_SR2_MSL) == (I2C_SR2_MSL));
-}
-
-/**
- * @brief Clear Address Matched flag.
- * @note Clearing this flag is done by a read access to the I2Cx_SR1
- * register followed by a read access to the I2Cx_SR2 register.
- * @rmtoll SR1 ADDR LL_I2C_ClearFlag_ADDR
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_ClearFlag_ADDR(I2C_TypeDef *I2Cx)
-{
- __IO uint32_t tmpreg;
- tmpreg = I2Cx->SR1;
- (void) tmpreg;
- tmpreg = I2Cx->SR2;
- (void) tmpreg;
-}
-
-/**
- * @brief Clear Acknowledge failure flag.
- * @rmtoll SR1 AF LL_I2C_ClearFlag_AF
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_ClearFlag_AF(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->SR1, I2C_SR1_AF);
-}
-
-/**
- * @brief Clear Stop detection flag.
- * @note Clearing this flag is done by a read access to the I2Cx_SR1
- * register followed by a write access to I2Cx_CR1 register.
- * @rmtoll SR1 STOPF LL_I2C_ClearFlag_STOP\n
- * CR1 PE LL_I2C_ClearFlag_STOP
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_ClearFlag_STOP(I2C_TypeDef *I2Cx)
-{
- __IO uint32_t tmpreg;
- tmpreg = I2Cx->SR1;
- (void) tmpreg;
- SET_BIT(I2Cx->CR1, I2C_CR1_PE);
-}
-
-/**
- * @brief Clear Bus error flag.
- * @rmtoll SR1 BERR LL_I2C_ClearFlag_BERR
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_ClearFlag_BERR(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->SR1, I2C_SR1_BERR);
-}
-
-/**
- * @brief Clear Arbitration lost flag.
- * @rmtoll SR1 ARLO LL_I2C_ClearFlag_ARLO
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_ClearFlag_ARLO(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->SR1, I2C_SR1_ARLO);
-}
-
-/**
- * @brief Clear Overrun/Underrun flag.
- * @rmtoll SR1 OVR LL_I2C_ClearFlag_OVR
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_ClearFlag_OVR(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->SR1, I2C_SR1_OVR);
-}
-
-/**
- * @brief Clear SMBus PEC error flag.
- * @rmtoll SR1 PECERR LL_I2C_ClearSMBusFlag_PECERR
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_ClearSMBusFlag_PECERR(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->SR1, I2C_SR1_PECERR);
-}
-
-/**
- * @brief Clear SMBus Timeout detection flag.
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @rmtoll SR1 TIMEOUT LL_I2C_ClearSMBusFlag_TIMEOUT
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_ClearSMBusFlag_TIMEOUT(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->SR1, I2C_SR1_TIMEOUT);
-}
-
-/**
- * @brief Clear SMBus Alert flag.
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @rmtoll SR1 SMBALERT LL_I2C_ClearSMBusFlag_ALERT
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_ClearSMBusFlag_ALERT(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->SR1, I2C_SR1_SMBALERT);
-}
-
-/**
- * @}
- */
-
-/** @defgroup I2C_LL_EF_Data_Management Data_Management
- * @{
- */
-
-/**
- * @brief Enable Reset of I2C peripheral.
- * @rmtoll CR1 SWRST LL_I2C_EnableReset
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_EnableReset(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->CR1, I2C_CR1_SWRST);
-}
-
-/**
- * @brief Disable Reset of I2C peripheral.
- * @rmtoll CR1 SWRST LL_I2C_DisableReset
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_DisableReset(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->CR1, I2C_CR1_SWRST);
-}
-
-/**
- * @brief Check if the I2C peripheral is under reset state or not.
- * @rmtoll CR1 SWRST LL_I2C_IsResetEnabled
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsResetEnabled(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->CR1, I2C_CR1_SWRST) == (I2C_CR1_SWRST));
-}
-
-/**
- * @brief Prepare the generation of a ACKnowledge or Non ACKnowledge condition after the address receive match code or next received byte.
- * @note Usage in Slave or Master mode.
- * @rmtoll CR1 ACK LL_I2C_AcknowledgeNextData
- * @param I2Cx I2C Instance.
- * @param TypeAcknowledge This parameter can be one of the following values:
- * @arg @ref LL_I2C_ACK
- * @arg @ref LL_I2C_NACK
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_AcknowledgeNextData(I2C_TypeDef *I2Cx, uint32_t TypeAcknowledge)
-{
- MODIFY_REG(I2Cx->CR1, I2C_CR1_ACK, TypeAcknowledge);
-}
-
-/**
- * @brief Generate a START or RESTART condition
- * @note The START bit can be set even if bus is BUSY or I2C is in slave mode.
- * This action has no effect when RELOAD is set.
- * @rmtoll CR1 START LL_I2C_GenerateStartCondition
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_GenerateStartCondition(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->CR1, I2C_CR1_START);
-}
-
-/**
- * @brief Generate a STOP condition after the current byte transfer (master mode).
- * @rmtoll CR1 STOP LL_I2C_GenerateStopCondition
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_GenerateStopCondition(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->CR1, I2C_CR1_STOP);
-}
-
-/**
- * @brief Enable bit POS (master/host mode).
- * @note In that case, the ACK bit controls the (N)ACK of the next byte received or the PEC bit indicates that the next byte in shift register is a PEC.
- * @rmtoll CR1 POS LL_I2C_EnableBitPOS
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_EnableBitPOS(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->CR1, I2C_CR1_POS);
-}
-
-/**
- * @brief Disable bit POS (master/host mode).
- * @note In that case, the ACK bit controls the (N)ACK of the current byte received or the PEC bit indicates that the current byte in shift register is a PEC.
- * @rmtoll CR1 POS LL_I2C_DisableBitPOS
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_DisableBitPOS(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->CR1, I2C_CR1_POS);
-}
-
-/**
- * @brief Check if bit POS is enabled or disabled.
- * @rmtoll CR1 POS LL_I2C_IsEnabledBitPOS
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsEnabledBitPOS(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->CR1, I2C_CR1_POS) == (I2C_CR1_POS));
-}
-
-/**
- * @brief Indicate the value of transfer direction.
- * @note RESET: Bus is in read transfer (peripheral point of view).
- * SET: Bus is in write transfer (peripheral point of view).
- * @rmtoll SR2 TRA LL_I2C_GetTransferDirection
- * @param I2Cx I2C Instance.
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_I2C_DIRECTION_WRITE
- * @arg @ref LL_I2C_DIRECTION_READ
- */
-__STATIC_INLINE uint32_t LL_I2C_GetTransferDirection(I2C_TypeDef *I2Cx)
-{
- return (uint32_t)(READ_BIT(I2Cx->SR2, I2C_SR2_TRA));
-}
-
-/**
- * @brief Enable DMA last transfer.
- * @note This action mean that next DMA EOT is the last transfer.
- * @rmtoll CR2 LAST LL_I2C_EnableLastDMA
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_EnableLastDMA(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->CR2, I2C_CR2_LAST);
-}
-
-/**
- * @brief Disable DMA last transfer.
- * @note This action mean that next DMA EOT is not the last transfer.
- * @rmtoll CR2 LAST LL_I2C_DisableLastDMA
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_DisableLastDMA(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->CR2, I2C_CR2_LAST);
-}
-
-/**
- * @brief Check if DMA last transfer is enabled or disabled.
- * @rmtoll CR2 LAST LL_I2C_IsEnabledLastDMA
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsEnabledLastDMA(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->CR2, I2C_CR2_LAST) == (I2C_CR2_LAST));
-}
-
-/**
- * @brief Enable transfer or internal comparison of the SMBus Packet Error byte (transmission or reception mode).
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @note This feature is cleared by hardware when the PEC byte is transferred or compared,
- * or by a START or STOP condition, it is also cleared by software.
- * @rmtoll CR1 PEC LL_I2C_EnableSMBusPECCompare
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_EnableSMBusPECCompare(I2C_TypeDef *I2Cx)
-{
- SET_BIT(I2Cx->CR1, I2C_CR1_PEC);
-}
-
-/**
- * @brief Disable transfer or internal comparison of the SMBus Packet Error byte (transmission or reception mode).
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @rmtoll CR1 PEC LL_I2C_DisableSMBusPECCompare
- * @param I2Cx I2C Instance.
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_DisableSMBusPECCompare(I2C_TypeDef *I2Cx)
-{
- CLEAR_BIT(I2Cx->CR1, I2C_CR1_PEC);
-}
-
-/**
- * @brief Check if the SMBus Packet Error byte transfer or internal comparison is requested or not.
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @rmtoll CR1 PEC LL_I2C_IsEnabledSMBusPECCompare
- * @param I2Cx I2C Instance.
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2C_IsEnabledSMBusPECCompare(I2C_TypeDef *I2Cx)
-{
- return (READ_BIT(I2Cx->CR1, I2C_CR1_PEC) == (I2C_CR1_PEC));
-}
-
-/**
- * @brief Get the SMBus Packet Error byte calculated.
- * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
- * SMBus feature is supported by the I2Cx Instance.
- * @rmtoll SR2 PEC LL_I2C_GetSMBusPEC
- * @param I2Cx I2C Instance.
- * @retval Value between Min_Data=0x00 and Max_Data=0xFF
- */
-__STATIC_INLINE uint32_t LL_I2C_GetSMBusPEC(I2C_TypeDef *I2Cx)
-{
- return (uint32_t)(READ_BIT(I2Cx->SR2, I2C_SR2_PEC) >> I2C_SR2_PEC_Pos);
-}
-
-/**
- * @brief Read Receive Data register.
- * @rmtoll DR DR LL_I2C_ReceiveData8
- * @param I2Cx I2C Instance.
- * @retval Value between Min_Data=0x0 and Max_Data=0xFF
- */
-__STATIC_INLINE uint8_t LL_I2C_ReceiveData8(I2C_TypeDef *I2Cx)
-{
- return (uint8_t)(READ_BIT(I2Cx->DR, I2C_DR_DR));
-}
-
-/**
- * @brief Write in Transmit Data Register .
- * @rmtoll DR DR LL_I2C_TransmitData8
- * @param I2Cx I2C Instance.
- * @param Data Value between Min_Data=0x0 and Max_Data=0xFF
- * @retval None
- */
-__STATIC_INLINE void LL_I2C_TransmitData8(I2C_TypeDef *I2Cx, uint8_t Data)
-{
- MODIFY_REG(I2Cx->DR, I2C_DR_DR, Data);
-}
-
-/**
- * @}
- */
-
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup I2C_LL_EF_Init Initialization and de-initialization functions
- * @{
- */
-
-uint32_t LL_I2C_Init(I2C_TypeDef *I2Cx, LL_I2C_InitTypeDef *I2C_InitStruct);
-uint32_t LL_I2C_DeInit(I2C_TypeDef *I2Cx);
-void LL_I2C_StructInit(LL_I2C_InitTypeDef *I2C_InitStruct);
-
-
-/**
- * @}
- */
-#endif /* USE_FULL_LL_DRIVER */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* I2C1 || I2C2 */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_LL_I2C_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_iwdg.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_iwdg.h
deleted file mode 100644
index 0f39fb5..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_iwdg.h
+++ /dev/null
@@ -1,327 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_iwdg.h
- * @author MCD Application Team
- * @brief Header file of IWDG LL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_LL_IWDG_H
-#define __STM32F1xx_LL_IWDG_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx.h"
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined(IWDG)
-
-/** @defgroup IWDG_LL IWDG
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup IWDG_LL_Private_Constants IWDG Private Constants
- * @{
- */
-
-#define LL_IWDG_KEY_RELOAD 0x0000AAAAU /*!< IWDG Reload Counter Enable */
-#define LL_IWDG_KEY_ENABLE 0x0000CCCCU /*!< IWDG Peripheral Enable */
-#define LL_IWDG_KEY_WR_ACCESS_ENABLE 0x00005555U /*!< IWDG KR Write Access Enable */
-#define LL_IWDG_KEY_WR_ACCESS_DISABLE 0x00000000U /*!< IWDG KR Write Access Disable */
-
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-
-/* Exported types ------------------------------------------------------------*/
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup IWDG_LL_Exported_Constants IWDG Exported Constants
- * @{
- */
-
-/** @defgroup IWDG_LL_EC_GET_FLAG Get Flags Defines
- * @brief Flags defines which can be used with LL_IWDG_ReadReg function
- * @{
- */
-#define LL_IWDG_SR_PVU IWDG_SR_PVU /*!< Watchdog prescaler value update */
-#define LL_IWDG_SR_RVU IWDG_SR_RVU /*!< Watchdog counter reload value update */
-
-/**
- * @}
- */
-
-/** @defgroup IWDG_LL_EC_PRESCALER Prescaler Divider
- * @{
- */
-#define LL_IWDG_PRESCALER_4 0x00000000U /*!< Divider by 4 */
-#define LL_IWDG_PRESCALER_8 (IWDG_PR_PR_0) /*!< Divider by 8 */
-#define LL_IWDG_PRESCALER_16 (IWDG_PR_PR_1) /*!< Divider by 16 */
-#define LL_IWDG_PRESCALER_32 (IWDG_PR_PR_1 | IWDG_PR_PR_0) /*!< Divider by 32 */
-#define LL_IWDG_PRESCALER_64 (IWDG_PR_PR_2) /*!< Divider by 64 */
-#define LL_IWDG_PRESCALER_128 (IWDG_PR_PR_2 | IWDG_PR_PR_0) /*!< Divider by 128 */
-#define LL_IWDG_PRESCALER_256 (IWDG_PR_PR_2 | IWDG_PR_PR_1) /*!< Divider by 256 */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup IWDG_LL_Exported_Macros IWDG Exported Macros
- * @{
- */
-
-/** @defgroup IWDG_LL_EM_WRITE_READ Common Write and read registers Macros
- * @{
- */
-
-/**
- * @brief Write a value in IWDG register
- * @param __INSTANCE__ IWDG Instance
- * @param __REG__ Register to be written
- * @param __VALUE__ Value to be written in the register
- * @retval None
- */
-#define LL_IWDG_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
-
-/**
- * @brief Read a value in IWDG register
- * @param __INSTANCE__ IWDG Instance
- * @param __REG__ Register to be read
- * @retval Register value
- */
-#define LL_IWDG_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup IWDG_LL_Exported_Functions IWDG Exported Functions
- * @{
- */
-/** @defgroup IWDG_LL_EF_Configuration Configuration
- * @{
- */
-
-/**
- * @brief Start the Independent Watchdog
- * @note Except if the hardware watchdog option is selected
- * @rmtoll KR KEY LL_IWDG_Enable
- * @param IWDGx IWDG Instance
- * @retval None
- */
-__STATIC_INLINE void LL_IWDG_Enable(IWDG_TypeDef *IWDGx)
-{
- WRITE_REG(IWDG->KR, LL_IWDG_KEY_ENABLE);
-}
-
-/**
- * @brief Reloads IWDG counter with value defined in the reload register
- * @rmtoll KR KEY LL_IWDG_ReloadCounter
- * @param IWDGx IWDG Instance
- * @retval None
- */
-__STATIC_INLINE void LL_IWDG_ReloadCounter(IWDG_TypeDef *IWDGx)
-{
- WRITE_REG(IWDG->KR, LL_IWDG_KEY_RELOAD);
-}
-
-/**
- * @brief Enable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers
- * @rmtoll KR KEY LL_IWDG_EnableWriteAccess
- * @param IWDGx IWDG Instance
- * @retval None
- */
-__STATIC_INLINE void LL_IWDG_EnableWriteAccess(IWDG_TypeDef *IWDGx)
-{
- WRITE_REG(IWDG->KR, LL_IWDG_KEY_WR_ACCESS_ENABLE);
-}
-
-/**
- * @brief Disable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers
- * @rmtoll KR KEY LL_IWDG_DisableWriteAccess
- * @param IWDGx IWDG Instance
- * @retval None
- */
-__STATIC_INLINE void LL_IWDG_DisableWriteAccess(IWDG_TypeDef *IWDGx)
-{
- WRITE_REG(IWDG->KR, LL_IWDG_KEY_WR_ACCESS_DISABLE);
-}
-
-/**
- * @brief Select the prescaler of the IWDG
- * @rmtoll PR PR LL_IWDG_SetPrescaler
- * @param IWDGx IWDG Instance
- * @param Prescaler This parameter can be one of the following values:
- * @arg @ref LL_IWDG_PRESCALER_4
- * @arg @ref LL_IWDG_PRESCALER_8
- * @arg @ref LL_IWDG_PRESCALER_16
- * @arg @ref LL_IWDG_PRESCALER_32
- * @arg @ref LL_IWDG_PRESCALER_64
- * @arg @ref LL_IWDG_PRESCALER_128
- * @arg @ref LL_IWDG_PRESCALER_256
- * @retval None
- */
-__STATIC_INLINE void LL_IWDG_SetPrescaler(IWDG_TypeDef *IWDGx, uint32_t Prescaler)
-{
- WRITE_REG(IWDGx->PR, IWDG_PR_PR & Prescaler);
-}
-
-/**
- * @brief Get the selected prescaler of the IWDG
- * @rmtoll PR PR LL_IWDG_GetPrescaler
- * @param IWDGx IWDG Instance
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_IWDG_PRESCALER_4
- * @arg @ref LL_IWDG_PRESCALER_8
- * @arg @ref LL_IWDG_PRESCALER_16
- * @arg @ref LL_IWDG_PRESCALER_32
- * @arg @ref LL_IWDG_PRESCALER_64
- * @arg @ref LL_IWDG_PRESCALER_128
- * @arg @ref LL_IWDG_PRESCALER_256
- */
-__STATIC_INLINE uint32_t LL_IWDG_GetPrescaler(IWDG_TypeDef *IWDGx)
-{
- return (uint32_t)(READ_REG(IWDGx->PR));
-}
-
-/**
- * @brief Specify the IWDG down-counter reload value
- * @rmtoll RLR RL LL_IWDG_SetReloadCounter
- * @param IWDGx IWDG Instance
- * @param Counter Value between Min_Data=0 and Max_Data=0x0FFF
- * @retval None
- */
-__STATIC_INLINE void LL_IWDG_SetReloadCounter(IWDG_TypeDef *IWDGx, uint32_t Counter)
-{
- WRITE_REG(IWDGx->RLR, IWDG_RLR_RL & Counter);
-}
-
-/**
- * @brief Get the specified IWDG down-counter reload value
- * @rmtoll RLR RL LL_IWDG_GetReloadCounter
- * @param IWDGx IWDG Instance
- * @retval Value between Min_Data=0 and Max_Data=0x0FFF
- */
-__STATIC_INLINE uint32_t LL_IWDG_GetReloadCounter(IWDG_TypeDef *IWDGx)
-{
- return (uint32_t)(READ_REG(IWDGx->RLR));
-}
-
-
-/**
- * @}
- */
-
-/** @defgroup IWDG_LL_EF_FLAG_Management FLAG_Management
- * @{
- */
-
-/**
- * @brief Check if flag Prescaler Value Update is set or not
- * @rmtoll SR PVU LL_IWDG_IsActiveFlag_PVU
- * @param IWDGx IWDG Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_IWDG_IsActiveFlag_PVU(IWDG_TypeDef *IWDGx)
-{
- return (READ_BIT(IWDGx->SR, IWDG_SR_PVU) == (IWDG_SR_PVU));
-}
-
-/**
- * @brief Check if flag Reload Value Update is set or not
- * @rmtoll SR RVU LL_IWDG_IsActiveFlag_RVU
- * @param IWDGx IWDG Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_IWDG_IsActiveFlag_RVU(IWDG_TypeDef *IWDGx)
-{
- return (READ_BIT(IWDGx->SR, IWDG_SR_RVU) == (IWDG_SR_RVU));
-}
-
-
-/**
- * @brief Check if all flags Prescaler, Reload & Window Value Update are reset or not
- * @rmtoll SR PVU LL_IWDG_IsReady\n
- * SR RVU LL_IWDG_IsReady
- * @param IWDGx IWDG Instance
- * @retval State of bits (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_IWDG_IsReady(IWDG_TypeDef *IWDGx)
-{
- return (READ_BIT(IWDGx->SR, IWDG_SR_PVU | IWDG_SR_RVU) == 0U);
-}
-
-/**
- * @}
- */
-
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* IWDG) */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_LL_IWDG_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_pwr.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_pwr.h
deleted file mode 100644
index f4106da..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_pwr.h
+++ /dev/null
@@ -1,456 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_pwr.h
- * @author MCD Application Team
- * @brief Header file of PWR LL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_LL_PWR_H
-#define __STM32F1xx_LL_PWR_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx.h"
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined(PWR)
-
-/** @defgroup PWR_LL PWR
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-/* Exported types ------------------------------------------------------------*/
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup PWR_LL_Exported_Constants PWR Exported Constants
- * @{
- */
-
-/** @defgroup PWR_LL_EC_CLEAR_FLAG Clear Flags Defines
- * @brief Flags defines which can be used with LL_PWR_WriteReg function
- * @{
- */
-#define LL_PWR_CR_CSBF PWR_CR_CSBF /*!< Clear standby flag */
-#define LL_PWR_CR_CWUF PWR_CR_CWUF /*!< Clear wakeup flag */
-/**
- * @}
- */
-
-/** @defgroup PWR_LL_EC_GET_FLAG Get Flags Defines
- * @brief Flags defines which can be used with LL_PWR_ReadReg function
- * @{
- */
-#define LL_PWR_CSR_WUF PWR_CSR_WUF /*!< Wakeup flag */
-#define LL_PWR_CSR_SBF PWR_CSR_SBF /*!< Standby flag */
-#define LL_PWR_CSR_PVDO PWR_CSR_PVDO /*!< Power voltage detector output flag */
-#define LL_PWR_CSR_EWUP1 PWR_CSR_EWUP /*!< Enable WKUP pin 1 */
-/**
- * @}
- */
-
-
-/** @defgroup PWR_LL_EC_MODE_PWR Mode Power
- * @{
- */
-#define LL_PWR_MODE_STOP_MAINREGU 0x00000000U /*!< Enter Stop mode when the CPU enters deepsleep */
-#define LL_PWR_MODE_STOP_LPREGU (PWR_CR_LPDS) /*!< Enter Stop mode (with low power Regulator ON) when the CPU enters deepsleep */
-#define LL_PWR_MODE_STANDBY (PWR_CR_PDDS) /*!< Enter Standby mode when the CPU enters deepsleep */
-/**
- * @}
- */
-
-/** @defgroup PWR_LL_EC_REGU_MODE_DS_MODE Regulator Mode In Deep Sleep Mode
- * @{
- */
-#define LL_PWR_REGU_DSMODE_MAIN 0x00000000U /*!< Voltage Regulator in main mode during deepsleep mode */
-#define LL_PWR_REGU_DSMODE_LOW_POWER (PWR_CR_LPDS) /*!< Voltage Regulator in low-power mode during deepsleep mode */
-/**
- * @}
- */
-
-/** @defgroup PWR_LL_EC_PVDLEVEL Power Voltage Detector Level
- * @{
- */
-#define LL_PWR_PVDLEVEL_0 (PWR_CR_PLS_LEV0) /*!< Voltage threshold detected by PVD 2.2 V */
-#define LL_PWR_PVDLEVEL_1 (PWR_CR_PLS_LEV1) /*!< Voltage threshold detected by PVD 2.3 V */
-#define LL_PWR_PVDLEVEL_2 (PWR_CR_PLS_LEV2) /*!< Voltage threshold detected by PVD 2.4 V */
-#define LL_PWR_PVDLEVEL_3 (PWR_CR_PLS_LEV3) /*!< Voltage threshold detected by PVD 2.5 V */
-#define LL_PWR_PVDLEVEL_4 (PWR_CR_PLS_LEV4) /*!< Voltage threshold detected by PVD 2.6 V */
-#define LL_PWR_PVDLEVEL_5 (PWR_CR_PLS_LEV5) /*!< Voltage threshold detected by PVD 2.7 V */
-#define LL_PWR_PVDLEVEL_6 (PWR_CR_PLS_LEV6) /*!< Voltage threshold detected by PVD 2.8 V */
-#define LL_PWR_PVDLEVEL_7 (PWR_CR_PLS_LEV7) /*!< Voltage threshold detected by PVD 2.9 V */
-/**
- * @}
- */
-/** @defgroup PWR_LL_EC_WAKEUP_PIN Wakeup Pins
- * @{
- */
-#define LL_PWR_WAKEUP_PIN1 (PWR_CSR_EWUP) /*!< WKUP pin 1 : PA0 */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup PWR_LL_Exported_Macros PWR Exported Macros
- * @{
- */
-
-/** @defgroup PWR_LL_EM_WRITE_READ Common write and read registers Macros
- * @{
- */
-
-/**
- * @brief Write a value in PWR register
- * @param __REG__ Register to be written
- * @param __VALUE__ Value to be written in the register
- * @retval None
- */
-#define LL_PWR_WriteReg(__REG__, __VALUE__) WRITE_REG(PWR->__REG__, (__VALUE__))
-
-/**
- * @brief Read a value in PWR register
- * @param __REG__ Register to be read
- * @retval Register value
- */
-#define LL_PWR_ReadReg(__REG__) READ_REG(PWR->__REG__)
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup PWR_LL_Exported_Functions PWR Exported Functions
- * @{
- */
-
-/** @defgroup PWR_LL_EF_Configuration Configuration
- * @{
- */
-
-/**
- * @brief Enable access to the backup domain
- * @rmtoll CR DBP LL_PWR_EnableBkUpAccess
- * @retval None
- */
-__STATIC_INLINE void LL_PWR_EnableBkUpAccess(void)
-{
- SET_BIT(PWR->CR, PWR_CR_DBP);
-}
-
-/**
- * @brief Disable access to the backup domain
- * @rmtoll CR DBP LL_PWR_DisableBkUpAccess
- * @retval None
- */
-__STATIC_INLINE void LL_PWR_DisableBkUpAccess(void)
-{
- CLEAR_BIT(PWR->CR, PWR_CR_DBP);
-}
-
-/**
- * @brief Check if the backup domain is enabled
- * @rmtoll CR DBP LL_PWR_IsEnabledBkUpAccess
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_PWR_IsEnabledBkUpAccess(void)
-{
- return (READ_BIT(PWR->CR, PWR_CR_DBP) == (PWR_CR_DBP));
-}
-
-/**
- * @brief Set voltage Regulator mode during deep sleep mode
- * @rmtoll CR LPDS LL_PWR_SetRegulModeDS
- * @param RegulMode This parameter can be one of the following values:
- * @arg @ref LL_PWR_REGU_DSMODE_MAIN
- * @arg @ref LL_PWR_REGU_DSMODE_LOW_POWER
- * @retval None
- */
-__STATIC_INLINE void LL_PWR_SetRegulModeDS(uint32_t RegulMode)
-{
- MODIFY_REG(PWR->CR, PWR_CR_LPDS, RegulMode);
-}
-
-/**
- * @brief Get voltage Regulator mode during deep sleep mode
- * @rmtoll CR LPDS LL_PWR_GetRegulModeDS
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_PWR_REGU_DSMODE_MAIN
- * @arg @ref LL_PWR_REGU_DSMODE_LOW_POWER
- */
-__STATIC_INLINE uint32_t LL_PWR_GetRegulModeDS(void)
-{
- return (uint32_t)(READ_BIT(PWR->CR, PWR_CR_LPDS));
-}
-
-/**
- * @brief Set Power Down mode when CPU enters deepsleep
- * @rmtoll CR PDDS LL_PWR_SetPowerMode\n
- * @rmtoll CR LPDS LL_PWR_SetPowerMode
- * @param PDMode This parameter can be one of the following values:
- * @arg @ref LL_PWR_MODE_STOP_MAINREGU
- * @arg @ref LL_PWR_MODE_STOP_LPREGU
- * @arg @ref LL_PWR_MODE_STANDBY
- * @retval None
- */
-__STATIC_INLINE void LL_PWR_SetPowerMode(uint32_t PDMode)
-{
- MODIFY_REG(PWR->CR, (PWR_CR_PDDS| PWR_CR_LPDS), PDMode);
-}
-
-/**
- * @brief Get Power Down mode when CPU enters deepsleep
- * @rmtoll CR PDDS LL_PWR_GetPowerMode\n
- * @rmtoll CR LPDS LL_PWR_GetPowerMode
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_PWR_MODE_STOP_MAINREGU
- * @arg @ref LL_PWR_MODE_STOP_LPREGU
- * @arg @ref LL_PWR_MODE_STANDBY
- */
-__STATIC_INLINE uint32_t LL_PWR_GetPowerMode(void)
-{
- return (uint32_t)(READ_BIT(PWR->CR, (PWR_CR_PDDS| PWR_CR_LPDS)));
-}
-
-/**
- * @brief Configure the voltage threshold detected by the Power Voltage Detector
- * @rmtoll CR PLS LL_PWR_SetPVDLevel
- * @param PVDLevel This parameter can be one of the following values:
- * @arg @ref LL_PWR_PVDLEVEL_0
- * @arg @ref LL_PWR_PVDLEVEL_1
- * @arg @ref LL_PWR_PVDLEVEL_2
- * @arg @ref LL_PWR_PVDLEVEL_3
- * @arg @ref LL_PWR_PVDLEVEL_4
- * @arg @ref LL_PWR_PVDLEVEL_5
- * @arg @ref LL_PWR_PVDLEVEL_6
- * @arg @ref LL_PWR_PVDLEVEL_7
- * @retval None
- */
-__STATIC_INLINE void LL_PWR_SetPVDLevel(uint32_t PVDLevel)
-{
- MODIFY_REG(PWR->CR, PWR_CR_PLS, PVDLevel);
-}
-
-/**
- * @brief Get the voltage threshold detection
- * @rmtoll CR PLS LL_PWR_GetPVDLevel
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_PWR_PVDLEVEL_0
- * @arg @ref LL_PWR_PVDLEVEL_1
- * @arg @ref LL_PWR_PVDLEVEL_2
- * @arg @ref LL_PWR_PVDLEVEL_3
- * @arg @ref LL_PWR_PVDLEVEL_4
- * @arg @ref LL_PWR_PVDLEVEL_5
- * @arg @ref LL_PWR_PVDLEVEL_6
- * @arg @ref LL_PWR_PVDLEVEL_7
- */
-__STATIC_INLINE uint32_t LL_PWR_GetPVDLevel(void)
-{
- return (uint32_t)(READ_BIT(PWR->CR, PWR_CR_PLS));
-}
-
-/**
- * @brief Enable Power Voltage Detector
- * @rmtoll CR PVDE LL_PWR_EnablePVD
- * @retval None
- */
-__STATIC_INLINE void LL_PWR_EnablePVD(void)
-{
- SET_BIT(PWR->CR, PWR_CR_PVDE);
-}
-
-/**
- * @brief Disable Power Voltage Detector
- * @rmtoll CR PVDE LL_PWR_DisablePVD
- * @retval None
- */
-__STATIC_INLINE void LL_PWR_DisablePVD(void)
-{
- CLEAR_BIT(PWR->CR, PWR_CR_PVDE);
-}
-
-/**
- * @brief Check if Power Voltage Detector is enabled
- * @rmtoll CR PVDE LL_PWR_IsEnabledPVD
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_PWR_IsEnabledPVD(void)
-{
- return (READ_BIT(PWR->CR, PWR_CR_PVDE) == (PWR_CR_PVDE));
-}
-
-/**
- * @brief Enable the WakeUp PINx functionality
- * @rmtoll CSR EWUP LL_PWR_EnableWakeUpPin
- * @param WakeUpPin This parameter can be one of the following values:
- * @arg @ref LL_PWR_WAKEUP_PIN1
- * @retval None
- */
-__STATIC_INLINE void LL_PWR_EnableWakeUpPin(uint32_t WakeUpPin)
-{
- SET_BIT(PWR->CSR, WakeUpPin);
-}
-
-/**
- * @brief Disable the WakeUp PINx functionality
- * @rmtoll CSR EWUP LL_PWR_DisableWakeUpPin
- * @param WakeUpPin This parameter can be one of the following values:
- * @arg @ref LL_PWR_WAKEUP_PIN1
- * @retval None
- */
-__STATIC_INLINE void LL_PWR_DisableWakeUpPin(uint32_t WakeUpPin)
-{
- CLEAR_BIT(PWR->CSR, WakeUpPin);
-}
-
-/**
- * @brief Check if the WakeUp PINx functionality is enabled
- * @rmtoll CSR EWUP LL_PWR_IsEnabledWakeUpPin
- * @param WakeUpPin This parameter can be one of the following values:
- * @arg @ref LL_PWR_WAKEUP_PIN1
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_PWR_IsEnabledWakeUpPin(uint32_t WakeUpPin)
-{
- return (READ_BIT(PWR->CSR, WakeUpPin) == (WakeUpPin));
-}
-
-
-/**
- * @}
- */
-
-/** @defgroup PWR_LL_EF_FLAG_Management FLAG_Management
- * @{
- */
-
-/**
- * @brief Get Wake-up Flag
- * @rmtoll CSR WUF LL_PWR_IsActiveFlag_WU
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_WU(void)
-{
- return (READ_BIT(PWR->CSR, PWR_CSR_WUF) == (PWR_CSR_WUF));
-}
-
-/**
- * @brief Get Standby Flag
- * @rmtoll CSR SBF LL_PWR_IsActiveFlag_SB
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_SB(void)
-{
- return (READ_BIT(PWR->CSR, PWR_CSR_SBF) == (PWR_CSR_SBF));
-}
-
-/**
- * @brief Indicate whether VDD voltage is below the selected PVD threshold
- * @rmtoll CSR PVDO LL_PWR_IsActiveFlag_PVDO
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_PVDO(void)
-{
- return (READ_BIT(PWR->CSR, PWR_CSR_PVDO) == (PWR_CSR_PVDO));
-}
-
-/**
- * @brief Clear Standby Flag
- * @rmtoll CR CSBF LL_PWR_ClearFlag_SB
- * @retval None
- */
-__STATIC_INLINE void LL_PWR_ClearFlag_SB(void)
-{
- SET_BIT(PWR->CR, PWR_CR_CSBF);
-}
-
-/**
- * @brief Clear Wake-up Flags
- * @rmtoll CR CWUF LL_PWR_ClearFlag_WU
- * @retval None
- */
-__STATIC_INLINE void LL_PWR_ClearFlag_WU(void)
-{
- SET_BIT(PWR->CR, PWR_CR_CWUF);
-}
-
-/**
- * @}
- */
-
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup PWR_LL_EF_Init De-initialization function
- * @{
- */
-ErrorStatus LL_PWR_DeInit(void);
-/**
- * @}
- */
-#endif /* USE_FULL_LL_DRIVER */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* defined(PWR) */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_LL_PWR_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_rtc.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_rtc.h
deleted file mode 100644
index c434010..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_rtc.h
+++ /dev/null
@@ -1,1019 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_rtc.h
- * @author MCD Application Team
- * @brief Header file of RTC LL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_LL_RTC_H
-#define __STM32F1xx_LL_RTC_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx.h"
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined(RTC)
-
-/** @defgroup RTC_LL RTC
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-
-/* Private macros ------------------------------------------------------------*/
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup RTC_LL_Private_Macros RTC Private Macros
- * @{
- */
-/**
- * @}
- */
-#endif /*USE_FULL_LL_DRIVER*/
-
-/* Exported types ------------------------------------------------------------*/
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup RTC_LL_ES_INIT RTC Exported Init structure
- * @{
- */
-
-/**
- * @brief RTC Init structures definition
- */
-typedef struct
-{
- uint32_t AsynchPrescaler; /*!< Specifies the RTC Asynchronous Predivider value.
- This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFFFFF
-
- This feature can be modified afterwards using unitary function
- @ref LL_RTC_SetAsynchPrescaler(). */
-
- uint32_t OutPutSource; /*!< Specifies which signal will be routed to the RTC Tamper pin.
- This parameter can be a value of @ref LL_RTC_Output_Source
-
- This feature can be modified afterwards using unitary function
- @ref LL_RTC_SetOutputSource(). */
-
-} LL_RTC_InitTypeDef;
-
-/**
- * @brief RTC Time structure definition
- */
-typedef struct
-{
- uint8_t Hours; /*!< Specifies the RTC Time Hours.
- This parameter must be a number between Min_Data = 0 and Max_Data = 23 */
-
- uint8_t Minutes; /*!< Specifies the RTC Time Minutes.
- This parameter must be a number between Min_Data = 0 and Max_Data = 59 */
-
- uint8_t Seconds; /*!< Specifies the RTC Time Seconds.
- This parameter must be a number between Min_Data = 0 and Max_Data = 59 */
-} LL_RTC_TimeTypeDef;
-
-
-/**
- * @brief RTC Alarm structure definition
- */
-typedef struct
-{
- LL_RTC_TimeTypeDef AlarmTime; /*!< Specifies the RTC Alarm Time members. */
-
-} LL_RTC_AlarmTypeDef;
-
-/**
- * @}
- */
-#endif /* USE_FULL_LL_DRIVER */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup RTC_LL_Exported_Constants RTC Exported Constants
- * @{
- */
-
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup RTC_LL_EC_FORMAT FORMAT
- * @{
- */
-#define LL_RTC_FORMAT_BIN (0x000000000U) /*!< Binary data format */
-#define LL_RTC_FORMAT_BCD (0x000000001U) /*!< BCD data format */
-/**
- * @}
- */
-#endif /* USE_FULL_LL_DRIVER */
-
-/** @defgroup RTC_LL_EC_BKP BACKUP
- * @{
- */
-#if RTC_BKP_NUMBER > 0
-#define LL_RTC_BKP_DR1 (0x00000001U)
-#define LL_RTC_BKP_DR2 (0x00000002U)
-#define LL_RTC_BKP_DR3 (0x00000003U)
-#define LL_RTC_BKP_DR4 (0x00000004U)
-#define LL_RTC_BKP_DR5 (0x00000005U)
-#define LL_RTC_BKP_DR6 (0x00000006U)
-#define LL_RTC_BKP_DR7 (0x00000007U)
-#define LL_RTC_BKP_DR8 (0x00000008U)
-#define LL_RTC_BKP_DR9 (0x00000009U)
-#define LL_RTC_BKP_DR10 (0x0000000AU)
-#endif /* RTC_BKP_NUMBER > 0 */
-#if RTC_BKP_NUMBER > 10
-#define LL_RTC_BKP_DR11 (0x0000000BU)
-#define LL_RTC_BKP_DR12 (0x0000000CU)
-#define LL_RTC_BKP_DR13 (0x0000000DU)
-#define LL_RTC_BKP_DR14 (0x0000000EU)
-#define LL_RTC_BKP_DR15 (0x0000000FU)
-#define LL_RTC_BKP_DR16 (0x00000010U)
-#define LL_RTC_BKP_DR17 (0x00000011U)
-#define LL_RTC_BKP_DR18 (0x00000012U)
-#define LL_RTC_BKP_DR19 (0x00000013U)
-#define LL_RTC_BKP_DR20 (0x00000014U)
-#define LL_RTC_BKP_DR21 (0x00000015U)
-#define LL_RTC_BKP_DR22 (0x00000016U)
-#define LL_RTC_BKP_DR23 (0x00000017U)
-#define LL_RTC_BKP_DR24 (0x00000018U)
-#define LL_RTC_BKP_DR25 (0x00000019U)
-#define LL_RTC_BKP_DR26 (0x0000001AU)
-#define LL_RTC_BKP_DR27 (0x0000001BU)
-#define LL_RTC_BKP_DR28 (0x0000001CU)
-#define LL_RTC_BKP_DR29 (0x0000001DU)
-#define LL_RTC_BKP_DR30 (0x0000001EU)
-#define LL_RTC_BKP_DR31 (0x0000001FU)
-#define LL_RTC_BKP_DR32 (0x00000020U)
-#define LL_RTC_BKP_DR33 (0x00000021U)
-#define LL_RTC_BKP_DR34 (0x00000022U)
-#define LL_RTC_BKP_DR35 (0x00000023U)
-#define LL_RTC_BKP_DR36 (0x00000024U)
-#define LL_RTC_BKP_DR37 (0x00000025U)
-#define LL_RTC_BKP_DR38 (0x00000026U)
-#define LL_RTC_BKP_DR39 (0x00000027U)
-#define LL_RTC_BKP_DR40 (0x00000028U)
-#define LL_RTC_BKP_DR41 (0x00000029U)
-#define LL_RTC_BKP_DR42 (0x0000002AU)
-#endif /* RTC_BKP_NUMBER > 10 */
-
-/**
- * @}
- */
-
-/** @defgroup RTC_LL_EC_TAMPLEVEL Tamper Active Level
- * @{
- */
-#define LL_RTC_TAMPER_ACTIVELEVEL_LOW BKP_CR_TPAL /*!< A high level on the TAMPER pin resets all data backup registers (if TPE bit is set) */
-#define LL_RTC_TAMPER_ACTIVELEVEL_HIGH (0x00000000U) /*!< A low level on the TAMPER pin resets all data backup registers (if TPE bit is set) */
-
-/**
- * @}
- */
-
-/** @defgroup LL_RTC_Output_Source Clock Source to output on the Tamper Pin
- * @{
- */
-#define LL_RTC_CALIB_OUTPUT_NONE (0x00000000U) /*!< Calibration output disabled */
-#define LL_RTC_CALIB_OUTPUT_RTCCLOCK BKP_RTCCR_CCO /*!< Calibration output is RTC Clock with a frequency divided by 64 on the TAMPER Pin */
-#define LL_RTC_CALIB_OUTPUT_ALARM BKP_RTCCR_ASOE /*!< Calibration output is Alarm pulse signal on the TAMPER pin */
-#define LL_RTC_CALIB_OUTPUT_SECOND (BKP_RTCCR_ASOS | BKP_RTCCR_ASOE) /*!< Calibration output is Second pulse signal on the TAMPER pin*/
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup RTC_LL_Exported_Macros RTC Exported Macros
- * @{
- */
-
-/** @defgroup RTC_LL_EM_WRITE_READ Common Write and read registers Macros
- * @{
- */
-
-/**
- * @brief Write a value in RTC register
- * @param __INSTANCE__ RTC Instance
- * @param __REG__ Register to be written
- * @param __VALUE__ Value to be written in the register
- * @retval None
- */
-#define LL_RTC_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
-
-/**
- * @brief Read a value in RTC register
- * @param __INSTANCE__ RTC Instance
- * @param __REG__ Register to be read
- * @retval Register value
- */
-#define LL_RTC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
-/**
- * @}
- */
-
-/** @defgroup RTC_LL_EM_Convert Convert helper Macros
- * @{
- */
-
-/**
- * @brief Helper macro to convert a value from 2 digit decimal format to BCD format
- * @param __VALUE__ Byte to be converted
- * @retval Converted byte
- */
-#define __LL_RTC_CONVERT_BIN2BCD(__VALUE__) (uint8_t)((((__VALUE__) / 10U) << 4U) | ((__VALUE__) % 10U))
-
-/**
- * @brief Helper macro to convert a value from BCD format to 2 digit decimal format
- * @param __VALUE__ BCD value to be converted
- * @retval Converted byte
- */
-#define __LL_RTC_CONVERT_BCD2BIN(__VALUE__) (uint8_t)(((uint8_t)((__VALUE__) & (uint8_t)0xF0U) >> (uint8_t)0x4U) * 10U + ((__VALUE__) & (uint8_t)0x0FU))
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup RTC_LL_Exported_Functions RTC Exported Functions
- * @{
- */
-
-/** @defgroup RTC_LL_EF_Configuration Configuration
- * @{
- */
-
-/**
- * @brief Set Asynchronous prescaler factor
- * @rmtoll PRLH PRL LL_RTC_SetAsynchPrescaler\n
- * @rmtoll PRLL PRL LL_RTC_SetAsynchPrescaler\n
- * @param RTCx RTC Instance
- * @param AsynchPrescaler Value between Min_Data = 0 and Max_Data = 0xFFFFF
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_SetAsynchPrescaler(RTC_TypeDef *RTCx, uint32_t AsynchPrescaler)
-{
- MODIFY_REG(RTCx->PRLH, RTC_PRLH_PRL, (AsynchPrescaler >> 16));
- MODIFY_REG(RTCx->PRLL, RTC_PRLL_PRL, (AsynchPrescaler & RTC_PRLL_PRL));
-}
-
-/**
- * @brief Get Asynchronous prescaler factor
- * @rmtoll DIVH DIV LL_RTC_GetDivider\n
- * @rmtoll DIVL DIV LL_RTC_GetDivider\n
- * @param RTCx RTC Instance
- * @retval Value between Min_Data = 0 and Max_Data = 0xFFFFF
- */
-__STATIC_INLINE uint32_t LL_RTC_GetDivider(RTC_TypeDef *RTCx)
-{
- register uint16_t Highprescaler = 0 , Lowprescaler = 0;
- Highprescaler = READ_REG(RTCx->DIVH & RTC_DIVH_RTC_DIV);
- Lowprescaler = READ_REG(RTCx->DIVL & RTC_DIVL_RTC_DIV);
-
- return (((uint32_t) Highprescaler << 16U) | Lowprescaler);
-}
-
-/**
- * @brief Set Output Source
- * @rmtoll RTCCR CCO LL_RTC_SetOutputSource
- * @rmtoll RTCCR ASOE LL_RTC_SetOutputSource
- * @rmtoll RTCCR ASOS LL_RTC_SetOutputSource
- * @param BKPx BKP Instance
- * @param OutputSource This parameter can be one of the following values:
- * @arg @ref LL_RTC_CALIB_OUTPUT_NONE
- * @arg @ref LL_RTC_CALIB_OUTPUT_RTCCLOCK
- * @arg @ref LL_RTC_CALIB_OUTPUT_ALARM
- * @arg @ref LL_RTC_CALIB_OUTPUT_SECOND
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_SetOutputSource(BKP_TypeDef *BKPx, uint32_t OutputSource)
-{
- MODIFY_REG(BKPx->RTCCR, (BKP_RTCCR_CCO | BKP_RTCCR_ASOE | BKP_RTCCR_ASOS), OutputSource);
-}
-
-/**
- * @brief Get Output Source
- * @rmtoll RTCCR CCO LL_RTC_GetOutPutSource
- * @rmtoll RTCCR ASOE LL_RTC_GetOutPutSource
- * @rmtoll RTCCR ASOS LL_RTC_GetOutPutSource
- * @param BKPx BKP Instance
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_RTC_CALIB_OUTPUT_NONE
- * @arg @ref LL_RTC_CALIB_OUTPUT_RTCCLOCK
- * @arg @ref LL_RTC_CALIB_OUTPUT_ALARM
- * @arg @ref LL_RTC_CALIB_OUTPUT_SECOND
- */
-__STATIC_INLINE uint32_t LL_RTC_GetOutPutSource(BKP_TypeDef *BKPx)
-{
- return (uint32_t)(READ_BIT(BKPx->RTCCR, (BKP_RTCCR_CCO | BKP_RTCCR_ASOE | BKP_RTCCR_ASOS)));
-}
-
-/**
- * @brief Enable the write protection for RTC registers.
- * @rmtoll CRL CNF LL_RTC_EnableWriteProtection
- * @param RTCx RTC Instance
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_EnableWriteProtection(RTC_TypeDef *RTCx)
-{
- CLEAR_BIT(RTCx->CRL, RTC_CRL_CNF);
-}
-
-/**
- * @brief Disable the write protection for RTC registers.
- * @rmtoll CRL RTC_CRL_CNF LL_RTC_DisableWriteProtection
- * @param RTCx RTC Instance
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_DisableWriteProtection(RTC_TypeDef *RTCx)
-{
- SET_BIT(RTCx->CRL, RTC_CRL_CNF);
-}
-
-/**
- * @}
- */
-
-/** @defgroup RTC_LL_EF_Time Time
- * @{
- */
-
-/**
- * @brief Set time counter in BCD format
- * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
- * @note It can be written in initialization mode only (@ref LL_RTC_EnterInitMode function)
- * @rmtoll CNTH CNT LL_RTC_TIME_Set\n
- * CNTL CNT LL_RTC_TIME_Set\n
- * @param RTCx RTC Instance
- * @param TimeCounter Value between Min_Data=0x00 and Max_Data=0xFFFFF
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_TIME_Set(RTC_TypeDef *RTCx, uint32_t TimeCounter)
-{
- /* Set RTC COUNTER MSB word */
- WRITE_REG(RTCx->CNTH, (TimeCounter >> 16U));
- /* Set RTC COUNTER LSB word */
- WRITE_REG(RTCx->CNTL, (TimeCounter & RTC_CNTL_RTC_CNT));
-}
-
-/**
- * @brief Get time counter in BCD format
- * @rmtoll CNTH CNT LL_RTC_TIME_Get\n
- * CNTL CNT LL_RTC_TIME_Get\n
- * @param RTCx RTC Instance
- * @retval Value between Min_Data = 0 and Max_Data = 0xFFFFF
- */
-__STATIC_INLINE uint32_t LL_RTC_TIME_Get(RTC_TypeDef *RTCx)
-{
- register uint16_t high = 0, low = 0;
-
- high = READ_REG(RTCx->CNTH & RTC_CNTH_RTC_CNT);
- low = READ_REG(RTCx->CNTL & RTC_CNTL_RTC_CNT);
- return ((uint32_t)(((uint32_t) high << 16U) | low));
-}
-
-/**
- * @}
- */
-
-/** @defgroup RTC_LL_EF_ALARM ALARM
- * @{
- */
-
-/**
- * @brief Set Alarm Counter
- * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
- * @rmtoll ALRH ALR LL_RTC_ALARM_Set\n
- * @rmtoll ALRL ALR LL_RTC_ALARM_Set\n
- * @param RTCx RTC Instance
- * @param AlarmCounter Value between Min_Data=0x00 and Max_Data=0xFFFFF
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_ALARM_Set(RTC_TypeDef *RTCx, uint32_t AlarmCounter)
-{
- /* Set RTC COUNTER MSB word */
- WRITE_REG(RTCx->ALRH, (AlarmCounter >> 16));
- /* Set RTC COUNTER LSB word */
- WRITE_REG(RTCx->ALRL, (AlarmCounter & RTC_ALRL_RTC_ALR));
-}
-
-/**
- * @brief Get Alarm Counter
- * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
- * @rmtoll ALRH ALR LL_RTC_ALARM_Get\n
- * @rmtoll ALRL ALR LL_RTC_ALARM_Get\n
- * @param RTCx RTC Instance
- * @retval None
- */
-__STATIC_INLINE uint32_t LL_RTC_ALARM_Get(RTC_TypeDef *RTCx)
-{
- register uint16_t high = 0, low = 0;
-
- high = READ_REG(RTCx->ALRH & RTC_ALRH_RTC_ALR);
- low = READ_REG(RTCx->ALRL & RTC_ALRL_RTC_ALR);
-
- return (((uint32_t) high << 16U) | low);
-}
-
-/**
- * @}
- */
-
-/** @defgroup RTC_LL_EF_Tamper Tamper
- * @{
- */
-
-/**
- * @brief Enable RTC_TAMPx input detection
- * @rmtoll CR TPE LL_RTC_TAMPER_Enable\n
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_TAMPER_Enable(BKP_TypeDef *BKPx)
-{
- SET_BIT(BKPx->CR, BKP_CR_TPE);
-}
-
-/**
- * @brief Disable RTC_TAMPx Tamper
- * @rmtoll CR TPE LL_RTC_TAMPER_Disable\n
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_TAMPER_Disable(BKP_TypeDef *BKPx)
-{
- CLEAR_BIT(BKP->CR, BKP_CR_TPE);
-}
-
-/**
- * @brief Enable Active level for Tamper input
- * @rmtoll CR TPAL LL_RTC_TAMPER_SetActiveLevel\n
- * @param BKPx BKP Instance
- * @param Tamper This parameter can be a combination of the following values:
- * @arg @ref LL_RTC_TAMPER_ACTIVELEVEL_LOW
- * @arg @ref LL_RTC_TAMPER_ACTIVELEVEL_HIGH
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_TAMPER_SetActiveLevel(BKP_TypeDef *BKPx, uint32_t Tamper)
-{
- MODIFY_REG(BKPx->CR, BKP_CR_TPAL, Tamper);
-}
-
-/**
- * @brief Disable Active level for Tamper input
- * @rmtoll CR TPAL LL_RTC_TAMPER_SetActiveLevel\n
- * @retval None
- */
-__STATIC_INLINE uint32_t LL_RTC_TAMPER_GetActiveLevel(BKP_TypeDef *BKPx)
-{
- return (uint32_t)(READ_BIT(BKPx->CR, BKP_CR_TPAL));
-}
-
-/**
- * @}
- */
-
-/** @defgroup RTC_LL_EF_Backup_Registers Backup_Registers
- * @{
- */
-
-/**
- * @brief Writes a data in a specified RTC Backup data register.
- * @rmtoll BKPDR DR LL_RTC_BKP_SetRegister
- * @param BKPx BKP Instance
- * @param BackupRegister This parameter can be one of the following values:
- * @arg @ref LL_RTC_BKP_DR1
- * @arg @ref LL_RTC_BKP_DR2
- * @arg @ref LL_RTC_BKP_DR3
- * @arg @ref LL_RTC_BKP_DR4
- * @arg @ref LL_RTC_BKP_DR5
- * @arg @ref LL_RTC_BKP_DR6
- * @arg @ref LL_RTC_BKP_DR7
- * @arg @ref LL_RTC_BKP_DR8
- * @arg @ref LL_RTC_BKP_DR9
- * @arg @ref LL_RTC_BKP_DR10
- * @arg @ref LL_RTC_BKP_DR11 (*)
- * @arg @ref LL_RTC_BKP_DR12 (*)
- * @arg @ref LL_RTC_BKP_DR13 (*)
- * @arg @ref LL_RTC_BKP_DR14 (*)
- * @arg @ref LL_RTC_BKP_DR15 (*)
- * @arg @ref LL_RTC_BKP_DR16 (*)
- * @arg @ref LL_RTC_BKP_DR17 (*)
- * @arg @ref LL_RTC_BKP_DR18 (*)
- * @arg @ref LL_RTC_BKP_DR19 (*)
- * @arg @ref LL_RTC_BKP_DR20 (*)
- * @arg @ref LL_RTC_BKP_DR21 (*)
- * @arg @ref LL_RTC_BKP_DR22 (*)
- * @arg @ref LL_RTC_BKP_DR23 (*)
- * @arg @ref LL_RTC_BKP_DR24 (*)
- * @arg @ref LL_RTC_BKP_DR25 (*)
- * @arg @ref LL_RTC_BKP_DR26 (*)
- * @arg @ref LL_RTC_BKP_DR27 (*)
- * @arg @ref LL_RTC_BKP_DR28 (*)
- * @arg @ref LL_RTC_BKP_DR29 (*)
- * @arg @ref LL_RTC_BKP_DR30 (*)
- * @arg @ref LL_RTC_BKP_DR31 (*)
- * @arg @ref LL_RTC_BKP_DR32 (*)
- * @arg @ref LL_RTC_BKP_DR33 (*)
- * @arg @ref LL_RTC_BKP_DR34 (*)
- * @arg @ref LL_RTC_BKP_DR35 (*)
- * @arg @ref LL_RTC_BKP_DR36 (*)
- * @arg @ref LL_RTC_BKP_DR37 (*)
- * @arg @ref LL_RTC_BKP_DR38 (*)
- * @arg @ref LL_RTC_BKP_DR39 (*)
- * @arg @ref LL_RTC_BKP_DR40 (*)
- * @arg @ref LL_RTC_BKP_DR41 (*)
- * @arg @ref LL_RTC_BKP_DR42 (*)
- * (*) value not defined in all devices.
- * @param Data Value between Min_Data=0x00 and Max_Data=0xFFFFFFFF
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_BKP_SetRegister(BKP_TypeDef *BKPx, uint32_t BackupRegister, uint32_t Data)
-{
- register uint32_t tmp = 0U;
-
- tmp = (uint32_t)BKP_BASE;
- tmp += (BackupRegister * 4U);
-
- /* Write the specified register */
- *(__IO uint32_t *)tmp = (uint32_t)Data;
-}
-
-/**
- * @brief Reads data from the specified RTC Backup data Register.
- * @rmtoll BKPDR DR LL_RTC_BKP_GetRegister
- * @param BKPx BKP Instance
- * @param BackupRegister This parameter can be one of the following values:
- * @arg @ref LL_RTC_BKP_DR1
- * @arg @ref LL_RTC_BKP_DR2
- * @arg @ref LL_RTC_BKP_DR3
- * @arg @ref LL_RTC_BKP_DR4
- * @arg @ref LL_RTC_BKP_DR5
- * @arg @ref LL_RTC_BKP_DR6
- * @arg @ref LL_RTC_BKP_DR7
- * @arg @ref LL_RTC_BKP_DR8
- * @arg @ref LL_RTC_BKP_DR9
- * @arg @ref LL_RTC_BKP_DR10
- * @arg @ref LL_RTC_BKP_DR11 (*)
- * @arg @ref LL_RTC_BKP_DR12 (*)
- * @arg @ref LL_RTC_BKP_DR13 (*)
- * @arg @ref LL_RTC_BKP_DR14 (*)
- * @arg @ref LL_RTC_BKP_DR15 (*)
- * @arg @ref LL_RTC_BKP_DR16 (*)
- * @arg @ref LL_RTC_BKP_DR17 (*)
- * @arg @ref LL_RTC_BKP_DR18 (*)
- * @arg @ref LL_RTC_BKP_DR19 (*)
- * @arg @ref LL_RTC_BKP_DR20 (*)
- * @arg @ref LL_RTC_BKP_DR21 (*)
- * @arg @ref LL_RTC_BKP_DR22 (*)
- * @arg @ref LL_RTC_BKP_DR23 (*)
- * @arg @ref LL_RTC_BKP_DR24 (*)
- * @arg @ref LL_RTC_BKP_DR25 (*)
- * @arg @ref LL_RTC_BKP_DR26 (*)
- * @arg @ref LL_RTC_BKP_DR27 (*)
- * @arg @ref LL_RTC_BKP_DR28 (*)
- * @arg @ref LL_RTC_BKP_DR29 (*)
- * @arg @ref LL_RTC_BKP_DR30 (*)
- * @arg @ref LL_RTC_BKP_DR31 (*)
- * @arg @ref LL_RTC_BKP_DR32 (*)
- * @arg @ref LL_RTC_BKP_DR33 (*)
- * @arg @ref LL_RTC_BKP_DR34 (*)
- * @arg @ref LL_RTC_BKP_DR35 (*)
- * @arg @ref LL_RTC_BKP_DR36 (*)
- * @arg @ref LL_RTC_BKP_DR37 (*)
- * @arg @ref LL_RTC_BKP_DR38 (*)
- * @arg @ref LL_RTC_BKP_DR39 (*)
- * @arg @ref LL_RTC_BKP_DR40 (*)
- * @arg @ref LL_RTC_BKP_DR41 (*)
- * @arg @ref LL_RTC_BKP_DR42 (*)
- * @retval Value between Min_Data=0x00 and Max_Data=0xFFFFFFFF
- */
-__STATIC_INLINE uint32_t LL_RTC_BKP_GetRegister(BKP_TypeDef *BKPx, uint32_t BackupRegister)
-{
- register uint32_t tmp = 0U;
-
- tmp = (uint32_t)BKP_BASE;
- tmp += (BackupRegister * 4U);
-
- /* Read the specified register */
- return ((*(__IO uint32_t *)tmp) & BKP_DR1_D);
-}
-
-/**
- * @}
- */
-
-/** @defgroup RTC_LL_EF_Calibration Calibration
- * @{
- */
-
-/**
- * @brief Set the coarse digital calibration
- * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
- * @note It can be written in initialization mode only (@ref LL_RTC_EnterInitMode function)
- * @rmtoll RTCCR CAL LL_RTC_CAL_SetCoarseDigital\n
- * @param BKPx RTC Instance
- * @param Value value of coarse calibration expressed in ppm (coded on 5 bits)
- * @note This Calibration value should be between 0 and 121 when using positive sign with a 4-ppm step.
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_CAL_SetCoarseDigital(BKP_TypeDef* BKPx, uint32_t Value)
-{
- MODIFY_REG(BKPx->RTCCR,BKP_RTCCR_CAL, Value);
-}
-
-/**
- * @brief Get the coarse digital calibration value
- * @rmtoll RTCCR CAL LL_RTC_CAL_SetCoarseDigital\n
- * @param BKPx BKP Instance
- * @retval value of coarse calibration expressed in ppm (coded on 5 bits)
- */
-__STATIC_INLINE uint32_t LL_RTC_CAL_GetCoarseDigital(BKP_TypeDef *BKPx)
-{
- return (uint32_t)(READ_BIT(BKPx->RTCCR, BKP_RTCCR_CAL));
-}
-/**
- * @}
- */
-
-/** @defgroup RTC_LL_EF_FLAG_Management FLAG_Management
- * @{
- */
-
-/**
- * @brief Get RTC_TAMPI Interruption detection flag
- * @rmtoll CSR TIF LL_RTC_IsActiveFlag_TAMPI
- * @param BKPx BKP Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMPI(BKP_TypeDef *BKPx)
-{
- return (READ_BIT(BKPx->CSR, BKP_CSR_TIF) == (BKP_CSR_TIF));
-}
-
-/**
- * @brief Clear RTC_TAMP Interruption detection flag
- * @rmtoll CSR CTI LL_RTC_ClearFlag_TAMPI
- * @param BKPx BKP Instance
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_ClearFlag_TAMPI(BKP_TypeDef *BKPx)
-{
- SET_BIT(BKPx->CSR, BKP_CSR_CTI);
-}
-
-/**
- * @brief Get RTC_TAMPE Event detection flag
- * @rmtoll CSR TEF LL_RTC_IsActiveFlag_TAMPE
- * @param BKPx BKP Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMPE(BKP_TypeDef *BKPx)
-{
- return (READ_BIT(BKPx->CSR, BKP_CSR_TEF) == (BKP_CSR_TEF));
-}
-
-/**
- * @brief Clear RTC_TAMPE Even detection flag
- * @rmtoll CSR CTE LL_RTC_ClearFlag_TAMPE
- * @param BKPx BKP Instance
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_ClearFlag_TAMPE(BKP_TypeDef *BKPx)
-{
- SET_BIT(BKPx->CSR, BKP_CSR_CTE);
-}
-
-/**
- * @brief Get Alarm flag
- * @rmtoll CRL ALRF LL_RTC_IsActiveFlag_ALR
- * @param RTCx RTC Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ALR(RTC_TypeDef *RTCx)
-{
- return (READ_BIT(RTCx->CRL, RTC_CRL_ALRF) == (RTC_CRL_ALRF));
-}
-
-/**
- * @brief Clear Alarm flag
- * @rmtoll CRL ALRF LL_RTC_ClearFlag_ALR
- * @param RTCx RTC Instance
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_ClearFlag_ALR(RTC_TypeDef *RTCx)
-{
- CLEAR_BIT(RTCx->CRL, RTC_CRL_ALRF);
-}
-
-/**
- * @brief Get Registers synchronization flag
- * @rmtoll CRL RSF LL_RTC_IsActiveFlag_RS
- * @param RTCx RTC Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_RS(RTC_TypeDef *RTCx)
-{
- return (READ_BIT(RTCx->CRL, RTC_CRL_RSF) == (RTC_CRL_RSF));
-}
-
-/**
- * @brief Clear Registers synchronization flag
- * @rmtoll CRL RSF LL_RTC_ClearFlag_RS
- * @param RTCx RTC Instance
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_ClearFlag_RS(RTC_TypeDef *RTCx)
-{
- CLEAR_BIT(RTCx->CRL, RTC_CRL_RSF);
-}
-
-/**
- * @brief Get Registers OverFlow flag
- * @rmtoll CRL OWF LL_RTC_IsActiveFlag_OW
- * @param RTCx RTC Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_OW(RTC_TypeDef *RTCx)
-{
- return (READ_BIT(RTCx->CRL, RTC_CRL_OWF) == (RTC_CRL_OWF));
-}
-
-/**
- * @brief Clear Registers OverFlow flag
- * @rmtoll CRL OWF LL_RTC_ClearFlag_OW
- * @param RTCx RTC Instance
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_ClearFlag_OW(RTC_TypeDef *RTCx)
-{
- CLEAR_BIT(RTCx->CRL, RTC_CRL_OWF);
-}
-
-/**
- * @brief Get Registers synchronization flag
- * @rmtoll CRL SECF LL_RTC_IsActiveFlag_SEC
- * @param RTCx RTC Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_SEC(RTC_TypeDef *RTCx)
-{
- return (READ_BIT(RTCx->CRL, RTC_CRL_SECF) == (RTC_CRL_SECF));
-}
-
-/**
- * @brief Clear Registers synchronization flag
- * @rmtoll CRL SECF LL_RTC_ClearFlag_SEC
- * @param RTCx RTC Instance
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_ClearFlag_SEC(RTC_TypeDef *RTCx)
-{
- CLEAR_BIT(RTCx->CRL, RTC_CRL_SECF);
-}
-
-/**
- * @brief Get RTC Operation OFF status flag
- * @rmtoll CRL RTOFF LL_RTC_IsActiveFlag_RTOF
- * @param RTCx RTC Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_RTOF(RTC_TypeDef *RTCx)
-{
- return (READ_BIT(RTCx->CRL, RTC_CRL_RTOFF) == (RTC_CRL_RTOFF));
-}
-
-/**
- * @}
- */
-
-/** @defgroup RTC_LL_EF_IT_Management IT_Management
- * @{
- */
-
-/**
- * @brief Enable Alarm interrupt
- * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
- * @rmtoll CRH ALRIE LL_RTC_EnableIT_ALR
- * @param RTCx RTC Instance
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_EnableIT_ALR(RTC_TypeDef *RTCx)
-{
- SET_BIT(RTCx->CRH, RTC_CRH_ALRIE);
-}
-
-/**
- * @brief Disable Alarm interrupt
- * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
- * @rmtoll CRH ALRIE LL_RTC_DisableIT_ALR
- * @param RTCx RTC Instance
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_DisableIT_ALR(RTC_TypeDef *RTCx)
-{
- CLEAR_BIT(RTCx->CRH, RTC_CRH_ALRIE);
-}
-
-/**
- * @brief Check if Alarm interrupt is enabled or not
- * @rmtoll CRH ALRIE LL_RTC_IsEnabledIT_ALR
- * @param RTCx RTC Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_ALR(RTC_TypeDef *RTCx)
-{
- return (READ_BIT(RTCx->CRH, RTC_CRH_ALRIE) == (RTC_CRH_ALRIE));
-}
-
-/**
- * @brief Enable Second Interrupt interrupt
- * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
- * @rmtoll CRH SECIE LL_RTC_EnableIT_SEC
- * @param RTCx RTC Instance
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_EnableIT_SEC(RTC_TypeDef *RTCx)
-{
- SET_BIT(RTCx->CRH, RTC_CRH_SECIE);
-}
-
-/**
- * @brief Disable Second interrupt
- * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
- * @rmtoll CRH SECIE LL_RTC_DisableIT_SEC
- * @param RTCx RTC Instance
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_DisableIT_SEC(RTC_TypeDef *RTCx)
-{
- CLEAR_BIT(RTCx->CRH, RTC_CRH_SECIE);
-}
-
-/**
- * @brief Check if Second interrupt is enabled or not
- * @rmtoll CRH SECIE LL_RTC_IsEnabledIT_SEC
- * @param RTCx RTC Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_SEC(RTC_TypeDef *RTCx)
-{
- return (READ_BIT(RTCx->CRH, RTC_CRH_SECIE) == (RTC_CRH_SECIE));
-}
-
-/**
- * @brief Enable OverFlow interrupt
- * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
- * @rmtoll CRH OWIE LL_RTC_EnableIT_OW
- * @param RTCx RTC Instance
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_EnableIT_OW(RTC_TypeDef *RTCx)
-{
- SET_BIT(RTCx->CRH, RTC_CRH_OWIE);
-}
-
-/**
- * @brief Disable OverFlow interrupt
- * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
- * @rmtoll CRH OWIE LL_RTC_DisableIT_OW
- * @param RTCx RTC Instance
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_DisableIT_OW(RTC_TypeDef *RTCx)
-{
- CLEAR_BIT(RTCx->CRH, RTC_CRH_OWIE);
-}
-
-/**
- * @brief Check if OverFlow interrupt is enabled or not
- * @rmtoll CRH OWIE LL_RTC_IsEnabledIT_OW
- * @param RTCx RTC Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_OW(RTC_TypeDef *RTCx)
-{
- return (READ_BIT(RTCx->CRH, RTC_CRH_OWIE) == (RTC_CRH_OWIE));
-}
-
-/**
- * @brief Enable Tamper interrupt
- * @rmtoll CSR TPIE LL_RTC_EnableIT_TAMP
- * @param BKPx BKP Instance
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_EnableIT_TAMP(BKP_TypeDef *BKPx)
-{
- SET_BIT(BKPx->CSR,BKP_CSR_TPIE);
-}
-
-/**
- * @brief Disable Tamper interrupt
- * @rmtoll CSR TPIE LL_RTC_EnableIT_TAMP
- * @param BKPx BKP Instance
- * @retval None
- */
-__STATIC_INLINE void LL_RTC_DisableIT_TAMP(BKP_TypeDef *BKPx)
-{
- CLEAR_BIT(BKPx->CSR,BKP_CSR_TPIE);
-}
-
-/**
- * @brief Check if all the TAMPER interrupts are enabled or not
- * @rmtoll CSR TPIE LL_RTC_IsEnabledIT_TAMP
- * @param BKPx BKP Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_TAMP(BKP_TypeDef *BKPx)
-{
- return (READ_BIT(BKPx->CSR,BKP_CSR_TPIE) == BKP_CSR_TPIE);
-}
-/**
- * @}
- */
-
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup RTC_LL_EF_Init Initialization and de-initialization functions
- * @{
- */
-
-ErrorStatus LL_RTC_DeInit(RTC_TypeDef *RTCx);
-ErrorStatus LL_RTC_Init(RTC_TypeDef *RTCx, LL_RTC_InitTypeDef *RTC_InitStruct);
-void LL_RTC_StructInit(LL_RTC_InitTypeDef *RTC_InitStruct);
-ErrorStatus LL_RTC_TIME_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_TimeTypeDef *RTC_TimeStruct);
-void LL_RTC_TIME_StructInit(LL_RTC_TimeTypeDef *RTC_TimeStruct);
-ErrorStatus LL_RTC_ALARM_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_AlarmTypeDef *RTC_AlarmStruct);
-void LL_RTC_ALARM_StructInit(LL_RTC_AlarmTypeDef *RTC_AlarmStruct);
-ErrorStatus LL_RTC_EnterInitMode(RTC_TypeDef *RTCx);
-ErrorStatus LL_RTC_ExitInitMode(RTC_TypeDef *RTCx);
-ErrorStatus LL_RTC_WaitForSynchro(RTC_TypeDef *RTCx);
-ErrorStatus LL_RTC_TIME_SetCounter(RTC_TypeDef *RTCx, uint32_t TimeCounter);
-ErrorStatus LL_RTC_ALARM_SetCounter(RTC_TypeDef *RTCx, uint32_t AlarmCounter);
-
-/**
- * @}
- */
-#endif /* USE_FULL_LL_DRIVER */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* defined(RTC) */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_LL_RTC_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_sdmmc.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_sdmmc.h
deleted file mode 100644
index 828346c..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_sdmmc.h
+++ /dev/null
@@ -1,1125 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_sdmmc.h
- * @author MCD Application Team
- * @brief Header file of low layer SDMMC HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __stm32f1xx_LL_SD_H
-#define __stm32f1xx_LL_SD_H
-
-#if defined(STM32F103xE) || defined(STM32F103xG)
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup SDMMC_LL
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup SDMMC_LL_Exported_Types SDMMC_LL Exported Types
- * @{
- */
-
-/**
- * @brief SDMMC Configuration Structure definition
- */
-typedef struct
-{
- uint32_t ClockEdge; /*!< Specifies the clock transition on which the bit capture is made.
- This parameter can be a value of @ref SDMMC_LL_Clock_Edge */
-
- uint32_t ClockBypass; /*!< Specifies whether the SDIO Clock divider bypass is
- enabled or disabled.
- This parameter can be a value of @ref SDMMC_LL_Clock_Bypass */
-
- uint32_t ClockPowerSave; /*!< Specifies whether SDIO Clock output is enabled or
- disabled when the bus is idle.
- This parameter can be a value of @ref SDMMC_LL_Clock_Power_Save */
-
- uint32_t BusWide; /*!< Specifies the SDIO bus width.
- This parameter can be a value of @ref SDMMC_LL_Bus_Wide */
-
- uint32_t HardwareFlowControl; /*!< Specifies whether the SDIO hardware flow control is enabled or disabled.
- This parameter can be a value of @ref SDMMC_LL_Hardware_Flow_Control */
-
- uint32_t ClockDiv; /*!< Specifies the clock frequency of the SDIO controller.
- This parameter can be a value between Min_Data = 0 and Max_Data = 255 */
-
-}SDIO_InitTypeDef;
-
-
-/**
- * @brief SDIO Command Control structure
- */
-typedef struct
-{
- uint32_t Argument; /*!< Specifies the SDIO command argument which is sent
- to a card as part of a command message. If a command
- contains an argument, it must be loaded into this register
- before writing the command to the command register. */
-
- uint32_t CmdIndex; /*!< Specifies the SDIO command index. It must be Min_Data = 0 and
- Max_Data = 64 */
-
- uint32_t Response; /*!< Specifies the SDIO response type.
- This parameter can be a value of @ref SDMMC_LL_Response_Type */
-
- uint32_t WaitForInterrupt; /*!< Specifies whether SDIO wait for interrupt request is
- enabled or disabled.
- This parameter can be a value of @ref SDMMC_LL_Wait_Interrupt_State */
-
- uint32_t CPSM; /*!< Specifies whether SDIO Command path state machine (CPSM)
- is enabled or disabled.
- This parameter can be a value of @ref SDMMC_LL_CPSM_State */
-}SDIO_CmdInitTypeDef;
-
-
-/**
- * @brief SDIO Data Control structure
- */
-typedef struct
-{
- uint32_t DataTimeOut; /*!< Specifies the data timeout period in card bus clock periods. */
-
- uint32_t DataLength; /*!< Specifies the number of data bytes to be transferred. */
-
- uint32_t DataBlockSize; /*!< Specifies the data block size for block transfer.
- This parameter can be a value of @ref SDMMC_LL_Data_Block_Size */
-
- uint32_t TransferDir; /*!< Specifies the data transfer direction, whether the transfer
- is a read or write.
- This parameter can be a value of @ref SDMMC_LL_Transfer_Direction */
-
- uint32_t TransferMode; /*!< Specifies whether data transfer is in stream or block mode.
- This parameter can be a value of @ref SDMMC_LL_Transfer_Type */
-
- uint32_t DPSM; /*!< Specifies whether SDIO Data path state machine (DPSM)
- is enabled or disabled.
- This parameter can be a value of @ref SDMMC_LL_DPSM_State */
-}SDIO_DataInitTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup SDMMC_LL_Exported_Constants SDMMC_LL Exported Constants
- * @{
- */
-#define SDMMC_ERROR_NONE 0x00000000U /*!< No error */
-#define SDMMC_ERROR_CMD_CRC_FAIL 0x00000001U /*!< Command response received (but CRC check failed) */
-#define SDMMC_ERROR_DATA_CRC_FAIL 0x00000002U /*!< Data block sent/received (CRC check failed) */
-#define SDMMC_ERROR_CMD_RSP_TIMEOUT 0x00000004U /*!< Command response timeout */
-#define SDMMC_ERROR_DATA_TIMEOUT 0x00000008U /*!< Data timeout */
-#define SDMMC_ERROR_TX_UNDERRUN 0x00000010U /*!< Transmit FIFO underrun */
-#define SDMMC_ERROR_RX_OVERRUN 0x00000020U /*!< Receive FIFO overrun */
-#define SDMMC_ERROR_ADDR_MISALIGNED 0x00000040U /*!< Misaligned address */
-#define SDMMC_ERROR_BLOCK_LEN_ERR 0x00000080U /*!< Transferred block length is not allowed for the card or the
- number of transferred bytes does not match the block length */
-#define SDMMC_ERROR_ERASE_SEQ_ERR 0x00000100U /*!< An error in the sequence of erase command occurs */
-#define SDMMC_ERROR_BAD_ERASE_PARAM 0x00000200U /*!< An invalid selection for erase groups */
-#define SDMMC_ERROR_WRITE_PROT_VIOLATION 0x00000400U /*!< Attempt to program a write protect block */
-#define SDMMC_ERROR_LOCK_UNLOCK_FAILED 0x00000800U /*!< Sequence or password error has been detected in unlock
- command or if there was an attempt to access a locked card */
-#define SDMMC_ERROR_COM_CRC_FAILED 0x00001000U /*!< CRC check of the previous command failed */
-#define SDMMC_ERROR_ILLEGAL_CMD 0x00002000U /*!< Command is not legal for the card state */
-#define SDMMC_ERROR_CARD_ECC_FAILED 0x00004000U /*!< Card internal ECC was applied but failed to correct the data */
-#define SDMMC_ERROR_CC_ERR 0x00008000U /*!< Internal card controller error */
-#define SDMMC_ERROR_GENERAL_UNKNOWN_ERR 0x00010000U /*!< General or unknown error */
-#define SDMMC_ERROR_STREAM_READ_UNDERRUN 0x00020000U /*!< The card could not sustain data reading in stream rmode */
-#define SDMMC_ERROR_STREAM_WRITE_OVERRUN 0x00040000U /*!< The card could not sustain data programming in stream mode */
-#define SDMMC_ERROR_CID_CSD_OVERWRITE 0x00080000U /*!< CID/CSD overwrite error */
-#define SDMMC_ERROR_WP_ERASE_SKIP 0x00100000U /*!< Only partial address space was erased */
-#define SDMMC_ERROR_CARD_ECC_DISABLED 0x00200000U /*!< Command has been executed without using internal ECC */
-#define SDMMC_ERROR_ERASE_RESET 0x00400000U /*!< Erase sequence was cleared before executing because an out
- of erase sequence command was received */
-#define SDMMC_ERROR_AKE_SEQ_ERR 0x00800000U /*!< Error in sequence of authentication */
-#define SDMMC_ERROR_INVALID_VOLTRANGE 0x01000000U /*!< Error in case of invalid voltage range */
-#define SDMMC_ERROR_ADDR_OUT_OF_RANGE 0x02000000U /*!< Error when addressed block is out of range */
-#define SDMMC_ERROR_REQUEST_NOT_APPLICABLE 0x04000000U /*!< Error when command request is not applicable */
-#define SDMMC_ERROR_INVALID_PARAMETER 0x08000000U /*!< the used parameter is not valid */
-#define SDMMC_ERROR_UNSUPPORTED_FEATURE 0x10000000U /*!< Error when feature is not insupported */
-#define SDMMC_ERROR_BUSY 0x20000000U /*!< Error when transfer process is busy */
-#define SDMMC_ERROR_DMA 0x40000000U /*!< Error while DMA transfer */
-#define SDMMC_ERROR_TIMEOUT 0x80000000U /*!< Timeout error */
-
-/**
- * @brief SDMMC Commands Index
- */
-#define SDMMC_CMD_GO_IDLE_STATE ((uint8_t)0) /*!< Resets the SD memory card. */
-#define SDMMC_CMD_SEND_OP_COND ((uint8_t)1) /*!< Sends host capacity support information and activates the card's initialization process. */
-#define SDMMC_CMD_ALL_SEND_CID ((uint8_t)2) /*!< Asks any card connected to the host to send the CID numbers on the CMD line. */
-#define SDMMC_CMD_SET_REL_ADDR ((uint8_t)3) /*!< Asks the card to publish a new relative address (RCA). */
-#define SDMMC_CMD_SET_DSR ((uint8_t)4) /*!< Programs the DSR of all cards. */
-#define SDMMC_CMD_SDMMC_SEN_OP_COND ((uint8_t)5) /*!< Sends host capacity support information (HCS) and asks the accessed card to send its
- operating condition register (OCR) content in the response on the CMD line. */
-#define SDMMC_CMD_HS_SWITCH ((uint8_t)6) /*!< Checks switchable function (mode 0) and switch card function (mode 1). */
-#define SDMMC_CMD_SEL_DESEL_CARD ((uint8_t)7) /*!< Selects the card by its own relative address and gets deselected by any other address */
-#define SDMMC_CMD_HS_SEND_EXT_CSD ((uint8_t)8) /*!< Sends SD Memory Card interface condition, which includes host supply voltage information
- and asks the card whether card supports voltage. */
-#define SDMMC_CMD_SEND_CSD ((uint8_t)9) /*!< Addressed card sends its card specific data (CSD) on the CMD line. */
-#define SDMMC_CMD_SEND_CID ((uint8_t)10) /*!< Addressed card sends its card identification (CID) on the CMD line. */
-#define SDMMC_CMD_READ_DAT_UNTIL_STOP ((uint8_t)11) /*!< SD card doesn't support it. */
-#define SDMMC_CMD_STOP_TRANSMISSION ((uint8_t)12) /*!< Forces the card to stop transmission. */
-#define SDMMC_CMD_SEND_STATUS ((uint8_t)13) /*!< Addressed card sends its status register. */
-#define SDMMC_CMD_HS_BUSTEST_READ ((uint8_t)14) /*!< Reserved */
-#define SDMMC_CMD_GO_INACTIVE_STATE ((uint8_t)15) /*!< Sends an addressed card into the inactive state. */
-#define SDMMC_CMD_SET_BLOCKLEN ((uint8_t)16) /*!< Sets the block length (in bytes for SDSC) for all following block commands
- (read, write, lock). Default block length is fixed to 512 Bytes. Not effective
- for SDHS and SDXC. */
-#define SDMMC_CMD_READ_SINGLE_BLOCK ((uint8_t)17) /*!< Reads single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of
- fixed 512 bytes in case of SDHC and SDXC. */
-#define SDMMC_CMD_READ_MULT_BLOCK ((uint8_t)18) /*!< Continuously transfers data blocks from card to host until interrupted by
- STOP_TRANSMISSION command. */
-#define SDMMC_CMD_HS_BUSTEST_WRITE ((uint8_t)19) /*!< 64 bytes tuning pattern is sent for SDR50 and SDR104. */
-#define SDMMC_CMD_WRITE_DAT_UNTIL_STOP ((uint8_t)20) /*!< Speed class control command. */
-#define SDMMC_CMD_SET_BLOCK_COUNT ((uint8_t)23) /*!< Specify block count for CMD18 and CMD25. */
-#define SDMMC_CMD_WRITE_SINGLE_BLOCK ((uint8_t)24) /*!< Writes single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of
- fixed 512 bytes in case of SDHC and SDXC. */
-#define SDMMC_CMD_WRITE_MULT_BLOCK ((uint8_t)25) /*!< Continuously writes blocks of data until a STOP_TRANSMISSION follows. */
-#define SDMMC_CMD_PROG_CID ((uint8_t)26) /*!< Reserved for manufacturers. */
-#define SDMMC_CMD_PROG_CSD ((uint8_t)27) /*!< Programming of the programmable bits of the CSD. */
-#define SDMMC_CMD_SET_WRITE_PROT ((uint8_t)28) /*!< Sets the write protection bit of the addressed group. */
-#define SDMMC_CMD_CLR_WRITE_PROT ((uint8_t)29) /*!< Clears the write protection bit of the addressed group. */
-#define SDMMC_CMD_SEND_WRITE_PROT ((uint8_t)30) /*!< Asks the card to send the status of the write protection bits. */
-#define SDMMC_CMD_SD_ERASE_GRP_START ((uint8_t)32) /*!< Sets the address of the first write block to be erased. (For SD card only). */
-#define SDMMC_CMD_SD_ERASE_GRP_END ((uint8_t)33) /*!< Sets the address of the last write block of the continuous range to be erased. */
-#define SDMMC_CMD_ERASE_GRP_START ((uint8_t)35) /*!< Sets the address of the first write block to be erased. Reserved for each command
- system set by switch function command (CMD6). */
-#define SDMMC_CMD_ERASE_GRP_END ((uint8_t)36) /*!< Sets the address of the last write block of the continuous range to be erased.
- Reserved for each command system set by switch function command (CMD6). */
-#define SDMMC_CMD_ERASE ((uint8_t)38) /*!< Reserved for SD security applications. */
-#define SDMMC_CMD_FAST_IO ((uint8_t)39) /*!< SD card doesn't support it (Reserved). */
-#define SDMMC_CMD_GO_IRQ_STATE ((uint8_t)40) /*!< SD card doesn't support it (Reserved). */
-#define SDMMC_CMD_LOCK_UNLOCK ((uint8_t)42) /*!< Sets/resets the password or lock/unlock the card. The size of the data block is set by
- the SET_BLOCK_LEN command. */
-#define SDMMC_CMD_APP_CMD ((uint8_t)55) /*!< Indicates to the card that the next command is an application specific command rather
- than a standard command. */
-#define SDMMC_CMD_GEN_CMD ((uint8_t)56) /*!< Used either to transfer a data block to the card or to get a data block from the card
- for general purpose/application specific commands. */
-#define SDMMC_CMD_NO_CMD ((uint8_t)64) /*!< No command */
-
-/**
- * @brief Following commands are SD Card Specific commands.
- * SDMMC_APP_CMD should be sent before sending these commands.
- */
-#define SDMMC_CMD_APP_SD_SET_BUSWIDTH ((uint8_t)6) /*!< (ACMD6) Defines the data bus width to be used for data transfer. The allowed data bus
- widths are given in SCR register. */
-#define SDMMC_CMD_SD_APP_STATUS ((uint8_t)13) /*!< (ACMD13) Sends the SD status. */
-#define SDMMC_CMD_SD_APP_SEND_NUM_WRITE_BLOCKS ((uint8_t)22) /*!< (ACMD22) Sends the number of the written (without errors) write blocks. Responds with
- 32bit+CRC data block. */
-#define SDMMC_CMD_SD_APP_OP_COND ((uint8_t)41) /*!< (ACMD41) Sends host capacity support information (HCS) and asks the accessed card to
- send its operating condition register (OCR) content in the response on the CMD line. */
-#define SDMMC_CMD_SD_APP_SET_CLR_CARD_DETECT ((uint8_t)42) /*!< (ACMD42) Connect/Disconnect the 50 KOhm pull-up resistor on CD/DAT3 (pin 1) of the card */
-#define SDMMC_CMD_SD_APP_SEND_SCR ((uint8_t)51) /*!< Reads the SD Configuration Register (SCR). */
-#define SDMMC_CMD_SDMMC_RW_DIRECT ((uint8_t)52) /*!< For SD I/O card only, reserved for security specification. */
-#define SDMMC_CMD_SDMMC_RW_EXTENDED ((uint8_t)53) /*!< For SD I/O card only, reserved for security specification. */
-
-/**
- * @brief Following commands are SD Card Specific security commands.
- * SDMMC_CMD_APP_CMD should be sent before sending these commands.
- */
-#define SDMMC_CMD_SD_APP_GET_MKB ((uint8_t)43)
-#define SDMMC_CMD_SD_APP_GET_MID ((uint8_t)44)
-#define SDMMC_CMD_SD_APP_SET_CER_RN1 ((uint8_t)45)
-#define SDMMC_CMD_SD_APP_GET_CER_RN2 ((uint8_t)46)
-#define SDMMC_CMD_SD_APP_SET_CER_RES2 ((uint8_t)47)
-#define SDMMC_CMD_SD_APP_GET_CER_RES1 ((uint8_t)48)
-#define SDMMC_CMD_SD_APP_SECURE_READ_MULTIPLE_BLOCK ((uint8_t)18)
-#define SDMMC_CMD_SD_APP_SECURE_WRITE_MULTIPLE_BLOCK ((uint8_t)25)
-#define SDMMC_CMD_SD_APP_SECURE_ERASE ((uint8_t)38)
-#define SDMMC_CMD_SD_APP_CHANGE_SECURE_AREA ((uint8_t)49)
-#define SDMMC_CMD_SD_APP_SECURE_WRITE_MKB ((uint8_t)48)
-
-/**
- * @brief Masks for errors Card Status R1 (OCR Register)
- */
-#define SDMMC_OCR_ADDR_OUT_OF_RANGE 0x80000000U
-#define SDMMC_OCR_ADDR_MISALIGNED 0x40000000U
-#define SDMMC_OCR_BLOCK_LEN_ERR 0x20000000U
-#define SDMMC_OCR_ERASE_SEQ_ERR 0x10000000U
-#define SDMMC_OCR_BAD_ERASE_PARAM 0x08000000U
-#define SDMMC_OCR_WRITE_PROT_VIOLATION 0x04000000U
-#define SDMMC_OCR_LOCK_UNLOCK_FAILED 0x01000000U
-#define SDMMC_OCR_COM_CRC_FAILED 0x00800000U
-#define SDMMC_OCR_ILLEGAL_CMD 0x00400000U
-#define SDMMC_OCR_CARD_ECC_FAILED 0x00200000U
-#define SDMMC_OCR_CC_ERROR 0x00100000U
-#define SDMMC_OCR_GENERAL_UNKNOWN_ERROR 0x00080000U
-#define SDMMC_OCR_STREAM_READ_UNDERRUN 0x00040000U
-#define SDMMC_OCR_STREAM_WRITE_OVERRUN 0x00020000U
-#define SDMMC_OCR_CID_CSD_OVERWRITE 0x00010000U
-#define SDMMC_OCR_WP_ERASE_SKIP 0x00008000U
-#define SDMMC_OCR_CARD_ECC_DISABLED 0x00004000U
-#define SDMMC_OCR_ERASE_RESET 0x00002000U
-#define SDMMC_OCR_AKE_SEQ_ERROR 0x00000008U
-#define SDMMC_OCR_ERRORBITS 0xFDFFE008U
-
-/**
- * @brief Masks for R6 Response
- */
-#define SDMMC_R6_GENERAL_UNKNOWN_ERROR 0x00002000U
-#define SDMMC_R6_ILLEGAL_CMD 0x00004000U
-#define SDMMC_R6_COM_CRC_FAILED 0x00008000U
-
-#define SDMMC_VOLTAGE_WINDOW_SD 0x80100000U
-#define SDMMC_HIGH_CAPACITY 0x40000000U
-#define SDMMC_STD_CAPACITY 0x00000000U
-#define SDMMC_CHECK_PATTERN 0x000001AAU
-
-#define SDMMC_MAX_VOLT_TRIAL 0x0000FFFFU
-
-#define SDMMC_MAX_TRIAL 0x0000FFFFU
-
-#define SDMMC_ALLZERO 0x00000000U
-
-#define SDMMC_WIDE_BUS_SUPPORT 0x00040000U
-#define SDMMC_SINGLE_BUS_SUPPORT 0x00010000U
-#define SDMMC_CARD_LOCKED 0x02000000U
-
-#define SDMMC_DATATIMEOUT 0xFFFFFFFFU
-
-#define SDMMC_0TO7BITS 0x000000FFU
-#define SDMMC_8TO15BITS 0x0000FF00U
-#define SDMMC_16TO23BITS 0x00FF0000U
-#define SDMMC_24TO31BITS 0xFF000000U
-#define SDMMC_MAX_DATA_LENGTH 0x01FFFFFFU
-
-#define SDMMC_HALFFIFO 0x00000008U
-#define SDMMC_HALFFIFOBYTES 0x00000020U
-
-/**
- * @brief Command Class supported
- */
-#define SDIO_CCCC_ERASE 0x00000020U
-
-#define SDIO_CMDTIMEOUT 5000U /* Command send and response timeout */
-#define SDIO_MAXERASETIMEOUT 63000U /* Max erase Timeout 63 s */
-
-
-/** @defgroup SDIO_LL_Clock_Edge Clock Edge
- * @{
- */
-#define SDIO_CLOCK_EDGE_RISING 0x00000000U
-#define SDIO_CLOCK_EDGE_FALLING SDIO_CLKCR_NEGEDGE
-
-#define IS_SDIO_CLOCK_EDGE(EDGE) (((EDGE) == SDIO_CLOCK_EDGE_RISING) || \
- ((EDGE) == SDIO_CLOCK_EDGE_FALLING))
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_Clock_Bypass Clock Bypass
- * @{
- */
-#define SDIO_CLOCK_BYPASS_DISABLE 0x00000000U
-#define SDIO_CLOCK_BYPASS_ENABLE SDIO_CLKCR_BYPASS
-
-#define IS_SDIO_CLOCK_BYPASS(BYPASS) (((BYPASS) == SDIO_CLOCK_BYPASS_DISABLE) || \
- ((BYPASS) == SDIO_CLOCK_BYPASS_ENABLE))
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_Clock_Power_Save Clock Power Saving
- * @{
- */
-#define SDIO_CLOCK_POWER_SAVE_DISABLE 0x00000000U
-#define SDIO_CLOCK_POWER_SAVE_ENABLE SDIO_CLKCR_PWRSAV
-
-#define IS_SDIO_CLOCK_POWER_SAVE(SAVE) (((SAVE) == SDIO_CLOCK_POWER_SAVE_DISABLE) || \
- ((SAVE) == SDIO_CLOCK_POWER_SAVE_ENABLE))
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_Bus_Wide Bus Width
- * @{
- */
-#define SDIO_BUS_WIDE_1B 0x00000000U
-#define SDIO_BUS_WIDE_4B SDIO_CLKCR_WIDBUS_0
-#define SDIO_BUS_WIDE_8B SDIO_CLKCR_WIDBUS_1
-
-#define IS_SDIO_BUS_WIDE(WIDE) (((WIDE) == SDIO_BUS_WIDE_1B) || \
- ((WIDE) == SDIO_BUS_WIDE_4B) || \
- ((WIDE) == SDIO_BUS_WIDE_8B))
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_Hardware_Flow_Control Hardware Flow Control
- * @{
- */
-#define SDIO_HARDWARE_FLOW_CONTROL_DISABLE 0x00000000U
-#define SDIO_HARDWARE_FLOW_CONTROL_ENABLE SDIO_CLKCR_HWFC_EN
-
-#define IS_SDIO_HARDWARE_FLOW_CONTROL(CONTROL) (((CONTROL) == SDIO_HARDWARE_FLOW_CONTROL_DISABLE) || \
- ((CONTROL) == SDIO_HARDWARE_FLOW_CONTROL_ENABLE))
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_Clock_Division Clock Division
- * @{
- */
-#define IS_SDIO_CLKDIV(DIV) ((DIV) <= 0xFFU)
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_Command_Index Command Index
- * @{
- */
-#define IS_SDIO_CMD_INDEX(INDEX) ((INDEX) < 0x40U)
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_Response_Type Response Type
- * @{
- */
-#define SDIO_RESPONSE_NO 0x00000000U
-#define SDIO_RESPONSE_SHORT SDIO_CMD_WAITRESP_0
-#define SDIO_RESPONSE_LONG SDIO_CMD_WAITRESP
-
-#define IS_SDIO_RESPONSE(RESPONSE) (((RESPONSE) == SDIO_RESPONSE_NO) || \
- ((RESPONSE) == SDIO_RESPONSE_SHORT) || \
- ((RESPONSE) == SDIO_RESPONSE_LONG))
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_Wait_Interrupt_State Wait Interrupt
- * @{
- */
-#define SDIO_WAIT_NO 0x00000000U
-#define SDIO_WAIT_IT SDIO_CMD_WAITINT
-#define SDIO_WAIT_PEND SDIO_CMD_WAITPEND
-
-#define IS_SDIO_WAIT(WAIT) (((WAIT) == SDIO_WAIT_NO) || \
- ((WAIT) == SDIO_WAIT_IT) || \
- ((WAIT) == SDIO_WAIT_PEND))
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_CPSM_State CPSM State
- * @{
- */
-#define SDIO_CPSM_DISABLE 0x00000000U
-#define SDIO_CPSM_ENABLE SDIO_CMD_CPSMEN
-
-#define IS_SDIO_CPSM(CPSM) (((CPSM) == SDIO_CPSM_DISABLE) || \
- ((CPSM) == SDIO_CPSM_ENABLE))
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_Response_Registers Response Register
- * @{
- */
-#define SDIO_RESP1 0x00000000U
-#define SDIO_RESP2 0x00000004U
-#define SDIO_RESP3 0x00000008U
-#define SDIO_RESP4 0x0000000CU
-
-#define IS_SDIO_RESP(RESP) (((RESP) == SDIO_RESP1) || \
- ((RESP) == SDIO_RESP2) || \
- ((RESP) == SDIO_RESP3) || \
- ((RESP) == SDIO_RESP4))
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_Data_Length Data Lenght
- * @{
- */
-#define IS_SDIO_DATA_LENGTH(LENGTH) ((LENGTH) <= 0x01FFFFFFU)
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_Data_Block_Size Data Block Size
- * @{
- */
-#define SDIO_DATABLOCK_SIZE_1B 0x00000000U
-#define SDIO_DATABLOCK_SIZE_2B SDIO_DCTRL_DBLOCKSIZE_0
-#define SDIO_DATABLOCK_SIZE_4B SDIO_DCTRL_DBLOCKSIZE_1
-#define SDIO_DATABLOCK_SIZE_8B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_1)
-#define SDIO_DATABLOCK_SIZE_16B SDIO_DCTRL_DBLOCKSIZE_2
-#define SDIO_DATABLOCK_SIZE_32B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_2)
-#define SDIO_DATABLOCK_SIZE_64B (SDIO_DCTRL_DBLOCKSIZE_1|SDIO_DCTRL_DBLOCKSIZE_2)
-#define SDIO_DATABLOCK_SIZE_128B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_1|SDIO_DCTRL_DBLOCKSIZE_2)
-#define SDIO_DATABLOCK_SIZE_256B SDIO_DCTRL_DBLOCKSIZE_3
-#define SDIO_DATABLOCK_SIZE_512B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_3)
-#define SDIO_DATABLOCK_SIZE_1024B (SDIO_DCTRL_DBLOCKSIZE_1|SDIO_DCTRL_DBLOCKSIZE_3)
-#define SDIO_DATABLOCK_SIZE_2048B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_1|SDIO_DCTRL_DBLOCKSIZE_3)
-#define SDIO_DATABLOCK_SIZE_4096B (SDIO_DCTRL_DBLOCKSIZE_2|SDIO_DCTRL_DBLOCKSIZE_3)
-#define SDIO_DATABLOCK_SIZE_8192B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_2|SDIO_DCTRL_DBLOCKSIZE_3)
-#define SDIO_DATABLOCK_SIZE_16384B (SDIO_DCTRL_DBLOCKSIZE_1|SDIO_DCTRL_DBLOCKSIZE_2|SDIO_DCTRL_DBLOCKSIZE_3)
-
-#define IS_SDIO_BLOCK_SIZE(SIZE) (((SIZE) == SDIO_DATABLOCK_SIZE_1B) || \
- ((SIZE) == SDIO_DATABLOCK_SIZE_2B) || \
- ((SIZE) == SDIO_DATABLOCK_SIZE_4B) || \
- ((SIZE) == SDIO_DATABLOCK_SIZE_8B) || \
- ((SIZE) == SDIO_DATABLOCK_SIZE_16B) || \
- ((SIZE) == SDIO_DATABLOCK_SIZE_32B) || \
- ((SIZE) == SDIO_DATABLOCK_SIZE_64B) || \
- ((SIZE) == SDIO_DATABLOCK_SIZE_128B) || \
- ((SIZE) == SDIO_DATABLOCK_SIZE_256B) || \
- ((SIZE) == SDIO_DATABLOCK_SIZE_512B) || \
- ((SIZE) == SDIO_DATABLOCK_SIZE_1024B) || \
- ((SIZE) == SDIO_DATABLOCK_SIZE_2048B) || \
- ((SIZE) == SDIO_DATABLOCK_SIZE_4096B) || \
- ((SIZE) == SDIO_DATABLOCK_SIZE_8192B) || \
- ((SIZE) == SDIO_DATABLOCK_SIZE_16384B))
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_Transfer_Direction Transfer Direction
- * @{
- */
-#define SDIO_TRANSFER_DIR_TO_CARD 0x00000000U
-#define SDIO_TRANSFER_DIR_TO_SDIO SDIO_DCTRL_DTDIR
-
-#define IS_SDIO_TRANSFER_DIR(DIR) (((DIR) == SDIO_TRANSFER_DIR_TO_CARD) || \
- ((DIR) == SDIO_TRANSFER_DIR_TO_SDIO))
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_Transfer_Type Transfer Type
- * @{
- */
-#define SDIO_TRANSFER_MODE_BLOCK 0x00000000U
-#define SDIO_TRANSFER_MODE_STREAM SDIO_DCTRL_DTMODE
-
-#define IS_SDIO_TRANSFER_MODE(MODE) (((MODE) == SDIO_TRANSFER_MODE_BLOCK) || \
- ((MODE) == SDIO_TRANSFER_MODE_STREAM))
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_DPSM_State DPSM State
- * @{
- */
-#define SDIO_DPSM_DISABLE 0x00000000U
-#define SDIO_DPSM_ENABLE SDIO_DCTRL_DTEN
-
-#define IS_SDIO_DPSM(DPSM) (((DPSM) == SDIO_DPSM_DISABLE) ||\
- ((DPSM) == SDIO_DPSM_ENABLE))
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_Read_Wait_Mode Read Wait Mode
- * @{
- */
-#define SDIO_READ_WAIT_MODE_DATA2 0x00000000U
-#define SDIO_READ_WAIT_MODE_CLK (SDIO_DCTRL_RWMOD)
-
-#define IS_SDIO_READWAIT_MODE(MODE) (((MODE) == SDIO_READ_WAIT_MODE_CLK) || \
- ((MODE) == SDIO_READ_WAIT_MODE_DATA2))
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_Interrupt_sources Interrupt Sources
- * @{
- */
-#define SDIO_IT_CCRCFAIL SDIO_STA_CCRCFAIL
-#define SDIO_IT_DCRCFAIL SDIO_STA_DCRCFAIL
-#define SDIO_IT_CTIMEOUT SDIO_STA_CTIMEOUT
-#define SDIO_IT_DTIMEOUT SDIO_STA_DTIMEOUT
-#define SDIO_IT_TXUNDERR SDIO_STA_TXUNDERR
-#define SDIO_IT_RXOVERR SDIO_STA_RXOVERR
-#define SDIO_IT_CMDREND SDIO_STA_CMDREND
-#define SDIO_IT_CMDSENT SDIO_STA_CMDSENT
-#define SDIO_IT_DATAEND SDIO_STA_DATAEND
-#define SDIO_IT_STBITERR SDIO_STA_STBITERR
-#define SDIO_IT_DBCKEND SDIO_STA_DBCKEND
-#define SDIO_IT_CMDACT SDIO_STA_CMDACT
-#define SDIO_IT_TXACT SDIO_STA_TXACT
-#define SDIO_IT_RXACT SDIO_STA_RXACT
-#define SDIO_IT_TXFIFOHE SDIO_STA_TXFIFOHE
-#define SDIO_IT_RXFIFOHF SDIO_STA_RXFIFOHF
-#define SDIO_IT_TXFIFOF SDIO_STA_TXFIFOF
-#define SDIO_IT_RXFIFOF SDIO_STA_RXFIFOF
-#define SDIO_IT_TXFIFOE SDIO_STA_TXFIFOE
-#define SDIO_IT_RXFIFOE SDIO_STA_RXFIFOE
-#define SDIO_IT_TXDAVL SDIO_STA_TXDAVL
-#define SDIO_IT_RXDAVL SDIO_STA_RXDAVL
-#define SDIO_IT_SDIOIT SDIO_STA_SDIOIT
-#define SDIO_IT_CEATAEND SDIO_STA_CEATAEND
-/**
- * @}
- */
-
-/** @defgroup SDMMC_LL_Flags Flags
- * @{
- */
-#define SDIO_FLAG_CCRCFAIL SDIO_STA_CCRCFAIL
-#define SDIO_FLAG_DCRCFAIL SDIO_STA_DCRCFAIL
-#define SDIO_FLAG_CTIMEOUT SDIO_STA_CTIMEOUT
-#define SDIO_FLAG_DTIMEOUT SDIO_STA_DTIMEOUT
-#define SDIO_FLAG_TXUNDERR SDIO_STA_TXUNDERR
-#define SDIO_FLAG_RXOVERR SDIO_STA_RXOVERR
-#define SDIO_FLAG_CMDREND SDIO_STA_CMDREND
-#define SDIO_FLAG_CMDSENT SDIO_STA_CMDSENT
-#define SDIO_FLAG_DATAEND SDIO_STA_DATAEND
-#define SDIO_FLAG_STBITERR SDIO_STA_STBITERR
-#define SDIO_FLAG_DBCKEND SDIO_STA_DBCKEND
-#define SDIO_FLAG_CMDACT SDIO_STA_CMDACT
-#define SDIO_FLAG_TXACT SDIO_STA_TXACT
-#define SDIO_FLAG_RXACT SDIO_STA_RXACT
-#define SDIO_FLAG_TXFIFOHE SDIO_STA_TXFIFOHE
-#define SDIO_FLAG_RXFIFOHF SDIO_STA_RXFIFOHF
-#define SDIO_FLAG_TXFIFOF SDIO_STA_TXFIFOF
-#define SDIO_FLAG_RXFIFOF SDIO_STA_RXFIFOF
-#define SDIO_FLAG_TXFIFOE SDIO_STA_TXFIFOE
-#define SDIO_FLAG_RXFIFOE SDIO_STA_RXFIFOE
-#define SDIO_FLAG_TXDAVL SDIO_STA_TXDAVL
-#define SDIO_FLAG_RXDAVL SDIO_STA_RXDAVL
-#define SDIO_FLAG_SDIOIT SDIO_STA_SDIOIT
-#define SDIO_FLAG_CEATAEND SDIO_STA_CEATAEND
-#define SDIO_STATIC_FLAGS ((uint32_t)(SDIO_FLAG_CCRCFAIL | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_CTIMEOUT |\
- SDIO_FLAG_DTIMEOUT | SDIO_FLAG_TXUNDERR | SDIO_FLAG_RXOVERR |\
- SDIO_FLAG_CMDREND | SDIO_FLAG_CMDSENT | SDIO_FLAG_DATAEND |\
- SDIO_FLAG_DBCKEND))
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup SDIO_LL_Exported_macros SDIO_LL Exported Macros
- * @{
- */
-
-/** @defgroup SDMMC_LL_Alias_Region Bit Address in the alias region
- * @{
- */
-/* ------------ SDIO registers bit address in the alias region -------------- */
-#define SDIO_OFFSET (SDIO_BASE - PERIPH_BASE)
-
-/* --- CLKCR Register ---*/
-/* Alias word address of CLKEN bit */
-#define CLKCR_OFFSET (SDIO_OFFSET + 0x04U)
-#define CLKEN_BITNUMBER 0x08U
-#define CLKCR_CLKEN_BB (PERIPH_BB_BASE + (CLKCR_OFFSET * 32U) + (CLKEN_BITNUMBER * 4U))
-
-/* --- CMD Register ---*/
-/* Alias word address of SDIOSUSPEND bit */
-#define CMD_OFFSET (SDIO_OFFSET + 0x0CU)
-#define SDIOSUSPEND_BITNUMBER 0x0BU
-#define CMD_SDIOSUSPEND_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32U) + (SDIOSUSPEND_BITNUMBER * 4U))
-
-/* Alias word address of ENCMDCOMPL bit */
-#define ENCMDCOMPL_BITNUMBER 0x0CU
-#define CMD_ENCMDCOMPL_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32U) + (ENCMDCOMPL_BITNUMBER * 4U))
-
-/* Alias word address of NIEN bit */
-#define NIEN_BITNUMBER 0x0DU
-#define CMD_NIEN_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32U) + (NIEN_BITNUMBER * 4U))
-
-/* Alias word address of ATACMD bit */
-#define ATACMD_BITNUMBER 0x0EU
-#define CMD_ATACMD_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32U) + (ATACMD_BITNUMBER * 4U))
-
-/* --- DCTRL Register ---*/
-/* Alias word address of DMAEN bit */
-#define DCTRL_OFFSET (SDIO_OFFSET + 0x2CU)
-#define DMAEN_BITNUMBER 0x03U
-#define DCTRL_DMAEN_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32U) + (DMAEN_BITNUMBER * 4U))
-
-/* Alias word address of RWSTART bit */
-#define RWSTART_BITNUMBER 0x08U
-#define DCTRL_RWSTART_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32U) + (RWSTART_BITNUMBER * 4U))
-
-/* Alias word address of RWSTOP bit */
-#define RWSTOP_BITNUMBER 0x09U
-#define DCTRL_RWSTOP_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32U) + (RWSTOP_BITNUMBER * 4U))
-
-/* Alias word address of RWMOD bit */
-#define RWMOD_BITNUMBER 0x0AU
-#define DCTRL_RWMOD_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32U) + (RWMOD_BITNUMBER * 4U))
-
-/* Alias word address of SDIOEN bit */
-#define SDIOEN_BITNUMBER 0x0BU
-#define DCTRL_SDIOEN_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32U) + (SDIOEN_BITNUMBER * 4U))
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_Register Bits And Addresses Definitions
- * @brief SDIO_LL registers bit address in the alias region
- * @{
- */
-/* ---------------------- SDIO registers bit mask --------------------------- */
-/* --- CLKCR Register ---*/
-/* CLKCR register clear mask */
-#define CLKCR_CLEAR_MASK ((uint32_t)(SDIO_CLKCR_CLKDIV | SDIO_CLKCR_PWRSAV |\
- SDIO_CLKCR_BYPASS | SDIO_CLKCR_WIDBUS |\
- SDIO_CLKCR_NEGEDGE | SDIO_CLKCR_HWFC_EN))
-
-/* --- DCTRL Register ---*/
-/* SDIO DCTRL Clear Mask */
-#define DCTRL_CLEAR_MASK ((uint32_t)(SDIO_DCTRL_DTEN | SDIO_DCTRL_DTDIR |\
- SDIO_DCTRL_DTMODE | SDIO_DCTRL_DBLOCKSIZE))
-
-/* --- CMD Register ---*/
-/* CMD Register clear mask */
-#define CMD_CLEAR_MASK ((uint32_t)(SDIO_CMD_CMDINDEX | SDIO_CMD_WAITRESP |\
- SDIO_CMD_WAITINT | SDIO_CMD_WAITPEND |\
- SDIO_CMD_CPSMEN | SDIO_CMD_SDIOSUSPEND))
-
-/* SDIO RESP Registers Address */
-#define SDIO_RESP_ADDR ((uint32_t)(SDIO_BASE + 0x14))
-
-/* SDIO Intialization Frequency (400KHz max) */
-#define SDIO_INIT_CLK_DIV ((uint8_t)0xC3)
-
-/* SDIO Data Transfer Frequency */
-#define SDIO_TRANSFER_CLK_DIV ((uint8_t)0x9)
-
-/**
- * @}
- */
-
-/** @defgroup SDIO_LL_Interrupt_Clock Interrupt And Clock Configuration
- * @brief macros to handle interrupts and specific clock configurations
- * @{
- */
-
-/**
- * @brief Enable the SDIO device.
- * @param __INSTANCE__: SDIO Instance
- * @retval None
- */
-#define __SDIO_ENABLE(__INSTANCE__) (*(__IO uint32_t *)CLKCR_CLKEN_BB = ENABLE)
-
-/**
- * @brief Disable the SDIO device.
- * @param __INSTANCE__: SDIO Instance
- * @retval None
- */
-#define __SDIO_DISABLE(__INSTANCE__) (*(__IO uint32_t *)CLKCR_CLKEN_BB = DISABLE)
-
-/**
- * @brief Enable the SDIO DMA transfer.
- * @param __INSTANCE__: SDIO Instance
- * @retval None
- */
-#define __SDIO_DMA_ENABLE(__INSTANCE__) (*(__IO uint32_t *)DCTRL_DMAEN_BB = ENABLE)
-/**
- * @brief Disable the SDIO DMA transfer.
- * @param __INSTANCE__: SDIO Instance
- * @retval None
- */
-#define __SDIO_DMA_DISABLE(__INSTANCE__) (*(__IO uint32_t *)DCTRL_DMAEN_BB = DISABLE)
-
-/**
- * @brief Enable the SDIO device interrupt.
- * @param __INSTANCE__ : Pointer to SDIO register base
- * @param __INTERRUPT__ : specifies the SDIO interrupt sources to be enabled.
- * This parameter can be one or a combination of the following values:
- * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
- * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
- * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
- * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
- * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
- * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
- * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
- * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
- * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
- * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
- * @arg SDIO_IT_RXACT: Data receive in progress interrupt
- * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
- * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
- * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
- * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
- * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
- * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
- * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
- * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
- * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
- * @retval None
- */
-#define __SDIO_ENABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->MASK |= (__INTERRUPT__))
-
-/**
- * @brief Disable the SDIO device interrupt.
- * @param __INSTANCE__ : Pointer to SDIO register base
- * @param __INTERRUPT__ : specifies the SDIO interrupt sources to be disabled.
- * This parameter can be one or a combination of the following values:
- * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
- * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
- * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
- * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
- * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
- * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
- * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
- * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
- * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
- * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
- * @arg SDIO_IT_RXACT: Data receive in progress interrupt
- * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
- * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
- * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
- * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
- * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
- * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
- * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
- * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
- * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
- * @retval None
- */
-#define __SDIO_DISABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->MASK &= ~(__INTERRUPT__))
-
-/**
- * @brief Checks whether the specified SDIO flag is set or not.
- * @param __INSTANCE__ : Pointer to SDIO register base
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed)
- * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed)
- * @arg SDIO_FLAG_CTIMEOUT: Command response timeout
- * @arg SDIO_FLAG_DTIMEOUT: Data timeout
- * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error
- * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error
- * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed)
- * @arg SDIO_FLAG_CMDSENT: Command sent (no response required)
- * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero)
- * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed)
- * @arg SDIO_FLAG_CMDACT: Command transfer in progress
- * @arg SDIO_FLAG_TXACT: Data transmit in progress
- * @arg SDIO_FLAG_RXACT: Data receive in progress
- * @arg SDIO_FLAG_TXFIFOHE: Transmit FIFO Half Empty
- * @arg SDIO_FLAG_RXFIFOHF: Receive FIFO Half Full
- * @arg SDIO_FLAG_TXFIFOF: Transmit FIFO full
- * @arg SDIO_FLAG_RXFIFOF: Receive FIFO full
- * @arg SDIO_FLAG_TXFIFOE: Transmit FIFO empty
- * @arg SDIO_FLAG_RXFIFOE: Receive FIFO empty
- * @arg SDIO_FLAG_TXDAVL: Data available in transmit FIFO
- * @arg SDIO_FLAG_RXDAVL: Data available in receive FIFO
- * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received
- * @retval The new state of SDIO_FLAG (SET or RESET).
- */
-#define __SDIO_GET_FLAG(__INSTANCE__, __FLAG__) (((__INSTANCE__)->STA &(__FLAG__)) != RESET)
-
-
-/**
- * @brief Clears the SDIO pending flags.
- * @param __INSTANCE__ : Pointer to SDIO register base
- * @param __FLAG__: specifies the flag to clear.
- * This parameter can be one or a combination of the following values:
- * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed)
- * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed)
- * @arg SDIO_FLAG_CTIMEOUT: Command response timeout
- * @arg SDIO_FLAG_DTIMEOUT: Data timeout
- * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error
- * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error
- * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed)
- * @arg SDIO_FLAG_CMDSENT: Command sent (no response required)
- * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero)
- * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed)
- * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received
- * @retval None
- */
-#define __SDIO_CLEAR_FLAG(__INSTANCE__, __FLAG__) ((__INSTANCE__)->ICR = (__FLAG__))
-
-/**
- * @brief Checks whether the specified SDIO interrupt has occurred or not.
- * @param __INSTANCE__ : Pointer to SDIO register base
- * @param __INTERRUPT__: specifies the SDIO interrupt source to check.
- * This parameter can be one of the following values:
- * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
- * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
- * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
- * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
- * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
- * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
- * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
- * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
- * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
- * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
- * @arg SDIO_IT_RXACT: Data receive in progress interrupt
- * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
- * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
- * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
- * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
- * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
- * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
- * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
- * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
- * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
- * @retval The new state of SDIO_IT (SET or RESET).
- */
-#define __SDIO_GET_IT (__INSTANCE__, __INTERRUPT__) (((__INSTANCE__)->STA &(__INTERRUPT__)) == (__INTERRUPT__))
-
-/**
- * @brief Clears the SDIO's interrupt pending bits.
- * @param __INSTANCE__ : Pointer to SDIO register base
- * @param __INTERRUPT__: specifies the interrupt pending bit to clear.
- * This parameter can be one or a combination of the following values:
- * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
- * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
- * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
- * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
- * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
- * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
- * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
- * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
- * @arg SDIO_IT_DATAEND: Data end (data counter, SDIO_DCOUNT, is zero) interrupt
- * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
- * @retval None
- */
-#define __SDIO_CLEAR_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->ICR = (__INTERRUPT__))
-
-/**
- * @brief Enable Start the SD I/O Read Wait operation.
- * @param __INSTANCE__ : Pointer to SDIO register base
- * @retval None
- */
-#define __SDIO_START_READWAIT_ENABLE(__INSTANCE__) (*(__IO uint32_t *) DCTRL_RWSTART_BB = ENABLE)
-
-/**
- * @brief Disable Start the SD I/O Read Wait operations.
- * @param __INSTANCE__ : Pointer to SDIO register base
- * @retval None
- */
-#define __SDIO_START_READWAIT_DISABLE(__INSTANCE__) (*(__IO uint32_t *) DCTRL_RWSTART_BB = DISABLE)
-
-/**
- * @brief Enable Start the SD I/O Read Wait operation.
- * @param __INSTANCE__ : Pointer to SDIO register base
- * @retval None
- */
-#define __SDIO_STOP_READWAIT_ENABLE(__INSTANCE__) (*(__IO uint32_t *) DCTRL_RWSTOP_BB = ENABLE)
-
-/**
- * @brief Disable Stop the SD I/O Read Wait operations.
- * @param __INSTANCE__ : Pointer to SDIO register base
- * @retval None
- */
-#define __SDIO_STOP_READWAIT_DISABLE(__INSTANCE__) (*(__IO uint32_t *) DCTRL_RWSTOP_BB = DISABLE)
-
-/**
- * @brief Enable the SD I/O Mode Operation.
- * @param __INSTANCE__ : Pointer to SDIO register base
- * @retval None
- */
-#define __SDIO_OPERATION_ENABLE(__INSTANCE__) (*(__IO uint32_t *) DCTRL_SDIOEN_BB = ENABLE)
-
-/**
- * @brief Disable the SD I/O Mode Operation.
- * @param __INSTANCE__ : Pointer to SDIO register base
- * @retval None
- */
-#define __SDIO_OPERATION_DISABLE(__INSTANCE__) (*(__IO uint32_t *) DCTRL_SDIOEN_BB = DISABLE)
-
-/**
- * @brief Enable the SD I/O Suspend command sending.
- * @param __INSTANCE__ : Pointer to SDIO register base
- * @retval None
- */
-#define __SDIO_SUSPEND_CMD_ENABLE(__INSTANCE__) (*(__IO uint32_t *) CMD_SDIOSUSPEND_BB = ENABLE)
-
-/**
- * @brief Disable the SD I/O Suspend command sending.
- * @param __INSTANCE__ : Pointer to SDIO register base
- * @retval None
- */
-#define __SDIO_SUSPEND_CMD_DISABLE(__INSTANCE__) (*(__IO uint32_t *) CMD_SDIOSUSPEND_BB = DISABLE)
-/**
- * @brief Enable the command completion signal.
- * @retval None
- */
-#define __SDIO_CEATA_CMD_COMPLETION_ENABLE() (*(__IO uint32_t *) CMD_ENCMDCOMPL_BB = ENABLE)
-
-/**
- * @brief Disable the command completion signal.
- * @retval None
- */
-#define __SDIO_CEATA_CMD_COMPLETION_DISABLE() (*(__IO uint32_t *) CMD_ENCMDCOMPL_BB = DISABLE)
-
-/**
- * @brief Enable the CE-ATA interrupt.
- * @retval None
- */
-#define __SDIO_CEATA_ENABLE_IT() (*(__IO uint32_t *) CMD_NIEN_BB = (uint32_t)0U)
-
-/**
- * @brief Disable the CE-ATA interrupt.
- * @retval None
- */
-#define __SDIO_CEATA_DISABLE_IT() (*(__IO uint32_t *) CMD_NIEN_BB = (uint32_t)1U)
-
-/**
- * @brief Enable send CE-ATA command (CMD61).
- * @retval None
- */
-#define __SDIO_CEATA_SENDCMD_ENABLE() (*(__IO uint32_t *) CMD_ATACMD_BB = ENABLE)
-
-/**
- * @brief Disable send CE-ATA command (CMD61).
- * @retval None
- */
-#define __SDIO_CEATA_SENDCMD_DISABLE() (*(__IO uint32_t *) CMD_ATACMD_BB = DISABLE)
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup SDMMC_LL_Exported_Functions
- * @{
- */
-
-/* Initialization/de-initialization functions **********************************/
-/** @addtogroup HAL_SDMMC_LL_Group1
- * @{
- */
-HAL_StatusTypeDef SDIO_Init(SDIO_TypeDef *SDIOx, SDIO_InitTypeDef Init);
-/**
- * @}
- */
-
-/* I/O operation functions *****************************************************/
-/** @addtogroup HAL_SDMMC_LL_Group2
- * @{
- */
-/* Blocking mode: Polling */
-uint32_t SDIO_ReadFIFO(SDIO_TypeDef *SDIOx);
-HAL_StatusTypeDef SDIO_WriteFIFO(SDIO_TypeDef *SDIOx, uint32_t *pWriteData);
-/**
- * @}
- */
-
-/* Peripheral Control functions ************************************************/
-/** @addtogroup HAL_SDMMC_LL_Group3
- * @{
- */
-HAL_StatusTypeDef SDIO_PowerState_ON(SDIO_TypeDef *SDIOx);
-HAL_StatusTypeDef SDIO_PowerState_OFF(SDIO_TypeDef *SDIOx);
-uint32_t SDIO_GetPowerState(SDIO_TypeDef *SDIOx);
-
-/* Command path state machine (CPSM) management functions */
-HAL_StatusTypeDef SDIO_SendCommand(SDIO_TypeDef *SDIOx, SDIO_CmdInitTypeDef *Command);
-uint8_t SDIO_GetCommandResponse(SDIO_TypeDef *SDIOx);
-uint32_t SDIO_GetResponse(SDIO_TypeDef *SDIOx, uint32_t Response);
-
-/* Data path state machine (DPSM) management functions */
-HAL_StatusTypeDef SDIO_ConfigData(SDIO_TypeDef *SDIOx, SDIO_DataInitTypeDef* Data);
-uint32_t SDIO_GetDataCounter(SDIO_TypeDef *SDIOx);
-uint32_t SDIO_GetFIFOCount(SDIO_TypeDef *SDIOx);
-
-/* SDMMC Cards mode management functions */
-HAL_StatusTypeDef SDIO_SetSDMMCReadWaitMode(SDIO_TypeDef *SDIOx, uint32_t SDIO_ReadWaitMode);
-
-/* SDMMC Commands management functions */
-uint32_t SDMMC_CmdBlockLength(SDIO_TypeDef *SDIOx, uint32_t BlockSize);
-uint32_t SDMMC_CmdReadSingleBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd);
-uint32_t SDMMC_CmdReadMultiBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd);
-uint32_t SDMMC_CmdWriteSingleBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd);
-uint32_t SDMMC_CmdWriteMultiBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd);
-uint32_t SDMMC_CmdSDEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd);
-uint32_t SDMMC_CmdSDEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd);
-uint32_t SDMMC_CmdErase(SDIO_TypeDef *SDIOx);
-uint32_t SDMMC_CmdStopTransfer(SDIO_TypeDef *SDIOx);
-uint32_t SDMMC_CmdSelDesel(SDIO_TypeDef *SDIOx, uint64_t Addr);
-uint32_t SDMMC_CmdGoIdleState(SDIO_TypeDef *SDIOx);
-uint32_t SDMMC_CmdOperCond(SDIO_TypeDef *SDIOx);
-uint32_t SDMMC_CmdAppCommand(SDIO_TypeDef *SDIOx, uint32_t Argument);
-uint32_t SDMMC_CmdAppOperCommand(SDIO_TypeDef *SDIOx, uint32_t SdType);
-uint32_t SDMMC_CmdBusWidth(SDIO_TypeDef *SDIOx, uint32_t BusWidth);
-uint32_t SDMMC_CmdSendSCR(SDIO_TypeDef *SDIOx);
-uint32_t SDMMC_CmdSendCID(SDIO_TypeDef *SDIOx);
-uint32_t SDMMC_CmdSendCSD(SDIO_TypeDef *SDIOx, uint32_t Argument);
-uint32_t SDMMC_CmdSetRelAdd(SDIO_TypeDef *SDIOx, uint16_t *pRCA);
-uint32_t SDMMC_CmdSendStatus(SDIO_TypeDef *SDIOx, uint32_t Argument);
-uint32_t SDMMC_CmdStatusRegister(SDIO_TypeDef *SDIOx);
-
-uint32_t SDMMC_CmdOpCondition(SDIO_TypeDef *SDIOx, uint32_t Argument);
-uint32_t SDMMC_CmdSwitch(SDIO_TypeDef *SDIOx, uint32_t Argument);
-uint32_t SDMMC_CmdEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd);
-uint32_t SDMMC_CmdEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd);
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32F103xE || STM32F103xG */
-
-#endif /* __stm32f1xx_LL_SD_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_spi.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_spi.h
deleted file mode 100644
index 379ae2d..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_spi.h
+++ /dev/null
@@ -1,1920 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_spi.h
- * @author MCD Application Team
- * @brief Header file of SPI LL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_LL_SPI_H
-#define __STM32F1xx_LL_SPI_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx.h"
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined (SPI1) || defined (SPI2) || defined (SPI3)
-
-/** @defgroup SPI_LL SPI
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-
-/* Exported types ------------------------------------------------------------*/
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup SPI_LL_ES_INIT SPI Exported Init structure
- * @{
- */
-
-/**
- * @brief SPI Init structures definition
- */
-typedef struct
-{
- uint32_t TransferDirection; /*!< Specifies the SPI unidirectional or bidirectional data mode.
- This parameter can be a value of @ref SPI_LL_EC_TRANSFER_MODE.
-
- This feature can be modified afterwards using unitary function @ref LL_SPI_SetTransferDirection().*/
-
- uint32_t Mode; /*!< Specifies the SPI mode (Master/Slave).
- This parameter can be a value of @ref SPI_LL_EC_MODE.
-
- This feature can be modified afterwards using unitary function @ref LL_SPI_SetMode().*/
-
- uint32_t DataWidth; /*!< Specifies the SPI data width.
- This parameter can be a value of @ref SPI_LL_EC_DATAWIDTH.
-
- This feature can be modified afterwards using unitary function @ref LL_SPI_SetDataWidth().*/
-
- uint32_t ClockPolarity; /*!< Specifies the serial clock steady state.
- This parameter can be a value of @ref SPI_LL_EC_POLARITY.
-
- This feature can be modified afterwards using unitary function @ref LL_SPI_SetClockPolarity().*/
-
- uint32_t ClockPhase; /*!< Specifies the clock active edge for the bit capture.
- This parameter can be a value of @ref SPI_LL_EC_PHASE.
-
- This feature can be modified afterwards using unitary function @ref LL_SPI_SetClockPhase().*/
-
- uint32_t NSS; /*!< Specifies whether the NSS signal is managed by hardware (NSS pin) or by software using the SSI bit.
- This parameter can be a value of @ref SPI_LL_EC_NSS_MODE.
-
- This feature can be modified afterwards using unitary function @ref LL_SPI_SetNSSMode().*/
-
- uint32_t BaudRate; /*!< Specifies the BaudRate prescaler value which will be used to configure the transmit and receive SCK clock.
- This parameter can be a value of @ref SPI_LL_EC_BAUDRATEPRESCALER.
- @note The communication clock is derived from the master clock. The slave clock does not need to be set.
-
- This feature can be modified afterwards using unitary function @ref LL_SPI_SetBaudRatePrescaler().*/
-
- uint32_t BitOrder; /*!< Specifies whether data transfers start from MSB or LSB bit.
- This parameter can be a value of @ref SPI_LL_EC_BIT_ORDER.
-
- This feature can be modified afterwards using unitary function @ref LL_SPI_SetTransferBitOrder().*/
-
- uint32_t CRCCalculation; /*!< Specifies if the CRC calculation is enabled or not.
- This parameter can be a value of @ref SPI_LL_EC_CRC_CALCULATION.
-
- This feature can be modified afterwards using unitary functions @ref LL_SPI_EnableCRC() and @ref LL_SPI_DisableCRC().*/
-
- uint32_t CRCPoly; /*!< Specifies the polynomial used for the CRC calculation.
- This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFFFF.
-
- This feature can be modified afterwards using unitary function @ref LL_SPI_SetCRCPolynomial().*/
-
-} LL_SPI_InitTypeDef;
-
-/**
- * @}
- */
-#endif /* USE_FULL_LL_DRIVER */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup SPI_LL_Exported_Constants SPI Exported Constants
- * @{
- */
-
-/** @defgroup SPI_LL_EC_GET_FLAG Get Flags Defines
- * @brief Flags defines which can be used with LL_SPI_ReadReg function
- * @{
- */
-#define LL_SPI_SR_RXNE SPI_SR_RXNE /*!< Rx buffer not empty flag */
-#define LL_SPI_SR_TXE SPI_SR_TXE /*!< Tx buffer empty flag */
-#define LL_SPI_SR_BSY SPI_SR_BSY /*!< Busy flag */
-#define LL_SPI_SR_CRCERR SPI_SR_CRCERR /*!< CRC error flag */
-#define LL_SPI_SR_MODF SPI_SR_MODF /*!< Mode fault flag */
-#define LL_SPI_SR_OVR SPI_SR_OVR /*!< Overrun flag */
-#define LL_SPI_SR_FRE SPI_SR_FRE /*!< TI mode frame format error flag */
-/**
- * @}
- */
-
-/** @defgroup SPI_LL_EC_IT IT Defines
- * @brief IT defines which can be used with LL_SPI_ReadReg and LL_SPI_WriteReg functions
- * @{
- */
-#define LL_SPI_CR2_RXNEIE SPI_CR2_RXNEIE /*!< Rx buffer not empty interrupt enable */
-#define LL_SPI_CR2_TXEIE SPI_CR2_TXEIE /*!< Tx buffer empty interrupt enable */
-#define LL_SPI_CR2_ERRIE SPI_CR2_ERRIE /*!< Error interrupt enable */
-/**
- * @}
- */
-
-/** @defgroup SPI_LL_EC_MODE Operation Mode
- * @{
- */
-#define LL_SPI_MODE_MASTER (SPI_CR1_MSTR | SPI_CR1_SSI) /*!< Master configuration */
-#define LL_SPI_MODE_SLAVE 0x00000000U /*!< Slave configuration */
-/**
- * @}
- */
-
-
-/** @defgroup SPI_LL_EC_PHASE Clock Phase
- * @{
- */
-#define LL_SPI_PHASE_1EDGE 0x00000000U /*!< First clock transition is the first data capture edge */
-#define LL_SPI_PHASE_2EDGE (SPI_CR1_CPHA) /*!< Second clock transition is the first data capture edge */
-/**
- * @}
- */
-
-/** @defgroup SPI_LL_EC_POLARITY Clock Polarity
- * @{
- */
-#define LL_SPI_POLARITY_LOW 0x00000000U /*!< Clock to 0 when idle */
-#define LL_SPI_POLARITY_HIGH (SPI_CR1_CPOL) /*!< Clock to 1 when idle */
-/**
- * @}
- */
-
-/** @defgroup SPI_LL_EC_BAUDRATEPRESCALER Baud Rate Prescaler
- * @{
- */
-#define LL_SPI_BAUDRATEPRESCALER_DIV2 0x00000000U /*!< BaudRate control equal to fPCLK/2 */
-#define LL_SPI_BAUDRATEPRESCALER_DIV4 (SPI_CR1_BR_0) /*!< BaudRate control equal to fPCLK/4 */
-#define LL_SPI_BAUDRATEPRESCALER_DIV8 (SPI_CR1_BR_1) /*!< BaudRate control equal to fPCLK/8 */
-#define LL_SPI_BAUDRATEPRESCALER_DIV16 (SPI_CR1_BR_1 | SPI_CR1_BR_0) /*!< BaudRate control equal to fPCLK/16 */
-#define LL_SPI_BAUDRATEPRESCALER_DIV32 (SPI_CR1_BR_2) /*!< BaudRate control equal to fPCLK/32 */
-#define LL_SPI_BAUDRATEPRESCALER_DIV64 (SPI_CR1_BR_2 | SPI_CR1_BR_0) /*!< BaudRate control equal to fPCLK/64 */
-#define LL_SPI_BAUDRATEPRESCALER_DIV128 (SPI_CR1_BR_2 | SPI_CR1_BR_1) /*!< BaudRate control equal to fPCLK/128 */
-#define LL_SPI_BAUDRATEPRESCALER_DIV256 (SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0) /*!< BaudRate control equal to fPCLK/256 */
-/**
- * @}
- */
-
-/** @defgroup SPI_LL_EC_BIT_ORDER Transmission Bit Order
- * @{
- */
-#define LL_SPI_LSB_FIRST (SPI_CR1_LSBFIRST) /*!< Data is transmitted/received with the LSB first */
-#define LL_SPI_MSB_FIRST 0x00000000U /*!< Data is transmitted/received with the MSB first */
-/**
- * @}
- */
-
-/** @defgroup SPI_LL_EC_TRANSFER_MODE Transfer Mode
- * @{
- */
-#define LL_SPI_FULL_DUPLEX 0x00000000U /*!< Full-Duplex mode. Rx and Tx transfer on 2 lines */
-#define LL_SPI_SIMPLEX_RX (SPI_CR1_RXONLY) /*!< Simplex Rx mode. Rx transfer only on 1 line */
-#define LL_SPI_HALF_DUPLEX_RX (SPI_CR1_BIDIMODE) /*!< Half-Duplex Rx mode. Rx transfer on 1 line */
-#define LL_SPI_HALF_DUPLEX_TX (SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE) /*!< Half-Duplex Tx mode. Tx transfer on 1 line */
-/**
- * @}
- */
-
-/** @defgroup SPI_LL_EC_NSS_MODE Slave Select Pin Mode
- * @{
- */
-#define LL_SPI_NSS_SOFT (SPI_CR1_SSM) /*!< NSS managed internally. NSS pin not used and free */
-#define LL_SPI_NSS_HARD_INPUT 0x00000000U /*!< NSS pin used in Input. Only used in Master mode */
-#define LL_SPI_NSS_HARD_OUTPUT (((uint32_t)SPI_CR2_SSOE << 16U)) /*!< NSS pin used in Output. Only used in Slave mode as chip select */
-/**
- * @}
- */
-
-/** @defgroup SPI_LL_EC_DATAWIDTH Datawidth
- * @{
- */
-#define LL_SPI_DATAWIDTH_8BIT 0x00000000U /*!< Data length for SPI transfer: 8 bits */
-#define LL_SPI_DATAWIDTH_16BIT (SPI_CR1_DFF) /*!< Data length for SPI transfer: 16 bits */
-/**
- * @}
- */
-#if defined(USE_FULL_LL_DRIVER)
-
-/** @defgroup SPI_LL_EC_CRC_CALCULATION CRC Calculation
- * @{
- */
-#define LL_SPI_CRCCALCULATION_DISABLE 0x00000000U /*!< CRC calculation disabled */
-#define LL_SPI_CRCCALCULATION_ENABLE (SPI_CR1_CRCEN) /*!< CRC calculation enabled */
-/**
- * @}
- */
-#endif /* USE_FULL_LL_DRIVER */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup SPI_LL_Exported_Macros SPI Exported Macros
- * @{
- */
-
-/** @defgroup SPI_LL_EM_WRITE_READ Common Write and read registers Macros
- * @{
- */
-
-/**
- * @brief Write a value in SPI register
- * @param __INSTANCE__ SPI Instance
- * @param __REG__ Register to be written
- * @param __VALUE__ Value to be written in the register
- * @retval None
- */
-#define LL_SPI_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
-
-/**
- * @brief Read a value in SPI register
- * @param __INSTANCE__ SPI Instance
- * @param __REG__ Register to be read
- * @retval Register value
- */
-#define LL_SPI_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup SPI_LL_Exported_Functions SPI Exported Functions
- * @{
- */
-
-/** @defgroup SPI_LL_EF_Configuration Configuration
- * @{
- */
-
-/**
- * @brief Enable SPI peripheral
- * @rmtoll CR1 SPE LL_SPI_Enable
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_Enable(SPI_TypeDef *SPIx)
-{
- SET_BIT(SPIx->CR1, SPI_CR1_SPE);
-}
-
-/**
- * @brief Disable SPI peripheral
- * @note When disabling the SPI, follow the procedure described in the Reference Manual.
- * @rmtoll CR1 SPE LL_SPI_Disable
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_Disable(SPI_TypeDef *SPIx)
-{
- CLEAR_BIT(SPIx->CR1, SPI_CR1_SPE);
-}
-
-/**
- * @brief Check if SPI peripheral is enabled
- * @rmtoll CR1 SPE LL_SPI_IsEnabled
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_SPI_IsEnabled(SPI_TypeDef *SPIx)
-{
- return (READ_BIT(SPIx->CR1, SPI_CR1_SPE) == (SPI_CR1_SPE));
-}
-
-/**
- * @brief Set SPI operation mode to Master or Slave
- * @note This bit should not be changed when communication is ongoing.
- * @rmtoll CR1 MSTR LL_SPI_SetMode\n
- * CR1 SSI LL_SPI_SetMode
- * @param SPIx SPI Instance
- * @param Mode This parameter can be one of the following values:
- * @arg @ref LL_SPI_MODE_MASTER
- * @arg @ref LL_SPI_MODE_SLAVE
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_SetMode(SPI_TypeDef *SPIx, uint32_t Mode)
-{
- MODIFY_REG(SPIx->CR1, SPI_CR1_MSTR | SPI_CR1_SSI, Mode);
-}
-
-/**
- * @brief Get SPI operation mode (Master or Slave)
- * @rmtoll CR1 MSTR LL_SPI_GetMode\n
- * CR1 SSI LL_SPI_GetMode
- * @param SPIx SPI Instance
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_SPI_MODE_MASTER
- * @arg @ref LL_SPI_MODE_SLAVE
- */
-__STATIC_INLINE uint32_t LL_SPI_GetMode(SPI_TypeDef *SPIx)
-{
- return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_MSTR | SPI_CR1_SSI));
-}
-
-
-/**
- * @brief Set clock phase
- * @note This bit should not be changed when communication is ongoing.
- * This bit is not used in SPI TI mode.
- * @rmtoll CR1 CPHA LL_SPI_SetClockPhase
- * @param SPIx SPI Instance
- * @param ClockPhase This parameter can be one of the following values:
- * @arg @ref LL_SPI_PHASE_1EDGE
- * @arg @ref LL_SPI_PHASE_2EDGE
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_SetClockPhase(SPI_TypeDef *SPIx, uint32_t ClockPhase)
-{
- MODIFY_REG(SPIx->CR1, SPI_CR1_CPHA, ClockPhase);
-}
-
-/**
- * @brief Get clock phase
- * @rmtoll CR1 CPHA LL_SPI_GetClockPhase
- * @param SPIx SPI Instance
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_SPI_PHASE_1EDGE
- * @arg @ref LL_SPI_PHASE_2EDGE
- */
-__STATIC_INLINE uint32_t LL_SPI_GetClockPhase(SPI_TypeDef *SPIx)
-{
- return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_CPHA));
-}
-
-/**
- * @brief Set clock polarity
- * @note This bit should not be changed when communication is ongoing.
- * This bit is not used in SPI TI mode.
- * @rmtoll CR1 CPOL LL_SPI_SetClockPolarity
- * @param SPIx SPI Instance
- * @param ClockPolarity This parameter can be one of the following values:
- * @arg @ref LL_SPI_POLARITY_LOW
- * @arg @ref LL_SPI_POLARITY_HIGH
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_SetClockPolarity(SPI_TypeDef *SPIx, uint32_t ClockPolarity)
-{
- MODIFY_REG(SPIx->CR1, SPI_CR1_CPOL, ClockPolarity);
-}
-
-/**
- * @brief Get clock polarity
- * @rmtoll CR1 CPOL LL_SPI_GetClockPolarity
- * @param SPIx SPI Instance
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_SPI_POLARITY_LOW
- * @arg @ref LL_SPI_POLARITY_HIGH
- */
-__STATIC_INLINE uint32_t LL_SPI_GetClockPolarity(SPI_TypeDef *SPIx)
-{
- return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_CPOL));
-}
-
-/**
- * @brief Set baud rate prescaler
- * @note These bits should not be changed when communication is ongoing. SPI BaudRate = fPCLK/Prescaler.
- * @rmtoll CR1 BR LL_SPI_SetBaudRatePrescaler
- * @param SPIx SPI Instance
- * @param BaudRate This parameter can be one of the following values:
- * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV2
- * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV4
- * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV8
- * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV16
- * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV32
- * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV64
- * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV128
- * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV256
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_SetBaudRatePrescaler(SPI_TypeDef *SPIx, uint32_t BaudRate)
-{
- MODIFY_REG(SPIx->CR1, SPI_CR1_BR, BaudRate);
-}
-
-/**
- * @brief Get baud rate prescaler
- * @rmtoll CR1 BR LL_SPI_GetBaudRatePrescaler
- * @param SPIx SPI Instance
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV2
- * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV4
- * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV8
- * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV16
- * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV32
- * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV64
- * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV128
- * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV256
- */
-__STATIC_INLINE uint32_t LL_SPI_GetBaudRatePrescaler(SPI_TypeDef *SPIx)
-{
- return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_BR));
-}
-
-/**
- * @brief Set transfer bit order
- * @note This bit should not be changed when communication is ongoing. This bit is not used in SPI TI mode.
- * @rmtoll CR1 LSBFIRST LL_SPI_SetTransferBitOrder
- * @param SPIx SPI Instance
- * @param BitOrder This parameter can be one of the following values:
- * @arg @ref LL_SPI_LSB_FIRST
- * @arg @ref LL_SPI_MSB_FIRST
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_SetTransferBitOrder(SPI_TypeDef *SPIx, uint32_t BitOrder)
-{
- MODIFY_REG(SPIx->CR1, SPI_CR1_LSBFIRST, BitOrder);
-}
-
-/**
- * @brief Get transfer bit order
- * @rmtoll CR1 LSBFIRST LL_SPI_GetTransferBitOrder
- * @param SPIx SPI Instance
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_SPI_LSB_FIRST
- * @arg @ref LL_SPI_MSB_FIRST
- */
-__STATIC_INLINE uint32_t LL_SPI_GetTransferBitOrder(SPI_TypeDef *SPIx)
-{
- return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_LSBFIRST));
-}
-
-/**
- * @brief Set transfer direction mode
- * @note For Half-Duplex mode, Rx Direction is set by default.
- * In master mode, the MOSI pin is used and in slave mode, the MISO pin is used for Half-Duplex.
- * @rmtoll CR1 RXONLY LL_SPI_SetTransferDirection\n
- * CR1 BIDIMODE LL_SPI_SetTransferDirection\n
- * CR1 BIDIOE LL_SPI_SetTransferDirection
- * @param SPIx SPI Instance
- * @param TransferDirection This parameter can be one of the following values:
- * @arg @ref LL_SPI_FULL_DUPLEX
- * @arg @ref LL_SPI_SIMPLEX_RX
- * @arg @ref LL_SPI_HALF_DUPLEX_RX
- * @arg @ref LL_SPI_HALF_DUPLEX_TX
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_SetTransferDirection(SPI_TypeDef *SPIx, uint32_t TransferDirection)
-{
- MODIFY_REG(SPIx->CR1, SPI_CR1_RXONLY | SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE, TransferDirection);
-}
-
-/**
- * @brief Get transfer direction mode
- * @rmtoll CR1 RXONLY LL_SPI_GetTransferDirection\n
- * CR1 BIDIMODE LL_SPI_GetTransferDirection\n
- * CR1 BIDIOE LL_SPI_GetTransferDirection
- * @param SPIx SPI Instance
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_SPI_FULL_DUPLEX
- * @arg @ref LL_SPI_SIMPLEX_RX
- * @arg @ref LL_SPI_HALF_DUPLEX_RX
- * @arg @ref LL_SPI_HALF_DUPLEX_TX
- */
-__STATIC_INLINE uint32_t LL_SPI_GetTransferDirection(SPI_TypeDef *SPIx)
-{
- return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_RXONLY | SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE));
-}
-
-/**
- * @brief Set frame data width
- * @rmtoll CR1 DFF LL_SPI_SetDataWidth
- * @param SPIx SPI Instance
- * @param DataWidth This parameter can be one of the following values:
- * @arg @ref LL_SPI_DATAWIDTH_8BIT
- * @arg @ref LL_SPI_DATAWIDTH_16BIT
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_SetDataWidth(SPI_TypeDef *SPIx, uint32_t DataWidth)
-{
- MODIFY_REG(SPIx->CR1, SPI_CR1_DFF, DataWidth);
-}
-
-/**
- * @brief Get frame data width
- * @rmtoll CR1 DFF LL_SPI_GetDataWidth
- * @param SPIx SPI Instance
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_SPI_DATAWIDTH_8BIT
- * @arg @ref LL_SPI_DATAWIDTH_16BIT
- */
-__STATIC_INLINE uint32_t LL_SPI_GetDataWidth(SPI_TypeDef *SPIx)
-{
- return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_DFF));
-}
-
-/**
- * @}
- */
-
-/** @defgroup SPI_LL_EF_CRC_Management CRC Management
- * @{
- */
-
-/**
- * @brief Enable CRC
- * @note This bit should be written only when SPI is disabled (SPE = 0) for correct operation.
- * @rmtoll CR1 CRCEN LL_SPI_EnableCRC
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_EnableCRC(SPI_TypeDef *SPIx)
-{
- SET_BIT(SPIx->CR1, SPI_CR1_CRCEN);
-}
-
-/**
- * @brief Disable CRC
- * @note This bit should be written only when SPI is disabled (SPE = 0) for correct operation.
- * @rmtoll CR1 CRCEN LL_SPI_DisableCRC
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_DisableCRC(SPI_TypeDef *SPIx)
-{
- CLEAR_BIT(SPIx->CR1, SPI_CR1_CRCEN);
-}
-
-/**
- * @brief Check if CRC is enabled
- * @note This bit should be written only when SPI is disabled (SPE = 0) for correct operation.
- * @rmtoll CR1 CRCEN LL_SPI_IsEnabledCRC
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_SPI_IsEnabledCRC(SPI_TypeDef *SPIx)
-{
- return (READ_BIT(SPIx->CR1, SPI_CR1_CRCEN) == (SPI_CR1_CRCEN));
-}
-
-/**
- * @brief Set CRCNext to transfer CRC on the line
- * @note This bit has to be written as soon as the last data is written in the SPIx_DR register.
- * @rmtoll CR1 CRCNEXT LL_SPI_SetCRCNext
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_SetCRCNext(SPI_TypeDef *SPIx)
-{
- SET_BIT(SPIx->CR1, SPI_CR1_CRCNEXT);
-}
-
-/**
- * @brief Set polynomial for CRC calculation
- * @rmtoll CRCPR CRCPOLY LL_SPI_SetCRCPolynomial
- * @param SPIx SPI Instance
- * @param CRCPoly This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFFFF
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_SetCRCPolynomial(SPI_TypeDef *SPIx, uint32_t CRCPoly)
-{
- WRITE_REG(SPIx->CRCPR, (uint16_t)CRCPoly);
-}
-
-/**
- * @brief Get polynomial for CRC calculation
- * @rmtoll CRCPR CRCPOLY LL_SPI_GetCRCPolynomial
- * @param SPIx SPI Instance
- * @retval Returned value is a number between Min_Data = 0x00 and Max_Data = 0xFFFF
- */
-__STATIC_INLINE uint32_t LL_SPI_GetCRCPolynomial(SPI_TypeDef *SPIx)
-{
- return (uint32_t)(READ_REG(SPIx->CRCPR));
-}
-
-/**
- * @brief Get Rx CRC
- * @rmtoll RXCRCR RXCRC LL_SPI_GetRxCRC
- * @param SPIx SPI Instance
- * @retval Returned value is a number between Min_Data = 0x00 and Max_Data = 0xFFFF
- */
-__STATIC_INLINE uint32_t LL_SPI_GetRxCRC(SPI_TypeDef *SPIx)
-{
- return (uint32_t)(READ_REG(SPIx->RXCRCR));
-}
-
-/**
- * @brief Get Tx CRC
- * @rmtoll TXCRCR TXCRC LL_SPI_GetTxCRC
- * @param SPIx SPI Instance
- * @retval Returned value is a number between Min_Data = 0x00 and Max_Data = 0xFFFF
- */
-__STATIC_INLINE uint32_t LL_SPI_GetTxCRC(SPI_TypeDef *SPIx)
-{
- return (uint32_t)(READ_REG(SPIx->TXCRCR));
-}
-
-/**
- * @}
- */
-
-/** @defgroup SPI_LL_EF_NSS_Management Slave Select Pin Management
- * @{
- */
-
-/**
- * @brief Set NSS mode
- * @note LL_SPI_NSS_SOFT Mode is not used in SPI TI mode.
- * @rmtoll CR1 SSM LL_SPI_SetNSSMode\n
- * @rmtoll CR2 SSOE LL_SPI_SetNSSMode
- * @param SPIx SPI Instance
- * @param NSS This parameter can be one of the following values:
- * @arg @ref LL_SPI_NSS_SOFT
- * @arg @ref LL_SPI_NSS_HARD_INPUT
- * @arg @ref LL_SPI_NSS_HARD_OUTPUT
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_SetNSSMode(SPI_TypeDef *SPIx, uint32_t NSS)
-{
- MODIFY_REG(SPIx->CR1, SPI_CR1_SSM, NSS);
- MODIFY_REG(SPIx->CR2, SPI_CR2_SSOE, ((uint32_t)(NSS >> 16U)));
-}
-
-/**
- * @brief Get NSS mode
- * @rmtoll CR1 SSM LL_SPI_GetNSSMode\n
- * @rmtoll CR2 SSOE LL_SPI_GetNSSMode
- * @param SPIx SPI Instance
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_SPI_NSS_SOFT
- * @arg @ref LL_SPI_NSS_HARD_INPUT
- * @arg @ref LL_SPI_NSS_HARD_OUTPUT
- */
-__STATIC_INLINE uint32_t LL_SPI_GetNSSMode(SPI_TypeDef *SPIx)
-{
- register uint32_t Ssm = (READ_BIT(SPIx->CR1, SPI_CR1_SSM));
- register uint32_t Ssoe = (READ_BIT(SPIx->CR2, SPI_CR2_SSOE) << 16U);
- return (Ssm | Ssoe);
-}
-
-/**
- * @}
- */
-
-/** @defgroup SPI_LL_EF_FLAG_Management FLAG Management
- * @{
- */
-
-/**
- * @brief Check if Rx buffer is not empty
- * @rmtoll SR RXNE LL_SPI_IsActiveFlag_RXNE
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_RXNE(SPI_TypeDef *SPIx)
-{
- return (READ_BIT(SPIx->SR, SPI_SR_RXNE) == (SPI_SR_RXNE));
-}
-
-/**
- * @brief Check if Tx buffer is empty
- * @rmtoll SR TXE LL_SPI_IsActiveFlag_TXE
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_TXE(SPI_TypeDef *SPIx)
-{
- return (READ_BIT(SPIx->SR, SPI_SR_TXE) == (SPI_SR_TXE));
-}
-
-/**
- * @brief Get CRC error flag
- * @rmtoll SR CRCERR LL_SPI_IsActiveFlag_CRCERR
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_CRCERR(SPI_TypeDef *SPIx)
-{
- return (READ_BIT(SPIx->SR, SPI_SR_CRCERR) == (SPI_SR_CRCERR));
-}
-
-/**
- * @brief Get mode fault error flag
- * @rmtoll SR MODF LL_SPI_IsActiveFlag_MODF
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_MODF(SPI_TypeDef *SPIx)
-{
- return (READ_BIT(SPIx->SR, SPI_SR_MODF) == (SPI_SR_MODF));
-}
-
-/**
- * @brief Get overrun error flag
- * @rmtoll SR OVR LL_SPI_IsActiveFlag_OVR
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_OVR(SPI_TypeDef *SPIx)
-{
- return (READ_BIT(SPIx->SR, SPI_SR_OVR) == (SPI_SR_OVR));
-}
-
-/**
- * @brief Get busy flag
- * @note The BSY flag is cleared under any one of the following conditions:
- * -When the SPI is correctly disabled
- * -When a fault is detected in Master mode (MODF bit set to 1)
- * -In Master mode, when it finishes a data transmission and no new data is ready to be
- * sent
- * -In Slave mode, when the BSY flag is set to '0' for at least one SPI clock cycle between
- * each data transfer.
- * @rmtoll SR BSY LL_SPI_IsActiveFlag_BSY
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_BSY(SPI_TypeDef *SPIx)
-{
- return (READ_BIT(SPIx->SR, SPI_SR_BSY) == (SPI_SR_BSY));
-}
-
-
-/**
- * @brief Clear CRC error flag
- * @rmtoll SR CRCERR LL_SPI_ClearFlag_CRCERR
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_ClearFlag_CRCERR(SPI_TypeDef *SPIx)
-{
- CLEAR_BIT(SPIx->SR, SPI_SR_CRCERR);
-}
-
-/**
- * @brief Clear mode fault error flag
- * @note Clearing this flag is done by a read access to the SPIx_SR
- * register followed by a write access to the SPIx_CR1 register
- * @rmtoll SR MODF LL_SPI_ClearFlag_MODF
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_ClearFlag_MODF(SPI_TypeDef *SPIx)
-{
- __IO uint32_t tmpreg;
- tmpreg = SPIx->SR;
- (void) tmpreg;
- tmpreg = CLEAR_BIT(SPIx->CR1, SPI_CR1_SPE);
- (void) tmpreg;
-}
-
-/**
- * @brief Clear overrun error flag
- * @note Clearing this flag is done by a read access to the SPIx_DR
- * register followed by a read access to the SPIx_SR register
- * @rmtoll SR OVR LL_SPI_ClearFlag_OVR
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_ClearFlag_OVR(SPI_TypeDef *SPIx)
-{
- __IO uint32_t tmpreg;
- tmpreg = SPIx->DR;
- (void) tmpreg;
- tmpreg = SPIx->SR;
- (void) tmpreg;
-}
-
-
-/**
- * @}
- */
-
-/** @defgroup SPI_LL_EF_IT_Management Interrupt Management
- * @{
- */
-
-/**
- * @brief Enable error interrupt
- * @note This bit controls the generation of an interrupt when an error condition occurs (CRCERR, OVR, MODF in SPI mode, FRE at TI mode).
- * @rmtoll CR2 ERRIE LL_SPI_EnableIT_ERR
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_EnableIT_ERR(SPI_TypeDef *SPIx)
-{
- SET_BIT(SPIx->CR2, SPI_CR2_ERRIE);
-}
-
-/**
- * @brief Enable Rx buffer not empty interrupt
- * @rmtoll CR2 RXNEIE LL_SPI_EnableIT_RXNE
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_EnableIT_RXNE(SPI_TypeDef *SPIx)
-{
- SET_BIT(SPIx->CR2, SPI_CR2_RXNEIE);
-}
-
-/**
- * @brief Enable Tx buffer empty interrupt
- * @rmtoll CR2 TXEIE LL_SPI_EnableIT_TXE
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_EnableIT_TXE(SPI_TypeDef *SPIx)
-{
- SET_BIT(SPIx->CR2, SPI_CR2_TXEIE);
-}
-
-/**
- * @brief Disable error interrupt
- * @note This bit controls the generation of an interrupt when an error condition occurs (CRCERR, OVR, MODF in SPI mode, FRE at TI mode).
- * @rmtoll CR2 ERRIE LL_SPI_DisableIT_ERR
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_DisableIT_ERR(SPI_TypeDef *SPIx)
-{
- CLEAR_BIT(SPIx->CR2, SPI_CR2_ERRIE);
-}
-
-/**
- * @brief Disable Rx buffer not empty interrupt
- * @rmtoll CR2 RXNEIE LL_SPI_DisableIT_RXNE
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_DisableIT_RXNE(SPI_TypeDef *SPIx)
-{
- CLEAR_BIT(SPIx->CR2, SPI_CR2_RXNEIE);
-}
-
-/**
- * @brief Disable Tx buffer empty interrupt
- * @rmtoll CR2 TXEIE LL_SPI_DisableIT_TXE
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_DisableIT_TXE(SPI_TypeDef *SPIx)
-{
- CLEAR_BIT(SPIx->CR2, SPI_CR2_TXEIE);
-}
-
-/**
- * @brief Check if error interrupt is enabled
- * @rmtoll CR2 ERRIE LL_SPI_IsEnabledIT_ERR
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_ERR(SPI_TypeDef *SPIx)
-{
- return (READ_BIT(SPIx->CR2, SPI_CR2_ERRIE) == (SPI_CR2_ERRIE));
-}
-
-/**
- * @brief Check if Rx buffer not empty interrupt is enabled
- * @rmtoll CR2 RXNEIE LL_SPI_IsEnabledIT_RXNE
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_RXNE(SPI_TypeDef *SPIx)
-{
- return (READ_BIT(SPIx->CR2, SPI_CR2_RXNEIE) == (SPI_CR2_RXNEIE));
-}
-
-/**
- * @brief Check if Tx buffer empty interrupt
- * @rmtoll CR2 TXEIE LL_SPI_IsEnabledIT_TXE
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_TXE(SPI_TypeDef *SPIx)
-{
- return (READ_BIT(SPIx->CR2, SPI_CR2_TXEIE) == (SPI_CR2_TXEIE));
-}
-
-/**
- * @}
- */
-
-/** @defgroup SPI_LL_EF_DMA_Management DMA Management
- * @{
- */
-
-/**
- * @brief Enable DMA Rx
- * @rmtoll CR2 RXDMAEN LL_SPI_EnableDMAReq_RX
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_EnableDMAReq_RX(SPI_TypeDef *SPIx)
-{
- SET_BIT(SPIx->CR2, SPI_CR2_RXDMAEN);
-}
-
-/**
- * @brief Disable DMA Rx
- * @rmtoll CR2 RXDMAEN LL_SPI_DisableDMAReq_RX
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_DisableDMAReq_RX(SPI_TypeDef *SPIx)
-{
- CLEAR_BIT(SPIx->CR2, SPI_CR2_RXDMAEN);
-}
-
-/**
- * @brief Check if DMA Rx is enabled
- * @rmtoll CR2 RXDMAEN LL_SPI_IsEnabledDMAReq_RX
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_SPI_IsEnabledDMAReq_RX(SPI_TypeDef *SPIx)
-{
- return (READ_BIT(SPIx->CR2, SPI_CR2_RXDMAEN) == (SPI_CR2_RXDMAEN));
-}
-
-/**
- * @brief Enable DMA Tx
- * @rmtoll CR2 TXDMAEN LL_SPI_EnableDMAReq_TX
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_EnableDMAReq_TX(SPI_TypeDef *SPIx)
-{
- SET_BIT(SPIx->CR2, SPI_CR2_TXDMAEN);
-}
-
-/**
- * @brief Disable DMA Tx
- * @rmtoll CR2 TXDMAEN LL_SPI_DisableDMAReq_TX
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_DisableDMAReq_TX(SPI_TypeDef *SPIx)
-{
- CLEAR_BIT(SPIx->CR2, SPI_CR2_TXDMAEN);
-}
-
-/**
- * @brief Check if DMA Tx is enabled
- * @rmtoll CR2 TXDMAEN LL_SPI_IsEnabledDMAReq_TX
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_SPI_IsEnabledDMAReq_TX(SPI_TypeDef *SPIx)
-{
- return (READ_BIT(SPIx->CR2, SPI_CR2_TXDMAEN) == (SPI_CR2_TXDMAEN));
-}
-
-/**
- * @brief Get the data register address used for DMA transfer
- * @rmtoll DR DR LL_SPI_DMA_GetRegAddr
- * @param SPIx SPI Instance
- * @retval Address of data register
- */
-__STATIC_INLINE uint32_t LL_SPI_DMA_GetRegAddr(SPI_TypeDef *SPIx)
-{
- return (uint32_t) & (SPIx->DR);
-}
-
-/**
- * @}
- */
-
-/** @defgroup SPI_LL_EF_DATA_Management DATA Management
- * @{
- */
-
-/**
- * @brief Read 8-Bits in the data register
- * @rmtoll DR DR LL_SPI_ReceiveData8
- * @param SPIx SPI Instance
- * @retval RxData Value between Min_Data=0x00 and Max_Data=0xFF
- */
-__STATIC_INLINE uint8_t LL_SPI_ReceiveData8(SPI_TypeDef *SPIx)
-{
- return (uint8_t)(READ_REG(SPIx->DR));
-}
-
-/**
- * @brief Read 16-Bits in the data register
- * @rmtoll DR DR LL_SPI_ReceiveData16
- * @param SPIx SPI Instance
- * @retval RxData Value between Min_Data=0x00 and Max_Data=0xFFFF
- */
-__STATIC_INLINE uint16_t LL_SPI_ReceiveData16(SPI_TypeDef *SPIx)
-{
- return (uint16_t)(READ_REG(SPIx->DR));
-}
-
-/**
- * @brief Write 8-Bits in the data register
- * @rmtoll DR DR LL_SPI_TransmitData8
- * @param SPIx SPI Instance
- * @param TxData Value between Min_Data=0x00 and Max_Data=0xFF
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_TransmitData8(SPI_TypeDef *SPIx, uint8_t TxData)
-{
- SPIx->DR = TxData;
-}
-
-/**
- * @brief Write 16-Bits in the data register
- * @rmtoll DR DR LL_SPI_TransmitData16
- * @param SPIx SPI Instance
- * @param TxData Value between Min_Data=0x00 and Max_Data=0xFFFF
- * @retval None
- */
-__STATIC_INLINE void LL_SPI_TransmitData16(SPI_TypeDef *SPIx, uint16_t TxData)
-{
- SPIx->DR = TxData;
-}
-
-/**
- * @}
- */
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup SPI_LL_EF_Init Initialization and de-initialization functions
- * @{
- */
-
-ErrorStatus LL_SPI_DeInit(SPI_TypeDef *SPIx);
-ErrorStatus LL_SPI_Init(SPI_TypeDef *SPIx, LL_SPI_InitTypeDef *SPI_InitStruct);
-void LL_SPI_StructInit(LL_SPI_InitTypeDef *SPI_InitStruct);
-
-/**
- * @}
- */
-#endif /* USE_FULL_LL_DRIVER */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#if defined(SPI_I2S_SUPPORT)
-/** @defgroup I2S_LL I2S
- * @{
- */
-
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-
-/* Exported types ------------------------------------------------------------*/
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup I2S_LL_ES_INIT I2S Exported Init structure
- * @{
- */
-
-/**
- * @brief I2S Init structure definition
- */
-
-typedef struct
-{
- uint32_t Mode; /*!< Specifies the I2S operating mode.
- This parameter can be a value of @ref I2S_LL_EC_MODE
-
- This feature can be modified afterwards using unitary function @ref LL_I2S_SetTransferMode().*/
-
- uint32_t Standard; /*!< Specifies the standard used for the I2S communication.
- This parameter can be a value of @ref I2S_LL_EC_STANDARD
-
- This feature can be modified afterwards using unitary function @ref LL_I2S_SetStandard().*/
-
-
- uint32_t DataFormat; /*!< Specifies the data format for the I2S communication.
- This parameter can be a value of @ref I2S_LL_EC_DATA_FORMAT
-
- This feature can be modified afterwards using unitary function @ref LL_I2S_SetDataFormat().*/
-
-
- uint32_t MCLKOutput; /*!< Specifies whether the I2S MCLK output is enabled or not.
- This parameter can be a value of @ref I2S_LL_EC_MCLK_OUTPUT
-
- This feature can be modified afterwards using unitary functions @ref LL_I2S_EnableMasterClock() or @ref LL_I2S_DisableMasterClock.*/
-
-
- uint32_t AudioFreq; /*!< Specifies the frequency selected for the I2S communication.
- This parameter can be a value of @ref I2S_LL_EC_AUDIO_FREQ
-
- Audio Frequency can be modified afterwards using Reference manual formulas to calculate Prescaler Linear, Parity
- and unitary functions @ref LL_I2S_SetPrescalerLinear() and @ref LL_I2S_SetPrescalerParity() to set it.*/
-
-
- uint32_t ClockPolarity; /*!< Specifies the idle state of the I2S clock.
- This parameter can be a value of @ref I2S_LL_EC_POLARITY
-
- This feature can be modified afterwards using unitary function @ref LL_I2S_SetClockPolarity().*/
-
-} LL_I2S_InitTypeDef;
-
-/**
- * @}
- */
-#endif /*USE_FULL_LL_DRIVER*/
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup I2S_LL_Exported_Constants I2S Exported Constants
- * @{
- */
-
-/** @defgroup I2S_LL_EC_GET_FLAG Get Flags Defines
- * @brief Flags defines which can be used with LL_I2S_ReadReg function
- * @{
- */
-#define LL_I2S_SR_RXNE LL_SPI_SR_RXNE /*!< Rx buffer not empty flag */
-#define LL_I2S_SR_TXE LL_SPI_SR_TXE /*!< Tx buffer empty flag */
-#define LL_I2S_SR_BSY LL_SPI_SR_BSY /*!< Busy flag */
-#define LL_I2S_SR_UDR SPI_SR_UDR /*!< Underrun flag */
-#define LL_I2S_SR_OVR LL_SPI_SR_OVR /*!< Overrun flag */
-#define LL_I2S_SR_FRE LL_SPI_SR_FRE /*!< TI mode frame format error flag */
-/**
- * @}
- */
-
-/** @defgroup SPI_LL_EC_IT IT Defines
- * @brief IT defines which can be used with LL_SPI_ReadReg and LL_SPI_WriteReg functions
- * @{
- */
-#define LL_I2S_CR2_RXNEIE LL_SPI_CR2_RXNEIE /*!< Rx buffer not empty interrupt enable */
-#define LL_I2S_CR2_TXEIE LL_SPI_CR2_TXEIE /*!< Tx buffer empty interrupt enable */
-#define LL_I2S_CR2_ERRIE LL_SPI_CR2_ERRIE /*!< Error interrupt enable */
-/**
- * @}
- */
-
-/** @defgroup I2S_LL_EC_DATA_FORMAT Data format
- * @{
- */
-#define LL_I2S_DATAFORMAT_16B 0x00000000U /*!< Data length 16 bits, Channel lenght 16bit */
-#define LL_I2S_DATAFORMAT_16B_EXTENDED (SPI_I2SCFGR_CHLEN) /*!< Data length 16 bits, Channel lenght 32bit */
-#define LL_I2S_DATAFORMAT_24B (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN_0) /*!< Data length 24 bits, Channel lenght 32bit */
-#define LL_I2S_DATAFORMAT_32B (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN_1) /*!< Data length 16 bits, Channel lenght 32bit */
-/**
- * @}
- */
-
-/** @defgroup I2S_LL_EC_POLARITY Clock Polarity
- * @{
- */
-#define LL_I2S_POLARITY_LOW 0x00000000U /*!< Clock steady state is low level */
-#define LL_I2S_POLARITY_HIGH (SPI_I2SCFGR_CKPOL) /*!< Clock steady state is high level */
-/**
- * @}
- */
-
-/** @defgroup I2S_LL_EC_STANDARD I2s Standard
- * @{
- */
-#define LL_I2S_STANDARD_PHILIPS 0x00000000U /*!< I2S standard philips */
-#define LL_I2S_STANDARD_MSB (SPI_I2SCFGR_I2SSTD_0) /*!< MSB justified standard (left justified) */
-#define LL_I2S_STANDARD_LSB (SPI_I2SCFGR_I2SSTD_1) /*!< LSB justified standard (right justified) */
-#define LL_I2S_STANDARD_PCM_SHORT (SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1) /*!< PCM standard, short frame synchronization */
-#define LL_I2S_STANDARD_PCM_LONG (SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1 | SPI_I2SCFGR_PCMSYNC) /*!< PCM standard, long frame synchronization */
-/**
- * @}
- */
-
-/** @defgroup I2S_LL_EC_MODE Operation Mode
- * @{
- */
-#define LL_I2S_MODE_SLAVE_TX 0x00000000U /*!< Slave Tx configuration */
-#define LL_I2S_MODE_SLAVE_RX (SPI_I2SCFGR_I2SCFG_0) /*!< Slave Rx configuration */
-#define LL_I2S_MODE_MASTER_TX (SPI_I2SCFGR_I2SCFG_1) /*!< Master Tx configuration */
-#define LL_I2S_MODE_MASTER_RX (SPI_I2SCFGR_I2SCFG_0 | SPI_I2SCFGR_I2SCFG_1) /*!< Master Rx configuration */
-/**
- * @}
- */
-
-/** @defgroup I2S_LL_EC_PRESCALER_FACTOR Prescaler Factor
- * @{
- */
-#define LL_I2S_PRESCALER_PARITY_EVEN 0x00000000U /*!< Odd factor: Real divider value is = I2SDIV * 2 */
-#define LL_I2S_PRESCALER_PARITY_ODD (SPI_I2SPR_ODD >> 8U) /*!< Odd factor: Real divider value is = (I2SDIV * 2)+1 */
-/**
- * @}
- */
-
-#if defined(USE_FULL_LL_DRIVER)
-
-/** @defgroup I2S_LL_EC_MCLK_OUTPUT MCLK Output
- * @{
- */
-#define LL_I2S_MCLK_OUTPUT_DISABLE 0x00000000U /*!< Master clock output is disabled */
-#define LL_I2S_MCLK_OUTPUT_ENABLE (SPI_I2SPR_MCKOE) /*!< Master clock output is enabled */
-/**
- * @}
- */
-
-/** @defgroup I2S_LL_EC_AUDIO_FREQ Audio Frequency
- * @{
- */
-
-#define LL_I2S_AUDIOFREQ_192K 192000U /*!< Audio Frequency configuration 192000 Hz */
-#define LL_I2S_AUDIOFREQ_96K 96000U /*!< Audio Frequency configuration 96000 Hz */
-#define LL_I2S_AUDIOFREQ_48K 48000U /*!< Audio Frequency configuration 48000 Hz */
-#define LL_I2S_AUDIOFREQ_44K 44100U /*!< Audio Frequency configuration 44100 Hz */
-#define LL_I2S_AUDIOFREQ_32K 32000U /*!< Audio Frequency configuration 32000 Hz */
-#define LL_I2S_AUDIOFREQ_22K 22050U /*!< Audio Frequency configuration 22050 Hz */
-#define LL_I2S_AUDIOFREQ_16K 16000U /*!< Audio Frequency configuration 16000 Hz */
-#define LL_I2S_AUDIOFREQ_11K 11025U /*!< Audio Frequency configuration 11025 Hz */
-#define LL_I2S_AUDIOFREQ_8K 8000U /*!< Audio Frequency configuration 8000 Hz */
-#define LL_I2S_AUDIOFREQ_DEFAULT 2U /*!< Audio Freq not specified. Register I2SDIV = 2 */
-/**
- * @}
- */
-#endif /* USE_FULL_LL_DRIVER */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup I2S_LL_Exported_Macros I2S Exported Macros
- * @{
- */
-
-/** @defgroup I2S_LL_EM_WRITE_READ Common Write and read registers Macros
- * @{
- */
-
-/**
- * @brief Write a value in I2S register
- * @param __INSTANCE__ I2S Instance
- * @param __REG__ Register to be written
- * @param __VALUE__ Value to be written in the register
- * @retval None
- */
-#define LL_I2S_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
-
-/**
- * @brief Read a value in I2S register
- * @param __INSTANCE__ I2S Instance
- * @param __REG__ Register to be read
- * @retval Register value
- */
-#define LL_I2S_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-
-/* Exported functions --------------------------------------------------------*/
-
-/** @defgroup I2S_LL_Exported_Functions I2S Exported Functions
- * @{
- */
-
-/** @defgroup I2S_LL_EF_Configuration Configuration
- * @{
- */
-
-/**
- * @brief Select I2S mode and Enable I2S peripheral
- * @rmtoll I2SCFGR I2SMOD LL_I2S_Enable\n
- * I2SCFGR I2SE LL_I2S_Enable
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_Enable(SPI_TypeDef *SPIx)
-{
- SET_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SE);
-}
-
-/**
- * @brief Disable I2S peripheral
- * @rmtoll I2SCFGR I2SE LL_I2S_Disable
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_Disable(SPI_TypeDef *SPIx)
-{
- CLEAR_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SE);
-}
-
-/**
- * @brief Check if I2S peripheral is enabled
- * @rmtoll I2SCFGR I2SE LL_I2S_IsEnabled
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2S_IsEnabled(SPI_TypeDef *SPIx)
-{
- return (READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SE) == (SPI_I2SCFGR_I2SE));
-}
-
-/**
- * @brief Set I2S data frame length
- * @rmtoll I2SCFGR DATLEN LL_I2S_SetDataFormat\n
- * I2SCFGR CHLEN LL_I2S_SetDataFormat
- * @param SPIx SPI Instance
- * @param DataFormat This parameter can be one of the following values:
- * @arg @ref LL_I2S_DATAFORMAT_16B
- * @arg @ref LL_I2S_DATAFORMAT_16B_EXTENDED
- * @arg @ref LL_I2S_DATAFORMAT_24B
- * @arg @ref LL_I2S_DATAFORMAT_32B
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_SetDataFormat(SPI_TypeDef *SPIx, uint32_t DataFormat)
-{
- MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN, DataFormat);
-}
-
-/**
- * @brief Get I2S data frame length
- * @rmtoll I2SCFGR DATLEN LL_I2S_GetDataFormat\n
- * I2SCFGR CHLEN LL_I2S_GetDataFormat
- * @param SPIx SPI Instance
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_I2S_DATAFORMAT_16B
- * @arg @ref LL_I2S_DATAFORMAT_16B_EXTENDED
- * @arg @ref LL_I2S_DATAFORMAT_24B
- * @arg @ref LL_I2S_DATAFORMAT_32B
- */
-__STATIC_INLINE uint32_t LL_I2S_GetDataFormat(SPI_TypeDef *SPIx)
-{
- return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN));
-}
-
-/**
- * @brief Set I2S clock polarity
- * @rmtoll I2SCFGR CKPOL LL_I2S_SetClockPolarity
- * @param SPIx SPI Instance
- * @param ClockPolarity This parameter can be one of the following values:
- * @arg @ref LL_I2S_POLARITY_LOW
- * @arg @ref LL_I2S_POLARITY_HIGH
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_SetClockPolarity(SPI_TypeDef *SPIx, uint32_t ClockPolarity)
-{
- SET_BIT(SPIx->I2SCFGR, ClockPolarity);
-}
-
-/**
- * @brief Get I2S clock polarity
- * @rmtoll I2SCFGR CKPOL LL_I2S_GetClockPolarity
- * @param SPIx SPI Instance
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_I2S_POLARITY_LOW
- * @arg @ref LL_I2S_POLARITY_HIGH
- */
-__STATIC_INLINE uint32_t LL_I2S_GetClockPolarity(SPI_TypeDef *SPIx)
-{
- return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_CKPOL));
-}
-
-/**
- * @brief Set I2S standard protocol
- * @rmtoll I2SCFGR I2SSTD LL_I2S_SetStandard\n
- * I2SCFGR PCMSYNC LL_I2S_SetStandard
- * @param SPIx SPI Instance
- * @param Standard This parameter can be one of the following values:
- * @arg @ref LL_I2S_STANDARD_PHILIPS
- * @arg @ref LL_I2S_STANDARD_MSB
- * @arg @ref LL_I2S_STANDARD_LSB
- * @arg @ref LL_I2S_STANDARD_PCM_SHORT
- * @arg @ref LL_I2S_STANDARD_PCM_LONG
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_SetStandard(SPI_TypeDef *SPIx, uint32_t Standard)
-{
- MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC, Standard);
-}
-
-/**
- * @brief Get I2S standard protocol
- * @rmtoll I2SCFGR I2SSTD LL_I2S_GetStandard\n
- * I2SCFGR PCMSYNC LL_I2S_GetStandard
- * @param SPIx SPI Instance
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_I2S_STANDARD_PHILIPS
- * @arg @ref LL_I2S_STANDARD_MSB
- * @arg @ref LL_I2S_STANDARD_LSB
- * @arg @ref LL_I2S_STANDARD_PCM_SHORT
- * @arg @ref LL_I2S_STANDARD_PCM_LONG
- */
-__STATIC_INLINE uint32_t LL_I2S_GetStandard(SPI_TypeDef *SPIx)
-{
- return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC));
-}
-
-/**
- * @brief Set I2S transfer mode
- * @rmtoll I2SCFGR I2SCFG LL_I2S_SetTransferMode
- * @param SPIx SPI Instance
- * @param Mode This parameter can be one of the following values:
- * @arg @ref LL_I2S_MODE_SLAVE_TX
- * @arg @ref LL_I2S_MODE_SLAVE_RX
- * @arg @ref LL_I2S_MODE_MASTER_TX
- * @arg @ref LL_I2S_MODE_MASTER_RX
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_SetTransferMode(SPI_TypeDef *SPIx, uint32_t Mode)
-{
- MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_I2SCFG, Mode);
-}
-
-/**
- * @brief Get I2S transfer mode
- * @rmtoll I2SCFGR I2SCFG LL_I2S_GetTransferMode
- * @param SPIx SPI Instance
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_I2S_MODE_SLAVE_TX
- * @arg @ref LL_I2S_MODE_SLAVE_RX
- * @arg @ref LL_I2S_MODE_MASTER_TX
- * @arg @ref LL_I2S_MODE_MASTER_RX
- */
-__STATIC_INLINE uint32_t LL_I2S_GetTransferMode(SPI_TypeDef *SPIx)
-{
- return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SCFG));
-}
-
-/**
- * @brief Set I2S linear prescaler
- * @rmtoll I2SPR I2SDIV LL_I2S_SetPrescalerLinear
- * @param SPIx SPI Instance
- * @param PrescalerLinear Value between Min_Data=0x02 and Max_Data=0xFF
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_SetPrescalerLinear(SPI_TypeDef *SPIx, uint8_t PrescalerLinear)
-{
- MODIFY_REG(SPIx->I2SPR, SPI_I2SPR_I2SDIV, PrescalerLinear);
-}
-
-/**
- * @brief Get I2S linear prescaler
- * @rmtoll I2SPR I2SDIV LL_I2S_GetPrescalerLinear
- * @param SPIx SPI Instance
- * @retval PrescalerLinear Value between Min_Data=0x02 and Max_Data=0xFF
- */
-__STATIC_INLINE uint32_t LL_I2S_GetPrescalerLinear(SPI_TypeDef *SPIx)
-{
- return (uint32_t)(READ_BIT(SPIx->I2SPR, SPI_I2SPR_I2SDIV));
-}
-
-/**
- * @brief Set I2S parity prescaler
- * @rmtoll I2SPR ODD LL_I2S_SetPrescalerParity
- * @param SPIx SPI Instance
- * @param PrescalerParity This parameter can be one of the following values:
- * @arg @ref LL_I2S_PRESCALER_PARITY_EVEN
- * @arg @ref LL_I2S_PRESCALER_PARITY_ODD
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_SetPrescalerParity(SPI_TypeDef *SPIx, uint32_t PrescalerParity)
-{
- MODIFY_REG(SPIx->I2SPR, SPI_I2SPR_ODD, PrescalerParity << 8U);
-}
-
-/**
- * @brief Get I2S parity prescaler
- * @rmtoll I2SPR ODD LL_I2S_GetPrescalerParity
- * @param SPIx SPI Instance
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_I2S_PRESCALER_PARITY_EVEN
- * @arg @ref LL_I2S_PRESCALER_PARITY_ODD
- */
-__STATIC_INLINE uint32_t LL_I2S_GetPrescalerParity(SPI_TypeDef *SPIx)
-{
- return (uint32_t)(READ_BIT(SPIx->I2SPR, SPI_I2SPR_ODD) >> 8U);
-}
-
-/**
- * @brief Enable the master clock ouput (Pin MCK)
- * @rmtoll I2SPR MCKOE LL_I2S_EnableMasterClock
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_EnableMasterClock(SPI_TypeDef *SPIx)
-{
- SET_BIT(SPIx->I2SPR, SPI_I2SPR_MCKOE);
-}
-
-/**
- * @brief Disable the master clock ouput (Pin MCK)
- * @rmtoll I2SPR MCKOE LL_I2S_DisableMasterClock
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_DisableMasterClock(SPI_TypeDef *SPIx)
-{
- CLEAR_BIT(SPIx->I2SPR, SPI_I2SPR_MCKOE);
-}
-
-/**
- * @brief Check if the master clock ouput (Pin MCK) is enabled
- * @rmtoll I2SPR MCKOE LL_I2S_IsEnabledMasterClock
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2S_IsEnabledMasterClock(SPI_TypeDef *SPIx)
-{
- return (READ_BIT(SPIx->I2SPR, SPI_I2SPR_MCKOE) == (SPI_I2SPR_MCKOE));
-}
-
-/**
- * @}
- */
-
-/** @defgroup I2S_LL_EF_FLAG FLAG Management
- * @{
- */
-
-/**
- * @brief Check if Rx buffer is not empty
- * @rmtoll SR RXNE LL_I2S_IsActiveFlag_RXNE
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_RXNE(SPI_TypeDef *SPIx)
-{
- return LL_SPI_IsActiveFlag_RXNE(SPIx);
-}
-
-/**
- * @brief Check if Tx buffer is empty
- * @rmtoll SR TXE LL_I2S_IsActiveFlag_TXE
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_TXE(SPI_TypeDef *SPIx)
-{
- return LL_SPI_IsActiveFlag_TXE(SPIx);
-}
-
-/**
- * @brief Get busy flag
- * @rmtoll SR BSY LL_I2S_IsActiveFlag_BSY
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_BSY(SPI_TypeDef *SPIx)
-{
- return LL_SPI_IsActiveFlag_BSY(SPIx);
-}
-
-/**
- * @brief Get overrun error flag
- * @rmtoll SR OVR LL_I2S_IsActiveFlag_OVR
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_OVR(SPI_TypeDef *SPIx)
-{
- return LL_SPI_IsActiveFlag_OVR(SPIx);
-}
-
-/**
- * @brief Get underrun error flag
- * @rmtoll SR UDR LL_I2S_IsActiveFlag_UDR
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_UDR(SPI_TypeDef *SPIx)
-{
- return (READ_BIT(SPIx->SR, SPI_SR_UDR) == (SPI_SR_UDR));
-}
-
-/**
- * @brief Get channel side flag.
- * @note 0: Channel Left has to be transmitted or has been received\n
- * 1: Channel Right has to be transmitted or has been received\n
- * It has no significance in PCM mode.
- * @rmtoll SR CHSIDE LL_I2S_IsActiveFlag_CHSIDE
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_CHSIDE(SPI_TypeDef *SPIx)
-{
- return (READ_BIT(SPIx->SR, SPI_SR_CHSIDE) == (SPI_SR_CHSIDE));
-}
-
-/**
- * @brief Clear overrun error flag
- * @rmtoll SR OVR LL_I2S_ClearFlag_OVR
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_ClearFlag_OVR(SPI_TypeDef *SPIx)
-{
- LL_SPI_ClearFlag_OVR(SPIx);
-}
-
-/**
- * @brief Clear underrun error flag
- * @rmtoll SR UDR LL_I2S_ClearFlag_UDR
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_ClearFlag_UDR(SPI_TypeDef *SPIx)
-{
- __IO uint32_t tmpreg;
- tmpreg = SPIx->SR;
- (void)tmpreg;
-}
-
-/**
- * @}
- */
-
-/** @defgroup I2S_LL_EF_IT Interrupt Management
- * @{
- */
-
-/**
- * @brief Enable error IT
- * @note This bit controls the generation of an interrupt when an error condition occurs (OVR, UDR and FRE in I2S mode).
- * @rmtoll CR2 ERRIE LL_I2S_EnableIT_ERR
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_EnableIT_ERR(SPI_TypeDef *SPIx)
-{
- LL_SPI_EnableIT_ERR(SPIx);
-}
-
-/**
- * @brief Enable Rx buffer not empty IT
- * @rmtoll CR2 RXNEIE LL_I2S_EnableIT_RXNE
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_EnableIT_RXNE(SPI_TypeDef *SPIx)
-{
- LL_SPI_EnableIT_RXNE(SPIx);
-}
-
-/**
- * @brief Enable Tx buffer empty IT
- * @rmtoll CR2 TXEIE LL_I2S_EnableIT_TXE
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_EnableIT_TXE(SPI_TypeDef *SPIx)
-{
- LL_SPI_EnableIT_TXE(SPIx);
-}
-
-/**
- * @brief Disable error IT
- * @note This bit controls the generation of an interrupt when an error condition occurs (OVR, UDR and FRE in I2S mode).
- * @rmtoll CR2 ERRIE LL_I2S_DisableIT_ERR
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_DisableIT_ERR(SPI_TypeDef *SPIx)
-{
- LL_SPI_DisableIT_ERR(SPIx);
-}
-
-/**
- * @brief Disable Rx buffer not empty IT
- * @rmtoll CR2 RXNEIE LL_I2S_DisableIT_RXNE
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_DisableIT_RXNE(SPI_TypeDef *SPIx)
-{
- LL_SPI_DisableIT_RXNE(SPIx);
-}
-
-/**
- * @brief Disable Tx buffer empty IT
- * @rmtoll CR2 TXEIE LL_I2S_DisableIT_TXE
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_DisableIT_TXE(SPI_TypeDef *SPIx)
-{
- LL_SPI_DisableIT_TXE(SPIx);
-}
-
-/**
- * @brief Check if ERR IT is enabled
- * @rmtoll CR2 ERRIE LL_I2S_IsEnabledIT_ERR
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_ERR(SPI_TypeDef *SPIx)
-{
- return LL_SPI_IsEnabledIT_ERR(SPIx);
-}
-
-/**
- * @brief Check if RXNE IT is enabled
- * @rmtoll CR2 RXNEIE LL_I2S_IsEnabledIT_RXNE
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_RXNE(SPI_TypeDef *SPIx)
-{
- return LL_SPI_IsEnabledIT_RXNE(SPIx);
-}
-
-/**
- * @brief Check if TXE IT is enabled
- * @rmtoll CR2 TXEIE LL_I2S_IsEnabledIT_TXE
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_TXE(SPI_TypeDef *SPIx)
-{
- return LL_SPI_IsEnabledIT_TXE(SPIx);
-}
-
-/**
- * @}
- */
-
-/** @defgroup I2S_LL_EF_DMA DMA Management
- * @{
- */
-
-/**
- * @brief Enable DMA Rx
- * @rmtoll CR2 RXDMAEN LL_I2S_EnableDMAReq_RX
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_EnableDMAReq_RX(SPI_TypeDef *SPIx)
-{
- LL_SPI_EnableDMAReq_RX(SPIx);
-}
-
-/**
- * @brief Disable DMA Rx
- * @rmtoll CR2 RXDMAEN LL_I2S_DisableDMAReq_RX
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_DisableDMAReq_RX(SPI_TypeDef *SPIx)
-{
- LL_SPI_DisableDMAReq_RX(SPIx);
-}
-
-/**
- * @brief Check if DMA Rx is enabled
- * @rmtoll CR2 RXDMAEN LL_I2S_IsEnabledDMAReq_RX
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2S_IsEnabledDMAReq_RX(SPI_TypeDef *SPIx)
-{
- return LL_SPI_IsEnabledDMAReq_RX(SPIx);
-}
-
-/**
- * @brief Enable DMA Tx
- * @rmtoll CR2 TXDMAEN LL_I2S_EnableDMAReq_TX
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_EnableDMAReq_TX(SPI_TypeDef *SPIx)
-{
- LL_SPI_EnableDMAReq_TX(SPIx);
-}
-
-/**
- * @brief Disable DMA Tx
- * @rmtoll CR2 TXDMAEN LL_I2S_DisableDMAReq_TX
- * @param SPIx SPI Instance
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_DisableDMAReq_TX(SPI_TypeDef *SPIx)
-{
- LL_SPI_DisableDMAReq_TX(SPIx);
-}
-
-/**
- * @brief Check if DMA Tx is enabled
- * @rmtoll CR2 TXDMAEN LL_I2S_IsEnabledDMAReq_TX
- * @param SPIx SPI Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_I2S_IsEnabledDMAReq_TX(SPI_TypeDef *SPIx)
-{
- return LL_SPI_IsEnabledDMAReq_TX(SPIx);
-}
-
-/**
- * @}
- */
-
-/** @defgroup I2S_LL_EF_DATA DATA Management
- * @{
- */
-
-/**
- * @brief Read 16-Bits in data register
- * @rmtoll DR DR LL_I2S_ReceiveData16
- * @param SPIx SPI Instance
- * @retval RxData Value between Min_Data=0x0000 and Max_Data=0xFFFF
- */
-__STATIC_INLINE uint16_t LL_I2S_ReceiveData16(SPI_TypeDef *SPIx)
-{
- return LL_SPI_ReceiveData16(SPIx);
-}
-
-/**
- * @brief Write 16-Bits in data register
- * @rmtoll DR DR LL_I2S_TransmitData16
- * @param SPIx SPI Instance
- * @param TxData Value between Min_Data=0x0000 and Max_Data=0xFFFF
- * @retval None
- */
-__STATIC_INLINE void LL_I2S_TransmitData16(SPI_TypeDef *SPIx, uint16_t TxData)
-{
- LL_SPI_TransmitData16(SPIx, TxData);
-}
-
-/**
- * @}
- */
-
-#if defined(USE_FULL_LL_DRIVER)
-/** @defgroup I2S_LL_EF_Init Initialization and de-initialization functions
- * @{
- */
-
-ErrorStatus LL_I2S_DeInit(SPI_TypeDef *SPIx);
-ErrorStatus LL_I2S_Init(SPI_TypeDef *SPIx, LL_I2S_InitTypeDef *I2S_InitStruct);
-void LL_I2S_StructInit(LL_I2S_InitTypeDef *I2S_InitStruct);
-void LL_I2S_ConfigPrescaler(SPI_TypeDef *SPIx, uint32_t PrescalerLinear, uint32_t PrescalerParity);
-
-/**
- * @}
- */
-#endif /* USE_FULL_LL_DRIVER */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-#endif /* SPI_I2S_SUPPORT */
-
-#endif /* defined (SPI1) || defined (SPI2) || defined (SPI3) */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_LL_SPI_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_system.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_system.h
deleted file mode 100644
index d7583f1..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_system.h
+++ /dev/null
@@ -1,590 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_system.h
- * @author MCD Application Team
- * @brief Header file of SYSTEM LL module.
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- The LL SYSTEM driver contains a set of generic APIs that can be
- used by user:
- (+) Some of the FLASH features need to be handled in the SYSTEM file.
- (+) Access to DBGCMU registers
- (+) Access to SYSCFG registers
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_LL_SYSTEM_H
-#define __STM32F1xx_LL_SYSTEM_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx.h"
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined (FLASH) || defined (DBGMCU)
-
-/** @defgroup SYSTEM_LL SYSTEM
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup SYSTEM_LL_Private_Constants SYSTEM Private Constants
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-
-/* Exported types ------------------------------------------------------------*/
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup SYSTEM_LL_Exported_Constants SYSTEM Exported Constants
- * @{
- */
-
-
-
-/** @defgroup SYSTEM_LL_EC_TRACE DBGMCU TRACE Pin Assignment
- * @{
- */
-#define LL_DBGMCU_TRACE_NONE 0x00000000U /*!< TRACE pins not assigned (default state) */
-#define LL_DBGMCU_TRACE_ASYNCH DBGMCU_CR_TRACE_IOEN /*!< TRACE pin assignment for Asynchronous Mode */
-#define LL_DBGMCU_TRACE_SYNCH_SIZE1 (DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE_0) /*!< TRACE pin assignment for Synchronous Mode with a TRACEDATA size of 1 */
-#define LL_DBGMCU_TRACE_SYNCH_SIZE2 (DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE_1) /*!< TRACE pin assignment for Synchronous Mode with a TRACEDATA size of 2 */
-#define LL_DBGMCU_TRACE_SYNCH_SIZE4 (DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE) /*!< TRACE pin assignment for Synchronous Mode with a TRACEDATA size of 4 */
-/**
- * @}
- */
-
-/** @defgroup SYSTEM_LL_EC_APB1_GRP1_STOP_IP DBGMCU APB1 GRP1 STOP IP
- * @{
- */
-#define LL_DBGMCU_APB1_GRP1_TIM2_STOP DBGMCU_CR_DBG_TIM2_STOP /*!< TIM2 counter stopped when core is halted */
-#define LL_DBGMCU_APB1_GRP1_TIM3_STOP DBGMCU_CR_DBG_TIM3_STOP /*!< TIM3 counter stopped when core is halted */
-#define LL_DBGMCU_APB1_GRP1_TIM4_STOP DBGMCU_CR_DBG_TIM4_STOP /*!< TIM4 counter stopped when core is halted */
-#if defined(DBGMCU_CR_DBG_TIM5_STOP)
-#define LL_DBGMCU_APB1_GRP1_TIM5_STOP DBGMCU_CR_DBG_TIM5_STOP /*!< TIM5 counter stopped when core is halted */
-#endif /* DBGMCU_CR_DBG_TIM5_STOP */
-#if defined(DBGMCU_CR_DBG_TIM6_STOP)
-#define LL_DBGMCU_APB1_GRP1_TIM6_STOP DBGMCU_CR_DBG_TIM6_STOP /*!< TIM6 counter stopped when core is halted */
-#endif /* DBGMCU_CR_DBG_TIM6_STOP */
-#if defined(DBGMCU_CR_DBG_TIM7_STOP)
-#define LL_DBGMCU_APB1_GRP1_TIM7_STOP DBGMCU_CR_DBG_TIM7_STOP /*!< TIM7 counter stopped when core is halted */
-#endif /* DBGMCU_CR_DBG_TIM7_STOP */
-#if defined(DBGMCU_CR_DBG_TIM12_STOP)
-#define LL_DBGMCU_APB1_GRP1_TIM12_STOP DBGMCU_CR_DBG_TIM12_STOP /*!< TIM12 counter stopped when core is halted */
-#endif /* DBGMCU_CR_DBG_TIM12_STOP */
-#if defined(DBGMCU_CR_DBG_TIM13_STOP)
-#define LL_DBGMCU_APB1_GRP1_TIM13_STOP DBGMCU_CR_DBG_TIM13_STOP /*!< TIM13 counter stopped when core is halted */
-#endif /* DBGMCU_CR_DBG_TIM13_STOP */
-#if defined(DBGMCU_CR_DBG_TIM14_STOP)
-#define LL_DBGMCU_APB1_GRP1_TIM14_STOP DBGMCU_CR_DBG_TIM14_STOP /*!< TIM14 counter stopped when core is halted */
-#endif /* DBGMCU_CR_DBG_TIM14_STOP */
-#define LL_DBGMCU_APB1_GRP1_WWDG_STOP DBGMCU_CR_DBG_WWDG_STOP /*!< Debug Window Watchdog stopped when Core is halted */
-#define LL_DBGMCU_APB1_GRP1_IWDG_STOP DBGMCU_CR_DBG_IWDG_STOP /*!< Debug Independent Watchdog stopped when Core is halted */
-#define LL_DBGMCU_APB1_GRP1_I2C1_STOP DBGMCU_CR_DBG_I2C1_SMBUS_TIMEOUT /*!< I2C1 SMBUS timeout mode stopped when Core is halted */
-#if defined(DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT)
-#define LL_DBGMCU_APB1_GRP1_I2C2_STOP DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT /*!< I2C2 SMBUS timeout mode stopped when Core is halted */
-#endif /* DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT */
-#if defined(DBGMCU_CR_DBG_CAN1_STOP)
-#define LL_DBGMCU_APB1_GRP1_CAN1_STOP DBGMCU_CR_DBG_CAN1_STOP /*!< CAN1 debug stopped when Core is halted */
-#endif /* DBGMCU_CR_DBG_CAN1_STOP */
-#if defined(DBGMCU_CR_DBG_CAN2_STOP)
-#define LL_DBGMCU_APB1_GRP1_CAN2_STOP DBGMCU_CR_DBG_CAN2_STOP /*!< CAN2 debug stopped when Core is halted */
-#endif /* DBGMCU_CR_DBG_CAN2_STOP */
-/**
- * @}
- */
-
-/** @defgroup SYSTEM_LL_EC_APB2_GRP1_STOP_IP DBGMCU APB2 GRP1 STOP IP
- * @{
- */
-#define LL_DBGMCU_APB2_GRP1_TIM1_STOP DBGMCU_CR_DBG_TIM1_STOP /*!< TIM1 counter stopped when core is halted */
-#if defined(DBGMCU_CR_DBG_TIM8_STOP)
-#define LL_DBGMCU_APB2_GRP1_TIM8_STOP DBGMCU_CR_DBG_TIM8_STOP /*!< TIM8 counter stopped when core is halted */
-#endif /* DBGMCU_CR_DBG_CAN1_STOP */
-#if defined(DBGMCU_CR_DBG_TIM9_STOP)
-#define LL_DBGMCU_APB2_GRP1_TIM9_STOP DBGMCU_CR_DBG_TIM9_STOP /*!< TIM9 counter stopped when core is halted */
-#endif /* DBGMCU_CR_DBG_TIM9_STOP */
-#if defined(DBGMCU_CR_DBG_TIM10_STOP)
-#define LL_DBGMCU_APB2_GRP1_TIM10_STOP DBGMCU_CR_DBG_TIM10_STOP /*!< TIM10 counter stopped when core is halted */
-#endif /* DBGMCU_CR_DBG_TIM10_STOP */
-#if defined(DBGMCU_CR_DBG_TIM11_STOP)
-#define LL_DBGMCU_APB2_GRP1_TIM11_STOP DBGMCU_CR_DBG_TIM11_STOP /*!< TIM11 counter stopped when core is halted */
-#endif /* DBGMCU_CR_DBG_TIM11_STOP */
-#if defined(DBGMCU_CR_DBG_TIM15_STOP)
-#define LL_DBGMCU_APB2_GRP1_TIM15_STOP DBGMCU_CR_DBG_TIM15_STOP /*!< TIM15 counter stopped when core is halted */
-#endif /* DBGMCU_CR_DBG_TIM15_STOP */
-#if defined(DBGMCU_CR_DBG_TIM16_STOP)
-#define LL_DBGMCU_APB2_GRP1_TIM16_STOP DBGMCU_CR_DBG_TIM16_STOP /*!< TIM16 counter stopped when core is halted */
-#endif /* DBGMCU_CR_DBG_TIM16_STOP */
-#if defined(DBGMCU_CR_DBG_TIM17_STOP)
-#define LL_DBGMCU_APB2_GRP1_TIM17_STOP DBGMCU_CR_DBG_TIM17_STOP /*!< TIM17 counter stopped when core is halted */
-#endif /* DBGMCU_CR_DBG_TIM17_STOP */
-/**
- * @}
- */
-
-/** @defgroup SYSTEM_LL_EC_LATENCY FLASH LATENCY
- * @{
- */
-#if defined(FLASH_ACR_LATENCY)
-#define LL_FLASH_LATENCY_0 0x00000000U /*!< FLASH Zero Latency cycle */
-#define LL_FLASH_LATENCY_1 FLASH_ACR_LATENCY_0 /*!< FLASH One Latency cycle */
-#define LL_FLASH_LATENCY_2 FLASH_ACR_LATENCY_1 /*!< FLASH Two wait states */
-#else
-#endif /* FLASH_ACR_LATENCY */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup SYSTEM_LL_Exported_Functions SYSTEM Exported Functions
- * @{
- */
-
-
-
-/** @defgroup SYSTEM_LL_EF_DBGMCU DBGMCU
- * @{
- */
-
-/**
- * @brief Return the device identifier
- * @note For Low Density devices, the device ID is 0x412
- * @note For Medium Density devices, the device ID is 0x410
- * @note For High Density devices, the device ID is 0x414
- * @note For XL Density devices, the device ID is 0x430
- * @note For Connectivity Line devices, the device ID is 0x418
- * @rmtoll DBGMCU_IDCODE DEV_ID LL_DBGMCU_GetDeviceID
- * @retval Values between Min_Data=0x00 and Max_Data=0xFFF
- */
-__STATIC_INLINE uint32_t LL_DBGMCU_GetDeviceID(void)
-{
- return (uint32_t)(READ_BIT(DBGMCU->IDCODE, DBGMCU_IDCODE_DEV_ID));
-}
-
-/**
- * @brief Return the device revision identifier
- * @note This field indicates the revision of the device.
- For example, it is read as revA -> 0x1000,for Low Density devices
- For example, it is read as revA -> 0x0000, revB -> 0x2000, revZ -> 0x2001, rev1,2,3,X or Y -> 0x2003,for Medium Density devices
- For example, it is read as revA or 1 -> 0x1000, revZ -> 0x1001,rev1,2,3,X or Y -> 0x1003,for Medium Density devices
- For example, it is read as revA or 1 -> 0x1003,for XL Density devices
- For example, it is read as revA -> 0x1000, revZ -> 0x1001 for Connectivity line devices
- * @rmtoll DBGMCU_IDCODE REV_ID LL_DBGMCU_GetRevisionID
- * @retval Values between Min_Data=0x00 and Max_Data=0xFFFF
- */
-__STATIC_INLINE uint32_t LL_DBGMCU_GetRevisionID(void)
-{
- return (uint32_t)(READ_BIT(DBGMCU->IDCODE, DBGMCU_IDCODE_REV_ID) >> DBGMCU_IDCODE_REV_ID_Pos);
-}
-
-/**
- * @brief Enable the Debug Module during SLEEP mode
- * @rmtoll DBGMCU_CR DBG_SLEEP LL_DBGMCU_EnableDBGSleepMode
- * @retval None
- */
-__STATIC_INLINE void LL_DBGMCU_EnableDBGSleepMode(void)
-{
- SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
-}
-
-/**
- * @brief Disable the Debug Module during SLEEP mode
- * @rmtoll DBGMCU_CR DBG_SLEEP LL_DBGMCU_DisableDBGSleepMode
- * @retval None
- */
-__STATIC_INLINE void LL_DBGMCU_DisableDBGSleepMode(void)
-{
- CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
-}
-
-/**
- * @brief Enable the Debug Module during STOP mode
- * @rmtoll DBGMCU_CR DBG_STOP LL_DBGMCU_EnableDBGStopMode
- * @retval None
- */
-__STATIC_INLINE void LL_DBGMCU_EnableDBGStopMode(void)
-{
- SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
-}
-
-/**
- * @brief Disable the Debug Module during STOP mode
- * @rmtoll DBGMCU_CR DBG_STOP LL_DBGMCU_DisableDBGStopMode
- * @retval None
- */
-__STATIC_INLINE void LL_DBGMCU_DisableDBGStopMode(void)
-{
- CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
-}
-
-/**
- * @brief Enable the Debug Module during STANDBY mode
- * @rmtoll DBGMCU_CR DBG_STANDBY LL_DBGMCU_EnableDBGStandbyMode
- * @retval None
- */
-__STATIC_INLINE void LL_DBGMCU_EnableDBGStandbyMode(void)
-{
- SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
-}
-
-/**
- * @brief Disable the Debug Module during STANDBY mode
- * @rmtoll DBGMCU_CR DBG_STANDBY LL_DBGMCU_DisableDBGStandbyMode
- * @retval None
- */
-__STATIC_INLINE void LL_DBGMCU_DisableDBGStandbyMode(void)
-{
- CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
-}
-
-/**
- * @brief Set Trace pin assignment control
- * @rmtoll DBGMCU_CR TRACE_IOEN LL_DBGMCU_SetTracePinAssignment\n
- * DBGMCU_CR TRACE_MODE LL_DBGMCU_SetTracePinAssignment
- * @param PinAssignment This parameter can be one of the following values:
- * @arg @ref LL_DBGMCU_TRACE_NONE
- * @arg @ref LL_DBGMCU_TRACE_ASYNCH
- * @arg @ref LL_DBGMCU_TRACE_SYNCH_SIZE1
- * @arg @ref LL_DBGMCU_TRACE_SYNCH_SIZE2
- * @arg @ref LL_DBGMCU_TRACE_SYNCH_SIZE4
- * @retval None
- */
-__STATIC_INLINE void LL_DBGMCU_SetTracePinAssignment(uint32_t PinAssignment)
-{
- MODIFY_REG(DBGMCU->CR, DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE, PinAssignment);
-}
-
-/**
- * @brief Get Trace pin assignment control
- * @rmtoll DBGMCU_CR TRACE_IOEN LL_DBGMCU_GetTracePinAssignment\n
- * DBGMCU_CR TRACE_MODE LL_DBGMCU_GetTracePinAssignment
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_DBGMCU_TRACE_NONE
- * @arg @ref LL_DBGMCU_TRACE_ASYNCH
- * @arg @ref LL_DBGMCU_TRACE_SYNCH_SIZE1
- * @arg @ref LL_DBGMCU_TRACE_SYNCH_SIZE2
- * @arg @ref LL_DBGMCU_TRACE_SYNCH_SIZE4
- */
-__STATIC_INLINE uint32_t LL_DBGMCU_GetTracePinAssignment(void)
-{
- return (uint32_t)(READ_BIT(DBGMCU->CR, DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE));
-}
-
-/**
- * @brief Freeze APB1 peripherals (group1 peripherals)
- * @rmtoll DBGMCU_CR_APB1 DBG_TIM2_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB1 DBG_TIM3_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB1 DBG_TIM4_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB1 DBG_TIM5_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB1 DBG_TIM6_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB1 DBG_TIM7_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB1 DBG_TIM12_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB1 DBG_TIM13_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB1 DBG_TIM14_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB1 DBG_RTC_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB1 DBG_WWDG_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB1 DBG_IWDG_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB1 DBG_I2C1_SMBUS_TIMEOUT LL_DBGMCU_APB1_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB1 DBG_I2C2_SMBUS_TIMEOUT LL_DBGMCU_APB1_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB1 DBG_CAN1_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB1 DBG_CAN2_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_DBGMCU_APB1_GRP1_TIM2_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_TIM3_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_TIM4_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_TIM5_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_TIM6_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_TIM7_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_TIM12_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_TIM13_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_TIM14_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_WWDG_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_IWDG_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_I2C1_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_I2C2_STOP (*)
- * @arg @ref LL_DBGMCU_APB1_GRP1_CAN1_STOP (*)
- * @arg @ref LL_DBGMCU_APB1_GRP1_CAN2_STOP (*)
- *
- * (*) value not defined in all devices.
- * @retval None
- */
-__STATIC_INLINE void LL_DBGMCU_APB1_GRP1_FreezePeriph(uint32_t Periphs)
-{
- SET_BIT(DBGMCU->CR, Periphs);
-}
-
-/**
- * @brief Unfreeze APB1 peripherals (group1 peripherals)
- * @rmtoll DBGMCU_CR_APB1 DBG_TIM2_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
- * DBGMCU_CR_APB1 DBG_TIM3_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
- * DBGMCU_CR_APB1 DBG_TIM4_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
- * DBGMCU_CR_APB1 DBG_TIM5_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
- * DBGMCU_CR_APB1 DBG_TIM6_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
- * DBGMCU_CR_APB1 DBG_TIM7_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
- * DBGMCU_CR_APB1 DBG_TIM12_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
- * DBGMCU_CR_APB1 DBG_TIM13_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
- * DBGMCU_CR_APB1 DBG_TIM14_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
- * DBGMCU_CR_APB1 DBG_RTC_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
- * DBGMCU_CR_APB1 DBG_WWDG_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
- * DBGMCU_CR_APB1 DBG_IWDG_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
- * DBGMCU_CR_APB1 DBG_I2C1_SMBUS_TIMEOUT LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
- * DBGMCU_CR_APB1 DBG_I2C2_SMBUS_TIMEOUT LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
- * DBGMCU_CR_APB1 DBG_CAN1_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
- * DBGMCU_CR_APB1 DBG_CAN2_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_DBGMCU_APB1_GRP1_TIM2_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_TIM3_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_TIM4_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_TIM5_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_TIM6_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_TIM7_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_TIM12_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_TIM13_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_TIM14_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_RTC_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_WWDG_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_IWDG_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_I2C1_STOP
- * @arg @ref LL_DBGMCU_APB1_GRP1_I2C2_STOP (*)
- * @arg @ref LL_DBGMCU_APB1_GRP1_CAN1_STOP (*)
- * @arg @ref LL_DBGMCU_APB1_GRP1_CAN2_STOP (*)
- *
- * (*) value not defined in all devices.
- * @retval None
- */
-__STATIC_INLINE void LL_DBGMCU_APB1_GRP1_UnFreezePeriph(uint32_t Periphs)
-{
- CLEAR_BIT(DBGMCU->CR, Periphs);
-}
-
-/**
- * @brief Freeze APB2 peripherals
- * @rmtoll DBGMCU_CR_APB2 DBG_TIM1_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB2 DBG_TIM8_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB2 DBG_TIM9_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB2 DBG_TIM10_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB2 DBG_TIM11_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB2 DBG_TIM15_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB2 DBG_TIM16_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB2 DBG_TIM17_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_DBGMCU_APB2_GRP1_TIM1_STOP
- * @arg @ref LL_DBGMCU_APB2_GRP1_TIM8_STOP (*)
- * @arg @ref LL_DBGMCU_APB2_GRP1_TIM9_STOP (*)
- * @arg @ref LL_DBGMCU_APB2_GRP1_TIM10_STOP (*)
- * @arg @ref LL_DBGMCU_APB2_GRP1_TIM11_STOP (*)
- * @arg @ref LL_DBGMCU_APB2_GRP1_TIM15_STOP (*)
- * @arg @ref LL_DBGMCU_APB2_GRP1_TIM16_STOP (*)
- * @arg @ref LL_DBGMCU_APB2_GRP1_TIM17_STOP (*)
- *
- * (*) value not defined in all devices.
- * @retval None
- */
-__STATIC_INLINE void LL_DBGMCU_APB2_GRP1_FreezePeriph(uint32_t Periphs)
-{
- SET_BIT(DBGMCU->CR, Periphs);
-}
-
-/**
- * @brief Unfreeze APB2 peripherals
- * @rmtoll DBGMCU_CR_APB2 DBG_TIM1_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB2 DBG_TIM8_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB2 DBG_TIM9_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB2 DBG_TIM10_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB2 DBG_TIM11_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB2 DBG_TIM15_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB2 DBG_TIM16_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
- * DBGMCU_CR_APB2 DBG_TIM17_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph
- * @param Periphs This parameter can be a combination of the following values:
- * @arg @ref LL_DBGMCU_APB2_GRP1_TIM1_STOP
- * @arg @ref LL_DBGMCU_APB2_GRP1_TIM8_STOP (*)
- * @arg @ref LL_DBGMCU_APB2_GRP1_TIM9_STOP (*)
- * @arg @ref LL_DBGMCU_APB2_GRP1_TIM10_STOP (*)
- * @arg @ref LL_DBGMCU_APB2_GRP1_TIM11_STOP (*)
- * @arg @ref LL_DBGMCU_APB2_GRP1_TIM15_STOP (*)
- * @arg @ref LL_DBGMCU_APB2_GRP1_TIM16_STOP (*)
- * @arg @ref LL_DBGMCU_APB2_GRP1_TIM17_STOP (*)
- *
- * (*) value not defined in all devices.
- * @retval None
- */
-__STATIC_INLINE void LL_DBGMCU_APB2_GRP1_UnFreezePeriph(uint32_t Periphs)
-{
- CLEAR_BIT(DBGMCU->CR, Periphs);
-}
-/**
- * @}
- */
-
-#if defined(FLASH_ACR_LATENCY)
-/** @defgroup SYSTEM_LL_EF_FLASH FLASH
- * @{
- */
-
-/**
- * @brief Set FLASH Latency
- * @rmtoll FLASH_ACR LATENCY LL_FLASH_SetLatency
- * @param Latency This parameter can be one of the following values:
- * @arg @ref LL_FLASH_LATENCY_0
- * @arg @ref LL_FLASH_LATENCY_1
- * @arg @ref LL_FLASH_LATENCY_2
- * @retval None
- */
-__STATIC_INLINE void LL_FLASH_SetLatency(uint32_t Latency)
-{
- MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, Latency);
-}
-
-/**
- * @brief Get FLASH Latency
- * @rmtoll FLASH_ACR LATENCY LL_FLASH_GetLatency
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_FLASH_LATENCY_0
- * @arg @ref LL_FLASH_LATENCY_1
- * @arg @ref LL_FLASH_LATENCY_2
- */
-__STATIC_INLINE uint32_t LL_FLASH_GetLatency(void)
-{
- return (uint32_t)(READ_BIT(FLASH->ACR, FLASH_ACR_LATENCY));
-}
-
-/**
- * @brief Enable Prefetch
- * @rmtoll FLASH_ACR PRFTBE LL_FLASH_EnablePrefetch
- * @retval None
- */
-__STATIC_INLINE void LL_FLASH_EnablePrefetch(void)
-{
- SET_BIT(FLASH->ACR, FLASH_ACR_PRFTBE);
-}
-
-/**
- * @brief Disable Prefetch
- * @rmtoll FLASH_ACR PRFTBE LL_FLASH_DisablePrefetch
- * @retval None
- */
-__STATIC_INLINE void LL_FLASH_DisablePrefetch(void)
-{
- CLEAR_BIT(FLASH->ACR, FLASH_ACR_PRFTBE);
-}
-
-/**
- * @brief Check if Prefetch buffer is enabled
- * @rmtoll FLASH_ACR PRFTBS LL_FLASH_IsPrefetchEnabled
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_FLASH_IsPrefetchEnabled(void)
-{
- return (READ_BIT(FLASH->ACR, FLASH_ACR_PRFTBS) == (FLASH_ACR_PRFTBS));
-}
-
-#endif /* FLASH_ACR_LATENCY */
-/**
- * @brief Enable Flash Half Cycle Access
- * @rmtoll FLASH_ACR HLFCYA LL_FLASH_EnableHalfCycleAccess
- * @retval None
- */
-__STATIC_INLINE void LL_FLASH_EnableHalfCycleAccess(void)
-{
- SET_BIT(FLASH->ACR, FLASH_ACR_HLFCYA);
-}
-
-/**
- * @brief Disable Flash Half Cycle Access
- * @rmtoll FLASH_ACR HLFCYA LL_FLASH_DisableHalfCycleAccess
- * @retval None
- */
-__STATIC_INLINE void LL_FLASH_DisableHalfCycleAccess(void)
-{
- CLEAR_BIT(FLASH->ACR, FLASH_ACR_HLFCYA);
-}
-
-/**
- * @brief Check if Flash Half Cycle Access is enabled or not
- * @rmtoll FLASH_ACR HLFCYA LL_FLASH_IsHalfCycleAccessEnabled
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_FLASH_IsHalfCycleAccessEnabled(void)
-{
- return (READ_BIT(FLASH->ACR, FLASH_ACR_HLFCYA) == (FLASH_ACR_HLFCYA));
-}
-
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* defined (FLASH) || defined (DBGMCU) */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_LL_SYSTEM_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usb.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usb.h
deleted file mode 100644
index f551663..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usb.h
+++ /dev/null
@@ -1,614 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_usb.h
- * @author MCD Application Team
- * @brief Header file of USB Low Layer HAL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_LL_USB_H
-#define __STM32F1xx_LL_USB_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-#if defined(STM32F102x6) || defined(STM32F102xB) || \
- defined(STM32F103x6) || defined(STM32F103xB) || \
- defined(STM32F103xE) || defined(STM32F103xG) || \
- defined(STM32F105xC) || defined(STM32F107xC)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup USB_LL
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup USB_LL_Exported_Types USB Low Layer Exported Types
- * @{
- */
-/**
- * @brief USB Mode definition
- */
-typedef enum
-{
- USB_DEVICE_MODE = 0,
- USB_HOST_MODE = 1,
- USB_DRD_MODE = 2
-}USB_ModeTypeDef;
-
-#if defined (USB_OTG_FS)
-/**
- * @brief URB States definition
- */
-typedef enum {
- URB_IDLE = 0,
- URB_DONE,
- URB_NOTREADY,
- URB_NYET,
- URB_ERROR,
- URB_STALL
-}USB_OTG_URBStateTypeDef;
-
-/**
- * @brief Host channel States definition
- */
-typedef enum {
- HC_IDLE = 0,
- HC_XFRC,
- HC_HALTED,
- HC_NAK,
- HC_NYET,
- HC_STALL,
- HC_XACTERR,
- HC_BBLERR,
- HC_DATATGLERR
-}USB_OTG_HCStateTypeDef;
-
-/**
- * @brief USB OTG Initialization Structure definition
- */
-typedef struct
-{
- uint32_t dev_endpoints; /*!< Device Endpoints number.
- This parameter depends on the used USB core.
- This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
-
- uint32_t Host_channels; /*!< Host Channels number.
- This parameter Depends on the used USB core.
- This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
-
- uint32_t speed; /*!< USB Core speed.
- This parameter can be any value of @ref USB_Core_Speed_ */
-
- uint32_t ep0_mps; /*!< Set the Endpoint 0 Max Packet size.
- This parameter can be any value of @ref USB_EP0_MPS_ */
-
- uint32_t Sof_enable; /*!< Enable or disable the output of the SOF signal. */
-
- uint32_t low_power_enable; /*!< Enable or disable the low power mode. */
-
- uint32_t vbus_sensing_enable; /*!< Enable or disable the VBUS Sensing feature. */
-
- uint32_t use_external_vbus; /*!< Enable or disable the use of the external VBUS. */
-}USB_OTG_CfgTypeDef;
-
-typedef struct
-{
- uint8_t num; /*!< Endpoint number
- This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
-
- uint8_t is_in; /*!< Endpoint direction
- This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
-
- uint8_t is_stall; /*!< Endpoint stall condition
- This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
-
- uint8_t type; /*!< Endpoint type
- This parameter can be any value of @ref USB_EP_Type_ */
-
- uint8_t data_pid_start; /*!< Initial data PID
- This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
-
- uint8_t even_odd_frame; /*!< IFrame parity
- This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
-
- uint16_t tx_fifo_num; /*!< Transmission FIFO number
- This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
-
- uint32_t maxpacket; /*!< Endpoint Max packet size
- This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
-
- uint8_t *xfer_buff; /*!< Pointer to transfer buffer */
-
- uint32_t dma_addr; /*!< 32 bits aligned transfer buffer address */
-
- uint32_t xfer_len; /*!< Current transfer length */
-
- uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer */
-}USB_OTG_EPTypeDef;
-
-typedef struct
-{
- uint8_t dev_addr ; /*!< USB device address.
- This parameter must be a number between Min_Data = 1 and Max_Data = 255 */
-
- uint8_t ch_num; /*!< Host channel number.
- This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
-
- uint8_t ep_num; /*!< Endpoint number.
- This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
-
- uint8_t ep_is_in; /*!< Endpoint direction
- This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
-
- uint8_t speed; /*!< USB Host speed.
- This parameter can be any value of @ref USB_Core_Speed_ */
-
- uint8_t do_ping; /*!< Enable or disable the use of the PING protocol for HS mode. */
-
- uint8_t process_ping; /*!< Execute the PING protocol for HS mode. */
-
- uint8_t ep_type; /*!< Endpoint Type.
- This parameter can be any value of @ref USB_EP_Type_ */
-
- uint16_t max_packet; /*!< Endpoint Max packet size.
- This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
-
- uint8_t data_pid; /*!< Initial data PID.
- This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
-
- uint8_t *xfer_buff; /*!< Pointer to transfer buffer. */
-
- uint32_t xfer_len; /*!< Current transfer length. */
-
- uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer. */
-
- uint8_t toggle_in; /*!< IN transfer current toggle flag.
- This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
-
- uint8_t toggle_out; /*!< OUT transfer current toggle flag
- This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
-
- uint32_t dma_addr; /*!< 32 bits aligned transfer buffer address. */
-
- uint32_t ErrCnt; /*!< Host channel error count.*/
-
- USB_OTG_URBStateTypeDef urb_state; /*!< URB state.
- This parameter can be any value of @ref USB_OTG_URBStateTypeDef */
-
- USB_OTG_HCStateTypeDef state; /*!< Host Channel state.
- This parameter can be any value of @ref USB_OTG_HCStateTypeDef */
-}USB_OTG_HCTypeDef;
-#endif /* USB_OTG_FS */
-
-#if defined (USB)
-/**
- * @brief USB Initialization Structure definition
- */
-typedef struct
-{
- uint32_t dev_endpoints; /*!< Device Endpoints number.
- This parameter depends on the used USB core.
- This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
-
- uint32_t speed; /*!< USB Core speed.
- This parameter can be any value of @ref USB_Core_Speed */
-
- uint32_t ep0_mps; /*!< Set the Endpoint 0 Max Packet size.
- This parameter can be any value of @ref USB_EP0_MPS */
-
- uint32_t phy_itface; /*!< Select the used PHY interface.
- This parameter can be any value of @ref USB_Core_PHY */
-
- uint32_t Sof_enable; /*!< Enable or disable the output of the SOF signal. */
-
- uint32_t low_power_enable; /*!< Enable or disable Low Power mode */
-
- uint32_t lpm_enable; /*!< Enable or disable Battery charging. */
-
- uint32_t battery_charging_enable; /*!< Enable or disable Battery charging. */
-} USB_CfgTypeDef;
-
-typedef struct
-{
- uint8_t num; /*!< Endpoint number
- This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
-
- uint8_t is_in; /*!< Endpoint direction
- This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
-
- uint8_t is_stall; /*!< Endpoint stall condition
- This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
-
- uint8_t type; /*!< Endpoint type
- This parameter can be any value of @ref USB_EP_Type */
-
- uint16_t pmaadress; /*!< PMA Address
- This parameter can be any value between Min_addr = 0 and Max_addr = 1K */
-
- uint16_t pmaaddr0; /*!< PMA Address0
- This parameter can be any value between Min_addr = 0 and Max_addr = 1K */
-
- uint16_t pmaaddr1; /*!< PMA Address1
- This parameter can be any value between Min_addr = 0 and Max_addr = 1K */
-
- uint8_t doublebuffer; /*!< Double buffer enable
- This parameter can be 0 or 1 */
-
- uint16_t tx_fifo_num; /*!< This parameter is not required by USB Device FS peripheral, it is used
- only by USB OTG FS peripheral
- This parameter is added to ensure compatibility across USB peripherals */
-
- uint32_t maxpacket; /*!< Endpoint Max packet size
- This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
-
- uint8_t *xfer_buff; /*!< Pointer to transfer buffer */
-
- uint32_t xfer_len; /*!< Current transfer length */
-
- uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer */
-
-} USB_EPTypeDef;
-#endif /* USB */
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup USB_LL_Exported_Constants USB Low Layer Exported Constants
- * @{
- */
-#if defined (USB_OTG_FS)
-/** @defgroup USB_LL_Core_Mode USB Low Layer Core Mode
- * @{
- */
-#define USB_OTG_MODE_DEVICE 0
-#define USB_OTG_MODE_HOST 1
-#define USB_OTG_MODE_DRD 2
-/**
- * @}
- */
-
-/** @defgroup USB_LL_Core_Speed USB Low Layer Core Speed
- * @{
- */
-#define USB_OTG_SPEED_LOW 2
-#define USB_OTG_SPEED_FULL 3
-
-/**
- * @}
- */
-
-/** @defgroup USB_LL_Core_PHY USB Low Layer Core PHY
- * @{
- */
-#define USB_OTG_ULPI_PHY 1
-#define USB_OTG_EMBEDDED_PHY 2
-/**
- * @}
- */
-
-/** @defgroup USB_LL_Core_MPS USB Low Layer Core MPS
- * @{
- */
-#define USB_OTG_FS_MAX_PACKET_SIZE 64
-#define USB_OTG_MAX_EP0_SIZE 64
-/**
- * @}
- */
-
-/** @defgroup USB_LL_Core_PHY_Frequency USB Low Layer Core PHY Frequency
- * @{
- */
-#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ (1 << 1)
-#define DSTS_ENUMSPD_LS_PHY_6MHZ (2 << 1)
-#define DSTS_ENUMSPD_FS_PHY_48MHZ (3 << 1)
-/**
- * @}
- */
-
-/** @defgroup USB_LL_CORE_Frame_Interval USB Low Layer Core Frame Interval
- * @{
- */
-#define DCFG_FRAME_INTERVAL_80 0
-#define DCFG_FRAME_INTERVAL_85 1
-#define DCFG_FRAME_INTERVAL_90 2
-#define DCFG_FRAME_INTERVAL_95 3
-/**
- * @}
- */
-
-/** @defgroup USB_LL_EP0_MPS USB Low Layer EP0 MPS
- * @{
- */
-#define DEP0CTL_MPS_64 0
-#define DEP0CTL_MPS_32 1
-#define DEP0CTL_MPS_16 2
-#define DEP0CTL_MPS_8 3
-/**
- * @}
- */
-
-/** @defgroup USB_LL_EP_Speed USB Low Layer EP Speed
- * @{
- */
-#define EP_SPEED_LOW 0
-#define EP_SPEED_FULL 1
-#define EP_SPEED_HIGH 2
-/**
- * @}
- */
-
-/** @defgroup USB_LL_EP_Type USB Low Layer EP Type
- * @{
- */
-#define EP_TYPE_CTRL 0
-#define EP_TYPE_ISOC 1
-#define EP_TYPE_BULK 2
-#define EP_TYPE_INTR 3
-#define EP_TYPE_MSK 3
-/**
- * @}
- */
-
-/** @defgroup USB_LL_STS_Defines USB Low Layer STS Defines
- * @{
- */
-#define STS_GOUT_NAK 1
-#define STS_DATA_UPDT 2
-#define STS_XFER_COMP 3
-#define STS_SETUP_COMP 4
-#define STS_SETUP_UPDT 6
-/**
- * @}
- */
-
-/** @defgroup USB_LL_HCFG_SPEED_Defines USB Low Layer HCFG Speed Defines
- * @{
- */
-#define HCFG_30_60_MHZ 0
-#define HCFG_48_MHZ 1
-#define HCFG_6_MHZ 2
-/**
- * @}
- */
-
-/** @defgroup USB_LL_HPRT0_PRTSPD_SPEED_Defines USB Low Layer HPRT0 PRTSPD Speed Defines
- * @{
- */
-#define HPRT0_PRTSPD_HIGH_SPEED 0
-#define HPRT0_PRTSPD_FULL_SPEED 1
-#define HPRT0_PRTSPD_LOW_SPEED 2
-/**
- * @}
- */
-
-#define HCCHAR_CTRL 0
-#define HCCHAR_ISOC 1
-#define HCCHAR_BULK 2
-#define HCCHAR_INTR 3
-
-#define HC_PID_DATA0 0
-#define HC_PID_DATA2 1
-#define HC_PID_DATA1 2
-#define HC_PID_SETUP 3
-
-#define GRXSTS_PKTSTS_IN 2
-#define GRXSTS_PKTSTS_IN_XFER_COMP 3
-#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5
-#define GRXSTS_PKTSTS_CH_HALTED 7
-
-#define USBx_PCGCCTL *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_PCGCCTL_BASE)
-#define USBx_HPRT0 *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_HOST_PORT_BASE)
-
-#define USBx_DEVICE ((USB_OTG_DeviceTypeDef *)((uint32_t )USBx + USB_OTG_DEVICE_BASE))
-#define USBx_INEP(i) ((USB_OTG_INEndpointTypeDef *)((uint32_t)USBx + USB_OTG_IN_ENDPOINT_BASE + (i)*USB_OTG_EP_REG_SIZE))
-#define USBx_OUTEP(i) ((USB_OTG_OUTEndpointTypeDef *)((uint32_t)USBx + USB_OTG_OUT_ENDPOINT_BASE + (i)*USB_OTG_EP_REG_SIZE))
-#define USBx_DFIFO(i) *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_FIFO_BASE + (i) * USB_OTG_FIFO_SIZE)
-
-#define USBx_HOST ((USB_OTG_HostTypeDef *)((uint32_t )USBx + USB_OTG_HOST_BASE))
-#define USBx_HC(i) ((USB_OTG_HostChannelTypeDef *)((uint32_t)USBx + USB_OTG_HOST_CHANNEL_BASE + (i)*USB_OTG_HOST_CHANNEL_SIZE))
-#endif /* USB_OTG_FS */
-
-#if defined (USB)
-/** @defgroup USB_LL_EP0_MPS USB Low Layer EP0 MPS
- * @{
- */
-#define DEP0CTL_MPS_64 0
-#define DEP0CTL_MPS_32 1
-#define DEP0CTL_MPS_16 2
-#define DEP0CTL_MPS_8 3
-/**
- * @}
- */
-
-/** @defgroup USB_LL_EP_Type USB Low Layer EP Type
- * @{
- */
-#define EP_TYPE_CTRL 0
-#define EP_TYPE_ISOC 1
-#define EP_TYPE_BULK 2
-#define EP_TYPE_INTR 3
-#define EP_TYPE_MSK 3
-/**
- * @}
- */
-
-#define BTABLE_ADDRESS (0x000)
-#endif /* USB */
-/**
- * @}
- */
-
-/* Exported macros -----------------------------------------------------------*/
-/** @defgroup USB_LL_Exported_Macros USB Low Layer Exported Macros
- * @{
- */
-#if defined (USB_OTG_FS)
-#define USB_MASK_INTERRUPT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->GINTMSK &= ~(__INTERRUPT__))
-#define USB_UNMASK_INTERRUPT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->GINTMSK |= (__INTERRUPT__))
-
-#define CLEAR_IN_EP_INTR(__EPNUM__, __INTERRUPT__) (USBx_INEP(__EPNUM__)->DIEPINT = (__INTERRUPT__))
-#define CLEAR_OUT_EP_INTR(__EPNUM__, __INTERRUPT__) (USBx_OUTEP(__EPNUM__)->DOEPINT = (__INTERRUPT__))
-#endif /* USB_OTG_FS */
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup USB_LL_Exported_Functions USB Low Layer Exported Functions
- * @{
- */
-/** @addtogroup USB_LL_Exported_Functions_Group1 Peripheral Control functions
- * @{
- */
-#if defined (USB_OTG_FS)
-HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef Init);
-HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef Init);
-HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx , USB_ModeTypeDef mode);
-HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx , uint8_t speed);
-HAL_StatusTypeDef USB_FlushRxFifo (USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_FlushTxFifo (USB_OTG_GlobalTypeDef *USBx, uint32_t num );
-HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
-HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
-HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep);
-HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep);
-HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len);
-void * USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len);
-HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep);
-HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep);
-HAL_StatusTypeDef USB_SetDevAddress (USB_OTG_GlobalTypeDef *USBx, uint8_t address);
-HAL_StatusTypeDef USB_DevConnect (USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_DevDisconnect (USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_ActivateSetup (USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t *psetup);
-uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx);
-uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx);
-uint32_t USB_ReadInterrupts (USB_OTG_GlobalTypeDef *USBx);
-uint32_t USB_ReadDevAllOutEpInterrupt (USB_OTG_GlobalTypeDef *USBx);
-uint32_t USB_ReadDevOutEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum);
-uint32_t USB_ReadDevAllInEpInterrupt (USB_OTG_GlobalTypeDef *USBx);
-uint32_t USB_ReadDevInEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum);
-void USB_ClearInterrupts (USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt);
-
-HAL_StatusTypeDef USB_HostInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg);
-HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx , uint8_t freq);
-HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_DriveVbus (USB_OTG_GlobalTypeDef *USBx, uint8_t state);
-uint32_t USB_GetHostSpeed (USB_OTG_GlobalTypeDef *USBx);
-uint32_t USB_GetCurrentFrame (USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx,
- uint8_t ch_num,
- uint8_t epnum,
- uint8_t dev_address,
- uint8_t speed,
- uint8_t ep_type,
- uint16_t mps);
-HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc);
-uint32_t USB_HC_ReadInterrupt (USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx , uint8_t hc_num);
-HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx , uint8_t ch_num);
-HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx);
-HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx);
-#endif /* USB_OTG_FS */
-
-#if defined (USB)
-HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef Init);
-HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef Init);
-HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx);
-HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx);
-HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx , USB_ModeTypeDef mode);
-HAL_StatusTypeDef USB_SetDevSpeed(USB_TypeDef *USBx , uint8_t speed);
-HAL_StatusTypeDef USB_FlushRxFifo (USB_TypeDef *USBx);
-HAL_StatusTypeDef USB_FlushTxFifo (USB_TypeDef *USBx, uint32_t num );
-HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep);
-HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep);
-HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx , USB_EPTypeDef *ep);
-HAL_StatusTypeDef USB_WritePacket(USB_TypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len);
-void * USB_ReadPacket(USB_TypeDef *USBx, uint8_t *dest, uint16_t len);
-HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx , USB_EPTypeDef *ep);
-HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx , USB_EPTypeDef *ep);
-HAL_StatusTypeDef USB_SetDevAddress (USB_TypeDef *USBx, uint8_t address);
-HAL_StatusTypeDef USB_DevConnect (USB_TypeDef *USBx);
-HAL_StatusTypeDef USB_DevDisconnect (USB_TypeDef *USBx);
-HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx);
-HAL_StatusTypeDef USB_EP0_OutStart(USB_TypeDef *USBx, uint8_t *psetup);
-uint32_t USB_ReadInterrupts (USB_TypeDef *USBx);
-uint32_t USB_ReadDevAllOutEpInterrupt (USB_TypeDef *USBx);
-uint32_t USB_ReadDevOutEPInterrupt (USB_TypeDef *USBx , uint8_t epnum);
-uint32_t USB_ReadDevAllInEpInterrupt (USB_TypeDef *USBx);
-uint32_t USB_ReadDevInEPInterrupt (USB_TypeDef *USBx , uint8_t epnum);
-void USB_ClearInterrupts (USB_TypeDef *USBx, uint32_t interrupt);
-
-HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx);
-HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx);
-void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes);
-void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes);
-#endif /* USB */
-/**
- * @}
- */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* STM32F102x6 || STM32F102xB || */
- /* STM32F103x6 || STM32F103xB || */
- /* STM32F103xE || STM32F103xG || */
- /* STM32F105xC || STM32F107xC */
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* __STM32F1xx_LL_USB_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_utils.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_utils.h
deleted file mode 100644
index 0a040b7..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_utils.h
+++ /dev/null
@@ -1,282 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_utils.h
- * @author MCD Application Team
- * @brief Header file of UTILS LL module.
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- The LL UTILS driver contains a set of generic APIs that can be
- used by user:
- (+) Device electronic signature
- (+) Timing functions
- (+) PLL configuration functions
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_LL_UTILS_H
-#define __STM32F1xx_LL_UTILS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx.h"
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-/** @defgroup UTILS_LL UTILS
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup UTILS_LL_Private_Constants UTILS Private Constants
- * @{
- */
-
-/* Max delay can be used in LL_mDelay */
-#define LL_MAX_DELAY 0xFFFFFFFFU
-
-/**
- * @brief Unique device ID register base address
- */
-#define UID_BASE_ADDRESS UID_BASE
-
-/**
- * @brief Flash size data register base address
- */
-#define FLASHSIZE_BASE_ADDRESS FLASHSIZE_BASE
-
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup UTILS_LL_Private_Macros UTILS Private Macros
- * @{
- */
-/**
- * @}
- */
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup UTILS_LL_ES_INIT UTILS Exported structures
- * @{
- */
-/**
- * @brief UTILS PLL structure definition
- */
-typedef struct
-{
- uint32_t PLLMul; /*!< Multiplication factor for PLL VCO input clock.
- This parameter can be a value of @ref RCC_LL_EC_PLL_MUL
-
- This feature can be modified afterwards using unitary function
- @ref LL_RCC_PLL_ConfigDomain_SYS(). */
-
- uint32_t Prediv; /*!< Division factor for HSE used as PLL clock source.
- This parameter can be a value of @ref RCC_LL_EC_PREDIV_DIV
-
- This feature can be modified afterwards using unitary function
- @ref LL_RCC_PLL_ConfigDomain_SYS(). */
-} LL_UTILS_PLLInitTypeDef;
-
-/**
- * @brief UTILS System, AHB and APB buses clock configuration structure definition
- */
-typedef struct
-{
- uint32_t AHBCLKDivider; /*!< The AHB clock (HCLK) divider. This clock is derived from the system clock (SYSCLK).
- This parameter can be a value of @ref RCC_LL_EC_SYSCLK_DIV
-
- This feature can be modified afterwards using unitary function
- @ref LL_RCC_SetAHBPrescaler(). */
-
- uint32_t APB1CLKDivider; /*!< The APB1 clock (PCLK1) divider. This clock is derived from the AHB clock (HCLK).
- This parameter can be a value of @ref RCC_LL_EC_APB1_DIV
-
- This feature can be modified afterwards using unitary function
- @ref LL_RCC_SetAPB1Prescaler(). */
-
- uint32_t APB2CLKDivider; /*!< The APB2 clock (PCLK2) divider. This clock is derived from the AHB clock (HCLK).
- This parameter can be a value of @ref RCC_LL_EC_APB2_DIV
-
- This feature can be modified afterwards using unitary function
- @ref LL_RCC_SetAPB2Prescaler(). */
-
-} LL_UTILS_ClkInitTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup UTILS_LL_Exported_Constants UTILS Exported Constants
- * @{
- */
-
-/** @defgroup UTILS_EC_HSE_BYPASS HSE Bypass activation
- * @{
- */
-#define LL_UTILS_HSEBYPASS_OFF 0x00000000U /*!< HSE Bypass is not enabled */
-#define LL_UTILS_HSEBYPASS_ON 0x00000001U /*!< HSE Bypass is enabled */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup UTILS_LL_Exported_Functions UTILS Exported Functions
- * @{
- */
-
-/** @defgroup UTILS_EF_DEVICE_ELECTRONIC_SIGNATURE DEVICE ELECTRONIC SIGNATURE
- * @{
- */
-
-/**
- * @brief Get Word0 of the unique device identifier (UID based on 96 bits)
- * @retval UID[31:0]
- */
-__STATIC_INLINE uint32_t LL_GetUID_Word0(void)
-{
- return (uint32_t)(READ_REG(*((uint32_t *)UID_BASE_ADDRESS)));
-}
-
-/**
- * @brief Get Word1 of the unique device identifier (UID based on 96 bits)
- * @retval UID[63:32]
- */
-__STATIC_INLINE uint32_t LL_GetUID_Word1(void)
-{
- return (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE_ADDRESS + 4U))));
-}
-
-/**
- * @brief Get Word2 of the unique device identifier (UID based on 96 bits)
- * @retval UID[95:64]
- */
-__STATIC_INLINE uint32_t LL_GetUID_Word2(void)
-{
- return (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE_ADDRESS + 8U))));
-}
-
-/**
- * @brief Get Flash memory size
- * @note This bitfield indicates the size of the device Flash memory expressed in
- * Kbytes. As an example, 0x040 corresponds to 64 Kbytes.
- * @retval FLASH_SIZE[15:0]: Flash memory size
- */
-__STATIC_INLINE uint32_t LL_GetFlashSize(void)
-{
- return (uint16_t)(READ_REG(*((uint32_t *)FLASHSIZE_BASE_ADDRESS)));
-}
-
-
-/**
- * @}
- */
-
-/** @defgroup UTILS_LL_EF_DELAY DELAY
- * @{
- */
-
-/**
- * @brief This function configures the Cortex-M SysTick source of the time base.
- * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
- * @note When a RTOS is used, it is recommended to avoid changing the SysTick
- * configuration by calling this function, for a delay use rather osDelay RTOS service.
- * @param Ticks Number of ticks
- * @retval None
- */
-__STATIC_INLINE void LL_InitTick(uint32_t HCLKFrequency, uint32_t Ticks)
-{
- /* Configure the SysTick to have interrupt in 1ms time base */
- SysTick->LOAD = (uint32_t)((HCLKFrequency / Ticks) - 1UL); /* set reload register */
- SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
- SysTick_CTRL_ENABLE_Msk; /* Enable the Systick Timer */
-}
-
-void LL_Init1msTick(uint32_t HCLKFrequency);
-void LL_mDelay(uint32_t Delay);
-
-/**
- * @}
- */
-
-/** @defgroup UTILS_EF_SYSTEM SYSTEM
- * @{
- */
-
-void LL_SetSystemCoreClock(uint32_t HCLKFrequency);
-ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
- LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
-ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
- LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_LL_UTILS_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_wwdg.h b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_wwdg.h
deleted file mode 100644
index 70f06ac..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_wwdg.h
+++ /dev/null
@@ -1,340 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_wwdg.h
- * @author MCD Application Team
- * @brief Header file of WWDG LL module.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_LL_WWDG_H
-#define __STM32F1xx_LL_WWDG_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx.h"
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined (WWDG)
-
-/** @defgroup WWDG_LL WWDG
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-
-/* Private constants ---------------------------------------------------------*/
-
-/* Private macros ------------------------------------------------------------*/
-
-/* Exported types ------------------------------------------------------------*/
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup WWDG_LL_Exported_Constants WWDG Exported Constants
- * @{
- */
-
-
-/** @defgroup WWDG_LL_EC_IT IT Defines
- * @brief IT defines which can be used with LL_WWDG_ReadReg and LL_WWDG_WriteReg functions
- * @{
- */
-#define LL_WWDG_CFR_EWI WWDG_CFR_EWI
-/**
- * @}
- */
-
-/** @defgroup WWDG_LL_EC_PRESCALER PRESCALER
-* @{
-*/
-#define LL_WWDG_PRESCALER_1 0x00000000U /*!< WWDG counter clock = (PCLK1/4096)/1 */
-#define LL_WWDG_PRESCALER_2 WWDG_CFR_WDGTB_0 /*!< WWDG counter clock = (PCLK1/4096)/2 */
-#define LL_WWDG_PRESCALER_4 WWDG_CFR_WDGTB_1 /*!< WWDG counter clock = (PCLK1/4096)/4 */
-#define LL_WWDG_PRESCALER_8 (WWDG_CFR_WDGTB_0 | WWDG_CFR_WDGTB_1) /*!< WWDG counter clock = (PCLK1/4096)/8 */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup WWDG_LL_Exported_Macros WWDG Exported Macros
- * @{
- */
-/** @defgroup WWDG_LL_EM_WRITE_READ Common Write and read registers macros
- * @{
- */
-/**
- * @brief Write a value in WWDG register
- * @param __INSTANCE__ WWDG Instance
- * @param __REG__ Register to be written
- * @param __VALUE__ Value to be written in the register
- * @retval None
- */
-#define LL_WWDG_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
-
-/**
- * @brief Read a value in WWDG register
- * @param __INSTANCE__ WWDG Instance
- * @param __REG__ Register to be read
- * @retval Register value
- */
-#define LL_WWDG_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
-/**
- * @}
- */
-
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup WWDG_LL_Exported_Functions WWDG Exported Functions
- * @{
- */
-
-/** @defgroup WWDG_LL_EF_Configuration Configuration
- * @{
- */
-/**
- * @brief Enable Window Watchdog. The watchdog is always disabled after a reset.
- * @note It is enabled by setting the WDGA bit in the WWDG_CR register,
- * then it cannot be disabled again except by a reset.
- * This bit is set by software and only cleared by hardware after a reset.
- * When WDGA = 1, the watchdog can generate a reset.
- * @rmtoll CR WDGA LL_WWDG_Enable
- * @param WWDGx WWDG Instance
- * @retval None
- */
-__STATIC_INLINE void LL_WWDG_Enable(WWDG_TypeDef *WWDGx)
-{
- SET_BIT(WWDGx->CR, WWDG_CR_WDGA);
-}
-
-/**
- * @brief Checks if Window Watchdog is enabled
- * @rmtoll CR WDGA LL_WWDG_IsEnabled
- * @param WWDGx WWDG Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_WWDG_IsEnabled(WWDG_TypeDef *WWDGx)
-{
- return (READ_BIT(WWDGx->CR, WWDG_CR_WDGA) == (WWDG_CR_WDGA));
-}
-
-/**
- * @brief Set the Watchdog counter value to provided value (7-bits T[6:0])
- * @note When writing to the WWDG_CR register, always write 1 in the MSB b6 to avoid generating an immediate reset
- * This counter is decremented every (4096 x 2expWDGTB) PCLK cycles
- * A reset is produced when it rolls over from 0x40 to 0x3F (bit T6 becomes cleared)
- * Setting the counter lower then 0x40 causes an immediate reset (if WWDG enabled)
- * @rmtoll CR T LL_WWDG_SetCounter
- * @param WWDGx WWDG Instance
- * @param Counter 0..0x7F (7 bit counter value)
- * @retval None
- */
-__STATIC_INLINE void LL_WWDG_SetCounter(WWDG_TypeDef *WWDGx, uint32_t Counter)
-{
- MODIFY_REG(WWDGx->CR, WWDG_CR_T, Counter);
-}
-
-/**
- * @brief Return current Watchdog Counter Value (7 bits counter value)
- * @rmtoll CR T LL_WWDG_GetCounter
- * @param WWDGx WWDG Instance
- * @retval 7 bit Watchdog Counter value
- */
-__STATIC_INLINE uint32_t LL_WWDG_GetCounter(WWDG_TypeDef *WWDGx)
-{
- return (uint32_t)(READ_BIT(WWDGx->CR, WWDG_CR_T));
-}
-
-/**
- * @brief Set the time base of the prescaler (WDGTB).
- * @note Prescaler is used to apply ratio on PCLK clock, so that Watchdog counter
- * is decremented every (4096 x 2expWDGTB) PCLK cycles
- * @rmtoll CFR WDGTB LL_WWDG_SetPrescaler
- * @param WWDGx WWDG Instance
- * @param Prescaler This parameter can be one of the following values:
- * @arg @ref LL_WWDG_PRESCALER_1
- * @arg @ref LL_WWDG_PRESCALER_2
- * @arg @ref LL_WWDG_PRESCALER_4
- * @arg @ref LL_WWDG_PRESCALER_8
- * @retval None
- */
-__STATIC_INLINE void LL_WWDG_SetPrescaler(WWDG_TypeDef *WWDGx, uint32_t Prescaler)
-{
- MODIFY_REG(WWDGx->CFR, WWDG_CFR_WDGTB, Prescaler);
-}
-
-/**
- * @brief Return current Watchdog Prescaler Value
- * @rmtoll CFR WDGTB LL_WWDG_GetPrescaler
- * @param WWDGx WWDG Instance
- * @retval Returned value can be one of the following values:
- * @arg @ref LL_WWDG_PRESCALER_1
- * @arg @ref LL_WWDG_PRESCALER_2
- * @arg @ref LL_WWDG_PRESCALER_4
- * @arg @ref LL_WWDG_PRESCALER_8
- */
-__STATIC_INLINE uint32_t LL_WWDG_GetPrescaler(WWDG_TypeDef *WWDGx)
-{
- return (uint32_t)(READ_BIT(WWDGx->CFR, WWDG_CFR_WDGTB));
-}
-
-/**
- * @brief Set the Watchdog Window value to be compared to the downcounter (7-bits W[6:0]).
- * @note This window value defines when write in the WWDG_CR register
- * to program Watchdog counter is allowed.
- * Watchdog counter value update must occur only when the counter value
- * is lower than the Watchdog window register value.
- * Otherwise, a MCU reset is generated if the 7-bit Watchdog counter value
- * (in the control register) is refreshed before the downcounter has reached
- * the watchdog window register value.
- * Physically is possible to set the Window lower then 0x40 but it is not recommended.
- * To generate an immediate reset, it is possible to set the Counter lower than 0x40.
- * @rmtoll CFR W LL_WWDG_SetWindow
- * @param WWDGx WWDG Instance
- * @param Window 0x00..0x7F (7 bit Window value)
- * @retval None
- */
-__STATIC_INLINE void LL_WWDG_SetWindow(WWDG_TypeDef *WWDGx, uint32_t Window)
-{
- MODIFY_REG(WWDGx->CFR, WWDG_CFR_W, Window);
-}
-
-/**
- * @brief Return current Watchdog Window Value (7 bits value)
- * @rmtoll CFR W LL_WWDG_GetWindow
- * @param WWDGx WWDG Instance
- * @retval 7 bit Watchdog Window value
- */
-__STATIC_INLINE uint32_t LL_WWDG_GetWindow(WWDG_TypeDef *WWDGx)
-{
- return (uint32_t)(READ_BIT(WWDGx->CFR, WWDG_CFR_W));
-}
-
-/**
- * @}
- */
-
-/** @defgroup WWDG_LL_EF_FLAG_Management FLAG_Management
- * @{
- */
-/**
- * @brief Indicates if the WWDG Early Wakeup Interrupt Flag is set or not.
- * @note This bit is set by hardware when the counter has reached the value 0x40.
- * It must be cleared by software by writing 0.
- * A write of 1 has no effect. This bit is also set if the interrupt is not enabled.
- * @rmtoll SR EWIF LL_WWDG_IsActiveFlag_EWKUP
- * @param WWDGx WWDG Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_WWDG_IsActiveFlag_EWKUP(WWDG_TypeDef *WWDGx)
-{
- return (READ_BIT(WWDGx->SR, WWDG_SR_EWIF) == (WWDG_SR_EWIF));
-}
-
-/**
- * @brief Clear WWDG Early Wakeup Interrupt Flag (EWIF)
- * @rmtoll SR EWIF LL_WWDG_ClearFlag_EWKUP
- * @param WWDGx WWDG Instance
- * @retval None
- */
-__STATIC_INLINE void LL_WWDG_ClearFlag_EWKUP(WWDG_TypeDef *WWDGx)
-{
- WRITE_REG(WWDGx->SR, ~WWDG_SR_EWIF);
-}
-
-/**
- * @}
- */
-
-/** @defgroup WWDG_LL_EF_IT_Management IT_Management
- * @{
- */
-/**
- * @brief Enable the Early Wakeup Interrupt.
- * @note When set, an interrupt occurs whenever the counter reaches value 0x40.
- * This interrupt is only cleared by hardware after a reset
- * @rmtoll CFR EWI LL_WWDG_EnableIT_EWKUP
- * @param WWDGx WWDG Instance
- * @retval None
- */
-__STATIC_INLINE void LL_WWDG_EnableIT_EWKUP(WWDG_TypeDef *WWDGx)
-{
- SET_BIT(WWDGx->CFR, WWDG_CFR_EWI);
-}
-
-/**
- * @brief Check if Early Wakeup Interrupt is enabled
- * @rmtoll CFR EWI LL_WWDG_IsEnabledIT_EWKUP
- * @param WWDGx WWDG Instance
- * @retval State of bit (1 or 0).
- */
-__STATIC_INLINE uint32_t LL_WWDG_IsEnabledIT_EWKUP(WWDG_TypeDef *WWDGx)
-{
- return (READ_BIT(WWDGx->CFR, WWDG_CFR_EWI) == (WWDG_CFR_EWI));
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* WWDG */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_LL_WWDG_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c
deleted file mode 100644
index a449258..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal.c
- * @author MCD Application Team
- * @brief HAL module driver.
- * This is the common part of the HAL initialization
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- The common HAL driver contains a set of generic and common APIs that can be
- used by the PPP peripheral drivers and the user to start using the HAL.
- [..]
- The HAL contains two APIs' categories:
- (+) Common HAL APIs
- (+) Services HAL APIs
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup HAL HAL
- * @brief HAL module driver.
- * @{
- */
-
-#ifdef HAL_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-
-/** @defgroup HAL_Private_Constants HAL Private Constants
- * @{
- */
-/**
- * @brief STM32F1xx HAL Driver version number V1.1.3
- */
-#define __STM32F1xx_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */
-#define __STM32F1xx_HAL_VERSION_SUB1 (0x01U) /*!< [23:16] sub1 version */
-#define __STM32F1xx_HAL_VERSION_SUB2 (0x03U) /*!< [15:8] sub2 version */
-#define __STM32F1xx_HAL_VERSION_RC (0x00U) /*!< [7:0] release candidate */
-#define __STM32F1xx_HAL_VERSION ((__STM32F1xx_HAL_VERSION_MAIN << 24)\
- |(__STM32F1xx_HAL_VERSION_SUB1 << 16)\
- |(__STM32F1xx_HAL_VERSION_SUB2 << 8 )\
- |(__STM32F1xx_HAL_VERSION_RC))
-
-#define IDCODE_DEVID_MASK 0x00000FFFU
-
-/**
- * @}
- */
-
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-
-/** @defgroup HAL_Private_Variables HAL Private Variables
- * @{
- */
-__IO uint32_t uwTick;
-uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid PRIO */
-HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */
-/**
- * @}
- */
-/* Private function prototypes -----------------------------------------------*/
-/* Exported functions ---------------------------------------------------------*/
-
-/** @defgroup HAL_Exported_Functions HAL Exported Functions
- * @{
- */
-
-/** @defgroup HAL_Exported_Functions_Group1 Initialization and de-initialization Functions
- * @brief Initialization and de-initialization functions
- *
-@verbatim
- ===============================================================================
- ##### Initialization and de-initialization functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Initializes the Flash interface, the NVIC allocation and initial clock
- configuration. It initializes the systick also when timeout is needed
- and the backup domain when enabled.
- (+) de-Initializes common part of the HAL.
- (+) Configure The time base source to have 1ms time base with a dedicated
- Tick interrupt priority.
- (++) SysTick timer is used by default as source of time base, but user
- can eventually implement his proper time base source (a general purpose
- timer for example or other time source), keeping in mind that Time base
- duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
- handled in milliseconds basis.
- (++) Time base configuration function (HAL_InitTick ()) is called automatically
- at the beginning of the program after reset by HAL_Init() or at any time
- when clock is configured, by HAL_RCC_ClockConfig().
- (++) Source of time base is configured to generate interrupts at regular
- time intervals. Care must be taken if HAL_Delay() is called from a
- peripheral ISR process, the Tick interrupt line must have higher priority
- (numerically lower) than the peripheral interrupt. Otherwise the caller
- ISR process will be blocked.
- (++) functions affecting time base configurations are declared as __weak
- to make override possible in case of other implementations in user file.
-@endverbatim
- * @{
- */
-
-/**
- * @brief This function is used to initialize the HAL Library; it must be the first
- * instruction to be executed in the main program (before to call any other
- * HAL function), it performs the following:
- * Configure the Flash prefetch.
- * Configures the SysTick to generate an interrupt each 1 millisecond,
- * which is clocked by the HSI (at this stage, the clock is not yet
- * configured and thus the system is running from the internal HSI at 16 MHz).
- * Set NVIC Group Priority to 4.
- * Calls the HAL_MspInit() callback function defined in user file
- * "stm32f1xx_hal_msp.c" to do the global low level hardware initialization
- *
- * @note SysTick is used as time base for the HAL_Delay() function, the application
- * need to ensure that the SysTick time base is always set to 1 millisecond
- * to have correct HAL operation.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_Init(void)
-{
- /* Configure Flash prefetch */
-#if (PREFETCH_ENABLE != 0)
-#if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || \
- defined(STM32F102x6) || defined(STM32F102xB) || \
- defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || \
- defined(STM32F105xC) || defined(STM32F107xC)
-
- /* Prefetch buffer is not available on value line devices */
- __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
-#endif
-#endif /* PREFETCH_ENABLE */
-
- /* Set Interrupt Group Priority */
- HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
-
- /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */
- HAL_InitTick(TICK_INT_PRIORITY);
-
- /* Init the low level hardware */
- HAL_MspInit();
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief This function de-Initializes common part of the HAL and stops the systick.
- * of time base.
- * @note This function is optional.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DeInit(void)
-{
- /* Reset of all peripherals */
- __HAL_RCC_APB1_FORCE_RESET();
- __HAL_RCC_APB1_RELEASE_RESET();
-
- __HAL_RCC_APB2_FORCE_RESET();
- __HAL_RCC_APB2_RELEASE_RESET();
-
-#if defined(STM32F105xC) || defined(STM32F107xC)
- __HAL_RCC_AHB_FORCE_RESET();
- __HAL_RCC_AHB_RELEASE_RESET();
-#endif
-
- /* De-Init the low level hardware */
- HAL_MspDeInit();
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Initialize the MSP.
- * @retval None
- */
-__weak void HAL_MspInit(void)
-{
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief DeInitializes the MSP.
- * @retval None
- */
-__weak void HAL_MspDeInit(void)
-{
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @brief This function configures the source of the time base.
- * The time source is configured to have 1ms time base with a dedicated
- * Tick interrupt priority.
- * @note This function is called automatically at the beginning of program after
- * reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig().
- * @note In the default implementation, SysTick timer is the source of time base.
- * It is used to generate interrupts at regular time intervals.
- * Care must be taken if HAL_Delay() is called from a peripheral ISR process,
- * The SysTick interrupt must have higher priority (numerically lower)
- * than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
- * The function is declared as __weak to be overwritten in case of other
- * implementation in user file.
- * @param TickPriority Tick interrupt priority.
- * @retval HAL status
- */
-__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
-{
- /* Configure the SysTick to have interrupt in 1ms time basis*/
- if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U)
- {
- return HAL_ERROR;
- }
-
- /* Configure the SysTick IRQ priority */
- if (TickPriority < (1UL << __NVIC_PRIO_BITS))
- {
- HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
- uwTickPrio = TickPriority;
- }
- else
- {
- return HAL_ERROR;
- }
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup HAL_Exported_Functions_Group2 HAL Control functions
- * @brief HAL Control functions
- *
-@verbatim
- ===============================================================================
- ##### HAL Control functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Provide a tick value in millisecond
- (+) Provide a blocking delay in millisecond
- (+) Suspend the time base source interrupt
- (+) Resume the time base source interrupt
- (+) Get the HAL API driver version
- (+) Get the device identifier
- (+) Get the device revision identifier
- (+) Enable/Disable Debug module during SLEEP mode
- (+) Enable/Disable Debug module during STOP mode
- (+) Enable/Disable Debug module during STANDBY mode
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief This function is called to increment a global variable "uwTick"
- * used as application time base.
- * @note In the default implementation, this variable is incremented each 1ms
- * in SysTick ISR.
- * @note This function is declared as __weak to be overwritten in case of other
- * implementations in user file.
- * @retval None
- */
-__weak void HAL_IncTick(void)
-{
- uwTick += uwTickFreq;
-}
-
-/**
- * @brief Provides a tick value in millisecond.
- * @note This function is declared as __weak to be overwritten in case of other
- * implementations in user file.
- * @retval tick value
- */
-__weak uint32_t HAL_GetTick(void)
-{
- return uwTick;
-}
-
-/**
- * @brief This function returns a tick priority.
- * @retval tick priority
- */
-uint32_t HAL_GetTickPrio(void)
-{
- return uwTickPrio;
-}
-
-/**
- * @brief Set new tick Freq.
- * @retval Status
- */
-HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq)
-{
- HAL_StatusTypeDef status = HAL_OK;
- assert_param(IS_TICKFREQ(Freq));
-
- if (uwTickFreq != Freq)
- {
- uwTickFreq = Freq;
-
- /* Apply the new tick Freq */
- status = HAL_InitTick(uwTickPrio);
- }
-
- return status;
-}
-
-/**
- * @brief Return tick frequency.
- * @retval tick period in Hz
- */
-HAL_TickFreqTypeDef HAL_GetTickFreq(void)
-{
- return uwTickFreq;
-}
-
-/**
- * @brief This function provides minimum delay (in milliseconds) based
- * on variable incremented.
- * @note In the default implementation , SysTick timer is the source of time base.
- * It is used to generate interrupts at regular time intervals where uwTick
- * is incremented.
- * @note This function is declared as __weak to be overwritten in case of other
- * implementations in user file.
- * @param Delay specifies the delay time length, in milliseconds.
- * @retval None
- */
-__weak void HAL_Delay(uint32_t Delay)
-{
- uint32_t tickstart = HAL_GetTick();
- uint32_t wait = Delay;
-
- /* Add a freq to guarantee minimum wait */
- if (wait < HAL_MAX_DELAY)
- {
- wait += (uint32_t)(uwTickFreq);
- }
-
- while ((HAL_GetTick() - tickstart) < wait)
- {
- }
-}
-
-/**
- * @brief Suspend Tick increment.
- * @note In the default implementation , SysTick timer is the source of time base. It is
- * used to generate interrupts at regular time intervals. Once HAL_SuspendTick()
- * is called, the SysTick interrupt will be disabled and so Tick increment
- * is suspended.
- * @note This function is declared as __weak to be overwritten in case of other
- * implementations in user file.
- * @retval None
- */
-__weak void HAL_SuspendTick(void)
-{
- /* Disable SysTick Interrupt */
- CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
-}
-
-/**
- * @brief Resume Tick increment.
- * @note In the default implementation , SysTick timer is the source of time base. It is
- * used to generate interrupts at regular time intervals. Once HAL_ResumeTick()
- * is called, the SysTick interrupt will be enabled and so Tick increment
- * is resumed.
- * @note This function is declared as __weak to be overwritten in case of other
- * implementations in user file.
- * @retval None
- */
-__weak void HAL_ResumeTick(void)
-{
- /* Enable SysTick Interrupt */
- SET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
-}
-
-/**
- * @brief Returns the HAL revision
- * @retval version 0xXYZR (8bits for each decimal, R for RC)
- */
-uint32_t HAL_GetHalVersion(void)
-{
- return __STM32F1xx_HAL_VERSION;
-}
-
-/**
- * @brief Returns the device revision identifier.
- * Note: On devices STM32F10xx8 and STM32F10xxB,
- * STM32F101xC/D/E and STM32F103xC/D/E,
- * STM32F101xF/G and STM32F103xF/G
- * STM32F10xx4 and STM32F10xx6
- * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
- * debug mode (not accessible by the user software in normal mode).
- * Refer to errata sheet of these devices for more details.
- * @retval Device revision identifier
- */
-uint32_t HAL_GetREVID(void)
-{
- return ((DBGMCU->IDCODE) >> DBGMCU_IDCODE_REV_ID_Pos);
-}
-
-/**
- * @brief Returns the device identifier.
- * Note: On devices STM32F10xx8 and STM32F10xxB,
- * STM32F101xC/D/E and STM32F103xC/D/E,
- * STM32F101xF/G and STM32F103xF/G
- * STM32F10xx4 and STM32F10xx6
- * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
- * debug mode (not accessible by the user software in normal mode).
- * Refer to errata sheet of these devices for more details.
- * @retval Device identifier
- */
-uint32_t HAL_GetDEVID(void)
-{
- return ((DBGMCU->IDCODE) & IDCODE_DEVID_MASK);
-}
-
-/**
- * @brief Enable the Debug Module during SLEEP mode
- * @retval None
- */
-void HAL_DBGMCU_EnableDBGSleepMode(void)
-{
- SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
-}
-
-/**
- * @brief Disable the Debug Module during SLEEP mode
- * Note: On devices STM32F10xx8 and STM32F10xxB,
- * STM32F101xC/D/E and STM32F103xC/D/E,
- * STM32F101xF/G and STM32F103xF/G
- * STM32F10xx4 and STM32F10xx6
- * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
- * debug mode (not accessible by the user software in normal mode).
- * Refer to errata sheet of these devices for more details.
- * @retval None
- */
-void HAL_DBGMCU_DisableDBGSleepMode(void)
-{
- CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
-}
-
-/**
- * @brief Enable the Debug Module during STOP mode
- * Note: On devices STM32F10xx8 and STM32F10xxB,
- * STM32F101xC/D/E and STM32F103xC/D/E,
- * STM32F101xF/G and STM32F103xF/G
- * STM32F10xx4 and STM32F10xx6
- * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
- * debug mode (not accessible by the user software in normal mode).
- * Refer to errata sheet of these devices for more details.
- * Note: On all STM32F1 devices:
- * If the system tick timer interrupt is enabled during the Stop mode
- * debug (DBG_STOP bit set in the DBGMCU_CR register ), it will wakeup
- * the system from Stop mode.
- * Workaround: To debug the Stop mode, disable the system tick timer
- * interrupt.
- * Refer to errata sheet of these devices for more details.
- * Note: On all STM32F1 devices:
- * If the system tick timer interrupt is enabled during the Stop mode
- * debug (DBG_STOP bit set in the DBGMCU_CR register ), it will wakeup
- * the system from Stop mode.
- * Workaround: To debug the Stop mode, disable the system tick timer
- * interrupt.
- * Refer to errata sheet of these devices for more details.
- * @retval None
- */
-void HAL_DBGMCU_EnableDBGStopMode(void)
-{
- SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
-}
-
-/**
- * @brief Disable the Debug Module during STOP mode
- * Note: On devices STM32F10xx8 and STM32F10xxB,
- * STM32F101xC/D/E and STM32F103xC/D/E,
- * STM32F101xF/G and STM32F103xF/G
- * STM32F10xx4 and STM32F10xx6
- * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
- * debug mode (not accessible by the user software in normal mode).
- * Refer to errata sheet of these devices for more details.
- * @retval None
- */
-void HAL_DBGMCU_DisableDBGStopMode(void)
-{
- CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
-}
-
-/**
- * @brief Enable the Debug Module during STANDBY mode
- * Note: On devices STM32F10xx8 and STM32F10xxB,
- * STM32F101xC/D/E and STM32F103xC/D/E,
- * STM32F101xF/G and STM32F103xF/G
- * STM32F10xx4 and STM32F10xx6
- * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
- * debug mode (not accessible by the user software in normal mode).
- * Refer to errata sheet of these devices for more details.
- * @retval None
- */
-void HAL_DBGMCU_EnableDBGStandbyMode(void)
-{
- SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
-}
-
-/**
- * @brief Disable the Debug Module during STANDBY mode
- * Note: On devices STM32F10xx8 and STM32F10xxB,
- * STM32F101xC/D/E and STM32F103xC/D/E,
- * STM32F101xF/G and STM32F103xF/G
- * STM32F10xx4 and STM32F10xx6
- * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
- * debug mode (not accessible by the user software in normal mode).
- * Refer to errata sheet of these devices for more details.
- * @retval None
- */
-void HAL_DBGMCU_DisableDBGStandbyMode(void)
-{
- CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
-}
-
-/**
- * @brief Return the unique device identifier (UID based on 96 bits)
- * @param UID pointer to 3 words array.
- * @retval Device identifier
- */
-void HAL_GetUID(uint32_t *UID)
-{
- UID[0] = (uint32_t)(READ_REG(*((uint32_t *)UID_BASE)));
- UID[1] = (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE + 4U))));
- UID[2] = (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE + 8U))));
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* HAL_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc.c
deleted file mode 100644
index de1ba75..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc.c
+++ /dev/null
@@ -1,2110 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_adc.c
- * @author MCD Application Team
- * @brief This file provides firmware functions to manage the following
- * functionalities of the Analog to Digital Convertor (ADC)
- * peripheral:
- * + Initialization and de-initialization functions
- * ++ Initialization and Configuration of ADC
- * + Operation functions
- * ++ Start, stop, get result of conversions of regular
- * group, using 3 possible modes: polling, interruption or DMA.
- * + Control functions
- * ++ Channels configuration on regular group
- * ++ Channels configuration on injected group
- * ++ Analog Watchdog configuration
- * + State functions
- * ++ ADC state machine management
- * ++ Interrupts and flags management
- * Other functions (extended functions) are available in file
- * "stm32f1xx_hal_adc_ex.c".
- *
- @verbatim
- ==============================================================================
- ##### ADC peripheral features #####
- ==============================================================================
- [..]
- (+) 12-bit resolution
-
- (+) Interrupt generation at the end of regular conversion, end of injected
- conversion, and in case of analog watchdog or overrun events.
-
- (+) Single and continuous conversion modes.
-
- (+) Scan mode for conversion of several channels sequentially.
-
- (+) Data alignment with in-built data coherency.
-
- (+) Programmable sampling time (channel wise)
-
- (+) ADC conversion of regular group and injected group.
-
- (+) External trigger (timer or EXTI)
- for both regular and injected groups.
-
- (+) DMA request generation for transfer of conversions data of regular group.
-
- (+) Multimode Dual mode (available on devices with 2 ADCs or more).
-
- (+) Configurable DMA data storage in Multimode Dual mode (available on devices
- with 2 DCs or more).
-
- (+) Configurable delay between conversions in Dual interleaved mode (available
- on devices with 2 DCs or more).
-
- (+) ADC calibration
-
- (+) ADC supply requirements: 2.4 V to 3.6 V at full speed and down to 1.8 V at
- slower speed.
-
- (+) ADC input range: from Vref- (connected to Vssa) to Vref+ (connected to
- Vdda or to an external voltage reference).
-
-
- ##### How to use this driver #####
- ==============================================================================
- [..]
-
- *** Configuration of top level parameters related to ADC ***
- ============================================================
- [..]
-
- (#) Enable the ADC interface
- (++) As prerequisite, ADC clock must be configured at RCC top level.
- Caution: On STM32F1, ADC clock frequency max is 14MHz (refer
- to device datasheet).
- Therefore, ADC clock prescaler must be configured in
- function of ADC clock source frequency to remain below
- this maximum frequency.
- (++) One clock setting is mandatory:
- ADC clock (core clock, also possibly conversion clock).
- (+++) Example:
- Into HAL_ADC_MspInit() (recommended code location) or with
- other device clock parameters configuration:
- (+++) RCC_PeriphCLKInitTypeDef PeriphClkInit;
- (+++) __ADC1_CLK_ENABLE();
- (+++) PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
- (+++) PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV2;
- (+++) HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
-
- (#) ADC pins configuration
- (++) Enable the clock for the ADC GPIOs
- using macro __HAL_RCC_GPIOx_CLK_ENABLE()
- (++) Configure these ADC pins in analog mode
- using function HAL_GPIO_Init()
-
- (#) Optionally, in case of usage of ADC with interruptions:
- (++) Configure the NVIC for ADC
- using function HAL_NVIC_EnableIRQ(ADCx_IRQn)
- (++) Insert the ADC interruption handler function HAL_ADC_IRQHandler()
- into the function of corresponding ADC interruption vector
- ADCx_IRQHandler().
-
- (#) Optionally, in case of usage of DMA:
- (++) Configure the DMA (DMA channel, mode normal or circular, ...)
- using function HAL_DMA_Init().
- (++) Configure the NVIC for DMA
- using function HAL_NVIC_EnableIRQ(DMAx_Channelx_IRQn)
- (++) Insert the ADC interruption handler function HAL_ADC_IRQHandler()
- into the function of corresponding DMA interruption vector
- DMAx_Channelx_IRQHandler().
-
- *** Configuration of ADC, groups regular/injected, channels parameters ***
- ==========================================================================
- [..]
-
- (#) Configure the ADC parameters (resolution, data alignment, ...)
- and regular group parameters (conversion trigger, sequencer, ...)
- using function HAL_ADC_Init().
-
- (#) Configure the channels for regular group parameters (channel number,
- channel rank into sequencer, ..., into regular group)
- using function HAL_ADC_ConfigChannel().
-
- (#) Optionally, configure the injected group parameters (conversion trigger,
- sequencer, ..., of injected group)
- and the channels for injected group parameters (channel number,
- channel rank into sequencer, ..., into injected group)
- using function HAL_ADCEx_InjectedConfigChannel().
-
- (#) Optionally, configure the analog watchdog parameters (channels
- monitored, thresholds, ...)
- using function HAL_ADC_AnalogWDGConfig().
-
- (#) Optionally, for devices with several ADC instances: configure the
- multimode parameters
- using function HAL_ADCEx_MultiModeConfigChannel().
-
- *** Execution of ADC conversions ***
- ====================================
- [..]
-
- (#) Optionally, perform an automatic ADC calibration to improve the
- conversion accuracy
- using function HAL_ADCEx_Calibration_Start().
-
- (#) ADC driver can be used among three modes: polling, interruption,
- transfer by DMA.
-
- (++) ADC conversion by polling:
- (+++) Activate the ADC peripheral and start conversions
- using function HAL_ADC_Start()
- (+++) Wait for ADC conversion completion
- using function HAL_ADC_PollForConversion()
- (or for injected group: HAL_ADCEx_InjectedPollForConversion() )
- (+++) Retrieve conversion results
- using function HAL_ADC_GetValue()
- (or for injected group: HAL_ADCEx_InjectedGetValue() )
- (+++) Stop conversion and disable the ADC peripheral
- using function HAL_ADC_Stop()
-
- (++) ADC conversion by interruption:
- (+++) Activate the ADC peripheral and start conversions
- using function HAL_ADC_Start_IT()
- (+++) Wait for ADC conversion completion by call of function
- HAL_ADC_ConvCpltCallback()
- (this function must be implemented in user program)
- (or for injected group: HAL_ADCEx_InjectedConvCpltCallback() )
- (+++) Retrieve conversion results
- using function HAL_ADC_GetValue()
- (or for injected group: HAL_ADCEx_InjectedGetValue() )
- (+++) Stop conversion and disable the ADC peripheral
- using function HAL_ADC_Stop_IT()
-
- (++) ADC conversion with transfer by DMA:
- (+++) Activate the ADC peripheral and start conversions
- using function HAL_ADC_Start_DMA()
- (+++) Wait for ADC conversion completion by call of function
- HAL_ADC_ConvCpltCallback() or HAL_ADC_ConvHalfCpltCallback()
- (these functions must be implemented in user program)
- (+++) Conversion results are automatically transferred by DMA into
- destination variable address.
- (+++) Stop conversion and disable the ADC peripheral
- using function HAL_ADC_Stop_DMA()
-
- (++) For devices with several ADCs: ADC multimode conversion
- with transfer by DMA:
- (+++) Activate the ADC peripheral (slave) and start conversions
- using function HAL_ADC_Start()
- (+++) Activate the ADC peripheral (master) and start conversions
- using function HAL_ADCEx_MultiModeStart_DMA()
- (+++) Wait for ADC conversion completion by call of function
- HAL_ADC_ConvCpltCallback() or HAL_ADC_ConvHalfCpltCallback()
- (these functions must be implemented in user program)
- (+++) Conversion results are automatically transferred by DMA into
- destination variable address.
- (+++) Stop conversion and disable the ADC peripheral (master)
- using function HAL_ADCEx_MultiModeStop_DMA()
- (+++) Stop conversion and disable the ADC peripheral (slave)
- using function HAL_ADC_Stop_IT()
-
- [..]
-
- (@) Callback functions must be implemented in user program:
- (+@) HAL_ADC_ErrorCallback()
- (+@) HAL_ADC_LevelOutOfWindowCallback() (callback of analog watchdog)
- (+@) HAL_ADC_ConvCpltCallback()
- (+@) HAL_ADC_ConvHalfCpltCallback
- (+@) HAL_ADCEx_InjectedConvCpltCallback()
-
- *** Deinitialization of ADC ***
- ============================================================
- [..]
-
- (#) Disable the ADC interface
- (++) ADC clock can be hard reset and disabled at RCC top level.
- (++) Hard reset of ADC peripherals
- using macro __ADCx_FORCE_RESET(), __ADCx_RELEASE_RESET().
- (++) ADC clock disable
- using the equivalent macro/functions as configuration step.
- (+++) Example:
- Into HAL_ADC_MspDeInit() (recommended code location) or with
- other device clock parameters configuration:
- (+++) PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC
- (+++) PeriphClkInit.AdcClockSelection = RCC_ADCPLLCLK2_OFF
- (+++) HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit)
-
- (#) ADC pins configuration
- (++) Disable the clock for the ADC GPIOs
- using macro __HAL_RCC_GPIOx_CLK_DISABLE()
-
- (#) Optionally, in case of usage of ADC with interruptions:
- (++) Disable the NVIC for ADC
- using function HAL_NVIC_EnableIRQ(ADCx_IRQn)
-
- (#) Optionally, in case of usage of DMA:
- (++) Deinitialize the DMA
- using function HAL_DMA_Init().
- (++) Disable the NVIC for DMA
- using function HAL_NVIC_EnableIRQ(DMAx_Channelx_IRQn)
-
- [..]
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup ADC ADC
- * @brief ADC HAL module driver
- * @{
- */
-
-#ifdef HAL_ADC_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @defgroup ADC_Private_Constants ADC Private Constants
- * @{
- */
-
- /* Timeout values for ADC enable and disable settling time. */
- /* Values defined to be higher than worst cases: low clocks freq, */
- /* maximum prescaler. */
- /* Ex of profile low frequency : Clock source at 0.1 MHz, ADC clock */
- /* prescaler 4, sampling time 12.5 ADC clock cycles, resolution 12 bits. */
- /* Unit: ms */
- #define ADC_ENABLE_TIMEOUT 2U
- #define ADC_DISABLE_TIMEOUT 2U
-
- /* Delay for ADC stabilization time. */
- /* Maximum delay is 1us (refer to device datasheet, parameter tSTAB). */
- /* Unit: us */
- #define ADC_STAB_DELAY_US 1U
-
- /* Delay for temperature sensor stabilization time. */
- /* Maximum delay is 10us (refer to device datasheet, parameter tSTART). */
- /* Unit: us */
- #define ADC_TEMPSENSOR_DELAY_US 10U
-
-/**
- * @}
- */
-
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @defgroup ADC_Private_Functions ADC Private Functions
- * @{
- */
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-
-/** @defgroup ADC_Exported_Functions ADC Exported Functions
- * @{
- */
-
-/** @defgroup ADC_Exported_Functions_Group1 Initialization/de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
- ===============================================================================
- ##### Initialization and de-initialization functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Initialize and configure the ADC.
- (+) De-initialize the ADC.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the ADC peripheral and regular group according to
- * parameters specified in structure "ADC_InitTypeDef".
- * @note As prerequisite, ADC clock must be configured at RCC top level
- * (clock source APB2).
- * See commented example code below that can be copied and uncommented
- * into HAL_ADC_MspInit().
- * @note Possibility to update parameters on the fly:
- * This function initializes the ADC MSP (HAL_ADC_MspInit()) only when
- * coming from ADC state reset. Following calls to this function can
- * be used to reconfigure some parameters of ADC_InitTypeDef
- * structure on the fly, without modifying MSP configuration. If ADC
- * MSP has to be modified again, HAL_ADC_DeInit() must be called
- * before HAL_ADC_Init().
- * The setting of these parameters is conditioned to ADC state.
- * For parameters constraints, see comments of structure
- * "ADC_InitTypeDef".
- * @note This function configures the ADC within 2 scopes: scope of entire
- * ADC and scope of regular group. For parameters details, see comments
- * of structure "ADC_InitTypeDef".
- * @param hadc: ADC handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc)
-{
- HAL_StatusTypeDef tmp_hal_status = HAL_OK;
- uint32_t tmp_cr1 = 0U;
- uint32_t tmp_cr2 = 0U;
- uint32_t tmp_sqr1 = 0U;
-
- /* Check ADC handle */
- if(hadc == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
- assert_param(IS_ADC_DATA_ALIGN(hadc->Init.DataAlign));
- assert_param(IS_ADC_SCAN_MODE(hadc->Init.ScanConvMode));
- assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
- assert_param(IS_ADC_EXTTRIG(hadc->Init.ExternalTrigConv));
-
- if(hadc->Init.ScanConvMode != ADC_SCAN_DISABLE)
- {
- assert_param(IS_ADC_REGULAR_NB_CONV(hadc->Init.NbrOfConversion));
- assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DiscontinuousConvMode));
- if(hadc->Init.DiscontinuousConvMode != DISABLE)
- {
- assert_param(IS_ADC_REGULAR_DISCONT_NUMBER(hadc->Init.NbrOfDiscConversion));
- }
- }
-
- /* As prerequisite, into HAL_ADC_MspInit(), ADC clock must be configured */
- /* at RCC top level. */
- /* Refer to header of this file for more details on clock enabling */
- /* procedure. */
-
- /* Actions performed only if ADC is coming from state reset: */
- /* - Initialization of ADC MSP */
- if (hadc->State == HAL_ADC_STATE_RESET)
- {
- /* Initialize ADC error code */
- ADC_CLEAR_ERRORCODE(hadc);
-
- /* Allocate lock resource and initialize it */
- hadc->Lock = HAL_UNLOCKED;
-
- /* Init the low level hardware */
- HAL_ADC_MspInit(hadc);
- }
-
- /* Stop potential conversion on going, on regular and injected groups */
- /* Disable ADC peripheral */
- /* Note: In case of ADC already enabled, precaution to not launch an */
- /* unwanted conversion while modifying register CR2 by writing 1 to */
- /* bit ADON. */
- tmp_hal_status = ADC_ConversionStop_Disable(hadc);
-
-
- /* Configuration of ADC parameters if previous preliminary actions are */
- /* correctly completed. */
- if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL) &&
- (tmp_hal_status == HAL_OK) )
- {
- /* Set ADC state */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
- HAL_ADC_STATE_BUSY_INTERNAL);
-
- /* Set ADC parameters */
-
- /* Configuration of ADC: */
- /* - data alignment */
- /* - external trigger to start conversion */
- /* - external trigger polarity (always set to 1, because needed for all */
- /* triggers: external trigger of SW start) */
- /* - continuous conversion mode */
- /* Note: External trigger polarity (ADC_CR2_EXTTRIG) is set into */
- /* HAL_ADC_Start_xxx functions because if set in this function, */
- /* a conversion on injected group would start a conversion also on */
- /* regular group after ADC enabling. */
- tmp_cr2 |= (hadc->Init.DataAlign |
- ADC_CFGR_EXTSEL(hadc, hadc->Init.ExternalTrigConv) |
- ADC_CR2_CONTINUOUS(hadc->Init.ContinuousConvMode) );
-
- /* Configuration of ADC: */
- /* - scan mode */
- /* - discontinuous mode disable/enable */
- /* - discontinuous mode number of conversions */
- tmp_cr1 |= (ADC_CR1_SCAN_SET(hadc->Init.ScanConvMode));
-
- /* Enable discontinuous mode only if continuous mode is disabled */
- /* Note: If parameter "Init.ScanConvMode" is set to disable, parameter */
- /* discontinuous is set anyway, but will have no effect on ADC HW. */
- if (hadc->Init.DiscontinuousConvMode == ENABLE)
- {
- if (hadc->Init.ContinuousConvMode == DISABLE)
- {
- /* Enable the selected ADC regular discontinuous mode */
- /* Set the number of channels to be converted in discontinuous mode */
- SET_BIT(tmp_cr1, ADC_CR1_DISCEN |
- ADC_CR1_DISCONTINUOUS_NUM(hadc->Init.NbrOfDiscConversion) );
- }
- else
- {
- /* ADC regular group settings continuous and sequencer discontinuous*/
- /* cannot be enabled simultaneously. */
-
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-
- /* Set ADC error code to ADC IP internal error */
- SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
- }
- }
-
- /* Update ADC configuration register CR1 with previous settings */
- MODIFY_REG(hadc->Instance->CR1,
- ADC_CR1_SCAN |
- ADC_CR1_DISCEN |
- ADC_CR1_DISCNUM ,
- tmp_cr1 );
-
- /* Update ADC configuration register CR2 with previous settings */
- MODIFY_REG(hadc->Instance->CR2,
- ADC_CR2_ALIGN |
- ADC_CR2_EXTSEL |
- ADC_CR2_EXTTRIG |
- ADC_CR2_CONT ,
- tmp_cr2 );
-
- /* Configuration of regular group sequencer: */
- /* - if scan mode is disabled, regular channels sequence length is set to */
- /* 0x00: 1 channel converted (channel on regular rank 1) */
- /* Parameter "NbrOfConversion" is discarded. */
- /* Note: Scan mode is present by hardware on this device and, if */
- /* disabled, discards automatically nb of conversions. Anyway, nb of */
- /* conversions is forced to 0x00 for alignment over all STM32 devices. */
- /* - if scan mode is enabled, regular channels sequence length is set to */
- /* parameter "NbrOfConversion" */
- if (ADC_CR1_SCAN_SET(hadc->Init.ScanConvMode) == ADC_SCAN_ENABLE)
- {
- tmp_sqr1 = ADC_SQR1_L_SHIFT(hadc->Init.NbrOfConversion);
- }
-
- MODIFY_REG(hadc->Instance->SQR1,
- ADC_SQR1_L ,
- tmp_sqr1 );
-
- /* Check back that ADC registers have effectively been configured to */
- /* ensure of no potential problem of ADC core IP clocking. */
- /* Check through register CR2 (excluding bits set in other functions: */
- /* execution control bits (ADON, JSWSTART, SWSTART), regular group bits */
- /* (DMA), injected group bits (JEXTTRIG and JEXTSEL), channel internal */
- /* measurement path bit (TSVREFE). */
- if (READ_BIT(hadc->Instance->CR2, ~(ADC_CR2_ADON | ADC_CR2_DMA |
- ADC_CR2_SWSTART | ADC_CR2_JSWSTART |
- ADC_CR2_JEXTTRIG | ADC_CR2_JEXTSEL |
- ADC_CR2_TSVREFE ))
- == tmp_cr2)
- {
- /* Set ADC error code to none */
- ADC_CLEAR_ERRORCODE(hadc);
-
- /* Set the ADC state */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_BUSY_INTERNAL,
- HAL_ADC_STATE_READY);
- }
- else
- {
- /* Update ADC state machine to error */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_BUSY_INTERNAL,
- HAL_ADC_STATE_ERROR_INTERNAL);
-
- /* Set ADC error code to ADC IP internal error */
- SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
-
- tmp_hal_status = HAL_ERROR;
- }
-
- }
- else
- {
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
-
- tmp_hal_status = HAL_ERROR;
- }
-
- /* Return function status */
- return tmp_hal_status;
-}
-
-/**
- * @brief Deinitialize the ADC peripheral registers to their default reset
- * values, with deinitialization of the ADC MSP.
- * If needed, the example code can be copied and uncommented into
- * function HAL_ADC_MspDeInit().
- * @param hadc: ADC handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef* hadc)
-{
- HAL_StatusTypeDef tmp_hal_status = HAL_OK;
-
- /* Check ADC handle */
- if(hadc == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
- /* Set ADC state */
- SET_BIT(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL);
-
- /* Stop potential conversion on going, on regular and injected groups */
- /* Disable ADC peripheral */
- tmp_hal_status = ADC_ConversionStop_Disable(hadc);
-
-
- /* Configuration of ADC parameters if previous preliminary actions are */
- /* correctly completed. */
- if (tmp_hal_status == HAL_OK)
- {
- /* ========== Reset ADC registers ========== */
-
-
-
-
- /* Reset register SR */
- __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_AWD | ADC_FLAG_JEOC | ADC_FLAG_EOC |
- ADC_FLAG_JSTRT | ADC_FLAG_STRT));
-
- /* Reset register CR1 */
- CLEAR_BIT(hadc->Instance->CR1, (ADC_CR1_AWDEN | ADC_CR1_JAWDEN | ADC_CR1_DISCNUM |
- ADC_CR1_JDISCEN | ADC_CR1_DISCEN | ADC_CR1_JAUTO |
- ADC_CR1_AWDSGL | ADC_CR1_SCAN | ADC_CR1_JEOCIE |
- ADC_CR1_AWDIE | ADC_CR1_EOCIE | ADC_CR1_AWDCH ));
-
- /* Reset register CR2 */
- CLEAR_BIT(hadc->Instance->CR2, (ADC_CR2_TSVREFE | ADC_CR2_SWSTART | ADC_CR2_JSWSTART |
- ADC_CR2_EXTTRIG | ADC_CR2_EXTSEL | ADC_CR2_JEXTTRIG |
- ADC_CR2_JEXTSEL | ADC_CR2_ALIGN | ADC_CR2_DMA |
- ADC_CR2_RSTCAL | ADC_CR2_CAL | ADC_CR2_CONT |
- ADC_CR2_ADON ));
-
- /* Reset register SMPR1 */
- CLEAR_BIT(hadc->Instance->SMPR1, (ADC_SMPR1_SMP17 | ADC_SMPR1_SMP16 | ADC_SMPR1_SMP15 |
- ADC_SMPR1_SMP14 | ADC_SMPR1_SMP13 | ADC_SMPR1_SMP12 |
- ADC_SMPR1_SMP11 | ADC_SMPR1_SMP10 ));
-
- /* Reset register SMPR2 */
- CLEAR_BIT(hadc->Instance->SMPR2, (ADC_SMPR2_SMP9 | ADC_SMPR2_SMP8 | ADC_SMPR2_SMP7 |
- ADC_SMPR2_SMP6 | ADC_SMPR2_SMP5 | ADC_SMPR2_SMP4 |
- ADC_SMPR2_SMP3 | ADC_SMPR2_SMP2 | ADC_SMPR2_SMP1 |
- ADC_SMPR2_SMP0 ));
-
- /* Reset register JOFR1 */
- CLEAR_BIT(hadc->Instance->JOFR1, ADC_JOFR1_JOFFSET1);
- /* Reset register JOFR2 */
- CLEAR_BIT(hadc->Instance->JOFR2, ADC_JOFR2_JOFFSET2);
- /* Reset register JOFR3 */
- CLEAR_BIT(hadc->Instance->JOFR3, ADC_JOFR3_JOFFSET3);
- /* Reset register JOFR4 */
- CLEAR_BIT(hadc->Instance->JOFR4, ADC_JOFR4_JOFFSET4);
-
- /* Reset register HTR */
- CLEAR_BIT(hadc->Instance->HTR, ADC_HTR_HT);
- /* Reset register LTR */
- CLEAR_BIT(hadc->Instance->LTR, ADC_LTR_LT);
-
- /* Reset register SQR1 */
- CLEAR_BIT(hadc->Instance->SQR1, ADC_SQR1_L |
- ADC_SQR1_SQ16 | ADC_SQR1_SQ15 |
- ADC_SQR1_SQ14 | ADC_SQR1_SQ13 );
-
- /* Reset register SQR1 */
- CLEAR_BIT(hadc->Instance->SQR1, ADC_SQR1_L |
- ADC_SQR1_SQ16 | ADC_SQR1_SQ15 |
- ADC_SQR1_SQ14 | ADC_SQR1_SQ13 );
-
- /* Reset register SQR2 */
- CLEAR_BIT(hadc->Instance->SQR2, ADC_SQR2_SQ12 | ADC_SQR2_SQ11 | ADC_SQR2_SQ10 |
- ADC_SQR2_SQ9 | ADC_SQR2_SQ8 | ADC_SQR2_SQ7 );
-
- /* Reset register SQR3 */
- CLEAR_BIT(hadc->Instance->SQR3, ADC_SQR3_SQ6 | ADC_SQR3_SQ5 | ADC_SQR3_SQ4 |
- ADC_SQR3_SQ3 | ADC_SQR3_SQ2 | ADC_SQR3_SQ1 );
-
- /* Reset register JSQR */
- CLEAR_BIT(hadc->Instance->JSQR, ADC_JSQR_JL |
- ADC_JSQR_JSQ4 | ADC_JSQR_JSQ3 |
- ADC_JSQR_JSQ2 | ADC_JSQR_JSQ1 );
-
- /* Reset register JSQR */
- CLEAR_BIT(hadc->Instance->JSQR, ADC_JSQR_JL |
- ADC_JSQR_JSQ4 | ADC_JSQR_JSQ3 |
- ADC_JSQR_JSQ2 | ADC_JSQR_JSQ1 );
-
- /* Reset register DR */
- /* bits in access mode read only, no direct reset applicable*/
-
- /* Reset registers JDR1, JDR2, JDR3, JDR4 */
- /* bits in access mode read only, no direct reset applicable*/
-
- /* ========== Hard reset ADC peripheral ========== */
- /* Performs a global reset of the entire ADC peripheral: ADC state is */
- /* forced to a similar state after device power-on. */
- /* If needed, copy-paste and uncomment the following reset code into */
- /* function "void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)": */
- /* */
- /* __HAL_RCC_ADC1_FORCE_RESET() */
- /* __HAL_RCC_ADC1_RELEASE_RESET() */
-
- /* DeInit the low level hardware */
- HAL_ADC_MspDeInit(hadc);
-
- /* Set ADC error code to none */
- ADC_CLEAR_ERRORCODE(hadc);
-
- /* Set ADC state */
- hadc->State = HAL_ADC_STATE_RESET;
-
- }
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- /* Return function status */
- return tmp_hal_status;
-}
-
-/**
- * @brief Initializes the ADC MSP.
- * @param hadc: ADC handle
- * @retval None
- */
-__weak void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hadc);
- /* NOTE : This function should not be modified. When the callback is needed,
- function HAL_ADC_MspInit must be implemented in the user file.
- */
-}
-
-/**
- * @brief DeInitializes the ADC MSP.
- * @param hadc: ADC handle
- * @retval None
- */
-__weak void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hadc);
- /* NOTE : This function should not be modified. When the callback is needed,
- function HAL_ADC_MspDeInit must be implemented in the user file.
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup ADC_Exported_Functions_Group2 IO operation functions
- * @brief Input and Output operation functions
- *
-@verbatim
- ===============================================================================
- ##### IO operation functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Start conversion of regular group.
- (+) Stop conversion of regular group.
- (+) Poll for conversion complete on regular group.
- (+) Poll for conversion event.
- (+) Get result of regular channel conversion.
- (+) Start conversion of regular group and enable interruptions.
- (+) Stop conversion of regular group and disable interruptions.
- (+) Handle ADC interrupt request
- (+) Start conversion of regular group and enable DMA transfer.
- (+) Stop conversion of regular group and disable ADC DMA transfer.
-@endverbatim
- * @{
- */
-
-/**
- * @brief Enables ADC, starts conversion of regular group.
- * Interruptions enabled in this function: None.
- * @param hadc: ADC handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc)
-{
- HAL_StatusTypeDef tmp_hal_status = HAL_OK;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
- /* Process locked */
- __HAL_LOCK(hadc);
-
- /* Enable the ADC peripheral */
- tmp_hal_status = ADC_Enable(hadc);
-
- /* Start conversion if ADC is effectively enabled */
- if (tmp_hal_status == HAL_OK)
- {
- /* Set ADC state */
- /* - Clear state bitfield related to regular group conversion results */
- /* - Set state bitfield related to regular operation */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC,
- HAL_ADC_STATE_REG_BUSY);
-
- /* Set group injected state (from auto-injection) and multimode state */
- /* for all cases of multimode: independent mode, multimode ADC master */
- /* or multimode ADC slave (for devices with several ADCs): */
- if (ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc))
- {
- /* Set ADC state (ADC independent or master) */
- CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
-
- /* If conversions on group regular are also triggering group injected, */
- /* update ADC state. */
- if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET)
- {
- ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
- }
- }
- else
- {
- /* Set ADC state (ADC slave) */
- SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
-
- /* If conversions on group regular are also triggering group injected, */
- /* update ADC state. */
- if (ADC_MULTIMODE_AUTO_INJECTED(hadc))
- {
- ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
- }
- }
-
- /* State machine update: Check if an injected conversion is ongoing */
- if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY))
- {
- /* Reset ADC error code fields related to conversions on group regular */
- CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA));
- }
- else
- {
- /* Reset ADC all error code fields */
- ADC_CLEAR_ERRORCODE(hadc);
- }
-
- /* Process unlocked */
- /* Unlock before starting ADC conversions: in case of potential */
- /* interruption, to let the process to ADC IRQ Handler. */
- __HAL_UNLOCK(hadc);
-
- /* Clear regular group conversion flag */
- /* (To ensure of no unknown state from potential previous ADC operations) */
- __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC);
-
- /* Enable conversion of regular group. */
- /* If software start has been selected, conversion starts immediately. */
- /* If external trigger has been selected, conversion will start at next */
- /* trigger event. */
- /* Case of multimode enabled: */
- /* - if ADC is slave, ADC is enabled only (conversion is not started). */
- /* - if ADC is master, ADC is enabled and conversion is started. */
- /* If ADC is master, ADC is enabled and conversion is started. */
- /* Note: Alternate trigger for single conversion could be to force an */
- /* additional set of bit ADON "hadc->Instance->CR2 |= ADC_CR2_ADON;"*/
- if (ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
- ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc) )
- {
- /* Start ADC conversion on regular group with SW start */
- SET_BIT(hadc->Instance->CR2, (ADC_CR2_SWSTART | ADC_CR2_EXTTRIG));
- }
- else
- {
- /* Start ADC conversion on regular group with external trigger */
- SET_BIT(hadc->Instance->CR2, ADC_CR2_EXTTRIG);
- }
- }
- else
- {
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
- }
-
- /* Return function status */
- return tmp_hal_status;
-}
-
-/**
- * @brief Stop ADC conversion of regular group (and injected channels in
- * case of auto_injection mode), disable ADC peripheral.
- * @note: ADC peripheral disable is forcing stop of potential
- * conversion on injected group. If injected group is under use, it
- * should be preliminarily stopped using HAL_ADCEx_InjectedStop function.
- * @param hadc: ADC handle
- * @retval HAL status.
- */
-HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc)
-{
- HAL_StatusTypeDef tmp_hal_status = HAL_OK;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
- /* Process locked */
- __HAL_LOCK(hadc);
-
- /* Stop potential conversion on going, on regular and injected groups */
- /* Disable ADC peripheral */
- tmp_hal_status = ADC_ConversionStop_Disable(hadc);
-
- /* Check if ADC is effectively disabled */
- if (tmp_hal_status == HAL_OK)
- {
- /* Set ADC state */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
- HAL_ADC_STATE_READY);
- }
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- /* Return function status */
- return tmp_hal_status;
-}
-
-/**
- * @brief Wait for regular group conversion to be completed.
- * @note This function cannot be used in a particular setup: ADC configured
- * in DMA mode.
- * In this case, DMA resets the flag EOC and polling cannot be
- * performed on each conversion.
- * @note On STM32F1 devices, limitation in case of sequencer enabled
- * (several ranks selected): polling cannot be done on each
- * conversion inside the sequence. In this case, polling is replaced by
- * wait for maximum conversion time.
- * @param hadc: ADC handle
- * @param Timeout: Timeout value in millisecond.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)
-{
- uint32_t tickstart = 0U;
-
- /* Variables for polling in case of scan mode enabled and polling for each */
- /* conversion. */
- __IO uint32_t Conversion_Timeout_CPU_cycles = 0U;
- uint32_t Conversion_Timeout_CPU_cycles_max = 0U;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
- /* Get tick count */
- tickstart = HAL_GetTick();
-
- /* Verification that ADC configuration is compliant with polling for */
- /* each conversion: */
- /* Particular case is ADC configured in DMA mode */
- if (HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_DMA))
- {
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- return HAL_ERROR;
- }
-
- /* Polling for end of conversion: differentiation if single/sequence */
- /* conversion. */
- /* - If single conversion for regular group (Scan mode disabled or enabled */
- /* with NbrOfConversion =1), flag EOC is used to determine the */
- /* conversion completion. */
- /* - If sequence conversion for regular group (scan mode enabled and */
- /* NbrOfConversion >=2), flag EOC is set only at the end of the */
- /* sequence. */
- /* To poll for each conversion, the maximum conversion time is computed */
- /* from ADC conversion time (selected sampling time + conversion time of */
- /* 12.5 ADC clock cycles) and APB2/ADC clock prescalers (depending on */
- /* settings, conversion time range can be from 28 to 32256 CPU cycles). */
- /* As flag EOC is not set after each conversion, no timeout status can */
- /* be set. */
- if (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_SCAN) &&
- HAL_IS_BIT_CLR(hadc->Instance->SQR1, ADC_SQR1_L) )
- {
- /* Wait until End of Conversion flag is raised */
- while(HAL_IS_BIT_CLR(hadc->Instance->SR, ADC_FLAG_EOC))
- {
- /* Check if timeout is disabled (set to infinite wait) */
- if(Timeout != HAL_MAX_DELAY)
- {
- if((Timeout == 0U) || ((HAL_GetTick() - tickstart ) > Timeout))
- {
- /* Update ADC state machine to timeout */
- SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- return HAL_TIMEOUT;
- }
- }
- }
- }
- else
- {
- /* Replace polling by wait for maximum conversion time */
- /* - Computation of CPU clock cycles corresponding to ADC clock cycles */
- /* and ADC maximum conversion cycles on all channels. */
- /* - Wait for the expected ADC clock cycles delay */
- Conversion_Timeout_CPU_cycles_max = ((SystemCoreClock
- / HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_ADC))
- * ADC_CONVCYCLES_MAX_RANGE(hadc) );
-
- while(Conversion_Timeout_CPU_cycles < Conversion_Timeout_CPU_cycles_max)
- {
- /* Check if timeout is disabled (set to infinite wait) */
- if(Timeout != HAL_MAX_DELAY)
- {
- if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
- {
- /* Update ADC state machine to timeout */
- SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- return HAL_TIMEOUT;
- }
- }
- Conversion_Timeout_CPU_cycles ++;
- }
- }
-
- /* Clear regular group conversion flag */
- __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_STRT | ADC_FLAG_EOC);
-
- /* Update ADC state machine */
- SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
-
- /* Determine whether any further conversion upcoming on group regular */
- /* by external trigger, continuous mode or scan sequence on going. */
- /* Note: On STM32F1 devices, in case of sequencer enabled */
- /* (several ranks selected), end of conversion flag is raised */
- /* at the end of the sequence. */
- if(ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
- (hadc->Init.ContinuousConvMode == DISABLE) )
- {
- /* Set ADC state */
- CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
-
- if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY))
- {
- SET_BIT(hadc->State, HAL_ADC_STATE_READY);
- }
- }
-
- /* Return ADC state */
- return HAL_OK;
-}
-
-/**
- * @brief Poll for conversion event.
- * @param hadc: ADC handle
- * @param EventType: the ADC event type.
- * This parameter can be one of the following values:
- * @arg ADC_AWD_EVENT: ADC Analog watchdog event.
- * @param Timeout: Timeout value in millisecond.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventType, uint32_t Timeout)
-{
- uint32_t tickstart = 0U;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
- assert_param(IS_ADC_EVENT_TYPE(EventType));
-
- /* Get tick count */
- tickstart = HAL_GetTick();
-
- /* Check selected event flag */
- while(__HAL_ADC_GET_FLAG(hadc, EventType) == RESET)
- {
- /* Check if timeout is disabled (set to infinite wait) */
- if(Timeout != HAL_MAX_DELAY)
- {
- if((Timeout == 0U) || ((HAL_GetTick() - tickstart ) > Timeout))
- {
- /* Update ADC state machine to timeout */
- SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- return HAL_TIMEOUT;
- }
- }
- }
-
- /* Analog watchdog (level out of window) event */
- /* Set ADC state */
- SET_BIT(hadc->State, HAL_ADC_STATE_AWD1);
-
- /* Clear ADC analog watchdog flag */
- __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD);
-
- /* Return ADC state */
- return HAL_OK;
-}
-
-/**
- * @brief Enables ADC, starts conversion of regular group with interruption.
- * Interruptions enabled in this function:
- * - EOC (end of conversion of regular group)
- * Each of these interruptions has its dedicated callback function.
- * @param hadc: ADC handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc)
-{
- HAL_StatusTypeDef tmp_hal_status = HAL_OK;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
- /* Process locked */
- __HAL_LOCK(hadc);
-
- /* Enable the ADC peripheral */
- tmp_hal_status = ADC_Enable(hadc);
-
- /* Start conversion if ADC is effectively enabled */
- if (tmp_hal_status == HAL_OK)
- {
- /* Set ADC state */
- /* - Clear state bitfield related to regular group conversion results */
- /* - Set state bitfield related to regular operation */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP,
- HAL_ADC_STATE_REG_BUSY);
-
- /* Set group injected state (from auto-injection) and multimode state */
- /* for all cases of multimode: independent mode, multimode ADC master */
- /* or multimode ADC slave (for devices with several ADCs): */
- if (ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc))
- {
- /* Set ADC state (ADC independent or master) */
- CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
-
- /* If conversions on group regular are also triggering group injected, */
- /* update ADC state. */
- if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET)
- {
- ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
- }
- }
- else
- {
- /* Set ADC state (ADC slave) */
- SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
-
- /* If conversions on group regular are also triggering group injected, */
- /* update ADC state. */
- if (ADC_MULTIMODE_AUTO_INJECTED(hadc))
- {
- ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
- }
- }
-
- /* State machine update: Check if an injected conversion is ongoing */
- if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY))
- {
- /* Reset ADC error code fields related to conversions on group regular */
- CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA));
- }
- else
- {
- /* Reset ADC all error code fields */
- ADC_CLEAR_ERRORCODE(hadc);
- }
-
- /* Process unlocked */
- /* Unlock before starting ADC conversions: in case of potential */
- /* interruption, to let the process to ADC IRQ Handler. */
- __HAL_UNLOCK(hadc);
-
- /* Clear regular group conversion flag and overrun flag */
- /* (To ensure of no unknown state from potential previous ADC operations) */
- __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC);
-
- /* Enable end of conversion interrupt for regular group */
- __HAL_ADC_ENABLE_IT(hadc, ADC_IT_EOC);
-
- /* Enable conversion of regular group. */
- /* If software start has been selected, conversion starts immediately. */
- /* If external trigger has been selected, conversion will start at next */
- /* trigger event. */
- /* Case of multimode enabled: */
- /* - if ADC is slave, ADC is enabled only (conversion is not started). */
- /* - if ADC is master, ADC is enabled and conversion is started. */
- if (ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
- ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc) )
- {
- /* Start ADC conversion on regular group with SW start */
- SET_BIT(hadc->Instance->CR2, (ADC_CR2_SWSTART | ADC_CR2_EXTTRIG));
- }
- else
- {
- /* Start ADC conversion on regular group with external trigger */
- SET_BIT(hadc->Instance->CR2, ADC_CR2_EXTTRIG);
- }
- }
- else
- {
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
- }
-
- /* Return function status */
- return tmp_hal_status;
-}
-
-/**
- * @brief Stop ADC conversion of regular group (and injected group in
- * case of auto_injection mode), disable interrution of
- * end-of-conversion, disable ADC peripheral.
- * @param hadc: ADC handle
- * @retval None
- */
-HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc)
-{
- HAL_StatusTypeDef tmp_hal_status = HAL_OK;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
- /* Process locked */
- __HAL_LOCK(hadc);
-
- /* Stop potential conversion on going, on regular and injected groups */
- /* Disable ADC peripheral */
- tmp_hal_status = ADC_ConversionStop_Disable(hadc);
-
- /* Check if ADC is effectively disabled */
- if (tmp_hal_status == HAL_OK)
- {
- /* Disable ADC end of conversion interrupt for regular group */
- __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC);
-
- /* Set ADC state */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
- HAL_ADC_STATE_READY);
- }
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- /* Return function status */
- return tmp_hal_status;
-}
-
-/**
- * @brief Enables ADC, starts conversion of regular group and transfers result
- * through DMA.
- * Interruptions enabled in this function:
- * - DMA transfer complete
- * - DMA half transfer
- * Each of these interruptions has its dedicated callback function.
- * @note For devices with several ADCs: This function is for single-ADC mode
- * only. For multimode, use the dedicated MultimodeStart function.
- * @note On STM32F1 devices, only ADC1 and ADC3 (ADC availability depending
- * on devices) have DMA capability.
- * ADC2 converted data can be transferred in dual ADC mode using DMA
- * of ADC1 (ADC master in multimode).
- * In case of using ADC1 with DMA on a device featuring 2 ADC
- * instances: ADC1 conversion register DR contains ADC1 conversion
- * result (ADC1 register DR bits 0 to 11) and, additionally, ADC2 last
- * conversion result (ADC1 register DR bits 16 to 27). Therefore, to
- * have DMA transferring the conversion results of ADC1 only, DMA must
- * be configured to transfer size: half word.
- * @param hadc: ADC handle
- * @param pData: The destination Buffer address.
- * @param Length: The length of data to be transferred from ADC peripheral to memory.
- * @retval None
- */
-HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length)
-{
- HAL_StatusTypeDef tmp_hal_status = HAL_OK;
-
- /* Check the parameters */
- assert_param(IS_ADC_DMA_CAPABILITY_INSTANCE(hadc->Instance));
-
- /* Verification if multimode is disabled (for devices with several ADC) */
- /* If multimode is enabled, dedicated function multimode conversion */
- /* start DMA must be used. */
- if(ADC_MULTIMODE_IS_ENABLE(hadc) == RESET)
- {
- /* Process locked */
- __HAL_LOCK(hadc);
-
- /* Enable the ADC peripheral */
- tmp_hal_status = ADC_Enable(hadc);
-
- /* Start conversion if ADC is effectively enabled */
- if (tmp_hal_status == HAL_OK)
- {
- /* Set ADC state */
- /* - Clear state bitfield related to regular group conversion results */
- /* - Set state bitfield related to regular operation */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP,
- HAL_ADC_STATE_REG_BUSY);
-
- /* Set group injected state (from auto-injection) and multimode state */
- /* for all cases of multimode: independent mode, multimode ADC master */
- /* or multimode ADC slave (for devices with several ADCs): */
- if (ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc))
- {
- /* Set ADC state (ADC independent or master) */
- CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
-
- /* If conversions on group regular are also triggering group injected, */
- /* update ADC state. */
- if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET)
- {
- ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
- }
- }
- else
- {
- /* Set ADC state (ADC slave) */
- SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
-
- /* If conversions on group regular are also triggering group injected, */
- /* update ADC state. */
- if (ADC_MULTIMODE_AUTO_INJECTED(hadc))
- {
- ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
- }
- }
-
- /* State machine update: Check if an injected conversion is ongoing */
- if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY))
- {
- /* Reset ADC error code fields related to conversions on group regular */
- CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA));
- }
- else
- {
- /* Reset ADC all error code fields */
- ADC_CLEAR_ERRORCODE(hadc);
- }
-
- /* Process unlocked */
- /* Unlock before starting ADC conversions: in case of potential */
- /* interruption, to let the process to ADC IRQ Handler. */
- __HAL_UNLOCK(hadc);
-
- /* Set the DMA transfer complete callback */
- hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt;
-
- /* Set the DMA half transfer complete callback */
- hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt;
-
- /* Set the DMA error callback */
- hadc->DMA_Handle->XferErrorCallback = ADC_DMAError;
-
-
- /* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC */
- /* start (in case of SW start): */
-
- /* Clear regular group conversion flag and overrun flag */
- /* (To ensure of no unknown state from potential previous ADC */
- /* operations) */
- __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC);
-
- /* Enable ADC DMA mode */
- SET_BIT(hadc->Instance->CR2, ADC_CR2_DMA);
-
- /* Start the DMA channel */
- HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length);
-
- /* Enable conversion of regular group. */
- /* If software start has been selected, conversion starts immediately. */
- /* If external trigger has been selected, conversion will start at next */
- /* trigger event. */
- if (ADC_IS_SOFTWARE_START_REGULAR(hadc))
- {
- /* Start ADC conversion on regular group with SW start */
- SET_BIT(hadc->Instance->CR2, (ADC_CR2_SWSTART | ADC_CR2_EXTTRIG));
- }
- else
- {
- /* Start ADC conversion on regular group with external trigger */
- SET_BIT(hadc->Instance->CR2, ADC_CR2_EXTTRIG);
- }
- }
- else
- {
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
- }
- }
- else
- {
- tmp_hal_status = HAL_ERROR;
- }
-
- /* Return function status */
- return tmp_hal_status;
-}
-
-/**
- * @brief Stop ADC conversion of regular group (and injected group in
- * case of auto_injection mode), disable ADC DMA transfer, disable
- * ADC peripheral.
- * @note: ADC peripheral disable is forcing stop of potential
- * conversion on injected group. If injected group is under use, it
- * should be preliminarily stopped using HAL_ADCEx_InjectedStop function.
- * @note For devices with several ADCs: This function is for single-ADC mode
- * only. For multimode, use the dedicated MultimodeStop function.
- * @note On STM32F1 devices, only ADC1 and ADC3 (ADC availability depending
- * on devices) have DMA capability.
- * @param hadc: ADC handle
- * @retval HAL status.
- */
-HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc)
-{
- HAL_StatusTypeDef tmp_hal_status = HAL_OK;
-
- /* Check the parameters */
- assert_param(IS_ADC_DMA_CAPABILITY_INSTANCE(hadc->Instance));
-
- /* Process locked */
- __HAL_LOCK(hadc);
-
- /* Stop potential conversion on going, on regular and injected groups */
- /* Disable ADC peripheral */
- tmp_hal_status = ADC_ConversionStop_Disable(hadc);
-
- /* Check if ADC is effectively disabled */
- if (tmp_hal_status == HAL_OK)
- {
- /* Disable ADC DMA mode */
- CLEAR_BIT(hadc->Instance->CR2, ADC_CR2_DMA);
-
- /* Disable the DMA channel (in case of DMA in circular mode or stop while */
- /* DMA transfer is on going) */
- tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
-
- /* Check if DMA channel effectively disabled */
- if (tmp_hal_status == HAL_OK)
- {
- /* Set ADC state */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
- HAL_ADC_STATE_READY);
- }
- else
- {
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
- }
- }
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- /* Return function status */
- return tmp_hal_status;
-}
-
-/**
- * @brief Get ADC regular group conversion result.
- * @note Reading register DR automatically clears ADC flag EOC
- * (ADC group regular end of unitary conversion).
- * @note This function does not clear ADC flag EOS
- * (ADC group regular end of sequence conversion).
- * Occurrence of flag EOS rising:
- * - If sequencer is composed of 1 rank, flag EOS is equivalent
- * to flag EOC.
- * - If sequencer is composed of several ranks, during the scan
- * sequence flag EOC only is raised, at the end of the scan sequence
- * both flags EOC and EOS are raised.
- * To clear this flag, either use function:
- * in programming model IT: @ref HAL_ADC_IRQHandler(), in programming
- * model polling: @ref HAL_ADC_PollForConversion()
- * or @ref __HAL_ADC_CLEAR_FLAG(&hadc, ADC_FLAG_EOS).
- * @param hadc: ADC handle
- * @retval ADC group regular conversion data
- */
-uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc)
-{
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
- /* Note: EOC flag is not cleared here by software because automatically */
- /* cleared by hardware when reading register DR. */
-
- /* Return ADC converted value */
- return hadc->Instance->DR;
-}
-
-/**
- * @brief Handles ADC interrupt request
- * @param hadc: ADC handle
- * @retval None
- */
-void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc)
-{
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
- assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
- assert_param(IS_ADC_REGULAR_NB_CONV(hadc->Init.NbrOfConversion));
-
-
- /* ========== Check End of Conversion flag for regular group ========== */
- if(__HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_EOC))
- {
- if(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOC) )
- {
- /* Update state machine on conversion status if not in error state */
- if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL))
- {
- /* Set ADC state */
- SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
- }
-
- /* Determine whether any further conversion upcoming on group regular */
- /* by external trigger, continuous mode or scan sequence on going. */
- /* Note: On STM32F1 devices, in case of sequencer enabled */
- /* (several ranks selected), end of conversion flag is raised */
- /* at the end of the sequence. */
- if(ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
- (hadc->Init.ContinuousConvMode == DISABLE) )
- {
- /* Disable ADC end of conversion interrupt on group regular */
- __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC);
-
- /* Set ADC state */
- CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
-
- if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY))
- {
- SET_BIT(hadc->State, HAL_ADC_STATE_READY);
- }
- }
-
- /* Conversion complete callback */
- HAL_ADC_ConvCpltCallback(hadc);
-
- /* Clear regular group conversion flag */
- __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_STRT | ADC_FLAG_EOC);
- }
- }
-
- /* ========== Check End of Conversion flag for injected group ========== */
- if(__HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_JEOC))
- {
- if(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOC))
- {
- /* Update state machine on conversion status if not in error state */
- if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL))
- {
- /* Set ADC state */
- SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC);
- }
-
- /* Determine whether any further conversion upcoming on group injected */
- /* by external trigger, scan sequence on going or by automatic injected */
- /* conversion from group regular (same conditions as group regular */
- /* interruption disabling above). */
- /* Note: On STM32F1 devices, in case of sequencer enabled */
- /* (several ranks selected), end of conversion flag is raised */
- /* at the end of the sequence. */
- if(ADC_IS_SOFTWARE_START_INJECTED(hadc) ||
- (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) &&
- (ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
- (hadc->Init.ContinuousConvMode == DISABLE) ) ) )
- {
- /* Disable ADC end of conversion interrupt on group injected */
- __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);
-
- /* Set ADC state */
- CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
-
- if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
- {
- SET_BIT(hadc->State, HAL_ADC_STATE_READY);
- }
- }
-
- /* Conversion complete callback */
- HAL_ADCEx_InjectedConvCpltCallback(hadc);
-
- /* Clear injected group conversion flag */
- __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JSTRT | ADC_FLAG_JEOC));
- }
- }
-
- /* ========== Check Analog watchdog flags ========== */
- if(__HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_AWD))
- {
- if(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_AWD))
- {
- /* Set ADC state */
- SET_BIT(hadc->State, HAL_ADC_STATE_AWD1);
-
- /* Level out of window callback */
- HAL_ADC_LevelOutOfWindowCallback(hadc);
-
- /* Clear the ADC analog watchdog flag */
- __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD);
- }
- }
-
-}
-
-/**
- * @brief Conversion complete callback in non blocking mode
- * @param hadc: ADC handle
- * @retval None
- */
-__weak void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hadc);
- /* NOTE : This function should not be modified. When the callback is needed,
- function HAL_ADC_ConvCpltCallback must be implemented in the user file.
- */
-}
-
-/**
- * @brief Conversion DMA half-transfer callback in non blocking mode
- * @param hadc: ADC handle
- * @retval None
- */
-__weak void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hadc);
- /* NOTE : This function should not be modified. When the callback is needed,
- function HAL_ADC_ConvHalfCpltCallback must be implemented in the user file.
- */
-}
-
-/**
- * @brief Analog watchdog callback in non blocking mode.
- * @param hadc: ADC handle
- * @retval None
- */
-__weak void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hadc);
- /* NOTE : This function should not be modified. When the callback is needed,
- function HAL_ADC_LevelOutOfWindowCallback must be implemented in the user file.
- */
-}
-
-/**
- * @brief ADC error callback in non blocking mode
- * (ADC conversion with interruption or transfer by DMA)
- * @param hadc: ADC handle
- * @retval None
- */
-__weak void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hadc);
- /* NOTE : This function should not be modified. When the callback is needed,
- function HAL_ADC_ErrorCallback must be implemented in the user file.
- */
-}
-
-
-/**
- * @}
- */
-
-/** @defgroup ADC_Exported_Functions_Group3 Peripheral Control functions
- * @brief Peripheral Control functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral Control functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Configure channels on regular group
- (+) Configure the analog watchdog
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Configures the the selected channel to be linked to the regular
- * group.
- * @note In case of usage of internal measurement channels:
- * Vbat/VrefInt/TempSensor.
- * These internal paths can be be disabled using function
- * HAL_ADC_DeInit().
- * @note Possibility to update parameters on the fly:
- * This function initializes channel into regular group, following
- * calls to this function can be used to reconfigure some parameters
- * of structure "ADC_ChannelConfTypeDef" on the fly, without reseting
- * the ADC.
- * The setting of these parameters is conditioned to ADC state.
- * For parameters constraints, see comments of structure
- * "ADC_ChannelConfTypeDef".
- * @param hadc: ADC handle
- * @param sConfig: Structure of ADC channel for regular group.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig)
-{
- HAL_StatusTypeDef tmp_hal_status = HAL_OK;
- __IO uint32_t wait_loop_index = 0U;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
- assert_param(IS_ADC_CHANNEL(sConfig->Channel));
- assert_param(IS_ADC_REGULAR_RANK(sConfig->Rank));
- assert_param(IS_ADC_SAMPLE_TIME(sConfig->SamplingTime));
-
- /* Process locked */
- __HAL_LOCK(hadc);
-
-
- /* Regular sequence configuration */
- /* For Rank 1 to 6 */
- if (sConfig->Rank < 7U)
- {
- MODIFY_REG(hadc->Instance->SQR3 ,
- ADC_SQR3_RK(ADC_SQR3_SQ1, sConfig->Rank) ,
- ADC_SQR3_RK(sConfig->Channel, sConfig->Rank) );
- }
- /* For Rank 7 to 12 */
- else if (sConfig->Rank < 13U)
- {
- MODIFY_REG(hadc->Instance->SQR2 ,
- ADC_SQR2_RK(ADC_SQR2_SQ7, sConfig->Rank) ,
- ADC_SQR2_RK(sConfig->Channel, sConfig->Rank) );
- }
- /* For Rank 13 to 16 */
- else
- {
- MODIFY_REG(hadc->Instance->SQR1 ,
- ADC_SQR1_RK(ADC_SQR1_SQ13, sConfig->Rank) ,
- ADC_SQR1_RK(sConfig->Channel, sConfig->Rank) );
- }
-
-
- /* Channel sampling time configuration */
- /* For channels 10 to 17 */
- if (sConfig->Channel >= ADC_CHANNEL_10)
- {
- MODIFY_REG(hadc->Instance->SMPR1 ,
- ADC_SMPR1(ADC_SMPR1_SMP10, sConfig->Channel) ,
- ADC_SMPR1(sConfig->SamplingTime, sConfig->Channel) );
- }
- else /* For channels 0 to 9 */
- {
- MODIFY_REG(hadc->Instance->SMPR2 ,
- ADC_SMPR2(ADC_SMPR2_SMP0, sConfig->Channel) ,
- ADC_SMPR2(sConfig->SamplingTime, sConfig->Channel) );
- }
-
- /* If ADC1 Channel_16 or Channel_17 is selected, enable Temperature sensor */
- /* and VREFINT measurement path. */
- if ((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) ||
- (sConfig->Channel == ADC_CHANNEL_VREFINT) )
- {
- /* For STM32F1 devices with several ADC: Only ADC1 can access internal */
- /* measurement channels (VrefInt/TempSensor). If these channels are */
- /* intended to be set on other ADC instances, an error is reported. */
- if (hadc->Instance == ADC1)
- {
- if (READ_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE) == RESET)
- {
- SET_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE);
-
- if ((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR))
- {
- /* Delay for temperature sensor stabilization time */
- /* Compute number of CPU cycles to wait for */
- wait_loop_index = (ADC_TEMPSENSOR_DELAY_US * (SystemCoreClock / 1000000U));
- while(wait_loop_index != 0U)
- {
- wait_loop_index--;
- }
- }
- }
- }
- else
- {
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-
- tmp_hal_status = HAL_ERROR;
- }
- }
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- /* Return function status */
- return tmp_hal_status;
-}
-
-/**
- * @brief Configures the analog watchdog.
- * @note Analog watchdog thresholds can be modified while ADC conversion
- * is on going.
- * In this case, some constraints must be taken into account:
- * the programmed threshold values are effective from the next
- * ADC EOC (end of unitary conversion).
- * Considering that registers write delay may happen due to
- * bus activity, this might cause an uncertainty on the
- * effective timing of the new programmed threshold values.
- * @param hadc: ADC handle
- * @param AnalogWDGConfig: Structure of ADC analog watchdog configuration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDGConfTypeDef* AnalogWDGConfig)
-{
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
- assert_param(IS_ADC_ANALOG_WATCHDOG_MODE(AnalogWDGConfig->WatchdogMode));
- assert_param(IS_FUNCTIONAL_STATE(AnalogWDGConfig->ITMode));
- assert_param(IS_ADC_RANGE(AnalogWDGConfig->HighThreshold));
- assert_param(IS_ADC_RANGE(AnalogWDGConfig->LowThreshold));
-
- if((AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REG) ||
- (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_INJEC) ||
- (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC) )
- {
- assert_param(IS_ADC_CHANNEL(AnalogWDGConfig->Channel));
- }
-
- /* Process locked */
- __HAL_LOCK(hadc);
-
- /* Analog watchdog configuration */
-
- /* Configure ADC Analog watchdog interrupt */
- if(AnalogWDGConfig->ITMode == ENABLE)
- {
- /* Enable the ADC Analog watchdog interrupt */
- __HAL_ADC_ENABLE_IT(hadc, ADC_IT_AWD);
- }
- else
- {
- /* Disable the ADC Analog watchdog interrupt */
- __HAL_ADC_DISABLE_IT(hadc, ADC_IT_AWD);
- }
-
- /* Configuration of analog watchdog: */
- /* - Set the analog watchdog enable mode: regular and/or injected groups, */
- /* one or all channels. */
- /* - Set the Analog watchdog channel (is not used if watchdog */
- /* mode "all channels": ADC_CFGR_AWD1SGL=0). */
- MODIFY_REG(hadc->Instance->CR1 ,
- ADC_CR1_AWDSGL |
- ADC_CR1_JAWDEN |
- ADC_CR1_AWDEN |
- ADC_CR1_AWDCH ,
- AnalogWDGConfig->WatchdogMode |
- AnalogWDGConfig->Channel );
-
- /* Set the high threshold */
- WRITE_REG(hadc->Instance->HTR, AnalogWDGConfig->HighThreshold);
-
- /* Set the low threshold */
- WRITE_REG(hadc->Instance->LTR, AnalogWDGConfig->LowThreshold);
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- /* Return function status */
- return HAL_OK;
-}
-
-
-/**
- * @}
- */
-
-
-/** @defgroup ADC_Exported_Functions_Group4 Peripheral State functions
- * @brief Peripheral State functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral State and Errors functions #####
- ===============================================================================
- [..]
- This subsection provides functions to get in run-time the status of the
- peripheral.
- (+) Check the ADC state
- (+) Check the ADC error code
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief return the ADC state
- * @param hadc: ADC handle
- * @retval HAL state
- */
-uint32_t HAL_ADC_GetState(ADC_HandleTypeDef* hadc)
-{
- /* Return ADC state */
- return hadc->State;
-}
-
-/**
- * @brief Return the ADC error code
- * @param hadc: ADC handle
- * @retval ADC Error Code
- */
-uint32_t HAL_ADC_GetError(ADC_HandleTypeDef *hadc)
-{
- return hadc->ErrorCode;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @defgroup ADC_Private_Functions ADC Private Functions
- * @{
- */
-
-/**
- * @brief Enable the selected ADC.
- * @note Prerequisite condition to use this function: ADC must be disabled
- * and voltage regulator must be enabled (done into HAL_ADC_Init()).
- * @param hadc: ADC handle
- * @retval HAL status.
- */
-HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef* hadc)
-{
- uint32_t tickstart = 0U;
- __IO uint32_t wait_loop_index = 0U;
-
- /* ADC enable and wait for ADC ready (in case of ADC is disabled or */
- /* enabling phase not yet completed: flag ADC ready not yet set). */
- /* Timeout implemented to not be stuck if ADC cannot be enabled (possible */
- /* causes: ADC clock not running, ...). */
- if (ADC_IS_ENABLE(hadc) == RESET)
- {
- /* Enable the Peripheral */
- __HAL_ADC_ENABLE(hadc);
-
- /* Delay for ADC stabilization time */
- /* Compute number of CPU cycles to wait for */
- wait_loop_index = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000U));
- while(wait_loop_index != 0U)
- {
- wait_loop_index--;
- }
-
- /* Get tick count */
- tickstart = HAL_GetTick();
-
- /* Wait for ADC effectively enabled */
- while(ADC_IS_ENABLE(hadc) == RESET)
- {
- if((HAL_GetTick() - tickstart) > ADC_ENABLE_TIMEOUT)
- {
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
-
- /* Set ADC error code to ADC IP internal error */
- SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- return HAL_ERROR;
- }
- }
- }
-
- /* Return HAL status */
- return HAL_OK;
-}
-
-/**
- * @brief Stop ADC conversion and disable the selected ADC
- * @note Prerequisite condition to use this function: ADC conversions must be
- * stopped to disable the ADC.
- * @param hadc: ADC handle
- * @retval HAL status.
- */
-HAL_StatusTypeDef ADC_ConversionStop_Disable(ADC_HandleTypeDef* hadc)
-{
- uint32_t tickstart = 0U;
-
- /* Verification if ADC is not already disabled */
- if (ADC_IS_ENABLE(hadc) != RESET)
- {
- /* Disable the ADC peripheral */
- __HAL_ADC_DISABLE(hadc);
-
- /* Get tick count */
- tickstart = HAL_GetTick();
-
- /* Wait for ADC effectively disabled */
- while(ADC_IS_ENABLE(hadc) != RESET)
- {
- if((HAL_GetTick() - tickstart) > ADC_DISABLE_TIMEOUT)
- {
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
-
- /* Set ADC error code to ADC IP internal error */
- SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
-
- return HAL_ERROR;
- }
- }
- }
-
- /* Return HAL status */
- return HAL_OK;
-}
-
-/**
- * @brief DMA transfer complete callback.
- * @param hdma: pointer to DMA handle.
- * @retval None
- */
-void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma)
-{
- /* Retrieve ADC handle corresponding to current DMA handle */
- ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- /* Update state machine on conversion status if not in error state */
- if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL | HAL_ADC_STATE_ERROR_DMA))
- {
- /* Update ADC state machine */
- SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
-
- /* Determine whether any further conversion upcoming on group regular */
- /* by external trigger, continuous mode or scan sequence on going. */
- /* Note: On STM32F1 devices, in case of sequencer enabled */
- /* (several ranks selected), end of conversion flag is raised */
- /* at the end of the sequence. */
- if(ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
- (hadc->Init.ContinuousConvMode == DISABLE) )
- {
- /* Set ADC state */
- CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
-
- if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY))
- {
- SET_BIT(hadc->State, HAL_ADC_STATE_READY);
- }
- }
-
- /* Conversion complete callback */
- HAL_ADC_ConvCpltCallback(hadc);
- }
- else
- {
- /* Call DMA error callback */
- hadc->DMA_Handle->XferErrorCallback(hdma);
- }
-}
-
-/**
- * @brief DMA half transfer complete callback.
- * @param hdma: pointer to DMA handle.
- * @retval None
- */
-void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma)
-{
- /* Retrieve ADC handle corresponding to current DMA handle */
- ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- /* Half conversion callback */
- HAL_ADC_ConvHalfCpltCallback(hadc);
-}
-
-/**
- * @brief DMA error callback
- * @param hdma: pointer to DMA handle.
- * @retval None
- */
-void ADC_DMAError(DMA_HandleTypeDef *hdma)
-{
- /* Retrieve ADC handle corresponding to current DMA handle */
- ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- /* Set ADC state */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
-
- /* Set ADC error code to DMA error */
- SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_DMA);
-
- /* Error callback */
- HAL_ADC_ErrorCallback(hadc);
-}
-
-/**
- * @}
- */
-
-#endif /* HAL_ADC_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc_ex.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc_ex.c
deleted file mode 100644
index 2d539a2..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc_ex.c
+++ /dev/null
@@ -1,1339 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_adc_ex.c
- * @author MCD Application Team
- * @brief This file provides firmware functions to manage the following
- * functionalities of the Analog to Digital Convertor (ADC)
- * peripheral:
- * + Operation functions
- * ++ Start, stop, get result of conversions of injected
- * group, using 2 possible modes: polling, interruption.
- * ++ Multimode feature (available on devices with 2 ADCs or more)
- * ++ Calibration (ADC automatic self-calibration)
- * + Control functions
- * ++ Channels configuration on injected group
- * Other functions (generic functions) are available in file
- * "stm32f1xx_hal_adc.c".
- *
- @verbatim
- [..]
- (@) Sections "ADC peripheral features" and "How to use this driver" are
- available in file of generic functions "stm32f1xx_hal_adc.c".
- [..]
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup ADCEx ADCEx
- * @brief ADC Extension HAL module driver
- * @{
- */
-
-#ifdef HAL_ADC_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @defgroup ADCEx_Private_Constants ADCEx Private Constants
- * @{
- */
-
- /* Delay for ADC calibration: */
- /* Hardware prerequisite before starting a calibration: the ADC must have */
- /* been in power-on state for at least two ADC clock cycles. */
- /* Unit: ADC clock cycles */
- #define ADC_PRECALIBRATION_DELAY_ADCCLOCKCYCLES 2U
-
- /* Timeout value for ADC calibration */
- /* Value defined to be higher than worst cases: low clocks freq, */
- /* maximum prescaler. */
- /* Ex of profile low frequency : Clock source at 0.1 MHz, ADC clock */
- /* prescaler 4, sampling time 12.5 ADC clock cycles, resolution 12 bits. */
- /* Unit: ms */
- #define ADC_CALIBRATION_TIMEOUT 10U
-
- /* Delay for temperature sensor stabilization time. */
- /* Maximum delay is 10us (refer to device datasheet, parameter tSTART). */
- /* Unit: us */
- #define ADC_TEMPSENSOR_DELAY_US 10U
-
-/**
- * @}
- */
-
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
-
-/** @defgroup ADCEx_Exported_Functions ADCEx Exported Functions
- * @{
- */
-
-/** @defgroup ADCEx_Exported_Functions_Group1 Extended Extended IO operation functions
- * @brief Extended Extended Input and Output operation functions
- *
-@verbatim
- ===============================================================================
- ##### IO operation functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Start conversion of injected group.
- (+) Stop conversion of injected group.
- (+) Poll for conversion complete on injected group.
- (+) Get result of injected channel conversion.
- (+) Start conversion of injected group and enable interruptions.
- (+) Stop conversion of injected group and disable interruptions.
-
- (+) Start multimode and enable DMA transfer.
- (+) Stop multimode and disable ADC DMA transfer.
- (+) Get result of multimode conversion.
-
- (+) Perform the ADC self-calibration for single or differential ending.
- (+) Get calibration factors for single or differential ending.
- (+) Set calibration factors for single or differential ending.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Perform an ADC automatic self-calibration
- * Calibration prerequisite: ADC must be disabled (execute this
- * function before HAL_ADC_Start() or after HAL_ADC_Stop() ).
- * During calibration process, ADC is enabled. ADC is let enabled at
- * the completion of this function.
- * @param hadc: ADC handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc)
-{
- HAL_StatusTypeDef tmp_hal_status = HAL_OK;
- uint32_t tickstart;
- __IO uint32_t wait_loop_index = 0U;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
- /* Process locked */
- __HAL_LOCK(hadc);
-
- /* 1. Calibration prerequisite: */
- /* - ADC must be disabled for at least two ADC clock cycles in disable */
- /* mode before ADC enable */
- /* Stop potential conversion on going, on regular and injected groups */
- /* Disable ADC peripheral */
- tmp_hal_status = ADC_ConversionStop_Disable(hadc);
-
- /* Check if ADC is effectively disabled */
- if (tmp_hal_status == HAL_OK)
- {
- /* Set ADC state */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
- HAL_ADC_STATE_BUSY_INTERNAL);
-
- /* Hardware prerequisite: delay before starting the calibration. */
- /* - Computation of CPU clock cycles corresponding to ADC clock cycles. */
- /* - Wait for the expected ADC clock cycles delay */
- wait_loop_index = ((SystemCoreClock
- / HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_ADC))
- * ADC_PRECALIBRATION_DELAY_ADCCLOCKCYCLES );
-
- while(wait_loop_index != 0U)
- {
- wait_loop_index--;
- }
-
- /* 2. Enable the ADC peripheral */
- ADC_Enable(hadc);
-
- /* 3. Resets ADC calibration registers */
- SET_BIT(hadc->Instance->CR2, ADC_CR2_RSTCAL);
-
- tickstart = HAL_GetTick();
-
- /* Wait for calibration reset completion */
- while(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_RSTCAL))
- {
- if((HAL_GetTick() - tickstart) > ADC_CALIBRATION_TIMEOUT)
- {
- /* Update ADC state machine to error */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_BUSY_INTERNAL,
- HAL_ADC_STATE_ERROR_INTERNAL);
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- return HAL_ERROR;
- }
- }
-
-
- /* 4. Start ADC calibration */
- SET_BIT(hadc->Instance->CR2, ADC_CR2_CAL);
-
- tickstart = HAL_GetTick();
-
- /* Wait for calibration completion */
- while(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_CAL))
- {
- if((HAL_GetTick() - tickstart) > ADC_CALIBRATION_TIMEOUT)
- {
- /* Update ADC state machine to error */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_BUSY_INTERNAL,
- HAL_ADC_STATE_ERROR_INTERNAL);
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- return HAL_ERROR;
- }
- }
-
- /* Set ADC state */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_BUSY_INTERNAL,
- HAL_ADC_STATE_READY);
- }
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- /* Return function status */
- return tmp_hal_status;
-}
-
-/**
- * @brief Enables ADC, starts conversion of injected group.
- * Interruptions enabled in this function: None.
- * @param hadc: ADC handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef* hadc)
-{
- HAL_StatusTypeDef tmp_hal_status = HAL_OK;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
- /* Process locked */
- __HAL_LOCK(hadc);
-
- /* Enable the ADC peripheral */
- tmp_hal_status = ADC_Enable(hadc);
-
- /* Start conversion if ADC is effectively enabled */
- if (tmp_hal_status == HAL_OK)
- {
- /* Set ADC state */
- /* - Clear state bitfield related to injected group conversion results */
- /* - Set state bitfield related to injected operation */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
- HAL_ADC_STATE_INJ_BUSY);
-
- /* Case of independent mode or multimode (for devices with several ADCs): */
- /* Set multimode state. */
- if (ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc))
- {
- CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
- }
- else
- {
- SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
- }
-
- /* Check if a regular conversion is ongoing */
- /* Note: On this device, there is no ADC error code fields related to */
- /* conversions on group injected only. In case of conversion on */
- /* going on group regular, no error code is reset. */
- if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
- {
- /* Reset ADC all error code fields */
- ADC_CLEAR_ERRORCODE(hadc);
- }
-
- /* Process unlocked */
- /* Unlock before starting ADC conversions: in case of potential */
- /* interruption, to let the process to ADC IRQ Handler. */
- __HAL_UNLOCK(hadc);
-
- /* Clear injected group conversion flag */
- /* (To ensure of no unknown state from potential previous ADC operations) */
- __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC);
-
- /* Enable conversion of injected group. */
- /* If software start has been selected, conversion starts immediately. */
- /* If external trigger has been selected, conversion will start at next */
- /* trigger event. */
- /* If automatic injected conversion is enabled, conversion will start */
- /* after next regular group conversion. */
- /* Case of multimode enabled (for devices with several ADCs): if ADC is */
- /* slave, ADC is enabled only (conversion is not started). If ADC is */
- /* master, ADC is enabled and conversion is started. */
- if (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO))
- {
- if (ADC_IS_SOFTWARE_START_INJECTED(hadc) &&
- ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc) )
- {
- /* Start ADC conversion on injected group with SW start */
- SET_BIT(hadc->Instance->CR2, (ADC_CR2_JSWSTART | ADC_CR2_JEXTTRIG));
- }
- else
- {
- /* Start ADC conversion on injected group with external trigger */
- SET_BIT(hadc->Instance->CR2, ADC_CR2_JEXTTRIG);
- }
- }
- }
- else
- {
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
- }
-
- /* Return function status */
- return tmp_hal_status;
-}
-
-/**
- * @brief Stop conversion of injected channels. Disable ADC peripheral if
- * no regular conversion is on going.
- * @note If ADC must be disabled and if conversion is on going on
- * regular group, function HAL_ADC_Stop must be used to stop both
- * injected and regular groups, and disable the ADC.
- * @note If injected group mode auto-injection is enabled,
- * function HAL_ADC_Stop must be used.
- * @note In case of auto-injection mode, HAL_ADC_Stop must be used.
- * @param hadc: ADC handle
- * @retval None
- */
-HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef* hadc)
-{
- HAL_StatusTypeDef tmp_hal_status = HAL_OK;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
- /* Process locked */
- __HAL_LOCK(hadc);
-
- /* Stop potential conversion and disable ADC peripheral */
- /* Conditioned to: */
- /* - No conversion on the other group (regular group) is intended to */
- /* continue (injected and regular groups stop conversion and ADC disable */
- /* are common) */
- /* - In case of auto-injection mode, HAL_ADC_Stop must be used. */
- if(((hadc->State & HAL_ADC_STATE_REG_BUSY) == RESET) &&
- HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) )
- {
- /* Stop potential conversion on going, on regular and injected groups */
- /* Disable ADC peripheral */
- tmp_hal_status = ADC_ConversionStop_Disable(hadc);
-
- /* Check if ADC is effectively disabled */
- if (tmp_hal_status == HAL_OK)
- {
- /* Set ADC state */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
- HAL_ADC_STATE_READY);
- }
- }
- else
- {
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-
- tmp_hal_status = HAL_ERROR;
- }
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- /* Return function status */
- return tmp_hal_status;
-}
-
-/**
- * @brief Wait for injected group conversion to be completed.
- * @param hadc: ADC handle
- * @param Timeout: Timeout value in millisecond.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)
-{
- uint32_t tickstart;
-
- /* Variables for polling in case of scan mode enabled and polling for each */
- /* conversion. */
- __IO uint32_t Conversion_Timeout_CPU_cycles = 0U;
- uint32_t Conversion_Timeout_CPU_cycles_max = 0U;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
- /* Get timeout */
- tickstart = HAL_GetTick();
-
- /* Polling for end of conversion: differentiation if single/sequence */
- /* conversion. */
- /* For injected group, flag JEOC is set only at the end of the sequence, */
- /* not for each conversion within the sequence. */
- /* - If single conversion for injected group (scan mode disabled or */
- /* InjectedNbrOfConversion ==1), flag JEOC is used to determine the */
- /* conversion completion. */
- /* - If sequence conversion for injected group (scan mode enabled and */
- /* InjectedNbrOfConversion >=2), flag JEOC is set only at the end of the */
- /* sequence. */
- /* To poll for each conversion, the maximum conversion time is computed */
- /* from ADC conversion time (selected sampling time + conversion time of */
- /* 12.5 ADC clock cycles) and APB2/ADC clock prescalers (depending on */
- /* settings, conversion time range can be from 28 to 32256 CPU cycles). */
- /* As flag JEOC is not set after each conversion, no timeout status can */
- /* be set. */
- if ((hadc->Instance->JSQR & ADC_JSQR_JL) == RESET)
- {
- /* Wait until End of Conversion flag is raised */
- while(HAL_IS_BIT_CLR(hadc->Instance->SR, ADC_FLAG_JEOC))
- {
- /* Check if timeout is disabled (set to infinite wait) */
- if(Timeout != HAL_MAX_DELAY)
- {
- if((Timeout == 0U) || ((HAL_GetTick() - tickstart ) > Timeout))
- {
- /* Update ADC state machine to timeout */
- SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- return HAL_TIMEOUT;
- }
- }
- }
- }
- else
- {
- /* Replace polling by wait for maximum conversion time */
- /* - Computation of CPU clock cycles corresponding to ADC clock cycles */
- /* and ADC maximum conversion cycles on all channels. */
- /* - Wait for the expected ADC clock cycles delay */
- Conversion_Timeout_CPU_cycles_max = ((SystemCoreClock
- / HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_ADC))
- * ADC_CONVCYCLES_MAX_RANGE(hadc) );
-
- while(Conversion_Timeout_CPU_cycles < Conversion_Timeout_CPU_cycles_max)
- {
- /* Check if timeout is disabled (set to infinite wait) */
- if(Timeout != HAL_MAX_DELAY)
- {
- if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
- {
- /* Update ADC state machine to timeout */
- SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- return HAL_TIMEOUT;
- }
- }
- Conversion_Timeout_CPU_cycles ++;
- }
- }
-
- /* Clear injected group conversion flag */
- /* Note: On STM32F1 ADC, clear regular conversion flag raised */
- /* simultaneously. */
- __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JSTRT | ADC_FLAG_JEOC | ADC_FLAG_EOC);
-
- /* Update ADC state machine */
- SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC);
-
- /* Determine whether any further conversion upcoming on group injected */
- /* by external trigger or by automatic injected conversion */
- /* from group regular. */
- if(ADC_IS_SOFTWARE_START_INJECTED(hadc) ||
- (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) &&
- (ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
- (hadc->Init.ContinuousConvMode == DISABLE) ) ) )
- {
- /* Set ADC state */
- CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
-
- if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
- {
- SET_BIT(hadc->State, HAL_ADC_STATE_READY);
- }
- }
-
- /* Return ADC state */
- return HAL_OK;
-}
-
-/**
- * @brief Enables ADC, starts conversion of injected group with interruption.
- * - JEOC (end of conversion of injected group)
- * Each of these interruptions has its dedicated callback function.
- * @param hadc: ADC handle
- * @retval HAL status.
- */
-HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef* hadc)
-{
- HAL_StatusTypeDef tmp_hal_status = HAL_OK;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
- /* Process locked */
- __HAL_LOCK(hadc);
-
- /* Enable the ADC peripheral */
- tmp_hal_status = ADC_Enable(hadc);
-
- /* Start conversion if ADC is effectively enabled */
- if (tmp_hal_status == HAL_OK)
- {
- /* Set ADC state */
- /* - Clear state bitfield related to injected group conversion results */
- /* - Set state bitfield related to injected operation */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
- HAL_ADC_STATE_INJ_BUSY);
-
- /* Case of independent mode or multimode (for devices with several ADCs): */
- /* Set multimode state. */
- if (ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc))
- {
- CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
- }
- else
- {
- SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
- }
-
- /* Check if a regular conversion is ongoing */
- /* Note: On this device, there is no ADC error code fields related to */
- /* conversions on group injected only. In case of conversion on */
- /* going on group regular, no error code is reset. */
- if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
- {
- /* Reset ADC all error code fields */
- ADC_CLEAR_ERRORCODE(hadc);
- }
-
- /* Process unlocked */
- /* Unlock before starting ADC conversions: in case of potential */
- /* interruption, to let the process to ADC IRQ Handler. */
- __HAL_UNLOCK(hadc);
-
- /* Clear injected group conversion flag */
- /* (To ensure of no unknown state from potential previous ADC operations) */
- __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC);
-
- /* Enable end of conversion interrupt for injected channels */
- __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
-
- /* Start conversion of injected group if software start has been selected */
- /* and if automatic injected conversion is disabled. */
- /* If external trigger has been selected, conversion will start at next */
- /* trigger event. */
- /* If automatic injected conversion is enabled, conversion will start */
- /* after next regular group conversion. */
- if (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO))
- {
- if (ADC_IS_SOFTWARE_START_INJECTED(hadc) &&
- ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc) )
- {
- /* Start ADC conversion on injected group with SW start */
- SET_BIT(hadc->Instance->CR2, (ADC_CR2_JSWSTART | ADC_CR2_JEXTTRIG));
- }
- else
- {
- /* Start ADC conversion on injected group with external trigger */
- SET_BIT(hadc->Instance->CR2, ADC_CR2_JEXTTRIG);
- }
- }
- }
- else
- {
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
- }
-
- /* Return function status */
- return tmp_hal_status;
-}
-
-/**
- * @brief Stop conversion of injected channels, disable interruption of
- * end-of-conversion. Disable ADC peripheral if no regular conversion
- * is on going.
- * @note If ADC must be disabled and if conversion is on going on
- * regular group, function HAL_ADC_Stop must be used to stop both
- * injected and regular groups, and disable the ADC.
- * @note If injected group mode auto-injection is enabled,
- * function HAL_ADC_Stop must be used.
- * @param hadc: ADC handle
- * @retval None
- */
-HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef* hadc)
-{
- HAL_StatusTypeDef tmp_hal_status = HAL_OK;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
- /* Process locked */
- __HAL_LOCK(hadc);
-
- /* Stop potential conversion and disable ADC peripheral */
- /* Conditioned to: */
- /* - No conversion on the other group (regular group) is intended to */
- /* continue (injected and regular groups stop conversion and ADC disable */
- /* are common) */
- /* - In case of auto-injection mode, HAL_ADC_Stop must be used. */
- if(((hadc->State & HAL_ADC_STATE_REG_BUSY) == RESET) &&
- HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) )
- {
- /* Stop potential conversion on going, on regular and injected groups */
- /* Disable ADC peripheral */
- tmp_hal_status = ADC_ConversionStop_Disable(hadc);
-
- /* Check if ADC is effectively disabled */
- if (tmp_hal_status == HAL_OK)
- {
- /* Disable ADC end of conversion interrupt for injected channels */
- __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);
-
- /* Set ADC state */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
- HAL_ADC_STATE_READY);
- }
- }
- else
- {
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-
- tmp_hal_status = HAL_ERROR;
- }
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- /* Return function status */
- return tmp_hal_status;
-}
-
-#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
-/**
- * @brief Enables ADC, starts conversion of regular group and transfers result
- * through DMA.
- * Multimode must have been previously configured using
- * HAL_ADCEx_MultiModeConfigChannel() function.
- * Interruptions enabled in this function:
- * - DMA transfer complete
- * - DMA half transfer
- * Each of these interruptions has its dedicated callback function.
- * @note: On STM32F1 devices, ADC slave regular group must be configured
- * with conversion trigger ADC_SOFTWARE_START.
- * @note: ADC slave can be enabled preliminarily using single-mode
- * HAL_ADC_Start() function.
- * @param hadc: ADC handle of ADC master (handle of ADC slave must not be used)
- * @param pData: The destination Buffer address.
- * @param Length: The length of data to be transferred from ADC peripheral to memory.
- * @retval None
- */
-HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length)
-{
- HAL_StatusTypeDef tmp_hal_status = HAL_OK;
- ADC_HandleTypeDef tmphadcSlave;
-
- /* Check the parameters */
- assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance));
- assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
-
- /* Process locked */
- __HAL_LOCK(hadc);
-
- /* Set a temporary handle of the ADC slave associated to the ADC master */
- ADC_MULTI_SLAVE(hadc, &tmphadcSlave);
-
- /* On STM32F1 devices, ADC slave regular group must be configured with */
- /* conversion trigger ADC_SOFTWARE_START. */
- /* Note: External trigger of ADC slave must be enabled, it is already done */
- /* into function "HAL_ADC_Init()". */
- if(!ADC_IS_SOFTWARE_START_REGULAR(&tmphadcSlave))
- {
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- return HAL_ERROR;
- }
-
- /* Enable the ADC peripherals: master and slave (in case if not already */
- /* enabled previously) */
- tmp_hal_status = ADC_Enable(hadc);
- if (tmp_hal_status == HAL_OK)
- {
- tmp_hal_status = ADC_Enable(&tmphadcSlave);
- }
-
- /* Start conversion if all ADCs of multimode are effectively enabled */
- if (tmp_hal_status == HAL_OK)
- {
- /* Set ADC state (ADC master) */
- /* - Clear state bitfield related to regular group conversion results */
- /* - Set state bitfield related to regular operation */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_MULTIMODE_SLAVE,
- HAL_ADC_STATE_REG_BUSY);
-
- /* If conversions on group regular are also triggering group injected, */
- /* update ADC state. */
- if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET)
- {
- ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
- }
-
- /* Process unlocked */
- /* Unlock before starting ADC conversions: in case of potential */
- /* interruption, to let the process to ADC IRQ Handler. */
- __HAL_UNLOCK(hadc);
-
- /* Set ADC error code to none */
- ADC_CLEAR_ERRORCODE(hadc);
-
-
- /* Set the DMA transfer complete callback */
- hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt;
-
- /* Set the DMA half transfer complete callback */
- hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt;
-
- /* Set the DMA error callback */
- hadc->DMA_Handle->XferErrorCallback = ADC_DMAError;
-
-
- /* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC */
- /* start (in case of SW start): */
-
- /* Clear regular group conversion flag and overrun flag */
- /* (To ensure of no unknown state from potential previous ADC operations) */
- __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC);
-
- /* Enable ADC DMA mode of ADC master */
- SET_BIT(hadc->Instance->CR2, ADC_CR2_DMA);
-
- /* Start the DMA channel */
- HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length);
-
- /* Start conversion of regular group if software start has been selected. */
- /* If external trigger has been selected, conversion will start at next */
- /* trigger event. */
- /* Note: Alternate trigger for single conversion could be to force an */
- /* additional set of bit ADON "hadc->Instance->CR2 |= ADC_CR2_ADON;"*/
- if (ADC_IS_SOFTWARE_START_REGULAR(hadc))
- {
- /* Start ADC conversion on regular group with SW start */
- SET_BIT(hadc->Instance->CR2, (ADC_CR2_SWSTART | ADC_CR2_EXTTRIG));
- }
- else
- {
- /* Start ADC conversion on regular group with external trigger */
- SET_BIT(hadc->Instance->CR2, ADC_CR2_EXTTRIG);
- }
- }
- else
- {
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
- }
-
- /* Return function status */
- return tmp_hal_status;
-}
-
-/**
- * @brief Stop ADC conversion of regular group (and injected channels in
- * case of auto_injection mode), disable ADC DMA transfer, disable
- * ADC peripheral.
- * @note Multimode is kept enabled after this function. To disable multimode
- * (set with HAL_ADCEx_MultiModeConfigChannel(), ADC must be
- * reinitialized using HAL_ADC_Init() or HAL_ADC_ReInit().
- * @note In case of DMA configured in circular mode, function
- * HAL_ADC_Stop_DMA must be called after this function with handle of
- * ADC slave, to properly disable the DMA channel.
- * @param hadc: ADC handle of ADC master (handle of ADC slave must not be used)
- * @retval None
- */
-HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef* hadc)
-{
- HAL_StatusTypeDef tmp_hal_status = HAL_OK;
- ADC_HandleTypeDef tmphadcSlave;
-
- /* Check the parameters */
- assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance));
-
- /* Process locked */
- __HAL_LOCK(hadc);
-
-
- /* Stop potential conversion on going, on regular and injected groups */
- /* Disable ADC master peripheral */
- tmp_hal_status = ADC_ConversionStop_Disable(hadc);
-
- /* Check if ADC is effectively disabled */
- if(tmp_hal_status == HAL_OK)
- {
- /* Set a temporary handle of the ADC slave associated to the ADC master */
- ADC_MULTI_SLAVE(hadc, &tmphadcSlave);
-
- /* Disable ADC slave peripheral */
- tmp_hal_status = ADC_ConversionStop_Disable(&tmphadcSlave);
-
- /* Check if ADC is effectively disabled */
- if(tmp_hal_status != HAL_OK)
- {
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- return HAL_ERROR;
- }
-
- /* Disable ADC DMA mode */
- CLEAR_BIT(hadc->Instance->CR2, ADC_CR2_DMA);
-
- /* Reset configuration of ADC DMA continuous request for dual mode */
- CLEAR_BIT(hadc->Instance->CR1, ADC_CR1_DUALMOD);
-
- /* Disable the DMA channel (in case of DMA in circular mode or stop while */
- /* while DMA transfer is on going) */
- tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
-
- /* Change ADC state (ADC master) */
- ADC_STATE_CLR_SET(hadc->State,
- HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
- HAL_ADC_STATE_READY);
- }
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- /* Return function status */
- return tmp_hal_status;
-}
-#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
-
-/**
- * @brief Get ADC injected group conversion result.
- * @note Reading register JDRx automatically clears ADC flag JEOC
- * (ADC group injected end of unitary conversion).
- * @note This function does not clear ADC flag JEOS
- * (ADC group injected end of sequence conversion)
- * Occurrence of flag JEOS rising:
- * - If sequencer is composed of 1 rank, flag JEOS is equivalent
- * to flag JEOC.
- * - If sequencer is composed of several ranks, during the scan
- * sequence flag JEOC only is raised, at the end of the scan sequence
- * both flags JEOC and EOS are raised.
- * Flag JEOS must not be cleared by this function because
- * it would not be compliant with low power features
- * (feature low power auto-wait, not available on all STM32 families).
- * To clear this flag, either use function:
- * in programming model IT: @ref HAL_ADC_IRQHandler(), in programming
- * model polling: @ref HAL_ADCEx_InjectedPollForConversion()
- * or @ref __HAL_ADC_CLEAR_FLAG(&hadc, ADC_FLAG_JEOS).
- * @param hadc: ADC handle
- * @param InjectedRank: the converted ADC injected rank.
- * This parameter can be one of the following values:
- * @arg ADC_INJECTED_RANK_1: Injected Channel1 selected
- * @arg ADC_INJECTED_RANK_2: Injected Channel2 selected
- * @arg ADC_INJECTED_RANK_3: Injected Channel3 selected
- * @arg ADC_INJECTED_RANK_4: Injected Channel4 selected
- * @retval ADC group injected conversion data
- */
-uint32_t HAL_ADCEx_InjectedGetValue(ADC_HandleTypeDef* hadc, uint32_t InjectedRank)
-{
- uint32_t tmp_jdr = 0U;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
- assert_param(IS_ADC_INJECTED_RANK(InjectedRank));
-
- /* Get ADC converted value */
- switch(InjectedRank)
- {
- case ADC_INJECTED_RANK_4:
- tmp_jdr = hadc->Instance->JDR4;
- break;
- case ADC_INJECTED_RANK_3:
- tmp_jdr = hadc->Instance->JDR3;
- break;
- case ADC_INJECTED_RANK_2:
- tmp_jdr = hadc->Instance->JDR2;
- break;
- case ADC_INJECTED_RANK_1:
- default:
- tmp_jdr = hadc->Instance->JDR1;
- break;
- }
-
- /* Return ADC converted value */
- return tmp_jdr;
-}
-
-#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
-/**
- * @brief Returns the last ADC Master&Slave regular conversions results data
- * in the selected multi mode.
- * @param hadc: ADC handle of ADC master (handle of ADC slave must not be used)
- * @retval The converted data value.
- */
-uint32_t HAL_ADCEx_MultiModeGetValue(ADC_HandleTypeDef* hadc)
-{
- uint32_t tmpDR = 0U;
-
- /* Check the parameters */
- assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance));
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
- /* Note: EOC flag is not cleared here by software because automatically */
- /* cleared by hardware when reading register DR. */
-
- /* On STM32F1 devices, ADC1 data register DR contains ADC2 conversions */
- /* only if ADC1 DMA mode is enabled. */
- tmpDR = hadc->Instance->DR;
-
- if (HAL_IS_BIT_CLR(ADC1->CR2, ADC_CR2_DMA))
- {
- tmpDR |= (ADC2->DR << 16U);
- }
-
- /* Return ADC converted value */
- return tmpDR;
-}
-#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
-
-/**
- * @brief Injected conversion complete callback in non blocking mode
- * @param hadc: ADC handle
- * @retval None
- */
-__weak void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hadc);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ADCEx_InjectedConvCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup ADCEx_Exported_Functions_Group2 Extended Peripheral Control functions
- * @brief Extended Peripheral Control functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral Control functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Configure channels on injected group
- (+) Configure multimode
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Configures the ADC injected group and the selected channel to be
- * linked to the injected group.
- * @note Possibility to update parameters on the fly:
- * This function initializes injected group, following calls to this
- * function can be used to reconfigure some parameters of structure
- * "ADC_InjectionConfTypeDef" on the fly, without reseting the ADC.
- * The setting of these parameters is conditioned to ADC state:
- * this function must be called when ADC is not under conversion.
- * @param hadc: ADC handle
- * @param sConfigInjected: Structure of ADC injected group and ADC channel for
- * injected group.
- * @retval None
- */
-HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc, ADC_InjectionConfTypeDef* sConfigInjected)
-{
- HAL_StatusTypeDef tmp_hal_status = HAL_OK;
- __IO uint32_t wait_loop_index = 0U;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
- assert_param(IS_ADC_CHANNEL(sConfigInjected->InjectedChannel));
- assert_param(IS_ADC_SAMPLE_TIME(sConfigInjected->InjectedSamplingTime));
- assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->AutoInjectedConv));
- assert_param(IS_ADC_EXTTRIGINJEC(sConfigInjected->ExternalTrigInjecConv));
- assert_param(IS_ADC_RANGE(sConfigInjected->InjectedOffset));
-
- if(hadc->Init.ScanConvMode != ADC_SCAN_DISABLE)
- {
- assert_param(IS_ADC_INJECTED_RANK(sConfigInjected->InjectedRank));
- assert_param(IS_ADC_INJECTED_NB_CONV(sConfigInjected->InjectedNbrOfConversion));
- assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjectedDiscontinuousConvMode));
- }
-
- /* Process locked */
- __HAL_LOCK(hadc);
-
- /* Configuration of injected group sequencer: */
- /* - if scan mode is disabled, injected channels sequence length is set to */
- /* 0x00: 1 channel converted (channel on regular rank 1) */
- /* Parameter "InjectedNbrOfConversion" is discarded. */
- /* Note: Scan mode is present by hardware on this device and, if */
- /* disabled, discards automatically nb of conversions. Anyway, nb of */
- /* conversions is forced to 0x00 for alignment over all STM32 devices. */
- /* - if scan mode is enabled, injected channels sequence length is set to */
- /* parameter "InjectedNbrOfConversion". */
- if (hadc->Init.ScanConvMode == ADC_SCAN_DISABLE)
- {
- if (sConfigInjected->InjectedRank == ADC_INJECTED_RANK_1)
- {
- /* Clear the old SQx bits for all injected ranks */
- MODIFY_REG(hadc->Instance->JSQR ,
- ADC_JSQR_JL |
- ADC_JSQR_JSQ4 |
- ADC_JSQR_JSQ3 |
- ADC_JSQR_JSQ2 |
- ADC_JSQR_JSQ1 ,
- ADC_JSQR_RK_JL(sConfigInjected->InjectedChannel,
- ADC_INJECTED_RANK_1,
- 0x01U));
- }
- /* If another injected rank than rank1 was intended to be set, and could */
- /* not due to ScanConvMode disabled, error is reported. */
- else
- {
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-
- tmp_hal_status = HAL_ERROR;
- }
- }
- else
- {
- /* Since injected channels rank conv. order depends on total number of */
- /* injected conversions, selected rank must be below or equal to total */
- /* number of injected conversions to be updated. */
- if (sConfigInjected->InjectedRank <= sConfigInjected->InjectedNbrOfConversion)
- {
- /* Clear the old SQx bits for the selected rank */
- /* Set the SQx bits for the selected rank */
- MODIFY_REG(hadc->Instance->JSQR ,
-
- ADC_JSQR_JL |
- ADC_JSQR_RK_JL(ADC_JSQR_JSQ1,
- sConfigInjected->InjectedRank,
- sConfigInjected->InjectedNbrOfConversion) ,
-
- ADC_JSQR_JL_SHIFT(sConfigInjected->InjectedNbrOfConversion) |
- ADC_JSQR_RK_JL(sConfigInjected->InjectedChannel,
- sConfigInjected->InjectedRank,
- sConfigInjected->InjectedNbrOfConversion) );
- }
- else
- {
- /* Clear the old SQx bits for the selected rank */
- MODIFY_REG(hadc->Instance->JSQR ,
-
- ADC_JSQR_JL |
- ADC_JSQR_RK_JL(ADC_JSQR_JSQ1,
- sConfigInjected->InjectedRank,
- sConfigInjected->InjectedNbrOfConversion) ,
-
- 0x00000000U);
- }
- }
-
- /* Configuration of injected group */
- /* Parameters update conditioned to ADC state: */
- /* Parameters that can be updated only when ADC is disabled: */
- /* - external trigger to start conversion */
- /* Parameters update not conditioned to ADC state: */
- /* - Automatic injected conversion */
- /* - Injected discontinuous mode */
- /* Note: In case of ADC already enabled, caution to not launch an unwanted */
- /* conversion while modifying register CR2 by writing 1 to bit ADON. */
- if (ADC_IS_ENABLE(hadc) == RESET)
- {
- MODIFY_REG(hadc->Instance->CR2 ,
- ADC_CR2_JEXTSEL |
- ADC_CR2_ADON ,
- ADC_CFGR_JEXTSEL(hadc, sConfigInjected->ExternalTrigInjecConv) );
- }
-
-
- /* Configuration of injected group */
- /* - Automatic injected conversion */
- /* - Injected discontinuous mode */
-
- /* Automatic injected conversion can be enabled if injected group */
- /* external triggers are disabled. */
- if (sConfigInjected->AutoInjectedConv == ENABLE)
- {
- if (sConfigInjected->ExternalTrigInjecConv == ADC_INJECTED_SOFTWARE_START)
- {
- SET_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO);
- }
- else
- {
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-
- tmp_hal_status = HAL_ERROR;
- }
- }
-
- /* Injected discontinuous can be enabled only if auto-injected mode is */
- /* disabled. */
- if (sConfigInjected->InjectedDiscontinuousConvMode == ENABLE)
- {
- if (sConfigInjected->AutoInjectedConv == DISABLE)
- {
- SET_BIT(hadc->Instance->CR1, ADC_CR1_JDISCEN);
- }
- else
- {
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-
- tmp_hal_status = HAL_ERROR;
- }
- }
-
-
- /* InjectedChannel sampling time configuration */
- /* For channels 10 to 17 */
- if (sConfigInjected->InjectedChannel >= ADC_CHANNEL_10)
- {
- MODIFY_REG(hadc->Instance->SMPR1 ,
- ADC_SMPR1(ADC_SMPR1_SMP10, sConfigInjected->InjectedChannel) ,
- ADC_SMPR1(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel) );
- }
- else /* For channels 0 to 9 */
- {
- MODIFY_REG(hadc->Instance->SMPR2 ,
- ADC_SMPR2(ADC_SMPR2_SMP0, sConfigInjected->InjectedChannel) ,
- ADC_SMPR2(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel) );
- }
-
- /* If ADC1 InjectedChannel_16 or InjectedChannel_17 is selected, enable Temperature sensor */
- /* and VREFINT measurement path. */
- if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) ||
- (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT) )
- {
- SET_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE);
- }
-
-
- /* Configure the offset: offset enable/disable, InjectedChannel, offset value */
- switch(sConfigInjected->InjectedRank)
- {
- case 1:
- /* Set injected channel 1 offset */
- MODIFY_REG(hadc->Instance->JOFR1,
- ADC_JOFR1_JOFFSET1,
- sConfigInjected->InjectedOffset);
- break;
- case 2:
- /* Set injected channel 2 offset */
- MODIFY_REG(hadc->Instance->JOFR2,
- ADC_JOFR2_JOFFSET2,
- sConfigInjected->InjectedOffset);
- break;
- case 3:
- /* Set injected channel 3 offset */
- MODIFY_REG(hadc->Instance->JOFR3,
- ADC_JOFR3_JOFFSET3,
- sConfigInjected->InjectedOffset);
- break;
- case 4:
- default:
- MODIFY_REG(hadc->Instance->JOFR4,
- ADC_JOFR4_JOFFSET4,
- sConfigInjected->InjectedOffset);
- break;
- }
-
- /* If ADC1 Channel_16 or Channel_17 is selected, enable Temperature sensor */
- /* and VREFINT measurement path. */
- if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) ||
- (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT) )
- {
- /* For STM32F1 devices with several ADC: Only ADC1 can access internal */
- /* measurement channels (VrefInt/TempSensor). If these channels are */
- /* intended to be set on other ADC instances, an error is reported. */
- if (hadc->Instance == ADC1)
- {
- if (READ_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE) == RESET)
- {
- SET_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE);
-
- if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR))
- {
- /* Delay for temperature sensor stabilization time */
- /* Compute number of CPU cycles to wait for */
- wait_loop_index = (ADC_TEMPSENSOR_DELAY_US * (SystemCoreClock / 1000000U));
- while(wait_loop_index != 0U)
- {
- wait_loop_index--;
- }
- }
- }
- }
- else
- {
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-
- tmp_hal_status = HAL_ERROR;
- }
- }
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- /* Return function status */
- return tmp_hal_status;
-}
-
-#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
-/**
- * @brief Enable ADC multimode and configure multimode parameters
- * @note Possibility to update parameters on the fly:
- * This function initializes multimode parameters, following
- * calls to this function can be used to reconfigure some parameters
- * of structure "ADC_MultiModeTypeDef" on the fly, without reseting
- * the ADCs (both ADCs of the common group).
- * The setting of these parameters is conditioned to ADC state.
- * For parameters constraints, see comments of structure
- * "ADC_MultiModeTypeDef".
- * @note To change back configuration from multimode to single mode, ADC must
- * be reset (using function HAL_ADC_Init() ).
- * @param hadc: ADC handle
- * @param multimode: Structure of ADC multimode configuration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef* hadc, ADC_MultiModeTypeDef* multimode)
-{
- HAL_StatusTypeDef tmp_hal_status = HAL_OK;
- ADC_HandleTypeDef tmphadcSlave;
-
- /* Check the parameters */
- assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance));
- assert_param(IS_ADC_MODE(multimode->Mode));
-
- /* Process locked */
- __HAL_LOCK(hadc);
-
- /* Set a temporary handle of the ADC slave associated to the ADC master */
- ADC_MULTI_SLAVE(hadc, &tmphadcSlave);
-
- /* Parameters update conditioned to ADC state: */
- /* Parameters that can be updated when ADC is disabled or enabled without */
- /* conversion on going on regular group: */
- /* - ADC master and ADC slave DMA configuration */
- /* Parameters that can be updated only when ADC is disabled: */
- /* - Multimode mode selection */
- /* To optimize code, all multimode settings can be set when both ADCs of */
- /* the common group are in state: disabled. */
- if ((ADC_IS_ENABLE(hadc) == RESET) &&
- (ADC_IS_ENABLE(&tmphadcSlave) == RESET) &&
- (IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance)) )
- {
- MODIFY_REG(hadc->Instance->CR1,
- ADC_CR1_DUALMOD ,
- multimode->Mode );
- }
- /* If one of the ADC sharing the same common group is enabled, no update */
- /* could be done on neither of the multimode structure parameters. */
- else
- {
- /* Update ADC state machine to error */
- SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-
- tmp_hal_status = HAL_ERROR;
- }
-
-
- /* Process unlocked */
- __HAL_UNLOCK(hadc);
-
- /* Return function status */
- return tmp_hal_status;
-}
-#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* HAL_ADC_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_can.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_can.c
deleted file mode 100644
index 7b1b92f..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_can.c
+++ /dev/null
@@ -1,2001 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_can.c
- * @author MCD Application Team
- * @brief CAN HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Controller Area Network (CAN) peripheral:
- * + Initialization and de-initialization functions
- * + Configuration functions
- * + Control functions
- * + Interrupts management
- * + Callbacks functions
- * + Peripheral State and Error functions
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- (#) Initialize the CAN low level resources by implementing the
- HAL_CAN_MspInit():
- (++) Enable the CAN interface clock using __HAL_RCC_CANx_CLK_ENABLE()
- (++) Configure CAN pins
- (+++) Enable the clock for the CAN GPIOs
- (+++) Configure CAN pins as alternate function open-drain
- (++) In case of using interrupts (e.g. HAL_CAN_ActivateNotification())
- (+++) Configure the CAN interrupt priority using
- HAL_NVIC_SetPriority()
- (+++) Enable the CAN IRQ handler using HAL_NVIC_EnableIRQ()
- (+++) In CAN IRQ handler, call HAL_CAN_IRQHandler()
-
- (#) Initialize the CAN peripheral using HAL_CAN_Init() function. This
- function resorts to HAL_CAN_MspInit() for low-level initialization.
-
- (#) Configure the reception filters using the following configuration
- functions:
- (++) HAL_CAN_ConfigFilter()
-
- (#) Start the CAN module using HAL_CAN_Start() function. At this level
- the node is active on the bus: it receive messages, and can send
- messages.
-
- (#) To manage messages transmission, the following Tx control functions
- can be used:
- (++) HAL_CAN_AddTxMessage() to request transmission of a new
- message.
- (++) HAL_CAN_AbortTxRequest() to abort transmission of a pending
- message.
- (++) HAL_CAN_GetTxMailboxesFreeLevel() to get the number of free Tx
- mailboxes.
- (++) HAL_CAN_IsTxMessagePending() to check if a message is pending
- in a Tx mailbox.
- (++) HAL_CAN_GetTxTimestamp() to get the timestamp of Tx message
- sent, if time triggered communication mode is enabled.
-
- (#) When a message is received into the CAN Rx FIFOs, it can be retrieved
- using the HAL_CAN_GetRxMessage() function. The function
- HAL_CAN_GetRxFifoFillLevel() allows to know how many Rx message are
- stored in the Rx Fifo.
-
- (#) Calling the HAL_CAN_Stop() function stops the CAN module.
-
- (#) The deinitialization is achieved with HAL_CAN_DeInit() function.
-
-
- *** Polling mode operation ***
- ==============================
- [..]
- (#) Reception:
- (++) Monitor reception of message using HAL_CAN_GetRxFifoFillLevel()
- until at least one message is received.
- (++) Then get the message using HAL_CAN_GetRxMessage().
-
- (#) Transmission:
- (++) Monitor the Tx mailboxes availability until at least one Tx
- mailbox is free, using HAL_CAN_GetTxMailboxesFreeLevel().
- (++) Then request transmission of a message using
- HAL_CAN_AddTxMessage().
-
-
- *** Interrupt mode operation ***
- ================================
- [..]
- (#) Notifications are activated using HAL_CAN_ActivateNotification()
- function. Then, the process can be controlled through the
- available user callbacks: HAL_CAN_xxxCallback(), using same APIs
- HAL_CAN_GetRxMessage() and HAL_CAN_AddTxMessage().
-
- (#) Notifications can be deactivated using
- HAL_CAN_DeactivateNotification() function.
-
- (#) Special care should be taken for CAN_IT_RX_FIFO0_MSG_PENDING and
- CAN_IT_RX_FIFO1_MSG_PENDING notifications. These notifications trig
- the callbacks HAL_CAN_RxFIFO0MsgPendingCallback() and
- HAL_CAN_RxFIFO1MsgPendingCallback(). User has two possible options
- here.
- (++) Directly get the Rx message in the callback, using
- HAL_CAN_GetRxMessage().
- (++) Or deactivate the notification in the callback without
- getting the Rx message. The Rx message can then be got later
- using HAL_CAN_GetRxMessage(). Once the Rx message have been
- read, the notification can be activated again.
-
-
- *** Sleep mode ***
- ==================
- [..]
- (#) The CAN peripheral can be put in sleep mode (low power), using
- HAL_CAN_RequestSleep(). The sleep mode will be entered as soon as the
- current CAN activity (transmission or reception of a CAN frame) will
- be completed.
-
- (#) A notification can be activated to be informed when the sleep mode
- will be entered.
-
- (#) It can be checked if the sleep mode is entered using
- HAL_CAN_IsSleepActive().
- Note that the CAN state (accessible from the API HAL_CAN_GetState())
- is HAL_CAN_STATE_SLEEP_PENDING as soon as the sleep mode request is
- submitted (the sleep mode is not yet entered), and become
- HAL_CAN_STATE_SLEEP_ACTIVE when the sleep mode is effective.
-
- (#) The wake-up from sleep mode can be trigged by two ways:
- (++) Using HAL_CAN_WakeUp(). When returning from this function,
- the sleep mode is exited (if return status is HAL_OK).
- (++) When a start of Rx CAN frame is detected by the CAN peripheral,
- if automatic wake up mode is enabled.
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#if defined(CAN1)
-
-/** @defgroup CAN CAN
- * @brief CAN driver modules
- * @{
- */
-
-#ifdef HAL_CAN_MODULE_ENABLED
-
-#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
- #error "The CAN driver cannot be used with its legacy, Please enable only one CAN module at once"
-#endif
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @defgroup CAN_Private_Constants CAN Private Constants
- * @{
- */
-#define CAN_TIMEOUT_VALUE 10U
-/**
- * @}
- */
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-
-/** @defgroup CAN_Exported_Functions CAN Exported Functions
- * @{
- */
-
-/** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
- ==============================================================================
- ##### Initialization and de-initialization functions #####
- ==============================================================================
- [..] This section provides functions allowing to:
- (+) HAL_CAN_Init : Initialize and configure the CAN.
- (+) HAL_CAN_DeInit : De-initialize the CAN.
- (+) HAL_CAN_MspInit : Initialize the CAN MSP.
- (+) HAL_CAN_MspDeInit : DeInitialize the CAN MSP.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the CAN peripheral according to the specified
- * parameters in the CAN_InitStruct.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef *hcan)
-{
- uint32_t tickstart;
-
- /* Check CAN handle */
- if (hcan == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
- assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TimeTriggeredMode));
- assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AutoBusOff));
- assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AutoWakeUp));
- assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AutoRetransmission));
- assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ReceiveFifoLocked));
- assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TransmitFifoPriority));
- assert_param(IS_CAN_MODE(hcan->Init.Mode));
- assert_param(IS_CAN_SJW(hcan->Init.SyncJumpWidth));
- assert_param(IS_CAN_BS1(hcan->Init.TimeSeg1));
- assert_param(IS_CAN_BS2(hcan->Init.TimeSeg2));
- assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler));
-
- if (hcan->State == HAL_CAN_STATE_RESET)
- {
- /* Init the low level hardware: CLOCK, NVIC */
- HAL_CAN_MspInit(hcan);
- }
-
- /* Exit from sleep mode */
- CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Check Sleep mode leave acknowledge */
- while ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
- {
- if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
-
- /* Change CAN state */
- hcan->State = HAL_CAN_STATE_ERROR;
-
- return HAL_ERROR;
- }
- }
-
- /* Request initialisation */
- SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Wait initialisation acknowledge */
- while ((hcan->Instance->MSR & CAN_MSR_INAK) == 0U)
- {
- if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
-
- /* Change CAN state */
- hcan->State = HAL_CAN_STATE_ERROR;
-
- return HAL_ERROR;
- }
- }
-
- /* Set the time triggered communication mode */
- if (hcan->Init.TimeTriggeredMode == ENABLE)
- {
- SET_BIT(hcan->Instance->MCR, CAN_MCR_TTCM);
- }
- else
- {
- CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_TTCM);
- }
-
- /* Set the automatic bus-off management */
- if (hcan->Init.AutoBusOff == ENABLE)
- {
- SET_BIT(hcan->Instance->MCR, CAN_MCR_ABOM);
- }
- else
- {
- CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_ABOM);
- }
-
- /* Set the automatic wake-up mode */
- if (hcan->Init.AutoWakeUp == ENABLE)
- {
- SET_BIT(hcan->Instance->MCR, CAN_MCR_AWUM);
- }
- else
- {
- CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_AWUM);
- }
-
- /* Set the automatic retransmission */
- if (hcan->Init.AutoRetransmission == ENABLE)
- {
- CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_NART);
- }
- else
- {
- SET_BIT(hcan->Instance->MCR, CAN_MCR_NART);
- }
-
- /* Set the receive FIFO locked mode */
- if (hcan->Init.ReceiveFifoLocked == ENABLE)
- {
- SET_BIT(hcan->Instance->MCR, CAN_MCR_RFLM);
- }
- else
- {
- CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_RFLM);
- }
-
- /* Set the transmit FIFO priority */
- if (hcan->Init.TransmitFifoPriority == ENABLE)
- {
- SET_BIT(hcan->Instance->MCR, CAN_MCR_TXFP);
- }
- else
- {
- CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_TXFP);
- }
-
- /* Set the bit timing register */
- WRITE_REG(hcan->Instance->BTR, (uint32_t)(hcan->Init.Mode |
- hcan->Init.SyncJumpWidth |
- hcan->Init.TimeSeg1 |
- hcan->Init.TimeSeg2 |
- (hcan->Init.Prescaler - 1U)));
-
- /* Initialize the error code */
- hcan->ErrorCode = HAL_CAN_ERROR_NONE;
-
- /* Initialize the CAN state */
- hcan->State = HAL_CAN_STATE_READY;
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Deinitializes the CAN peripheral registers to their default
- * reset values.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef *hcan)
-{
- /* Check CAN handle */
- if (hcan == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
-
- /* Stop the CAN module */
- (void)HAL_CAN_Stop(hcan);
-
- /* DeInit the low level hardware: CLOCK, NVIC */
- HAL_CAN_MspDeInit(hcan);
-
- /* Reset the CAN peripheral */
- SET_BIT(hcan->Instance->MCR, CAN_MCR_RESET);
-
- /* Reset the CAN ErrorCode */
- hcan->ErrorCode = HAL_CAN_ERROR_NONE;
-
- /* Change CAN state */
- hcan->State = HAL_CAN_STATE_RESET;
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the CAN MSP.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval None
- */
-__weak void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcan);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_CAN_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief DeInitializes the CAN MSP.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval None
- */
-__weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef *hcan)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcan);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_CAN_MspDeInit could be implemented in the user file
- */
-}
-
-
-/**
- * @}
- */
-
-/** @defgroup CAN_Exported_Functions_Group2 Configuration functions
- * @brief Configuration functions.
- *
-@verbatim
- ==============================================================================
- ##### Configuration functions #####
- ==============================================================================
- [..] This section provides functions allowing to:
- (+) HAL_CAN_ConfigFilter : Configure the CAN reception filters
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Configures the CAN reception filter according to the specified
- * parameters in the CAN_FilterInitStruct.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @param sFilterConfig pointer to a CAN_FilterTypeDef structure that
- * contains the filter configuration information.
- * @retval None
- */
-HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan, CAN_FilterTypeDef *sFilterConfig)
-{
- uint32_t filternbrbitpos;
- CAN_TypeDef *can_ip = hcan->Instance;
- HAL_CAN_StateTypeDef state = hcan->State;
-
- if ((state == HAL_CAN_STATE_READY) ||
- (state == HAL_CAN_STATE_LISTENING))
- {
- /* Check the parameters */
- assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterIdHigh));
- assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterIdLow));
- assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterMaskIdHigh));
- assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterMaskIdLow));
- assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
- assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
- assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
- assert_param(IS_CAN_FILTER_ACTIVATION(sFilterConfig->FilterActivation));
-
-#if defined(CAN2)
- /* CAN1 and CAN2 are dual instances with 28 common filters banks */
- /* Select master instance to access the filter banks */
- can_ip = CAN1;
-
- /* Check the parameters */
- assert_param(IS_CAN_FILTER_BANK_DUAL(sFilterConfig->FilterBank));
- assert_param(IS_CAN_FILTER_BANK_DUAL(sFilterConfig->SlaveStartFilterBank));
-#else
- /* CAN1 is single instance with 14 dedicated filters banks */
-
- /* Check the parameters */
- assert_param(IS_CAN_FILTER_BANK_SINGLE(sFilterConfig->FilterBank));
-#endif
-
- /* Initialisation mode for the filter */
- SET_BIT(can_ip->FMR, CAN_FMR_FINIT);
-
-#if defined(CAN2)
- /* Select the start filter number of CAN2 slave instance */
- CLEAR_BIT(can_ip->FMR, CAN_FMR_CAN2SB);
- SET_BIT(can_ip->FMR, sFilterConfig->SlaveStartFilterBank << CAN_FMR_CAN2SB_Pos);
-
-#endif
- /* Convert filter number into bit position */
- filternbrbitpos = (uint32_t)1 << (sFilterConfig->FilterBank & 0x1FU);
-
- /* Filter Deactivation */
- CLEAR_BIT(can_ip->FA1R, filternbrbitpos);
-
- /* Filter Scale */
- if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
- {
- /* 16-bit scale for the filter */
- CLEAR_BIT(can_ip->FS1R, filternbrbitpos);
-
- /* First 16-bit identifier and First 16-bit mask */
- /* Or First 16-bit identifier and Second 16-bit identifier */
- can_ip->sFilterRegister[sFilterConfig->FilterBank].FR1 =
- ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16U) |
- (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
-
- /* Second 16-bit identifier and Second 16-bit mask */
- /* Or Third 16-bit identifier and Fourth 16-bit identifier */
- can_ip->sFilterRegister[sFilterConfig->FilterBank].FR2 =
- ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
- (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh);
- }
-
- if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
- {
- /* 32-bit scale for the filter */
- SET_BIT(can_ip->FS1R, filternbrbitpos);
-
- /* 32-bit identifier or First 32-bit identifier */
- can_ip->sFilterRegister[sFilterConfig->FilterBank].FR1 =
- ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh) << 16U) |
- (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
-
- /* 32-bit mask or Second 32-bit identifier */
- can_ip->sFilterRegister[sFilterConfig->FilterBank].FR2 =
- ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
- (0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow);
- }
-
- /* Filter Mode */
- if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
- {
- /* Id/Mask mode for the filter*/
- CLEAR_BIT(can_ip->FM1R, filternbrbitpos);
- }
- else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
- {
- /* Identifier list mode for the filter*/
- SET_BIT(can_ip->FM1R, filternbrbitpos);
- }
-
- /* Filter FIFO assignment */
- if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
- {
- /* FIFO 0 assignation for the filter */
- CLEAR_BIT(can_ip->FFA1R, filternbrbitpos);
- }
- else
- {
- /* FIFO 1 assignation for the filter */
- SET_BIT(can_ip->FFA1R, filternbrbitpos);
- }
-
- /* Filter activation */
- if (sFilterConfig->FilterActivation == CAN_FILTER_ENABLE)
- {
- SET_BIT(can_ip->FA1R, filternbrbitpos);
- }
-
- /* Leave the initialisation mode for the filter */
- CLEAR_BIT(can_ip->FMR, CAN_FMR_FINIT);
-
- /* Return function status */
- return HAL_OK;
- }
- else
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
-
- return HAL_ERROR;
- }
-}
-
-/**
- * @}
- */
-
-/** @defgroup CAN_Exported_Functions_Group3 Control functions
- * @brief Control functions
- *
-@verbatim
- ==============================================================================
- ##### Control functions #####
- ==============================================================================
- [..] This section provides functions allowing to:
- (+) HAL_CAN_Start : Start the CAN module
- (+) HAL_CAN_Stop : Stop the CAN module
- (+) HAL_CAN_RequestSleep : Request sleep mode entry.
- (+) HAL_CAN_WakeUp : Wake up from sleep mode.
- (+) HAL_CAN_IsSleepActive : Check is sleep mode is active.
- (+) HAL_CAN_AddTxMessage : Add a message to the Tx mailboxes
- and activate the corresponding
- transmission request
- (+) HAL_CAN_AbortTxRequest : Abort transmission request
- (+) HAL_CAN_GetTxMailboxesFreeLevel : Return Tx mailboxes free level
- (+) HAL_CAN_IsTxMessagePending : Check if a transmission request is
- pending on the selected Tx mailbox
- (+) HAL_CAN_GetRxMessage : Get a CAN frame from the Rx FIFO
- (+) HAL_CAN_GetRxFifoFillLevel : Return Rx FIFO fill level
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Start the CAN module.
- * @param hcan pointer to an CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *hcan)
-{
- uint32_t tickstart;
-
- if (hcan->State == HAL_CAN_STATE_READY)
- {
- /* Change CAN peripheral state */
- hcan->State = HAL_CAN_STATE_LISTENING;
-
- /* Request leave initialisation */
- CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Wait the acknowledge */
- while ((hcan->Instance->MSR & CAN_MSR_INAK) != 0U)
- {
- /* Check for the Timeout */
- if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
-
- /* Change CAN state */
- hcan->State = HAL_CAN_STATE_ERROR;
-
- return HAL_ERROR;
- }
- }
-
- /* Reset the CAN ErrorCode */
- hcan->ErrorCode = HAL_CAN_ERROR_NONE;
-
- /* Return function status */
- return HAL_OK;
- }
- else
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_NOT_READY;
-
- return HAL_ERROR;
- }
-}
-
-/**
- * @brief Stop the CAN module and enable access to configuration registers.
- * @param hcan pointer to an CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_CAN_Stop(CAN_HandleTypeDef *hcan)
-{
- uint32_t tickstart;
-
- if (hcan->State == HAL_CAN_STATE_LISTENING)
- {
- /* Request initialisation */
- SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Wait the acknowledge */
- while ((hcan->Instance->MSR & CAN_MSR_INAK) == 0U)
- {
- /* Check for the Timeout */
- if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
-
- /* Change CAN state */
- hcan->State = HAL_CAN_STATE_ERROR;
-
- return HAL_ERROR;
- }
- }
-
- /* Exit from sleep mode */
- CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
-
- /* Change CAN peripheral state */
- hcan->State = HAL_CAN_STATE_READY;
-
- /* Return function status */
- return HAL_OK;
- }
- else
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_NOT_STARTED;
-
- return HAL_ERROR;
- }
-}
-
-/**
- * @brief Request the sleep mode (low power) entry.
- * When returning from this function, Sleep mode will be entered
- * as soon as the current CAN activity (transmission or reception
- * of a CAN frame) has been completed.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval HAL status.
- */
-HAL_StatusTypeDef HAL_CAN_RequestSleep(CAN_HandleTypeDef *hcan)
-{
- HAL_CAN_StateTypeDef state = hcan->State;
-
- if ((state == HAL_CAN_STATE_READY) ||
- (state == HAL_CAN_STATE_LISTENING))
- {
- /* Request Sleep mode */
- SET_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
-
- /* Return function status */
- return HAL_OK;
- }
- else
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
-
- /* Return function status */
- return HAL_ERROR;
- }
-}
-
-/**
- * @brief Wake up from sleep mode.
- * When returning with HAL_OK status from this function, Sleep mode
- * is exited.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval HAL status.
- */
-HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef *hcan)
-{
- __IO uint32_t count = 0;
- uint32_t timeout = 1000000U;
- HAL_CAN_StateTypeDef state = hcan->State;
-
- if ((state == HAL_CAN_STATE_READY) ||
- (state == HAL_CAN_STATE_LISTENING))
- {
- /* Wake up request */
- CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
-
- /* Wait sleep mode is exited */
- do
- {
- /* Increment counter */
- count++;
-
- /* Check if timeout is reached */
- if (count > timeout)
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
-
- return HAL_ERROR;
- }
- }
- while ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U);
-
- /* Return function status */
- return HAL_OK;
- }
- else
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
-
- return HAL_ERROR;
- }
-}
-
-/**
- * @brief Check is sleep mode is active.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval Status
- * - 0 : Sleep mode is not active.
- * - 1 : Sleep mode is active.
- */
-uint32_t HAL_CAN_IsSleepActive(CAN_HandleTypeDef *hcan)
-{
- uint32_t status = 0U;
- HAL_CAN_StateTypeDef state = hcan->State;
-
- if ((state == HAL_CAN_STATE_READY) ||
- (state == HAL_CAN_STATE_LISTENING))
- {
- /* Check Sleep mode */
- if ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
- {
- status = 1U;
- }
- }
-
- /* Return function status */
- return status;
-}
-
-/**
- * @brief Add a message to the first free Tx mailbox and activate the
- * corresponding transmission request.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @param pHeader pointer to a CAN_TxHeaderTypeDef structure.
- * @param aData array containing the payload of the Tx frame.
- * @param pTxMailbox pointer to a variable where the function will return
- * the TxMailbox used to store the Tx message.
- * This parameter can be a value of @arg CAN_Tx_Mailboxes.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, CAN_TxHeaderTypeDef *pHeader, uint8_t aData[], uint32_t *pTxMailbox)
-{
- uint32_t transmitmailbox;
- HAL_CAN_StateTypeDef state = hcan->State;
- uint32_t tsr = READ_REG(hcan->Instance->TSR);
-
- /* Check the parameters */
- assert_param(IS_CAN_IDTYPE(pHeader->IDE));
- assert_param(IS_CAN_RTR(pHeader->RTR));
- assert_param(IS_CAN_DLC(pHeader->DLC));
- if (pHeader->IDE == CAN_ID_STD)
- {
- assert_param(IS_CAN_STDID(pHeader->StdId));
- }
- else
- {
- assert_param(IS_CAN_EXTID(pHeader->ExtId));
- }
- assert_param(IS_FUNCTIONAL_STATE(pHeader->TransmitGlobalTime));
-
- if ((state == HAL_CAN_STATE_READY) ||
- (state == HAL_CAN_STATE_LISTENING))
- {
- /* Check that all the Tx mailboxes are not full */
- if (((tsr & CAN_TSR_TME0) != 0U) ||
- ((tsr & CAN_TSR_TME1) != 0U) ||
- ((tsr & CAN_TSR_TME2) != 0U))
- {
- /* Select an empty transmit mailbox */
- transmitmailbox = (tsr & CAN_TSR_CODE) >> CAN_TSR_CODE_Pos;
-
- /* Check transmit mailbox value */
- if (transmitmailbox > 2U)
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_INTERNAL;
-
- return HAL_ERROR;
- }
-
- /* Store the Tx mailbox */
- *pTxMailbox = (uint32_t)1 << transmitmailbox;
-
- /* Set up the Id */
- if (pHeader->IDE == CAN_ID_STD)
- {
- hcan->Instance->sTxMailBox[transmitmailbox].TIR = ((pHeader->StdId << CAN_TI0R_STID_Pos) |
- pHeader->RTR);
- }
- else
- {
- hcan->Instance->sTxMailBox[transmitmailbox].TIR = ((pHeader->ExtId << CAN_TI0R_EXID_Pos) |
- pHeader->IDE |
- pHeader->RTR);
- }
-
- /* Set up the DLC */
- hcan->Instance->sTxMailBox[transmitmailbox].TDTR = (pHeader->DLC);
-
- /* Set up the Transmit Global Time mode */
- if (pHeader->TransmitGlobalTime == ENABLE)
- {
- SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TDTR, CAN_TDT0R_TGT);
- }
-
- /* Set up the data field */
- WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR,
- ((uint32_t)aData[7] << CAN_TDH0R_DATA7_Pos) |
- ((uint32_t)aData[6] << CAN_TDH0R_DATA6_Pos) |
- ((uint32_t)aData[5] << CAN_TDH0R_DATA5_Pos) |
- ((uint32_t)aData[4] << CAN_TDH0R_DATA4_Pos));
- WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR,
- ((uint32_t)aData[3] << CAN_TDL0R_DATA3_Pos) |
- ((uint32_t)aData[2] << CAN_TDL0R_DATA2_Pos) |
- ((uint32_t)aData[1] << CAN_TDL0R_DATA1_Pos) |
- ((uint32_t)aData[0] << CAN_TDL0R_DATA0_Pos));
-
- /* Request transmission */
- SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);
-
- /* Return function status */
- return HAL_OK;
- }
- else
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;
-
- return HAL_ERROR;
- }
- }
- else
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
-
- return HAL_ERROR;
- }
-}
-
-/**
- * @brief Abort transmission requests
- * @param hcan pointer to an CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @param TxMailboxes List of the Tx Mailboxes to abort.
- * This parameter can be any combination of @arg CAN_Tx_Mailboxes.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_CAN_AbortTxRequest(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes)
-{
- HAL_CAN_StateTypeDef state = hcan->State;
-
- /* Check function parameters */
- assert_param(IS_CAN_TX_MAILBOX_LIST(TxMailboxes));
-
- if ((state == HAL_CAN_STATE_READY) ||
- (state == HAL_CAN_STATE_LISTENING))
- {
- /* Check Tx Mailbox 0 */
- if ((TxMailboxes & CAN_TX_MAILBOX0) != 0U)
- {
- /* Add cancellation request for Tx Mailbox 0 */
- SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ0);
- }
-
- /* Check Tx Mailbox 1 */
- if ((TxMailboxes & CAN_TX_MAILBOX1) != 0U)
- {
- /* Add cancellation request for Tx Mailbox 1 */
- SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ1);
- }
-
- /* Check Tx Mailbox 2 */
- if ((TxMailboxes & CAN_TX_MAILBOX2) != 0U)
- {
- /* Add cancellation request for Tx Mailbox 2 */
- SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ2);
- }
-
- /* Return function status */
- return HAL_OK;
- }
- else
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
-
- return HAL_ERROR;
- }
-}
-
-/**
- * @brief Return Tx Mailboxes free level: number of free Tx Mailboxes.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval Number of free Tx Mailboxes.
- */
-uint32_t HAL_CAN_GetTxMailboxesFreeLevel(CAN_HandleTypeDef *hcan)
-{
- uint32_t freelevel = 0U;
- HAL_CAN_StateTypeDef state = hcan->State;
-
- if ((state == HAL_CAN_STATE_READY) ||
- (state == HAL_CAN_STATE_LISTENING))
- {
- /* Check Tx Mailbox 0 status */
- if ((hcan->Instance->TSR & CAN_TSR_TME0) != 0U)
- {
- freelevel++;
- }
-
- /* Check Tx Mailbox 1 status */
- if ((hcan->Instance->TSR & CAN_TSR_TME1) != 0U)
- {
- freelevel++;
- }
-
- /* Check Tx Mailbox 2 status */
- if ((hcan->Instance->TSR & CAN_TSR_TME2) != 0U)
- {
- freelevel++;
- }
- }
-
- /* Return Tx Mailboxes free level */
- return freelevel;
-}
-
-/**
- * @brief Check if a transmission request is pending on the selected Tx
- * Mailboxes.
- * @param hcan pointer to an CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @param TxMailboxes List of Tx Mailboxes to check.
- * This parameter can be any combination of @arg CAN_Tx_Mailboxes.
- * @retval Status
- * - 0 : No pending transmission request on any selected Tx Mailboxes.
- * - 1 : Pending transmission request on at least one of the selected
- * Tx Mailbox.
- */
-uint32_t HAL_CAN_IsTxMessagePending(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes)
-{
- uint32_t status = 0U;
- HAL_CAN_StateTypeDef state = hcan->State;
-
- /* Check function parameters */
- assert_param(IS_CAN_TX_MAILBOX_LIST(TxMailboxes));
-
- if ((state == HAL_CAN_STATE_READY) ||
- (state == HAL_CAN_STATE_LISTENING))
- {
- /* Check pending transmission request on the selected Tx Mailboxes */
- if ((hcan->Instance->TSR & (TxMailboxes << CAN_TSR_TME0_Pos)) != (TxMailboxes << CAN_TSR_TME0_Pos))
- {
- status = 1U;
- }
- }
-
- /* Return status */
- return status;
-}
-
-/**
- * @brief Return timestamp of Tx message sent, if time triggered communication
- mode is enabled.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @param TxMailbox Tx Mailbox where the timestamp of message sent will be
- * read.
- * This parameter can be one value of @arg CAN_Tx_Mailboxes.
- * @retval Timestamp of message sent from Tx Mailbox.
- */
-uint32_t HAL_CAN_GetTxTimestamp(CAN_HandleTypeDef *hcan, uint32_t TxMailbox)
-{
- uint32_t timestamp = 0U;
- uint32_t transmitmailbox;
- HAL_CAN_StateTypeDef state = hcan->State;
-
- /* Check function parameters */
- assert_param(IS_CAN_TX_MAILBOX(TxMailbox));
-
- if ((state == HAL_CAN_STATE_READY) ||
- (state == HAL_CAN_STATE_LISTENING))
- {
- /* Select the Tx mailbox */
- transmitmailbox = POSITION_VAL(TxMailbox);
-
- /* Get timestamp */
- timestamp = (hcan->Instance->sTxMailBox[transmitmailbox].TDTR & CAN_TDT0R_TIME) >> CAN_TDT0R_TIME_Pos;
- }
-
- /* Return the timestamp */
- return timestamp;
-}
-
-/**
- * @brief Get an CAN frame from the Rx FIFO zone into the message RAM.
- * @param hcan pointer to an CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @param RxFifo Fifo number of the received message to be read.
- * This parameter can be a value of @arg CAN_receive_FIFO_number.
- * @param pHeader pointer to a CAN_RxHeaderTypeDef structure where the header
- * of the Rx frame will be stored.
- * @param aData array where the payload of the Rx frame will be stored.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_CAN_GetRxMessage(CAN_HandleTypeDef *hcan, uint32_t RxFifo, CAN_RxHeaderTypeDef *pHeader, uint8_t aData[])
-{
- HAL_CAN_StateTypeDef state = hcan->State;
-
- assert_param(IS_CAN_RX_FIFO(RxFifo));
-
- if ((state == HAL_CAN_STATE_READY) ||
- (state == HAL_CAN_STATE_LISTENING))
- {
- /* Check the Rx FIFO */
- if (RxFifo == CAN_RX_FIFO0) /* Rx element is assigned to Rx FIFO 0 */
- {
- /* Check that the Rx FIFO 0 is not empty */
- if ((hcan->Instance->RF0R & CAN_RF0R_FMP0) == 0U)
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;
-
- return HAL_ERROR;
- }
- }
- else /* Rx element is assigned to Rx FIFO 1 */
- {
- /* Check that the Rx FIFO 1 is not empty */
- if ((hcan->Instance->RF1R & CAN_RF1R_FMP1) == 0U)
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;
-
- return HAL_ERROR;
- }
- }
-
- /* Get the header */
- pHeader->IDE = CAN_RI0R_IDE & hcan->Instance->sFIFOMailBox[RxFifo].RIR;
- if (pHeader->IDE == CAN_ID_STD)
- {
- pHeader->StdId = (CAN_RI0R_STID & hcan->Instance->sFIFOMailBox[RxFifo].RIR) >> CAN_TI0R_STID_Pos;
- }
- else
- {
- pHeader->ExtId = ((CAN_RI0R_EXID | CAN_RI0R_STID) & hcan->Instance->sFIFOMailBox[RxFifo].RIR) >> CAN_RI0R_EXID_Pos;
- }
- pHeader->RTR = (CAN_RI0R_RTR & hcan->Instance->sFIFOMailBox[RxFifo].RIR) >> CAN_RI0R_RTR_Pos;
- pHeader->DLC = (CAN_RDT0R_DLC & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_DLC_Pos;
- pHeader->FilterMatchIndex = (CAN_RDT0R_FMI & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_FMI_Pos;
- pHeader->Timestamp = (CAN_RDT0R_TIME & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_TIME_Pos;
-
- /* Get the data */
- aData[0] = (uint8_t)((CAN_RDL0R_DATA0 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA0_Pos);
- aData[1] = (uint8_t)((CAN_RDL0R_DATA1 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA1_Pos);
- aData[2] = (uint8_t)((CAN_RDL0R_DATA2 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA2_Pos);
- aData[3] = (uint8_t)((CAN_RDL0R_DATA3 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA3_Pos);
- aData[4] = (uint8_t)((CAN_RDH0R_DATA4 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA4_Pos);
- aData[5] = (uint8_t)((CAN_RDH0R_DATA5 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA5_Pos);
- aData[6] = (uint8_t)((CAN_RDH0R_DATA6 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA6_Pos);
- aData[7] = (uint8_t)((CAN_RDH0R_DATA7 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA7_Pos);
-
- /* Release the FIFO */
- if (RxFifo == CAN_RX_FIFO0) /* Rx element is assigned to Rx FIFO 0 */
- {
- /* Release RX FIFO 0 */
- SET_BIT(hcan->Instance->RF0R, CAN_RF0R_RFOM0);
- }
- else /* Rx element is assigned to Rx FIFO 1 */
- {
- /* Release RX FIFO 1 */
- SET_BIT(hcan->Instance->RF1R, CAN_RF1R_RFOM1);
- }
-
- /* Return function status */
- return HAL_OK;
- }
- else
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
-
- return HAL_ERROR;
- }
-}
-
-/**
- * @brief Return Rx FIFO fill level.
- * @param hcan pointer to an CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @param RxFifo Rx FIFO.
- * This parameter can be a value of @arg CAN_receive_FIFO_number.
- * @retval Number of messages available in Rx FIFO.
- */
-uint32_t HAL_CAN_GetRxFifoFillLevel(CAN_HandleTypeDef *hcan, uint32_t RxFifo)
-{
- uint32_t filllevel = 0U;
- HAL_CAN_StateTypeDef state = hcan->State;
-
- /* Check function parameters */
- assert_param(IS_CAN_RX_FIFO(RxFifo));
-
- if ((state == HAL_CAN_STATE_READY) ||
- (state == HAL_CAN_STATE_LISTENING))
- {
- if (RxFifo == CAN_RX_FIFO0)
- {
- filllevel = hcan->Instance->RF0R & CAN_RF0R_FMP0;
- }
- else /* RxFifo == CAN_RX_FIFO1 */
- {
- filllevel = hcan->Instance->RF1R & CAN_RF1R_FMP1;
- }
- }
-
- /* Return Rx FIFO fill level */
- return filllevel;
-}
-
-/**
- * @}
- */
-
-/** @defgroup CAN_Exported_Functions_Group4 Interrupts management
- * @brief Interrupts management
- *
-@verbatim
- ==============================================================================
- ##### Interrupts management #####
- ==============================================================================
- [..] This section provides functions allowing to:
- (+) HAL_CAN_ActivateNotification : Enable interrupts
- (+) HAL_CAN_DeactivateNotification : Disable interrupts
- (+) HAL_CAN_IRQHandler : Handles CAN interrupt request
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Enable interrupts.
- * @param hcan pointer to an CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @param ActiveITs indicates which interrupts will be enabled.
- * This parameter can be any combination of @arg CAN_Interrupts.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan, uint32_t ActiveITs)
-{
- HAL_CAN_StateTypeDef state = hcan->State;
-
- /* Check function parameters */
- assert_param(IS_CAN_IT(ActiveITs));
-
- if ((state == HAL_CAN_STATE_READY) ||
- (state == HAL_CAN_STATE_LISTENING))
- {
- /* Enable the selected interrupts */
- __HAL_CAN_ENABLE_IT(hcan, ActiveITs);
-
- /* Return function status */
- return HAL_OK;
- }
- else
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
-
- return HAL_ERROR;
- }
-}
-
-/**
- * @brief Disable interrupts.
- * @param hcan pointer to an CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @param InactiveITs indicates which interrupts will be disabled.
- * This parameter can be any combination of @arg CAN_Interrupts.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_CAN_DeactivateNotification(CAN_HandleTypeDef *hcan, uint32_t InactiveITs)
-{
- HAL_CAN_StateTypeDef state = hcan->State;
-
- /* Check function parameters */
- assert_param(IS_CAN_IT(InactiveITs));
-
- if ((state == HAL_CAN_STATE_READY) ||
- (state == HAL_CAN_STATE_LISTENING))
- {
- /* Disable the selected interrupts */
- __HAL_CAN_DISABLE_IT(hcan, InactiveITs);
-
- /* Return function status */
- return HAL_OK;
- }
- else
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
-
- return HAL_ERROR;
- }
-}
-
-/**
- * @brief Handles CAN interrupt request
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval None
- */
-void HAL_CAN_IRQHandler(CAN_HandleTypeDef *hcan)
-{
- uint32_t errorcode = HAL_CAN_ERROR_NONE;
- uint32_t interrupts = READ_REG(hcan->Instance->IER);
- uint32_t msrflags = READ_REG(hcan->Instance->MSR);
- uint32_t tsrflags = READ_REG(hcan->Instance->TSR);
- uint32_t rf0rflags = READ_REG(hcan->Instance->RF0R);
- uint32_t rf1rflags = READ_REG(hcan->Instance->RF1R);
- uint32_t esrflags = READ_REG(hcan->Instance->ESR);
-
- /* Transmit Mailbox empty interrupt management *****************************/
- if ((interrupts & CAN_IT_TX_MAILBOX_EMPTY) != 0U)
- {
- /* Transmit Mailbox 0 management *****************************************/
- if ((tsrflags & CAN_TSR_RQCP0) != 0U)
- {
- /* Clear the Transmission Complete flag (and TXOK0,ALST0,TERR0 bits) */
- __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP0);
-
- if ((tsrflags & CAN_TSR_TXOK0) != 0U)
- {
- /* Transmission Mailbox 0 complete callback */
- /* Call weak (surcharged) callback */
- HAL_CAN_TxMailbox0CompleteCallback(hcan);
- }
- else
- {
- if ((tsrflags & CAN_TSR_ALST0) != 0U)
- {
- /* Update error code */
- errorcode |= HAL_CAN_ERROR_TX_ALST0;
- }
- else if ((tsrflags & CAN_TSR_TERR0) != 0U)
- {
- /* Update error code */
- errorcode |= HAL_CAN_ERROR_TX_TERR0;
- }
- else
- {
- /* Transmission Mailbox 0 abort callback */
- /* Call weak (surcharged) callback */
- HAL_CAN_TxMailbox0AbortCallback(hcan);
- }
- }
- }
-
- /* Transmit Mailbox 1 management *****************************************/
- if ((tsrflags & CAN_TSR_RQCP1) != 0U)
- {
- /* Clear the Transmission Complete flag (and TXOK1,ALST1,TERR1 bits) */
- __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP1);
-
- if ((tsrflags & CAN_TSR_TXOK1) != 0U)
- {
- /* Transmission Mailbox 1 complete callback */
- /* Call weak (surcharged) callback */
- HAL_CAN_TxMailbox1CompleteCallback(hcan);
- }
- else
- {
- if ((tsrflags & CAN_TSR_ALST1) != 0U)
- {
- /* Update error code */
- errorcode |= HAL_CAN_ERROR_TX_ALST1;
- }
- else if ((tsrflags & CAN_TSR_TERR1) != 0U)
- {
- /* Update error code */
- errorcode |= HAL_CAN_ERROR_TX_TERR1;
- }
- else
- {
- /* Transmission Mailbox 1 abort callback */
- /* Call weak (surcharged) callback */
- HAL_CAN_TxMailbox1AbortCallback(hcan);
- }
- }
- }
-
- /* Transmit Mailbox 2 management *****************************************/
- if ((tsrflags & CAN_TSR_RQCP2) != 0U)
- {
- /* Clear the Transmission Complete flag (and TXOK2,ALST2,TERR2 bits) */
- __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP2);
-
- if ((tsrflags & CAN_TSR_TXOK2) != 0U)
- {
- /* Transmission Mailbox 2 complete callback */
- /* Call weak (surcharged) callback */
- HAL_CAN_TxMailbox2CompleteCallback(hcan);
- }
- else
- {
- if ((tsrflags & CAN_TSR_ALST2) != 0U)
- {
- /* Update error code */
- errorcode |= HAL_CAN_ERROR_TX_ALST2;
- }
- else if ((tsrflags & CAN_TSR_TERR2) != 0U)
- {
- /* Update error code */
- errorcode |= HAL_CAN_ERROR_TX_TERR2;
- }
- else
- {
- /* Transmission Mailbox 2 abort callback */
- /* Call weak (surcharged) callback */
- HAL_CAN_TxMailbox2AbortCallback(hcan);
- }
- }
- }
- }
-
- /* Receive FIFO 0 overrun interrupt management *****************************/
- if ((interrupts & CAN_IT_RX_FIFO0_OVERRUN) != 0U)
- {
- if ((rf0rflags & CAN_RF0R_FOVR0) != 0U)
- {
- /* Set CAN error code to Rx Fifo 0 overrun error */
- errorcode |= HAL_CAN_ERROR_RX_FOV0;
-
- /* Clear FIFO0 Overrun Flag */
- __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
- }
- }
-
- /* Receive FIFO 0 full interrupt management ********************************/
- if ((interrupts & CAN_IT_RX_FIFO0_FULL) != 0U)
- {
- if ((rf0rflags & CAN_RF0R_FULL0) != 0U)
- {
- /* Clear FIFO 0 full Flag */
- __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF0);
-
- /* Receive FIFO 0 full Callback */
- /* Call weak (surcharged) callback */
- HAL_CAN_RxFifo0FullCallback(hcan);
- }
- }
-
- /* Receive FIFO 0 message pending interrupt management *********************/
- if ((interrupts & CAN_IT_RX_FIFO0_MSG_PENDING) != 0U)
- {
- /* Check if message is still pending */
- if ((hcan->Instance->RF0R & CAN_RF0R_FMP0) != 0U)
- {
- /* Receive FIFO 0 mesage pending Callback */
- /* Call weak (surcharged) callback */
- HAL_CAN_RxFifo0MsgPendingCallback(hcan);
- }
- }
-
- /* Receive FIFO 1 overrun interrupt management *****************************/
- if ((interrupts & CAN_IT_RX_FIFO1_OVERRUN) != 0U)
- {
- if ((rf1rflags & CAN_RF1R_FOVR1) != 0U)
- {
- /* Set CAN error code to Rx Fifo 1 overrun error */
- errorcode |= HAL_CAN_ERROR_RX_FOV1;
-
- /* Clear FIFO1 Overrun Flag */
- __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
- }
- }
-
- /* Receive FIFO 1 full interrupt management ********************************/
- if ((interrupts & CAN_IT_RX_FIFO1_FULL) != 0U)
- {
- if ((rf1rflags & CAN_RF1R_FULL1) != 0U)
- {
- /* Clear FIFO 1 full Flag */
- __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF1);
-
- /* Receive FIFO 1 full Callback */
- /* Call weak (surcharged) callback */
- HAL_CAN_RxFifo1FullCallback(hcan);
- }
- }
-
- /* Receive FIFO 1 message pending interrupt management *********************/
- if ((interrupts & CAN_IT_RX_FIFO1_MSG_PENDING) != 0U)
- {
- /* Check if message is still pending */
- if ((hcan->Instance->RF1R & CAN_RF1R_FMP1) != 0U)
- {
- /* Receive FIFO 1 mesage pending Callback */
- /* Call weak (surcharged) callback */
- HAL_CAN_RxFifo1MsgPendingCallback(hcan);
- }
- }
-
- /* Sleep interrupt management *********************************************/
- if ((interrupts & CAN_IT_SLEEP_ACK) != 0U)
- {
- if ((msrflags & CAN_MSR_SLAKI) != 0U)
- {
- /* Clear Sleep interrupt Flag */
- __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_SLAKI);
-
- /* Sleep Callback */
- /* Call weak (surcharged) callback */
- HAL_CAN_SleepCallback(hcan);
- }
- }
-
- /* WakeUp interrupt management *********************************************/
- if ((interrupts & CAN_IT_WAKEUP) != 0U)
- {
- if ((msrflags & CAN_MSR_WKUI) != 0U)
- {
- /* Clear WakeUp Flag */
- __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_WKU);
-
- /* WakeUp Callback */
- /* Call weak (surcharged) callback */
- HAL_CAN_WakeUpFromRxMsgCallback(hcan);
- }
- }
-
- /* Error interrupts management *********************************************/
- if ((interrupts & CAN_IT_ERROR) != 0U)
- {
- if ((msrflags & CAN_MSR_ERRI) != 0U)
- {
- /* Check Error Warning Flag */
- if (((interrupts & CAN_IT_ERROR_WARNING) != 0U) &&
- ((esrflags & CAN_ESR_EWGF) != 0U))
- {
- /* Set CAN error code to Error Warning */
- errorcode |= HAL_CAN_ERROR_EWG;
-
- /* No need for clear of Error Warning Flag as read-only */
- }
-
- /* Check Error Passive Flag */
- if (((interrupts & CAN_IT_ERROR_PASSIVE) != 0U) &&
- ((esrflags & CAN_ESR_EPVF) != 0U))
- {
- /* Set CAN error code to Error Passive */
- errorcode |= HAL_CAN_ERROR_EPV;
-
- /* No need for clear of Error Passive Flag as read-only */
- }
-
- /* Check Bus-off Flag */
- if (((interrupts & CAN_IT_BUSOFF) != 0U) &&
- ((esrflags & CAN_ESR_BOFF) != 0U))
- {
- /* Set CAN error code to Bus-Off */
- errorcode |= HAL_CAN_ERROR_BOF;
-
- /* No need for clear of Error Bus-Off as read-only */
- }
-
- /* Check Last Error Code Flag */
- if (((interrupts & CAN_IT_LAST_ERROR_CODE) != 0U) &&
- ((esrflags & CAN_ESR_LEC) != 0U))
- {
- switch (esrflags & CAN_ESR_LEC)
- {
- case (CAN_ESR_LEC_0):
- /* Set CAN error code to Stuff error */
- errorcode |= HAL_CAN_ERROR_STF;
- break;
- case (CAN_ESR_LEC_1):
- /* Set CAN error code to Form error */
- errorcode |= HAL_CAN_ERROR_FOR;
- break;
- case (CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
- /* Set CAN error code to Acknowledgement error */
- errorcode |= HAL_CAN_ERROR_ACK;
- break;
- case (CAN_ESR_LEC_2):
- /* Set CAN error code to Bit recessive error */
- errorcode |= HAL_CAN_ERROR_BR;
- break;
- case (CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
- /* Set CAN error code to Bit Dominant error */
- errorcode |= HAL_CAN_ERROR_BD;
- break;
- case (CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
- /* Set CAN error code to CRC error */
- errorcode |= HAL_CAN_ERROR_CRC;
- break;
- default:
- break;
- }
-
- /* Clear Last error code Flag */
- CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC);
- }
- }
-
- /* Clear ERRI Flag */
- __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_ERRI);
- }
-
- /* Call the Error call Back in case of Errors */
- if (errorcode != HAL_CAN_ERROR_NONE)
- {
- /* Update error code in handle */
- hcan->ErrorCode |= errorcode;
-
- /* Call Error callback function */
- /* Call weak (surcharged) callback */
- HAL_CAN_ErrorCallback(hcan);
- }
-}
-
-/**
- * @}
- */
-
-/** @defgroup CAN_Exported_Functions_Group5 Callback functions
- * @brief CAN Callback functions
- *
-@verbatim
- ==============================================================================
- ##### Callback functions #####
- ==============================================================================
- [..]
- This subsection provides the following callback functions:
- (+) HAL_CAN_TxMailbox0CompleteCallback
- (+) HAL_CAN_TxMailbox1CompleteCallback
- (+) HAL_CAN_TxMailbox2CompleteCallback
- (+) HAL_CAN_TxMailbox0AbortCallback
- (+) HAL_CAN_TxMailbox1AbortCallback
- (+) HAL_CAN_TxMailbox2AbortCallback
- (+) HAL_CAN_RxFifo0MsgPendingCallback
- (+) HAL_CAN_RxFifo0FullCallback
- (+) HAL_CAN_RxFifo1MsgPendingCallback
- (+) HAL_CAN_RxFifo1FullCallback
- (+) HAL_CAN_SleepCallback
- (+) HAL_CAN_WakeUpFromRxMsgCallback
- (+) HAL_CAN_ErrorCallback
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Transmission Mailbox 0 complete callback.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval None
- */
-__weak void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcan);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_CAN_TxMailbox0CompleteCallback could be implemented in the
- user file
- */
-}
-
-/**
- * @brief Transmission Mailbox 1 complete callback.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval None
- */
-__weak void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcan);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_CAN_TxMailbox1CompleteCallback could be implemented in the
- user file
- */
-}
-
-/**
- * @brief Transmission Mailbox 2 complete callback.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval None
- */
-__weak void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcan);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_CAN_TxMailbox2CompleteCallback could be implemented in the
- user file
- */
-}
-
-/**
- * @brief Transmission Mailbox 0 Cancellation callback.
- * @param hcan pointer to an CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval None
- */
-__weak void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcan);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_CAN_TxMailbox0AbortCallback could be implemented in the
- user file
- */
-}
-
-/**
- * @brief Transmission Mailbox 1 Cancellation callback.
- * @param hcan pointer to an CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval None
- */
-__weak void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcan);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_CAN_TxMailbox1AbortCallback could be implemented in the
- user file
- */
-}
-
-/**
- * @brief Transmission Mailbox 2 Cancellation callback.
- * @param hcan pointer to an CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval None
- */
-__weak void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcan);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_CAN_TxMailbox2AbortCallback could be implemented in the
- user file
- */
-}
-
-/**
- * @brief Rx FIFO 0 message pending callback.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval None
- */
-__weak void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcan);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_CAN_RxFifo0MsgPendingCallback could be implemented in the
- user file
- */
-}
-
-/**
- * @brief Rx FIFO 0 full callback.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval None
- */
-__weak void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcan);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_CAN_RxFifo0FullCallback could be implemented in the user
- file
- */
-}
-
-/**
- * @brief Rx FIFO 1 message pending callback.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval None
- */
-__weak void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcan);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_CAN_RxFifo1MsgPendingCallback could be implemented in the
- user file
- */
-}
-
-/**
- * @brief Rx FIFO 1 full callback.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval None
- */
-__weak void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcan);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_CAN_RxFifo1FullCallback could be implemented in the user
- file
- */
-}
-
-/**
- * @brief Sleep callback.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval None
- */
-__weak void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcan);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_CAN_SleepCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief WakeUp from Rx message callback.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval None
- */
-__weak void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcan);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_CAN_WakeUpFromRxMsgCallback could be implemented in the
- user file
- */
-}
-
-/**
- * @brief Error CAN callback.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval None
- */
-__weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcan);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_CAN_ErrorCallback could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup CAN_Exported_Functions_Group6 Peripheral State and Error functions
- * @brief CAN Peripheral State functions
- *
-@verbatim
- ==============================================================================
- ##### Peripheral State and Error functions #####
- ==============================================================================
- [..]
- This subsection provides functions allowing to :
- (+) HAL_CAN_GetState() : Return the CAN state.
- (+) HAL_CAN_GetError() : Return the CAN error codes if any.
- (+) HAL_CAN_ResetError(): Reset the CAN error codes if any.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Return the CAN state.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval HAL state
- */
-HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef *hcan)
-{
- HAL_CAN_StateTypeDef state = hcan->State;
-
- if ((state == HAL_CAN_STATE_READY) ||
- (state == HAL_CAN_STATE_LISTENING))
- {
- /* Check sleep mode acknowledge flag */
- if ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
- {
- /* Sleep mode is active */
- state = HAL_CAN_STATE_SLEEP_ACTIVE;
- }
- /* Check sleep mode request flag */
- else if ((hcan->Instance->MCR & CAN_MCR_SLEEP) != 0U)
- {
- /* Sleep mode request is pending */
- state = HAL_CAN_STATE_SLEEP_PENDING;
- }
- else
- {
- /* Neither sleep mode request nor sleep mode acknowledge */
- }
- }
-
- /* Return CAN state */
- return state;
-}
-
-/**
- * @brief Return the CAN error code.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval CAN Error Code
- */
-uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
-{
- /* Return CAN error code */
- return hcan->ErrorCode;
-}
-
-/**
- * @brief Reset the CAN error code.
- * @param hcan pointer to a CAN_HandleTypeDef structure that contains
- * the configuration information for the specified CAN.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_CAN_ResetError(CAN_HandleTypeDef *hcan)
-{
- HAL_StatusTypeDef status = HAL_OK;
- HAL_CAN_StateTypeDef state = hcan->State;
-
- if ((state == HAL_CAN_STATE_READY) ||
- (state == HAL_CAN_STATE_LISTENING))
- {
- /* Reset CAN error code */
- hcan->ErrorCode = 0U;
- }
- else
- {
- /* Update error code */
- hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
-
- status = HAL_ERROR;
- }
-
- /* Return the status */
- return status;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* HAL_CAN_MODULE_ENABLED */
-
-/**
- * @}
- */
-
-#endif /* CAN1 */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cec.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cec.c
deleted file mode 100644
index 630b638..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cec.c
+++ /dev/null
@@ -1,692 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_cec.c
- * @author MCD Application Team
- * @brief CEC HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the High Definition Multimedia Interface
- * Consumer Electronics Control Peripheral (CEC).
- * + Initialization and de-initialization function
- * + IO operation function
- * + Peripheral Control function
- *
- *
- @verbatim
- ===============================================================================
- ##### How to use this driver #####
- ===============================================================================
- [..]
- The CEC HAL driver can be used as follow:
-
- (#) Declare a CEC_HandleTypeDef handle structure.
- (#) Initialize the CEC low level resources by implementing the HAL_CEC_MspInit ()API:
- (##) Enable the CEC interface clock.
- (##) CEC pins configuration:
- (+++) Enable the clock for the CEC GPIOs.
- (+++) Configure these CEC pins as alternate function pull-up.
- (##) NVIC configuration if you need to use interrupt process (HAL_CEC_Transmit_IT()
- and HAL_CEC_Receive_IT() APIs):
- (+++) Configure the CEC interrupt priority.
- (+++) Enable the NVIC CEC IRQ handle.
- (+++) The specific CEC interrupts (Transmission complete interrupt,
- RXNE interrupt and Error Interrupts) will be managed using the macros
- __HAL_CEC_ENABLE_IT() and __HAL_CEC_DISABLE_IT() inside the transmit
- and receive process.
-
- (#) Program the Bit Timing Error Mode and the Bit Period Error Mode in the hcec Init structure.
-
- (#) Initialize the CEC registers by calling the HAL_CEC_Init() API.
-
- [..]
- (@) This API (HAL_CEC_Init()) configures also the low level Hardware (GPIO, CLOCK, CORTEX...etc)
- by calling the customed HAL_CEC_MspInit() API.
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-#ifdef HAL_CEC_MODULE_ENABLED
-
-#if defined(STM32F100xB) || defined(STM32F100xE)
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup CEC CEC
- * @brief HAL CEC module driver
- * @{
- */
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @defgroup CEC_Private_Constants CEC Private Constants
- * @{
- */
-#define CEC_CFGR_FIELDS (CEC_CFGR_BTEM | CEC_CFGR_BPEM )
-#define CEC_FLAG_TRANSMIT_MASK (CEC_FLAG_TSOM|CEC_FLAG_TEOM|CEC_FLAG_TBTRF)
-#define CEC_FLAG_RECEIVE_MASK (CEC_FLAG_RSOM|CEC_FLAG_REOM|CEC_FLAG_RBTF)
-#define CEC_ESR_ALL_ERROR (CEC_ESR_BTE|CEC_ESR_BPE|CEC_ESR_RBTFE|CEC_ESR_SBE|CEC_ESR_ACKE|CEC_ESR_LINE|CEC_ESR_TBTFE)
-#define CEC_RXXFERSIZE_INITIALIZE 0xFFFF /*!< Value used to initialise the RxXferSize of the handle */
-/**
- * @}
- */
-
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @defgroup CEC_Private_Functions CEC Private Functions
- * @{
- */
-static HAL_StatusTypeDef CEC_Transmit_IT(CEC_HandleTypeDef *hcec);
-static HAL_StatusTypeDef CEC_Receive_IT(CEC_HandleTypeDef *hcec);
-/**
- * @}
- */
-
-/* Exported functions ---------------------------------------------------------*/
-
-/** @defgroup CEC_Exported_Functions CEC Exported Functions
- * @{
- */
-
-/** @defgroup CEC_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
-===============================================================================
- ##### Initialization and Configuration functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to initialize the CEC
- (+) The following parameters need to be configured:
- (++) TimingErrorFree
- (++) PeriodErrorFree
- (++) InitiatorAddress
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the CEC mode according to the specified
- * parameters in the CEC_InitTypeDef and creates the associated handle .
- * @param hcec: CEC handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_CEC_Init(CEC_HandleTypeDef *hcec)
-{
- /* Check the CEC handle allocation */
- if((hcec == NULL) ||(hcec->Init.RxBuffer == NULL))
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance));
- assert_param(IS_CEC_BIT_TIMING_ERROR_MODE(hcec->Init.TimingErrorFree));
- assert_param(IS_CEC_BIT_PERIOD_ERROR_MODE(hcec->Init.PeriodErrorFree));
- assert_param(IS_CEC_ADDRESS(hcec->Init.OwnAddress));
-
- if(hcec->gState == HAL_CEC_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- hcec->Lock = HAL_UNLOCKED;
- /* Init the low level hardware : GPIO, CLOCK */
- HAL_CEC_MspInit(hcec);
- }
- hcec->gState = HAL_CEC_STATE_BUSY;
-
- /* Disable the Peripheral */
- __HAL_CEC_DISABLE(hcec);
-
- /* Write to CEC Control Register */
- MODIFY_REG(hcec->Instance->CFGR, CEC_CFGR_FIELDS, hcec->Init.TimingErrorFree | hcec->Init.PeriodErrorFree);
-
- /* Write to CEC Own Address Register */
- MODIFY_REG(hcec->Instance->OAR, CEC_OAR_OA, hcec->Init.OwnAddress);
-
- /* Configure the prescaler to generate the required 50 microseconds time base.*/
- MODIFY_REG(hcec->Instance->PRES, CEC_PRES_PRES, 50U * (HAL_RCC_GetPCLK1Freq()/1000000U) - 1U);
-
- /* Enable the following CEC Interrupt */
- __HAL_CEC_ENABLE_IT(hcec, CEC_IT_IE);
-
- /* Enable the CEC Peripheral */
- __HAL_CEC_ENABLE(hcec);
-
- hcec->ErrorCode = HAL_CEC_ERROR_NONE;
- hcec->gState = HAL_CEC_STATE_READY;
- hcec->RxState = HAL_CEC_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief DeInitializes the CEC peripheral
- * @param hcec: CEC handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_CEC_DeInit(CEC_HandleTypeDef *hcec)
-{
- /* Check the CEC handle allocation */
- if(hcec == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance));
-
- hcec->gState = HAL_CEC_STATE_BUSY;
-
- /* DeInit the low level hardware */
- HAL_CEC_MspDeInit(hcec);
-
- __HAL_RCC_CEC_FORCE_RESET();
- __HAL_RCC_CEC_RELEASE_RESET();
-
- hcec->ErrorCode = HAL_CEC_ERROR_NONE;
- hcec->gState = HAL_CEC_STATE_RESET;
- hcec->RxState = HAL_CEC_STATE_RESET;
-
- /* Process Unlock */
- __HAL_UNLOCK(hcec);
-
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the Own Address of the CEC device
- * @param hcec: CEC handle
- * @param CEC_OwnAddress: The CEC own address.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_CEC_SetDeviceAddress(CEC_HandleTypeDef *hcec, uint16_t CEC_OwnAddress)
-{
- /* Check the parameters */
- assert_param(IS_CEC_OWN_ADDRESS(CEC_OwnAddress));
-
- if ((hcec->gState == HAL_CEC_STATE_READY) && (hcec->RxState == HAL_CEC_STATE_READY))
- {
- /* Process Locked */
- __HAL_LOCK(hcec);
-
- hcec->gState = HAL_CEC_STATE_BUSY;
-
- /* Disable the Peripheral */
- __HAL_CEC_DISABLE(hcec);
-
- if(CEC_OwnAddress != CEC_OWN_ADDRESS_NONE)
- {
- MODIFY_REG(hcec->Instance->OAR, CEC_OAR_OA, hcec->Init.OwnAddress);
- }
- else
- {
- CLEAR_BIT(hcec->Instance->OAR, CEC_OAR_OA);
- }
-
- hcec->gState = HAL_CEC_STATE_READY;
- hcec->ErrorCode = HAL_CEC_ERROR_NONE;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hcec);
-
- /* Enable the Peripheral */
- __HAL_CEC_ENABLE(hcec);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief CEC MSP Init
- * @param hcec: CEC handle
- * @retval None
- */
- __weak void HAL_CEC_MspInit(CEC_HandleTypeDef *hcec)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcec);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_CEC_MspInit can be implemented in the user file
- */
-}
-
-/**
- * @brief CEC MSP DeInit
- * @param hcec: CEC handle
- * @retval None
- */
- __weak void HAL_CEC_MspDeInit(CEC_HandleTypeDef *hcec)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcec);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_CEC_MspDeInit can be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup CEC_Exported_Functions_Group2 Input and Output operation functions
- * @brief CEC Transmit/Receive functions
- *
-@verbatim
- ===============================================================================
- ##### IO operation functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to manage the CEC data transfers.
-
- (#) The CEC handle must contain the initiator (TX side) and the destination (RX side)
- logical addresses (4-bit long addresses, 0xF for broadcast messages destination)
-
- (#) The communication is performed using Interrupts.
- These API's return the HAL status.
- The end of the data processing will be indicated through the
- dedicated CEC IRQ when using Interrupt mode.
- The HAL_CEC_TxCpltCallback(), HAL_CEC_RxCpltCallback() user callbacks
- will be executed respectively at the end of the transmit or Receive process
- The HAL_CEC_ErrorCallback() user callback will be executed when a communication
- error is detected
-
- (#) API's with Interrupt are :
- (+) HAL_CEC_Transmit_IT()
- (+) HAL_CEC_IRQHandler()
-
- (#) A set of User Callbacks are provided:
- (+) HAL_CEC_TxCpltCallback()
- (+) HAL_CEC_RxCpltCallback()
- (+) HAL_CEC_ErrorCallback()
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Send data in interrupt mode
- * @param hcec: CEC handle
- * @param InitiatorAddress: Initiator address
- * @param DestinationAddress: destination logical address
- * @param pData: pointer to input byte data buffer
- * @param Size: amount of data to be sent in bytes (without counting the header).
- * 0 means only the header is sent (ping operation).
- * Maximum TX size is 15 bytes (1 opcode and up to 14 operands).
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_CEC_Transmit_IT(CEC_HandleTypeDef *hcec, uint8_t InitiatorAddress,uint8_t DestinationAddress, uint8_t *pData, uint32_t Size)
-{
- /* if the IP isn't already busy and if there is no previous transmission
- already pending due to arbitration lost */
- if(hcec->gState == HAL_CEC_STATE_READY)
- {
- if((pData == NULL ) && (Size > 0U))
- {
- return HAL_ERROR;
- }
-
- assert_param(IS_CEC_ADDRESS(DestinationAddress));
- assert_param(IS_CEC_ADDRESS(InitiatorAddress));
- assert_param(IS_CEC_MSGSIZE(Size));
-
- /* Process Locked */
- __HAL_LOCK(hcec);
- hcec->pTxBuffPtr = pData;
- hcec->gState = HAL_CEC_STATE_BUSY_TX;
- hcec->ErrorCode = HAL_CEC_ERROR_NONE;
-
- /* initialize the number of bytes to send,
- * 0 means only one header is sent (ping operation) */
- hcec->TxXferCount = Size;
-
- /* send header block */
- hcec->Instance->TXD = (uint8_t)((uint32_t)InitiatorAddress << CEC_INITIATOR_LSB_POS) | DestinationAddress;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hcec);
-
- /* case no data to be sent, sender is only pinging the system */
- if (Size != 0)
- {
- /* Set TX Start of Message (TXSOM) bit */
- MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, CEC_FLAG_TSOM);
- }
- else
- {
- /* Send a ping command */
- MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, CEC_FLAG_TEOM|CEC_FLAG_TSOM);
- }
- return HAL_OK;
-
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Get size of the received frame.
- * @param hcec: CEC handle
- * @retval Frame size
- */
-uint32_t HAL_CEC_GetLastReceivedFrameSize(CEC_HandleTypeDef *hcec)
-{
- return hcec->RxXferSize;
-}
-
-/**
- * @brief Change Rx Buffer.
- * @param hcec: CEC handle
- * @param Rxbuffer: Rx Buffer
- * @note This function can be called only inside the HAL_CEC_RxCpltCallback()
- * @retval Frame size
- */
-void HAL_CEC_ChangeRxBuffer(CEC_HandleTypeDef *hcec, uint8_t* Rxbuffer)
-{
- hcec->Init.RxBuffer = Rxbuffer;
-}
-
-/**
- * @brief This function handles CEC interrupt requests.
- * @param hcec: CEC handle
- * @retval None
- */
-void HAL_CEC_IRQHandler(CEC_HandleTypeDef *hcec)
-{
- /* Save error status register for further error handling purposes */
- hcec->ErrorCode = READ_BIT(hcec->Instance->ESR, CEC_ESR_ALL_ERROR);
-
- /* Transmit error */
- if(__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TERR) != RESET)
- {
- /* Acknowledgement of the error */
- __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TERR);
-
- hcec->gState = HAL_CEC_STATE_READY;
- }
-
- /* Receive error */
- if(__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_RERR) != RESET)
- {
- /* Acknowledgement of the error */
- __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RERR);
- hcec->Init.RxBuffer-=hcec->RxXferSize;
- hcec->RxXferSize = 0U;
- hcec->RxState = HAL_CEC_STATE_READY;
- }
-
- if((hcec->ErrorCode & CEC_ESR_ALL_ERROR) != 0U)
- {
- /* Error Call Back */
- HAL_CEC_ErrorCallback(hcec);
- }
-
- /* Transmit byte request or block transfer finished */
- if(__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TBTRF) != RESET)
- {
- CEC_Transmit_IT(hcec);
- }
-
- /* Receive byte or block transfer finished */
- if(__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_RBTF) != RESET)
- {
- if(hcec->RxXferSize == 0U)
- {
- /* reception is starting */
- hcec->RxState = HAL_CEC_STATE_BUSY_RX;
- }
- CEC_Receive_IT(hcec);
- }
-}
-
-
-/**
- * @brief Tx Transfer completed callback
- * @param hcec: CEC handle
- * @retval None
- */
- __weak void HAL_CEC_TxCpltCallback(CEC_HandleTypeDef *hcec)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcec);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_CEC_TxCpltCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief Rx Transfer completed callback
- * @param hcec: CEC handle
- * @param RxFrameSize: Size of frame
- * @retval None
- */
-__weak void HAL_CEC_RxCpltCallback(CEC_HandleTypeDef *hcec, uint32_t RxFrameSize)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcec);
- UNUSED(RxFrameSize);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_CEC_RxCpltCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief CEC error callbacks
- * @param hcec: CEC handle
- * @retval None
- */
- __weak void HAL_CEC_ErrorCallback(CEC_HandleTypeDef *hcec)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcec);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_CEC_ErrorCallback can be implemented in the user file
- */
-}
-/**
- * @}
- */
-
-/** @defgroup CEC_Exported_Functions_Group3 Peripheral Control functions
- * @brief CEC control functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral Control function #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to control the CEC.
- (+) HAL_CEC_GetState() API can be helpful to check in run-time the state of the CEC peripheral.
- (+) HAL_CEC_GetError() API can be helpful to check in run-time the error of the CEC peripheral.
-@endverbatim
- * @{
- */
-/**
- * @brief return the CEC state
- * @param hcec: pointer to a CEC_HandleTypeDef structure that contains
- * the configuration information for the specified CEC module.
- * @retval HAL state
- */
-HAL_CEC_StateTypeDef HAL_CEC_GetState(CEC_HandleTypeDef *hcec)
-{
- uint32_t temp1= 0x00U, temp2 = 0x00U;
- temp1 = hcec->gState;
- temp2 = hcec->RxState;
-
- return (HAL_CEC_StateTypeDef)(temp1 | temp2);
-}
-
-/**
-* @brief Return the CEC error code
-* @param hcec : pointer to a CEC_HandleTypeDef structure that contains
- * the configuration information for the specified CEC.
-* @retval CEC Error Code
-*/
-uint32_t HAL_CEC_GetError(CEC_HandleTypeDef *hcec)
-{
- return hcec->ErrorCode;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup CEC_Private_Functions
- * @{
- */
-
- /**
- * @brief Send data in interrupt mode
- * @param hcec: CEC handle.
- * Function called under interruption only, once
- * interruptions have been enabled by HAL_CEC_Transmit_IT()
- * @retval HAL status
- */
-static HAL_StatusTypeDef CEC_Transmit_IT(CEC_HandleTypeDef *hcec)
-{
- /* if the IP is already busy or if there is a previous transmission
- already pending due to arbitration loss */
- if((hcec->gState == HAL_CEC_STATE_BUSY_TX) || (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) != RESET))
- {
- /* if all data have been sent */
- if(hcec->TxXferCount == 0U)
- {
- /* Acknowledge successful completion by writing 0x00 */
- MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, 0x00U);
-
- hcec->gState = HAL_CEC_STATE_READY;
-
- HAL_CEC_TxCpltCallback(hcec);
-
- return HAL_OK;
- }
- else
- {
- /* Reduce the number of bytes to transfer by one */
- hcec->TxXferCount--;
-
- /* Write data to TX buffer*/
- hcec->Instance->TXD = *hcec->pTxBuffPtr++;
-
- /* If this is the last byte of the ongoing transmission */
- if(hcec->TxXferCount == 0U)
- {
- /* Acknowledge byte request and signal end of message */
- MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, CEC_FLAG_TEOM);
- }
- else
- {
- /* Acknowledge byte request by writing 0x00 */
- MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, 0x00U);
- }
-
- return HAL_OK;
- }
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receive data in interrupt mode.
- * @param hcec: CEC handle.
- * Function called under interruption only, once
- * interruptions have been enabled by HAL_CEC_Receive_IT()
- * @retval HAL status
- */
-static HAL_StatusTypeDef CEC_Receive_IT(CEC_HandleTypeDef *hcec)
-{
- static uint32_t temp;
-
- if(hcec->RxState == HAL_CEC_STATE_BUSY_RX)
- {
- temp = hcec->Instance->CSR;
-
- /* Store received data */
- hcec->RxXferSize++;
- *hcec->Init.RxBuffer++ = hcec->Instance->RXD;
-
- /* Acknowledge received byte by writing 0x00 */
- MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_RECEIVE_MASK, 0x00U);
-
- /* If the End Of Message is reached */
- if(HAL_IS_BIT_SET(temp, CEC_FLAG_REOM))
- {
- /* Interrupts are not disabled due to transmission still ongoing */
- hcec->RxState = HAL_CEC_STATE_READY;
-
- HAL_CEC_RxCpltCallback(hcec, hcec->RxXferSize);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* defined(STM32F100xB) || defined(STM32F100xE) */
-
-#endif /* HAL_CEC_MODULE_ENABLED */
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c
deleted file mode 100644
index ba8bb63..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c
+++ /dev/null
@@ -1,521 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_cortex.c
- * @author MCD Application Team
- * @brief CORTEX HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the CORTEX:
- * + Initialization and de-initialization functions
- * + Peripheral Control functions
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
-
- [..]
- *** How to configure Interrupts using CORTEX HAL driver ***
- ===========================================================
- [..]
- This section provides functions allowing to configure the NVIC interrupts (IRQ).
- The Cortex-M3 exceptions are managed by CMSIS functions.
-
- (#) Configure the NVIC Priority Grouping using HAL_NVIC_SetPriorityGrouping()
- function according to the following table.
- (#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority().
- (#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ().
- (#) please refer to programming manual for details in how to configure priority.
-
- -@- When the NVIC_PRIORITYGROUP_0 is selected, IRQ preemption is no more possible.
- The pending IRQ priority will be managed only by the sub priority.
-
- -@- IRQ priority order (sorted by highest to lowest priority):
- (+@) Lowest preemption priority
- (+@) Lowest sub priority
- (+@) Lowest hardware priority (IRQ number)
-
- [..]
- *** How to configure Systick using CORTEX HAL driver ***
- ========================================================
- [..]
- Setup SysTick Timer for time base.
-
- (+) The HAL_SYSTICK_Config()function calls the SysTick_Config() function which
- is a CMSIS function that:
- (++) Configures the SysTick Reload register with value passed as function parameter.
- (++) Configures the SysTick IRQ priority to the lowest value 0x0F.
- (++) Resets the SysTick Counter register.
- (++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK).
- (++) Enables the SysTick Interrupt.
- (++) Starts the SysTick Counter.
-
- (+) You can change the SysTick Clock source to be HCLK_Div8 by calling the macro
- __HAL_CORTEX_SYSTICKCLK_CONFIG(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the
- HAL_SYSTICK_Config() function call. The __HAL_CORTEX_SYSTICKCLK_CONFIG() macro is defined
- inside the stm32f1xx_hal_cortex.h file.
-
- (+) You can change the SysTick IRQ priority by calling the
- HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function
- call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is a CMSIS function.
-
- (+) To adjust the SysTick time base, use the following formula:
-
- Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s)
- (++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function
- (++) Reload Value should not exceed 0xFFFFFF
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup CORTEX CORTEX
- * @brief CORTEX HAL module driver
- * @{
- */
-
-#ifdef HAL_CORTEX_MODULE_ENABLED
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-
-/** @defgroup CORTEX_Exported_Functions CORTEX Exported Functions
- * @{
- */
-
-
-/** @defgroup CORTEX_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
- ==============================================================================
- ##### Initialization and de-initialization functions #####
- ==============================================================================
- [..]
- This section provides the CORTEX HAL driver functions allowing to configure Interrupts
- Systick functionalities
-
-@endverbatim
- * @{
- */
-
-
-/**
- * @brief Sets the priority grouping field (preemption priority and subpriority)
- * using the required unlock sequence.
- * @param PriorityGroup: The priority grouping bits length.
- * This parameter can be one of the following values:
- * @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
- * 4 bits for subpriority
- * @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
- * 3 bits for subpriority
- * @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
- * 2 bits for subpriority
- * @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
- * 1 bits for subpriority
- * @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
- * 0 bits for subpriority
- * @note When the NVIC_PriorityGroup_0 is selected, IRQ preemption is no more possible.
- * The pending IRQ priority will be managed only by the subpriority.
- * @retval None
- */
-void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
-{
- /* Check the parameters */
- assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
-
- /* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
- NVIC_SetPriorityGrouping(PriorityGroup);
-}
-
-/**
- * @brief Sets the priority of an interrupt.
- * @param IRQn: External interrupt number.
- * This parameter can be an enumerator of IRQn_Type enumeration
- * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xx.h))
- * @param PreemptPriority: The preemption priority for the IRQn channel.
- * This parameter can be a value between 0 and 15
- * A lower priority value indicates a higher priority
- * @param SubPriority: the subpriority level for the IRQ channel.
- * This parameter can be a value between 0 and 15
- * A lower priority value indicates a higher priority.
- * @retval None
- */
-void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
-{
- uint32_t prioritygroup = 0x00U;
-
- /* Check the parameters */
- assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
- assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
-
- prioritygroup = NVIC_GetPriorityGrouping();
-
- NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
-}
-
-/**
- * @brief Enables a device specific interrupt in the NVIC interrupt controller.
- * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
- * function should be called before.
- * @param IRQn External interrupt number.
- * This parameter can be an enumerator of IRQn_Type enumeration
- * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
- * @retval None
- */
-void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
-{
- /* Check the parameters */
- assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
-
- /* Enable interrupt */
- NVIC_EnableIRQ(IRQn);
-}
-
-/**
- * @brief Disables a device specific interrupt in the NVIC interrupt controller.
- * @param IRQn External interrupt number.
- * This parameter can be an enumerator of IRQn_Type enumeration
- * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
- * @retval None
- */
-void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
-{
- /* Check the parameters */
- assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
-
- /* Disable interrupt */
- NVIC_DisableIRQ(IRQn);
-}
-
-/**
- * @brief Initiates a system reset request to reset the MCU.
- * @retval None
- */
-void HAL_NVIC_SystemReset(void)
-{
- /* System Reset */
- NVIC_SystemReset();
-}
-
-/**
- * @brief Initializes the System Timer and its interrupt, and starts the System Tick Timer.
- * Counter is in free running mode to generate periodic interrupts.
- * @param TicksNumb: Specifies the ticks Number of ticks between two interrupts.
- * @retval status: - 0 Function succeeded.
- * - 1 Function failed.
- */
-uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
-{
- return SysTick_Config(TicksNumb);
-}
-/**
- * @}
- */
-
-/** @defgroup CORTEX_Exported_Functions_Group2 Peripheral Control functions
- * @brief Cortex control functions
- *
-@verbatim
- ==============================================================================
- ##### Peripheral Control functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to control the CORTEX
- (NVIC, SYSTICK, MPU) functionalities.
-
-
-@endverbatim
- * @{
- */
-
-#if (__MPU_PRESENT == 1U)
-/**
- * @brief Disables the MPU
- * @retval None
- */
-void HAL_MPU_Disable(void)
-{
- /* Make sure outstanding transfers are done */
- __DMB();
-
- /* Disable fault exceptions */
- SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
-
- /* Disable the MPU and clear the control register*/
- MPU->CTRL = 0U;
-}
-
-/**
- * @brief Enable the MPU.
- * @param MPU_Control: Specifies the control mode of the MPU during hard fault,
- * NMI, FAULTMASK and privileged access to the default memory
- * This parameter can be one of the following values:
- * @arg MPU_HFNMI_PRIVDEF_NONE
- * @arg MPU_HARDFAULT_NMI
- * @arg MPU_PRIVILEGED_DEFAULT
- * @arg MPU_HFNMI_PRIVDEF
- * @retval None
- */
-void HAL_MPU_Enable(uint32_t MPU_Control)
-{
- /* Enable the MPU */
- MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
-
- /* Enable fault exceptions */
- SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
-
- /* Ensure MPU setting take effects */
- __DSB();
- __ISB();
-}
-
-/**
- * @brief Initializes and configures the Region and the memory to be protected.
- * @param MPU_Init: Pointer to a MPU_Region_InitTypeDef structure that contains
- * the initialization and configuration information.
- * @retval None
- */
-void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
-{
- /* Check the parameters */
- assert_param(IS_MPU_REGION_NUMBER(MPU_Init->Number));
- assert_param(IS_MPU_REGION_ENABLE(MPU_Init->Enable));
-
- /* Set the Region number */
- MPU->RNR = MPU_Init->Number;
-
- if ((MPU_Init->Enable) != RESET)
- {
- /* Check the parameters */
- assert_param(IS_MPU_INSTRUCTION_ACCESS(MPU_Init->DisableExec));
- assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(MPU_Init->AccessPermission));
- assert_param(IS_MPU_TEX_LEVEL(MPU_Init->TypeExtField));
- assert_param(IS_MPU_ACCESS_SHAREABLE(MPU_Init->IsShareable));
- assert_param(IS_MPU_ACCESS_CACHEABLE(MPU_Init->IsCacheable));
- assert_param(IS_MPU_ACCESS_BUFFERABLE(MPU_Init->IsBufferable));
- assert_param(IS_MPU_SUB_REGION_DISABLE(MPU_Init->SubRegionDisable));
- assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size));
-
- MPU->RBAR = MPU_Init->BaseAddress;
- MPU->RASR = ((uint32_t)MPU_Init->DisableExec << MPU_RASR_XN_Pos) |
- ((uint32_t)MPU_Init->AccessPermission << MPU_RASR_AP_Pos) |
- ((uint32_t)MPU_Init->TypeExtField << MPU_RASR_TEX_Pos) |
- ((uint32_t)MPU_Init->IsShareable << MPU_RASR_S_Pos) |
- ((uint32_t)MPU_Init->IsCacheable << MPU_RASR_C_Pos) |
- ((uint32_t)MPU_Init->IsBufferable << MPU_RASR_B_Pos) |
- ((uint32_t)MPU_Init->SubRegionDisable << MPU_RASR_SRD_Pos) |
- ((uint32_t)MPU_Init->Size << MPU_RASR_SIZE_Pos) |
- ((uint32_t)MPU_Init->Enable << MPU_RASR_ENABLE_Pos);
- }
- else
- {
- MPU->RBAR = 0x00U;
- MPU->RASR = 0x00U;
- }
-}
-#endif /* __MPU_PRESENT */
-
-/**
- * @brief Gets the priority grouping field from the NVIC Interrupt Controller.
- * @retval Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field)
- */
-uint32_t HAL_NVIC_GetPriorityGrouping(void)
-{
- /* Get the PRIGROUP[10:8] field value */
- return NVIC_GetPriorityGrouping();
-}
-
-/**
- * @brief Gets the priority of an interrupt.
- * @param IRQn: External interrupt number.
- * This parameter can be an enumerator of IRQn_Type enumeration
- * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
- * @param PriorityGroup: the priority grouping bits length.
- * This parameter can be one of the following values:
- * @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
- * 4 bits for subpriority
- * @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
- * 3 bits for subpriority
- * @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
- * 2 bits for subpriority
- * @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
- * 1 bits for subpriority
- * @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
- * 0 bits for subpriority
- * @param pPreemptPriority: Pointer on the Preemptive priority value (starting from 0).
- * @param pSubPriority: Pointer on the Subpriority value (starting from 0).
- * @retval None
- */
-void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t *pPreemptPriority, uint32_t *pSubPriority)
-{
- /* Check the parameters */
- assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
- /* Get priority for Cortex-M system or device specific interrupts */
- NVIC_DecodePriority(NVIC_GetPriority(IRQn), PriorityGroup, pPreemptPriority, pSubPriority);
-}
-
-/**
- * @brief Sets Pending bit of an external interrupt.
- * @param IRQn External interrupt number
- * This parameter can be an enumerator of IRQn_Type enumeration
- * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
- * @retval None
- */
-void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)
-{
- /* Check the parameters */
- assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
-
- /* Set interrupt pending */
- NVIC_SetPendingIRQ(IRQn);
-}
-
-/**
- * @brief Gets Pending Interrupt (reads the pending register in the NVIC
- * and returns the pending bit for the specified interrupt).
- * @param IRQn External interrupt number.
- * This parameter can be an enumerator of IRQn_Type enumeration
- * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
- * @retval status: - 0 Interrupt status is not pending.
- * - 1 Interrupt status is pending.
- */
-uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)
-{
- /* Check the parameters */
- assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
-
- /* Return 1 if pending else 0 */
- return NVIC_GetPendingIRQ(IRQn);
-}
-
-/**
- * @brief Clears the pending bit of an external interrupt.
- * @param IRQn External interrupt number.
- * This parameter can be an enumerator of IRQn_Type enumeration
- * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
- * @retval None
- */
-void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)
-{
- /* Check the parameters */
- assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
-
- /* Clear pending interrupt */
- NVIC_ClearPendingIRQ(IRQn);
-}
-
-/**
- * @brief Gets active interrupt ( reads the active register in NVIC and returns the active bit).
- * @param IRQn External interrupt number
- * This parameter can be an enumerator of IRQn_Type enumeration
- * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
- * @retval status: - 0 Interrupt status is not pending.
- * - 1 Interrupt status is pending.
- */
-uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn)
-{
- /* Check the parameters */
- assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
-
- /* Return 1 if active else 0 */
- return NVIC_GetActive(IRQn);
-}
-
-/**
- * @brief Configures the SysTick clock source.
- * @param CLKSource: specifies the SysTick clock source.
- * This parameter can be one of the following values:
- * @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
- * @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
- * @retval None
- */
-void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)
-{
- /* Check the parameters */
- assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource));
- if (CLKSource == SYSTICK_CLKSOURCE_HCLK)
- {
- SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
- }
- else
- {
- SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK;
- }
-}
-
-/**
- * @brief This function handles SYSTICK interrupt request.
- * @retval None
- */
-void HAL_SYSTICK_IRQHandler(void)
-{
- HAL_SYSTICK_Callback();
-}
-
-/**
- * @brief SYSTICK callback.
- * @retval None
- */
-__weak void HAL_SYSTICK_Callback(void)
-{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_SYSTICK_Callback could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* HAL_CORTEX_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_crc.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_crc.c
deleted file mode 100644
index dc5b630..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_crc.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_crc.c
- * @author MCD Application Team
- * @brief CRC HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Cyclic Redundancy Check (CRC) peripheral:
- * + Initialization and de-initialization functions
- * + Peripheral Control functions
- * + Peripheral State functions
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- The CRC HAL driver can be used as follows:
-
- (#) Enable CRC AHB clock using __HAL_RCC_CRC_CLK_ENABLE();
-
- (#) Use HAL_CRC_Accumulate() function to compute the CRC value of
- a 32-bit data buffer using combination of the previous CRC value
- and the new one.
-
- (#) Use HAL_CRC_Calculate() function to compute the CRC Value of
- a new 32-bit data buffer. This function resets the CRC computation
- unit before starting the computation to avoid getting wrong CRC values.
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup CRC CRC
- * @brief CRC HAL module driver.
- * @{
- */
-
-#ifdef HAL_CRC_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
-
-/** @defgroup CRC_Exported_Functions CRC Exported Functions
- * @{
- */
-
-/** @defgroup CRC_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions.
- *
-@verbatim
- ==============================================================================
- ##### Initialization and de-initialization functions #####
- ==============================================================================
- [..] This section provides functions allowing to:
- (+) Initialize the CRC according to the specified parameters
- in the CRC_InitTypeDef and create the associated handle
- (+) DeInitialize the CRC peripheral
- (+) Initialize the CRC MSP
- (+) DeInitialize CRC MSP
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the CRC according to the specified
- * parameters in the CRC_InitTypeDef and creates the associated handle.
- * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains
- * the configuration information for CRC
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc)
-{
- /* Check the CRC handle allocation */
- if(hcrc == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
-
- if(hcrc->State == HAL_CRC_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- hcrc->Lock = HAL_UNLOCKED;
-
- /* Init the low level hardware */
- HAL_CRC_MspInit(hcrc);
- }
-
- /* Change CRC peripheral state */
- hcrc->State = HAL_CRC_STATE_READY;
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief DeInitializes the CRC peripheral.
- * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains
- * the configuration information for CRC
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_CRC_DeInit(CRC_HandleTypeDef *hcrc)
-{
- /* Check the CRC handle allocation */
- if(hcrc == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
-
- /* Change CRC peripheral state */
- hcrc->State = HAL_CRC_STATE_BUSY;
-
- /* DeInit the low level hardware */
- HAL_CRC_MspDeInit(hcrc);
-
- /* Resets the CRC calculation unit and sets the data register to 0xFFFF FFFF */
- __HAL_CRC_DR_RESET(hcrc);
-
- /* Reset IDR register content */
- CLEAR_BIT(hcrc->Instance->IDR, CRC_IDR_IDR);
-
- /* Change CRC peripheral state */
- hcrc->State = HAL_CRC_STATE_RESET;
-
- /* Release Lock */
- __HAL_UNLOCK(hcrc);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the CRC MSP.
- * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains
- * the configuration information for CRC
- * @retval None
- */
-__weak void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcrc);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_CRC_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief DeInitializes the CRC MSP.
- * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains
- * the configuration information for CRC
- * @retval None
- */
-__weak void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hcrc);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_CRC_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup CRC_Exported_Functions_Group2 Peripheral Control functions
- * @brief management functions.
- *
-@verbatim
- ==============================================================================
- ##### Peripheral Control functions #####
- ==============================================================================
- [..] This section provides functions allowing to:
- (+) Compute the 32-bit CRC value of 32-bit data buffer,
- using combination of the previous CRC value and the new one.
- (+) Compute the 32-bit CRC value of 32-bit data buffer,
- independently of the previous CRC value.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Computes the 32-bit CRC of 32-bit data buffer using combination
- * of the previous CRC value and the new one.
- * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains
- * the configuration information for CRC
- * @param pBuffer: pointer to the buffer containing the data to be computed
- * @param BufferLength: length of the buffer to be computed (defined in word, 4 bytes)
- * @retval 32-bit CRC
- */
-uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
-{
- uint32_t index = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hcrc);
-
- /* Change CRC peripheral state */
- hcrc->State = HAL_CRC_STATE_BUSY;
-
- /* Enter Data to the CRC calculator */
- for(index = 0U; index < BufferLength; index++)
- {
- hcrc->Instance->DR = pBuffer[index];
- }
-
- /* Change CRC peripheral state */
- hcrc->State = HAL_CRC_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hcrc);
-
- /* Return the CRC computed value */
- return hcrc->Instance->DR;
-}
-
-/**
- * @brief Computes the 32-bit CRC of 32-bit data buffer independently
- * of the previous CRC value.
- * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains
- * the configuration information for CRC
- * @param pBuffer: Pointer to the buffer containing the data to be computed
- * @param BufferLength: Length of the buffer to be computed (defined in word, 4 bytes)
- * @retval 32-bit CRC
- */
-uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
-{
- uint32_t index = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hcrc);
-
- /* Change CRC peripheral state */
- hcrc->State = HAL_CRC_STATE_BUSY;
-
- /* Reset CRC Calculation Unit */
- __HAL_CRC_DR_RESET(hcrc);
-
- /* Enter Data to the CRC calculator */
- for(index = 0U; index < BufferLength; index++)
- {
- hcrc->Instance->DR = pBuffer[index];
- }
-
- /* Change CRC peripheral state */
- hcrc->State = HAL_CRC_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hcrc);
-
- /* Return the CRC computed value */
- return hcrc->Instance->DR;
-}
-
-/**
- * @}
- */
-
-/** @defgroup CRC_Exported_Functions_Group3 Peripheral State functions
- * @brief Peripheral State functions.
- *
-@verbatim
- ==============================================================================
- ##### Peripheral State functions #####
- ==============================================================================
- [..]
- This subsection permits to get in run-time the status of the peripheral.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Returns the CRC state.
- * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains
- * the configuration information for CRC
- * @retval HAL state
- */
-HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc)
-{
- return hcrc->State;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* HAL_CRC_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dac.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dac.c
deleted file mode 100644
index 9f8d91c..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dac.c
+++ /dev/null
@@ -1,937 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_dac.c
- * @author MCD Application Team
- * @brief DAC HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Digital to Analog Converter (DAC) peripheral:
- * + Initialization and de-initialization functions
- * + IO operation functions
- * + Peripheral Control functions
- * + Peripheral State and Errors functions
- *
- *
- @verbatim
- ==============================================================================
- ##### DAC Peripheral features #####
- ==============================================================================
- [..]
- *** DAC Channels ***
- ====================
- [..]
- The device integrates two 12-bit Digital Analog Converters that can
- be used independently or simultaneously (dual mode):
- (#) DAC channel1 with DAC_OUT1 (PA4) as output
- (#) DAC channel2 with DAC_OUT2 (PA5) as output
-
- *** DAC Triggers ***
- ====================
- [..]
- Digital to Analog conversion can be non-triggered using DAC_TRIGGER_NONE
- and DAC_OUT1/DAC_OUT2 is available once writing to DHRx register.
- [..]
- Digital to Analog conversion can be triggered by:
- (#) External event: EXTI Line 9 (any GPIOx_PIN_9) using DAC_TRIGGER_EXT_IT9.
- The used pin (GPIOx_PIN_9) must be configured in input mode.
-
- (#) Timers TRGO: TIM2, TIM4, TIM6, TIM7
- For STM32F10x connectivity line devices and STM32F100x devices: TIM3
- For STM32F10x high-density and XL-density devices: TIM8
- For STM32F100x high-density value line devices: TIM15 as
- replacement of TIM5.
- (DAC_TRIGGER_T2_TRGO, DAC_TRIGGER_T4_TRGO...)
-
- (#) Software using DAC_TRIGGER_SOFTWARE
-
- *** DAC Buffer mode feature ***
- ===============================
- [..]
- Each DAC channel integrates an output buffer that can be used to
- reduce the output impedance, and to drive external loads directly
- without having to add an external operational amplifier.
- To enable, the output buffer use
- sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
- [..]
- (@) Refer to the device datasheet for more details about output
- impedance value with and without output buffer.
-
- *** DAC connect feature ***
- ===============================
- [..]
- Each DAC channel can be connected internally.
- To connect, use
- sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_ENABLE;
-
- *** GPIO configurations guidelines ***
- =====================
- [..]
- When a DAC channel is used (ex channel1 on PA4) and the other is not
- (ex channel1 on PA5 is configured in Analog and disabled).
- Channel1 may disturb channel2 as coupling effect.
- Note that there is no coupling on channel2 as soon as channel2 is turned on.
- Coupling on adjacent channel could be avoided as follows:
- when unused PA5 is configured as INPUT PULL-UP or DOWN.
- PA5 is configured in ANALOG just before it is turned on.
-
- *** DAC wave generation feature ***
- ===================================
- [..]
- Both DAC channels can be used to generate
- (#) Noise wave using HAL_DACEx_NoiseWaveGenerate()
- (#) Triangle wave using HAL_DACEx_TriangleWaveGenerate()
-
- *** DAC data format ***
- =======================
- [..]
- The DAC data format can be:
- (#) 8-bit right alignment using DAC_ALIGN_8B_R
- (#) 12-bit left alignment using DAC_ALIGN_12B_L
- (#) 12-bit right alignment using DAC_ALIGN_12B_R
-
- *** DAC data value to voltage correspondance ***
- ================================================
- [..]
- The analog output voltage on each DAC channel pin is determined
- by the following equation:
- [..]
- DAC_OUTx = VREF+ * DOR / 4095
- (+) with DOR is the Data Output Register
- [..]
- VEF+ is the input voltage reference (refer to the device datasheet)
- [..]
- e.g. To set DAC_OUT1 to 0.7V, use
- (+) Assuming that VREF+ = 3.3V, DAC_OUT1 = (3.3 * 868) / 4095 = 0.7V
-
- *** DMA requests ***
- =====================
- [..]
- A DMA1 request can be generated when an external trigger (but not
- a software trigger) occurs if DMA1 requests are enabled using
- HAL_DAC_Start_DMA()
- [..]
- DMA requests are mapped as following:
- (#) DAC channel1 :
- For STM32F100x low-density, medium-density, high-density with DAC
- DMA remap:
- mapped on DMA1 channel3 which must be
- already configured
- For STM32F100x high-density without DAC DMA remap and other
- STM32F1 devices:
- mapped on DMA2 channel3 which must be
- already configured
- (#) DAC channel2 :
- For STM32F100x low-density, medium-density, high-density with DAC
- DMA remap:
- mapped on DMA1 channel4 which must be
- already configured
- For STM32F100x high-density without DAC DMA remap and other
- STM32F1 devices:
- mapped on DMA2 channel4 which must be
- already configured
-
- ##### How to use this driver #####
- ==============================================================================
- [..]
- (+) DAC APB clock must be enabled to get write access to DAC
- registers using HAL_DAC_Init()
- (+) Configure DAC_OUTx (DAC_OUT1: PA4, DAC_OUT2: PA5) in analog mode.
- (+) Configure the DAC channel using HAL_DAC_ConfigChannel() function.
- (+) Enable the DAC channel using HAL_DAC_Start() or HAL_DAC_Start_DMA functions
-
- *** Polling mode IO operation ***
- =================================
- [..]
- (+) Start the DAC peripheral using HAL_DAC_Start()
- (+) To read the DAC last data output value, use the HAL_DAC_GetValue() function.
- (+) Stop the DAC peripheral using HAL_DAC_Stop()
-
- *** DMA mode IO operation ***
- ==============================
- [..]
- (+) Start the DAC peripheral using HAL_DAC_Start_DMA(), at this stage the user specify the length
- of data to be transferred at each end of conversion
- (+) At the middle of data transfer HAL_DACEx_ConvHalfCpltCallbackCh1()or HAL_DACEx_ConvHalfCpltCallbackCh2()
- function is executed and user can add his own code by customization of function pointer
- HAL_DAC_ConvHalfCpltCallbackCh1 or HAL_DAC_ConvHalfCpltCallbackCh2
- (+) At The end of data transfer HAL_DAC_ConvCpltCallbackCh1()or HAL_DAC_ConvCpltCallbackCh2()
- function is executed and user can add his own code by customization of function pointer
- HAL_DAC_ConvCpltCallbackCh1 or HAL_DAC_ConvCpltCallbackCh2
- (+) In case of transfer Error, HAL_DAC_ErrorCallbackCh1() or HAL_DACEx_ErrorCallbackCh2() function is executed and user can
- add his own code by customization of function pointer HAL_DAC_ErrorCallbackCh1 or HAL_DACEx_ErrorCallbackCh2
- (+) For STM32F100x devices with specific feature: DMA underrun.
- In case of DMA underrun, DAC interruption triggers and execute internal function HAL_DAC_IRQHandler.
- HAL_DAC_DMAUnderrunCallbackCh1()or HAL_DACEx_DMAUnderrunCallbackCh2()
- function is executed and user can add his own code by customization of function pointer
- HAL_DAC_DMAUnderrunCallbackCh1 or HAL_DACEx_DMAUnderrunCallbackCh2
- add his own code by customization of function pointer HAL_DAC_ErrorCallbackCh1
- (+) Stop the DAC peripheral using HAL_DAC_Stop_DMA()
-
- *** DAC HAL driver macros list ***
- =============================================
- [..]
- Below the list of most used macros in DAC HAL driver.
-
- (+) __HAL_DAC_ENABLE : Enable the DAC peripheral (For STM32F100x devices with specific feature: DMA underrun)
- (+) __HAL_DAC_DISABLE : Disable the DAC peripheral (For STM32F100x devices with specific feature: DMA underrun)
- (+) __HAL_DAC_CLEAR_FLAG: Clear the DAC's pending flags (For STM32F100x devices with specific feature: DMA underrun)
- (+) __HAL_DAC_GET_FLAG: Get the selected DAC's flag status (For STM32F100x devices with specific feature: DMA underrun)
-
- [..]
- (@) You can refer to the DAC HAL driver header file for more useful macros
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup DAC DAC
- * @brief DAC driver modules
- * @{
- */
-
-#ifdef HAL_DAC_MODULE_ENABLED
-#if defined (STM32F100xB) || defined (STM32F100xE) || defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC)
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Exported functions -------------------------------------------------------*/
-
-/** @defgroup DAC_Exported_Functions DAC Exported Functions
- * @{
- */
-
-/** @defgroup DAC_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
- ==============================================================================
- ##### Initialization and de-initialization functions #####
- ==============================================================================
- [..] This section provides functions allowing to:
- (+) Initialize and configure the DAC.
- (+) De-initialize the DAC.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the DAC peripheral according to the specified parameters
- * in the DAC_InitStruct.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DAC_Init(DAC_HandleTypeDef* hdac)
-{
- /* Check DAC handle */
- if(hdac == NULL)
- {
- return HAL_ERROR;
- }
- /* Check the parameters */
- assert_param(IS_DAC_ALL_INSTANCE(hdac->Instance));
-
- if(hdac->State == HAL_DAC_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- hdac->Lock = HAL_UNLOCKED;
-
- /* Init the low level hardware */
- HAL_DAC_MspInit(hdac);
- }
-
- /* Initialize the DAC state*/
- hdac->State = HAL_DAC_STATE_BUSY;
-
- /* Set DAC error code to none */
- hdac->ErrorCode = HAL_DAC_ERROR_NONE;
-
- /* Initialize the DAC state*/
- hdac->State = HAL_DAC_STATE_READY;
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Deinitializes the DAC peripheral registers to their default reset values.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DAC_DeInit(DAC_HandleTypeDef* hdac)
-{
- /* Check DAC handle */
- if(hdac == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_DAC_ALL_INSTANCE(hdac->Instance));
-
- /* Change DAC state */
- hdac->State = HAL_DAC_STATE_BUSY;
-
- /* DeInit the low level hardware */
- HAL_DAC_MspDeInit(hdac);
-
- /* Set DAC error code to none */
- hdac->ErrorCode = HAL_DAC_ERROR_NONE;
-
- /* Change DAC state */
- hdac->State = HAL_DAC_STATE_RESET;
-
- /* Release Lock */
- __HAL_UNLOCK(hdac);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the DAC MSP.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @retval None
- */
-__weak void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hdac);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_DAC_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief DeInitializes the DAC MSP.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @retval None
- */
-__weak void HAL_DAC_MspDeInit(DAC_HandleTypeDef* hdac)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hdac);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_DAC_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup DAC_Exported_Functions_Group2 IO operation functions
- * @brief IO operation functions
- *
-@verbatim
- ==============================================================================
- ##### IO operation functions #####
- ==============================================================================
- [..] This section provides functions allowing to:
- (+) Start conversion.
- (+) Stop conversion.
- (+) Start conversion and enable DMA transfer.
- (+) Stop conversion and disable DMA transfer.
- (+) Get result of conversion.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Enables DAC and starts conversion of channel.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @param Channel: The selected DAC channel.
- * This parameter can be one of the following values:
- * @arg DAC_CHANNEL_1: DAC Channel1 selected
- * @arg DAC_CHANNEL_2: DAC Channel2 selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef* hdac, uint32_t Channel)
-{
- /* Check the parameters */
- assert_param(IS_DAC_CHANNEL(Channel));
-
- /* Process locked */
- __HAL_LOCK(hdac);
-
- /* Change DAC state */
- hdac->State = HAL_DAC_STATE_BUSY;
-
- /* Enable the Peripharal */
- __HAL_DAC_ENABLE(hdac, Channel);
-
- if(Channel == DAC_CHANNEL_1)
- {
- /* Check if software trigger enabled */
- if((hdac->Instance->CR & (DAC_CR_TEN1 | DAC_CR_TSEL1)) == (DAC_CR_TEN1 | DAC_CR_TSEL1))
- {
- /* Enable the selected DAC software conversion */
- SET_BIT(hdac->Instance->SWTRIGR, DAC_SWTRIGR_SWTRIG1);
- }
- }
- else
- {
- /* Check if software trigger enabled */
- if((hdac->Instance->CR & (DAC_CR_TEN2 | DAC_CR_TSEL2)) == (DAC_CR_TEN2 | DAC_CR_TSEL2))
- {
- /* Enable the selected DAC software conversion*/
- SET_BIT(hdac->Instance->SWTRIGR, DAC_SWTRIGR_SWTRIG2);
- }
- }
-
- /* Change DAC state */
- hdac->State = HAL_DAC_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hdac);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Disables DAC and stop conversion of channel.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @param Channel: The selected DAC channel.
- * This parameter can be one of the following values:
- * @arg DAC_CHANNEL_1: DAC Channel1 selected
- * @arg DAC_CHANNEL_2: DAC Channel2 selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DAC_Stop(DAC_HandleTypeDef* hdac, uint32_t Channel)
-{
- /* Check the parameters */
- assert_param(IS_DAC_CHANNEL(Channel));
-
- /* Disable the Peripheral */
- __HAL_DAC_DISABLE(hdac, Channel);
-
- /* Change DAC state */
- hdac->State = HAL_DAC_STATE_READY;
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Enables DAC and starts conversion of channel.
- * Note: For STM32F100x devices with specific feature: DMA underrun.
- * On these devices, this function enables the interruption of DMA
- * underrun.
- * (refer to redefinition of this function in DAC extended file)
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @param Channel: The selected DAC channel.
- * This parameter can be one of the following values:
- * @arg DAC_CHANNEL_1: DAC Channel1 selected
- * @arg DAC_CHANNEL_2: DAC Channel2 selected
- * @param pData: The Source memory Buffer address.
- * @param Length: The length of data to be transferred from memory to DAC peripheral
- * @param Alignment: Specifies the data alignment for DAC channel.
- * This parameter can be one of the following values:
- * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
- * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
- * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
- * @retval HAL status
- */
-__weak HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t* pData, uint32_t Length, uint32_t Alignment)
-{
- uint32_t tmpreg = 0U;
-
- /* Check the parameters */
- assert_param(IS_DAC_CHANNEL(Channel));
- assert_param(IS_DAC_ALIGN(Alignment));
-
- /* Process locked */
- __HAL_LOCK(hdac);
-
- /* Change DAC state */
- hdac->State = HAL_DAC_STATE_BUSY;
-
- if(Channel == DAC_CHANNEL_1)
- {
- /* Set the DMA transfer complete callback for channel1 */
- hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1;
-
- /* Set the DMA half transfer complete callback for channel1 */
- hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1;
-
- /* Set the DMA error callback for channel1 */
- hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1;
-
- /* Enable the selected DAC channel1 DMA request */
- SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1);
-
- /* Case of use of channel 1 */
- switch(Alignment)
- {
- case DAC_ALIGN_12B_R:
- /* Get DHR12R1 address */
- tmpreg = (uint32_t)&hdac->Instance->DHR12R1;
- break;
- case DAC_ALIGN_12B_L:
- /* Get DHR12L1 address */
- tmpreg = (uint32_t)&hdac->Instance->DHR12L1;
- break;
- case DAC_ALIGN_8B_R:
- /* Get DHR8R1 address */
- tmpreg = (uint32_t)&hdac->Instance->DHR8R1;
- break;
- default:
- break;
- }
- }
- else
- {
- /* Set the DMA transfer complete callback for channel2 */
- hdac->DMA_Handle2->XferCpltCallback = DAC_DMAConvCpltCh2;
-
- /* Set the DMA half transfer complete callback for channel2 */
- hdac->DMA_Handle2->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh2;
-
- /* Set the DMA error callback for channel2 */
- hdac->DMA_Handle2->XferErrorCallback = DAC_DMAErrorCh2;
-
- /* Enable the selected DAC channel2 DMA request */
- SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN2);
-
- /* Case of use of channel 2 */
- switch(Alignment)
- {
- case DAC_ALIGN_12B_R:
- /* Get DHR12R2 address */
- tmpreg = (uint32_t)&hdac->Instance->DHR12R2;
- break;
- case DAC_ALIGN_12B_L:
- /* Get DHR12L2 address */
- tmpreg = (uint32_t)&hdac->Instance->DHR12L2;
- break;
- case DAC_ALIGN_8B_R:
- /* Get DHR8R2 address */
- tmpreg = (uint32_t)&hdac->Instance->DHR8R2;
- break;
- default:
- break;
- }
- }
-
- /* Enable the DMA channel */
- if(Channel == DAC_CHANNEL_1)
- {
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, Length);
- }
- else
- {
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, tmpreg, Length);
- }
-
- /* Process Unlocked */
- __HAL_UNLOCK(hdac);
-
- /* Enable the Peripharal */
- __HAL_DAC_ENABLE(hdac, Channel);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Disables DAC and stop conversion of channel.
- * Note: For STM32F100x devices with specific feature: DMA underrun.
- * On these devices, this function disables the interruption of DMA
- * underrun.
- * (refer to redefinition of this function in DAC extended file)
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @param Channel: The selected DAC channel.
- * This parameter can be one of the following values:
- * @arg DAC_CHANNEL_1: DAC Channel1 selected
- * @arg DAC_CHANNEL_2: DAC Channel2 selected
- * @retval HAL status
- */
-__weak HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel)
-{
- HAL_StatusTypeDef status = HAL_OK;
-
- /* Check the parameters */
- assert_param(IS_DAC_CHANNEL(Channel));
-
- /* Disable the selected DAC channel DMA request */
- CLEAR_BIT(hdac->Instance->CR, DAC_CR_DMAEN1 << Channel);
-
- /* Disable the Peripharal */
- __HAL_DAC_DISABLE(hdac, Channel);
-
- /* Disable the DMA Channel */
- /* Channel1 is used */
- if (Channel == DAC_CHANNEL_1)
- {
- status = HAL_DMA_Abort(hdac->DMA_Handle1);
- }
- else /* Channel2 is used for */
- {
- status = HAL_DMA_Abort(hdac->DMA_Handle2);
- }
-
- /* Check if DMA Channel effectively disabled */
- if (status != HAL_OK)
- {
- /* Update ADC state machine to error */
- hdac->State = HAL_DAC_STATE_ERROR;
- }
- else
- {
- /* Change DAC state */
- hdac->State = HAL_DAC_STATE_READY;
- }
-
- /* Return function status */
- return status;
-}
-
-/**
- * @brief Returns the last data output value of the selected DAC channel.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @param Channel: The selected DAC channel.
- * This parameter can be one of the following values:
- * @arg DAC_CHANNEL_1: DAC Channel1 selected
- * @arg DAC_CHANNEL_2: DAC Channel2 selected
- * @retval The selected DAC channel data output value.
- */
-uint32_t HAL_DAC_GetValue(DAC_HandleTypeDef* hdac, uint32_t Channel)
-{
- /* Check the parameters */
- assert_param(IS_DAC_CHANNEL(Channel));
-
- /* Returns the DAC channel data output register value */
- if(Channel == DAC_CHANNEL_1)
- {
- return hdac->Instance->DOR1;
- }
- else
- {
- return hdac->Instance->DOR2;
- }
-}
-
-/**
- * @brief Conversion complete callback in non blocking mode for Channel1
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @retval None
- */
-__weak void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef* hdac)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hdac);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_DAC_ConvCpltCallbackCh1 could be implemented in the user file
- */
-}
-
-/**
- * @brief Conversion half DMA transfer callback in non blocking mode for Channel1
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @retval None
- */
-__weak void HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef* hdac)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hdac);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_DAC_ConvHalfCpltCallbackCh1 could be implemented in the user file
- */
-}
-
-/**
- * @brief Error DAC callback for Channel1.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @retval None
- */
-__weak void HAL_DAC_ErrorCallbackCh1(DAC_HandleTypeDef *hdac)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hdac);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_DAC_ErrorCallbackCh1 could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup DAC_Exported_Functions_Group3 Peripheral Control functions
- * @brief Peripheral Control functions
- *
-@verbatim
- ==============================================================================
- ##### Peripheral Control functions #####
- ==============================================================================
- [..] This section provides functions allowing to:
- (+) Configure channels.
- (+) Set the specified data holding register value for DAC channel.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Configures the selected DAC channel.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @param sConfig: DAC configuration structure.
- * @param Channel: The selected DAC channel.
- * This parameter can be one of the following values:
- * @arg DAC_CHANNEL_1: DAC Channel1 selected
- * @arg DAC_CHANNEL_2: DAC Channel2 selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DAC_ConfigChannel(DAC_HandleTypeDef* hdac, DAC_ChannelConfTypeDef* sConfig, uint32_t Channel)
-{
- uint32_t tmpreg1 = 0U;
-
- /* Check the DAC parameters */
- assert_param(IS_DAC_TRIGGER(sConfig->DAC_Trigger));
- assert_param(IS_DAC_OUTPUT_BUFFER_STATE(sConfig->DAC_OutputBuffer));
- assert_param(IS_DAC_CHANNEL(Channel));
-
- /* Process locked */
- __HAL_LOCK(hdac);
-
- /* Change DAC state */
- hdac->State = HAL_DAC_STATE_BUSY;
-
- /* Configure for the selected DAC channel: buffer output, trigger */
- /* Set TSELx and TENx bits according to DAC_Trigger value */
- /* Set BOFFx bit according to DAC_OutputBuffer value */
- SET_BIT(tmpreg1, (sConfig->DAC_Trigger | sConfig->DAC_OutputBuffer));
-
- /* Clear BOFFx, TENx, TSELx, WAVEx and MAMPx bits */
- /* Calculate CR register value depending on DAC_Channel */
- MODIFY_REG(hdac->Instance->CR,
- ((uint32_t)(DAC_CR_MAMP1 | DAC_CR_WAVE1 | DAC_CR_TSEL1 | DAC_CR_TEN1 | DAC_CR_BOFF1)) << Channel,
- tmpreg1 << Channel);
-
- /* Disable wave generation */
- hdac->Instance->CR &= ~(DAC_CR_WAVE1 << Channel);
-
- /* Change DAC state */
- hdac->State = HAL_DAC_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hdac);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Set the specified data holding register value for DAC channel.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @param Channel: The selected DAC channel.
- * This parameter can be one of the following values:
- * @arg DAC_CHANNEL_1: DAC Channel1 selected
- * @arg DAC_CHANNEL_2: DAC Channel2 selected
- * @param Alignment: Specifies the data alignment.
- * This parameter can be one of the following values:
- * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
- * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
- * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
- * @param Data: Data to be loaded in the selected data holding register.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data)
-{
- __IO uint32_t tmp = 0U;
-
- /* Check the parameters */
- assert_param(IS_DAC_CHANNEL(Channel));
- assert_param(IS_DAC_ALIGN(Alignment));
- assert_param(IS_DAC_DATA(Data));
-
- tmp = (uint32_t)hdac->Instance;
- if(Channel == DAC_CHANNEL_1)
- {
- tmp += DAC_DHR12R1_ALIGNMENT(Alignment);
- }
- else
- {
- tmp += DAC_DHR12R2_ALIGNMENT(Alignment);
- }
-
- /* Set the DAC channel selected data holding register */
- *(__IO uint32_t *) tmp = Data;
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup DAC_Exported_Functions_Group4 Peripheral State and Errors functions
- * @brief Peripheral State and Errors functions
- *
-@verbatim
- ==============================================================================
- ##### Peripheral State and Errors functions #####
- ==============================================================================
- [..]
- This subsection provides functions allowing to
- (+) Check the DAC state.
- (+) Check the DAC Errors.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief return the DAC state
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @retval HAL state
- */
-HAL_DAC_StateTypeDef HAL_DAC_GetState(DAC_HandleTypeDef* hdac)
-{
- /* Return DAC state */
- return hdac->State;
-}
-
-
-/**
- * @brief Return the DAC error code
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @retval DAC Error Code
- */
-uint32_t HAL_DAC_GetError(DAC_HandleTypeDef *hdac)
-{
- return hdac->ErrorCode;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup DAC_Private_Functions
- * @{
- */
-
-/**
- * @brief DMA conversion complete callback.
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-void DAC_DMAConvCpltCh1(DMA_HandleTypeDef *hdma)
-{
- DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- HAL_DAC_ConvCpltCallbackCh1(hdac);
-
- hdac->State = HAL_DAC_STATE_READY;
-}
-
-/**
- * @brief DMA half transfer complete callback.
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-void DAC_DMAHalfConvCpltCh1(DMA_HandleTypeDef *hdma)
-{
- DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- /* Conversion complete callback */
- HAL_DAC_ConvHalfCpltCallbackCh1(hdac);
-}
-
-/**
- * @brief DMA error callback
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-void DAC_DMAErrorCh1(DMA_HandleTypeDef *hdma)
-{
- DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- /* Set DAC error code to DMA error */
- hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
-
- HAL_DAC_ErrorCallbackCh1(hdac);
-
- hdac->State = HAL_DAC_STATE_READY;
-}
-
-/**
- * @}
- */
-
-#endif /* STM32F100xB || STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
-#endif /* HAL_DAC_MODULE_ENABLED */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dac_ex.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dac_ex.c
deleted file mode 100644
index 486d9ec..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dac_ex.c
+++ /dev/null
@@ -1,667 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_dac_ex.c
- * @author MCD Application Team
- * @brief DAC HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of DAC extension peripheral:
- * + Extended features functions
- *
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- (+) When Dual mode is enabled (i.e DAC Channel1 and Channel2 are used simultaneously) :
- Use HAL_DACEx_DualGetValue() to get digital data to be converted and use
- HAL_DACEx_DualSetValue() to set digital value to converted simultaneously in Channel 1 and Channel 2.
- (+) Use HAL_DACEx_TriangleWaveGenerate() to generate Triangle signal.
- (+) Use HAL_DACEx_NoiseWaveGenerate() to generate Noise signal.
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup DACEx DACEx
- * @brief DACEx driver module
- * @{
- */
-
-#ifdef HAL_DAC_MODULE_ENABLED
-#if defined (STM32F100xB) || defined (STM32F100xE) || defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC)
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-
-/** @defgroup DACEx_Exported_Functions DACEx Exported Functions
- * @{
- */
-
-/** @defgroup DACEx_Exported_Functions_Group1 Extended features functions
- * @brief Extended features functions
- *
-@verbatim
- ==============================================================================
- ##### Extended features functions #####
- ==============================================================================
- [..] This section provides functions allowing to:
- (+) Start conversion.
- (+) Stop conversion.
- (+) Start conversion and enable DMA transfer.
- (+) Stop conversion and disable DMA transfer.
- (+) Get result of conversion.
- (+) Get result of dual mode conversion.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Returns the last data output value of the selected DAC channel.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @retval The selected DAC channel data output value.
- */
-uint32_t HAL_DACEx_DualGetValue(DAC_HandleTypeDef* hdac)
-{
- uint32_t tmp = 0U;
-
- tmp |= hdac->Instance->DOR1;
-
- tmp |= hdac->Instance->DOR2 << 16U;
-
- /* Returns the DAC channel data output register value */
- return tmp;
-}
-
-/**
- * @brief Enables or disables the selected DAC channel wave generation.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @param Channel: The selected DAC channel.
- * This parameter can be one of the following values:
- * DAC_CHANNEL_1 / DAC_CHANNEL_2
- * @param Amplitude: Select max triangle amplitude.
- * This parameter can be one of the following values:
- * @arg DAC_TRIANGLEAMPLITUDE_1: Select max triangle amplitude of 1
- * @arg DAC_TRIANGLEAMPLITUDE_3: Select max triangle amplitude of 3
- * @arg DAC_TRIANGLEAMPLITUDE_7: Select max triangle amplitude of 7
- * @arg DAC_TRIANGLEAMPLITUDE_15: Select max triangle amplitude of 15
- * @arg DAC_TRIANGLEAMPLITUDE_31: Select max triangle amplitude of 31
- * @arg DAC_TRIANGLEAMPLITUDE_63: Select max triangle amplitude of 63
- * @arg DAC_TRIANGLEAMPLITUDE_127: Select max triangle amplitude of 127
- * @arg DAC_TRIANGLEAMPLITUDE_255: Select max triangle amplitude of 255
- * @arg DAC_TRIANGLEAMPLITUDE_511: Select max triangle amplitude of 511
- * @arg DAC_TRIANGLEAMPLITUDE_1023: Select max triangle amplitude of 1023
- * @arg DAC_TRIANGLEAMPLITUDE_2047: Select max triangle amplitude of 2047
- * @arg DAC_TRIANGLEAMPLITUDE_4095: Select max triangle amplitude of 4095
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Amplitude)
-{
- /* Check the parameters */
- assert_param(IS_DAC_CHANNEL(Channel));
- assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
-
- /* Process locked */
- __HAL_LOCK(hdac);
-
- /* Change DAC state */
- hdac->State = HAL_DAC_STATE_BUSY;
-
- /* Enable the selected wave generation for the selected DAC channel */
- MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1)|(DAC_CR_MAMP1))<State = HAL_DAC_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hdac);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Enables or disables the selected DAC channel wave generation.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @param Channel: The selected DAC channel.
- * This parameter can be one of the following values:
- * DAC_CHANNEL_1 / DAC_CHANNEL_2
- * @param Amplitude: Unmask DAC channel LFSR for noise wave generation.
- * This parameter can be one of the following values:
- * @arg DAC_LFSRUNMASK_BIT0: Unmask DAC channel LFSR bit0 for noise wave generation
- * @arg DAC_LFSRUNMASK_BITS1_0: Unmask DAC channel LFSR bit[1:0] for noise wave generation
- * @arg DAC_LFSRUNMASK_BITS2_0: Unmask DAC channel LFSR bit[2:0] for noise wave generation
- * @arg DAC_LFSRUNMASK_BITS3_0: Unmask DAC channel LFSR bit[3:0] for noise wave generation
- * @arg DAC_LFSRUNMASK_BITS4_0: Unmask DAC channel LFSR bit[4:0] for noise wave generation
- * @arg DAC_LFSRUNMASK_BITS5_0: Unmask DAC channel LFSR bit[5:0] for noise wave generation
- * @arg DAC_LFSRUNMASK_BITS6_0: Unmask DAC channel LFSR bit[6:0] for noise wave generation
- * @arg DAC_LFSRUNMASK_BITS7_0: Unmask DAC channel LFSR bit[7:0] for noise wave generation
- * @arg DAC_LFSRUNMASK_BITS8_0: Unmask DAC channel LFSR bit[8:0] for noise wave generation
- * @arg DAC_LFSRUNMASK_BITS9_0: Unmask DAC channel LFSR bit[9:0] for noise wave generation
- * @arg DAC_LFSRUNMASK_BITS10_0: Unmask DAC channel LFSR bit[10:0] for noise wave generation
- * @arg DAC_LFSRUNMASK_BITS11_0: Unmask DAC channel LFSR bit[11:0] for noise wave generation
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Amplitude)
-{
- /* Check the parameters */
- assert_param(IS_DAC_CHANNEL(Channel));
- assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
-
- /* Process locked */
- __HAL_LOCK(hdac);
-
- /* Change DAC state */
- hdac->State = HAL_DAC_STATE_BUSY;
-
- /* Enable the selected wave generation for the selected DAC channel */
- MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1)|(DAC_CR_MAMP1))<State = HAL_DAC_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hdac);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Set the specified data holding register value for dual DAC channel.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @param Alignment: Specifies the data alignment for dual channel DAC.
- * This parameter can be one of the following values:
- * DAC_ALIGN_8B_R: 8bit right data alignment selected
- * DAC_ALIGN_12B_L: 12bit left data alignment selected
- * DAC_ALIGN_12B_R: 12bit right data alignment selected
- * @param Data1: Data for DAC Channel2 to be loaded in the selected data holding register.
- * @param Data2: Data for DAC Channel1 to be loaded in the selected data holding register.
- * @note In dual mode, a unique register access is required to write in both
- * DAC channels at the same time.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef* hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2)
-{
- uint32_t data = 0U, tmp = 0U;
-
- /* Check the parameters */
- assert_param(IS_DAC_ALIGN(Alignment));
- assert_param(IS_DAC_DATA(Data1));
- assert_param(IS_DAC_DATA(Data2));
-
- /* Calculate and set dual DAC data holding register value */
- if (Alignment == DAC_ALIGN_8B_R)
- {
- data = ((uint32_t)Data2 << 8U) | Data1;
- }
- else
- {
- data = ((uint32_t)Data2 << 16U) | Data1;
- }
-
- tmp = (uint32_t)hdac->Instance;
- tmp += DAC_DHR12RD_ALIGNMENT(Alignment);
-
- /* Set the dual DAC selected data holding register */
- *(__IO uint32_t *)tmp = data;
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Conversion complete callback in non blocking mode for Channel2
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @retval None
- */
-__weak void HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef* hdac)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hdac);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_DACEx_ConvCpltCallbackCh2 could be implemented in the user file
- */
-}
-
-/**
- * @brief Conversion half DMA transfer callback in non blocking mode for Channel2
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @retval None
- */
-__weak void HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef* hdac)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hdac);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_DACEx_ConvHalfCpltCallbackCh2 could be implemented in the user file
- */
-}
-
-/**
- * @brief Error DAC callback for Channel2.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @retval None
- */
-__weak void HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef *hdac)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hdac);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_DACEx_ErrorCallbackCh2 could be implemented in the user file
- */
-}
-
-#if defined (STM32F100xB) || defined (STM32F100xE)
-/**
- * @brief DMA underrun DAC callback for channel1.
- * Note: For STM32F100x devices with specific feature: DMA underrun.
- * On these devices, this function uses the interruption of DMA
- * underrun.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @retval None
- */
-__weak void HAL_DAC_DMAUnderrunCallbackCh1(DAC_HandleTypeDef *hdac)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hdac);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_DAC_DMAUnderrunCallbackCh1 could be implemented in the user file
- */
-}
-
-/**
- * @brief DMA underrun DAC callback for channel2.
- * Note: For STM32F100x devices with specific feature: DMA underrun.
- * On these devices, this function uses the interruption of DMA
- * underrun.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @retval None
- */
-__weak void HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef *hdac)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hdac);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_DACEx_DMAUnderrunCallbackCh2 could be implemented in the user file
- */
-}
-#endif /* STM32F100xB) || defined (STM32F100xE) */
-
-/**
- * @}
- */
-
-#if defined (STM32F100xB) || defined (STM32F100xE)
-/**
- * @brief Enables DAC and starts conversion of channel.
- * Note: For STM32F100x devices with specific feature: DMA underrun.
- * On these devices, this function enables the interruption of DMA
- * underrun.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @param Channel: The selected DAC channel.
- * This parameter can be one of the following values:
- * @arg DAC_CHANNEL_1: DAC Channel1 selected
- * @arg DAC_CHANNEL_2: DAC Channel2 selected
- * @param pData: The destination peripheral Buffer address.
- * @param Length: The length of data to be transferred from memory to DAC peripheral
- * @param Alignment: Specifies the data alignment for DAC channel.
- * This parameter can be one of the following values:
- * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
- * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
- * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t* pData, uint32_t Length, uint32_t Alignment)
-{
- uint32_t tmpreg = 0U;
-
- /* Check the parameters */
- assert_param(IS_DAC_CHANNEL(Channel));
- assert_param(IS_DAC_ALIGN(Alignment));
-
- /* Process locked */
- __HAL_LOCK(hdac);
-
- /* Change DAC state */
- hdac->State = HAL_DAC_STATE_BUSY;
-
- if(Channel == DAC_CHANNEL_1)
- {
- /* Set the DMA transfer complete callback for channel1 */
- hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1;
-
- /* Set the DMA half transfer complete callback for channel1 */
- hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1;
-
- /* Set the DMA error callback for channel1 */
- hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1;
-
- /* Enable the selected DAC channel1 DMA request */
- SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1);
-
- /* Case of use of channel 1 */
- switch(Alignment)
- {
- case DAC_ALIGN_12B_R:
- /* Get DHR12R1 address */
- tmpreg = (uint32_t)&hdac->Instance->DHR12R1;
- break;
- case DAC_ALIGN_12B_L:
- /* Get DHR12L1 address */
- tmpreg = (uint32_t)&hdac->Instance->DHR12L1;
- break;
- case DAC_ALIGN_8B_R:
- /* Get DHR8R1 address */
- tmpreg = (uint32_t)&hdac->Instance->DHR8R1;
- break;
- default:
- break;
- }
- }
- else
- {
- /* Set the DMA transfer complete callback for channel2 */
- hdac->DMA_Handle2->XferCpltCallback = DAC_DMAConvCpltCh2;
-
- /* Set the DMA half transfer complete callback for channel2 */
- hdac->DMA_Handle2->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh2;
-
- /* Set the DMA error callback for channel2 */
- hdac->DMA_Handle2->XferErrorCallback = DAC_DMAErrorCh2;
-
- /* Enable the selected DAC channel2 DMA request */
- SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN2);
-
- /* Case of use of channel 2 */
- switch(Alignment)
- {
- case DAC_ALIGN_12B_R:
- /* Get DHR12R2 address */
- tmpreg = (uint32_t)&hdac->Instance->DHR12R2;
- break;
- case DAC_ALIGN_12B_L:
- /* Get DHR12L2 address */
- tmpreg = (uint32_t)&hdac->Instance->DHR12L2;
- break;
- case DAC_ALIGN_8B_R:
- /* Get DHR8R2 address */
- tmpreg = (uint32_t)&hdac->Instance->DHR8R2;
- break;
- default:
- break;
- }
- }
-
- /* Enable the DMA channel */
- if(Channel == DAC_CHANNEL_1)
- {
- /* Enable the DAC DMA underrun interrupt */
- __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1);
-
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, Length);
- }
- else
- {
- /* Enable the DAC DMA underrun interrupt */
- __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR2);
-
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, tmpreg, Length);
- }
-
- /* Enable the Peripharal */
- __HAL_DAC_ENABLE(hdac, Channel);
-
- /* Process Unlocked */
- __HAL_UNLOCK(hdac);
-
- /* Return function status */
- return HAL_OK;
-}
-#endif /* STM32F100xB) || defined (STM32F100xE) */
-
-#if defined (STM32F100xB) || defined (STM32F100xE)
-/**
- * @brief Disables DAC and stop conversion of channel.
- * Note: For STM32F100x devices with specific feature: DMA underrun.
- * On these devices, this function disables the interruption of DMA
- * underrun.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @param Channel: The selected DAC channel.
- * This parameter can be one of the following values:
- * @arg DAC_CHANNEL_1: DAC Channel1 selected
- * @arg DAC_CHANNEL_2: DAC Channel2 selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel)
-{
- HAL_StatusTypeDef status = HAL_OK;
-
- /* Check the parameters */
- assert_param(IS_DAC_CHANNEL(Channel));
-
- /* Disable the selected DAC channel DMA request */
- hdac->Instance->CR &= ~(DAC_CR_DMAEN1 << Channel);
-
- /* Disable the Peripharal */
- __HAL_DAC_DISABLE(hdac, Channel);
-
- /* Disable the DMA Channel */
- /* Channel1 is used */
- if(Channel == DAC_CHANNEL_1)
- {
- /* Disable the DMA channel */
- status = HAL_DMA_Abort(hdac->DMA_Handle1);
-
- /* Disable the DAC DMA underrun interrupt */
- __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR1);
- }
- else /* Channel2 is used for */
- {
- /* Disable the DMA channel */
- status = HAL_DMA_Abort(hdac->DMA_Handle2);
-
- /* Disable the DAC DMA underrun interrupt */
- __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR2);
- }
-
- /* Check if DMA Channel effectively disabled */
- if(status != HAL_OK)
- {
- /* Update ADC state machine to error */
- hdac->State = HAL_DAC_STATE_ERROR;
- }
- else
- {
- /* Change DAC state */
- hdac->State = HAL_DAC_STATE_READY;
- }
-
- /* Return function status */
- return status;
-}
-#endif /* STM32F100xB) || defined (STM32F100xE) */
-
-#if defined (STM32F100xB) || defined (STM32F100xE)
-/**
- * @brief Handles DAC interrupt request
- * Note: For STM32F100x devices with specific feature: DMA underrun.
- * On these devices, this function uses the interruption of DMA
- * underrun.
- * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
- * the configuration information for the specified DAC.
- * @retval None
- */
-void HAL_DAC_IRQHandler(DAC_HandleTypeDef* hdac)
-{
-
- if(__HAL_DAC_GET_IT_SOURCE(hdac, DAC_IT_DMAUDR1))
- {
- /* Check underrun flag of DAC channel 1 */
- if(__HAL_DAC_GET_FLAG(hdac, DAC_FLAG_DMAUDR1))
- {
- /* Change DAC state to error state */
- hdac->State = HAL_DAC_STATE_ERROR;
-
- /* Set DAC error code to chanel1 DMA underrun error */
- SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_DMAUNDERRUNCH1);
-
- /* Clear the underrun flag */
- __HAL_DAC_CLEAR_FLAG(hdac,DAC_FLAG_DMAUDR1);
-
- /* Disable the selected DAC channel1 DMA request */
- CLEAR_BIT(hdac->Instance->CR, DAC_CR_DMAEN1);
-
- /* Error callback */
- HAL_DAC_DMAUnderrunCallbackCh1(hdac);
- }
- }
-
- if(__HAL_DAC_GET_IT_SOURCE(hdac, DAC_IT_DMAUDR2))
- {
- /* Check underrun flag of DAC channel 2 */
- if(__HAL_DAC_GET_FLAG(hdac, DAC_FLAG_DMAUDR2))
- {
- /* Change DAC state to error state */
- hdac->State = HAL_DAC_STATE_ERROR;
-
- /* Set DAC error code to channel2 DMA underrun error */
- SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_DMAUNDERRUNCH2);
-
- /* Clear the underrun flag */
- __HAL_DAC_CLEAR_FLAG(hdac,DAC_FLAG_DMAUDR2);
-
- /* Disable the selected DAC channel1 DMA request */
- CLEAR_BIT(hdac->Instance->CR, DAC_CR_DMAEN2);
-
- /* Error callback */
- HAL_DACEx_DMAUnderrunCallbackCh2(hdac);
- }
- }
-}
-#endif /* STM32F100xB || STM32F100xE */
-
-
-/**
- * @}
- */
-
-/** @defgroup DACEx_Private_Functions DACEx Private Functions
- * @{
- */
-
-/**
- * @brief DMA conversion complete callback.
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma)
-{
- DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- HAL_DACEx_ConvCpltCallbackCh2(hdac);
-
- hdac->State= HAL_DAC_STATE_READY;
-}
-
-/**
- * @brief DMA half transfer complete callback.
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma)
-{
- DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- /* Conversion complete callback */
- HAL_DACEx_ConvHalfCpltCallbackCh2(hdac);
-}
-
-/**
- * @brief DMA error callback
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma)
-{
- DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- /* Set DAC error code to DMA error */
- hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
-
- HAL_DACEx_ErrorCallbackCh2(hdac);
-
- hdac->State= HAL_DAC_STATE_READY;
-}
-
-/**
- * @}
- */
-
-#endif /* STM32F100xB || STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
-#endif /* HAL_DAC_MODULE_ENABLED */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c
deleted file mode 100644
index d3989c2..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c
+++ /dev/null
@@ -1,902 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_dma.c
- * @author MCD Application Team
- * @brief DMA HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Direct Memory Access (DMA) peripheral:
- * + Initialization and de-initialization functions
- * + IO operation functions
- * + Peripheral State and errors functions
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- (#) Enable and configure the peripheral to be connected to the DMA Channel
- (except for internal SRAM / FLASH memories: no initialization is
- necessary). Please refer to the Reference manual for connection between peripherals
- and DMA requests.
-
- (#) For a given Channel, program the required configuration through the following parameters:
- Channel request, Transfer Direction, Source and Destination data formats,
- Circular or Normal mode, Channel Priority level, Source and Destination Increment mode
- using HAL_DMA_Init() function.
-
- (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
- detection.
-
- (#) Use HAL_DMA_Abort() function to abort the current transfer
-
- -@- In Memory-to-Memory transfer mode, Circular mode is not allowed.
- *** Polling mode IO operation ***
- =================================
- [..]
- (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source
- address and destination address and the Length of data to be transferred
- (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this
- case a fixed Timeout can be configured by User depending from his application.
-
- *** Interrupt mode IO operation ***
- ===================================
- [..]
- (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
- (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
- (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of
- Source address and destination address and the Length of data to be transferred.
- In this case the DMA interrupt is configured
- (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
- (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can
- add his own function by customization of function pointer XferCpltCallback and
- XferErrorCallback (i.e. a member of DMA handle structure).
-
- *** DMA HAL driver macros list ***
- =============================================
- [..]
- Below the list of most used macros in DMA HAL driver.
-
- (+) __HAL_DMA_ENABLE: Enable the specified DMA Channel.
- (+) __HAL_DMA_DISABLE: Disable the specified DMA Channel.
- (+) __HAL_DMA_GET_FLAG: Get the DMA Channel pending flags.
- (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Channel pending flags.
- (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Channel interrupts.
- (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Channel interrupts.
- (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Channel interrupt has occurred or not.
-
- [..]
- (@) You can refer to the DMA HAL driver header file for more useful macros
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup DMA DMA
- * @brief DMA HAL module driver
- * @{
- */
-
-#ifdef HAL_DMA_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @defgroup DMA_Private_Functions DMA Private Functions
- * @{
- */
-static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
-/**
- * @}
- */
-
-/* Exported functions ---------------------------------------------------------*/
-
-/** @defgroup DMA_Exported_Functions DMA Exported Functions
- * @{
- */
-
-/** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and de-initialization functions
- *
-@verbatim
- ===============================================================================
- ##### Initialization and de-initialization functions #####
- ===============================================================================
- [..]
- This section provides functions allowing to initialize the DMA Channel source
- and destination addresses, incrementation and data sizes, transfer direction,
- circular/normal mode selection, memory-to-memory mode selection and Channel priority value.
- [..]
- The HAL_DMA_Init() function follows the DMA configuration procedures as described in
- reference manual.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initialize the DMA according to the specified
- * parameters in the DMA_InitTypeDef and initialize the associated handle.
- * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA Channel.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
-{
- uint32_t tmp = 0U;
-
- /* Check the DMA handle allocation */
- if(hdma == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
- assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
- assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
- assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
- assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
- assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
- assert_param(IS_DMA_MODE(hdma->Init.Mode));
- assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
-
-#if defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F100xE) || defined (STM32F105xC) || defined (STM32F107xC)
- /* calculation of the channel index */
- if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
- {
- /* DMA1 */
- hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
- hdma->DmaBaseAddress = DMA1;
- }
- else
- {
- /* DMA2 */
- hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2;
- hdma->DmaBaseAddress = DMA2;
- }
-#else
- /* DMA1 */
- hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
- hdma->DmaBaseAddress = DMA1;
-#endif /* STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG || STM32F100xE || STM32F105xC || STM32F107xC */
-
- /* Change DMA peripheral state */
- hdma->State = HAL_DMA_STATE_BUSY;
-
- /* Get the CR register value */
- tmp = hdma->Instance->CCR;
-
- /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */
- tmp &= ((uint32_t)~(DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | \
- DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | \
- DMA_CCR_DIR));
-
- /* Prepare the DMA Channel configuration */
- tmp |= hdma->Init.Direction |
- hdma->Init.PeriphInc | hdma->Init.MemInc |
- hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
- hdma->Init.Mode | hdma->Init.Priority;
-
- /* Write to DMA Channel CR register */
- hdma->Instance->CCR = tmp;
-
- /* Initialise the error code */
- hdma->ErrorCode = HAL_DMA_ERROR_NONE;
-
- /* Initialize the DMA state*/
- hdma->State = HAL_DMA_STATE_READY;
- /* Allocate lock resource and initialize it */
- hdma->Lock = HAL_UNLOCKED;
-
- return HAL_OK;
-}
-
-/**
- * @brief DeInitialize the DMA peripheral.
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA Channel.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
-{
- /* Check the DMA handle allocation */
- if(hdma == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
-
- /* Disable the selected DMA Channelx */
- __HAL_DMA_DISABLE(hdma);
-
- /* Reset DMA Channel control register */
- hdma->Instance->CCR = 0U;
-
- /* Reset DMA Channel Number of Data to Transfer register */
- hdma->Instance->CNDTR = 0U;
-
- /* Reset DMA Channel peripheral address register */
- hdma->Instance->CPAR = 0U;
-
- /* Reset DMA Channel memory address register */
- hdma->Instance->CMAR = 0U;
-
-#if defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F100xE) || defined (STM32F105xC) || defined (STM32F107xC)
- /* calculation of the channel index */
- if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
- {
- /* DMA1 */
- hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
- hdma->DmaBaseAddress = DMA1;
- }
- else
- {
- /* DMA2 */
- hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2;
- hdma->DmaBaseAddress = DMA2;
- }
-#else
- /* DMA1 */
- hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
- hdma->DmaBaseAddress = DMA1;
-#endif /* STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG || STM32F100xE || STM32F105xC || STM32F107xC */
-
- /* Clear all flags */
- hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex));
-
- /* Clean all callbacks */
- hdma->XferCpltCallback = NULL;
- hdma->XferHalfCpltCallback = NULL;
- hdma->XferErrorCallback = NULL;
- hdma->XferAbortCallback = NULL;
-
- /* Reset the error code */
- hdma->ErrorCode = HAL_DMA_ERROR_NONE;
-
- /* Reset the DMA state */
- hdma->State = HAL_DMA_STATE_RESET;
-
- /* Release Lock */
- __HAL_UNLOCK(hdma);
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions
- * @brief Input and Output operation functions
- *
-@verbatim
- ===============================================================================
- ##### IO operation functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Configure the source, destination address and data length and Start DMA transfer
- (+) Configure the source, destination address and data length and
- Start DMA transfer with interrupt
- (+) Abort DMA transfer
- (+) Poll for transfer complete
- (+) Handle DMA interrupt request
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Start the DMA Transfer.
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA Channel.
- * @param SrcAddress: The source memory Buffer address
- * @param DstAddress: The destination memory Buffer address
- * @param DataLength: The length of data to be transferred from source to destination
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
-{
- HAL_StatusTypeDef status = HAL_OK;
-
- /* Check the parameters */
- assert_param(IS_DMA_BUFFER_SIZE(DataLength));
-
- /* Process locked */
- __HAL_LOCK(hdma);
-
- if(HAL_DMA_STATE_READY == hdma->State)
- {
- /* Change DMA peripheral state */
- hdma->State = HAL_DMA_STATE_BUSY;
- hdma->ErrorCode = HAL_DMA_ERROR_NONE;
-
- /* Disable the peripheral */
- __HAL_DMA_DISABLE(hdma);
-
- /* Configure the source, destination address and the data length & clear flags*/
- DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
-
- /* Enable the Peripheral */
- __HAL_DMA_ENABLE(hdma);
- }
- else
- {
- /* Process Unlocked */
- __HAL_UNLOCK(hdma);
- status = HAL_BUSY;
- }
- return status;
-}
-
-/**
- * @brief Start the DMA Transfer with interrupt enabled.
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA Channel.
- * @param SrcAddress: The source memory Buffer address
- * @param DstAddress: The destination memory Buffer address
- * @param DataLength: The length of data to be transferred from source to destination
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
-{
- HAL_StatusTypeDef status = HAL_OK;
-
- /* Check the parameters */
- assert_param(IS_DMA_BUFFER_SIZE(DataLength));
-
- /* Process locked */
- __HAL_LOCK(hdma);
-
- if(HAL_DMA_STATE_READY == hdma->State)
- {
- /* Change DMA peripheral state */
- hdma->State = HAL_DMA_STATE_BUSY;
- hdma->ErrorCode = HAL_DMA_ERROR_NONE;
-
- /* Disable the peripheral */
- __HAL_DMA_DISABLE(hdma);
-
- /* Configure the source, destination address and the data length & clear flags*/
- DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
-
- /* Enable the transfer complete interrupt */
- /* Enable the transfer Error interrupt */
- if(NULL != hdma->XferHalfCpltCallback)
- {
- /* Enable the Half transfer complete interrupt as well */
- __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
- }
- else
- {
- __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
- __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_TE));
- }
- /* Enable the Peripheral */
- __HAL_DMA_ENABLE(hdma);
- }
- else
- {
- /* Process Unlocked */
- __HAL_UNLOCK(hdma);
-
- /* Remain BUSY */
- status = HAL_BUSY;
- }
- return status;
-}
-
-/**
- * @brief Abort the DMA Transfer.
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA Channel.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
-{
- HAL_StatusTypeDef status = HAL_OK;
-
- /* Disable DMA IT */
- __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
-
- /* Disable the channel */
- __HAL_DMA_DISABLE(hdma);
-
- /* Clear all flags */
- hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
-
- /* Change the DMA state */
- hdma->State = HAL_DMA_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hdma);
-
- return status;
-}
-
-/**
- * @brief Aborts the DMA Transfer in Interrupt mode.
- * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA Channel.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
-{
- HAL_StatusTypeDef status = HAL_OK;
-
- if(HAL_DMA_STATE_BUSY != hdma->State)
- {
- /* no transfer ongoing */
- hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
-
- status = HAL_ERROR;
- }
- else
- {
- /* Disable DMA IT */
- __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
-
- /* Disable the channel */
- __HAL_DMA_DISABLE(hdma);
-
- /* Clear all flags */
- __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_GI_FLAG_INDEX(hdma));
-
- /* Change the DMA state */
- hdma->State = HAL_DMA_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hdma);
-
- /* Call User Abort callback */
- if(hdma->XferAbortCallback != NULL)
- {
- hdma->XferAbortCallback(hdma);
- }
- }
- return status;
-}
-
-/**
- * @brief Polling for transfer complete.
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA Channel.
- * @param CompleteLevel: Specifies the DMA level complete.
- * @param Timeout: Timeout duration.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
-{
- uint32_t temp;
- uint32_t tickstart = 0U;
-
- if(HAL_DMA_STATE_BUSY != hdma->State)
- {
- /* no transfer ongoing */
- hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
- __HAL_UNLOCK(hdma);
- return HAL_ERROR;
- }
-
- /* Polling mode not supported in circular mode */
- if (RESET != (hdma->Instance->CCR & DMA_CCR_CIRC))
- {
- hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
- return HAL_ERROR;
- }
-
- /* Get the level transfer complete flag */
- if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
- {
- /* Transfer Complete flag */
- temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
- }
- else
- {
- /* Half Transfer Complete flag */
- temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
- }
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
- {
- if((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET))
- {
- /* When a DMA transfer error occurs */
- /* A hardware clear of its EN bits is performed */
- /* Clear all flags */
- hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
-
- /* Update error code */
- SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE);
-
- /* Change the DMA state */
- hdma->State= HAL_DMA_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hdma);
-
- return HAL_ERROR;
- }
- /* Check for the Timeout */
- if(Timeout != HAL_MAX_DELAY)
- {
- if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
- {
- /* Update error code */
- SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT);
-
- /* Change the DMA state */
- hdma->State = HAL_DMA_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hdma);
-
- return HAL_ERROR;
- }
- }
- }
-
- if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
- {
- /* Clear the transfer complete flag */
- __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
-
- /* The selected Channelx EN bit is cleared (DMA is disabled and
- all transfers are complete) */
- hdma->State = HAL_DMA_STATE_READY;
- }
- else
- {
- /* Clear the half transfer complete flag */
- __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
- }
-
- /* Process unlocked */
- __HAL_UNLOCK(hdma);
-
- return HAL_OK;
-}
-
-/**
- * @brief Handles DMA interrupt request.
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA Channel.
- * @retval None
- */
-void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
-{
- uint32_t flag_it = hdma->DmaBaseAddress->ISR;
- uint32_t source_it = hdma->Instance->CCR;
-
- /* Half Transfer Complete Interrupt management ******************************/
- if (((flag_it & (DMA_FLAG_HT1 << hdma->ChannelIndex)) != RESET) && ((source_it & DMA_IT_HT) != RESET))
- {
- /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
- if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
- {
- /* Disable the half transfer interrupt */
- __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
- }
- /* Clear the half transfer complete flag */
- __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
-
- /* DMA peripheral state is not updated in Half Transfer */
- /* but in Transfer Complete case */
-
- if(hdma->XferHalfCpltCallback != NULL)
- {
- /* Half transfer callback */
- hdma->XferHalfCpltCallback(hdma);
- }
- }
-
- /* Transfer Complete Interrupt management ***********************************/
- else if (((flag_it & (DMA_FLAG_TC1 << hdma->ChannelIndex)) != RESET) && ((source_it & DMA_IT_TC) != RESET))
- {
- if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
- {
- /* Disable the transfer complete and error interrupt */
- __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC);
-
- /* Change the DMA state */
- hdma->State = HAL_DMA_STATE_READY;
- }
- /* Clear the transfer complete flag */
- __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
-
- /* Process Unlocked */
- __HAL_UNLOCK(hdma);
-
- if(hdma->XferCpltCallback != NULL)
- {
- /* Transfer complete callback */
- hdma->XferCpltCallback(hdma);
- }
- }
-
- /* Transfer Error Interrupt management **************************************/
- else if (( RESET != (flag_it & (DMA_FLAG_TE1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TE)))
- {
- /* When a DMA transfer error occurs */
- /* A hardware clear of its EN bits is performed */
- /* Disable ALL DMA IT */
- __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
-
- /* Clear all flags */
- hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
-
- /* Update error code */
- hdma->ErrorCode = HAL_DMA_ERROR_TE;
-
- /* Change the DMA state */
- hdma->State = HAL_DMA_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hdma);
-
- if (hdma->XferErrorCallback != NULL)
- {
- /* Transfer error callback */
- hdma->XferErrorCallback(hdma);
- }
- }
- return;
-}
-
-/**
- * @brief Register callbacks
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA Channel.
- * @param CallbackID: User Callback identifer
- * a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
- * @param pCallback: pointer to private callbacsk function which has pointer to
- * a DMA_HandleTypeDef structure as parameter.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)( DMA_HandleTypeDef * _hdma))
-{
- HAL_StatusTypeDef status = HAL_OK;
-
- /* Process locked */
- __HAL_LOCK(hdma);
-
- if(HAL_DMA_STATE_READY == hdma->State)
- {
- switch (CallbackID)
- {
- case HAL_DMA_XFER_CPLT_CB_ID:
- hdma->XferCpltCallback = pCallback;
- break;
-
- case HAL_DMA_XFER_HALFCPLT_CB_ID:
- hdma->XferHalfCpltCallback = pCallback;
- break;
-
- case HAL_DMA_XFER_ERROR_CB_ID:
- hdma->XferErrorCallback = pCallback;
- break;
-
- case HAL_DMA_XFER_ABORT_CB_ID:
- hdma->XferAbortCallback = pCallback;
- break;
-
- default:
- status = HAL_ERROR;
- break;
- }
- }
- else
- {
- status = HAL_ERROR;
- }
-
- /* Release Lock */
- __HAL_UNLOCK(hdma);
-
- return status;
-}
-
-/**
- * @brief UnRegister callbacks
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA Channel.
- * @param CallbackID: User Callback identifer
- * a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
-{
- HAL_StatusTypeDef status = HAL_OK;
-
- /* Process locked */
- __HAL_LOCK(hdma);
-
- if(HAL_DMA_STATE_READY == hdma->State)
- {
- switch (CallbackID)
- {
- case HAL_DMA_XFER_CPLT_CB_ID:
- hdma->XferCpltCallback = NULL;
- break;
-
- case HAL_DMA_XFER_HALFCPLT_CB_ID:
- hdma->XferHalfCpltCallback = NULL;
- break;
-
- case HAL_DMA_XFER_ERROR_CB_ID:
- hdma->XferErrorCallback = NULL;
- break;
-
- case HAL_DMA_XFER_ABORT_CB_ID:
- hdma->XferAbortCallback = NULL;
- break;
-
- case HAL_DMA_XFER_ALL_CB_ID:
- hdma->XferCpltCallback = NULL;
- hdma->XferHalfCpltCallback = NULL;
- hdma->XferErrorCallback = NULL;
- hdma->XferAbortCallback = NULL;
- break;
-
- default:
- status = HAL_ERROR;
- break;
- }
- }
- else
- {
- status = HAL_ERROR;
- }
-
- /* Release Lock */
- __HAL_UNLOCK(hdma);
-
- return status;
-}
-
-/**
- * @}
- */
-
-/** @defgroup DMA_Exported_Functions_Group3 Peripheral State and Errors functions
- * @brief Peripheral State and Errors functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral State and Errors functions #####
- ===============================================================================
- [..]
- This subsection provides functions allowing to
- (+) Check the DMA state
- (+) Get error code
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Return the DMA hande state.
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA Channel.
- * @retval HAL state
- */
-HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
-{
- /* Return DMA handle state */
- return hdma->State;
-}
-
-/**
- * @brief Return the DMA error code.
- * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA Channel.
- * @retval DMA Error Code
- */
-uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
-{
- return hdma->ErrorCode;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup DMA_Private_Functions
- * @{
- */
-
-/**
- * @brief Sets the DMA Transfer parameter.
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA Channel.
- * @param SrcAddress: The source memory Buffer address
- * @param DstAddress: The destination memory Buffer address
- * @param DataLength: The length of data to be transferred from source to destination
- * @retval HAL status
- */
-static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
-{
- /* Clear all flags */
- hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
-
- /* Configure DMA Channel data length */
- hdma->Instance->CNDTR = DataLength;
-
- /* Memory to Peripheral */
- if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
- {
- /* Configure DMA Channel destination address */
- hdma->Instance->CPAR = DstAddress;
-
- /* Configure DMA Channel source address */
- hdma->Instance->CMAR = SrcAddress;
- }
- /* Peripheral to Memory */
- else
- {
- /* Configure DMA Channel source address */
- hdma->Instance->CPAR = SrcAddress;
-
- /* Configure DMA Channel destination address */
- hdma->Instance->CMAR = DstAddress;
- }
-}
-
-/**
- * @}
- */
-
-#endif /* HAL_DMA_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_eth.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_eth.c
deleted file mode 100644
index 081259c..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_eth.c
+++ /dev/null
@@ -1,2043 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_eth.c
- * @author MCD Application Team
- * @brief ETH HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Ethernet (ETH) peripheral:
- * + Initialization and de-initialization functions
- * + IO operation functions
- * + Peripheral Control functions
- * + Peripheral State and Errors functions
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- (#)Declare a ETH_HandleTypeDef handle structure, for example:
- ETH_HandleTypeDef heth;
-
- (#)Fill parameters of Init structure in heth handle
-
- (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...)
-
- (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API:
- (##) Enable the Ethernet interface clock using
- (+++) __HAL_RCC_ETHMAC_CLK_ENABLE();
- (+++) __HAL_RCC_ETHMACTX_CLK_ENABLE();
- (+++) __HAL_RCC_ETHMACRX_CLK_ENABLE();
-
- (##) Initialize the related GPIO clocks
- (##) Configure Ethernet pin-out
- (##) Configure Ethernet NVIC interrupt (IT mode)
-
- (#)Initialize Ethernet DMA Descriptors in chain mode and point to allocated buffers:
- (##) HAL_ETH_DMATxDescListInit(); for Transmission process
- (##) HAL_ETH_DMARxDescListInit(); for Reception process
-
- (#)Enable MAC and DMA transmission and reception:
- (##) HAL_ETH_Start();
-
- (#)Prepare ETH DMA TX Descriptors and give the hand to ETH DMA to transfer
- the frame to MAC TX FIFO:
- (##) HAL_ETH_TransmitFrame();
-
- (#)Poll for a received frame in ETH RX DMA Descriptors and get received
- frame parameters
- (##) HAL_ETH_GetReceivedFrame(); (should be called into an infinite loop)
-
- (#) Get a received frame when an ETH RX interrupt occurs:
- (##) HAL_ETH_GetReceivedFrame_IT(); (called in IT mode only)
-
- (#) Communicate with external PHY device:
- (##) Read a specific register from the PHY
- HAL_ETH_ReadPHYRegister();
- (##) Write data to a specific RHY register:
- HAL_ETH_WritePHYRegister();
-
- (#) Configure the Ethernet MAC after ETH peripheral initialization
- HAL_ETH_ConfigMAC(); all MAC parameters should be filled.
-
- (#) Configure the Ethernet DMA after ETH peripheral initialization
- HAL_ETH_ConfigDMA(); all DMA parameters should be filled.
-
- -@- The PTP protocol and the DMA descriptors ring mode are not supported
- in this driver
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-#if defined (STM32F107xC)
-
-/** @defgroup ETH ETH
- * @brief ETH HAL module driver
- * @{
- */
-
-#ifdef HAL_ETH_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @defgroup ETH_Private_Constants ETH Private Constants
- * @{
- */
-#define ETH_TIMEOUT_SWRESET 500U
-#define ETH_TIMEOUT_LINKED_STATE 5000U
-#define ETH_TIMEOUT_AUTONEGO_COMPLETED 5000U
-
-/**
- * @}
- */
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @defgroup ETH_Private_Functions ETH Private Functions
- * @{
- */
-static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err);
-static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr);
-static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth);
-static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth);
-static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth);
-static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth);
-static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth);
-static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth);
-static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth);
-static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth);
-static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth);
-static void ETH_Delay(uint32_t mdelay);
-
-/**
- * @}
- */
-/* Private functions ---------------------------------------------------------*/
-
-/** @defgroup ETH_Exported_Functions ETH Exported Functions
- * @{
- */
-
-/** @defgroup ETH_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
- @verbatim
- ===============================================================================
- ##### Initialization and de-initialization functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Initialize and configure the Ethernet peripheral
- (+) De-initialize the Ethernet peripheral
-
- @endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the Ethernet MAC and DMA according to default
- * parameters.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
-{
- uint32_t tmpreg1 = 0U, phyreg = 0U;
- uint32_t hclk = 60000000U;
- uint32_t tickstart = 0U;
- uint32_t err = ETH_SUCCESS;
-
- /* Check the ETH peripheral state */
- if (heth == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check parameters */
- assert_param(IS_ETH_AUTONEGOTIATION(heth->Init.AutoNegotiation));
- assert_param(IS_ETH_RX_MODE(heth->Init.RxMode));
- assert_param(IS_ETH_CHECKSUM_MODE(heth->Init.ChecksumMode));
- assert_param(IS_ETH_MEDIA_INTERFACE(heth->Init.MediaInterface));
-
- if (heth->State == HAL_ETH_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- heth->Lock = HAL_UNLOCKED;
- /* Init the low level hardware : GPIO, CLOCK, NVIC. */
- HAL_ETH_MspInit(heth);
- }
-
- /* Select MII or RMII Mode*/
- AFIO->MAPR &= ~(AFIO_MAPR_MII_RMII_SEL);
- AFIO->MAPR |= (uint32_t)heth->Init.MediaInterface;
-
- /* Ethernet Software reset */
- /* Set the SWR bit: resets all MAC subsystem internal registers and logic */
- /* After reset all the registers holds their respective reset values */
- (heth->Instance)->DMABMR |= ETH_DMABMR_SR;
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Wait for software reset */
- while (((heth->Instance)->DMABMR & ETH_DMABMR_SR) != (uint32_t)RESET)
- {
- /* Check for the Timeout */
- if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_SWRESET)
- {
- heth->State = HAL_ETH_STATE_TIMEOUT;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- /* Note: The SWR is not performed if the ETH_RX_CLK or the ETH_TX_CLK are
- not available, please check your external PHY or the IO configuration */
- return HAL_TIMEOUT;
- }
- }
-
- /*-------------------------------- MAC Initialization ----------------------*/
- /* Get the ETHERNET MACMIIAR value */
- tmpreg1 = (heth->Instance)->MACMIIAR;
- /* Clear CSR Clock Range CR[2:0] bits */
- tmpreg1 &= ETH_MACMIIAR_CR_MASK;
-
- /* Get hclk frequency value */
- hclk = HAL_RCC_GetHCLKFreq();
-
- /* Set CR bits depending on hclk value */
- if ((hclk >= 20000000U) && (hclk < 35000000U))
- {
- /* CSR Clock Range between 20-35 MHz */
- tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV16;
- }
- else if ((hclk >= 35000000U) && (hclk < 60000000U))
- {
- /* CSR Clock Range between 35-60 MHz */
- tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV26;
- }
- else
- {
- /* CSR Clock Range between 60-72 MHz */
- tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV42;
- }
-
- /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
- (heth->Instance)->MACMIIAR = (uint32_t)tmpreg1;
-
- /*-------------------- PHY initialization and configuration ----------------*/
- /* Put the PHY in reset mode */
- if ((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_RESET)) != HAL_OK)
- {
- /* In case of write timeout */
- err = ETH_ERROR;
-
- /* Config MAC and DMA */
- ETH_MACDMAConfig(heth, err);
-
- /* Set the ETH peripheral state to READY */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Return HAL_ERROR */
- return HAL_ERROR;
- }
-
- /* Delay to assure PHY reset */
- HAL_Delay(PHY_RESET_DELAY);
-
- if ((heth->Init).AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE)
- {
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* We wait for linked status */
- do
- {
- HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg);
-
- /* Check for the Timeout */
- if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_LINKED_STATE)
- {
- /* In case of write timeout */
- err = ETH_ERROR;
-
- /* Config MAC and DMA */
- ETH_MACDMAConfig(heth, err);
-
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- return HAL_TIMEOUT;
- }
- }
- while (((phyreg & PHY_LINKED_STATUS) != PHY_LINKED_STATUS));
-
-
- /* Enable Auto-Negotiation */
- if ((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_AUTONEGOTIATION)) != HAL_OK)
- {
- /* In case of write timeout */
- err = ETH_ERROR;
-
- /* Config MAC and DMA */
- ETH_MACDMAConfig(heth, err);
-
- /* Set the ETH peripheral state to READY */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Return HAL_ERROR */
- return HAL_ERROR;
- }
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Wait until the auto-negotiation will be completed */
- do
- {
- HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg);
-
- /* Check for the Timeout */
- if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_AUTONEGO_COMPLETED)
- {
- /* In case of write timeout */
- err = ETH_ERROR;
-
- /* Config MAC and DMA */
- ETH_MACDMAConfig(heth, err);
-
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- return HAL_TIMEOUT;
- }
-
- }
- while (((phyreg & PHY_AUTONEGO_COMPLETE) != PHY_AUTONEGO_COMPLETE));
-
- /* Read the result of the auto-negotiation */
- if ((HAL_ETH_ReadPHYRegister(heth, PHY_SR, &phyreg)) != HAL_OK)
- {
- /* In case of write timeout */
- err = ETH_ERROR;
-
- /* Config MAC and DMA */
- ETH_MACDMAConfig(heth, err);
-
- /* Set the ETH peripheral state to READY */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Return HAL_ERROR */
- return HAL_ERROR;
- }
-
- /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */
- if ((phyreg & PHY_DUPLEX_STATUS) != (uint32_t)RESET)
- {
- /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
- (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
- }
- else
- {
- /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */
- (heth->Init).DuplexMode = ETH_MODE_HALFDUPLEX;
- }
- /* Configure the MAC with the speed fixed by the auto-negotiation process */
- if ((phyreg & PHY_SPEED_STATUS) == PHY_SPEED_STATUS)
- {
- /* Set Ethernet speed to 10M following the auto-negotiation */
- (heth->Init).Speed = ETH_SPEED_10M;
- }
- else
- {
- /* Set Ethernet speed to 100M following the auto-negotiation */
- (heth->Init).Speed = ETH_SPEED_100M;
- }
- }
- else /* AutoNegotiation Disable */
- {
- /* Check parameters */
- assert_param(IS_ETH_SPEED(heth->Init.Speed));
- assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode));
-
- /* Set MAC Speed and Duplex Mode */
- if (HAL_ETH_WritePHYRegister(heth, PHY_BCR, ((uint16_t)((heth->Init).DuplexMode >> 3U) |
- (uint16_t)((heth->Init).Speed >> 1U))) != HAL_OK)
- {
- /* In case of write timeout */
- err = ETH_ERROR;
-
- /* Config MAC and DMA */
- ETH_MACDMAConfig(heth, err);
-
- /* Set the ETH peripheral state to READY */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Return HAL_ERROR */
- return HAL_ERROR;
- }
-
- /* Delay to assure PHY configuration */
- HAL_Delay(PHY_CONFIG_DELAY);
- }
-
- /* Config MAC and DMA */
- ETH_MACDMAConfig(heth, err);
-
- /* Set ETH HAL State to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief De-Initializes the ETH peripheral.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth)
-{
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
- HAL_ETH_MspDeInit(heth);
-
- /* Set ETH HAL state to Disabled */
- heth->State = HAL_ETH_STATE_RESET;
-
- /* Release Lock */
- __HAL_UNLOCK(heth);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the DMA Tx descriptors in chain mode.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param DMATxDescTab: Pointer to the first Tx desc list
- * @param TxBuff: Pointer to the first TxBuffer list
- * @param TxBuffCount: Number of the used Tx desc in the list
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_DMATxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMATxDescTab, uint8_t *TxBuff, uint32_t TxBuffCount)
-{
- uint32_t i = 0U;
- ETH_DMADescTypeDef *dmatxdesc;
-
- /* Process Locked */
- __HAL_LOCK(heth);
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Set the DMATxDescToSet pointer with the first one of the DMATxDescTab list */
- heth->TxDesc = DMATxDescTab;
-
- /* Fill each DMATxDesc descriptor with the right values */
- for (i = 0U; i < TxBuffCount; i++)
- {
- /* Get the pointer on the ith member of the Tx Desc list */
- dmatxdesc = DMATxDescTab + i;
-
- /* Set Second Address Chained bit */
- dmatxdesc->Status = ETH_DMATXDESC_TCH;
-
- /* Set Buffer1 address pointer */
- dmatxdesc->Buffer1Addr = (uint32_t)(&TxBuff[i * ETH_TX_BUF_SIZE]);
-
- if ((heth->Init).ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
- {
- /* Set the DMA Tx descriptors checksum insertion */
- dmatxdesc->Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL;
- }
-
- /* Initialize the next descriptor with the Next Descriptor Polling Enable */
- if (i < (TxBuffCount - 1U))
- {
- /* Set next descriptor address register with next descriptor base address */
- dmatxdesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab + i + 1U);
- }
- else
- {
- /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
- dmatxdesc->Buffer2NextDescAddr = (uint32_t) DMATxDescTab;
- }
- }
-
- /* Set Transmit Descriptor List Address Register */
- (heth->Instance)->DMATDLAR = (uint32_t) DMATxDescTab;
-
- /* Set ETH HAL State to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the DMA Rx descriptors in chain mode.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param DMARxDescTab: Pointer to the first Rx desc list
- * @param RxBuff: Pointer to the first RxBuffer list
- * @param RxBuffCount: Number of the used Rx desc in the list
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_DMARxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount)
-{
- uint32_t i = 0U;
- ETH_DMADescTypeDef *DMARxDesc;
-
- /* Process Locked */
- __HAL_LOCK(heth);
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Set the Ethernet RxDesc pointer with the first one of the DMARxDescTab list */
- heth->RxDesc = DMARxDescTab;
-
- /* Fill each DMARxDesc descriptor with the right values */
- for (i = 0U; i < RxBuffCount; i++)
- {
- /* Get the pointer on the ith member of the Rx Desc list */
- DMARxDesc = DMARxDescTab + i;
-
- /* Set Own bit of the Rx descriptor Status */
- DMARxDesc->Status = ETH_DMARXDESC_OWN;
-
- /* Set Buffer1 size and Second Address Chained bit */
- DMARxDesc->ControlBufferSize = ETH_DMARXDESC_RCH | ETH_RX_BUF_SIZE;
-
- /* Set Buffer1 address pointer */
- DMARxDesc->Buffer1Addr = (uint32_t)(&RxBuff[i * ETH_RX_BUF_SIZE]);
-
- if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
- {
- /* Enable Ethernet DMA Rx Descriptor interrupt */
- DMARxDesc->ControlBufferSize &= ~ETH_DMARXDESC_DIC;
- }
-
- /* Initialize the next descriptor with the Next Descriptor Polling Enable */
- if (i < (RxBuffCount - 1U))
- {
- /* Set next descriptor address register with next descriptor base address */
- DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab + i + 1U);
- }
- else
- {
- /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
- DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab);
- }
- }
-
- /* Set Receive Descriptor List Address Register */
- (heth->Instance)->DMARDLAR = (uint32_t) DMARxDescTab;
-
- /* Set ETH HAL State to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the ETH MSP.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(heth);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief DeInitializes ETH MSP.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(heth);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup ETH_Exported_Functions_Group2 IO operation functions
- * @brief Data transfers functions
- *
- @verbatim
- ==============================================================================
- ##### IO operation functions #####
- ==============================================================================
- [..] This section provides functions allowing to:
- (+) Transmit a frame
- HAL_ETH_TransmitFrame();
- (+) Receive a frame
- HAL_ETH_GetReceivedFrame();
- HAL_ETH_GetReceivedFrame_IT();
- (+) Read from an External PHY register
- HAL_ETH_ReadPHYRegister();
- (+) Write to an External PHY register
- HAL_ETH_WritePHYRegister();
-
- @endverbatim
-
- * @{
- */
-
-/**
- * @brief Sends an Ethernet frame.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param FrameLength: Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength)
-{
- uint32_t bufcount = 0U, size = 0U, i = 0U;
-
- /* Process Locked */
- __HAL_LOCK(heth);
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- if (FrameLength == 0U)
- {
- /* Set ETH HAL state to READY */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- return HAL_ERROR;
- }
-
- /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
- if (((heth->TxDesc)->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
- {
- /* OWN bit set */
- heth->State = HAL_ETH_STATE_BUSY_TX;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- return HAL_ERROR;
- }
-
- /* Get the number of needed Tx buffers for the current frame */
- if (FrameLength > ETH_TX_BUF_SIZE)
- {
- bufcount = FrameLength / ETH_TX_BUF_SIZE;
- if (FrameLength % ETH_TX_BUF_SIZE)
- {
- bufcount++;
- }
- }
- else
- {
- bufcount = 1U;
- }
- if (bufcount == 1U)
- {
- /* Set LAST and FIRST segment */
- heth->TxDesc->Status |= ETH_DMATXDESC_FS | ETH_DMATXDESC_LS;
- /* Set frame size */
- heth->TxDesc->ControlBufferSize = (FrameLength & ETH_DMATXDESC_TBS1);
- /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
- heth->TxDesc->Status |= ETH_DMATXDESC_OWN;
- /* Point to next descriptor */
- heth->TxDesc = (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr);
- }
- else
- {
- for (i = 0U; i < bufcount; i++)
- {
- /* Clear FIRST and LAST segment bits */
- heth->TxDesc->Status &= ~(ETH_DMATXDESC_FS | ETH_DMATXDESC_LS);
-
- if (i == 0U)
- {
- /* Setting the first segment bit */
- heth->TxDesc->Status |= ETH_DMATXDESC_FS;
- }
-
- /* Program size */
- heth->TxDesc->ControlBufferSize = (ETH_TX_BUF_SIZE & ETH_DMATXDESC_TBS1);
-
- if (i == (bufcount - 1U))
- {
- /* Setting the last segment bit */
- heth->TxDesc->Status |= ETH_DMATXDESC_LS;
- size = FrameLength - (bufcount - 1U) * ETH_TX_BUF_SIZE;
- heth->TxDesc->ControlBufferSize = (size & ETH_DMATXDESC_TBS1);
- }
-
- /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
- heth->TxDesc->Status |= ETH_DMATXDESC_OWN;
- /* point to next descriptor */
- heth->TxDesc = (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr);
- }
- }
-
- /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
- if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET)
- {
- /* Clear TBUS ETHERNET DMA flag */
- (heth->Instance)->DMASR = ETH_DMASR_TBUS;
- /* Resume DMA transmission*/
- (heth->Instance)->DMATPDR = 0U;
- }
-
- /* Set ETH HAL State to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Checks for received frames.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_GetReceivedFrame(ETH_HandleTypeDef *heth)
-{
- uint32_t framelength = 0U;
-
- /* Process Locked */
- __HAL_LOCK(heth);
-
- /* Check the ETH state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Check if segment is not owned by DMA */
- /* (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) && ((heth->RxDesc->Status & ETH_DMARXDESC_LS) != (uint32_t)RESET)) */
- if (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET))
- {
- /* Check if last segment */
- if (((heth->RxDesc->Status & ETH_DMARXDESC_LS) != (uint32_t)RESET))
- {
- /* increment segment count */
- (heth->RxFrameInfos).SegCount++;
-
- /* Check if last segment is first segment: one segment contains the frame */
- if ((heth->RxFrameInfos).SegCount == 1U)
- {
- (heth->RxFrameInfos).FSRxDesc = heth->RxDesc;
- }
-
- heth->RxFrameInfos.LSRxDesc = heth->RxDesc;
-
- /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
- framelength = (((heth->RxDesc)->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4U;
- heth->RxFrameInfos.length = framelength;
-
- /* Get the address of the buffer start address */
- heth->RxFrameInfos.buffer = ((heth->RxFrameInfos).FSRxDesc)->Buffer1Addr;
- /* point to next descriptor */
- heth->RxDesc = (ETH_DMADescTypeDef *)((heth->RxDesc)->Buffer2NextDescAddr);
-
- /* Set HAL State to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- /* Return function status */
- return HAL_OK;
- }
- /* Check if first segment */
- else if ((heth->RxDesc->Status & ETH_DMARXDESC_FS) != (uint32_t)RESET)
- {
- (heth->RxFrameInfos).FSRxDesc = heth->RxDesc;
- (heth->RxFrameInfos).LSRxDesc = NULL;
- (heth->RxFrameInfos).SegCount = 1U;
- /* Point to next descriptor */
- heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
- }
- /* Check if intermediate segment */
- else
- {
- (heth->RxFrameInfos).SegCount++;
- /* Point to next descriptor */
- heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
- }
- }
-
- /* Set ETH HAL State to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- /* Return function status */
- return HAL_ERROR;
-}
-
-/**
- * @brief Gets the Received frame in interrupt mode.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_GetReceivedFrame_IT(ETH_HandleTypeDef *heth)
-{
- uint32_t descriptorscancounter = 0U;
-
- /* Process Locked */
- __HAL_LOCK(heth);
-
- /* Set ETH HAL State to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Scan descriptors owned by CPU */
- while (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) && (descriptorscancounter < ETH_RXBUFNB))
- {
- /* Just for security */
- descriptorscancounter++;
-
- /* Check if first segment in frame */
- /* ((heth->RxDesc->Status & ETH_DMARXDESC_FS) != (uint32_t)RESET) && ((heth->RxDesc->Status & ETH_DMARXDESC_LS) == (uint32_t)RESET)) */
- if ((heth->RxDesc->Status & (ETH_DMARXDESC_FS | ETH_DMARXDESC_LS)) == (uint32_t)ETH_DMARXDESC_FS)
- {
- heth->RxFrameInfos.FSRxDesc = heth->RxDesc;
- heth->RxFrameInfos.SegCount = 1U;
- /* Point to next descriptor */
- heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
- }
- /* Check if intermediate segment */
- /* ((heth->RxDesc->Status & ETH_DMARXDESC_LS) == (uint32_t)RESET)&& ((heth->RxDesc->Status & ETH_DMARXDESC_FS) == (uint32_t)RESET)) */
- else if ((heth->RxDesc->Status & (ETH_DMARXDESC_LS | ETH_DMARXDESC_FS)) == (uint32_t)RESET)
- {
- /* Increment segment count */
- (heth->RxFrameInfos.SegCount)++;
- /* Point to next descriptor */
- heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
- }
- /* Should be last segment */
- else
- {
- /* Last segment */
- heth->RxFrameInfos.LSRxDesc = heth->RxDesc;
-
- /* Increment segment count */
- (heth->RxFrameInfos.SegCount)++;
-
- /* Check if last segment is first segment: one segment contains the frame */
- if ((heth->RxFrameInfos.SegCount) == 1U)
- {
- heth->RxFrameInfos.FSRxDesc = heth->RxDesc;
- }
-
- /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
- heth->RxFrameInfos.length = (((heth->RxDesc)->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4U;
-
- /* Get the address of the buffer start address */
- heth->RxFrameInfos.buffer = ((heth->RxFrameInfos).FSRxDesc)->Buffer1Addr;
-
- /* Point to next descriptor */
- heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
-
- /* Set HAL State to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- /* Return function status */
- return HAL_OK;
- }
- }
-
- /* Set HAL State to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- /* Return function status */
- return HAL_ERROR;
-}
-
-/**
- * @brief This function handles ETH interrupt request.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
-{
- /* Frame received */
- if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_R))
- {
- /* Receive complete callback */
- HAL_ETH_RxCpltCallback(heth);
-
- /* Clear the Eth DMA Rx IT pending bits */
- __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_R);
-
- /* Set HAL State to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- }
- /* Frame transmitted */
- else if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_T))
- {
- /* Transfer complete callback */
- HAL_ETH_TxCpltCallback(heth);
-
- /* Clear the Eth DMA Tx IT pending bits */
- __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_T);
-
- /* Set HAL State to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
- }
-
- /* Clear the interrupt flags */
- __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_NIS);
-
- /* ETH DMA Error */
- if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_AIS))
- {
- /* Ethernet Error callback */
- HAL_ETH_ErrorCallback(heth);
-
- /* Clear the interrupt flags */
- __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_FLAG_AIS);
-
- /* Set HAL State to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
- }
-}
-
-/**
- * @brief Tx Transfer completed callbacks.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(heth);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_TxCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Rx Transfer completed callbacks.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(heth);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_TxCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Ethernet transfer error callbacks
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(heth);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_TxCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Reads a PHY register
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param PHYReg: PHY register address, is the index of one of the 32 PHY register.
- * This parameter can be one of the following values:
- * PHY_BCR: Transceiver Basic Control Register,
- * PHY_BSR: Transceiver Basic Status Register.
- * More PHY register could be read depending on the used PHY
- * @param RegValue: PHY register value
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t *RegValue)
-{
- uint32_t tmpreg1 = 0U;
- uint32_t tickstart = 0U;
-
- /* Check parameters */
- assert_param(IS_ETH_PHY_ADDRESS(heth->Init.PhyAddress));
-
- /* Check the ETH peripheral state */
- if (heth->State == HAL_ETH_STATE_BUSY_RD)
- {
- return HAL_BUSY;
- }
- /* Set ETH HAL State to BUSY_RD */
- heth->State = HAL_ETH_STATE_BUSY_RD;
-
- /* Get the ETHERNET MACMIIAR value */
- tmpreg1 = heth->Instance->MACMIIAR;
-
- /* Keep only the CSR Clock Range CR[2:0] bits value */
- tmpreg1 &= ~ETH_MACMIIAR_CR_MASK;
-
- /* Prepare the MII address register value */
- tmpreg1 |= (((uint32_t)heth->Init.PhyAddress << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */
- tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR); /* Set the PHY register address */
- tmpreg1 &= ~ETH_MACMIIAR_MW; /* Set the read mode */
- tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */
-
- /* Write the result value into the MII Address register */
- heth->Instance->MACMIIAR = tmpreg1;
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Check for the Busy flag */
- while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB)
- {
- /* Check for the Timeout */
- if ((HAL_GetTick() - tickstart) > PHY_READ_TO)
- {
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- return HAL_TIMEOUT;
- }
-
- tmpreg1 = heth->Instance->MACMIIAR;
- }
-
- /* Get MACMIIDR value */
- *RegValue = (uint16_t)(heth->Instance->MACMIIDR);
-
- /* Set ETH HAL State to READY */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Writes to a PHY register.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param PHYReg: PHY register address, is the index of one of the 32 PHY register.
- * This parameter can be one of the following values:
- * PHY_BCR: Transceiver Control Register.
- * More PHY register could be written depending on the used PHY
- * @param RegValue: the value to write
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t RegValue)
-{
- uint32_t tmpreg1 = 0U;
- uint32_t tickstart = 0U;
-
- /* Check parameters */
- assert_param(IS_ETH_PHY_ADDRESS(heth->Init.PhyAddress));
-
- /* Check the ETH peripheral state */
- if (heth->State == HAL_ETH_STATE_BUSY_WR)
- {
- return HAL_BUSY;
- }
- /* Set ETH HAL State to BUSY_WR */
- heth->State = HAL_ETH_STATE_BUSY_WR;
-
- /* Get the ETHERNET MACMIIAR value */
- tmpreg1 = heth->Instance->MACMIIAR;
-
- /* Keep only the CSR Clock Range CR[2:0] bits value */
- tmpreg1 &= ~ETH_MACMIIAR_CR_MASK;
-
- /* Prepare the MII register address value */
- tmpreg1 |= (((uint32_t)heth->Init.PhyAddress << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */
- tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR); /* Set the PHY register address */
- tmpreg1 |= ETH_MACMIIAR_MW; /* Set the write mode */
- tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */
-
- /* Give the value to the MII data register */
- heth->Instance->MACMIIDR = (uint16_t)RegValue;
-
- /* Write the result value into the MII Address register */
- heth->Instance->MACMIIAR = tmpreg1;
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Check for the Busy flag */
- while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB)
- {
- /* Check for the Timeout */
- if ((HAL_GetTick() - tickstart) > PHY_WRITE_TO)
- {
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- return HAL_TIMEOUT;
- }
-
- tmpreg1 = heth->Instance->MACMIIAR;
- }
-
- /* Set ETH HAL State to READY */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions
- * @brief Peripheral Control functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral Control functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Enable MAC and DMA transmission and reception.
- HAL_ETH_Start();
- (+) Disable MAC and DMA transmission and reception.
- HAL_ETH_Stop();
- (+) Set the MAC configuration in runtime mode
- HAL_ETH_ConfigMAC();
- (+) Set the DMA configuration in runtime mode
- HAL_ETH_ConfigDMA();
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Enables Ethernet MAC and DMA reception/transmission
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth)
-{
- /* Process Locked */
- __HAL_LOCK(heth);
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Enable transmit state machine of the MAC for transmission on the MII */
- ETH_MACTransmissionEnable(heth);
-
- /* Enable receive state machine of the MAC for reception from the MII */
- ETH_MACReceptionEnable(heth);
-
- /* Flush Transmit FIFO */
- ETH_FlushTransmitFIFO(heth);
-
- /* Start DMA transmission */
- ETH_DMATransmissionEnable(heth);
-
- /* Start DMA reception */
- ETH_DMAReceptionEnable(heth);
-
- /* Set the ETH state to READY*/
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Stop Ethernet MAC and DMA reception/transmission
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth)
-{
- /* Process Locked */
- __HAL_LOCK(heth);
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Stop DMA transmission */
- ETH_DMATransmissionDisable(heth);
-
- /* Stop DMA reception */
- ETH_DMAReceptionDisable(heth);
-
- /* Disable receive state machine of the MAC for reception from the MII */
- ETH_MACReceptionDisable(heth);
-
- /* Flush Transmit FIFO */
- ETH_FlushTransmitFIFO(heth);
-
- /* Disable transmit state machine of the MAC for transmission on the MII */
- ETH_MACTransmissionDisable(heth);
-
- /* Set the ETH state*/
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Set ETH MAC Configuration.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param macconf: MAC Configuration structure
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef *macconf)
-{
- uint32_t tmpreg1 = 0U;
-
- /* Process Locked */
- __HAL_LOCK(heth);
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- assert_param(IS_ETH_SPEED(heth->Init.Speed));
- assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode));
-
- if (macconf != NULL)
- {
- /* Check the parameters */
- assert_param(IS_ETH_WATCHDOG(macconf->Watchdog));
- assert_param(IS_ETH_JABBER(macconf->Jabber));
- assert_param(IS_ETH_INTER_FRAME_GAP(macconf->InterFrameGap));
- assert_param(IS_ETH_CARRIER_SENSE(macconf->CarrierSense));
- assert_param(IS_ETH_RECEIVE_OWN(macconf->ReceiveOwn));
- assert_param(IS_ETH_LOOPBACK_MODE(macconf->LoopbackMode));
- assert_param(IS_ETH_CHECKSUM_OFFLOAD(macconf->ChecksumOffload));
- assert_param(IS_ETH_RETRY_TRANSMISSION(macconf->RetryTransmission));
- assert_param(IS_ETH_AUTOMATIC_PADCRC_STRIP(macconf->AutomaticPadCRCStrip));
- assert_param(IS_ETH_BACKOFF_LIMIT(macconf->BackOffLimit));
- assert_param(IS_ETH_DEFERRAL_CHECK(macconf->DeferralCheck));
- assert_param(IS_ETH_RECEIVE_ALL(macconf->ReceiveAll));
- assert_param(IS_ETH_SOURCE_ADDR_FILTER(macconf->SourceAddrFilter));
- assert_param(IS_ETH_CONTROL_FRAMES(macconf->PassControlFrames));
- assert_param(IS_ETH_BROADCAST_FRAMES_RECEPTION(macconf->BroadcastFramesReception));
- assert_param(IS_ETH_DESTINATION_ADDR_FILTER(macconf->DestinationAddrFilter));
- assert_param(IS_ETH_PROMISCUOUS_MODE(macconf->PromiscuousMode));
- assert_param(IS_ETH_MULTICAST_FRAMES_FILTER(macconf->MulticastFramesFilter));
- assert_param(IS_ETH_UNICAST_FRAMES_FILTER(macconf->UnicastFramesFilter));
- assert_param(IS_ETH_PAUSE_TIME(macconf->PauseTime));
- assert_param(IS_ETH_ZEROQUANTA_PAUSE(macconf->ZeroQuantaPause));
- assert_param(IS_ETH_PAUSE_LOW_THRESHOLD(macconf->PauseLowThreshold));
- assert_param(IS_ETH_UNICAST_PAUSE_FRAME_DETECT(macconf->UnicastPauseFrameDetect));
- assert_param(IS_ETH_RECEIVE_FLOWCONTROL(macconf->ReceiveFlowControl));
- assert_param(IS_ETH_TRANSMIT_FLOWCONTROL(macconf->TransmitFlowControl));
- assert_param(IS_ETH_VLAN_TAG_COMPARISON(macconf->VLANTagComparison));
- assert_param(IS_ETH_VLAN_TAG_IDENTIFIER(macconf->VLANTagIdentifier));
-
- /*------------------------ ETHERNET MACCR Configuration --------------------*/
- /* Get the ETHERNET MACCR value */
- tmpreg1 = (heth->Instance)->MACCR;
- /* Clear WD, PCE, PS, TE and RE bits */
- tmpreg1 &= ETH_MACCR_CLEAR_MASK;
-
- tmpreg1 |= (uint32_t)(macconf->Watchdog |
- macconf->Jabber |
- macconf->InterFrameGap |
- macconf->CarrierSense |
- (heth->Init).Speed |
- macconf->ReceiveOwn |
- macconf->LoopbackMode |
- (heth->Init).DuplexMode |
- macconf->ChecksumOffload |
- macconf->RetryTransmission |
- macconf->AutomaticPadCRCStrip |
- macconf->BackOffLimit |
- macconf->DeferralCheck);
-
- /* Write to ETHERNET MACCR */
- (heth->Instance)->MACCR = (uint32_t)tmpreg1;
-
- /* Wait until the write operation will be taken into account :
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg1 = (heth->Instance)->MACCR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- (heth->Instance)->MACCR = tmpreg1;
-
- /*----------------------- ETHERNET MACFFR Configuration --------------------*/
- /* Write to ETHERNET MACFFR */
- (heth->Instance)->MACFFR = (uint32_t)(macconf->ReceiveAll |
- macconf->SourceAddrFilter |
- macconf->PassControlFrames |
- macconf->BroadcastFramesReception |
- macconf->DestinationAddrFilter |
- macconf->PromiscuousMode |
- macconf->MulticastFramesFilter |
- macconf->UnicastFramesFilter);
-
- /* Wait until the write operation will be taken into account :
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg1 = (heth->Instance)->MACFFR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- (heth->Instance)->MACFFR = tmpreg1;
-
- /*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/
- /* Write to ETHERNET MACHTHR */
- (heth->Instance)->MACHTHR = (uint32_t)macconf->HashTableHigh;
-
- /* Write to ETHERNET MACHTLR */
- (heth->Instance)->MACHTLR = (uint32_t)macconf->HashTableLow;
- /*----------------------- ETHERNET MACFCR Configuration --------------------*/
-
- /* Get the ETHERNET MACFCR value */
- tmpreg1 = (heth->Instance)->MACFCR;
- /* Clear xx bits */
- tmpreg1 &= ETH_MACFCR_CLEAR_MASK;
-
- tmpreg1 |= (uint32_t)((macconf->PauseTime << 16U) |
- macconf->ZeroQuantaPause |
- macconf->PauseLowThreshold |
- macconf->UnicastPauseFrameDetect |
- macconf->ReceiveFlowControl |
- macconf->TransmitFlowControl);
-
- /* Write to ETHERNET MACFCR */
- (heth->Instance)->MACFCR = (uint32_t)tmpreg1;
-
- /* Wait until the write operation will be taken into account :
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg1 = (heth->Instance)->MACFCR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- (heth->Instance)->MACFCR = tmpreg1;
-
- /*----------------------- ETHERNET MACVLANTR Configuration -----------------*/
- (heth->Instance)->MACVLANTR = (uint32_t)(macconf->VLANTagComparison |
- macconf->VLANTagIdentifier);
-
- /* Wait until the write operation will be taken into account :
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg1 = (heth->Instance)->MACVLANTR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- (heth->Instance)->MACVLANTR = tmpreg1;
- }
- else /* macconf == NULL : here we just configure Speed and Duplex mode */
- {
- /*------------------------ ETHERNET MACCR Configuration --------------------*/
- /* Get the ETHERNET MACCR value */
- tmpreg1 = (heth->Instance)->MACCR;
-
- /* Clear FES and DM bits */
- tmpreg1 &= ~(0x00004800U);
-
- tmpreg1 |= (uint32_t)(heth->Init.Speed | heth->Init.DuplexMode);
-
- /* Write to ETHERNET MACCR */
- (heth->Instance)->MACCR = (uint32_t)tmpreg1;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg1 = (heth->Instance)->MACCR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- (heth->Instance)->MACCR = tmpreg1;
- }
-
- /* Set the ETH state to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Sets ETH DMA Configuration.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param dmaconf: DMA Configuration structure
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef *dmaconf)
-{
- uint32_t tmpreg1 = 0U;
-
- /* Process Locked */
- __HAL_LOCK(heth);
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Check parameters */
- assert_param(IS_ETH_DROP_TCPIP_CHECKSUM_FRAME(dmaconf->DropTCPIPChecksumErrorFrame));
- assert_param(IS_ETH_RECEIVE_STORE_FORWARD(dmaconf->ReceiveStoreForward));
- assert_param(IS_ETH_FLUSH_RECEIVE_FRAME(dmaconf->FlushReceivedFrame));
- assert_param(IS_ETH_TRANSMIT_STORE_FORWARD(dmaconf->TransmitStoreForward));
- assert_param(IS_ETH_TRANSMIT_THRESHOLD_CONTROL(dmaconf->TransmitThresholdControl));
- assert_param(IS_ETH_FORWARD_ERROR_FRAMES(dmaconf->ForwardErrorFrames));
- assert_param(IS_ETH_FORWARD_UNDERSIZED_GOOD_FRAMES(dmaconf->ForwardUndersizedGoodFrames));
- assert_param(IS_ETH_RECEIVE_THRESHOLD_CONTROL(dmaconf->ReceiveThresholdControl));
- assert_param(IS_ETH_SECOND_FRAME_OPERATE(dmaconf->SecondFrameOperate));
- assert_param(IS_ETH_ADDRESS_ALIGNED_BEATS(dmaconf->AddressAlignedBeats));
- assert_param(IS_ETH_FIXED_BURST(dmaconf->FixedBurst));
- assert_param(IS_ETH_RXDMA_BURST_LENGTH(dmaconf->RxDMABurstLength));
- assert_param(IS_ETH_TXDMA_BURST_LENGTH(dmaconf->TxDMABurstLength));
- assert_param(IS_ETH_DMA_DESC_SKIP_LENGTH(dmaconf->DescriptorSkipLength));
- assert_param(IS_ETH_DMA_ARBITRATION_ROUNDROBIN_RXTX(dmaconf->DMAArbitration));
-
- /*----------------------- ETHERNET DMAOMR Configuration --------------------*/
- /* Get the ETHERNET DMAOMR value */
- tmpreg1 = (heth->Instance)->DMAOMR;
- /* Clear xx bits */
- tmpreg1 &= ETH_DMAOMR_CLEAR_MASK;
-
- tmpreg1 |= (uint32_t)(dmaconf->DropTCPIPChecksumErrorFrame |
- dmaconf->ReceiveStoreForward |
- dmaconf->FlushReceivedFrame |
- dmaconf->TransmitStoreForward |
- dmaconf->TransmitThresholdControl |
- dmaconf->ForwardErrorFrames |
- dmaconf->ForwardUndersizedGoodFrames |
- dmaconf->ReceiveThresholdControl |
- dmaconf->SecondFrameOperate);
-
- /* Write to ETHERNET DMAOMR */
- (heth->Instance)->DMAOMR = (uint32_t)tmpreg1;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg1 = (heth->Instance)->DMAOMR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- (heth->Instance)->DMAOMR = tmpreg1;
-
- /*----------------------- ETHERNET DMABMR Configuration --------------------*/
- (heth->Instance)->DMABMR = (uint32_t)(dmaconf->AddressAlignedBeats |
- dmaconf->FixedBurst |
- dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
- dmaconf->TxDMABurstLength |
- (dmaconf->DescriptorSkipLength << 2U) |
- dmaconf->DMAArbitration |
- ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg1 = (heth->Instance)->DMABMR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- (heth->Instance)->DMABMR = tmpreg1;
-
- /* Set the ETH state to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(heth);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup ETH_Exported_Functions_Group4 Peripheral State functions
- * @brief Peripheral State functions
- *
- @verbatim
- ===============================================================================
- ##### Peripheral State functions #####
- ===============================================================================
- [..]
- This subsection permits to get in run-time the status of the peripheral
- and the data flow.
- (+) Get the ETH handle state:
- HAL_ETH_GetState();
-
-
- @endverbatim
- * @{
- */
-
-/**
- * @brief Return the ETH HAL state
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL state
- */
-HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth)
-{
- /* Return ETH state */
- return heth->State;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup ETH_Private_Functions
- * @{
- */
-
-/**
- * @brief Configures Ethernet MAC and DMA with default parameters.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param err: Ethernet Init error
- * @retval HAL status
- */
-static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
-{
- ETH_MACInitTypeDef macinit;
- ETH_DMAInitTypeDef dmainit;
- uint32_t tmpreg1 = 0U;
-
- if (err != ETH_SUCCESS) /* Auto-negotiation failed */
- {
- /* Set Ethernet duplex mode to Full-duplex */
- (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
-
- /* Set Ethernet speed to 100M */
- (heth->Init).Speed = ETH_SPEED_100M;
- }
-
- /* Ethernet MAC default initialization **************************************/
- macinit.Watchdog = ETH_WATCHDOG_ENABLE;
- macinit.Jabber = ETH_JABBER_ENABLE;
- macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
- macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
- macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
- macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
- if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
- {
- macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
- }
- else
- {
- macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
- }
- macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE;
- macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
- macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
- macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
- macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE;
- macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;
- macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
- macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;
- macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;
- macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;
- macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;
- macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
- macinit.HashTableHigh = 0x0U;
- macinit.HashTableLow = 0x0U;
- macinit.PauseTime = 0x0U;
- macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
- macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
- macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
- macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
- macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;
- macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
- macinit.VLANTagIdentifier = 0x0U;
-
- /*------------------------ ETHERNET MACCR Configuration --------------------*/
- /* Get the ETHERNET MACCR value */
- tmpreg1 = (heth->Instance)->MACCR;
- /* Clear WD, PCE, PS, TE and RE bits */
- tmpreg1 &= ETH_MACCR_CLEAR_MASK;
- /* Set the WD bit according to ETH Watchdog value */
- /* Set the JD: bit according to ETH Jabber value */
- /* Set the IFG bit according to ETH InterFrameGap value */
- /* Set the DCRS bit according to ETH CarrierSense value */
- /* Set the FES bit according to ETH Speed value */
- /* Set the DO bit according to ETH ReceiveOwn value */
- /* Set the LM bit according to ETH LoopbackMode value */
- /* Set the DM bit according to ETH Mode value */
- /* Set the IPCO bit according to ETH ChecksumOffload value */
- /* Set the DR bit according to ETH RetryTransmission value */
- /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */
- /* Set the BL bit according to ETH BackOffLimit value */
- /* Set the DC bit according to ETH DeferralCheck value */
- tmpreg1 |= (uint32_t)(macinit.Watchdog |
- macinit.Jabber |
- macinit.InterFrameGap |
- macinit.CarrierSense |
- (heth->Init).Speed |
- macinit.ReceiveOwn |
- macinit.LoopbackMode |
- (heth->Init).DuplexMode |
- macinit.ChecksumOffload |
- macinit.RetryTransmission |
- macinit.AutomaticPadCRCStrip |
- macinit.BackOffLimit |
- macinit.DeferralCheck);
-
- /* Write to ETHERNET MACCR */
- (heth->Instance)->MACCR = (uint32_t)tmpreg1;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg1 = (heth->Instance)->MACCR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- (heth->Instance)->MACCR = tmpreg1;
-
- /*----------------------- ETHERNET MACFFR Configuration --------------------*/
- /* Set the RA bit according to ETH ReceiveAll value */
- /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */
- /* Set the PCF bit according to ETH PassControlFrames value */
- /* Set the DBF bit according to ETH BroadcastFramesReception value */
- /* Set the DAIF bit according to ETH DestinationAddrFilter value */
- /* Set the PR bit according to ETH PromiscuousMode value */
- /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */
- /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */
- /* Write to ETHERNET MACFFR */
- (heth->Instance)->MACFFR = (uint32_t)(macinit.ReceiveAll |
- macinit.SourceAddrFilter |
- macinit.PassControlFrames |
- macinit.BroadcastFramesReception |
- macinit.DestinationAddrFilter |
- macinit.PromiscuousMode |
- macinit.MulticastFramesFilter |
- macinit.UnicastFramesFilter);
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg1 = (heth->Instance)->MACFFR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- (heth->Instance)->MACFFR = tmpreg1;
-
- /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/
- /* Write to ETHERNET MACHTHR */
- (heth->Instance)->MACHTHR = (uint32_t)macinit.HashTableHigh;
-
- /* Write to ETHERNET MACHTLR */
- (heth->Instance)->MACHTLR = (uint32_t)macinit.HashTableLow;
- /*----------------------- ETHERNET MACFCR Configuration -------------------*/
-
- /* Get the ETHERNET MACFCR value */
- tmpreg1 = (heth->Instance)->MACFCR;
- /* Clear xx bits */
- tmpreg1 &= ETH_MACFCR_CLEAR_MASK;
-
- /* Set the PT bit according to ETH PauseTime value */
- /* Set the DZPQ bit according to ETH ZeroQuantaPause value */
- /* Set the PLT bit according to ETH PauseLowThreshold value */
- /* Set the UP bit according to ETH UnicastPauseFrameDetect value */
- /* Set the RFE bit according to ETH ReceiveFlowControl value */
- /* Set the TFE bit according to ETH TransmitFlowControl value */
- tmpreg1 |= (uint32_t)((macinit.PauseTime << 16U) |
- macinit.ZeroQuantaPause |
- macinit.PauseLowThreshold |
- macinit.UnicastPauseFrameDetect |
- macinit.ReceiveFlowControl |
- macinit.TransmitFlowControl);
-
- /* Write to ETHERNET MACFCR */
- (heth->Instance)->MACFCR = (uint32_t)tmpreg1;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg1 = (heth->Instance)->MACFCR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- (heth->Instance)->MACFCR = tmpreg1;
-
- /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/
- /* Set the ETV bit according to ETH VLANTagComparison value */
- /* Set the VL bit according to ETH VLANTagIdentifier value */
- (heth->Instance)->MACVLANTR = (uint32_t)(macinit.VLANTagComparison |
- macinit.VLANTagIdentifier);
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg1 = (heth->Instance)->MACVLANTR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- (heth->Instance)->MACVLANTR = tmpreg1;
-
- /* Ethernet DMA default initialization ************************************/
- dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
- dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
- dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
- dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
- dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
- dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
- dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
- dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
- dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
- dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
- dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;
- dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
- dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
- dmainit.DescriptorSkipLength = 0x0U;
- dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
-
- /* Get the ETHERNET DMAOMR value */
- tmpreg1 = (heth->Instance)->DMAOMR;
- /* Clear xx bits */
- tmpreg1 &= ETH_DMAOMR_CLEAR_MASK;
-
- /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */
- /* Set the RSF bit according to ETH ReceiveStoreForward value */
- /* Set the DFF bit according to ETH FlushReceivedFrame value */
- /* Set the TSF bit according to ETH TransmitStoreForward value */
- /* Set the TTC bit according to ETH TransmitThresholdControl value */
- /* Set the FEF bit according to ETH ForwardErrorFrames value */
- /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */
- /* Set the RTC bit according to ETH ReceiveThresholdControl value */
- /* Set the OSF bit according to ETH SecondFrameOperate value */
- tmpreg1 |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame |
- dmainit.ReceiveStoreForward |
- dmainit.FlushReceivedFrame |
- dmainit.TransmitStoreForward |
- dmainit.TransmitThresholdControl |
- dmainit.ForwardErrorFrames |
- dmainit.ForwardUndersizedGoodFrames |
- dmainit.ReceiveThresholdControl |
- dmainit.SecondFrameOperate);
-
- /* Write to ETHERNET DMAOMR */
- (heth->Instance)->DMAOMR = (uint32_t)tmpreg1;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg1 = (heth->Instance)->DMAOMR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- (heth->Instance)->DMAOMR = tmpreg1;
-
- /*----------------------- ETHERNET DMABMR Configuration ------------------*/
- /* Set the AAL bit according to ETH AddressAlignedBeats value */
- /* Set the FB bit according to ETH FixedBurst value */
- /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */
- /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */
- /* Set the DSL bit according to ETH DesciptorSkipLength value */
- /* Set the PR and DA bits according to ETH DMAArbitration value */
- (heth->Instance)->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats |
- dmainit.FixedBurst |
- dmainit.RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
- dmainit.TxDMABurstLength |
- (dmainit.DescriptorSkipLength << 2U) |
- dmainit.DMAArbitration |
- ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg1 = (heth->Instance)->DMABMR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- (heth->Instance)->DMABMR = tmpreg1;
-
- if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
- {
- /* Enable the Ethernet Rx Interrupt */
- __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);
- }
-
- /* Initialize MAC address in ethernet MAC */
- ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
-}
-
-/**
- * @brief Configures the selected MAC address.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param MacAddr: The MAC address to configure
- * This parameter can be one of the following values:
- * @arg ETH_MAC_Address0: MAC Address0
- * @arg ETH_MAC_Address1: MAC Address1
- * @arg ETH_MAC_Address2: MAC Address2
- * @arg ETH_MAC_Address3: MAC Address3
- * @param Addr: Pointer to MAC address buffer data (6 bytes)
- * @retval HAL status
- */
-static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)
-{
- uint32_t tmpreg1;
-
- /* Prevent unused argument(s) compilation warning */
- UNUSED(heth);
-
- /* Check the parameters */
- assert_param(IS_ETH_MAC_ADDRESS0123(MacAddr));
-
- /* Calculate the selected MAC address high register */
- tmpreg1 = ((uint32_t)Addr[5U] << 8U) | (uint32_t)Addr[4U];
- /* Load the selected MAC address high register */
- (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_HBASE + MacAddr))) = tmpreg1;
- /* Calculate the selected MAC address low register */
- tmpreg1 = ((uint32_t)Addr[3U] << 24U) | ((uint32_t)Addr[2U] << 16U) | ((uint32_t)Addr[1U] << 8U) | Addr[0U];
-
- /* Load the selected MAC address low register */
- (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_LBASE + MacAddr))) = tmpreg1;
-}
-
-/**
- * @brief Enables the MAC transmission.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth)
-{
- __IO uint32_t tmpreg1 = 0U;
-
- /* Enable the MAC transmission */
- (heth->Instance)->MACCR |= ETH_MACCR_TE;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg1 = (heth->Instance)->MACCR;
- ETH_Delay(ETH_REG_WRITE_DELAY);
- (heth->Instance)->MACCR = tmpreg1;
-}
-
-/**
- * @brief Disables the MAC transmission.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth)
-{
- __IO uint32_t tmpreg1 = 0U;
-
- /* Disable the MAC transmission */
- (heth->Instance)->MACCR &= ~ETH_MACCR_TE;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg1 = (heth->Instance)->MACCR;
- ETH_Delay(ETH_REG_WRITE_DELAY);
- (heth->Instance)->MACCR = tmpreg1;
-}
-
-/**
- * @brief Enables the MAC reception.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth)
-{
- __IO uint32_t tmpreg1 = 0U;
-
- /* Enable the MAC reception */
- (heth->Instance)->MACCR |= ETH_MACCR_RE;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg1 = (heth->Instance)->MACCR;
- ETH_Delay(ETH_REG_WRITE_DELAY);
- (heth->Instance)->MACCR = tmpreg1;
-}
-
-/**
- * @brief Disables the MAC reception.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth)
-{
- __IO uint32_t tmpreg1 = 0U;
-
- /* Disable the MAC reception */
- (heth->Instance)->MACCR &= ~ETH_MACCR_RE;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg1 = (heth->Instance)->MACCR;
- ETH_Delay(ETH_REG_WRITE_DELAY);
- (heth->Instance)->MACCR = tmpreg1;
-}
-
-/**
- * @brief Enables the DMA transmission.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth)
-{
- /* Enable the DMA transmission */
- (heth->Instance)->DMAOMR |= ETH_DMAOMR_ST;
-}
-
-/**
- * @brief Disables the DMA transmission.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth)
-{
- /* Disable the DMA transmission */
- (heth->Instance)->DMAOMR &= ~ETH_DMAOMR_ST;
-}
-
-/**
- * @brief Enables the DMA reception.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth)
-{
- /* Enable the DMA reception */
- (heth->Instance)->DMAOMR |= ETH_DMAOMR_SR;
-}
-
-/**
- * @brief Disables the DMA reception.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth)
-{
- /* Disable the DMA reception */
- (heth->Instance)->DMAOMR &= ~ETH_DMAOMR_SR;
-}
-
-/**
- * @brief Clears the ETHERNET transmit FIFO.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth)
-{
- __IO uint32_t tmpreg1 = 0U;
-
- /* Set the Flush Transmit FIFO bit */
- (heth->Instance)->DMAOMR |= ETH_DMAOMR_FTF;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg1 = (heth->Instance)->DMAOMR;
- ETH_Delay(ETH_REG_WRITE_DELAY);
- (heth->Instance)->DMAOMR = tmpreg1;
-}
-
-/**
- * @brief This function provides delay (in milliseconds) based on CPU cycles method.
- * @param mdelay: specifies the delay time length, in milliseconds.
- * @retval None
- */
-static void ETH_Delay(uint32_t mdelay)
-{
- __IO uint32_t Delay = mdelay * (SystemCoreClock / 8U / 1000U);
- do
- {
- __NOP();
- }
- while (Delay --);
-}
-
-/**
- * @}
- */
-
-#endif /* HAL_ETH_MODULE_ENABLED */
-/**
- * @}
- */
-
-#endif /* STM32F107xC */
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c
deleted file mode 100644
index ea72390..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c
+++ /dev/null
@@ -1,983 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_flash.c
- * @author MCD Application Team
- * @brief FLASH HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the internal FLASH memory:
- * + Program operations functions
- * + Memory Control functions
- * + Peripheral State functions
- *
- @verbatim
- ==============================================================================
- ##### FLASH peripheral features #####
- ==============================================================================
- [..] The Flash memory interface manages CPU AHB I-Code and D-Code accesses
- to the Flash memory. It implements the erase and program Flash memory operations
- and the read and write protection mechanisms.
-
- [..] The Flash memory interface accelerates code execution with a system of instruction
- prefetch.
-
- [..] The FLASH main features are:
- (+) Flash memory read operations
- (+) Flash memory program/erase operations
- (+) Read / write protections
- (+) Prefetch on I-Code
- (+) Option Bytes programming
-
-
- ##### How to use this driver #####
- ==============================================================================
- [..]
- This driver provides functions and macros to configure and program the FLASH
- memory of all STM32F1xx devices.
-
- (#) FLASH Memory I/O Programming functions: this group includes all needed
- functions to erase and program the main memory:
- (++) Lock and Unlock the FLASH interface
- (++) Erase function: Erase page, erase all pages
- (++) Program functions: half word, word and doubleword
- (#) FLASH Option Bytes Programming functions: this group includes all needed
- functions to manage the Option Bytes:
- (++) Lock and Unlock the Option Bytes
- (++) Set/Reset the write protection
- (++) Set the Read protection Level
- (++) Program the user Option Bytes
- (++) Launch the Option Bytes loader
- (++) Erase Option Bytes
- (++) Program the data Option Bytes
- (++) Get the Write protection.
- (++) Get the user option bytes.
-
- (#) Interrupts and flags management functions : this group
- includes all needed functions to:
- (++) Handle FLASH interrupts
- (++) Wait for last FLASH operation according to its status
- (++) Get error flag status
-
- [..] In addition to these function, this driver includes a set of macros allowing
- to handle the following operations:
-
- (+) Set/Get the latency
- (+) Enable/Disable the prefetch buffer
- (+) Enable/Disable the half cycle access
- (+) Enable/Disable the FLASH interrupts
- (+) Monitor the FLASH flags status
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#ifdef HAL_FLASH_MODULE_ENABLED
-
-/** @defgroup FLASH FLASH
- * @brief FLASH HAL module driver
- * @{
- */
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @defgroup FLASH_Private_Constants FLASH Private Constants
- * @{
- */
-/**
- * @}
- */
-
-/* Private macro ---------------------------- ---------------------------------*/
-/** @defgroup FLASH_Private_Macros FLASH Private Macros
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private variables ---------------------------------------------------------*/
-/** @defgroup FLASH_Private_Variables FLASH Private Variables
- * @{
- */
-/* Variables used for Erase pages under interruption*/
-FLASH_ProcessTypeDef pFlash;
-/**
- * @}
- */
-
-/* Private function prototypes -----------------------------------------------*/
-/** @defgroup FLASH_Private_Functions FLASH Private Functions
- * @{
- */
-static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data);
-static void FLASH_SetErrorCode(void);
-extern void FLASH_PageErase(uint32_t PageAddress);
-/**
- * @}
- */
-
-/* Exported functions ---------------------------------------------------------*/
-/** @defgroup FLASH_Exported_Functions FLASH Exported Functions
- * @{
- */
-
-/** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
- * @brief Programming operation functions
- *
-@verbatim
-@endverbatim
- * @{
- */
-
-/**
- * @brief Program halfword, word or double word at a specified address
- * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
- * The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
- *
- * @note If an erase and a program operations are requested simultaneously,
- * the erase operation is performed before the program one.
- *
- * @note FLASH should be previously erased before new programmation (only exception to this
- * is when 0x0000 is programmed)
- *
- * @param TypeProgram: Indicate the way to program at a specified address.
- * This parameter can be a value of @ref FLASH_Type_Program
- * @param Address: Specifies the address to be programmed.
- * @param Data: Specifies the data to be programmed
- *
- * @retval HAL_StatusTypeDef HAL Status
- */
-HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
-{
- HAL_StatusTypeDef status = HAL_ERROR;
- uint8_t index = 0;
- uint8_t nbiterations = 0;
-
- /* Process Locked */
- __HAL_LOCK(&pFlash);
-
- /* Check the parameters */
- assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
- assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
-
-#if defined(FLASH_BANK2_END)
- if(Address <= FLASH_BANK1_END)
- {
-#endif /* FLASH_BANK2_END */
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
-#if defined(FLASH_BANK2_END)
- }
- else
- {
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperationBank2(FLASH_TIMEOUT_VALUE);
- }
-#endif /* FLASH_BANK2_END */
-
- if(status == HAL_OK)
- {
- if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
- {
- /* Program halfword (16-bit) at a specified address. */
- nbiterations = 1U;
- }
- else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
- {
- /* Program word (32-bit = 2*16-bit) at a specified address. */
- nbiterations = 2U;
- }
- else
- {
- /* Program double word (64-bit = 4*16-bit) at a specified address. */
- nbiterations = 4U;
- }
-
- for (index = 0U; index < nbiterations; index++)
- {
- FLASH_Program_HalfWord((Address + (2U*index)), (uint16_t)(Data >> (16U*index)));
-
-#if defined(FLASH_BANK2_END)
- if(Address <= FLASH_BANK1_END)
- {
-#endif /* FLASH_BANK2_END */
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
-
- /* If the program operation is completed, disable the PG Bit */
- CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
-#if defined(FLASH_BANK2_END)
- }
- else
- {
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperationBank2(FLASH_TIMEOUT_VALUE);
-
- /* If the program operation is completed, disable the PG Bit */
- CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG);
- }
-#endif /* FLASH_BANK2_END */
- /* In case of error, stop programation procedure */
- if (status != HAL_OK)
- {
- break;
- }
- }
- }
-
- /* Process Unlocked */
- __HAL_UNLOCK(&pFlash);
-
- return status;
-}
-
-/**
- * @brief Program halfword, word or double word at a specified address with interrupt enabled.
- * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
- * The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
- *
- * @note If an erase and a program operations are requested simultaneously,
- * the erase operation is performed before the program one.
- *
- * @param TypeProgram: Indicate the way to program at a specified address.
- * This parameter can be a value of @ref FLASH_Type_Program
- * @param Address: Specifies the address to be programmed.
- * @param Data: Specifies the data to be programmed
- *
- * @retval HAL_StatusTypeDef HAL Status
- */
-HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
-{
- HAL_StatusTypeDef status = HAL_OK;
-
- /* Process Locked */
- __HAL_LOCK(&pFlash);
-
- /* Check the parameters */
- assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
- assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
-
-#if defined(FLASH_BANK2_END)
- /* If procedure already ongoing, reject the next one */
- if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
- {
- return HAL_ERROR;
- }
-
- if(Address <= FLASH_BANK1_END)
- {
- /* Enable End of FLASH Operation and Error source interrupts */
- __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1);
-
- }else
- {
- /* Enable End of FLASH Operation and Error source interrupts */
- __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
- }
-#else
- /* Enable End of FLASH Operation and Error source interrupts */
- __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
-#endif /* FLASH_BANK2_END */
-
- pFlash.Address = Address;
- pFlash.Data = Data;
-
- if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
- {
- pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMHALFWORD;
- /* Program halfword (16-bit) at a specified address. */
- pFlash.DataRemaining = 1U;
- }
- else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
- {
- pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMWORD;
- /* Program word (32-bit : 2*16-bit) at a specified address. */
- pFlash.DataRemaining = 2U;
- }
- else
- {
- pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMDOUBLEWORD;
- /* Program double word (64-bit : 4*16-bit) at a specified address. */
- pFlash.DataRemaining = 4U;
- }
-
- /* Program halfword (16-bit) at a specified address. */
- FLASH_Program_HalfWord(Address, (uint16_t)Data);
-
- return status;
-}
-
-/**
- * @brief This function handles FLASH interrupt request.
- * @retval None
- */
-void HAL_FLASH_IRQHandler(void)
-{
- uint32_t addresstmp = 0U;
-
- /* Check FLASH operation error flags */
-#if defined(FLASH_BANK2_END)
- if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK1) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK1) || \
- (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2)))
-#else
- if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) ||__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
-#endif /* FLASH_BANK2_END */
- {
- /* Return the faulty address */
- addresstmp = pFlash.Address;
- /* Reset address */
- pFlash.Address = 0xFFFFFFFFU;
-
- /* Save the Error code */
- FLASH_SetErrorCode();
-
- /* FLASH error interrupt user callback */
- HAL_FLASH_OperationErrorCallback(addresstmp);
-
- /* Stop the procedure ongoing */
- pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
- }
-
- /* Check FLASH End of Operation flag */
-#if defined(FLASH_BANK2_END)
- if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK1))
- {
- /* Clear FLASH End of Operation pending bit */
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK1);
-#else
- if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
- {
- /* Clear FLASH End of Operation pending bit */
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
-#endif /* FLASH_BANK2_END */
-
- /* Process can continue only if no error detected */
- if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
- {
- if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
- {
- /* Nb of pages to erased can be decreased */
- pFlash.DataRemaining--;
-
- /* Check if there are still pages to erase */
- if(pFlash.DataRemaining != 0U)
- {
- addresstmp = pFlash.Address;
- /*Indicate user which sector has been erased */
- HAL_FLASH_EndOfOperationCallback(addresstmp);
-
- /*Increment sector number*/
- addresstmp = pFlash.Address + FLASH_PAGE_SIZE;
- pFlash.Address = addresstmp;
-
- /* If the erase operation is completed, disable the PER Bit */
- CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
-
- FLASH_PageErase(addresstmp);
- }
- else
- {
- /* No more pages to Erase, user callback can be called. */
- /* Reset Sector and stop Erase pages procedure */
- pFlash.Address = addresstmp = 0xFFFFFFFFU;
- pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
- /* FLASH EOP interrupt user callback */
- HAL_FLASH_EndOfOperationCallback(addresstmp);
- }
- }
- else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
- {
- /* Operation is completed, disable the MER Bit */
- CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
-
-#if defined(FLASH_BANK2_END)
- /* Stop Mass Erase procedure if no pending mass erase on other bank */
- if (HAL_IS_BIT_CLR(FLASH->CR2, FLASH_CR2_MER))
- {
-#endif /* FLASH_BANK2_END */
- /* MassErase ended. Return the selected bank */
- /* FLASH EOP interrupt user callback */
- HAL_FLASH_EndOfOperationCallback(0U);
-
- /* Stop Mass Erase procedure*/
- pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
- }
-#if defined(FLASH_BANK2_END)
- }
-#endif /* FLASH_BANK2_END */
- else
- {
- /* Nb of 16-bit data to program can be decreased */
- pFlash.DataRemaining--;
-
- /* Check if there are still 16-bit data to program */
- if(pFlash.DataRemaining != 0U)
- {
- /* Increment address to 16-bit */
- pFlash.Address += 2U;
- addresstmp = pFlash.Address;
-
- /* Shift to have next 16-bit data */
- pFlash.Data = (pFlash.Data >> 16U);
-
- /* Operation is completed, disable the PG Bit */
- CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
-
- /*Program halfword (16-bit) at a specified address.*/
- FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
- }
- else
- {
- /* Program ended. Return the selected address */
- /* FLASH EOP interrupt user callback */
- if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
- {
- HAL_FLASH_EndOfOperationCallback(pFlash.Address);
- }
- else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
- {
- HAL_FLASH_EndOfOperationCallback(pFlash.Address - 2U);
- }
- else
- {
- HAL_FLASH_EndOfOperationCallback(pFlash.Address - 6U);
- }
-
- /* Reset Address and stop Program procedure */
- pFlash.Address = 0xFFFFFFFFU;
- pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
- }
- }
- }
- }
-
-#if defined(FLASH_BANK2_END)
- /* Check FLASH End of Operation flag */
- if(__HAL_FLASH_GET_FLAG( FLASH_FLAG_EOP_BANK2))
- {
- /* Clear FLASH End of Operation pending bit */
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2);
-
- /* Process can continue only if no error detected */
- if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
- {
- if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
- {
- /* Nb of pages to erased can be decreased */
- pFlash.DataRemaining--;
-
- /* Check if there are still pages to erase*/
- if(pFlash.DataRemaining != 0U)
- {
- /* Indicate user which page address has been erased*/
- HAL_FLASH_EndOfOperationCallback(pFlash.Address);
-
- /* Increment page address to next page */
- pFlash.Address += FLASH_PAGE_SIZE;
- addresstmp = pFlash.Address;
-
- /* Operation is completed, disable the PER Bit */
- CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER);
-
- FLASH_PageErase(addresstmp);
- }
- else
- {
- /*No more pages to Erase*/
-
- /*Reset Address and stop Erase pages procedure*/
- pFlash.Address = 0xFFFFFFFFU;
- pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
-
- /* FLASH EOP interrupt user callback */
- HAL_FLASH_EndOfOperationCallback(pFlash.Address);
- }
- }
- else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
- {
- /* Operation is completed, disable the MER Bit */
- CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
-
- if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_MER))
- {
- /* MassErase ended. Return the selected bank*/
- /* FLASH EOP interrupt user callback */
- HAL_FLASH_EndOfOperationCallback(0U);
-
- pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
- }
- }
- else
- {
- /* Nb of 16-bit data to program can be decreased */
- pFlash.DataRemaining--;
-
- /* Check if there are still 16-bit data to program */
- if(pFlash.DataRemaining != 0U)
- {
- /* Increment address to 16-bit */
- pFlash.Address += 2U;
- addresstmp = pFlash.Address;
-
- /* Shift to have next 16-bit data */
- pFlash.Data = (pFlash.Data >> 16U);
-
- /* Operation is completed, disable the PG Bit */
- CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG);
-
- /*Program halfword (16-bit) at a specified address.*/
- FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
- }
- else
- {
- /*Program ended. Return the selected address*/
- /* FLASH EOP interrupt user callback */
- if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
- {
- HAL_FLASH_EndOfOperationCallback(pFlash.Address);
- }
- else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
- {
- HAL_FLASH_EndOfOperationCallback(pFlash.Address-2U);
- }
- else
- {
- HAL_FLASH_EndOfOperationCallback(pFlash.Address-6U);
- }
-
- /* Reset Address and stop Program procedure*/
- pFlash.Address = 0xFFFFFFFFU;
- pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
- }
- }
- }
- }
-#endif
-
- if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
- {
-#if defined(FLASH_BANK2_END)
- /* Operation is completed, disable the PG, PER and MER Bits for both bank */
- CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER));
- CLEAR_BIT(FLASH->CR2, (FLASH_CR2_PG | FLASH_CR2_PER | FLASH_CR2_MER));
-
- /* Disable End of FLASH Operation and Error source interrupts for both banks */
- __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1 | FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
-#else
- /* Operation is completed, disable the PG, PER and MER Bits */
- CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER));
-
- /* Disable End of FLASH Operation and Error source interrupts */
- __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
-#endif /* FLASH_BANK2_END */
-
- /* Process Unlocked */
- __HAL_UNLOCK(&pFlash);
- }
-}
-
-/**
- * @brief FLASH end of operation interrupt callback
- * @param ReturnValue: The value saved in this parameter depends on the ongoing procedure
- * - Mass Erase: No return value expected
- * - Pages Erase: Address of the page which has been erased
- * (if 0xFFFFFFFF, it means that all the selected pages have been erased)
- * - Program: Address which was selected for data program
- * @retval none
- */
-__weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(ReturnValue);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief FLASH operation error interrupt callback
- * @param ReturnValue: The value saved in this parameter depends on the ongoing procedure
- * - Mass Erase: No return value expected
- * - Pages Erase: Address of the page which returned an error
- * - Program: Address which was selected for data program
- * @retval none
- */
-__weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(ReturnValue);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_FLASH_OperationErrorCallback could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
- * @brief management functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral Control functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to control the FLASH
- memory operations.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Unlock the FLASH control register access
- * @retval HAL Status
- */
-HAL_StatusTypeDef HAL_FLASH_Unlock(void)
-{
- HAL_StatusTypeDef status = HAL_OK;
-
- if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
- {
- /* Authorize the FLASH Registers access */
- WRITE_REG(FLASH->KEYR, FLASH_KEY1);
- WRITE_REG(FLASH->KEYR, FLASH_KEY2);
-
- /* Verify Flash is unlocked */
- if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
- {
- status = HAL_ERROR;
- }
- }
-#if defined(FLASH_BANK2_END)
- if(READ_BIT(FLASH->CR2, FLASH_CR2_LOCK) != RESET)
- {
- /* Authorize the FLASH BANK2 Registers access */
- WRITE_REG(FLASH->KEYR2, FLASH_KEY1);
- WRITE_REG(FLASH->KEYR2, FLASH_KEY2);
-
- /* Verify Flash BANK2 is unlocked */
- if(READ_BIT(FLASH->CR2, FLASH_CR2_LOCK) != RESET)
- {
- status = HAL_ERROR;
- }
- }
-#endif /* FLASH_BANK2_END */
-
- return status;
-}
-
-/**
- * @brief Locks the FLASH control register access
- * @retval HAL Status
- */
-HAL_StatusTypeDef HAL_FLASH_Lock(void)
-{
- /* Set the LOCK Bit to lock the FLASH Registers access */
- SET_BIT(FLASH->CR, FLASH_CR_LOCK);
-
-#if defined(FLASH_BANK2_END)
- /* Set the LOCK Bit to lock the FLASH BANK2 Registers access */
- SET_BIT(FLASH->CR2, FLASH_CR2_LOCK);
-
-#endif /* FLASH_BANK2_END */
- return HAL_OK;
-}
-
-/**
- * @brief Unlock the FLASH Option Control Registers access.
- * @retval HAL Status
- */
-HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
-{
- if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_OPTWRE))
- {
- /* Authorizes the Option Byte register programming */
- WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
- WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
- }
- else
- {
- return HAL_ERROR;
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Lock the FLASH Option Control Registers access.
- * @retval HAL Status
- */
-HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
-{
- /* Clear the OPTWRE Bit to lock the FLASH Option Byte Registers access */
- CLEAR_BIT(FLASH->CR, FLASH_CR_OPTWRE);
-
- return HAL_OK;
-}
-
-/**
- * @brief Launch the option byte loading.
- * @note This function will reset automatically the MCU.
- * @retval None
- */
-void HAL_FLASH_OB_Launch(void)
-{
- /* Initiates a system reset request to launch the option byte loading */
- HAL_NVIC_SystemReset();
-}
-
-/**
- * @}
- */
-
-/** @defgroup FLASH_Exported_Functions_Group3 Peripheral errors functions
- * @brief Peripheral errors functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral Errors functions #####
- ===============================================================================
- [..]
- This subsection permit to get in run-time errors of the FLASH peripheral.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Get the specific FLASH error flag.
- * @retval FLASH_ErrorCode The returned value can be:
- * @ref FLASH_Error_Codes
- */
-uint32_t HAL_FLASH_GetError(void)
-{
- return pFlash.ErrorCode;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup FLASH_Private_Functions
- * @{
- */
-
-/**
- * @brief Program a half-word (16-bit) at a specified address.
- * @param Address specify the address to be programmed.
- * @param Data specify the data to be programmed.
- * @retval None
- */
-static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
-{
- /* Clean the error context */
- pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
-
-#if defined(FLASH_BANK2_END)
- if(Address <= FLASH_BANK1_END)
- {
-#endif /* FLASH_BANK2_END */
- /* Proceed to program the new data */
- SET_BIT(FLASH->CR, FLASH_CR_PG);
-#if defined(FLASH_BANK2_END)
- }
- else
- {
- /* Proceed to program the new data */
- SET_BIT(FLASH->CR2, FLASH_CR2_PG);
- }
-#endif /* FLASH_BANK2_END */
-
- /* Write data in the address */
- *(__IO uint16_t*)Address = Data;
-}
-
-/**
- * @brief Wait for a FLASH operation to complete.
- * @param Timeout maximum flash operation timeout
- * @retval HAL Status
- */
-HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
-{
- /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
- Even if the FLASH operation fails, the BUSY flag will be reset and an error
- flag will be set */
-
- uint32_t tickstart = HAL_GetTick();
-
- while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
- {
- if (Timeout != HAL_MAX_DELAY)
- {
- if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
- {
- return HAL_TIMEOUT;
- }
- }
- }
-
- /* Check FLASH End of Operation flag */
- if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
- {
- /* Clear FLASH End of Operation pending bit */
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
- }
-
- if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) ||
- __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) ||
- __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
- {
- /*Save the error code*/
- FLASH_SetErrorCode();
- return HAL_ERROR;
- }
-
- /* There is no error flag set */
- return HAL_OK;
-}
-
-#if defined(FLASH_BANK2_END)
-/**
- * @brief Wait for a FLASH BANK2 operation to complete.
- * @param Timeout maximum flash operation timeout
- * @retval HAL_StatusTypeDef HAL Status
- */
-HAL_StatusTypeDef FLASH_WaitForLastOperationBank2(uint32_t Timeout)
-{
- /* Wait for the FLASH BANK2 operation to complete by polling on BUSY flag to be reset.
- Even if the FLASH BANK2 operation fails, the BUSY flag will be reset and an error
- flag will be set */
-
- uint32_t tickstart = HAL_GetTick();
-
- while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY_BANK2))
- {
- if (Timeout != HAL_MAX_DELAY)
- {
- if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
- {
- return HAL_TIMEOUT;
- }
- }
- }
-
- /* Check FLASH End of Operation flag */
- if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK2))
- {
- /* Clear FLASH End of Operation pending bit */
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2);
- }
-
- if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))
- {
- /*Save the error code*/
- FLASH_SetErrorCode();
- return HAL_ERROR;
- }
-
- /* If there is an error flag set */
- return HAL_OK;
-
-}
-#endif /* FLASH_BANK2_END */
-
-/**
- * @brief Set the specific FLASH error flag.
- * @retval None
- */
-static void FLASH_SetErrorCode(void)
-{
- uint32_t flags = 0U;
-
-#if defined(FLASH_BANK2_END)
- if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2))
-#else
- if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR))
-#endif /* FLASH_BANK2_END */
- {
- pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
-#if defined(FLASH_BANK2_END)
- flags |= FLASH_FLAG_WRPERR | FLASH_FLAG_WRPERR_BANK2;
-#else
- flags |= FLASH_FLAG_WRPERR;
-#endif /* FLASH_BANK2_END */
- }
-#if defined(FLASH_BANK2_END)
- if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))
-#else
- if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
-#endif /* FLASH_BANK2_END */
- {
- pFlash.ErrorCode |= HAL_FLASH_ERROR_PROG;
-#if defined(FLASH_BANK2_END)
- flags |= FLASH_FLAG_PGERR | FLASH_FLAG_PGERR_BANK2;
-#else
- flags |= FLASH_FLAG_PGERR;
-#endif /* FLASH_BANK2_END */
- }
- if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR))
- {
- pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV;
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
- }
-
- /* Clear FLASH error pending bits */
- __HAL_FLASH_CLEAR_FLAG(flags);
-}
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* HAL_FLASH_MODULE_ENABLED */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c
deleted file mode 100644
index b83fbc6..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c
+++ /dev/null
@@ -1,1143 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_flash_ex.c
- * @author MCD Application Team
- * @brief Extended FLASH HAL module driver.
- *
- * This file provides firmware functions to manage the following
- * functionalities of the FLASH peripheral:
- * + Extended Initialization/de-initialization functions
- * + Extended I/O operation functions
- * + Extended Peripheral Control functions
- *
- @verbatim
- ==============================================================================
- ##### Flash peripheral extended features #####
- ==============================================================================
-
- ##### How to use this driver #####
- ==============================================================================
- [..] This driver provides functions to configure and program the FLASH memory
- of all STM32F1xxx devices. It includes
-
- (++) Set/Reset the write protection
- (++) Program the user Option Bytes
- (++) Get the Read protection Level
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-#ifdef HAL_FLASH_MODULE_ENABLED
-
-/** @addtogroup FLASH
- * @{
- */
-/** @addtogroup FLASH_Private_Variables
- * @{
- */
-/* Variables used for Erase pages under interruption*/
-extern FLASH_ProcessTypeDef pFlash;
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @defgroup FLASHEx FLASHEx
- * @brief FLASH HAL Extension module driver
- * @{
- */
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @defgroup FLASHEx_Private_Constants FLASHEx Private Constants
- * @{
- */
-#define FLASH_POSITION_IWDGSW_BIT FLASH_OBR_IWDG_SW_Pos
-#define FLASH_POSITION_OB_USERDATA0_BIT FLASH_OBR_DATA0_Pos
-#define FLASH_POSITION_OB_USERDATA1_BIT FLASH_OBR_DATA1_Pos
-/**
- * @}
- */
-
-/* Private macro -------------------------------------------------------------*/
-/** @defgroup FLASHEx_Private_Macros FLASHEx Private Macros
- * @{
- */
-/**
- * @}
- */
-
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
- * @{
- */
-/* Erase operations */
-static void FLASH_MassErase(uint32_t Banks);
-void FLASH_PageErase(uint32_t PageAddress);
-
-/* Option bytes control */
-static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WriteProtectPage);
-static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WriteProtectPage);
-static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel);
-static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig);
-static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data);
-static uint32_t FLASH_OB_GetWRP(void);
-static uint32_t FLASH_OB_GetRDP(void);
-static uint8_t FLASH_OB_GetUser(void);
-
-/**
- * @}
- */
-
-/* Exported functions ---------------------------------------------------------*/
-/** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions
- * @{
- */
-
-/** @defgroup FLASHEx_Exported_Functions_Group1 FLASHEx Memory Erasing functions
- * @brief FLASH Memory Erasing functions
- *
-@verbatim
- ==============================================================================
- ##### FLASH Erasing Programming functions #####
- ==============================================================================
-
- [..] The FLASH Memory Erasing functions, includes the following functions:
- (+) @ref HAL_FLASHEx_Erase: return only when erase has been done
- (+) @ref HAL_FLASHEx_Erase_IT: end of erase is done when @ref HAL_FLASH_EndOfOperationCallback
- is called with parameter 0xFFFFFFFF
-
- [..] Any operation of erase should follow these steps:
- (#) Call the @ref HAL_FLASH_Unlock() function to enable the flash control register and
- program memory access.
- (#) Call the desired function to erase page.
- (#) Call the @ref HAL_FLASH_Lock() to disable the flash program memory access
- (recommended to protect the FLASH memory against possible unwanted operation).
-
-@endverbatim
- * @{
- */
-
-
-/**
- * @brief Perform a mass erase or erase the specified FLASH memory pages
- * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function
- * must be called before.
- * Call the @ref HAL_FLASH_Lock() to disable the flash memory access
- * (recommended to protect the FLASH memory against possible unwanted operation)
- * @param[in] pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
- * contains the configuration information for the erasing.
- *
- * @param[out] PageError pointer to variable that
- * contains the configuration information on faulty page in case of error
- * (0xFFFFFFFF means that all the pages have been correctly erased)
- *
- * @retval HAL_StatusTypeDef HAL Status
- */
-HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
-{
- HAL_StatusTypeDef status = HAL_ERROR;
- uint32_t address = 0U;
-
- /* Process Locked */
- __HAL_LOCK(&pFlash);
-
- /* Check the parameters */
- assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
-
- if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
- {
-#if defined(FLASH_BANK2_END)
- if (pEraseInit->Banks == FLASH_BANK_BOTH)
- {
- /* Mass Erase requested for Bank1 and Bank2 */
- /* Wait for last operation to be completed */
- if ((FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) && \
- (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK))
- {
- /*Mass erase to be done*/
- FLASH_MassErase(FLASH_BANK_BOTH);
-
- /* Wait for last operation to be completed */
- if ((FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) && \
- (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK))
- {
- status = HAL_OK;
- }
-
- /* If the erase operation is completed, disable the MER Bit */
- CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
- CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
- }
- }
- else if (pEraseInit->Banks == FLASH_BANK_2)
- {
- /* Mass Erase requested for Bank2 */
- /* Wait for last operation to be completed */
- if (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
- {
- /*Mass erase to be done*/
- FLASH_MassErase(FLASH_BANK_2);
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
-
- /* If the erase operation is completed, disable the MER Bit */
- CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
- }
- }
- else
-#endif /* FLASH_BANK2_END */
- {
- /* Mass Erase requested for Bank1 */
- /* Wait for last operation to be completed */
- if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
- {
- /*Mass erase to be done*/
- FLASH_MassErase(FLASH_BANK_1);
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-
- /* If the erase operation is completed, disable the MER Bit */
- CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
- }
- }
- }
- else
- {
- /* Page Erase is requested */
- /* Check the parameters */
- assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
- assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));
-
-#if defined(FLASH_BANK2_END)
- /* Page Erase requested on address located on bank2 */
- if(pEraseInit->PageAddress > FLASH_BANK1_END)
- {
- /* Wait for last operation to be completed */
- if (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
- {
- /*Initialization of PageError variable*/
- *PageError = 0xFFFFFFFFU;
-
- /* Erase by page by page to be done*/
- for(address = pEraseInit->PageAddress;
- address < (pEraseInit->PageAddress + (pEraseInit->NbPages)*FLASH_PAGE_SIZE);
- address += FLASH_PAGE_SIZE)
- {
- FLASH_PageErase(address);
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
-
- /* If the erase operation is completed, disable the PER Bit */
- CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER);
-
- if (status != HAL_OK)
- {
- /* In case of error, stop erase procedure and return the faulty address */
- *PageError = address;
- break;
- }
- }
- }
- }
- else
-#endif /* FLASH_BANK2_END */
- {
- /* Page Erase requested on address located on bank1 */
- /* Wait for last operation to be completed */
- if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
- {
- /*Initialization of PageError variable*/
- *PageError = 0xFFFFFFFFU;
-
- /* Erase page by page to be done*/
- for(address = pEraseInit->PageAddress;
- address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress);
- address += FLASH_PAGE_SIZE)
- {
- FLASH_PageErase(address);
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-
- /* If the erase operation is completed, disable the PER Bit */
- CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
-
- if (status != HAL_OK)
- {
- /* In case of error, stop erase procedure and return the faulty address */
- *PageError = address;
- break;
- }
- }
- }
- }
- }
-
- /* Process Unlocked */
- __HAL_UNLOCK(&pFlash);
-
- return status;
-}
-
-/**
- * @brief Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled
- * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function
- * must be called before.
- * Call the @ref HAL_FLASH_Lock() to disable the flash memory access
- * (recommended to protect the FLASH memory against possible unwanted operation)
- * @param pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
- * contains the configuration information for the erasing.
- *
- * @retval HAL_StatusTypeDef HAL Status
- */
-HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
-{
- HAL_StatusTypeDef status = HAL_OK;
-
- /* Process Locked */
- __HAL_LOCK(&pFlash);
-
- /* If procedure already ongoing, reject the next one */
- if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
-
- /* Enable End of FLASH Operation and Error source interrupts */
- __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
-
-#if defined(FLASH_BANK2_END)
- /* Enable End of FLASH Operation and Error source interrupts */
- __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
-
-#endif
- if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
- {
- /*Mass erase to be done*/
- pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE;
- FLASH_MassErase(pEraseInit->Banks);
- }
- else
- {
- /* Erase by page to be done*/
-
- /* Check the parameters */
- assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
- assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));
-
- pFlash.ProcedureOnGoing = FLASH_PROC_PAGEERASE;
- pFlash.DataRemaining = pEraseInit->NbPages;
- pFlash.Address = pEraseInit->PageAddress;
-
- /*Erase 1st page and wait for IT*/
- FLASH_PageErase(pEraseInit->PageAddress);
- }
-
- return status;
-}
-
-/**
- * @}
- */
-
-/** @defgroup FLASHEx_Exported_Functions_Group2 Option Bytes Programming functions
- * @brief Option Bytes Programming functions
- *
-@verbatim
- ==============================================================================
- ##### Option Bytes Programming functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to control the FLASH
- option bytes operations.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Erases the FLASH option bytes.
- * @note This functions erases all option bytes except the Read protection (RDP).
- * The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
- * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
- * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
- * (system reset will occur)
- * @retval HAL status
- */
-
-HAL_StatusTypeDef HAL_FLASHEx_OBErase(void)
-{
- uint8_t rdptmp = OB_RDP_LEVEL_0;
- HAL_StatusTypeDef status = HAL_ERROR;
-
- /* Get the actual read protection Option Byte value */
- rdptmp = FLASH_OB_GetRDP();
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-
- if(status == HAL_OK)
- {
- /* Clean the error context */
- pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
-
- /* If the previous operation is completed, proceed to erase the option bytes */
- SET_BIT(FLASH->CR, FLASH_CR_OPTER);
- SET_BIT(FLASH->CR, FLASH_CR_STRT);
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-
- /* If the erase operation is completed, disable the OPTER Bit */
- CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER);
-
- if(status == HAL_OK)
- {
- /* Restore the last read protection Option Byte value */
- status = FLASH_OB_RDP_LevelConfig(rdptmp);
- }
- }
-
- /* Return the erase status */
- return status;
-}
-
-/**
- * @brief Program option bytes
- * @note The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
- * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
- * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
- * (system reset will occur)
- *
- * @param pOBInit pointer to an FLASH_OBInitStruct structure that
- * contains the configuration information for the programming.
- *
- * @retval HAL_StatusTypeDef HAL Status
- */
-HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
-{
- HAL_StatusTypeDef status = HAL_ERROR;
-
- /* Process Locked */
- __HAL_LOCK(&pFlash);
-
- /* Check the parameters */
- assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
-
- /* Write protection configuration */
- if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
- {
- assert_param(IS_WRPSTATE(pOBInit->WRPState));
- if (pOBInit->WRPState == OB_WRPSTATE_ENABLE)
- {
- /* Enable of Write protection on the selected page */
- status = FLASH_OB_EnableWRP(pOBInit->WRPPage);
- }
- else
- {
- /* Disable of Write protection on the selected page */
- status = FLASH_OB_DisableWRP(pOBInit->WRPPage);
- }
- if (status != HAL_OK)
- {
- /* Process Unlocked */
- __HAL_UNLOCK(&pFlash);
- return status;
- }
- }
-
- /* Read protection configuration */
- if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP)
- {
- status = FLASH_OB_RDP_LevelConfig(pOBInit->RDPLevel);
- if (status != HAL_OK)
- {
- /* Process Unlocked */
- __HAL_UNLOCK(&pFlash);
- return status;
- }
- }
-
- /* USER configuration */
- if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER)
- {
- status = FLASH_OB_UserConfig(pOBInit->USERConfig);
- if (status != HAL_OK)
- {
- /* Process Unlocked */
- __HAL_UNLOCK(&pFlash);
- return status;
- }
- }
-
- /* DATA configuration*/
- if((pOBInit->OptionType & OPTIONBYTE_DATA) == OPTIONBYTE_DATA)
- {
- status = FLASH_OB_ProgramData(pOBInit->DATAAddress, pOBInit->DATAData);
- if (status != HAL_OK)
- {
- /* Process Unlocked */
- __HAL_UNLOCK(&pFlash);
- return status;
- }
- }
-
- /* Process Unlocked */
- __HAL_UNLOCK(&pFlash);
-
- return status;
-}
-
-/**
- * @brief Get the Option byte configuration
- * @param pOBInit pointer to an FLASH_OBInitStruct structure that
- * contains the configuration information for the programming.
- *
- * @retval None
- */
-void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
-{
- pOBInit->OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER;
-
- /*Get WRP*/
- pOBInit->WRPPage = FLASH_OB_GetWRP();
-
- /*Get RDP Level*/
- pOBInit->RDPLevel = FLASH_OB_GetRDP();
-
- /*Get USER*/
- pOBInit->USERConfig = FLASH_OB_GetUser();
-}
-
-/**
- * @brief Get the Option byte user data
- * @param DATAAdress Address of the option byte DATA
- * This parameter can be one of the following values:
- * @arg @ref OB_DATA_ADDRESS_DATA0
- * @arg @ref OB_DATA_ADDRESS_DATA1
- * @retval Value programmed in USER data
- */
-uint32_t HAL_FLASHEx_OBGetUserData(uint32_t DATAAdress)
-{
- uint32_t value = 0;
-
- if (DATAAdress == OB_DATA_ADDRESS_DATA0)
- {
- /* Get value programmed in OB USER Data0 */
- value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA0) >> FLASH_POSITION_OB_USERDATA0_BIT;
- }
- else
- {
- /* Get value programmed in OB USER Data1 */
- value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA1) >> FLASH_POSITION_OB_USERDATA1_BIT;
- }
-
- return value;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup FLASHEx_Private_Functions
- * @{
- */
-
-/**
- * @brief Full erase of FLASH memory Bank
- * @param Banks Banks to be erased
- * This parameter can be one of the following values:
- * @arg @ref FLASH_BANK_1 Bank1 to be erased
- @if STM32F101xG
- * @arg @ref FLASH_BANK_2 Bank2 to be erased
- * @arg @ref FLASH_BANK_BOTH Bank1 and Bank2 to be erased
- @endif
- @if STM32F103xG
- * @arg @ref FLASH_BANK_2 Bank2 to be erased
- * @arg @ref FLASH_BANK_BOTH Bank1 and Bank2 to be erased
- @endif
- *
- * @retval None
- */
-static void FLASH_MassErase(uint32_t Banks)
-{
- /* Check the parameters */
- assert_param(IS_FLASH_BANK(Banks));
-
- /* Clean the error context */
- pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
-
-#if defined(FLASH_BANK2_END)
- if(Banks == FLASH_BANK_BOTH)
- {
- /* bank1 & bank2 will be erased*/
- SET_BIT(FLASH->CR, FLASH_CR_MER);
- SET_BIT(FLASH->CR2, FLASH_CR2_MER);
- SET_BIT(FLASH->CR, FLASH_CR_STRT);
- SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
- }
- else if(Banks == FLASH_BANK_2)
- {
- /*Only bank2 will be erased*/
- SET_BIT(FLASH->CR2, FLASH_CR2_MER);
- SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
- }
- else
- {
-#endif /* FLASH_BANK2_END */
-#if !defined(FLASH_BANK2_END)
- /* Prevent unused argument(s) compilation warning */
- UNUSED(Banks);
-#endif /* FLASH_BANK2_END */
- /* Only bank1 will be erased*/
- SET_BIT(FLASH->CR, FLASH_CR_MER);
- SET_BIT(FLASH->CR, FLASH_CR_STRT);
-#if defined(FLASH_BANK2_END)
- }
-#endif /* FLASH_BANK2_END */
-}
-
-/**
- * @brief Enable the write protection of the desired pages
- * @note An option byte erase is done automatically in this function.
- * @note When the memory read protection level is selected (RDP level = 1),
- * it is not possible to program or erase the flash page i if
- * debug features are connected or boot code is executed in RAM, even if nWRPi = 1
- *
- * @param WriteProtectPage specifies the page(s) to be write protected.
- * The value of this parameter depend on device used within the same series
- * @retval HAL status
- */
-static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WriteProtectPage)
-{
- HAL_StatusTypeDef status = HAL_OK;
- uint16_t WRP0_Data = 0xFFFF;
-#if defined(FLASH_WRP1_WRP1)
- uint16_t WRP1_Data = 0xFFFF;
-#endif /* FLASH_WRP1_WRP1 */
-#if defined(FLASH_WRP2_WRP2)
- uint16_t WRP2_Data = 0xFFFF;
-#endif /* FLASH_WRP2_WRP2 */
-#if defined(FLASH_WRP3_WRP3)
- uint16_t WRP3_Data = 0xFFFF;
-#endif /* FLASH_WRP3_WRP3 */
-
- /* Check the parameters */
- assert_param(IS_OB_WRP(WriteProtectPage));
-
- /* Get current write protected pages and the new pages to be protected ******/
- WriteProtectPage = (uint32_t)(~((~FLASH_OB_GetWRP()) | WriteProtectPage));
-
-#if defined(OB_WRP_PAGES0TO15MASK)
- WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK);
-#elif defined(OB_WRP_PAGES0TO31MASK)
- WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK);
-#endif /* OB_WRP_PAGES0TO31MASK */
-
-#if defined(OB_WRP_PAGES16TO31MASK)
- WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8U);
-#elif defined(OB_WRP_PAGES32TO63MASK)
- WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8U);
-#endif /* OB_WRP_PAGES32TO63MASK */
-
-#if defined(OB_WRP_PAGES64TO95MASK)
- WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16U);
-#endif /* OB_WRP_PAGES64TO95MASK */
-#if defined(OB_WRP_PAGES32TO47MASK)
- WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16U);
-#endif /* OB_WRP_PAGES32TO47MASK */
-
-#if defined(OB_WRP_PAGES96TO127MASK)
- WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24U);
-#elif defined(OB_WRP_PAGES48TO255MASK)
- WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24U);
-#elif defined(OB_WRP_PAGES48TO511MASK)
- WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO511MASK) >> 24U);
-#elif defined(OB_WRP_PAGES48TO127MASK)
- WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24U);
-#endif /* OB_WRP_PAGES96TO127MASK */
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-
- if(status == HAL_OK)
- {
- /* Clean the error context */
- pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
-
- /* To be able to write again option byte, need to perform a option byte erase */
- status = HAL_FLASHEx_OBErase();
- if (status == HAL_OK)
- {
- /* Enable write protection */
- SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
-
-#if defined(FLASH_WRP0_WRP0)
- if(WRP0_Data != 0xFFU)
- {
- OB->WRP0 &= WRP0_Data;
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
- }
-#endif /* FLASH_WRP0_WRP0 */
-
-#if defined(FLASH_WRP1_WRP1)
- if((status == HAL_OK) && (WRP1_Data != 0xFFU))
- {
- OB->WRP1 &= WRP1_Data;
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
- }
-#endif /* FLASH_WRP1_WRP1 */
-
-#if defined(FLASH_WRP2_WRP2)
- if((status == HAL_OK) && (WRP2_Data != 0xFFU))
- {
- OB->WRP2 &= WRP2_Data;
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
- }
-#endif /* FLASH_WRP2_WRP2 */
-
-#if defined(FLASH_WRP3_WRP3)
- if((status == HAL_OK) && (WRP3_Data != 0xFFU))
- {
- OB->WRP3 &= WRP3_Data;
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
- }
-#endif /* FLASH_WRP3_WRP3 */
-
- /* if the program operation is completed, disable the OPTPG Bit */
- CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
- }
- }
-
- return status;
-}
-
-/**
- * @brief Disable the write protection of the desired pages
- * @note An option byte erase is done automatically in this function.
- * @note When the memory read protection level is selected (RDP level = 1),
- * it is not possible to program or erase the flash page i if
- * debug features are connected or boot code is executed in RAM, even if nWRPi = 1
- *
- * @param WriteProtectPage specifies the page(s) to be write unprotected.
- * The value of this parameter depend on device used within the same series
- * @retval HAL status
- */
-static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WriteProtectPage)
-{
- HAL_StatusTypeDef status = HAL_OK;
- uint16_t WRP0_Data = 0xFFFF;
-#if defined(FLASH_WRP1_WRP1)
- uint16_t WRP1_Data = 0xFFFF;
-#endif /* FLASH_WRP1_WRP1 */
-#if defined(FLASH_WRP2_WRP2)
- uint16_t WRP2_Data = 0xFFFF;
-#endif /* FLASH_WRP2_WRP2 */
-#if defined(FLASH_WRP3_WRP3)
- uint16_t WRP3_Data = 0xFFFF;
-#endif /* FLASH_WRP3_WRP3 */
-
- /* Check the parameters */
- assert_param(IS_OB_WRP(WriteProtectPage));
-
- /* Get current write protected pages and the new pages to be unprotected ******/
- WriteProtectPage = (FLASH_OB_GetWRP() | WriteProtectPage);
-
-#if defined(OB_WRP_PAGES0TO15MASK)
- WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK);
-#elif defined(OB_WRP_PAGES0TO31MASK)
- WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK);
-#endif /* OB_WRP_PAGES0TO31MASK */
-
-#if defined(OB_WRP_PAGES16TO31MASK)
- WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8U);
-#elif defined(OB_WRP_PAGES32TO63MASK)
- WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8U);
-#endif /* OB_WRP_PAGES32TO63MASK */
-
-#if defined(OB_WRP_PAGES64TO95MASK)
- WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16U);
-#endif /* OB_WRP_PAGES64TO95MASK */
-#if defined(OB_WRP_PAGES32TO47MASK)
- WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16U);
-#endif /* OB_WRP_PAGES32TO47MASK */
-
-#if defined(OB_WRP_PAGES96TO127MASK)
- WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24U);
-#elif defined(OB_WRP_PAGES48TO255MASK)
- WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24U);
-#elif defined(OB_WRP_PAGES48TO511MASK)
- WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO511MASK) >> 24U);
-#elif defined(OB_WRP_PAGES48TO127MASK)
- WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24U);
-#endif /* OB_WRP_PAGES96TO127MASK */
-
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-
- if(status == HAL_OK)
- {
- /* Clean the error context */
- pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
-
- /* To be able to write again option byte, need to perform a option byte erase */
- status = HAL_FLASHEx_OBErase();
- if (status == HAL_OK)
- {
- SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
-
-#if defined(FLASH_WRP0_WRP0)
- if(WRP0_Data != 0xFFU)
- {
- OB->WRP0 |= WRP0_Data;
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
- }
-#endif /* FLASH_WRP0_WRP0 */
-
-#if defined(FLASH_WRP1_WRP1)
- if((status == HAL_OK) && (WRP1_Data != 0xFFU))
- {
- OB->WRP1 |= WRP1_Data;
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
- }
-#endif /* FLASH_WRP1_WRP1 */
-
-#if defined(FLASH_WRP2_WRP2)
- if((status == HAL_OK) && (WRP2_Data != 0xFFU))
- {
- OB->WRP2 |= WRP2_Data;
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
- }
-#endif /* FLASH_WRP2_WRP2 */
-
-#if defined(FLASH_WRP3_WRP3)
- if((status == HAL_OK) && (WRP3_Data != 0xFFU))
- {
- OB->WRP3 |= WRP3_Data;
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
- }
-#endif /* FLASH_WRP3_WRP3 */
-
- /* if the program operation is completed, disable the OPTPG Bit */
- CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
- }
- }
- return status;
-}
-
-/**
- * @brief Set the read protection level.
- * @param ReadProtectLevel specifies the read protection level.
- * This parameter can be one of the following values:
- * @arg @ref OB_RDP_LEVEL_0 No protection
- * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
- * @retval HAL status
- */
-static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel)
-{
- HAL_StatusTypeDef status = HAL_OK;
-
- /* Check the parameters */
- assert_param(IS_OB_RDP_LEVEL(ReadProtectLevel));
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-
- if(status == HAL_OK)
- {
- /* Clean the error context */
- pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
-
- /* If the previous operation is completed, proceed to erase the option bytes */
- SET_BIT(FLASH->CR, FLASH_CR_OPTER);
- SET_BIT(FLASH->CR, FLASH_CR_STRT);
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-
- /* If the erase operation is completed, disable the OPTER Bit */
- CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER);
-
- if(status == HAL_OK)
- {
- /* Enable the Option Bytes Programming operation */
- SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
-
- WRITE_REG(OB->RDP, ReadProtectLevel);
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-
- /* if the program operation is completed, disable the OPTPG Bit */
- CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
- }
- }
-
- return status;
-}
-
-/**
- * @brief Program the FLASH User Option Byte.
- * @note Programming of the OB should be performed only after an erase (otherwise PGERR occurs)
- * @param UserConfig The FLASH User Option Bytes values FLASH_OBR_IWDG_SW(Bit2),
- * FLASH_OBR_nRST_STOP(Bit3),FLASH_OBR_nRST_STDBY(Bit4).
- * And BFBF2(Bit5) for STM32F101xG and STM32F103xG .
- * @retval HAL status
- */
-static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig)
-{
- HAL_StatusTypeDef status = HAL_OK;
-
- /* Check the parameters */
- assert_param(IS_OB_IWDG_SOURCE((UserConfig&OB_IWDG_SW)));
- assert_param(IS_OB_STOP_SOURCE((UserConfig&OB_STOP_NO_RST)));
- assert_param(IS_OB_STDBY_SOURCE((UserConfig&OB_STDBY_NO_RST)));
-#if defined(FLASH_BANK2_END)
- assert_param(IS_OB_BOOT1((UserConfig&OB_BOOT1_SET)));
-#endif /* FLASH_BANK2_END */
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-
- if(status == HAL_OK)
- {
- /* Clean the error context */
- pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
-
- /* Enable the Option Bytes Programming operation */
- SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
-
-#if defined(FLASH_BANK2_END)
- OB->USER = (UserConfig | 0xF0U);
-#else
- OB->USER = (UserConfig | 0x88U);
-#endif /* FLASH_BANK2_END */
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-
- /* if the program operation is completed, disable the OPTPG Bit */
- CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
- }
-
- return status;
-}
-
-/**
- * @brief Programs a half word at a specified Option Byte Data address.
- * @note The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
- * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
- * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
- * (system reset will occur)
- * Programming of the OB should be performed only after an erase (otherwise PGERR occurs)
- * @param Address specifies the address to be programmed.
- * This parameter can be 0x1FFFF804 or 0x1FFFF806.
- * @param Data specifies the data to be programmed.
- * @retval HAL status
- */
-static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data)
-{
- HAL_StatusTypeDef status = HAL_ERROR;
-
- /* Check the parameters */
- assert_param(IS_OB_DATA_ADDRESS(Address));
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-
- if(status == HAL_OK)
- {
- /* Clean the error context */
- pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
-
- /* Enables the Option Bytes Programming operation */
- SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
- *(__IO uint16_t*)Address = Data;
-
- /* Wait for last operation to be completed */
- status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
-
- /* If the program operation is completed, disable the OPTPG Bit */
- CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
- }
- /* Return the Option Byte Data Program Status */
- return status;
-}
-
-/**
- * @brief Return the FLASH Write Protection Option Bytes value.
- * @retval The FLASH Write Protection Option Bytes value
- */
-static uint32_t FLASH_OB_GetWRP(void)
-{
- /* Return the FLASH write protection Register value */
- return (uint32_t)(READ_REG(FLASH->WRPR));
-}
-
-/**
- * @brief Returns the FLASH Read Protection level.
- * @retval FLASH RDP level
- * This parameter can be one of the following values:
- * @arg @ref OB_RDP_LEVEL_0 No protection
- * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
- */
-static uint32_t FLASH_OB_GetRDP(void)
-{
- uint32_t readstatus = OB_RDP_LEVEL_0;
- uint32_t tmp_reg = 0U;
-
- /* Read RDP level bits */
- tmp_reg = READ_BIT(FLASH->OBR, FLASH_OBR_RDPRT);
-
- if (tmp_reg == FLASH_OBR_RDPRT)
- {
- readstatus = OB_RDP_LEVEL_1;
- }
- else
- {
- readstatus = OB_RDP_LEVEL_0;
- }
-
- return readstatus;
-}
-
-/**
- * @brief Return the FLASH User Option Byte value.
- * @retval The FLASH User Option Bytes values: FLASH_OBR_IWDG_SW(Bit2),
- * FLASH_OBR_nRST_STOP(Bit3),FLASH_OBR_nRST_STDBY(Bit4).
- * And FLASH_OBR_BFB2(Bit5) for STM32F101xG and STM32F103xG .
- */
-static uint8_t FLASH_OB_GetUser(void)
-{
- /* Return the User Option Byte */
- return (uint8_t)((READ_REG(FLASH->OBR) & FLASH_OBR_USER) >> FLASH_POSITION_IWDGSW_BIT);
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup FLASH
- * @{
- */
-
-/** @addtogroup FLASH_Private_Functions
- * @{
- */
-
-/**
- * @brief Erase the specified FLASH memory page
- * @param PageAddress FLASH page to erase
- * The value of this parameter depend on device used within the same series
- *
- * @retval None
- */
-void FLASH_PageErase(uint32_t PageAddress)
-{
- /* Clean the error context */
- pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
-
-#if defined(FLASH_BANK2_END)
- if(PageAddress > FLASH_BANK1_END)
- {
- /* Proceed to erase the page */
- SET_BIT(FLASH->CR2, FLASH_CR2_PER);
- WRITE_REG(FLASH->AR2, PageAddress);
- SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
- }
- else
- {
-#endif /* FLASH_BANK2_END */
- /* Proceed to erase the page */
- SET_BIT(FLASH->CR, FLASH_CR_PER);
- WRITE_REG(FLASH->AR, PageAddress);
- SET_BIT(FLASH->CR, FLASH_CR_STRT);
-#if defined(FLASH_BANK2_END)
- }
-#endif /* FLASH_BANK2_END */
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* HAL_FLASH_MODULE_ENABLED */
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c
deleted file mode 100644
index 2d56951..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_gpio.c
- * @author MCD Application Team
- * @brief GPIO HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the General Purpose Input/Output (GPIO) peripheral:
- * + Initialization and de-initialization functions
- * + IO operation functions
- *
- @verbatim
- ==============================================================================
- ##### GPIO Peripheral features #####
- ==============================================================================
- [..]
- Subject to the specific hardware characteristics of each I/O port listed in the datasheet, each
- port bit of the General Purpose IO (GPIO) Ports, can be individually configured by software
- in several modes:
- (+) Input mode
- (+) Analog mode
- (+) Output mode
- (+) Alternate function mode
- (+) External interrupt/event lines
-
- [..]
- During and just after reset, the alternate functions and external interrupt
- lines are not active and the I/O ports are configured in input floating mode.
-
- [..]
- All GPIO pins have weak internal pull-up and pull-down resistors, which can be
- activated or not.
-
- [..]
- In Output or Alternate mode, each IO can be configured on open-drain or push-pull
- type and the IO speed can be selected depending on the VDD value.
-
- [..]
- All ports have external interrupt/event capability. To use external interrupt
- lines, the port must be configured in input mode. All available GPIO pins are
- connected to the 16 external interrupt/event lines from EXTI0 to EXTI15.
-
- [..]
- The external interrupt/event controller consists of up to 20 edge detectors in connectivity
- line devices, or 19 edge detectors in other devices for generating event/interrupt requests.
- Each input line can be independently configured to select the type (event or interrupt) and
- the corresponding trigger event (rising or falling or both). Each line can also masked
- independently. A pending register maintains the status line of the interrupt requests
-
- ##### How to use this driver #####
- ==============================================================================
- [..]
- (#) Enable the GPIO APB2 clock using the following function : __HAL_RCC_GPIOx_CLK_ENABLE().
-
- (#) Configure the GPIO pin(s) using HAL_GPIO_Init().
- (++) Configure the IO mode using "Mode" member from GPIO_InitTypeDef structure
- (++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef
- structure.
- (++) In case of Output or alternate function mode selection: the speed is
- configured through "Speed" member from GPIO_InitTypeDef structure
- (++) Analog mode is required when a pin is to be used as ADC channel
- or DAC output.
- (++) In case of external interrupt/event selection the "Mode" member from
- GPIO_InitTypeDef structure select the type (interrupt or event) and
- the corresponding trigger event (rising or falling or both).
-
- (#) In case of external interrupt/event mode selection, configure NVIC IRQ priority
- mapped to the EXTI line using HAL_NVIC_SetPriority() and enable it using
- HAL_NVIC_EnableIRQ().
-
- (#) To get the level of a pin configured in input mode use HAL_GPIO_ReadPin().
-
- (#) To set/reset the level of a pin configured in output mode use
- HAL_GPIO_WritePin()/HAL_GPIO_TogglePin().
-
- (#) To lock pin configuration until next reset use HAL_GPIO_LockPin().
-
- (#) During and just after reset, the alternate functions are not
- active and the GPIO pins are configured in input floating mode (except JTAG
- pins).
-
- (#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose
- (PC14 and PC15, respectively) when the LSE oscillator is off. The LSE has
- priority over the GPIO function.
-
- (#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as
- general purpose PD0 and PD1, respectively, when the HSE oscillator is off.
- The HSE has priority over the GPIO function.
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup GPIO GPIO
- * @brief GPIO HAL module driver
- * @{
- */
-
-#ifdef HAL_GPIO_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @addtogroup GPIO_Private_Constants GPIO Private Constants
- * @{
- */
-#define GPIO_MODE 0x00000003U
-#define EXTI_MODE 0x10000000U
-#define GPIO_MODE_IT 0x00010000U
-#define GPIO_MODE_EVT 0x00020000U
-#define RISING_EDGE 0x00100000U
-#define FALLING_EDGE 0x00200000U
-#define GPIO_OUTPUT_TYPE 0x00000010U
-
-#define GPIO_NUMBER 16U
-
-/* Definitions for bit manipulation of CRL and CRH register */
-#define GPIO_CR_MODE_INPUT 0x00000000U /*!< 00: Input mode (reset state) */
-#define GPIO_CR_CNF_ANALOG 0x00000000U /*!< 00: Analog mode */
-#define GPIO_CR_CNF_INPUT_FLOATING 0x00000004U /*!< 01: Floating input (reset state) */
-#define GPIO_CR_CNF_INPUT_PU_PD 0x00000008U /*!< 10: Input with pull-up / pull-down */
-#define GPIO_CR_CNF_GP_OUTPUT_PP 0x00000000U /*!< 00: General purpose output push-pull */
-#define GPIO_CR_CNF_GP_OUTPUT_OD 0x00000004U /*!< 01: General purpose output Open-drain */
-#define GPIO_CR_CNF_AF_OUTPUT_PP 0x00000008U /*!< 10: Alternate function output Push-pull */
-#define GPIO_CR_CNF_AF_OUTPUT_OD 0x0000000CU /*!< 11: Alternate function output Open-drain */
-
-/**
- * @}
- */
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup GPIO_Exported_Functions GPIO Exported Functions
- * @{
- */
-
-/** @defgroup GPIO_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
- ===============================================================================
- ##### Initialization and de-initialization functions #####
- ===============================================================================
- [..]
- This section provides functions allowing to initialize and de-initialize the GPIOs
- to be ready for use.
-
-@endverbatim
- * @{
- */
-
-
-/**
- * @brief Initializes the GPIOx peripheral according to the specified parameters in the GPIO_Init.
- * @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
- * @param GPIO_Init: pointer to a GPIO_InitTypeDef structure that contains
- * the configuration information for the specified GPIO peripheral.
- * @retval None
- */
-void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
-{
- uint32_t position;
- uint32_t ioposition = 0x00U;
- uint32_t iocurrent = 0x00U;
- uint32_t temp = 0x00U;
- uint32_t config = 0x00U;
- __IO uint32_t *configregister; /* Store the address of CRL or CRH register based on pin number */
- uint32_t registeroffset = 0U; /* offset used during computation of CNF and MODE bits placement inside CRL or CRH register */
-
- /* Check the parameters */
- assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
- assert_param(IS_GPIO_PIN(GPIO_Init->Pin));
- assert_param(IS_GPIO_MODE(GPIO_Init->Mode));
-
- /* Configure the port pins */
- for (position = 0U; position < GPIO_NUMBER; position++)
- {
- /* Get the IO position */
- ioposition = (0x01U << position);
-
- /* Get the current IO position */
- iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition;
-
- if (iocurrent == ioposition)
- {
- /* Check the Alternate function parameters */
- assert_param(IS_GPIO_AF_INSTANCE(GPIOx));
-
- /* Based on the required mode, filling config variable with MODEy[1:0] and CNFy[3:2] corresponding bits */
- switch (GPIO_Init->Mode)
- {
- /* If we are configuring the pin in OUTPUT push-pull mode */
- case GPIO_MODE_OUTPUT_PP:
- /* Check the GPIO speed parameter */
- assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
- config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_PP;
- break;
-
- /* If we are configuring the pin in OUTPUT open-drain mode */
- case GPIO_MODE_OUTPUT_OD:
- /* Check the GPIO speed parameter */
- assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
- config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_OD;
- break;
-
- /* If we are configuring the pin in ALTERNATE FUNCTION push-pull mode */
- case GPIO_MODE_AF_PP:
- /* Check the GPIO speed parameter */
- assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
- config = GPIO_Init->Speed + GPIO_CR_CNF_AF_OUTPUT_PP;
- break;
-
- /* If we are configuring the pin in ALTERNATE FUNCTION open-drain mode */
- case GPIO_MODE_AF_OD:
- /* Check the GPIO speed parameter */
- assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
- config = GPIO_Init->Speed + GPIO_CR_CNF_AF_OUTPUT_OD;
- break;
-
- /* If we are configuring the pin in INPUT (also applicable to EVENT and IT mode) */
- case GPIO_MODE_INPUT:
- case GPIO_MODE_IT_RISING:
- case GPIO_MODE_IT_FALLING:
- case GPIO_MODE_IT_RISING_FALLING:
- case GPIO_MODE_EVT_RISING:
- case GPIO_MODE_EVT_FALLING:
- case GPIO_MODE_EVT_RISING_FALLING:
- /* Check the GPIO pull parameter */
- assert_param(IS_GPIO_PULL(GPIO_Init->Pull));
- if (GPIO_Init->Pull == GPIO_NOPULL)
- {
- config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_FLOATING;
- }
- else if (GPIO_Init->Pull == GPIO_PULLUP)
- {
- config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD;
-
- /* Set the corresponding ODR bit */
- GPIOx->BSRR = ioposition;
- }
- else /* GPIO_PULLDOWN */
- {
- config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD;
-
- /* Reset the corresponding ODR bit */
- GPIOx->BRR = ioposition;
- }
- break;
-
- /* If we are configuring the pin in INPUT analog mode */
- case GPIO_MODE_ANALOG:
- config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_ANALOG;
- break;
-
- /* Parameters are checked with assert_param */
- default:
- break;
- }
-
- /* Check if the current bit belongs to first half or last half of the pin count number
- in order to address CRH or CRL register*/
- configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL : &GPIOx->CRH;
- registeroffset = (iocurrent < GPIO_PIN_8) ? (position << 2U) : ((position - 8U) << 2U);
-
- /* Apply the new configuration of the pin to the register */
- MODIFY_REG((*configregister), ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << registeroffset), (config << registeroffset));
-
- /*--------------------- EXTI Mode Configuration ------------------------*/
- /* Configure the External Interrupt or event for the current IO */
- if ((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE)
- {
- /* Enable AFIO Clock */
- __HAL_RCC_AFIO_CLK_ENABLE();
- temp = AFIO->EXTICR[position >> 2U];
- CLEAR_BIT(temp, (0x0FU) << (4U * (position & 0x03U)));
- SET_BIT(temp, (GPIO_GET_INDEX(GPIOx)) << (4U * (position & 0x03U)));
- AFIO->EXTICR[position >> 2U] = temp;
-
-
- /* Configure the interrupt mask */
- if ((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT)
- {
- SET_BIT(EXTI->IMR, iocurrent);
- }
- else
- {
- CLEAR_BIT(EXTI->IMR, iocurrent);
- }
-
- /* Configure the event mask */
- if ((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT)
- {
- SET_BIT(EXTI->EMR, iocurrent);
- }
- else
- {
- CLEAR_BIT(EXTI->EMR, iocurrent);
- }
-
- /* Enable or disable the rising trigger */
- if ((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE)
- {
- SET_BIT(EXTI->RTSR, iocurrent);
- }
- else
- {
- CLEAR_BIT(EXTI->RTSR, iocurrent);
- }
-
- /* Enable or disable the falling trigger */
- if ((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE)
- {
- SET_BIT(EXTI->FTSR, iocurrent);
- }
- else
- {
- CLEAR_BIT(EXTI->FTSR, iocurrent);
- }
- }
- }
- }
-}
-
-/**
- * @brief De-initializes the GPIOx peripheral registers to their default reset values.
- * @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
- * @param GPIO_Pin: specifies the port bit to be written.
- * This parameter can be one of GPIO_PIN_x where x can be (0..15).
- * @retval None
- */
-void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
-{
- uint32_t position = 0x00U;
- uint32_t iocurrent = 0x00U;
- uint32_t tmp = 0x00U;
- __IO uint32_t *configregister; /* Store the address of CRL or CRH register based on pin number */
- uint32_t registeroffset = 0U;
-
- /* Check the parameters */
- assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
- assert_param(IS_GPIO_PIN(GPIO_Pin));
-
- /* Configure the port pins */
- while ((GPIO_Pin >> position) != 0U)
- {
- /* Get current io position */
- iocurrent = (GPIO_Pin) & (1U << position);
-
- if (iocurrent)
- {
- /*------------------------- GPIO Mode Configuration --------------------*/
- /* Check if the current bit belongs to first half or last half of the pin count number
- in order to address CRH or CRL register */
- configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL : &GPIOx->CRH;
- registeroffset = (iocurrent < GPIO_PIN_8) ? (position << 2U) : ((position - 8U) << 2U);
-
- /* CRL/CRH default value is floating input(0x04) shifted to correct position */
- MODIFY_REG(*configregister, ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << registeroffset), GPIO_CRL_CNF0_0 << registeroffset);
-
- /* ODR default value is 0 */
- CLEAR_BIT(GPIOx->ODR, iocurrent);
-
- /*------------------------- EXTI Mode Configuration --------------------*/
- /* Clear the External Interrupt or Event for the current IO */
-
- tmp = AFIO->EXTICR[position >> 2U];
- tmp &= 0x0FU << (4U * (position & 0x03U));
- if (tmp == (GPIO_GET_INDEX(GPIOx) << (4U * (position & 0x03U))))
- {
- tmp = 0x0FU << (4U * (position & 0x03U));
- CLEAR_BIT(AFIO->EXTICR[position >> 2U], tmp);
-
- /* Clear EXTI line configuration */
- CLEAR_BIT(EXTI->IMR, (uint32_t)iocurrent);
- CLEAR_BIT(EXTI->EMR, (uint32_t)iocurrent);
-
- /* Clear Rising Falling edge configuration */
- CLEAR_BIT(EXTI->RTSR, (uint32_t)iocurrent);
- CLEAR_BIT(EXTI->FTSR, (uint32_t)iocurrent);
- }
- }
-
- position++;
- }
-}
-
-/**
- * @}
- */
-
-/** @defgroup GPIO_Exported_Functions_Group2 IO operation functions
- * @brief GPIO Read and Write
- *
-@verbatim
- ===============================================================================
- ##### IO operation functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to manage the GPIOs.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Reads the specified input port pin.
- * @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
- * @param GPIO_Pin: specifies the port bit to read.
- * This parameter can be GPIO_PIN_x where x can be (0..15).
- * @retval The input port pin value.
- */
-GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
-{
- GPIO_PinState bitstatus;
-
- /* Check the parameters */
- assert_param(IS_GPIO_PIN(GPIO_Pin));
-
- if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET)
- {
- bitstatus = GPIO_PIN_SET;
- }
- else
- {
- bitstatus = GPIO_PIN_RESET;
- }
- return bitstatus;
-}
-
-/**
- * @brief Sets or clears the selected data port bit.
- *
- * @note This function uses GPIOx_BSRR register to allow atomic read/modify
- * accesses. In this way, there is no risk of an IRQ occurring between
- * the read and the modify access.
- *
- * @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
- * @param GPIO_Pin: specifies the port bit to be written.
- * This parameter can be one of GPIO_PIN_x where x can be (0..15).
- * @param PinState: specifies the value to be written to the selected bit.
- * This parameter can be one of the GPIO_PinState enum values:
- * @arg GPIO_PIN_RESET: to clear the port pin
- * @arg GPIO_PIN_SET: to set the port pin
- * @retval None
- */
-void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
-{
- /* Check the parameters */
- assert_param(IS_GPIO_PIN(GPIO_Pin));
- assert_param(IS_GPIO_PIN_ACTION(PinState));
-
- if (PinState != GPIO_PIN_RESET)
- {
- GPIOx->BSRR = GPIO_Pin;
- }
- else
- {
- GPIOx->BSRR = (uint32_t)GPIO_Pin << 16U;
- }
-}
-
-/**
- * @brief Toggles the specified GPIO pin
- * @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
- * @param GPIO_Pin: Specifies the pins to be toggled.
- * @retval None
- */
-void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
-{
- /* Check the parameters */
- assert_param(IS_GPIO_PIN(GPIO_Pin));
-
- GPIOx->ODR ^= GPIO_Pin;
-}
-
-/**
-* @brief Locks GPIO Pins configuration registers.
-* @note The locking mechanism allows the IO configuration to be frozen. When the LOCK sequence
-* has been applied on a port bit, it is no longer possible to modify the value of the port bit until
-* the next reset.
-* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
-* @param GPIO_Pin: specifies the port bit to be locked.
-* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
-* @retval None
-*/
-HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
-{
- __IO uint32_t tmp = GPIO_LCKR_LCKK;
-
- /* Check the parameters */
- assert_param(IS_GPIO_LOCK_INSTANCE(GPIOx));
- assert_param(IS_GPIO_PIN(GPIO_Pin));
-
- /* Apply lock key write sequence */
- SET_BIT(tmp, GPIO_Pin);
- /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
- GPIOx->LCKR = tmp;
- /* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */
- GPIOx->LCKR = GPIO_Pin;
- /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
- GPIOx->LCKR = tmp;
- /* Read LCKK bit*/
- tmp = GPIOx->LCKR;
-
- if ((uint32_t)(GPIOx->LCKR & GPIO_LCKR_LCKK))
- {
- return HAL_OK;
- }
- else
- {
- return HAL_ERROR;
- }
-}
-
-/**
- * @brief This function handles EXTI interrupt request.
- * @param GPIO_Pin: Specifies the pins connected EXTI line
- * @retval None
- */
-void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
-{
- /* EXTI line interrupt detected */
- if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
- {
- __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
- HAL_GPIO_EXTI_Callback(GPIO_Pin);
- }
-}
-
-/**
- * @brief EXTI line detection callbacks.
- * @param GPIO_Pin: Specifies the pins connected EXTI line
- * @retval None
- */
-__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(GPIO_Pin);
- /* NOTE: This function Should not be modified, when the callback is needed,
- the HAL_GPIO_EXTI_Callback could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* HAL_GPIO_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c
deleted file mode 100644
index 551333b..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_gpio_ex.c
- * @author MCD Application Team
- * @brief GPIO Extension HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the General Purpose Input/Output (GPIO) extension peripheral.
- * + Extended features functions
- *
- @verbatim
- ==============================================================================
- ##### GPIO Peripheral extension features #####
- ==============================================================================
- [..] GPIO module on STM32F1 family, manage also the AFIO register:
- (+) Possibility to use the EVENTOUT Cortex feature
-
- ##### How to use this driver #####
- ==============================================================================
- [..] This driver provides functions to use EVENTOUT Cortex feature
- (#) Configure EVENTOUT Cortex feature using the function HAL_GPIOEx_ConfigEventout()
- (#) Activate EVENTOUT Cortex feature using the HAL_GPIOEx_EnableEventout()
- (#) Deactivate EVENTOUT Cortex feature using the HAL_GPIOEx_DisableEventout()
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup GPIOEx GPIOEx
- * @brief GPIO HAL module driver
- * @{
- */
-
-#ifdef HAL_GPIO_MODULE_ENABLED
-
-/** @defgroup GPIOEx_Exported_Functions GPIOEx Exported Functions
- * @{
- */
-
-/** @defgroup GPIOEx_Exported_Functions_Group1 Extended features functions
- * @brief Extended features functions
- *
-@verbatim
- ==============================================================================
- ##### Extended features functions #####
- ==============================================================================
- [..] This section provides functions allowing to:
- (+) Configure EVENTOUT Cortex feature using the function HAL_GPIOEx_ConfigEventout()
- (+) Activate EVENTOUT Cortex feature using the HAL_GPIOEx_EnableEventout()
- (+) Deactivate EVENTOUT Cortex feature using the HAL_GPIOEx_DisableEventout()
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Configures the port and pin on which the EVENTOUT Cortex signal will be connected.
- * @param GPIO_PortSource Select the port used to output the Cortex EVENTOUT signal.
- * This parameter can be a value of @ref GPIOEx_EVENTOUT_PORT.
- * @param GPIO_PinSource Select the pin used to output the Cortex EVENTOUT signal.
- * This parameter can be a value of @ref GPIOEx_EVENTOUT_PIN.
- * @retval None
- */
-void HAL_GPIOEx_ConfigEventout(uint32_t GPIO_PortSource, uint32_t GPIO_PinSource)
-{
- /* Verify the parameters */
- assert_param(IS_AFIO_EVENTOUT_PORT(GPIO_PortSource));
- assert_param(IS_AFIO_EVENTOUT_PIN(GPIO_PinSource));
-
- /* Apply the new configuration */
- MODIFY_REG(AFIO->EVCR, (AFIO_EVCR_PORT) | (AFIO_EVCR_PIN), (GPIO_PortSource) | (GPIO_PinSource));
-}
-
-/**
- * @brief Enables the Event Output.
- * @retval None
- */
-void HAL_GPIOEx_EnableEventout(void)
-{
- SET_BIT(AFIO->EVCR, AFIO_EVCR_EVOE);
-}
-
-/**
- * @brief Disables the Event Output.
- * @retval None
- */
-void HAL_GPIOEx_DisableEventout(void)
-{
- CLEAR_BIT(AFIO->EVCR, AFIO_EVCR_EVOE);
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* HAL_GPIO_MODULE_ENABLED */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_hcd.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_hcd.c
deleted file mode 100644
index 0c377d9..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_hcd.c
+++ /dev/null
@@ -1,1194 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_hcd.c
- * @author MCD Application Team
- * @brief HCD HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the USB Peripheral Controller:
- * + Initialization and de-initialization functions
- * + IO operation functions
- * + Peripheral Control functions
- * + Peripheral State functions
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- (#)Declare a HCD_HandleTypeDef handle structure, for example:
- HCD_HandleTypeDef hhcd;
-
- (#)Fill parameters of Init structure in HCD handle
-
- (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...)
-
- (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API:
- (##) Enable the HCD/USB Low Level interface clock using the following macro
- (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE()
-
- (##) Initialize the related GPIO clocks
- (##) Configure HCD pin-out
- (##) Configure HCD NVIC interrupt
-
- (#)Associate the Upper USB Host stack to the HAL HCD Driver:
- (##) hhcd.pData = phost;
-
- (#)Enable HCD transmission and reception:
- (##) HAL_HCD_Start();
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-
-#ifdef HAL_HCD_MODULE_ENABLED
-
-#if defined(STM32F105xC) || defined(STM32F107xC)
-
-/** @defgroup HCD HCD
- * @brief HCD HAL module driver
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-/* Private function ----------------------------------------------------------*/
-/** @defgroup HCD_Private_Functions HCD Private Functions
- * @{
- */
-static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
-static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
-static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd);
-static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup HCD_Exported_Functions HCD Exported Functions
- * @{
- */
-
-/** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
- ===============================================================================
- ##### Initialization and de-initialization functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initialize the host driver
- * @param hhcd: HCD handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
-{
- /* Check the HCD handle allocation */
- if(hhcd == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance));
-
- if(hhcd->State == HAL_HCD_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- hhcd->Lock = HAL_UNLOCKED;
-
- /* Init the low level hardware : GPIO, CLOCK, NVIC... */
- HAL_HCD_MspInit(hhcd);
- }
-
- hhcd->State = HAL_HCD_STATE_BUSY;
-
- /* Disable the Interrupts */
- __HAL_HCD_DISABLE(hhcd);
-
- /* Init the Core (common init.) */
- USB_CoreInit(hhcd->Instance, hhcd->Init);
-
- /* Force Host Mode*/
- USB_SetCurrentMode(hhcd->Instance , USB_HOST_MODE);
-
- /* Init Host */
- USB_HostInit(hhcd->Instance, hhcd->Init);
-
- hhcd->State= HAL_HCD_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Initialize a host channel
- * @param hhcd: HCD handle
- * @param ch_num: Channel number.
- * This parameter can be a value from 1 to 15
- * @param epnum: Endpoint number.
- * This parameter can be a value from 1 to 15
- * @param dev_address : Current device address
- * This parameter can be a value from 0 to 255
- * @param speed: Current device speed.
- * This parameter can be one of these values:
- * HCD_SPEED_FULL: Full speed mode,
- * HCD_SPEED_LOW: Low speed mode
- * @param ep_type: Endpoint Type.
- * This parameter can be one of these values:
- * EP_TYPE_CTRL: Control type,
- * EP_TYPE_ISOC: Isochronous type,
- * EP_TYPE_BULK: Bulk type,
- * EP_TYPE_INTR: Interrupt type
- * @param mps: Max Packet Size.
- * This parameter can be a value from 0 to32K
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd,
- uint8_t ch_num,
- uint8_t epnum,
- uint8_t dev_address,
- uint8_t speed,
- uint8_t ep_type,
- uint16_t mps)
-{
- HAL_StatusTypeDef status = HAL_OK;
-
- __HAL_LOCK(hhcd);
-
- hhcd->hc[ch_num].dev_addr = dev_address;
- hhcd->hc[ch_num].max_packet = mps;
- hhcd->hc[ch_num].ch_num = ch_num;
- hhcd->hc[ch_num].ep_type = ep_type;
- hhcd->hc[ch_num].ep_num = epnum & 0x7FU;
- hhcd->hc[ch_num].ep_is_in = ((epnum & 0x80U) == 0x80U);
- hhcd->hc[ch_num].speed = speed;
-
- status = USB_HC_Init(hhcd->Instance,
- ch_num,
- epnum,
- dev_address,
- speed,
- ep_type,
- mps);
- __HAL_UNLOCK(hhcd);
-
- return status;
-}
-
-/**
- * @brief Halt a host channel
- * @param hhcd: HCD handle
- * @param ch_num: Channel number.
- * This parameter can be a value from 1 to 15
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd,
- uint8_t ch_num)
-{
- __HAL_LOCK(hhcd);
- USB_HC_Halt(hhcd->Instance, ch_num);
- __HAL_UNLOCK(hhcd);
-
- return HAL_OK;
-}
-
-/**
- * @brief DeInitialize the host driver
- * @param hhcd: HCD handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
-{
- /* Check the HCD handle allocation */
- if(hhcd == NULL)
- {
- return HAL_ERROR;
- }
-
- hhcd->State = HAL_HCD_STATE_BUSY;
-
- /* DeInit the low level hardware */
- HAL_HCD_MspDeInit(hhcd);
-
- __HAL_HCD_DISABLE(hhcd);
-
- hhcd->State = HAL_HCD_STATE_RESET;
-
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the HCD MSP.
- * @param hhcd: HCD handle
- * @retval None
- */
-__weak void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hhcd);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_HCD_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief DeInitializes HCD MSP.
- * @param hhcd: HCD handle
- * @retval None
- */
-__weak void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hhcd);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_HCD_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup HCD_Exported_Functions_Group2 IO operation functions
- * @brief HCD IO operation functions
- *
-@verbatim
- ===============================================================================
- ##### IO operation functions #####
- ===============================================================================
- This subsection provides a set of functions allowing to manage the USB Host Data
- Transfer
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Submit a new URB for processing
- * @param hhcd: HCD handle
- * @param ch_num: Channel number.
- * This parameter can be a value from 1 to 15
- * @param direction: Channel number.
- * This parameter can be one of these values:
- * 0 : Output / 1 : Input
- * @param ep_type: Endpoint Type.
- * This parameter can be one of these values:
- * EP_TYPE_CTRL: Control type/
- * EP_TYPE_ISOC: Isochronous type/
- * EP_TYPE_BULK: Bulk type/
- * EP_TYPE_INTR: Interrupt type/
- * @param token: Endpoint Type.
- * This parameter can be one of these values:
- * 0: HC_PID_SETUP / 1: HC_PID_DATA1
- * @param pbuff: pointer to URB data
- * @param length: Length of URB data
- * @param do_ping: activate do ping protocol (for high speed only).
- * This parameter can be one of these values:
- * 0 : do ping inactive / 1 : do ping active
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
- uint8_t ch_num,
- uint8_t direction,
- uint8_t ep_type,
- uint8_t token,
- uint8_t* pbuff,
- uint16_t length,
- uint8_t do_ping)
-{
- hhcd->hc[ch_num].ep_is_in = direction;
- hhcd->hc[ch_num].ep_type = ep_type;
-
- if(token == 0U)
- {
- hhcd->hc[ch_num].data_pid = HC_PID_SETUP;
- }
- else
- {
- hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
- }
-
- /* Manage Data Toggle */
- switch(ep_type)
- {
- case EP_TYPE_CTRL:
- if((token == 1U) && (direction == 0U)) /*send data */
- {
- if (length == 0U)
- { /* For Status OUT stage, Length==0, Status Out PID = 1 */
- hhcd->hc[ch_num].toggle_out = 1U;
- }
-
- /* Set the Data Toggle bit as per the Flag */
- if ( hhcd->hc[ch_num].toggle_out == 0U)
- { /* Put the PID 0 */
- hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
- }
- else
- { /* Put the PID 1 */
- hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
- }
- if(hhcd->hc[ch_num].urb_state != URB_NOTREADY)
- {
- hhcd->hc[ch_num].do_ping = do_ping;
- }
- }
- break;
-
- case EP_TYPE_BULK:
- if(direction == 0U)
- {
- /* Set the Data Toggle bit as per the Flag */
- if ( hhcd->hc[ch_num].toggle_out == 0U)
- { /* Put the PID 0 */
- hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
- }
- else
- { /* Put the PID 1 */
- hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
- }
- if(hhcd->hc[ch_num].urb_state != URB_NOTREADY)
- {
- hhcd->hc[ch_num].do_ping = do_ping;
- }
- }
- else
- {
- if( hhcd->hc[ch_num].toggle_in == 0U)
- {
- hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
- }
- else
- {
- hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
- }
- }
- break;
-
- case EP_TYPE_INTR:
- if(direction == 0U)
- {
- /* Set the Data Toggle bit as per the Flag */
- if ( hhcd->hc[ch_num].toggle_out == 0U)
- { /* Put the PID 0 */
- hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
- }
- else
- { /* Put the PID 1 */
- hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
- }
- }
- else
- {
- if( hhcd->hc[ch_num].toggle_in == 0U)
- {
- hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
- }
- else
- {
- hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
- }
- }
- break;
-
- case EP_TYPE_ISOC:
- hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
- break;
- }
-
- hhcd->hc[ch_num].xfer_buff = pbuff;
- hhcd->hc[ch_num].xfer_len = length;
- hhcd->hc[ch_num].urb_state = URB_IDLE;
- hhcd->hc[ch_num].xfer_count = 0U;
- hhcd->hc[ch_num].ch_num = ch_num;
- hhcd->hc[ch_num].state = HC_IDLE;
-
- return USB_HC_StartXfer(hhcd->Instance, &(hhcd->hc[ch_num]));
-}
-
-/**
- * @brief handle HCD interrupt request.
- * @param hhcd: HCD handle
- * @retval None
- */
-void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
-{
- USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
-
- uint32_t index = 0U, interrupt = 0U;
-
- /* ensure that we are in device mode */
- if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
- {
- /* Avoid spurious interrupt */
- if(__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
- {
- return;
- }
-
- if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
- {
- /* Incorrect mode, acknowledge the interrupt */
- __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
- }
-
- if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
- {
- /* Incorrect mode, acknowledge the interrupt */
- __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
- }
-
- if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
- {
- /* Incorrect mode, acknowledge the interrupt */
- __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
- }
-
- if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
- {
- /* Incorrect mode, acknowledge the interrupt */
- __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
- }
-
- /* Handle Host Disconnect Interrupts */
- if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
- {
-
- /* Cleanup HPRT */
- USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
- USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
-
- /* Handle Host Port Interrupts */
- HAL_HCD_Disconnect_Callback(hhcd);
- USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ);
- __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
- }
-
- /* Handle Host Port Interrupts */
- if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
- {
- HCD_Port_IRQHandler (hhcd);
- }
-
- /* Handle Host SOF Interrupts */
- if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
- {
- HAL_HCD_SOF_Callback(hhcd);
- __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
- }
-
- /* Handle Host channel Interrupts */
- if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
- {
- interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
- for (index = 0U; index < hhcd->Init.Host_channels ; index++)
- {
- if (interrupt & (1 << index))
- {
- if ((USBx_HC(index)->HCCHAR) & USB_OTG_HCCHAR_EPDIR)
- {
- HCD_HC_IN_IRQHandler (hhcd, index);
- }
- else
- {
- HCD_HC_OUT_IRQHandler (hhcd, index);
- }
- }
- }
- __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
- }
-
- /* Handle Rx Queue Level Interrupts */
- if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL))
- {
- USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
-
- HCD_RXQLVL_IRQHandler (hhcd);
-
- USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
- }
- }
-}
-
-/**
- * @brief SOF callback.
- * @param hhcd: HCD handle
- * @retval None
- */
-__weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hhcd);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_HCD_SOF_Callback could be implemented in the user file
- */
-}
-
-/**
- * @brief Connexion Event callback.
- * @param hhcd: HCD handle
- * @retval None
- */
-__weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hhcd);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_HCD_Connect_Callback could be implemented in the user file
- */
-}
-
-/**
- * @brief Disonnection Event callback.
- * @param hhcd: HCD handle
- * @retval None
- */
-__weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hhcd);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_HCD_Disconnect_Callback could be implemented in the user file
- */
-}
-
-/**
- * @brief Notify URB state change callback.
- * @param hhcd: HCD handle
- * @param chnum: Channel number.
- * This parameter can be a value from 1 to 15
- * @param urb_state:
- * This parameter can be one of these values:
- * URB_IDLE/
- * URB_DONE/
- * URB_NOTREADY/
- * URB_NYET/
- * URB_ERROR/
- * URB_STALL/
- * @retval None
- */
-__weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hhcd);
- UNUSED(chnum);
- UNUSED(urb_state);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
- * @brief management functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral Control functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to control the HCD data
- transfers.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Start the host driver
- * @param hhcd: HCD handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
-{
- __HAL_LOCK(hhcd);
- __HAL_HCD_ENABLE(hhcd);
- USB_DriveVbus(hhcd->Instance, 1U);
- __HAL_UNLOCK(hhcd);
- return HAL_OK;
-}
-
-/**
- * @brief Stop the host driver
- * @param hhcd: HCD handle
- * @retval HAL status
- */
-
-HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
-{
- __HAL_LOCK(hhcd);
- USB_StopHost(hhcd->Instance);
- __HAL_UNLOCK(hhcd);
- return HAL_OK;
-}
-
-/**
- * @brief Reset the host port
- * @param hhcd: HCD handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
-{
- return (USB_ResetPort(hhcd->Instance));
-}
-
-/**
- * @}
- */
-
-/** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
- * @brief Peripheral State functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral State functions #####
- ===============================================================================
- [..]
- This subsection permits to get in run-time the status of the peripheral
- and the data flow.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Return the HCD handle state
- * @param hhcd: HCD handle
- * @retval HAL state
- */
-HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd)
-{
- return hhcd->State;
-}
-
-/**
- * @brief Return URB state for a channel
- * @param hhcd: HCD handle
- * @param chnum: Channel number.
- * This parameter can be a value from 1 to 15
- * @retval URB state.
- * This parameter can be one of these values:
- * URB_IDLE/
- * URB_DONE/
- * URB_NOTREADY/
- * URB_NYET/
- * URB_ERROR/
- * URB_STALL/
- */
-HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
-{
- return hhcd->hc[chnum].urb_state;
-}
-
-
-/**
- * @brief Return the last host transfer size
- * @param hhcd: HCD handle
- * @param chnum: Channel number.
- * This parameter can be a value from 1 to 15
- * @retval last transfer size in byte
- */
-uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum)
-{
- return hhcd->hc[chnum].xfer_count;
-}
-
-/**
- * @brief Return the Host Channel state
- * @param hhcd: HCD handle
- * @param chnum: Channel number.
- * This parameter can be a value from 1 to 15
- * @retval Host channel state
- * This parameter can be one of the these values:
- * HC_IDLE/
- * HC_XFRC/
- * HC_HALTED/
- * HC_NYET/
- * HC_NAK/
- * HC_STALL/
- * HC_XACTERR/
- * HC_BBLERR/
- * HC_DATATGLERR/
- */
-HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
-{
- return hhcd->hc[chnum].state;
-}
-
-/**
- * @brief Return the current Host frame number
- * @param hhcd: HCD handle
- * @retval Current Host frame number
- */
-uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
-{
- return (USB_GetCurrentFrame(hhcd->Instance));
-}
-
-/**
- * @brief Return the Host enumeration speed
- * @param hhcd: HCD handle
- * @retval Enumeration speed
- */
-uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
-{
- return (USB_GetHostSpeed(hhcd->Instance));
-}
-
-/**
- * @}
- */
-/**
- * @}
- */
-
-/** @addtogroup HCD_Private_Functions
- * @{
- */
-/**
- * @brief This function handles Host Channel IN interrupt requests.
- * @param hhcd: HCD handle
- * @param chnum: Channel number.
- * This parameter can be a value from 1 to 15
- * @retval none
- */
-static void HCD_HC_IN_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum)
-{
- USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
- uint32_t tmpreg = 0U;
-
- if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR)
- {
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
- __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
- }
- else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK)
- {
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
- }
-
- else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL)
- {
- __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
- hhcd->hc[chnum].state = HC_STALL;
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
- USB_HC_Halt(hhcd->Instance, chnum);
- }
- else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR)
- {
- __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
- USB_HC_Halt(hhcd->Instance, chnum);
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
- hhcd->hc[chnum].state = HC_DATATGLERR;
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
- }
-
- if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR)
- {
- __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
- USB_HC_Halt(hhcd->Instance, chnum);
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
- }
-
- else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC)
- {
- hhcd->hc[chnum].state = HC_XFRC;
- hhcd->hc[chnum].ErrCnt = 0U;
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
-
- if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
- (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
- {
- __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
- USB_HC_Halt(hhcd->Instance, chnum);
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
-
- }
- else if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
- {
- USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
- hhcd->hc[chnum].urb_state = URB_DONE;
- HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
- }
- hhcd->hc[chnum].toggle_in ^= 1U;
-
- }
- else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH)
- {
- __HAL_HCD_MASK_HALT_HC_INT(chnum);
-
- if(hhcd->hc[chnum].state == HC_XFRC)
- {
- hhcd->hc[chnum].urb_state = URB_DONE;
- }
- else if (hhcd->hc[chnum].state == HC_STALL)
- {
- hhcd->hc[chnum].urb_state = URB_STALL;
- }
- else if((hhcd->hc[chnum].state == HC_XACTERR) ||
- (hhcd->hc[chnum].state == HC_DATATGLERR))
- {
- if(hhcd->hc[chnum].ErrCnt++ > 3U)
- {
- hhcd->hc[chnum].ErrCnt = 0U;
- hhcd->hc[chnum].urb_state = URB_ERROR;
- }
- else
- {
- hhcd->hc[chnum].urb_state = URB_NOTREADY;
- }
-
- /* re-activate the channel */
- tmpreg = USBx_HC(chnum)->HCCHAR;
- tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
- tmpreg |= USB_OTG_HCCHAR_CHENA;
- USBx_HC(chnum)->HCCHAR = tmpreg;
- }
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
- HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
- }
-
- else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR)
- {
- __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
- hhcd->hc[chnum].ErrCnt++;
- hhcd->hc[chnum].state = HC_XACTERR;
- USB_HC_Halt(hhcd->Instance, chnum);
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
- }
- else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK)
- {
- if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
- {
- __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
- USB_HC_Halt(hhcd->Instance, chnum);
- }
- else if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
- (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
- {
- /* re-activate the channel */
- tmpreg = USBx_HC(chnum)->HCCHAR;
- tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
- tmpreg |= USB_OTG_HCCHAR_CHENA;
- USBx_HC(chnum)->HCCHAR = tmpreg;
- }
- hhcd->hc[chnum].state = HC_NAK;
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
- }
-}
-
-/**
- * @brief This function handles Host Channel OUT interrupt requests.
- * @param hhcd: HCD handle
- * @param chnum: Channel number.
- * This parameter can be a value from 1 to 15
- * @retval none
- */
-static void HCD_HC_OUT_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum)
-{
- USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
- uint32_t tmpreg = 0U;
-
- if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR)
- {
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
- __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
- }
- else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK)
- {
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
-
- if( hhcd->hc[chnum].do_ping == 1U)
- {
- hhcd->hc[chnum].state = HC_NYET;
- __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
- USB_HC_Halt(hhcd->Instance, chnum);
- hhcd->hc[chnum].urb_state = URB_NOTREADY;
- }
- }
-
- else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NYET)
- {
- hhcd->hc[chnum].state = HC_NYET;
- hhcd->hc[chnum].ErrCnt= 0U;
- __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
- USB_HC_Halt(hhcd->Instance, chnum);
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
-
- }
-
- else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR)
- {
- __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
- USB_HC_Halt(hhcd->Instance, chnum);
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
- }
-
- else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC)
- {
- hhcd->hc[chnum].ErrCnt = 0U;
- __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
- USB_HC_Halt(hhcd->Instance, chnum);
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
- hhcd->hc[chnum].state = HC_XFRC;
- }
- else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL)
- {
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
- __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
- USB_HC_Halt(hhcd->Instance, chnum);
- hhcd->hc[chnum].state = HC_STALL;
- }
- else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK)
- {
- hhcd->hc[chnum].ErrCnt = 0U;
- __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
- USB_HC_Halt(hhcd->Instance, chnum);
- hhcd->hc[chnum].state = HC_NAK;
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
- }
- else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR)
- {
- __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
- USB_HC_Halt(hhcd->Instance, chnum);
- hhcd->hc[chnum].state = HC_XACTERR;
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
- }
- else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR)
- {
- __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
- USB_HC_Halt(hhcd->Instance, chnum);
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
- hhcd->hc[chnum].state = HC_DATATGLERR;
- }
- else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH)
- {
- __HAL_HCD_MASK_HALT_HC_INT(chnum);
-
- if(hhcd->hc[chnum].state == HC_XFRC)
- {
- hhcd->hc[chnum].urb_state = URB_DONE;
- if (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)
- {
- hhcd->hc[chnum].toggle_out ^= 1U;
- }
- }
- else if (hhcd->hc[chnum].state == HC_NAK)
- {
- hhcd->hc[chnum].urb_state = URB_NOTREADY;
- }
- else if (hhcd->hc[chnum].state == HC_NYET)
- {
- hhcd->hc[chnum].urb_state = URB_NOTREADY;
- hhcd->hc[chnum].do_ping = 0U;
- }
- else if (hhcd->hc[chnum].state == HC_STALL)
- {
- hhcd->hc[chnum].urb_state = URB_STALL;
- }
- else if((hhcd->hc[chnum].state == HC_XACTERR) ||
- (hhcd->hc[chnum].state == HC_DATATGLERR))
- {
- if(hhcd->hc[chnum].ErrCnt++ > 3U)
- {
- hhcd->hc[chnum].ErrCnt = 0U;
- hhcd->hc[chnum].urb_state = URB_ERROR;
- }
- else
- {
- hhcd->hc[chnum].urb_state = URB_NOTREADY;
- }
-
- /* re-activate the channel */
- tmpreg = USBx_HC(chnum)->HCCHAR;
- tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
- tmpreg |= USB_OTG_HCCHAR_CHENA;
- USBx_HC(chnum)->HCCHAR = tmpreg;
- }
-
- __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
- HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
- }
-}
-
-/**
- * @brief This function handles Rx Queue Level interrupt requests.
- * @param hhcd: HCD handle
- * @retval none
- */
-static void HCD_RXQLVL_IRQHandler (HCD_HandleTypeDef *hhcd)
-{
- USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
- uint8_t channelnum =0U;
- uint32_t pktsts;
- uint32_t pktcnt;
- uint32_t temp = 0U;
- uint32_t tmpreg = 0U;
-
- temp = hhcd->Instance->GRXSTSP;
- channelnum = temp & USB_OTG_GRXSTSP_EPNUM;
- pktsts = (temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U;
- pktcnt = (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
-
- switch (pktsts)
- {
- case GRXSTS_PKTSTS_IN:
- /* Read the data into the host buffer. */
- if ((pktcnt > 0U) && (hhcd->hc[channelnum].xfer_buff != (void *)0U))
- {
- USB_ReadPacket(hhcd->Instance, hhcd->hc[channelnum].xfer_buff, pktcnt);
-
- /*manage multiple Xfer */
- hhcd->hc[channelnum].xfer_buff += pktcnt;
- hhcd->hc[channelnum].xfer_count += pktcnt;
-
- if((USBx_HC(channelnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) > 0U)
- {
- /* re-activate the channel when more packets are expected */
- tmpreg = USBx_HC(channelnum)->HCCHAR;
- tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
- tmpreg |= USB_OTG_HCCHAR_CHENA;
- USBx_HC(channelnum)->HCCHAR = tmpreg;
- hhcd->hc[channelnum].toggle_in ^= 1U;
- }
- }
- break;
-
- case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
- break;
-
- case GRXSTS_PKTSTS_IN_XFER_COMP:
- case GRXSTS_PKTSTS_CH_HALTED:
- default:
- break;
- }
-}
-
-/**
- * @brief This function handles Host Port interrupt requests.
- * @param hhcd: HCD handle
- * @retval None
- */
-static void HCD_Port_IRQHandler (HCD_HandleTypeDef *hhcd)
-{
- USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
- __IO uint32_t hprt0 = 0, hprt0_dup = 0U;
-
- /* Handle Host Port Interrupts */
- hprt0 = USBx_HPRT0;
- hprt0_dup = USBx_HPRT0;
-
- hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
- USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
-
- /* Check whether Port Connect Detected */
- if((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
- {
- if((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
- {
- USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
- HAL_HCD_Connect_Callback(hhcd);
- }
- hprt0_dup |= USB_OTG_HPRT_PCDET;
- }
-
- /* Check whether Port Enable Changed */
- if((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
- {
- hprt0_dup |= USB_OTG_HPRT_PENCHNG;
-
- if((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
- {
- if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17U))
- {
- USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_6_MHZ );
- }
- else
- {
- USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ );
- }
- HAL_HCD_Connect_Callback(hhcd);
- }
- else
- {
- /* Cleanup HPRT */
- USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
- USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
-
- USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
- }
- }
-
- /* Check For an over current */
- if((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
- {
- hprt0_dup |= USB_OTG_HPRT_POCCHNG;
- }
-
- /* Clear Port Interrupts */
- USBx_HPRT0 = hprt0_dup;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* STM32F105xC || STM32F107xC */
-
-#endif /* HAL_HCD_MODULE_ENABLED */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2s.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2s.c
deleted file mode 100644
index 40909cc..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2s.c
+++ /dev/null
@@ -1,1458 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_i2s.c
- * @author MCD Application Team
- * @brief I2S HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Integrated Interchip Sound (I2S) peripheral:
- * + Initialization and de-initialization functions
- * + IO operation functions
- * + Peripheral State and Errors functions
- @verbatim
- ===============================================================================
- ##### How to use this driver #####
- ===============================================================================
- [..]
- The I2S HAL driver can be used as follow:
-
- (#) Declare a I2S_HandleTypeDef handle structure.
- (#) Initialize the I2S low level resources by implement the HAL_I2S_MspInit() API:
- (##) Enable the SPIx interface clock.
- (##) I2S pins configuration:
- (+++) Enable the clock for the I2S GPIOs.
- (+++) Configure these I2S pins as alternate function.
- (##) NVIC configuration if you need to use interrupt process (HAL_I2S_Transmit_IT()
- and HAL_I2S_Receive_IT() APIs).
- (+++) Configure the I2Sx interrupt priority.
- (+++) Enable the NVIC I2S IRQ handle.
- (##) DMA Configuration if you need to use DMA process (HAL_I2S_Transmit_DMA()
- and HAL_I2S_Receive_DMA() APIs:
- (+++) Declare a DMA handle structure for the Tx/Rx Channel.
- (+++) Enable the DMAx interface clock.
- (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
- (+++) Configure the DMA Tx/Rx Channel.
- (+++) Associate the initialized DMA handle to the I2S DMA Tx/Rx handle.
- (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
- DMA Tx/Rx Channel.
-
- (#) Program the Mode, Standard, Data Format, MCLK Output, Audio frequency and Polarity
- using HAL_I2S_Init() function.
-
- -@- The specific I2S interrupts (Transmission complete interrupt,
- RXNE interrupt and Error Interrupts) will be managed using the macros
- __HAL_I2S_ENABLE_IT() and __HAL_I2S_DISABLE_IT() inside the transmit and receive process.
- -@- The I2SxCLK source is the system clock (provided by the HSI, the HSE or the PLL, and sourcing the AHB clock).
- For connectivity line devices, the I2SxCLK source can be either SYSCLK or the PLL3 VCO (2 x PLL3CLK) clock
- in order to achieve the maximum accuracy.
- -@- Make sure that either:
- (+@) External clock source is configured after setting correctly
- the define constant HSE_VALUE in the stm32f1xx_hal_conf.h file.
-
- (#) Three operation modes are available within this driver :
-
- *** Polling mode IO operation ***
- =================================
- [..]
- (+) Send an amount of data in blocking mode using HAL_I2S_Transmit()
- (+) Receive an amount of data in blocking mode using HAL_I2S_Receive()
-
- *** Interrupt mode IO operation ***
- ===================================
- [..]
- (+) Send an amount of data in non blocking mode using HAL_I2S_Transmit_IT()
- (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
- (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2S_TxCpltCallback
- (+) Receive an amount of data in non blocking mode using HAL_I2S_Receive_IT()
- (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
- (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2S_RxCpltCallback
- (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
- add his own code by customization of function pointer HAL_I2S_ErrorCallback
-
- *** DMA mode IO operation ***
- ==============================
- [..]
- (+) Send an amount of data in non blocking mode (DMA) using HAL_I2S_Transmit_DMA()
- (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
- (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2S_TxCpltCallback
- (+) Receive an amount of data in non blocking mode (DMA) using HAL_I2S_Receive_DMA()
- (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
- (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2S_RxCpltCallback
- (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
- add his own code by customization of function pointer HAL_I2S_ErrorCallback
- (+) Pause the DMA Transfer using HAL_I2S_DMAPause()
- (+) Resume the DMA Transfer using HAL_I2S_DMAResume()
- (+) Stop the DMA Transfer using HAL_I2S_DMAStop()
-
- *** I2S HAL driver macros list ***
- =============================================
- [..]
- Below the list of most used macros in I2S HAL driver.
-
- (+) __HAL_I2S_ENABLE: Enable the specified SPI peripheral (in I2S mode)
- (+) __HAL_I2S_DISABLE: Disable the specified SPI peripheral (in I2S mode)
- (+) __HAL_I2S_ENABLE_IT : Enable the specified I2S interrupts
- (+) __HAL_I2S_DISABLE_IT : Disable the specified I2S interrupts
- (+) __HAL_I2S_GET_FLAG: Check whether the specified I2S flag is set or not
-
- [..]
- (@) You can refer to the I2S HAL driver header file for more useful macros
-
-
- *** I2C Workarounds linked to Silicon Limitation ***
- ====================================================
- [..]
- (@) Only the 16-bit mode with no data extension can be used when the I2S
- is in Master and used the PCM long synchronization mode.
-
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#ifdef HAL_I2S_MODULE_ENABLED
-#if defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
-
-/** @defgroup I2S I2S
- * @brief I2S HAL module driver
- * @{
- */
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @addtogroup I2S_Private_Functions I2S Private Functions
- * @{
- */
-static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma);
-static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
-static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma);
-static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
-static void I2S_DMAError(DMA_HandleTypeDef *hdma);
-static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s);
-static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s);
-static void I2S_IRQHandler(I2S_HandleTypeDef *hi2s);
-static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, uint32_t State,
- uint32_t Timeout);
-/**
- * @}
- */
-
-/* Exported functions ---------------------------------------------------------*/
-/** @defgroup I2S_Exported_Functions I2S Exported Functions
- * @{
- */
-
-/** @defgroup I2S_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
- ===============================================================================
- ##### Initialization and de-initialization functions #####
- ===============================================================================
- [..] This subsection provides a set of functions allowing to initialize and
- de-initialize the I2Sx peripheral in simplex mode:
-
- (+) User must Implement HAL_I2S_MspInit() function in which he configures
- all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
-
- (+) Call the function HAL_I2S_Init() to configure the selected device with
- the selected configuration:
- (++) Mode
- (++) Standard
- (++) Data Format
- (++) MCLK Output
- (++) Audio frequency
- (++) Polarity
-
- (+) Call the function HAL_I2S_DeInit() to restore the default configuration
- of the selected I2Sx peripheral.
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the I2S according to the specified parameters
- * in the I2S_InitTypeDef and create the associated handle.
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s)
-{
- uint32_t tmpreg = 0U, i2sdiv = 2U, i2sodd = 0U, packetlength = 16U;
- uint32_t tmp = 0U, i2sclk = 0U;
-
- /* Check the I2S handle allocation */
- if(hi2s == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the I2S parameters */
- assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
- assert_param(IS_I2S_MODE(hi2s->Init.Mode));
- assert_param(IS_I2S_STANDARD(hi2s->Init.Standard));
- assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat));
- assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput));
- assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq));
- assert_param(IS_I2S_CPOL(hi2s->Init.CPOL));
-
- hi2s->State = HAL_I2S_STATE_BUSY;
-
- /* Initialize Default I2S IrqHandler ISR */
- hi2s->IrqHandlerISR = I2S_IRQHandler;
-
- /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
- HAL_I2S_MspInit(hi2s);
-
- /*----------------------- SPIx I2SCFGR & I2SPR Configuration ---------------*/
- /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
- CLEAR_BIT(hi2s->Instance->I2SCFGR,(SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CKPOL | \
- SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \
- SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD));
- hi2s->Instance->I2SPR = 0x0002U;
-
- /* Get the I2SCFGR register value */
- tmpreg = hi2s->Instance->I2SCFGR;
-
- /* If the default frequency value has to be written, reinitialize i2sdiv and i2sodd */
- /* If the requested audio frequency is not the default, compute the prescaler */
- if(hi2s->Init.AudioFreq != I2S_AUDIOFREQ_DEFAULT)
- {
- /* Check the frame length (For the Prescaler computing) *******************/
- /* Set I2S Packet Length value*/
- if(hi2s->Init.DataFormat != I2S_DATAFORMAT_16B)
- {
- /* Packet length is 32 bits */
- packetlength = 32U;
- }
- else
- {
- /* Packet length is 16 bits */
- packetlength = 16U;
- }
-
- /* I2S standard */
- if(hi2s->Init.Standard <= I2S_STANDARD_LSB)
- {
- /* In I2S standard packet lenght is multiplied by 2 */
- packetlength = packetlength * 2U;
- }
-
- if(hi2s->Instance == SPI2)
- {
- /* Get the source clock value: based on SPI2 Instance */
- i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2S2);
- }
- else if(hi2s->Instance == SPI3)
- {
- /* Get the source clock value: based on SPI3 Instance */
- i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2S3);
- }
- else
- {
- /* Get the source clock value: based on System Clock value */
- i2sclk = HAL_RCC_GetSysClockFreq();
- }
-
- /* Compute the Real divider depending on the MCLK output state, with a floating point */
- if(hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE)
- {
- /* MCLK output is enabled */
- if (hi2s->Init.DataFormat != I2S_DATAFORMAT_16B)
- {
- tmp = (uint32_t)(((((i2sclk / (packetlength*4)) * 10) / hi2s->Init.AudioFreq)) + 5);
- }
- else
- {
- tmp = (uint32_t)(((((i2sclk / (packetlength*8)) * 10) / hi2s->Init.AudioFreq)) + 5);
- }
- }
- else
- {
- /* MCLK output is disabled */
- tmp = (uint32_t)(((((i2sclk / packetlength) *10 ) / hi2s->Init.AudioFreq)) + 5);
- }
-
- /* Remove the flatting point */
- tmp = tmp / 10U;
-
- /* Check the parity of the divider */
- i2sodd = (uint16_t)(tmp & (uint16_t)1U);
-
- /* Compute the i2sdiv prescaler */
- i2sdiv = (uint16_t)((tmp - i2sodd) / 2U);
-
- /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
- i2sodd = (uint32_t) (i2sodd << 8U);
- }
-
- /* Test if the divider is 1 or 0 or greater than 0xFF */
- if((i2sdiv < 2U) || (i2sdiv > 0xFFU))
- {
- /* Set the default values */
- i2sdiv = 2U;
- i2sodd = 0U;
-
- /* Set the error code and execute error callback*/
- SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_PRESCALER);
- HAL_I2S_ErrorCallback(hi2s);
- return HAL_ERROR;
- }
-
- /* Write to SPIx I2SPR register the computed value */
- hi2s->Instance->I2SPR = (uint32_t)((uint32_t)i2sdiv | (uint32_t)(i2sodd | (uint32_t)hi2s->Init.MCLKOutput));
-
- /* Configure the I2S with the I2S_InitStruct values */
- tmpreg |= (uint16_t)((uint16_t)SPI_I2SCFGR_I2SMOD | (uint16_t)(hi2s->Init.Mode | \
- (uint16_t)(hi2s->Init.Standard | (uint16_t)(hi2s->Init.DataFormat | \
- (uint16_t)hi2s->Init.CPOL))));
- /* Write to SPIx I2SCFGR */
- WRITE_REG(hi2s->Instance->I2SCFGR,tmpreg);
- hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
- hi2s->State = HAL_I2S_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief DeInitializes the I2S peripheral
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s)
-{
- /* Check the I2S handle allocation */
- if(hi2s == NULL)
- {
- return HAL_ERROR;
- }
-
- hi2s->State = HAL_I2S_STATE_BUSY;
-
- /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
- HAL_I2S_MspDeInit(hi2s);
-
- hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
- hi2s->State = HAL_I2S_STATE_RESET;
-
- /* Release Lock */
- __HAL_UNLOCK(hi2s);
-
- return HAL_OK;
-}
-
-/**
- * @brief I2S MSP Init
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @retval None
- */
- __weak void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2s);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_I2S_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief I2S MSP DeInit
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @retval None
- */
- __weak void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2s);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_I2S_MspDeInit could be implemented in the user file
- */
-}
-/**
- * @}
- */
-
-/** @defgroup I2S_Exported_Functions_Group2 IO operation functions
- * @brief Data transfers functions
- *
-@verbatim
- ===============================================================================
- ##### IO operation functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to manage the I2S data
- transfers.
-
- (#) There are two modes of transfer:
- (++) Blocking mode : The communication is performed in the polling mode.
- The status of all data processing is returned by the same function
- after finishing transfer.
- (++) No-Blocking mode : The communication is performed using Interrupts
- or DMA. These functions return the status of the transfer startup.
- The end of the data processing will be indicated through the
- dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
- using DMA mode.
-
- (#) Blocking mode functions are :
- (++) HAL_I2S_Transmit()
- (++) HAL_I2S_Receive()
-
- (#) No-Blocking mode functions with Interrupt are :
- (++) HAL_I2S_Transmit_IT()
- (++) HAL_I2S_Receive_IT()
-
- (#) No-Blocking mode functions with DMA are :
- (++) HAL_I2S_Transmit_DMA()
- (++) HAL_I2S_Receive_DMA()
-
- (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
- (++) HAL_I2S_TxCpltCallback()
- (++) HAL_I2S_RxCpltCallback()
- (++) HAL_I2S_ErrorCallback()
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Transmit an amount of data in blocking mode
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @param pData: a 16-bit pointer to data buffer.
- * @param Size: number of data sample to be sent:
- * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
- * configuration phase, the Size parameter means the number of 16-bit data length
- * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
- * the Size parameter means the number of 16-bit data length.
- * @param Timeout: Timeout duration
- * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
- * between Master and Slave(example: audio streaming).
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
-{
- uint32_t tmp1 = 0U;
-
- if((pData == NULL ) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- if(hi2s->State == HAL_I2S_STATE_READY)
- {
- tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
-
- if((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
- {
- hi2s->TxXferSize = (Size << 1U);
- hi2s->TxXferCount = (Size << 1U);
- }
- else
- {
- hi2s->TxXferSize = Size;
- hi2s->TxXferCount = Size;
- }
-
- /* Process Locked */
- __HAL_LOCK(hi2s);
-
- hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
- hi2s->State = HAL_I2S_STATE_BUSY_TX;
-
- /* Check if the I2S is already enabled */
- if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
- {
- /* Enable I2S peripheral */
- __HAL_I2S_ENABLE(hi2s);
- }
-
- while(hi2s->TxXferCount > 0U)
- {
- hi2s->Instance->DR = (*pData++);
- hi2s->TxXferCount--;
-
- /* Wait until TXE flag is set */
- if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK)
- {
- /* Set the error code and execute error callback*/
- SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
- HAL_I2S_ErrorCallback(hi2s);
- return HAL_TIMEOUT;
- }
-
- /* Check if an underrun occurs */
- if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
- {
- /* Clear underrun flag */
- __HAL_I2S_CLEAR_UDRFLAG(hi2s);
- /* Set the I2S State ready */
- hi2s->State = HAL_I2S_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2s);
-
- /* Set the error code and execute error callback*/
- SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
- HAL_I2S_ErrorCallback(hi2s);
-
- return HAL_ERROR;
- }
- }
- hi2s->State = HAL_I2S_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2s);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receive an amount of data in blocking mode
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @param pData: a 16-bit pointer to data buffer
- * @param Size: number of data sample to be sent:
- * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
- * configuration phase, the Size parameter means the number of 16-bit data length
- * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
- * the Size parameter means the number of 16-bit data length.
- * @param Timeout: Timeout duration
- * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
- * between Master and Slave(example: audio streaming)
- * @note In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
- * in continuous way and as the I2S is not disabled at the end of the I2S transaction
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
-{
- uint32_t tmp1 = 0U;
-
- if((pData == NULL ) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- if(hi2s->State == HAL_I2S_STATE_READY)
- {
- tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
- if((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
- {
- hi2s->RxXferSize = (Size << 1U);
- hi2s->RxXferCount = (Size << 1U);
- }
- else
- {
- hi2s->RxXferSize = Size;
- hi2s->RxXferCount = Size;
- }
- /* Process Locked */
- __HAL_LOCK(hi2s);
-
- hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
- hi2s->State = HAL_I2S_STATE_BUSY_RX;
-
- /* Check if the I2S is already enabled */
- if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
- {
- /* Enable I2S peripheral */
- __HAL_I2S_ENABLE(hi2s);
- }
-
- /* Check if Master Receiver mode is selected */
- if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
- {
- /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
- access to the SPI_SR register. */
- __HAL_I2S_CLEAR_OVRFLAG(hi2s);
- }
-
- /* Receive data */
- while(hi2s->RxXferCount > 0U)
- {
- /* Wait until RXNE flag is set */
- if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout) != HAL_OK)
- {
- /* Set the error code and execute error callback*/
- SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_TIMEOUT);
- HAL_I2S_ErrorCallback(hi2s);
- return HAL_TIMEOUT;
- }
-
- /* Check if an overrun occurs */
- if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
- {
- /* Clear overrun flag */
- __HAL_I2S_CLEAR_OVRFLAG(hi2s);
-
- /* Set the I2S State ready */
- hi2s->State = HAL_I2S_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2s);
-
- /* Set the error code and execute error callback*/
- SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
- HAL_I2S_ErrorCallback(hi2s);
-
- return HAL_ERROR;
- }
-
- (*pData++) = hi2s->Instance->DR;
- hi2s->RxXferCount--;
- }
-
- hi2s->State = HAL_I2S_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2s);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Transmit an amount of data in non-blocking mode with Interrupt
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @param pData: a 16-bit pointer to data buffer.
- * @param Size: number of data sample to be sent:
- * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
- * configuration phase, the Size parameter means the number of 16-bit data length
- * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
- * the Size parameter means the number of 16-bit data length.
- * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
- * between Master and Slave(example: audio streaming).
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
-{
- uint32_t tmp1 = 0U;
-
- if(hi2s->State == HAL_I2S_STATE_READY)
- {
- if((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- hi2s->pTxBuffPtr = pData;
- tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
- if((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
- {
- hi2s->TxXferSize = (Size << 1U);
- hi2s->TxXferCount = (Size << 1U);
- }
- else
- {
- hi2s->TxXferSize = Size;
- hi2s->TxXferCount = Size;
- }
-
- /* Process Locked */
- __HAL_LOCK(hi2s);
-
- hi2s->State = HAL_I2S_STATE_BUSY_TX;
- hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
-
- /* Enable TXE and ERR interrupt */
- __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
-
- /* Check if the I2S is already enabled */
- if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
- {
- /* Enable I2S peripheral */
- __HAL_I2S_ENABLE(hi2s);
- }
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2s);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receive an amount of data in non-blocking mode with Interrupt
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @param pData: a 16-bit pointer to the Receive data buffer.
- * @param Size: number of data sample to be sent:
- * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
- * configuration phase, the Size parameter means the number of 16-bit data length
- * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
- * the Size parameter means the number of 16-bit data length.
- * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
- * between Master and Slave(example: audio streaming).
- * @note It is recommended to use DMA for the I2S receiver to avoid de-synchronisation
- * between Master and Slave otherwise the I2S interrupt should be optimized.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
-{
- uint32_t tmp1 = 0U;
-
- if(hi2s->State == HAL_I2S_STATE_READY)
- {
- if((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- hi2s->pRxBuffPtr = pData;
- tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
- if((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
- {
- hi2s->RxXferSize = (Size << 1U);
- hi2s->RxXferCount = (Size << 1U);
- }
- else
- {
- hi2s->RxXferSize = Size;
- hi2s->RxXferCount = Size;
- }
- /* Process Locked */
- __HAL_LOCK(hi2s);
-
- hi2s->State = HAL_I2S_STATE_BUSY_RX;
- hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
-
- /* Enable TXE and ERR interrupt */
- __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
-
- /* Check if the I2S is already enabled */
- if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
- {
- /* Enable I2S peripheral */
- __HAL_I2S_ENABLE(hi2s);
- }
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2s);
-
- return HAL_OK;
- }
-
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Transmit an amount of data in non-blocking mode with DMA
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @param pData: a 16-bit pointer to the Transmit data buffer.
- * @param Size: number of data sample to be sent:
- * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
- * configuration phase, the Size parameter means the number of 16-bit data length
- * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
- * the Size parameter means the number of 16-bit data length.
- * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
- * between Master and Slave(example: audio streaming).
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
-{
- uint32_t *tmp = NULL;
- uint32_t tmp1 = 0U;
-
- if((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- if(hi2s->State == HAL_I2S_STATE_READY)
- {
- hi2s->pTxBuffPtr = pData;
- tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
- if((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
- {
- hi2s->TxXferSize = (Size << 1U);
- hi2s->TxXferCount = (Size << 1U);
- }
- else
- {
- hi2s->TxXferSize = Size;
- hi2s->TxXferCount = Size;
- }
-
- /* Process Locked */
- __HAL_LOCK(hi2s);
-
- hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
- hi2s->State = HAL_I2S_STATE_BUSY_TX;
-
- /* Set the I2S Tx DMA Half transfer complete callback */
- hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
-
- /* Set the I2S Tx DMA transfer complete callback */
- hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
-
- /* Set the DMA error callback */
- hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
-
- /* Enable the Tx DMA Stream */
- tmp = (uint32_t*)&pData;
- HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize);
-
- /* Check if the I2S is already enabled */
- if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
- {
- /* Enable I2S peripheral */
- __HAL_I2S_ENABLE(hi2s);
- }
-
- /* Check if the I2S Tx request is already enabled */
- if((hi2s->Instance->CR2 & SPI_CR2_TXDMAEN) != SPI_CR2_TXDMAEN)
- {
- /* Enable Tx DMA Request */
- SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
- }
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2s);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receive an amount of data in non-blocking mode with DMA
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @param pData: a 16-bit pointer to the Receive data buffer.
- * @param Size: number of data sample to be sent:
- * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
- * configuration phase, the Size parameter means the number of 16-bit data length
- * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
- * the Size parameter means the number of 16-bit data length.
- * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
- * between Master and Slave(example: audio streaming).
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
-{
- uint32_t *tmp = NULL;
- uint32_t tmp1 = 0U;
-
- if((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- if(hi2s->State == HAL_I2S_STATE_READY)
- {
- hi2s->pRxBuffPtr = pData;
- tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
- if((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
- {
- hi2s->RxXferSize = (Size << 1U);
- hi2s->RxXferCount = (Size << 1U);
- }
- else
- {
- hi2s->RxXferSize = Size;
- hi2s->RxXferCount = Size;
- }
- /* Process Locked */
- __HAL_LOCK(hi2s);
-
- hi2s->State = HAL_I2S_STATE_BUSY_RX;
- hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
-
- /* Set the I2S Rx DMA Half transfer complete callback */
- hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
-
- /* Set the I2S Rx DMA transfer complete callback */
- hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
-
- /* Set the DMA error callback */
- hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
-
- /* Check if Master Receiver mode is selected */
- if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
- {
- /* Clear the Overrun Flag by a read operation to the SPI_DR register followed by a read
- access to the SPI_SR register. */
- __HAL_I2S_CLEAR_OVRFLAG(hi2s);
- }
-
- /* Enable the Rx DMA Stream */
- tmp = (uint32_t*)&pData;
- HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, *(uint32_t*)tmp, hi2s->RxXferSize);
-
- /* Check if the I2S is already enabled */
- if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
- {
- /* Enable I2S peripheral */
- __HAL_I2S_ENABLE(hi2s);
- }
-
- /* Check if the I2S Rx request is already enabled */
- if((hi2s->Instance->CR2 &SPI_CR2_RXDMAEN) != SPI_CR2_RXDMAEN)
- {
- /* Enable Rx DMA Request */
- SET_BIT(hi2s->Instance->CR2,SPI_CR2_RXDMAEN);
- }
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2s);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Pauses the audio channel playing from the Media.
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s)
-{
- /* Process Locked */
- __HAL_LOCK(hi2s);
-
- if(hi2s->State == HAL_I2S_STATE_BUSY_TX)
- {
- /* Disable the I2S DMA Tx request */
- CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_TXDMAEN);
- }
- else if(hi2s->State == HAL_I2S_STATE_BUSY_RX)
- {
- /* Disable the I2S DMA Rx request */
- CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_RXDMAEN);
- }
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2s);
-
- return HAL_OK;
-}
-
-/**
- * @brief Resumes the audio channel playing from the Media.
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s)
-{
- /* Process Locked */
- __HAL_LOCK(hi2s);
-
- if(hi2s->State == HAL_I2S_STATE_BUSY_TX)
- {
- /* Enable the I2S DMA Tx request */
- SET_BIT(hi2s->Instance->CR2,SPI_CR2_TXDMAEN);
- }
- else if(hi2s->State == HAL_I2S_STATE_BUSY_RX)
- {
- /* Enable the I2S DMA Rx request */
- SET_BIT(hi2s->Instance->CR2,SPI_CR2_RXDMAEN);
- }
-
- /* If the I2S peripheral is still not enabled, enable it */
- if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) == 0U)
- {
- /* Enable I2S peripheral */
- __HAL_I2S_ENABLE(hi2s);
- }
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2s);
-
- return HAL_OK;
-}
-
-/**
- * @brief Resumes the audio channel playing from the Media.
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
-{
- /* Process Locked */
- __HAL_LOCK(hi2s);
-
- if(hi2s->State == HAL_I2S_STATE_BUSY_TX)
- {
- /* Disable the I2S DMA requests */
- CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_TXDMAEN);
-
- /* Disable the I2S DMA Channel */
- HAL_DMA_Abort(hi2s->hdmatx);
- }
- else if(hi2s->State == HAL_I2S_STATE_BUSY_RX)
- {
- /* Disable the I2S DMA requests */
- CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_RXDMAEN);
-
- /* Disable the I2S DMA Channel */
- HAL_DMA_Abort(hi2s->hdmarx);
- }
- /* Disable I2S peripheral */
- __HAL_I2S_DISABLE(hi2s);
-
- hi2s->State = HAL_I2S_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2s);
-
- return HAL_OK;
-}
-
-/**
- * @brief This function handles I2S interrupt request.
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @retval None
- */
-void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
-{
- /* Call the IrqHandler ISR set during HAL_I2S_INIT */
- hi2s->IrqHandlerISR(hi2s);
-}
-
-/**
- * @brief Tx Transfer Half completed callbacks
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @retval None
- */
- __weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2s);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_I2S_TxHalfCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Tx Transfer completed callbacks
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @retval None
- */
- __weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2s);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_I2S_TxCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Rx Transfer half completed callbacks
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @retval None
- */
-__weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2s);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_I2S_RxHalfCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Rx Transfer completed callbacks
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @retval None
- */
-__weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2s);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_I2S_RxCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief I2S error callbacks
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @retval None
- */
- __weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2s);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_I2S_ErrorCallback could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions
- * @brief Peripheral State functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral State and Errors functions #####
- ===============================================================================
- [..]
- This subsection permits to get in run-time the status of the peripheral
- and the data flow.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Return the I2S state
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @retval HAL state
- */
-HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s)
-{
- return hi2s->State;
-}
-
-/**
- * @brief Return the I2S error code
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @retval I2S Error Code
- */
-uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s)
-{
- return hi2s->ErrorCode;
-}
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private functions ---------------------------------------------------------*/
-/** @addtogroup I2S_Private_Functions I2S Private Functions
- * @{
- */
-/**
- * @brief DMA I2S transmit process complete callback
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
-{
- I2S_HandleTypeDef* hi2s = ( I2S_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- if(HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
- {
- /* Disable Tx DMA Request */
- CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_TXDMAEN);
-
- hi2s->TxXferCount = 0U;
- hi2s->State = HAL_I2S_STATE_READY;
- }
- HAL_I2S_TxCpltCallback(hi2s);
-}
-/**
- * @brief DMA I2S transmit process half complete callback
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
-{
- I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
-
- HAL_I2S_TxHalfCpltCallback(hi2s);
-}
-
-/**
- * @brief DMA I2S receive process complete callback
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
-{
- I2S_HandleTypeDef* hi2s = ( I2S_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- if(HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
- {
- /* Disable Rx DMA Request */
- CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_RXDMAEN);
- hi2s->RxXferCount = 0U;
- hi2s->State = HAL_I2S_STATE_READY;
- }
- HAL_I2S_RxCpltCallback(hi2s);
-}
-
-/**
- * @brief DMA I2S receive process half complete callback
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
-{
- I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
-
- HAL_I2S_RxHalfCpltCallback(hi2s);
-}
-
-/**
- * @brief DMA I2S communication error callback
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void I2S_DMAError(DMA_HandleTypeDef *hdma)
-{
- I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
-
- /* Disable Rx and Tx DMA Request */
- CLEAR_BIT(hi2s->Instance->CR2,(SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
- hi2s->TxXferCount = 0U;
- hi2s->RxXferCount = 0U;
-
- hi2s->State= HAL_I2S_STATE_READY;
-
- SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_DMA);
- HAL_I2S_ErrorCallback(hi2s);
-}
-
-/**
- * @brief Transmit an amount of data in non-blocking mode with Interrupt
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @retval HAL status
- */
-static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s)
-{
- /* Transmit data */
- hi2s->Instance->DR = (*hi2s->pTxBuffPtr++);
- hi2s->TxXferCount--;
-
- if(hi2s->TxXferCount == 0U)
- {
- /* Disable TXE and ERR interrupt */
- __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
-
- hi2s->State = HAL_I2S_STATE_READY;
- HAL_I2S_TxCpltCallback(hi2s);
- }
-}
-
-/**
- * @brief Receive an amount of data in non-blocking mode with Interrupt
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @retval HAL status
- */
-static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s)
-{
- /* Receive data */
- (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR;
- hi2s->RxXferCount--;
-
- if(hi2s->RxXferCount == 0U)
- {
- /* Disable RXNE and ERR interrupt */
- __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
-
- hi2s->State = HAL_I2S_STATE_READY;
- HAL_I2S_RxCpltCallback(hi2s);
- }
-}
-
-/**
- * @brief This function handles I2S interrupt request.
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @retval None
- */
-static void I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
-{
- __IO uint32_t i2ssr = hi2s->Instance->SR;
-
- if(hi2s->State == HAL_I2S_STATE_BUSY_RX)
- {
- /* I2S in mode Receiver ------------------------------------------------*/
- if(((i2ssr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_RXNE) != RESET))
- {
- I2S_Receive_IT(hi2s);
- }
-
- /* I2S Overrun error interrupt occurred -------------------------------------*/
- if(((i2ssr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET))
- {
- /* Disable RXNE and ERR interrupt */
- __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
-
- /* Clear Overrun flag */
- __HAL_I2S_CLEAR_OVRFLAG(hi2s);
-
- /* Set the I2S State ready */
- hi2s->State = HAL_I2S_STATE_READY;
-
-
- /* Set the error code and execute error callback*/
- SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_OVR);
- HAL_I2S_ErrorCallback(hi2s);
- }
- }
-
- if(hi2s->State == HAL_I2S_STATE_BUSY_TX)
- {
- /* I2S in mode Transmitter -----------------------------------------------*/
- if(((i2ssr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_TXE) != RESET))
- {
- I2S_Transmit_IT(hi2s);
- }
-
- /* I2S Underrun error interrupt occurred --------------------------------*/
- if(((i2ssr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET))
- {
- /* Disable TXE and ERR interrupt */
- __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
-
- /* Clear Underrun flag */
- __HAL_I2S_CLEAR_UDRFLAG(hi2s);
-
- /* Set the I2S State ready */
- hi2s->State = HAL_I2S_STATE_READY;
-
- /* Set the error code and execute error callback*/
- SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
- HAL_I2S_ErrorCallback(hi2s);
- }
- }
-}
-
-/**
- * @brief This function handles I2S Communication Timeout.
- * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
- * the configuration information for I2S module
- * @param Flag: Flag checked
- * @param State: Value of the flag expected
- * @param Timeout: Duration of the timeout
- * @retval HAL status
- */
-static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, uint32_t State,
- uint32_t Timeout)
-{
- uint32_t tickstart = HAL_GetTick();
-
- /* Wait until flag is set to status*/
- while(((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
- {
- if(Timeout != HAL_MAX_DELAY)
- {
- if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
- {
- /* Set the I2S State ready */
- hi2s->State = HAL_I2S_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2s);
-
- return HAL_TIMEOUT;
- }
- }
- }
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
-#endif /* HAL_I2S_MODULE_ENABLED */
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_irda.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_irda.c
deleted file mode 100644
index 697a339..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_irda.c
+++ /dev/null
@@ -1,2131 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_irda.c
- * @author MCD Application Team
- * @brief IRDA HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the IrDA SIR ENDEC block (IrDA):
- * + Initialization and de-initialization functions
- * + IO operation functions
- * + Peripheral Control functions
- * + Peripheral State and Errors functions
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- The IRDA HAL driver can be used as follows:
-
- (#) Declare a IRDA_HandleTypeDef handle structure.
- (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API:
- (##) Enable the USARTx interface clock.
- (##) IRDA pins configuration:
- (+++) Enable the clock for the IRDA GPIOs.
- (+++) Configure the IRDA pins as alternate function pull-up.
- (##) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT()
- and HAL_IRDA_Receive_IT() APIs):
- (+++) Configure the USARTx interrupt priority.
- (+++) Enable the NVIC USART IRQ handle.
- (##) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA()
- and HAL_IRDA_Receive_DMA() APIs):
- (+++) Declare a DMA handle structure for the Tx/Rx channel.
- (+++) Enable the DMAx interface clock.
- (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
- (+++) Configure the DMA Tx/Rx channel.
- (+++) Associate the initialized DMA handle to the IRDA DMA Tx/Rx handle.
- (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
- (+++) Configure the IRDAx interrupt priority and enable the NVIC USART IRQ handle
- (used for last byte sending completion detection in DMA non circular mode)
-
- (#) Program the Baud Rate, Word Length, Parity, IrDA Mode, Prescaler
- and Mode(Receiver/Transmitter) in the hirda Init structure.
-
- (#) Initialize the IRDA registers by calling the HAL_IRDA_Init() API:
- (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
- by calling the customized HAL_IRDA_MspInit() API.
- [..]
- (@) The specific IRDA interrupts (Transmission complete interrupt,
- RXNE interrupt and Error Interrupts) will be managed using the macros
- __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process.
- [..]
- Three operation modes are available within this driver :
-
- *** Polling mode IO operation ***
- =================================
- [..]
- (+) Send an amount of data in blocking mode using HAL_IRDA_Transmit()
- (+) Receive an amount of data in blocking mode using HAL_IRDA_Receive()
-
- *** Interrupt mode IO operation ***
- ===================================
- [..]
- (+) Send an amount of data in non blocking mode using HAL_IRDA_Transmit_IT()
- (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_IRDA_TxCpltCallback
- (+) Receive an amount of data in non blocking mode using HAL_IRDA_Receive_IT()
- (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_IRDA_RxCpltCallback
- (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
- add his own code by customization of function pointer HAL_IRDA_ErrorCallback
-
- *** DMA mode IO operation ***
- ==============================
- [..]
- (+) Send an amount of data in non blocking mode (DMA) using HAL_IRDA_Transmit_DMA()
- (+) At transmission end of half transfer HAL_IRDA_TxHalfCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_IRDA_TxHalfCpltCallback
- (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_IRDA_TxCpltCallback
- (+) Receive an amount of data in non blocking mode (DMA) using HAL_IRDA_Receive_DMA()
- (+) At reception end of half transfer HAL_IRDA_RxHalfCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_IRDA_RxHalfCpltCallback
- (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_IRDA_RxCpltCallback
- (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
- add his own code by customization of function pointer HAL_IRDA_ErrorCallback
- (+) Pause the DMA Transfer using HAL_IRDA_DMAPause()
- (+) Resume the DMA Transfer using HAL_IRDA_DMAResume()
- (+) Stop the DMA Transfer using HAL_IRDA_DMAStop()
-
- *** IRDA HAL driver macros list ***
- ====================================
- [..]
- Below the list of most used macros in IRDA HAL driver.
-
- (+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral
- (+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral
- (+) __HAL_IRDA_GET_FLAG : Check whether the specified IRDA flag is set or not
- (+) __HAL_IRDA_CLEAR_FLAG : Clear the specified IRDA pending flag
- (+) __HAL_IRDA_ENABLE_IT: Enable the specified IRDA interrupt
- (+) __HAL_IRDA_DISABLE_IT: Disable the specified IRDA interrupt
- (+) __HAL_IRDA_GET_IT_SOURCE: Check whether the specified IRDA interrupt has occurred or not
-
- [..]
- (@) You can refer to the IRDA HAL driver header file for more useful macros
- @endverbatim
- [..]
- (@) Additionnal remark: If the parity is enabled, then the MSB bit of the data written
- in the data register is transmitted but is changed by the parity bit.
- Depending on the frame length defined by the M bit (8-bits or 9-bits),
- the possible IRDA frame formats are as listed in the following table:
- +-------------------------------------------------------------+
- | M bit | PCE bit | IRDA frame |
- |---------------------|---------------------------------------|
- | 0 | 0 | | SB | 8 bit data | 1 STB | |
- |---------|-----------|---------------------------------------|
- | 0 | 1 | | SB | 7 bit data | PB | 1 STB | |
- |---------|-----------|---------------------------------------|
- | 1 | 0 | | SB | 9 bit data | 1 STB | |
- |---------|-----------|---------------------------------------|
- | 1 | 1 | | SB | 8 bit data | PB | 1 STB | |
- +-------------------------------------------------------------+
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup IRDA IRDA
- * @brief HAL IRDA module driver
- * @{
- */
-#ifdef HAL_IRDA_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @addtogroup IRDA_Private_Constants
- * @{
- */
-/**
- * @}
- */
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @addtogroup IRDA_Private_Functions
- * @{
- */
-static void IRDA_SetConfig (IRDA_HandleTypeDef *hirda);
-static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda);
-static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda);
-static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda);
-static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma);
-static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma);
-static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
-static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma);
-static void IRDA_DMAError(DMA_HandleTypeDef *hdma);
-static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma);
-static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
-static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
-static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
-static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
-static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart,uint32_t Timeout);
-static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda);
-static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda);
-/**
- * @}
- */
-/* Exported functions ---------------------------------------------------------*/
-/** @defgroup IRDA_Exported_Functions IrDA Exported Functions
- * @{
- */
-
-/** @defgroup IRDA_Exported_Functions_Group1 IrDA Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
- ==============================================================================
- ##### Initialization and Configuration functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
- in IrDA mode.
- (+) For the asynchronous mode only these parameters can be configured:
- (++) BaudRate
- (++) WordLength
- (++) Parity: If the parity is enabled, then the MSB bit of the data written
- in the data register is transmitted but is changed by the parity bit.
- Depending on the frame length defined by the M bit (8-bits or 9-bits),
- please refer to Reference manual for possible IRDA frame formats.
- (++) Prescaler: A pulse of width less than two and greater than one PSC period(s) may or may
- not be rejected. The receiver set up time should be managed by software. The IrDA physical layer
- specification specifies a minimum of 10 ms delay between transmission and
- reception (IrDA is a half duplex protocol).
- (++) Mode: Receiver/transmitter modes
- (++) IrDAMode: the IrDA can operate in the Normal mode or in the Low power mode.
- [..]
- The HAL_IRDA_Init() API follows IRDA configuration procedures (details for the procedures
- are available in reference manual).
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the IRDA mode according to the specified
- * parameters in the IRDA_InitTypeDef and create the associated handle.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda)
-{
- /* Check the IRDA handle allocation */
- if(hirda == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_IRDA_INSTANCE(hirda->Instance));
-
- if(hirda->gState == HAL_IRDA_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- hirda->Lock = HAL_UNLOCKED;
- /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
- HAL_IRDA_MspInit(hirda);
- }
-
- hirda->gState = HAL_IRDA_STATE_BUSY;
-
- /* Disable the IRDA peripheral */
- __HAL_IRDA_DISABLE(hirda);
-
- /* Set the IRDA communication parameters */
- IRDA_SetConfig(hirda);
-
- /* In IrDA mode, the following bits must be kept cleared:
- - LINEN, STOP and CLKEN bits in the USART_CR2 register,
- - SCEN and HDSEL bits in the USART_CR3 register.*/
- CLEAR_BIT(hirda->Instance->CR2, (USART_CR2_LINEN | USART_CR2_STOP | USART_CR2_CLKEN));
- CLEAR_BIT(hirda->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL));
-
- /* Enable the IRDA peripheral */
- __HAL_IRDA_ENABLE(hirda);
-
- /* Set the prescaler */
- MODIFY_REG(hirda->Instance->GTPR, USART_GTPR_PSC, hirda->Init.Prescaler);
-
- /* Configure the IrDA mode */
- MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.IrDAMode);
-
- /* Enable the IrDA mode by setting the IREN bit in the CR3 register */
- SET_BIT(hirda->Instance->CR3, USART_CR3_IREN);
-
- /* Initialize the IRDA state*/
- hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
- hirda->gState= HAL_IRDA_STATE_READY;
- hirda->RxState= HAL_IRDA_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief DeInitializes the IRDA peripheral
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda)
-{
- /* Check the IRDA handle allocation */
- if(hirda == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_IRDA_INSTANCE(hirda->Instance));
-
- hirda->gState = HAL_IRDA_STATE_BUSY;
-
- /* Disable the Peripheral */
- __HAL_IRDA_DISABLE(hirda);
-
- /* DeInit the low level hardware */
- HAL_IRDA_MspDeInit(hirda);
-
- hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
- hirda->gState = HAL_IRDA_STATE_RESET;
- hirda->RxState = HAL_IRDA_STATE_RESET;
-
- /* Release Lock */
- __HAL_UNLOCK(hirda);
-
- return HAL_OK;
-}
-
-/**
- * @brief IRDA MSP Init.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @retval None
- */
-__weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hirda);
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_IRDA_MspInit can be implemented in the user file
- */
-}
-
-/**
- * @brief IRDA MSP DeInit.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @retval None
- */
-__weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hirda);
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_IRDA_MspDeInit can be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup IRDA_Exported_Functions_Group2 IO operation functions
- * @brief IRDA Transmit and Receive functions
- *
-@verbatim
- ==============================================================================
- ##### IO operation functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to manage the IRDA data transfers.
- IrDA is a half duplex communication protocol. If the Transmitter is busy, any data
- on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver
- is busy, data on the TX from the USART to IrDA will not be encoded by IrDA.
- While receiving data, transmission should be avoided as the data to be transmitted
- could be corrupted.
-
- (#) There are two modes of transfer:
- (++) Blocking mode: The communication is performed in polling mode.
- The HAL status of all data processing is returned by the same function
- after finishing transfer.
- (++) No-Blocking mode: The communication is performed using Interrupts
- or DMA, these APIs return the HAL status.
- The end of the data processing will be indicated through the
- dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when
- using DMA mode.
- The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks
- will be executed respectively at the end of the transmit or Receive process
- The HAL_IRDA_ErrorCallback() user callback will be executed when a communication
- error is detected
-
- (#) Blocking mode APIs are:
- (++) HAL_IRDA_Transmit()
- (++) HAL_IRDA_Receive()
-
- (#) Non Blocking mode APIs with Interrupt are:
- (++) HAL_IRDA_Transmit_IT()
- (++) HAL_IRDA_Receive_IT()
- (++) HAL_IRDA_IRQHandler()
-
- (#) Non Blocking mode functions with DMA are:
- (++) HAL_IRDA_Transmit_DMA()
- (++) HAL_IRDA_Receive_DMA()
- (++) HAL_IRDA_DMAPause()
- (++) HAL_IRDA_DMAResume()
- (++) HAL_IRDA_DMAStop()
-
- (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
- (++) HAL_IRDA_TxHalfCpltCallback()
- (++) HAL_IRDA_TxCpltCallback()
- (++) HAL_IRDA_RxHalfCpltCallback()
- (++) HAL_IRDA_RxCpltCallback()
- (++) HAL_IRDA_ErrorCallback()
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Sends an amount of data in blocking mode.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @param pData: Pointer to data buffer
- * @param Size: Amount of data to be sent
- * @param Timeout: Specify timeout value
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
-{
- uint16_t* tmp;
- uint32_t tickstart = 0U;
-
- /* Check that a Tx process is not already ongoing */
- if(hirda->gState == HAL_IRDA_STATE_READY)
- {
- if((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hirda);
-
- hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
- hirda->gState = HAL_IRDA_STATE_BUSY_TX;
-
- /* Init tickstart for timeout managment */
- tickstart = HAL_GetTick();
-
- hirda->TxXferSize = Size;
- hirda->TxXferCount = Size;
- while(hirda->TxXferCount > 0U)
- {
- hirda->TxXferCount--;
- if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
- {
- if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- tmp = (uint16_t*) pData;
- hirda->Instance->DR = (*tmp & (uint16_t)0x01FF);
- if(hirda->Init.Parity == IRDA_PARITY_NONE)
- {
- pData +=2U;
- }
- else
- {
- pData +=1U;
- }
- }
- else
- {
- if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- hirda->Instance->DR = (*pData++ & (uint8_t)0xFF);
- }
- }
-
- if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
-
- /* At end of Tx process, restore hirda->gState to Ready */
- hirda->gState = HAL_IRDA_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hirda);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receive an amount of data in blocking mode.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @param pData: Pointer to data buffer
- * @param Size: Amount of data to be received
- * @param Timeout: Specify timeout value
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
-{
- uint16_t* tmp;
- uint32_t tickstart = 0U;
-
- /* Check that a Rx process is not already ongoing */
- if(hirda->RxState == HAL_IRDA_STATE_READY)
- {
- if((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hirda);
-
- hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
- hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
-
- /* Init tickstart for timeout managment */
- tickstart = HAL_GetTick();
-
- hirda->RxXferSize = Size;
- hirda->RxXferCount = Size;
-
- /* Check the remain data to be received */
- while(hirda->RxXferCount > 0U)
- {
- hirda->RxXferCount--;
- if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
- {
- if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- tmp = (uint16_t*)pData;
- if(hirda->Init.Parity == IRDA_PARITY_NONE)
- {
- *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x01FF);
- pData +=2U;
- }
- else
- {
- *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x00FF);
- pData +=1U;
- }
- }
- else
- {
- if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- if(hirda->Init.Parity == IRDA_PARITY_NONE)
- {
- *pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x00FF);
- }
- else
- {
- *pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x007F);
- }
- }
- }
-
- /* At end of Rx process, restore hirda->RxState to Ready */
- hirda->RxState = HAL_IRDA_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hirda);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Sends an amount of data in non blocking mode.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @param pData: Pointer to data buffer
- * @param Size: Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
-{
- /* Check that a Tx process is not already ongoing */
- if(hirda->gState == HAL_IRDA_STATE_READY)
- {
- if((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
- /* Process Locked */
- __HAL_LOCK(hirda);
-
- hirda->pTxBuffPtr = pData;
- hirda->TxXferSize = Size;
- hirda->TxXferCount = Size;
-
- hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
- hirda->gState = HAL_IRDA_STATE_BUSY_TX;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hirda);
-
- /* Enable the IRDA Transmit data register empty Interrupt */
- __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TXE);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receives an amount of data in non blocking mode.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @param pData: Pointer to data buffer
- * @param Size: Amount of data to be received
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
-{
- /* Check that a Rx process is not already ongoing */
- if(hirda->RxState == HAL_IRDA_STATE_READY)
- {
- if((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hirda);
-
- hirda->pRxBuffPtr = pData;
- hirda->RxXferSize = Size;
- hirda->RxXferCount = Size;
-
- hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
- hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hirda);
-
- /* Enable the IRDA Parity Error Interrupt */
- __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_PE);
-
- /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
- __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_ERR);
-
- /* Enable the IRDA Data Register not empty Interrupt */
- __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_RXNE);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Sends an amount of data in non blocking mode.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @param pData: Pointer to data buffer
- * @param Size: Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
-{
- uint32_t *tmp;
-
- /* Check that a Tx process is not already ongoing */
- if(hirda->gState == HAL_IRDA_STATE_READY)
- {
- if((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hirda);
-
- hirda->pTxBuffPtr = pData;
- hirda->TxXferSize = Size;
- hirda->TxXferCount = Size;
-
- hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
- hirda->gState = HAL_IRDA_STATE_BUSY_TX;
-
- /* Set the IRDA DMA transfer complete callback */
- hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt;
-
- /* Set the IRDA DMA half transfer complete callback */
- hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt;
-
- /* Set the DMA error callback */
- hirda->hdmatx->XferErrorCallback = IRDA_DMAError;
-
- /* Set the DMA abort callback */
- hirda->hdmatx->XferAbortCallback = NULL;
-
- /* Enable the IRDA transmit DMA Channel */
- tmp = (uint32_t*)&pData;
- HAL_DMA_Start_IT(hirda->hdmatx, *(uint32_t*)tmp, (uint32_t)&hirda->Instance->DR, Size);
-
- /* Clear the TC flag in the SR register by writing 0 to it */
- __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_FLAG_TC);
-
- /* Process Unlocked */
- __HAL_UNLOCK(hirda);
-
- /* Enable the DMA transfer for transmit request by setting the DMAT bit
- in the USART CR3 register */
- SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receives an amount of data in non blocking mode.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @param pData: Pointer to data buffer
- * @param Size: Amount of data to be received
- * @note When the IRDA parity is enabled (PCE = 1) the data received contain the parity bit.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
-{
- uint32_t *tmp;
-
- /* Check that a Rx process is not already ongoing */
- if(hirda->RxState == HAL_IRDA_STATE_READY)
- {
- if((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hirda);
-
- hirda->pRxBuffPtr = pData;
- hirda->RxXferSize = Size;
-
- hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
- hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
-
- /* Set the IRDA DMA transfer complete callback */
- hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt;
-
- /* Set the IRDA DMA half transfer complete callback */
- hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt;
-
- /* Set the DMA error callback */
- hirda->hdmarx->XferErrorCallback = IRDA_DMAError;
-
- /* Set the DMA abort callback */
- hirda->hdmarx->XferAbortCallback = NULL;
-
- /* Enable the DMA channel */
- tmp = (uint32_t*)&pData;
- HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->DR, *(uint32_t*)tmp, Size);
-
- /* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */
- __HAL_IRDA_CLEAR_OREFLAG(hirda);
-
- /* Process Unlocked */
- __HAL_UNLOCK(hirda);
-
- /* Enable the IRDA Parity Error Interrupt */
- SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
-
- /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
- SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
-
- /* Enable the DMA transfer for the receiver request by setting the DMAR bit
- in the USART CR3 register */
- SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Pauses the DMA Transfer.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda)
-{
- uint32_t dmarequest = 0x00U;
-
- /* Process Locked */
- __HAL_LOCK(hirda);
-
- dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT);
- if((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest)
- {
- /* Disable the IRDA DMA Tx request */
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
- }
-
- dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
- if((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest)
- {
- /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
-
- /* Disable the IRDA DMA Rx request */
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
- }
-
- /* Process Unlocked */
- __HAL_UNLOCK(hirda);
-
- return HAL_OK;
-}
-
-/**
- * @brief Resumes the DMA Transfer.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda)
-{
- /* Process Locked */
- __HAL_LOCK(hirda);
-
- if(hirda->gState == HAL_IRDA_STATE_BUSY_TX)
- {
- /* Enable the IRDA DMA Tx request */
- SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
- }
-
- if(hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
- {
- /* Clear the Overrun flag before resuming the Rx transfer */
- __HAL_IRDA_CLEAR_OREFLAG(hirda);
-
- /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */
- SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
- SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
-
- /* Enable the IRDA DMA Rx request */
- SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
- }
-
- /* Process Unlocked */
- __HAL_UNLOCK(hirda);
-
- return HAL_OK;
-}
-
-/**
- * @brief Stops the DMA Transfer.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda)
-{
- uint32_t dmarequest = 0x00U;
- /* The Lock is not implemented on this API to allow the user application
- to call the HAL IRDA API under callbacks HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback():
- when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
- and the correspond call back is executed HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback()
- */
-
- /* Stop IRDA DMA Tx request if ongoing */
- dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT);
- if((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest)
- {
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
-
- /* Abort the IRDA DMA Tx channel */
- if(hirda->hdmatx != NULL)
- {
- HAL_DMA_Abort(hirda->hdmatx);
- }
- IRDA_EndTxTransfer(hirda);
- }
-
- /* Stop IRDA DMA Rx request if ongoing */
- dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
- if((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest)
- {
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the IRDA DMA Rx channel */
- if(hirda->hdmarx != NULL)
- {
- HAL_DMA_Abort(hirda->hdmarx);
- }
- IRDA_EndRxTransfer(hirda);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing transfers (blocking mode).
- * @param hirda IRDA handle.
- * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
- * - Set handle State to READY
- * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_IRDA_Abort(IRDA_HandleTypeDef *hirda)
-{
- /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
-
- /* Disable the IRDA DMA Tx request if enabled */
- if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
- {
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
-
- /* Abort the IRDA DMA Tx channel: use blocking DMA Abort API (no callback) */
- if(hirda->hdmatx != NULL)
- {
- /* Set the IRDA DMA Abort callback to Null.
- No call back execution at end of DMA abort procedure */
- hirda->hdmatx->XferAbortCallback = NULL;
-
- HAL_DMA_Abort(hirda->hdmatx);
- }
- }
-
- /* Disable the IRDA DMA Rx request if enabled */
- if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
- {
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the IRDA DMA Rx channel: use blocking DMA Abort API (no callback) */
- if(hirda->hdmarx != NULL)
- {
- /* Set the IRDA DMA Abort callback to Null.
- No call back execution at end of DMA abort procedure */
- hirda->hdmarx->XferAbortCallback = NULL;
-
- HAL_DMA_Abort(hirda->hdmarx);
- }
- }
-
- /* Reset Tx and Rx transfer counters */
- hirda->TxXferCount = 0x00U;
- hirda->RxXferCount = 0x00U;
-
- /* Reset ErrorCode */
- hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
-
- /* Restore hirda->RxState and hirda->gState to Ready */
- hirda->RxState = HAL_IRDA_STATE_READY;
- hirda->gState = HAL_IRDA_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing Transmit transfer (blocking mode).
- * @param hirda IRDA handle.
- * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
- * - Set handle State to READY
- * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef *hirda)
-{
- /* Disable TXEIE and TCIE interrupts */
- CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
-
- /* Disable the IRDA DMA Tx request if enabled */
- if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
- {
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
-
- /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
- if(hirda->hdmatx != NULL)
- {
- /* Set the IRDA DMA Abort callback to Null.
- No call back execution at end of DMA abort procedure */
- hirda->hdmatx->XferAbortCallback = NULL;
-
- HAL_DMA_Abort(hirda->hdmatx);
- }
- }
-
- /* Reset Tx transfer counter */
- hirda->TxXferCount = 0x00U;
-
- /* Restore hirda->gState to Ready */
- hirda->gState = HAL_IRDA_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing Receive transfer (blocking mode).
- * @param hirda IRDA handle.
- * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
- * - Set handle State to READY
- * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_IRDA_AbortReceive(IRDA_HandleTypeDef *hirda)
-{
- /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
-
- /* Disable the IRDA DMA Rx request if enabled */
- if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
- {
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
- if(hirda->hdmarx != NULL)
- {
- /* Set the IRDA DMA Abort callback to Null.
- No call back execution at end of DMA abort procedure */
- hirda->hdmarx->XferAbortCallback = NULL;
-
- HAL_DMA_Abort(hirda->hdmarx);
- }
- }
-
- /* Reset Rx transfer counter */
- hirda->RxXferCount = 0x00U;
-
- /* Restore hirda->RxState to Ready */
- hirda->RxState = HAL_IRDA_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing transfers (Interrupt mode).
- * @param hirda IRDA handle.
- * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
- * - Set handle State to READY
- * - At abort completion, call user abort complete callback
- * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
- * considered as completed only when user abort complete callback is executed (not when exiting function).
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_IRDA_Abort_IT(IRDA_HandleTypeDef *hirda)
-{
- uint32_t AbortCplt = 0x01U;
-
- /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
-
- /* If DMA Tx and/or DMA Rx Handles are associated to IRDA Handle, DMA Abort complete callbacks should be initialised
- before any call to DMA Abort functions */
- /* DMA Tx Handle is valid */
- if(hirda->hdmatx != NULL)
- {
- /* Set DMA Abort Complete callback if IRDA DMA Tx request if enabled.
- Otherwise, set it to NULL */
- if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
- {
- hirda->hdmatx->XferAbortCallback = IRDA_DMATxAbortCallback;
- }
- else
- {
- hirda->hdmatx->XferAbortCallback = NULL;
- }
- }
- /* DMA Rx Handle is valid */
- if(hirda->hdmarx != NULL)
- {
- /* Set DMA Abort Complete callback if IRDA DMA Rx request if enabled.
- Otherwise, set it to NULL */
- if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
- {
- hirda->hdmarx->XferAbortCallback = IRDA_DMARxAbortCallback;
- }
- else
- {
- hirda->hdmarx->XferAbortCallback = NULL;
- }
- }
-
- /* Disable the IRDA DMA Tx request if enabled */
- if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
- {
- /* Disable DMA Tx at IRDA level */
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
-
- /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */
- if(hirda->hdmatx != NULL)
- {
- /* IRDA Tx DMA Abort callback has already been initialised :
- will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
-
- /* Abort DMA TX */
- if(HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
- {
- hirda->hdmatx->XferAbortCallback = NULL;
- }
- else
- {
- AbortCplt = 0x00U;
- }
- }
- }
-
- /* Disable the IRDA DMA Rx request if enabled */
- if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
- {
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */
- if(hirda->hdmarx != NULL)
- {
- /* IRDA Rx DMA Abort callback has already been initialised :
- will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
-
- /* Abort DMA RX */
- if(HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
- {
- hirda->hdmarx->XferAbortCallback = NULL;
- AbortCplt = 0x01U;
- }
- else
- {
- AbortCplt = 0x00U;
- }
- }
- }
-
- /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
- if(AbortCplt == 0x01U)
- {
- /* Reset Tx and Rx transfer counters */
- hirda->TxXferCount = 0x00U;
- hirda->RxXferCount = 0x00U;
-
- /* Reset ErrorCode */
- hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
-
- /* Restore hirda->gState and hirda->RxState to Ready */
- hirda->gState = HAL_IRDA_STATE_READY;
- hirda->RxState = HAL_IRDA_STATE_READY;
-
- /* As no DMA to be aborted, call directly user Abort complete callback */
- HAL_IRDA_AbortCpltCallback(hirda);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing Transmit transfer (Interrupt mode).
- * @param hirda IRDA handle.
- * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
- * - Set handle State to READY
- * - At abort completion, call user abort complete callback
- * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
- * considered as completed only when user abort complete callback is executed (not when exiting function).
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef *hirda)
-{
- /* Disable TXEIE and TCIE interrupts */
- CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
-
- /* Disable the IRDA DMA Tx request if enabled */
- if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
- {
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
-
- /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
- if(hirda->hdmatx != NULL)
- {
- /* Set the IRDA DMA Abort callback :
- will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
- hirda->hdmatx->XferAbortCallback = IRDA_DMATxOnlyAbortCallback;
-
- /* Abort DMA TX */
- if(HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
- {
- /* Call Directly hirda->hdmatx->XferAbortCallback function in case of error */
- hirda->hdmatx->XferAbortCallback(hirda->hdmatx);
- }
- }
- else
- {
- /* Reset Tx transfer counter */
- hirda->TxXferCount = 0x00U;
-
- /* Restore hirda->gState to Ready */
- hirda->gState = HAL_IRDA_STATE_READY;
-
- /* As no DMA to be aborted, call directly user Abort complete callback */
- HAL_IRDA_AbortTransmitCpltCallback(hirda);
- }
- }
- else
- {
- /* Reset Tx transfer counter */
- hirda->TxXferCount = 0x00U;
-
- /* Restore hirda->gState to Ready */
- hirda->gState = HAL_IRDA_STATE_READY;
-
- /* As no DMA to be aborted, call directly user Abort complete callback */
- HAL_IRDA_AbortTransmitCpltCallback(hirda);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing Receive transfer (Interrupt mode).
- * @param hirda IRDA handle.
- * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
- * - Set handle State to READY
- * - At abort completion, call user abort complete callback
- * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
- * considered as completed only when user abort complete callback is executed (not when exiting function).
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef *hirda)
-{
- /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
-
- /* Disable the IRDA DMA Rx request if enabled */
- if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
- {
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
- if(hirda->hdmarx != NULL)
- {
- /* Set the IRDA DMA Abort callback :
- will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
- hirda->hdmarx->XferAbortCallback = IRDA_DMARxOnlyAbortCallback;
-
- /* Abort DMA RX */
- if(HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
- {
- /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */
- hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
- }
- }
- else
- {
- /* Reset Rx transfer counter */
- hirda->RxXferCount = 0x00U;
-
- /* Restore hirda->RxState to Ready */
- hirda->RxState = HAL_IRDA_STATE_READY;
-
- /* As no DMA to be aborted, call directly user Abort complete callback */
- HAL_IRDA_AbortReceiveCpltCallback(hirda);
- }
- }
- else
- {
- /* Reset Rx transfer counter */
- hirda->RxXferCount = 0x00U;
-
- /* Restore hirda->RxState to Ready */
- hirda->RxState = HAL_IRDA_STATE_READY;
-
- /* As no DMA to be aborted, call directly user Abort complete callback */
- HAL_IRDA_AbortReceiveCpltCallback(hirda);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief This function handles IRDA interrupt request.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @retval None
- */
-void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda)
-{
- uint32_t isrflags = READ_REG(hirda->Instance->SR);
- uint32_t cr1its = READ_REG(hirda->Instance->CR1);
- uint32_t cr3its = READ_REG(hirda->Instance->CR3);
- uint32_t errorflags = 0x00U;
- uint32_t dmarequest = 0x00U;
-
- /* If no error occurs */
- errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
- if(errorflags == RESET)
- {
- /* IRDA in mode Receiver -----------------------------------------------*/
- if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
- {
- IRDA_Receive_IT(hirda);
- return;
- }
- }
-
- /* If some errors occur */
- if((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
- {
- /* IRDA parity error interrupt occurred -------------------------------*/
- if(((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
- {
- hirda->ErrorCode |= HAL_IRDA_ERROR_PE;
- }
-
- /* IRDA noise error interrupt occurred --------------------------------*/
- if(((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
- {
- hirda->ErrorCode |= HAL_IRDA_ERROR_NE;
- }
-
- /* IRDA frame error interrupt occurred --------------------------------*/
- if(((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
- {
- hirda->ErrorCode |= HAL_IRDA_ERROR_FE;
- }
-
- /* IRDA Over-Run interrupt occurred -----------------------------------*/
- if(((isrflags & USART_SR_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
- {
- hirda->ErrorCode |= HAL_IRDA_ERROR_ORE;
- }
- /* Call IRDA Error Call back function if need be -----------------------*/
- if(hirda->ErrorCode != HAL_IRDA_ERROR_NONE)
- {
- /* IRDA in mode Receiver ---------------------------------------------*/
- if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
- {
- IRDA_Receive_IT(hirda);
- }
-
- /* If Overrun error occurs, or if any error occurs in DMA mode reception,
- consider error as blocking */
- dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
- if(((hirda->ErrorCode & HAL_IRDA_ERROR_ORE) != RESET) || dmarequest)
- {
- /* Blocking error : transfer is aborted
- Set the IRDA state ready to be able to start again the process,
- Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
- IRDA_EndRxTransfer(hirda);
-
- /* Disable the IRDA DMA Rx request if enabled */
- if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
- {
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the IRDA DMA Rx channel */
- if(hirda->hdmarx != NULL)
- {
- /* Set the IRDA DMA Abort callback :
- will lead to call HAL_IRDA_ErrorCallback() at end of DMA abort procedure */
- hirda->hdmarx->XferAbortCallback = IRDA_DMAAbortOnError;
-
- if(HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
- {
- /* Call Directly XferAbortCallback function in case of error */
- hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
- }
- }
- else
- {
- /* Call user error callback */
- HAL_IRDA_ErrorCallback(hirda);
- }
- }
- else
- {
- /* Call user error callback */
- HAL_IRDA_ErrorCallback(hirda);
- }
- }
- else
- {
- /* Non Blocking error : transfer could go on.
- Error is notified to user through user error callback */
- HAL_IRDA_ErrorCallback(hirda);
- hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
- }
- }
- return;
- } /* End if some error occurs */
-
- /* IRDA in mode Transmitter ------------------------------------------------*/
- if(((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
- {
- IRDA_Transmit_IT(hirda);
- return;
- }
-
- /* IRDA in mode Transmitter end --------------------------------------------*/
- if(((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
- {
- IRDA_EndTransmit_IT(hirda);
- return;
- }
-}
-
-/**
- * @brief Tx Transfer complete callbacks.
- * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @retval None
- */
-__weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hirda);
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_IRDA_TxCpltCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief Tx Half Transfer completed callbacks.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval None
- */
-__weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hirda);
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_IRDA_TxHalfCpltCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief Rx Transfer complete callbacks.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @retval None
- */
-__weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hirda);
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_IRDA_RxCpltCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief Rx Half Transfer complete callbacks.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @retval None
- */
-__weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hirda);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_IRDA_RxHalfCpltCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief IRDA error callbacks.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @retval None
- */
-__weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hirda);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_IRDA_ErrorCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief IRDA Abort Complete callback.
- * @param hirda IRDA handle.
- * @retval None
- */
-__weak void HAL_IRDA_AbortCpltCallback(IRDA_HandleTypeDef *hirda)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hirda);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_IRDA_AbortCpltCallback can be implemented in the user file.
- */
-}
-
-/**
- * @brief IRDA Abort Transmit Complete callback.
- * @param hirda IRDA handle.
- * @retval None
- */
-__weak void HAL_IRDA_AbortTransmitCpltCallback(IRDA_HandleTypeDef *hirda)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hirda);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_IRDA_AbortTransmitCpltCallback can be implemented in the user file.
- */
-}
-
-/**
- * @brief IRDA Abort ReceiveComplete callback.
- * @param hirda IRDA handle.
- * @retval None
- */
-__weak void HAL_IRDA_AbortReceiveCpltCallback(IRDA_HandleTypeDef *hirda)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hirda);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_IRDA_AbortReceiveCpltCallback can be implemented in the user file.
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup IRDA_Exported_Functions_Group3 Peripheral State and Errors functions
- * @brief IRDA State and Errors functions
- *
-@verbatim
- ==============================================================================
- ##### Peripheral State and Errors functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to return the State of IrDA
- communication process and also return Peripheral Errors occurred during communication process
- (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state of the IrDA peripheral.
- (+) HAL_IRDA_GetError() check in run-time errors that could be occurred during communication.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Returns the IRDA state.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @retval HAL state
- */
-HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda)
-{
- uint32_t temp1 = 0x00U, temp2 = 0x00U;
- temp1 = hirda->gState;
- temp2 = hirda->RxState;
-
- return (HAL_IRDA_StateTypeDef)(temp1 | temp2);
-}
-
-/**
- * @brief Return the IRDA error code
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @retval IRDA Error Code
- */
-uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda)
-{
- return hirda->ErrorCode;
-}
-
-/**
- * @}
- */
-
-/**
- * @brief DMA IRDA transmit process complete callback.
- * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma)
-{
- IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- /* DMA Normal mode */
- if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
- {
- hirda->TxXferCount = 0U;
-
- /* Disable the DMA transfer for transmit request by setting the DMAT bit
- in the IRDA CR3 register */
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
-
- /* Enable the IRDA Transmit Complete Interrupt */
- __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC);
- }
- /* DMA Circular mode */
- else
- {
- HAL_IRDA_TxCpltCallback(hirda);
- }
-}
-
-/**
- * @brief DMA IRDA receive process half complete callback
- * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma)
-{
- IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- HAL_IRDA_TxHalfCpltCallback(hirda);
-}
-
-/**
- * @brief DMA IRDA receive process complete callback.
- * @param hdma: DMA handle
- * @retval None
- */
-static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
-{
- IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- /* DMA Normal mode */
- if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
- {
- hirda->RxXferCount = 0U;
-
- /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
-
- /* Disable the DMA transfer for the receiver request by setting the DMAR bit
- in the IRDA CR3 register */
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
-
- /* At end of Rx process, restore hirda->RxState to Ready */
- hirda->RxState = HAL_IRDA_STATE_READY;
- }
- HAL_IRDA_RxCpltCallback(hirda);
-}
-
-/**
- * @brief DMA IRDA receive process half complete callback
- * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma)
-{
- IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- HAL_IRDA_RxHalfCpltCallback(hirda);
-}
-
-/**
- * @brief DMA IRDA communication error callback.
- * @param hdma: DMA handle
- * @retval None
- */
-static void IRDA_DMAError(DMA_HandleTypeDef *hdma)
-{
- uint32_t dmarequest = 0x00U;
- IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- /* Stop IRDA DMA Tx request if ongoing */
- dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT);
- if((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest)
- {
- hirda->TxXferCount = 0U;
- IRDA_EndTxTransfer(hirda);
- }
-
- /* Stop IRDA DMA Rx request if ongoing */
- dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
- if((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest)
- {
- hirda->RxXferCount = 0U;
- IRDA_EndRxTransfer(hirda);
- }
-
- hirda->ErrorCode |= HAL_IRDA_ERROR_DMA;
-
- HAL_IRDA_ErrorCallback(hirda);
-}
-
-/**
- * @brief This function handles IRDA Communication Timeout.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @param Flag: specifies the IRDA flag to check.
- * @param Status: The new Flag status (SET or RESET).
- * @param Tickstart: Tick start value
- * @param Timeout: Timeout duration
- * @retval HAL status
- */
-static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
-{
- /* Wait until flag is set */
- while((__HAL_IRDA_GET_FLAG(hirda, Flag) ? SET : RESET) == Status)
- {
- /* Check for the Timeout */
- if(Timeout != HAL_MAX_DELAY)
- {
- if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout))
- {
- /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
- CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
-
- hirda->gState = HAL_IRDA_STATE_READY;
- hirda->RxState = HAL_IRDA_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hirda);
-
- return HAL_TIMEOUT;
- }
- }
- }
- return HAL_OK;
-}
-
-/**
- * @brief End ongoing Tx transfer on IRDA peripheral (following error detection or Transmit completion).
- * @param hirda: IRDA handle.
- * @retval None
- */
-static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda)
-{
- /* Disable TXEIE and TCIE interrupts */
- CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
-
- /* At end of Tx process, restore hirda->gState to Ready */
- hirda->gState = HAL_IRDA_STATE_READY;
-}
-
-/**
- * @brief End ongoing Rx transfer on IRDA peripheral (following error detection or Reception completion).
- * @param hirda: IRDA handle.
- * @retval None
- */
-static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda)
-{
- /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
-
- /* At end of Rx process, restore hirda->RxState to Ready */
- hirda->RxState = HAL_IRDA_STATE_READY;
-}
-
-/**
- * @brief DMA IRDA communication abort callback, when initiated by HAL services on Error
- * (To be called at end of DMA Abort procedure following error occurrence).
- * @param hdma DMA handle.
- * @retval None
- */
-static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma)
-{
- IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- hirda->RxXferCount = 0x00U;
- hirda->TxXferCount = 0x00U;
-
- HAL_IRDA_ErrorCallback(hirda);
-}
-
-/**
- * @brief DMA IRDA Tx communication abort callback, when initiated by user
- * (To be called at end of DMA Tx Abort procedure following user abort request).
- * @note When this callback is executed, User Abort complete call back is called only if no
- * Abort still ongoing for Rx DMA Handle.
- * @param hdma DMA handle.
- * @retval None
- */
-static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
-{
- IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- hirda->hdmatx->XferAbortCallback = NULL;
-
- /* Check if an Abort process is still ongoing */
- if(hirda->hdmarx != NULL)
- {
- if(hirda->hdmarx->XferAbortCallback != NULL)
- {
- return;
- }
- }
-
- /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
- hirda->TxXferCount = 0x00U;
- hirda->RxXferCount = 0x00U;
-
- /* Reset ErrorCode */
- hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
-
- /* Restore hirda->gState and hirda->RxState to Ready */
- hirda->gState = HAL_IRDA_STATE_READY;
- hirda->RxState = HAL_IRDA_STATE_READY;
-
- /* Call user Abort complete callback */
- HAL_IRDA_AbortCpltCallback(hirda);
-}
-
-/**
- * @brief DMA IRDA Rx communication abort callback, when initiated by user
- * (To be called at end of DMA Rx Abort procedure following user abort request).
- * @note When this callback is executed, User Abort complete call back is called only if no
- * Abort still ongoing for Tx DMA Handle.
- * @param hdma DMA handle.
- * @retval None
- */
-static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
-{
- IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- hirda->hdmarx->XferAbortCallback = NULL;
-
- /* Check if an Abort process is still ongoing */
- if(hirda->hdmatx != NULL)
- {
- if(hirda->hdmatx->XferAbortCallback != NULL)
- {
- return;
- }
- }
-
- /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
- hirda->TxXferCount = 0x00U;
- hirda->RxXferCount = 0x00U;
-
- /* Reset ErrorCode */
- hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
-
- /* Restore hirda->gState and hirda->RxState to Ready */
- hirda->gState = HAL_IRDA_STATE_READY;
- hirda->RxState = HAL_IRDA_STATE_READY;
-
- /* Call user Abort complete callback */
- HAL_IRDA_AbortCpltCallback(hirda);
-}
-
-/**
- * @brief DMA IRDA Tx communication abort callback, when initiated by user by a call to
- * HAL_IRDA_AbortTransmit_IT API (Abort only Tx transfer)
- * (This callback is executed at end of DMA Tx Abort procedure following user abort request,
- * and leads to user Tx Abort Complete callback execution).
- * @param hdma DMA handle.
- * @retval None
- */
-static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
-{
- IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- hirda->TxXferCount = 0x00U;
-
- /* Restore hirda->gState to Ready */
- hirda->gState = HAL_IRDA_STATE_READY;
-
- /* Call user Abort complete callback */
- HAL_IRDA_AbortTransmitCpltCallback(hirda);
-}
-
-/**
- * @brief DMA IRDA Rx communication abort callback, when initiated by user by a call to
- * HAL_IRDA_AbortReceive_IT API (Abort only Rx transfer)
- * (This callback is executed at end of DMA Rx Abort procedure following user abort request,
- * and leads to user Rx Abort Complete callback execution).
- * @param hdma DMA handle.
- * @retval None
- */
-static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
-{
- IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- hirda->RxXferCount = 0x00U;
-
- /* Restore hirda->RxState to Ready */
- hirda->RxState = HAL_IRDA_STATE_READY;
-
- /* Call user Abort complete callback */
- HAL_IRDA_AbortReceiveCpltCallback(hirda);
-}
-
-/**
- * @brief Send an amount of data in non blocking mode.
- * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @retval HAL status
- */
-static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda)
-{
- uint16_t* tmp;
-
- /* Check that a Tx process is ongoing */
- if(hirda->gState == HAL_IRDA_STATE_BUSY_TX)
- {
- if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
- {
- tmp = (uint16_t*) hirda->pTxBuffPtr;
- hirda->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
- if(hirda->Init.Parity == IRDA_PARITY_NONE)
- {
- hirda->pTxBuffPtr += 2U;
- }
- else
- {
- hirda->pTxBuffPtr += 1U;
- }
- }
- else
- {
- hirda->Instance->DR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0x00FF);
- }
-
- if(--hirda->TxXferCount == 0U)
- {
- /* Disable the IRDA Transmit Data Register Empty Interrupt */
- CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TXEIE);
-
- /* Enable the IRDA Transmit Complete Interrupt */
- SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
- }
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Wraps up transmission in non blocking mode.
- * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @retval HAL status
- */
-static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda)
-{
- /* Disable the IRDA Transmit Complete Interrupt */
- CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
-
- /* Tx process is ended, restore hirda->gState to Ready */
- hirda->gState = HAL_IRDA_STATE_READY;
- HAL_IRDA_TxCpltCallback(hirda);
-
- return HAL_OK;
-}
-
-/**
- * @brief Receives an amount of data in non blocking mode.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @retval HAL status
- */
-static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda)
-{
- uint16_t* tmp;
- uint16_t uhdata;
-
- /* Check that a Rx process is ongoing */
- if(hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
- {
- uhdata = (uint16_t) READ_REG(hirda->Instance->DR);
- if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
- {
- tmp = (uint16_t*) hirda->pRxBuffPtr;
- if(hirda->Init.Parity == IRDA_PARITY_NONE)
- {
- *tmp = (uint16_t)(uhdata & (uint16_t)0x01FF);
- hirda->pRxBuffPtr += 2U;
- }
- else
- {
- *tmp = (uint16_t)(uhdata & (uint16_t)0x00FF);
- hirda->pRxBuffPtr += 1U;
- }
- }
- else
- {
- if(hirda->Init.Parity == IRDA_PARITY_NONE)
- {
- *hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)0x00FF);
- }
- else
- {
- *hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)0x007F);
- }
- }
-
- if(--hirda->RxXferCount == 0U)
- {
- /* Disable the IRDA Data Register not empty Interrupt */
- __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE);
-
- /* Disable the IRDA Parity Error Interrupt */
- __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE);
-
- /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
- __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
-
- /* Rx process is completed, restore hirda->RxState to Ready */
- hirda->RxState = HAL_IRDA_STATE_READY;
- HAL_IRDA_RxCpltCallback(hirda);
-
- return HAL_OK;
- }
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Configures the IRDA peripheral.
- * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
- * the configuration information for the specified IRDA module.
- * @retval None
- */
-static void IRDA_SetConfig(IRDA_HandleTypeDef *hirda)
-{
- /* Check the parameters */
- assert_param(IS_IRDA_INSTANCE(hirda->Instance));
- assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate));
- assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength));
- assert_param(IS_IRDA_PARITY(hirda->Init.Parity));
- assert_param(IS_IRDA_MODE(hirda->Init.Mode));
- assert_param(IS_IRDA_POWERMODE(hirda->Init.IrDAMode));
-
- /*-------------------------- USART CR2 Configuration ------------------------*/
- /* Clear STOP[13:12] bits */
- CLEAR_BIT(hirda->Instance->CR2, USART_CR2_STOP);
-
- /*-------------------------- USART CR1 Configuration -----------------------*/
- /* Clear M, PCE, PS, TE and RE bits */
- CLEAR_BIT(hirda->Instance->CR1, USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE);
-
- /* Configure the USART Word Length, Parity and mode:
- Set the M bits according to hirda->Init.WordLength value
- Set PCE and PS bits according to hirda->Init.Parity value
- Set TE and RE bits according to hirda->Init.Mode value */
- /* Write to USART CR1 */
- SET_BIT(hirda->Instance->CR1, (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode);
-
- /*-------------------------- USART CR3 Configuration -----------------------*/
- /* Clear CTSE and RTSE bits */
- CLEAR_BIT(hirda->Instance->CR3, USART_CR3_RTSE | USART_CR3_CTSE);
-
- /*-------------------------- USART BRR Configuration -----------------------*/
- if(hirda->Instance == USART1)
- {
- SET_BIT(hirda->Instance->BRR, IRDA_BRR(HAL_RCC_GetPCLK2Freq(), hirda->Init.BaudRate));
- }
- else
- {
- SET_BIT(hirda->Instance->BRR, IRDA_BRR(HAL_RCC_GetPCLK1Freq(), hirda->Init.BaudRate));
- }
-}
-
-/**
- * @}
- */
-
-#endif /* HAL_IRDA_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_iwdg.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_iwdg.c
deleted file mode 100644
index 79fef5d..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_iwdg.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_iwdg.c
- * @author MCD Application Team
- * @brief IWDG HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Independent Watchdog (IWDG) peripheral:
- * + Initialization and Start functions
- * + IO operation functions
- *
- @verbatim
- ==============================================================================
- ##### IWDG Generic features #####
- ==============================================================================
- [..]
- (+) The IWDG can be started by either software or hardware (configurable
- through option byte).
-
- (+) The IWDG is clocked by Low-Speed clock (LSI) and thus stays active even
- if the main clock fails.
-
- (+) Once the IWDG is started, the LSI is forced ON and both can not be
- disabled. The counter starts counting down from the reset value (0xFFF).
- When it reaches the end of count value (0x000) a reset signal is
- generated (IWDG reset).
-
- (+) Whenever the key value 0x0000 AAAA is written in the IWDG_KR register,
- the IWDG_RLR value is reloaded in the counter and the watchdog reset is
- prevented.
-
- (+) The IWDG is implemented in the VDD voltage domain that is still functional
- in STOP and STANDBY mode (IWDG reset can wake-up from STANDBY).
- IWDGRST flag in RCC_CSR register can be used to inform when an IWDG
- reset occurs.
-
- (+) Debug mode : When the microcontroller enters debug mode (core halted),
- the IWDG counter either continues to work normally or stops, depending
- on DBG_IWDG_STOP configuration bit in DBG module, accessible through
- __HAL_DBGMCU_FREEZE_IWDG() and __HAL_DBGMCU_UNFREEZE_IWDG() macros
-
- [..] Min-max timeout value @32KHz (LSI): ~125us / ~32.7s
- The IWDG timeout may vary due to LSI frequency dispersion. STM32F1xx
- devices provide the capability to measure the LSI frequency (LSI clock
- connected internally to TIM5 CH4 input capture). The measured value
- can be used to have an IWDG timeout with an acceptable accuracy.
-
- ##### How to use this driver #####
- ==============================================================================
- [..]
- (#) Use IWDG using HAL_IWDG_Init() function to :
- (++) Enable instance by writing Start keyword in IWDG_KEY register. LSI
- clock is forced ON and IWDG counter starts downcounting.
- (++) Enable write access to configuration register: IWDG_PR & IWDG_RLR.
- (++) Configure the IWDG prescaler and counter reload value. This reload
- value will be loaded in the IWDG counter each time the watchdog is
- reloaded, then the IWDG will start counting down from this value.
- (++) wait for status flags to be reset"
-
- (#) Then the application program must refresh the IWDG counter at regular
- intervals during normal operation to prevent an MCU reset, using
- HAL_IWDG_Refresh() function.
-
- *** IWDG HAL driver macros list ***
- ====================================
- [..]
- Below the list of most used macros in IWDG HAL driver:
- (+) __HAL_IWDG_START: Enable the IWDG peripheral
- (+) __HAL_IWDG_RELOAD_COUNTER: Reloads IWDG counter with value defined in
- the reload register
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#ifdef HAL_IWDG_MODULE_ENABLED
-/** @defgroup IWDG IWDG
- * @brief IWDG HAL module driver.
- * @{
- */
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @defgroup IWDG_Private_Defines IWDG Private Defines
- * @{
- */
-/* Status register need 5 RC LSI divided by prescaler clock to be updated. With
- higher prescaler (256), and according to HSI variation, we need to wait at
- least 6 cycles so 48 ms. */
-#define HAL_IWDG_DEFAULT_TIMEOUT 48U
-/**
- * @}
- */
-
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-
-/** @addtogroup IWDG_Exported_Functions
- * @{
- */
-
-/** @addtogroup IWDG_Exported_Functions_Group1
- * @brief Initialization and Start functions.
- *
-@verbatim
- ===============================================================================
- ##### Initialization and Start functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Initialize the IWDG according to the specified parameters in the
- IWDG_InitTypeDef of associated handle.
- (+) Once initialization is performed in HAL_IWDG_Init function, Watchdog
- is reloaded in order to exit function with correct time base.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initialize the IWDG according to the specified parameters in the
- * IWDG_InitTypeDef and start watchdog. Before exiting function,
- * watchdog is refreshed in order to have correct time base.
- * @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains
- * the configuration information for the specified IWDG module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg)
-{
- uint32_t tickstart;
-
- /* Check the IWDG handle allocation */
- if (hiwdg == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_IWDG_ALL_INSTANCE(hiwdg->Instance));
- assert_param(IS_IWDG_PRESCALER(hiwdg->Init.Prescaler));
- assert_param(IS_IWDG_RELOAD(hiwdg->Init.Reload));
-
- /* Enable IWDG. LSI is turned on automaticaly */
- __HAL_IWDG_START(hiwdg);
-
- /* Enable write access to IWDG_PR and IWDG_RLR registers by writing 0x5555 in KR */
- IWDG_ENABLE_WRITE_ACCESS(hiwdg);
-
- /* Write to IWDG registers the Prescaler & Reload values to work with */
- hiwdg->Instance->PR = hiwdg->Init.Prescaler;
- hiwdg->Instance->RLR = hiwdg->Init.Reload;
-
- /* Check pending flag, if previous update not done, return timeout */
- tickstart = HAL_GetTick();
-
- /* Wait for register to be updated */
- while (hiwdg->Instance->SR != RESET)
- {
- if ((HAL_GetTick() - tickstart) > HAL_IWDG_DEFAULT_TIMEOUT)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Reload IWDG counter with value defined in the reload register */
- __HAL_IWDG_RELOAD_COUNTER(hiwdg);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @addtogroup IWDG_Exported_Functions_Group2
- * @brief IO operation functions
- *
-@verbatim
- ===============================================================================
- ##### IO operation functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Refresh the IWDG.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Refresh the IWDG.
- * @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains
- * the configuration information for the specified IWDG module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg)
-{
- /* Reload IWDG counter with value defined in the reload register */
- __HAL_IWDG_RELOAD_COUNTER(hiwdg);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* HAL_IWDG_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_mmc.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_mmc.c
deleted file mode 100644
index 2667e18..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_mmc.c
+++ /dev/null
@@ -1,2596 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_mmc.c
- * @author MCD Application Team
- * @brief MMC card HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Secure Digital (MMC) peripheral:
- * + Initialization and de-initialization functions
- * + IO operation functions
- * + Peripheral Control functions
- * + MMC card Control functions
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- This driver implements a high level communication layer for read and write from/to
- this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by
- the user in HAL_MMC_MspInit() function (MSP layer).
- Basically, the MSP layer configuration should be the same as we provide in the
- examples.
- You can easily tailor this configuration according to hardware resources.
-
- [..]
- This driver is a generic layered driver for SDMMC memories which uses the HAL
- SDMMC driver functions to interface with MMC and eMMC cards devices.
- It is used as follows:
-
- (#)Initialize the SDMMC low level resources by implement the HAL_MMC_MspInit() API:
- (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE();
- (##) SDMMC pins configuration for MMC card
- (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
- (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init()
- and according to your pin assignment;
- (##) DMA Configuration if you need to use DMA process (HAL_MMC_ReadBlocks_DMA()
- and HAL_MMC_WriteBlocks_DMA() APIs).
- (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE();
- (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled.
- (##) NVIC configuration if you need to use interrupt process when using DMA transfer.
- (+++) Configure the SDMMC and DMA interrupt priorities using functions
- HAL_NVIC_SetPriority(); DMA priority is superior to SDMMC's priority
- (+++) Enable the NVIC DMA and SDMMC IRQs using function HAL_NVIC_EnableIRQ()
- (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
- and __HAL_MMC_DISABLE_IT() inside the communication process.
- (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
- and __HAL_MMC_CLEAR_IT()
- (##) NVIC configuration if you need to use interrupt process (HAL_MMC_ReadBlocks_IT()
- and HAL_MMC_WriteBlocks_IT() APIs).
- (+++) Configure the SDMMC interrupt priorities using function
- HAL_NVIC_SetPriority();
- (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ()
- (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
- and __HAL_MMC_DISABLE_IT() inside the communication process.
- (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
- and __HAL_MMC_CLEAR_IT()
- (#) At this stage, you can perform MMC read/write/erase operations after MMC card initialization
-
-
- *** MMC Card Initialization and configuration ***
- ================================================
- [..]
- To initialize the MMC Card, use the HAL_MMC_Init() function. It Initializes
- SDMMC IP (STM32 side) and the MMC Card, and put it into StandBy State (Ready for data transfer).
- This function provide the following operations:
-
- (#) Initialize the SDMMC peripheral interface with defaullt configuration.
- The initialization process is done at 400KHz. You can change or adapt
- this frequency by adjusting the "ClockDiv" field.
- The MMC Card frequency (SDMMC_CK) is computed as follows:
-
- SDMMC_CK = SDMMCCLK / (ClockDiv + 2)
-
- In initialization mode and according to the MMC Card standard,
- make sure that the SDMMC_CK frequency doesn't exceed 400KHz.
-
- This phase of initialization is done through SDMMC_Init() and
- SDMMC_PowerState_ON() SDMMC low level APIs.
-
- (#) Initialize the MMC card. The API used is HAL_MMC_InitCard().
- This phase allows the card initialization and identification
- and check the MMC Card type (Standard Capacity or High Capacity)
- The initialization flow is compatible with MMC standard.
-
- This API (HAL_MMC_InitCard()) could be used also to reinitialize the card in case
- of plug-off plug-in.
-
- (#) Configure the MMC Card Data transfer frequency. By Default, the card transfer
- frequency is set to 24MHz. You can change or adapt this frequency by adjusting
- the "ClockDiv" field.
- In transfer mode and according to the MMC Card standard, make sure that the
- SDMMC_CK frequency doesn't exceed 25MHz and 50MHz in High-speed mode switch.
- To be able to use a frequency higher than 24MHz, you should use the SDMMC
- peripheral in bypass mode. Refer to the corresponding reference manual
- for more details.
-
- (#) Select the corresponding MMC Card according to the address read with the step 2.
-
- (#) Configure the MMC Card in wide bus mode: 4-bits data.
-
- *** MMC Card Read operation ***
- ==============================
- [..]
- (+) You can read from MMC card in polling mode by using function HAL_MMC_ReadBlocks().
- This function allows the read of 512 bytes blocks.
- You can choose either one block read operation or multiple block read operation
- by adjusting the "NumberOfBlocks" parameter.
- After this, you have to ensure that the transfer is done correctly. The check is done
- through HAL_MMC_GetCardState() function for MMC card state.
-
- (+) You can read from MMC card in DMA mode by using function HAL_MMC_ReadBlocks_DMA().
- This function allows the read of 512 bytes blocks.
- You can choose either one block read operation or multiple block read operation
- by adjusting the "NumberOfBlocks" parameter.
- After this, you have to ensure that the transfer is done correctly. The check is done
- through HAL_MMC_GetCardState() function for MMC card state.
- You could also check the DMA transfer process through the MMC Rx interrupt event.
-
- (+) You can read from MMC card in Interrupt mode by using function HAL_MMC_ReadBlocks_IT().
- This function allows the read of 512 bytes blocks.
- You can choose either one block read operation or multiple block read operation
- by adjusting the "NumberOfBlocks" parameter.
- After this, you have to ensure that the transfer is done correctly. The check is done
- through HAL_MMC_GetCardState() function for MMC card state.
- You could also check the IT transfer process through the MMC Rx interrupt event.
-
- *** MMC Card Write operation ***
- ===============================
- [..]
- (+) You can write to MMC card in polling mode by using function HAL_MMC_WriteBlocks().
- This function allows the read of 512 bytes blocks.
- You can choose either one block read operation or multiple block read operation
- by adjusting the "NumberOfBlocks" parameter.
- After this, you have to ensure that the transfer is done correctly. The check is done
- through HAL_MMC_GetCardState() function for MMC card state.
-
- (+) You can write to MMC card in DMA mode by using function HAL_MMC_WriteBlocks_DMA().
- This function allows the read of 512 bytes blocks.
- You can choose either one block read operation or multiple block read operation
- by adjusting the "NumberOfBlocks" parameter.
- After this, you have to ensure that the transfer is done correctly. The check is done
- through HAL_MMC_GetCardState() function for MMC card state.
- You could also check the DMA transfer process through the MMC Tx interrupt event.
-
- (+) You can write to MMC card in Interrupt mode by using function HAL_MMC_WriteBlocks_IT().
- This function allows the read of 512 bytes blocks.
- You can choose either one block read operation or multiple block read operation
- by adjusting the "NumberOfBlocks" parameter.
- After this, you have to ensure that the transfer is done correctly. The check is done
- through HAL_MMC_GetCardState() function for MMC card state.
- You could also check the IT transfer process through the MMC Tx interrupt event.
-
- *** MMC card status ***
- ======================
- [..]
- (+) The MMC Status contains status bits that are related to the MMC Memory
- Card proprietary features. To get MMC card status use the HAL_MMC_GetCardStatus().
-
- *** MMC card information ***
- ===========================
- [..]
- (+) To get MMC card information, you can use the function HAL_MMC_GetCardInfo().
- It returns useful information about the MMC card such as block size, card type,
- block number ...
-
- *** MMC card CSD register ***
- ============================
- [..]
- (+) The HAL_MMC_GetCardCSD() API allows to get the parameters of the CSD register.
- Some of the CSD parameters are useful for card initialization and identification.
-
- *** MMC card CID register ***
- ============================
- [..]
- (+) The HAL_MMC_GetCardCID() API allows to get the parameters of the CID register.
- Some of the CID parameters are useful for card initialization and identification.
-
- *** MMC HAL driver macros list ***
- ==================================
- [..]
- Below the list of most used macros in MMC HAL driver.
-
- (+) __HAL_MMC_ENABLE : Enable the MMC device
- (+) __HAL_MMC_DISABLE : Disable the MMC device
- (+) __HAL_MMC_DMA_ENABLE: Enable the SDMMC DMA transfer
- (+) __HAL_MMC_DMA_DISABLE: Disable the SDMMC DMA transfer
- (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt
- (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt
- (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not
- (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags
-
- [..]
- (@) You can refer to the MMC HAL driver header file for more useful macros
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup MMC
- * @{
- */
-
-#ifdef HAL_MMC_MODULE_ENABLED
-
-#if defined(STM32F103xE) || defined(STM32F103xG)
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @addtogroup MMC_Private_Defines
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
-/** @defgroup MMC_Private_Functions MMC Private Functions
- * @{
- */
-static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc);
-static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc);
-static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus);
-static HAL_StatusTypeDef MMC_PowerOFF(MMC_HandleTypeDef *hmmc);
-static HAL_StatusTypeDef MMC_Write_IT(MMC_HandleTypeDef *hmmc);
-static HAL_StatusTypeDef MMC_Read_IT(MMC_HandleTypeDef *hmmc);
-static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma);
-static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
-static void MMC_DMAError(DMA_HandleTypeDef *hdma);
-static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma);
-static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma);
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup MMC_Exported_Functions
- * @{
- */
-
-/** @addtogroup MMC_Exported_Functions_Group1
- * @brief Initialization and de-initialization functions
- *
-@verbatim
- ==============================================================================
- ##### Initialization and de-initialization functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to initialize/de-initialize the MMC
- card device to be ready for use.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the MMC according to the specified parameters in the
- MMC_HandleTypeDef and create the associated handle.
- * @param hmmc: Pointer to the MMC handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc)
-{
- /* Check the MMC handle allocation */
- if(hmmc == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_SDIO_ALL_INSTANCE(hmmc->Instance));
- assert_param(IS_SDIO_CLOCK_EDGE(hmmc->Init.ClockEdge));
- assert_param(IS_SDIO_CLOCK_BYPASS(hmmc->Init.ClockBypass));
- assert_param(IS_SDIO_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave));
- assert_param(IS_SDIO_BUS_WIDE(hmmc->Init.BusWide));
- assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl));
- assert_param(IS_SDIO_CLKDIV(hmmc->Init.ClockDiv));
-
- if(hmmc->State == HAL_MMC_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- hmmc->Lock = HAL_UNLOCKED;
- /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
- HAL_MMC_MspInit(hmmc);
- }
-
- hmmc->State = HAL_MMC_STATE_BUSY;
-
- /* Initialize the Card parameters */
- HAL_MMC_InitCard(hmmc);
-
- /* Initialize the error code */
- hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
-
- /* Initialize the MMC operation */
- hmmc->Context = MMC_CONTEXT_NONE;
-
- /* Initialize the MMC state */
- hmmc->State = HAL_MMC_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the MMC Card.
- * @param hmmc: Pointer to MMC handle
- * @note This function initializes the MMC card. It could be used when a card
- re-initialization is needed.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc)
-{
- uint32_t errorstate = HAL_MMC_ERROR_NONE;
- MMC_InitTypeDef Init;
-
- /* Default SDMMC peripheral configuration for MMC card initialization */
- Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
- Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
- Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
- Init.BusWide = SDIO_BUS_WIDE_1B;
- Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
- Init.ClockDiv = SDIO_INIT_CLK_DIV;
-
- /* Initialize SDMMC peripheral interface with default configuration */
- SDIO_Init(hmmc->Instance, Init);
-
- /* Disable SDMMC Clock */
- __HAL_MMC_DISABLE(hmmc);
-
- /* Set Power State to ON */
- SDIO_PowerState_ON(hmmc->Instance);
-
- /* Enable SDMMC Clock */
- __HAL_MMC_ENABLE(hmmc);
-
- /* Required power up waiting time before starting the SD initialization
- sequence */
- HAL_Delay(2U);
-
- /* Identify card operating voltage */
- errorstate = MMC_PowerON(hmmc);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- hmmc->State = HAL_MMC_STATE_READY;
- hmmc->ErrorCode |= errorstate;
- return HAL_ERROR;
- }
-
- /* Card initialization */
- errorstate = MMC_InitCard(hmmc);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- hmmc->State = HAL_MMC_STATE_READY;
- hmmc->ErrorCode |= errorstate;
- return HAL_ERROR;
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief De-Initializes the MMC card.
- * @param hmmc: Pointer to MMC handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc)
-{
- /* Check the MMC handle allocation */
- if(hmmc == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_SDIO_ALL_INSTANCE(hmmc->Instance));
-
- hmmc->State = HAL_MMC_STATE_BUSY;
-
- /* Set SD power state to off */
- MMC_PowerOFF(hmmc);
-
- /* De-Initialize the MSP layer */
- HAL_MMC_MspDeInit(hmmc);
-
- hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
- hmmc->State = HAL_MMC_STATE_RESET;
-
- return HAL_OK;
-}
-
-
-/**
- * @brief Initializes the MMC MSP.
- * @param hmmc: Pointer to MMC handle
- * @retval None
- */
-__weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hmmc);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_MMC_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief De-Initialize MMC MSP.
- * @param hmmc: Pointer to MMC handle
- * @retval None
- */
-__weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hmmc);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_MMC_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @addtogroup MMC_Exported_Functions_Group2
- * @brief Data transfer functions
- *
-@verbatim
- ==============================================================================
- ##### IO operation functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to manage the data
- transfer from/to MMC card.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Reads block(s) from a specified address in a card. The Data transfer
- * is managed by polling mode.
- * @note This API should be followed by a check on the card state through
- * HAL_MMC_GetCardState().
- * @param hmmc: Pointer to MMC handle
- * @param pData: pointer to the buffer that will contain the received data
- * @param BlockAdd: Block Address from where data is to be read
- * @param NumberOfBlocks: Number of MMC blocks to read
- * @param Timeout: Specify timeout value
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
-{
- SDIO_DataInitTypeDef config;
- uint32_t errorstate = HAL_MMC_ERROR_NONE;
- uint32_t tickstart = HAL_GetTick();
- uint32_t count = 0U, *tempbuff = (uint32_t *)pData;
-
- if(NULL == pData)
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
- return HAL_ERROR;
- }
-
- if(hmmc->State == HAL_MMC_STATE_READY)
- {
- hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
-
- if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
- return HAL_ERROR;
- }
-
- hmmc->State = HAL_MMC_STATE_BUSY;
-
- /* Initialize data control register */
- hmmc->Instance->DCTRL = 0U;
-
- /* Check the Card capacity in term of Logical number of blocks */
- if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
- {
- BlockAdd *= 512U;
- }
-
- /* Set Block Size for Card */
- errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= errorstate;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Configure the MMC DPSM (Data Path State Machine) */
- config.DataTimeOut = SDMMC_DATATIMEOUT;
- config.DataLength = NumberOfBlocks * BLOCKSIZE;
- config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
- config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
- config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
- config.DPSM = SDIO_DPSM_ENABLE;
- SDIO_ConfigData(hmmc->Instance, &config);
-
- /* Read block(s) in polling mode */
- if(NumberOfBlocks > 1U)
- {
- hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
-
- /* Read Multi Block command */
- errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd);
- }
- else
- {
- hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK;
-
- /* Read Single Block command */
- errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd);
- }
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= errorstate;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Poll on SDMMC flags */
-#ifdef SDIO_STA_STBITERR
- while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_STA_STBITERR))
-#else /* SDIO_STA_STBITERR not defined */
- while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
-#endif /* SDIO_STA_STBITERR */
- {
- if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF))
- {
- /* Read data from SDMMC Rx FIFO */
- for(count = 0U; count < 8U; count++)
- {
- *(tempbuff + count) = SDIO_ReadFIFO(hmmc->Instance);
- }
- tempbuff += 8U;
- }
-
- if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
- hmmc->State= HAL_MMC_STATE_READY;
- return HAL_TIMEOUT;
- }
- }
-
- /* Send stop transmission command in case of multiblock read */
- if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
- {
- /* Send stop transmission command */
- errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= errorstate;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
- }
-
- /* Get error state */
- if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
- else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
- else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR))
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Empty FIFO if there is still any data */
- while ((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXDAVL)))
- {
- *tempbuff = SDIO_ReadFIFO(hmmc->Instance);
- tempbuff++;
-
- if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
- hmmc->State= HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
- }
-
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
-
- hmmc->State = HAL_MMC_STATE_READY;
-
- return HAL_OK;
- }
- else
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
- return HAL_ERROR;
- }
-}
-
-/**
- * @brief Allows to write block(s) to a specified address in a card. The Data
- * transfer is managed by polling mode.
- * @note This API should be followed by a check on the card state through
- * HAL_MMC_GetCardState().
- * @param hmmc: Pointer to MMC handle
- * @param pData: pointer to the buffer that will contain the data to transmit
- * @param BlockAdd: Block Address where data will be written
- * @param NumberOfBlocks: Number of MMC blocks to write
- * @param Timeout: Specify timeout value
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
-{
- SDIO_DataInitTypeDef config;
- uint32_t errorstate = HAL_MMC_ERROR_NONE;
- uint32_t tickstart = HAL_GetTick();
- uint32_t count = 0U;
- uint32_t *tempbuff = (uint32_t *)pData;
-
- if(NULL == pData)
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
- return HAL_ERROR;
- }
-
- if(hmmc->State == HAL_MMC_STATE_READY)
- {
- hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
-
- if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
- return HAL_ERROR;
- }
-
- hmmc->State = HAL_MMC_STATE_BUSY;
-
- /* Initialize data control register */
- hmmc->Instance->DCTRL = 0U;
-
- /* Check the Card capacity in term of Logical number of blocks */
- if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
- {
- BlockAdd *= 512U;
- }
-
- /* Set Block Size for Card */
- errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= errorstate;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Write Blocks in Polling mode */
- if(NumberOfBlocks > 1U)
- {
- hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
-
- /* Write Multi Block command */
- errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd);
- }
- else
- {
- hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
-
- /* Write Single Block command */
- errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd);
- }
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= errorstate;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Configure the MMC DPSM (Data Path State Machine) */
- config.DataTimeOut = SDMMC_DATATIMEOUT;
- config.DataLength = NumberOfBlocks * BLOCKSIZE;
- config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
- config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
- config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
- config.DPSM = SDIO_DPSM_ENABLE;
- SDIO_ConfigData(hmmc->Instance, &config);
-
- /* Write block(s) in polling mode */
-#ifdef SDIO_STA_STBITERR
- while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
-#else /* SDIO_STA_STBITERR not defined */
- while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
-#endif /* SDIO_STA_STBITERR */
- {
- if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXFIFOHE))
- {
- /* Write data to SDIO Tx FIFO */
- for(count = 0U; count < 8U; count++)
- {
- SDIO_WriteFIFO(hmmc->Instance, (tempbuff + count));
- }
- tempbuff += 8U;
- }
-
- if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= errorstate;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_TIMEOUT;
- }
- }
-
- /* Send stop transmission command in case of multiblock write */
- if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
- {
- /* Send stop transmission command */
- errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= errorstate;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
- }
-
- /* Get error state */
- if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
- else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
- else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR))
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
-
- hmmc->State = HAL_MMC_STATE_READY;
-
- return HAL_OK;
- }
- else
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
- return HAL_ERROR;
- }
-}
-
-/**
- * @brief Reads block(s) from a specified address in a card. The Data transfer
- * is managed in interrupt mode.
- * @note This API should be followed by a check on the card state through
- * HAL_MMC_GetCardState().
- * @note You could also check the IT transfer process through the MMC Rx
- * interrupt event.
- * @param hmmc: Pointer to MMC handle
- * @param pData: Pointer to the buffer that will contain the received data
- * @param BlockAdd: Block Address from where data is to be read
- * @param NumberOfBlocks: Number of blocks to read.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
-{
- SDIO_DataInitTypeDef config;
- uint32_t errorstate = HAL_MMC_ERROR_NONE;
-
- if(NULL == pData)
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
- return HAL_ERROR;
- }
-
- if(hmmc->State == HAL_MMC_STATE_READY)
- {
- hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
-
- if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
- return HAL_ERROR;
- }
-
- hmmc->State = HAL_MMC_STATE_BUSY;
-
- /* Initialize data control register */
- hmmc->Instance->DCTRL = 0U;
-
- hmmc->pRxBuffPtr = (uint32_t *)pData;
- hmmc->RxXferSize = BLOCKSIZE * NumberOfBlocks;
-
- __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF));
-
- /* Check the Card capacity in term of Logical number of blocks */
- if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
- {
- BlockAdd *= 512U;
- }
-
- /* Configure the MMC DPSM (Data Path State Machine) */
- config.DataTimeOut = SDMMC_DATATIMEOUT;
- config.DataLength = BLOCKSIZE * NumberOfBlocks;
- config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
- config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
- config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
- config.DPSM = SDIO_DPSM_ENABLE;
- SDIO_ConfigData(hmmc->Instance, &config);
-
- /* Set Block Size for Card */
- errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= errorstate;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Read Blocks in IT mode */
- if(NumberOfBlocks > 1U)
- {
- hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
-
- /* Read Multi Block command */
- errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd);
- }
- else
- {
- hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
-
- /* Read Single Block command */
- errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd);
- }
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= errorstate;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Writes block(s) to a specified address in a card. The Data transfer
- * is managed in interrupt mode.
- * @note This API should be followed by a check on the card state through
- * HAL_MMC_GetCardState().
- * @note You could also check the IT transfer process through the MMC Tx
- * interrupt event.
- * @param hmmc: Pointer to MMC handle
- * @param pData: Pointer to the buffer that will contain the data to transmit
- * @param BlockAdd: Block Address where data will be written
- * @param NumberOfBlocks: Number of blocks to write
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
-{
- SDIO_DataInitTypeDef config;
- uint32_t errorstate = HAL_MMC_ERROR_NONE;
-
- if(NULL == pData)
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
- return HAL_ERROR;
- }
-
- if(hmmc->State == HAL_MMC_STATE_READY)
- {
- hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
-
- if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
- return HAL_ERROR;
- }
-
- hmmc->State = HAL_MMC_STATE_BUSY;
-
- /* Initialize data control register */
- hmmc->Instance->DCTRL = 0U;
-
- hmmc->pTxBuffPtr = (uint32_t *)pData;
- hmmc->TxXferSize = BLOCKSIZE * NumberOfBlocks;
-
- /* Enable transfer interrupts */
- __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE));
-
- /* Check the Card capacity in term of Logical number of blocks */
- if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
- {
- BlockAdd *= 512U;
- }
-
- /* Set Block Size for Card */
- errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= errorstate;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Write Blocks in Polling mode */
- if(NumberOfBlocks > 1U)
- {
- hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK| MMC_CONTEXT_IT);
-
- /* Write Multi Block command */
- errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd);
- }
- else
- {
- hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
-
- /* Write Single Block command */
- errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd);
- }
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= errorstate;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Configure the MMC DPSM (Data Path State Machine) */
- config.DataTimeOut = SDMMC_DATATIMEOUT;
- config.DataLength = BLOCKSIZE * NumberOfBlocks;
- config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
- config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
- config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
- config.DPSM = SDIO_DPSM_ENABLE;
- SDIO_ConfigData(hmmc->Instance, &config);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Reads block(s) from a specified address in a card. The Data transfer
- * is managed by DMA mode.
- * @note This API should be followed by a check on the card state through
- * HAL_MMC_GetCardState().
- * @note You could also check the DMA transfer process through the MMC Rx
- * interrupt event.
- * @param hmmc: Pointer MMC handle
- * @param pData: Pointer to the buffer that will contain the received data
- * @param BlockAdd: Block Address from where data is to be read
- * @param NumberOfBlocks: Number of blocks to read.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
-{
- SDIO_DataInitTypeDef config;
- uint32_t errorstate = HAL_MMC_ERROR_NONE;
-
- if(NULL == pData)
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
- return HAL_ERROR;
- }
-
- if(hmmc->State == HAL_MMC_STATE_READY)
- {
- hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
-
- if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
- return HAL_ERROR;
- }
-
- hmmc->State = HAL_MMC_STATE_BUSY;
-
- /* Initialize data control register */
- hmmc->Instance->DCTRL = 0U;
-
-#ifdef SDIO_STA_STBITER
- __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_IT_STBITERR));
-#else /* SDIO_STA_STBITERR not defined */
- __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
-#endif /* SDIO_STA_STBITERR */
-
- /* Set the DMA transfer complete callback */
- hmmc->hdmarx->XferCpltCallback = MMC_DMAReceiveCplt;
-
- /* Set the DMA error callback */
- hmmc->hdmarx->XferErrorCallback = MMC_DMAError;
-
- /* Set the DMA Abort callback */
- hmmc->hdmarx->XferAbortCallback = NULL;
-
- /* Enable the DMA Channel */
- HAL_DMA_Start_IT(hmmc->hdmarx, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)pData, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4);
-
- /* Enable MMC DMA transfer */
- __HAL_MMC_DMA_ENABLE(hmmc);
-
- /* Check the Card capacity in term of Logical number of blocks */
- if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
- {
- BlockAdd *= 512U;
- }
-
- /* Configure the MMC DPSM (Data Path State Machine) */
- config.DataTimeOut = SDMMC_DATATIMEOUT;
- config.DataLength = BLOCKSIZE * NumberOfBlocks;
- config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
- config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
- config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
- config.DPSM = SDIO_DPSM_ENABLE;
- SDIO_ConfigData(hmmc->Instance, &config);
-
- /* Set Block Size for Card */
- errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= errorstate;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Read Blocks in DMA mode */
- if(NumberOfBlocks > 1U)
- {
- hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
-
- /* Read Multi Block command */
- errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd);
- }
- else
- {
- hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
-
- /* Read Single Block command */
- errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd);
- }
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= errorstate;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Writes block(s) to a specified address in a card. The Data transfer
- * is managed by DMA mode.
- * @note This API should be followed by a check on the card state through
- * HAL_MMC_GetCardState().
- * @note You could also check the DMA transfer process through the MMC Tx
- * interrupt event.
- * @param hmmc: Pointer to MMC handle
- * @param pData: Pointer to the buffer that will contain the data to transmit
- * @param BlockAdd: Block Address where data will be written
- * @param NumberOfBlocks: Number of blocks to write
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
-{
- SDIO_DataInitTypeDef config;
- uint32_t errorstate = HAL_MMC_ERROR_NONE;
-
- if(NULL == pData)
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
- return HAL_ERROR;
- }
-
- if(hmmc->State == HAL_MMC_STATE_READY)
- {
- hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
-
- if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
- return HAL_ERROR;
- }
-
- hmmc->State = HAL_MMC_STATE_BUSY;
-
- /* Initialize data control register */
- hmmc->Instance->DCTRL = 0U;
-
- /* Enable MMC Error interrupts */
-#ifdef SDIO_STA_STBITER
- __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR));
-#else /* SDIO_STA_STBITERR not defined */
- __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR));
-#endif /* SDIO_STA_STBITERR */
-
- /* Set the DMA transfer complete callback */
- hmmc->hdmatx->XferCpltCallback = MMC_DMATransmitCplt;
-
- /* Set the DMA error callback */
- hmmc->hdmatx->XferErrorCallback = MMC_DMAError;
-
- /* Set the DMA Abort callback */
- hmmc->hdmatx->XferAbortCallback = NULL;
-
- /* Check the Card capacity in term of Logical number of blocks */
- if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
- {
- BlockAdd *= 512U;
- }
-
- /* Set Block Size for Card */
- errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= errorstate;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Write Blocks in Polling mode */
- if(NumberOfBlocks > 1U)
- {
- hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
-
- /* Write Multi Block command */
- errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd);
- }
- else
- {
- hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
-
- /* Write Single Block command */
- errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd);
- }
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= errorstate;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Enable SDIO DMA transfer */
- __HAL_MMC_DMA_ENABLE(hmmc);
-
- /* Enable the DMA Channel */
- HAL_DMA_Start_IT(hmmc->hdmatx, (uint32_t)pData, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4);
-
- /* Configure the MMC DPSM (Data Path State Machine) */
- config.DataTimeOut = SDMMC_DATATIMEOUT;
- config.DataLength = BLOCKSIZE * NumberOfBlocks;
- config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
- config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
- config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
- config.DPSM = SDIO_DPSM_ENABLE;
- SDIO_ConfigData(hmmc->Instance, &config);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Erases the specified memory area of the given MMC card.
- * @note This API should be followed by a check on the card state through
- * HAL_MMC_GetCardState().
- * @param hmmc: Pointer to MMC handle
- * @param BlockStartAdd: Start Block address
- * @param BlockEndAdd: End Block address
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
-{
- uint32_t errorstate = HAL_MMC_ERROR_NONE;
-
- if(hmmc->State == HAL_MMC_STATE_READY)
- {
- hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
-
- if(BlockEndAdd < BlockStartAdd)
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
- return HAL_ERROR;
- }
-
- if(BlockEndAdd > (hmmc->MmcCard.LogBlockNbr))
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
- return HAL_ERROR;
- }
-
- hmmc->State = HAL_MMC_STATE_BUSY;
-
- /* Check if the card command class supports erase command */
- if(((hmmc->MmcCard.Class) & SDIO_CCCC_ERASE) == 0U)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- if((SDIO_GetResponse(hmmc->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Check the Card capacity in term of Logical number of blocks */
- if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
- {
- BlockStartAdd *= 512U;
- BlockEndAdd *= 512U;
- }
-
- /* Send CMD35 MMC_ERASE_GRP_START with argument as addr */
- errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, BlockStartAdd);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= errorstate;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Send CMD36 MMC_ERASE_GRP_END with argument as addr */
- errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, BlockEndAdd);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= errorstate;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Send CMD38 ERASE */
- errorstate = SDMMC_CmdErase(hmmc->Instance);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->ErrorCode |= errorstate;
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
-
- hmmc->State = HAL_MMC_STATE_READY;
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief This function handles MMC card interrupt request.
- * @param hmmc: Pointer to MMC handle
- * @retval None
- */
-void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
-{
- uint32_t errorstate = HAL_MMC_ERROR_NONE;
-
- /* Check for SDIO interrupt flags */
- if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DATAEND) != RESET)
- {
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_DATAEND);
-
-#ifdef SDIO_STA_STBITERR
- __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
- SDIO_IT_TXUNDERR | SDIO_IT_RXOVERR | SDIO_IT_STBITERR);
-#else /* SDIO_STA_STBITERR not defined */
- __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
- SDIO_IT_TXUNDERR | SDIO_IT_RXOVERR);
-#endif
-
- if((hmmc->Context & MMC_CONTEXT_IT) != RESET)
- {
- if(((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != RESET) || ((hmmc->Context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != RESET))
- {
- errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- hmmc->ErrorCode |= errorstate;
- HAL_MMC_ErrorCallback(hmmc);
- }
- }
-
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
-
- hmmc->State = HAL_MMC_STATE_READY;
- if(((hmmc->Context & MMC_CONTEXT_READ_SINGLE_BLOCK) != RESET) || ((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != RESET))
- {
- HAL_MMC_RxCpltCallback(hmmc);
- }
- else
- {
- HAL_MMC_TxCpltCallback(hmmc);
- }
- }
- else if((hmmc->Context & MMC_CONTEXT_DMA) != RESET)
- {
- if((hmmc->Context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != RESET)
- {
- errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- hmmc->ErrorCode |= errorstate;
- HAL_MMC_ErrorCallback(hmmc);
- }
- }
- if(((hmmc->Context & MMC_CONTEXT_READ_SINGLE_BLOCK) == RESET) && ((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) == RESET))
- {
- /* Disable the DMA transfer for transmit request by setting the DMAEN bit
- in the MMC DCTRL register */
- hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
-
- hmmc->State = HAL_MMC_STATE_READY;
-
- HAL_MMC_TxCpltCallback(hmmc);
- }
- }
- }
-
- else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_TXFIFOHE) != RESET)
- {
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_TXFIFOHE);
-
- MMC_Write_IT(hmmc);
- }
-
- else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_RXFIFOHF) != RESET)
- {
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_RXFIFOHF);
-
- MMC_Read_IT(hmmc);
- }
-
-#ifdef SDIO_STA_STBITERR
- else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR) != RESET)
- {
- /* Set Error code */
- if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL) != RESET)
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
- }
- if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DTIMEOUT) != RESET)
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
- }
- if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_RXOVERR) != RESET)
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
- }
- if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_TXUNDERR) != RESET)
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
- }
- if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_STBITERR) != RESET)
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
- }
-
- /* Clear All flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS | SDIO_FLAG_STBITERR);
-
- /* Disable all interrupts */
- __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
- SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR |SDIO_IT_STBITERR);
-
- if((hmmc->Context & MMC_CONTEXT_DMA) != RESET)
- {
- /* Abort the MMC DMA Streams */
- if(hmmc->hdmatx != NULL)
- {
- /* Set the DMA Tx abort callback */
- hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
- /* Abort DMA in IT mode */
- if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
- {
- MMC_DMATxAbort(hmmc->hdmatx);
- }
- }
- else if(hmmc->hdmarx != NULL)
- {
- /* Set the DMA Rx abort callback */
- hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
- /* Abort DMA in IT mode */
- if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
- {
- MMC_DMARxAbort(hmmc->hdmarx);
- }
- }
- else
- {
- hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
- hmmc->State = HAL_MMC_STATE_READY;
- HAL_MMC_AbortCallback(hmmc);
- }
- }
- else if((hmmc->Context & MMC_CONTEXT_IT) != RESET)
- {
- /* Set the MMC state to ready to be able to start again the process */
- hmmc->State = HAL_MMC_STATE_READY;
- HAL_MMC_ErrorCallback(hmmc);
- }
- }
-#else /* SDIO_STA_STBITERR not defined */
- else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_TXUNDERR) != RESET)
- {
- /* Set Error code */
- if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL) != RESET)
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
- }
- if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DTIMEOUT) != RESET)
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
- }
- if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_RXOVERR) != RESET)
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
- }
- if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_TXUNDERR) != RESET)
- {
- hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
- }
-
- /* Clear All flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
-
- /* Disable all interrupts */
- __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
- SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
-
- if((hmmc->Context & MMC_CONTEXT_DMA) != RESET)
- {
- /* Abort the MMC DMA Streams */
- if(hmmc->hdmatx != NULL)
- {
- /* Set the DMA Tx abort callback */
- hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
- /* Abort DMA in IT mode */
- if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
- {
- MMC_DMATxAbort(hmmc->hdmatx);
- }
- }
- else if(hmmc->hdmarx != NULL)
- {
- /* Set the DMA Rx abort callback */
- hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
- /* Abort DMA in IT mode */
- if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
- {
- MMC_DMARxAbort(hmmc->hdmarx);
- }
- }
- else
- {
- hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
- hmmc->State = HAL_MMC_STATE_READY;
- HAL_MMC_AbortCallback(hmmc);
- }
- }
- else if((hmmc->Context & MMC_CONTEXT_IT) != RESET)
- {
- /* Set the MMC state to ready to be able to start again the process */
- hmmc->State = HAL_MMC_STATE_READY;
- HAL_MMC_ErrorCallback(hmmc);
- }
- }
-#endif /* SDIO_STA_STBITERR */
-}
-
-/**
- * @brief return the MMC state
- * @param hmmc: Pointer to mmc handle
- * @retval HAL state
- */
-HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc)
-{
- return hmmc->State;
-}
-
-/**
-* @brief Return the MMC error code
-* @param hmmc : Pointer to a MMC_HandleTypeDef structure that contains
- * the configuration information.
-* @retval MMC Error Code
-*/
-uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc)
-{
- return hmmc->ErrorCode;
-}
-
-/**
- * @brief Tx Transfer completed callbacks
- * @param hmmc: Pointer to MMC handle
- * @retval None
- */
- __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hmmc);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_MMC_TxCpltCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief Rx Transfer completed callbacks
- * @param hmmc: Pointer MMC handle
- * @retval None
- */
-__weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hmmc);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_MMC_RxCpltCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief MMC error callbacks
- * @param hmmc: Pointer MMC handle
- * @retval None
- */
-__weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hmmc);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_MMC_ErrorCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief MMC Abort callbacks
- * @param hmmc: Pointer MMC handle
- * @retval None
- */
-__weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hmmc);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_MMC_ErrorCallback can be implemented in the user file
- */
-}
-
-
-/**
- * @}
- */
-
-/** @addtogroup MMC_Exported_Functions_Group3
- * @brief management functions
- *
-@verbatim
- ==============================================================================
- ##### Peripheral Control functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to control the MMC card
- operations and get the related information
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Returns information the information of the card which are stored on
- * the CID register.
- * @param hmmc: Pointer to MMC handle
- * @param pCID: Pointer to a HAL_MMC_CIDTypedef structure that
- * contains all CID register parameters
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
-{
- uint32_t tmp = 0U;
-
- /* Byte 0 */
- tmp = (uint8_t)((hmmc->CID[0U] & 0xFF000000U) >> 24U);
- pCID->ManufacturerID = tmp;
-
- /* Byte 1 */
- tmp = (uint8_t)((hmmc->CID[0U] & 0x00FF0000U) >> 16U);
- pCID->OEM_AppliID = tmp << 8U;
-
- /* Byte 2 */
- tmp = (uint8_t)((hmmc->CID[0U] & 0x000000FF00U) >> 8U);
- pCID->OEM_AppliID |= tmp;
-
- /* Byte 3 */
- tmp = (uint8_t)(hmmc->CID[0U] & 0x000000FFU);
- pCID->ProdName1 = tmp << 24U;
-
- /* Byte 4 */
- tmp = (uint8_t)((hmmc->CID[1U] & 0xFF000000U) >> 24U);
- pCID->ProdName1 |= tmp << 16U;
-
- /* Byte 5 */
- tmp = (uint8_t)((hmmc->CID[1U] & 0x00FF0000U) >> 16U);
- pCID->ProdName1 |= tmp << 8U;
-
- /* Byte 6 */
- tmp = (uint8_t)((hmmc->CID[1U] & 0x0000FF00U) >> 8U);
- pCID->ProdName1 |= tmp;
-
- /* Byte 7 */
- tmp = (uint8_t)(hmmc->CID[1U] & 0x000000FFU);
- pCID->ProdName2 = tmp;
-
- /* Byte 8 */
- tmp = (uint8_t)((hmmc->CID[2U] & 0xFF000000U) >> 24U);
- pCID->ProdRev = tmp;
-
- /* Byte 9 */
- tmp = (uint8_t)((hmmc->CID[2U] & 0x00FF0000U) >> 16U);
- pCID->ProdSN = tmp << 24U;
-
- /* Byte 10 */
- tmp = (uint8_t)((hmmc->CID[2U] & 0x0000FF00U) >> 8U);
- pCID->ProdSN |= tmp << 16U;
-
- /* Byte 11 */
- tmp = (uint8_t)(hmmc->CID[2U] & 0x000000FFU);
- pCID->ProdSN |= tmp << 8U;
-
- /* Byte 12 */
- tmp = (uint8_t)((hmmc->CID[3U] & 0xFF000000U) >> 24U);
- pCID->ProdSN |= tmp;
-
- /* Byte 13 */
- tmp = (uint8_t)((hmmc->CID[3U] & 0x00FF0000U) >> 16U);
- pCID->Reserved1 |= (tmp & 0xF0U) >> 4U;
- pCID->ManufactDate = (tmp & 0x0FU) << 8U;
-
- /* Byte 14 */
- tmp = (uint8_t)((hmmc->CID[3U] & 0x0000FF00U) >> 8U);
- pCID->ManufactDate |= tmp;
-
- /* Byte 15 */
- tmp = (uint8_t)(hmmc->CID[3U] & 0x000000FFU);
- pCID->CID_CRC = (tmp & 0xFEU) >> 1U;
- pCID->Reserved2 = 1U;
-
- return HAL_OK;
-}
-
-/**
- * @brief Returns information the information of the card which are stored on
- * the CSD register.
- * @param hmmc: Pointer to MMC handle
- * @param pCSD: Pointer to a HAL_MMC_CardInfoTypeDef structure that
- * contains all CSD register parameters
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
-{
- uint32_t tmp = 0U;
-
- /* Byte 0 */
- tmp = (hmmc->CSD[0U] & 0xFF000000U) >> 24U;
- pCSD->CSDStruct = (uint8_t)((tmp & 0xC0U) >> 6U);
- pCSD->SysSpecVersion = (uint8_t)((tmp & 0x3CU) >> 2U);
- pCSD->Reserved1 = tmp & 0x03U;
-
- /* Byte 1 */
- tmp = (hmmc->CSD[0U] & 0x00FF0000U) >> 16U;
- pCSD->TAAC = (uint8_t)tmp;
-
- /* Byte 2 */
- tmp = (hmmc->CSD[0U] & 0x0000FF00U) >> 8U;
- pCSD->NSAC = (uint8_t)tmp;
-
- /* Byte 3 */
- tmp = hmmc->CSD[0U] & 0x000000FFU;
- pCSD->MaxBusClkFrec = (uint8_t)tmp;
-
- /* Byte 4 */
- tmp = (hmmc->CSD[1U] & 0xFF000000U) >> 24U;
- pCSD->CardComdClasses = (uint16_t)(tmp << 4U);
-
- /* Byte 5 */
- tmp = (hmmc->CSD[1U] & 0x00FF0000U) >> 16U;
- pCSD->CardComdClasses |= (uint16_t)((tmp & 0xF0U) >> 4U);
- pCSD->RdBlockLen = (uint8_t)(tmp & 0x0FU);
-
- /* Byte 6 */
- tmp = (hmmc->CSD[1U] & 0x0000FF00U) >> 8U;
- pCSD->PartBlockRead = (uint8_t)((tmp & 0x80U) >> 7U);
- pCSD->WrBlockMisalign = (uint8_t)((tmp & 0x40U) >> 6U);
- pCSD->RdBlockMisalign = (uint8_t)((tmp & 0x20U) >> 5U);
- pCSD->DSRImpl = (uint8_t)((tmp & 0x10U) >> 4U);
- pCSD->Reserved2 = 0; /*!< Reserved */
-
- pCSD->DeviceSize = (tmp & 0x03U) << 10U;
-
- /* Byte 7 */
- tmp = (uint8_t)(hmmc->CSD[1U] & 0x000000FFU);
- pCSD->DeviceSize |= (tmp) << 2U;
-
- /* Byte 8 */
- tmp = (uint8_t)((hmmc->CSD[2U] & 0xFF000000U) >> 24U);
- pCSD->DeviceSize |= (tmp & 0xC0U) >> 6U;
-
- pCSD->MaxRdCurrentVDDMin = (tmp & 0x38U) >> 3U;
- pCSD->MaxRdCurrentVDDMax = (tmp & 0x07U);
-
- /* Byte 9 */
- tmp = (uint8_t)((hmmc->CSD[2U] & 0x00FF0000U) >> 16U);
- pCSD->MaxWrCurrentVDDMin = (tmp & 0xE0U) >> 5U;
- pCSD->MaxWrCurrentVDDMax = (tmp & 0x1CU) >> 2U;
- pCSD->DeviceSizeMul = (tmp & 0x03U) << 1U;
- /* Byte 10 */
- tmp = (uint8_t)((hmmc->CSD[2] & 0x0000FF00U) >> 8U);
- pCSD->DeviceSizeMul |= (tmp & 0x80U) >> 7U;
-
- hmmc->MmcCard.BlockNbr = (pCSD->DeviceSize + 1U) ;
- hmmc->MmcCard.BlockNbr *= (1U << (pCSD->DeviceSizeMul + 2U));
- hmmc->MmcCard.BlockSize = 1U << (pCSD->RdBlockLen);
-
- hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U);
- hmmc->MmcCard.LogBlockSize = 512U;
-
- pCSD->EraseGrSize = (tmp & 0x40U) >> 6U;
- pCSD->EraseGrMul = (tmp & 0x3FU) << 1U;
-
- /* Byte 11 */
- tmp = (uint8_t)(hmmc->CSD[2U] & 0x000000FFU);
- pCSD->EraseGrMul |= (tmp & 0x80U) >> 7U;
- pCSD->WrProtectGrSize = (tmp & 0x7FU);
-
- /* Byte 12 */
- tmp = (uint8_t)((hmmc->CSD[3U] & 0xFF000000U) >> 24U);
- pCSD->WrProtectGrEnable = (tmp & 0x80U) >> 7U;
- pCSD->ManDeflECC = (tmp & 0x60U) >> 5U;
- pCSD->WrSpeedFact = (tmp & 0x1CU) >> 2U;
- pCSD->MaxWrBlockLen = (tmp & 0x03U) << 2U;
-
- /* Byte 13 */
- tmp = (uint8_t)((hmmc->CSD[3U] & 0x00FF0000U) >> 16U);
- pCSD->MaxWrBlockLen |= (tmp & 0xC0U) >> 6U;
- pCSD->WriteBlockPaPartial = (tmp & 0x20U) >> 5U;
- pCSD->Reserved3 = 0U;
- pCSD->ContentProtectAppli = (tmp & 0x01U);
-
- /* Byte 14 */
- tmp = (uint8_t)((hmmc->CSD[3U] & 0x0000FF00U) >> 8U);
- pCSD->FileFormatGrouop = (tmp & 0x80U) >> 7U;
- pCSD->CopyFlag = (tmp & 0x40U) >> 6U;
- pCSD->PermWrProtect = (tmp & 0x20U) >> 5U;
- pCSD->TempWrProtect = (tmp & 0x10U) >> 4U;
- pCSD->FileFormat = (tmp & 0x0CU) >> 2U;
- pCSD->ECC = (tmp & 0x03U);
-
- /* Byte 15 */
- tmp = (uint8_t)(hmmc->CSD[3U] & 0x000000FFU);
- pCSD->CSD_CRC = (tmp & 0xFEU) >> 1U;
- pCSD->Reserved4 = 1U;
-
- return HAL_OK;
-}
-
-/**
- * @brief Gets the MMC card info.
- * @param hmmc: Pointer to MMC handle
- * @param pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
- * will contain the MMC card status information
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
-{
- pCardInfo->CardType = (uint32_t)(hmmc->MmcCard.CardType);
- pCardInfo->Class = (uint32_t)(hmmc->MmcCard.Class);
- pCardInfo->RelCardAdd = (uint32_t)(hmmc->MmcCard.RelCardAdd);
- pCardInfo->BlockNbr = (uint32_t)(hmmc->MmcCard.BlockNbr);
- pCardInfo->BlockSize = (uint32_t)(hmmc->MmcCard.BlockSize);
- pCardInfo->LogBlockNbr = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
- pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
-
- return HAL_OK;
-}
-
-/**
- * @brief Enables wide bus operation for the requested card if supported by
- * card.
- * @param hmmc: Pointer to MMC handle
- * @param WideMode: Specifies the MMC card wide bus mode
- * This parameter can be one of the following values:
- * @arg SDIO_BUS_WIDE_8B: 8-bit data transfer
- * @arg SDIO_BUS_WIDE_4B: 4-bit data transfer
- * @arg SDIO_BUS_WIDE_1B: 1-bit data transfer
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
-{
- __IO uint32_t count = 0U;
- SDIO_InitTypeDef Init;
- uint32_t errorstate = HAL_MMC_ERROR_NONE;
- uint32_t response = 0U, busy = 0U;
-
- /* Check the parameters */
- assert_param(IS_SDIO_BUS_WIDE(WideMode));
-
- /* Chnage Satte */
- hmmc->State = HAL_MMC_STATE_BUSY;
-
- /* Update Clock for Bus mode update */
- Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
- Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
- Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
- Init.BusWide = WideMode;
- Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
- Init.ClockDiv = SDIO_INIT_CLK_DIV;
- /* Initialize SDIO*/
- SDIO_Init(hmmc->Instance, Init);
-
- if(WideMode == SDIO_BUS_WIDE_8B)
- {
- errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- hmmc->ErrorCode |= errorstate;
- }
- }
- else if(WideMode == SDIO_BUS_WIDE_4B)
- {
- errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- hmmc->ErrorCode |= errorstate;
- }
- }
- else if(WideMode == SDIO_BUS_WIDE_1B)
- {
- errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- hmmc->ErrorCode |= errorstate;
- }
- }
- else
- {
- /* WideMode is not a valid argument*/
- hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
- }
-
- /* Check for switch error and violation of the trial number of sending CMD 13 */
- while(busy == 0U)
- {
- if(count++ == SDMMC_MAX_TRIAL)
- {
- hmmc->State = HAL_MMC_STATE_READY;
- hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
- return HAL_ERROR;
- }
-
- /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
- errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- hmmc->ErrorCode |= errorstate;
- }
-
- /* Get command response */
- response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
-
- /* Get operating voltage*/
- busy = (((response >> 7U) == 1U) ? 0U : 1U);
- }
-
- /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
- count = SDMMC_DATATIMEOUT;
- while((response & 0x00000100U) == 0U)
- {
- if(count-- == 0U)
- {
- hmmc->State = HAL_MMC_STATE_READY;
- hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
- return HAL_ERROR;
- }
-
- /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
- errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- hmmc->ErrorCode |= errorstate;
- }
-
- /* Get command response */
- response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
- }
-
- if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
- hmmc->State = HAL_MMC_STATE_READY;
- return HAL_ERROR;
- }
- else
- {
- /* Configure the SDIO peripheral */
- Init.ClockEdge = hmmc->Init.ClockEdge;
- Init.ClockBypass = hmmc->Init.ClockBypass;
- Init.ClockPowerSave = hmmc->Init.ClockPowerSave;
- Init.BusWide = WideMode;
- Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl;
- Init.ClockDiv = hmmc->Init.ClockDiv;
- SDIO_Init(hmmc->Instance, Init);
- }
-
- /* Change State */
- hmmc->State = HAL_MMC_STATE_READY;
-
- return HAL_OK;
-}
-
-
-/**
- * @brief Gets the current mmc card data state.
- * @param hmmc: pointer to MMC handle
- * @retval Card state
- */
-HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
-{
- HAL_MMC_CardStateTypeDef cardstate = HAL_MMC_CARD_TRANSFER;
- uint32_t errorstate = HAL_MMC_ERROR_NONE;
- uint32_t resp1 = 0U;
-
- errorstate = MMC_SendStatus(hmmc, &resp1);
- if(errorstate != HAL_OK)
- {
- hmmc->ErrorCode |= errorstate;
- }
-
- cardstate = (HAL_MMC_CardStateTypeDef)((resp1 >> 9U) & 0x0FU);
-
- return cardstate;
-}
-
-/**
- * @brief Abort the current transfer and disable the MMC.
- * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
- * the configuration information for MMC module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
-{
- HAL_MMC_CardStateTypeDef CardState;
-
- /* DIsable All interrupts */
- __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
- SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
-
- /* Clear All flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
-
- if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
- {
- /* Disable the MMC DMA request */
- hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
-
- /* Abort the MMC DMA Tx Stream */
- if(hmmc->hdmatx != NULL)
- {
- HAL_DMA_Abort(hmmc->hdmatx);
- }
- /* Abort the MMC DMA Rx Stream */
- if(hmmc->hdmarx != NULL)
- {
- HAL_DMA_Abort(hmmc->hdmarx);
- }
- }
-
- hmmc->State = HAL_MMC_STATE_READY;
- CardState = HAL_MMC_GetCardState(hmmc);
- if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
- {
- hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
- }
- if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
- {
- return HAL_ERROR;
- }
- return HAL_OK;
-}
-
-/**
- * @brief Abort the current transfer and disable the MMC (IT mode).
- * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
- * the configuration information for MMC module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
-{
- HAL_MMC_CardStateTypeDef CardState;
-
- /* DIsable All interrupts */
- __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
- SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
-
- /* Clear All flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
-
- if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
- {
- /* Disable the MMC DMA request */
- hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
-
- /* Abort the MMC DMA Tx Stream */
- if(hmmc->hdmatx != NULL)
- {
- hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
- if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
- {
- hmmc->hdmatx = NULL;
- }
- }
- /* Abort the MMC DMA Rx Stream */
- if(hmmc->hdmarx != NULL)
- {
- hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
- if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
- {
- hmmc->hdmarx = NULL;
- }
- }
- }
-
- /* No transfer ongoing on both DMA channels*/
- if((hmmc->hdmatx == NULL) && (hmmc->hdmarx == NULL))
- {
- CardState = HAL_MMC_GetCardState(hmmc);
- hmmc->State = HAL_MMC_STATE_READY;
- if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
- {
- hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
- }
- if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
- {
- return HAL_ERROR;
- }
- else
- {
- HAL_MMC_AbortCallback(hmmc);
- }
- }
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private function ----------------------------------------------------------*/
-/** @addtogroup MMC_Private_Functions
- * @{
- */
-
-/**
- * @brief DMA MMC transmit process complete callback
- * @param hdma: DMA handle
- * @retval None
- */
-static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma)
-{
- MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
-
- /* Enable DATAEND Interrupt */
- __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DATAEND));
-}
-
-/**
- * @brief DMA MMC receive process complete callback
- * @param hdma: DMA handle
- * @retval None
- */
-static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
-{
- MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
- uint32_t errorstate = HAL_MMC_ERROR_NONE;
-
- /* Send stop command in multiblock write */
- if(hmmc->Context == (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA))
- {
- errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- hmmc->ErrorCode |= errorstate;
- HAL_MMC_ErrorCallback(hmmc);
- }
- }
-
- /* Disable the DMA transfer for transmit request by setting the DMAEN bit
- in the MMC DCTRL register */
- hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
-
- /* Clear all the static flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
-
- hmmc->State = HAL_MMC_STATE_READY;
-
- HAL_MMC_RxCpltCallback(hmmc);
-}
-
-/**
- * @brief DMA MMC communication error callback
- * @param hdma: DMA handle
- * @retval None
- */
-static void MMC_DMAError(DMA_HandleTypeDef *hdma)
-{
- MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
- HAL_MMC_CardStateTypeDef CardState;
-
- if((hmmc->hdmarx->ErrorCode == HAL_DMA_ERROR_TE) || (hmmc->hdmatx->ErrorCode == HAL_DMA_ERROR_TE))
- {
- /* Clear All flags */
- __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
-
- /* Disable All interrupts */
- __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
- SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
-
- hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
- CardState = HAL_MMC_GetCardState(hmmc);
- if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
- {
- hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
- }
-
- hmmc->State= HAL_MMC_STATE_READY;
- }
-
- HAL_MMC_ErrorCallback(hmmc);
-}
-
-/**
- * @brief DMA MMC Tx Abort callback
- * @param hdma: DMA handle
- * @retval None
- */
-static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma)
-{
- MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
- HAL_MMC_CardStateTypeDef CardState;
-
- if(hmmc->hdmatx != NULL)
- {
- hmmc->hdmatx = NULL;
- }
-
- /* All DMA channels are aborted */
- if(hmmc->hdmarx == NULL)
- {
- CardState = HAL_MMC_GetCardState(hmmc);
- hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
- hmmc->State = HAL_MMC_STATE_READY;
- if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
- {
- hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
-
- if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
- {
- HAL_MMC_AbortCallback(hmmc);
- }
- else
- {
- HAL_MMC_ErrorCallback(hmmc);
- }
- }
- }
-}
-
-/**
- * @brief DMA MMC Rx Abort callback
- * @param hdma: DMA handle
- * @retval None
- */
-static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma)
-{
- MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
- HAL_MMC_CardStateTypeDef CardState;
-
- if(hmmc->hdmarx != NULL)
- {
- hmmc->hdmarx = NULL;
- }
-
- /* All DMA channels are aborted */
- if(hmmc->hdmatx == NULL)
- {
- CardState = HAL_MMC_GetCardState(hmmc);
- hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
- hmmc->State = HAL_MMC_STATE_READY;
- if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
- {
- hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
-
- if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
- {
- HAL_MMC_AbortCallback(hmmc);
- }
- else
- {
- HAL_MMC_ErrorCallback(hmmc);
- }
- }
- }
-}
-
-
-/**
- * @brief Initializes the mmc card.
- * @param hmmc: Pointer to MMC handle
- * @retval MMC Card error state
- */
-static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
-{
- HAL_MMC_CardCSDTypeDef CSD;
- uint32_t errorstate = HAL_MMC_ERROR_NONE;
- uint16_t mmc_rca = 1;
-
- /* Check the power State */
- if(SDIO_GetPowerState(hmmc->Instance) == 0U)
- {
- /* Power off */
- return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
- }
-
- /* Send CMD2 ALL_SEND_CID */
- errorstate = SDMMC_CmdSendCID(hmmc->Instance);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- return errorstate;
- }
- else
- {
- /* Get Card identification number data */
- hmmc->CID[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
- hmmc->CID[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2);
- hmmc->CID[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3);
- hmmc->CID[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4);
- }
-
- /* Send CMD3 SET_REL_ADDR with argument 0 */
- /* MMC Card publishes its RCA. */
- errorstate = SDMMC_CmdSetRelAdd(hmmc->Instance, &mmc_rca);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- return errorstate;
- }
-
- /* Get the MMC card RCA */
- hmmc->MmcCard.RelCardAdd = mmc_rca;
-
- /* Send CMD9 SEND_CSD with argument as card's RCA */
- errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- return errorstate;
- }
- else
- {
- /* Get Card Specific Data */
- hmmc->CSD[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
- hmmc->CSD[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2);
- hmmc->CSD[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3);
- hmmc->CSD[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4);
- }
-
- /* Get the Card Class */
- hmmc->MmcCard.Class = (SDIO_GetResponse(hmmc->Instance, SDIO_RESP2) >> 20U);
-
- /* Get CSD parameters */
- HAL_MMC_GetCardCSD(hmmc, &CSD);
-
- /* Select the Card */
- errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- return errorstate;
- }
-
- /* Configure SDIO peripheral interface */
- SDIO_Init(hmmc->Instance, hmmc->Init);
-
- /* All cards are initialized */
- return HAL_MMC_ERROR_NONE;
-}
-
-/**
- * @brief Enquires cards about their operating voltage and configures clock
- * controls and stores MMC information that will be needed in future
- * in the MMC handle.
- * @param hmmc: Pointer to MMC handle
- * @retval error state
- */
-static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
-{
- __IO uint32_t count = 0U;
- uint32_t response = 0U, validvoltage = 0U;
- uint32_t errorstate = HAL_MMC_ERROR_NONE;
-
- /* CMD0: GO_IDLE_STATE */
- errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- return errorstate;
- }
-
- while(validvoltage == 0U)
- {
- if(count++ == SDMMC_MAX_VOLT_TRIAL)
- {
- return HAL_MMC_ERROR_INVALID_VOLTRANGE;
- }
-
- /* SEND CMD1 APP_CMD with MMC_HIGH_VOLTAGE_RANGE(0xC0FF8000) as argument */
- errorstate = SDMMC_CmdOpCondition(hmmc->Instance, eMMC_HIGH_VOLTAGE_RANGE);
- if(errorstate != HAL_MMC_ERROR_NONE)
- {
- return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
- }
-
- /* Get command response */
- response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
-
- /* Get operating voltage*/
- validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
- }
-
- /* When power routine is finished and command returns valid voltage */
- if ((response & eMMC_HIGH_VOLTAGE_RANGE) == MMC_HIGH_VOLTAGE_RANGE)
- {
- /* When voltage range of the card is within 2.7V and 3.6V */
- hmmc->MmcCard.CardType = MMC_HIGH_VOLTAGE_CARD;
- }
- else
- {
- /* When voltage range of the card is within 1.65V and 1.95V or 2.7V and 3.6V */
- hmmc->MmcCard.CardType = MMC_DUAL_VOLTAGE_CARD;
- }
-
- return HAL_MMC_ERROR_NONE;
-}
-
-/**
- * @brief Turns the SDIO output signals off.
- * @param hmmc: Pointer to MMC handle
- * @retval HAL status
- */
-static HAL_StatusTypeDef MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
-{
- /* Set Power State to OFF */
- SDIO_PowerState_OFF(hmmc->Instance);
-
- return HAL_OK;
-}
-
-/**
- * @brief Returns the current card's status.
- * @param hmmc: Pointer to MMC handle
- * @param pCardStatus: pointer to the buffer that will contain the MMC card
- * status (Card Status register)
- * @retval error state
- */
-static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
-{
- uint32_t errorstate = HAL_MMC_ERROR_NONE;
-
- if(pCardStatus == NULL)
- {
- return HAL_MMC_ERROR_PARAM;
- }
-
- /* Send Status command */
- errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
- if(errorstate != HAL_OK)
- {
- return errorstate;
- }
-
- /* Get MMC card status */
- *pCardStatus = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
-
- return HAL_MMC_ERROR_NONE;
-}
-
-/**
- * @brief Wrap up reading in non-blocking mode.
- * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
- * the configuration information.
- * @retval HAL status
- */
-static HAL_StatusTypeDef MMC_Read_IT(MMC_HandleTypeDef *hmmc)
-{
- uint32_t count = 0U;
- uint32_t* tmp;
-
- tmp = (uint32_t*)hmmc->pRxBuffPtr;
-
- /* Read data from SDMMC Rx FIFO */
- for(count = 0U; count < 8U; count++)
- {
- *(tmp + count) = SDIO_ReadFIFO(hmmc->Instance);
- }
-
- hmmc->pRxBuffPtr += 8U;
-
- return HAL_OK;
-}
-
-/**
- * @brief Wrap up writing in non-blocking mode.
- * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
- * the configuration information.
- * @retval HAL status
- */
-static HAL_StatusTypeDef MMC_Write_IT(MMC_HandleTypeDef *hmmc)
-{
- uint32_t count = 0U;
- uint32_t* tmp;
-
- tmp = (uint32_t*)hmmc->pTxBuffPtr;
-
- /* Write data to SDMMC Tx FIFO */
- for(count = 0U; count < 8U; count++)
- {
- SDIO_WriteFIFO(hmmc->Instance, (tmp + count));
- }
-
- hmmc->pTxBuffPtr += 8U;
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-#endif /* STM32F103xE || STM32F103xG */
-
-#endif /* HAL_MMC_MODULE_ENABLED */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_msp_template.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_msp_template.c
deleted file mode 100644
index 3087239..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_msp_template.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_msp_template.c
- * @author MCD Application Team
- * @brief HAL BSP module.
- * This file template is located in the HAL folder and should be copied
- * to the user folder.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup HAL_MSP HAL_MSP
- * @brief HAL MSP module.
- * @{
- */
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
-
-/** @defgroup HAL_MSP_Exported_Functions HAL MSP Exported Functions
- * @{
- */
-
-/**
- * @brief Initializes the Global MSP.
- * @retval None
- */
-void HAL_MspInit(void)
-{
-
-}
-
-/**
- * @brief DeInitializes the Global MSP.
- * @retval None
- */
-void HAL_MspDeInit(void)
-{
-
-}
-
-/**
- * @brief Initializes the PPP MSP.
- * @retval None
- */
-void HAL_PPP_MspInit(void)
-{
-
-}
-
-/**
- * @brief DeInitializes the PPP MSP.
- * @retval None
- */
-void HAL_PPP_MspDeInit(void)
-{
-
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_nand.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_nand.c
deleted file mode 100644
index c32abe8..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_nand.c
+++ /dev/null
@@ -1,1802 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_nand.c
- * @author MCD Application Team
- * @brief NAND HAL module driver.
- * This file provides a generic firmware to drive NAND memories mounted
- * as external device.
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- This driver is a generic layered driver which contains a set of APIs used to
- control NAND flash memories. It uses the FSMC layer functions to interface
- with NAND devices. This driver is used as follows:
-
- (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
- with control and timing parameters for both common and attribute spaces.
-
- (+) Read NAND flash memory maker and device IDs using the function
- HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef
- structure declared by the function caller.
-
- (+) Access NAND flash memory by read/write operations using the functions
- HAL_NAND_Read_Page_8b()/HAL_NAND_Read_SpareArea_8b(),
- HAL_NAND_Write_Page_8b()/HAL_NAND_Write_SpareArea_8b(),
- HAL_NAND_Read_Page_16b()/HAL_NAND_Read_SpareArea_16b(),
- HAL_NAND_Write_Page_16b()/HAL_NAND_Write_SpareArea_16b()
- to read/write page(s)/spare area(s). These functions use specific device
- information (Block, page size..) predefined by the user in the NAND_DeviceConfigTypeDef
- structure. The read/write address information is contained by the Nand_Address_Typedef
- structure passed as parameter.
-
- (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
-
- (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
- The erase block address information is contained in the Nand_Address_Typedef
- structure passed as parameter.
-
- (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
-
- (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
- HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
- feature or the function HAL_NAND_GetECC() to get the ECC correction code.
-
- (+) You can monitor the NAND device HAL state by calling the function
- HAL_NAND_GetState()
-
- [..]
- (@) This driver is a set of generic APIs which handle standard NAND flash operations.
- If a NAND flash device contains different operations and/or implementations,
- it should be implemented separately.
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#ifdef HAL_NAND_MODULE_ENABLED
-
-#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG)
-
-/** @defgroup NAND NAND
- * @brief NAND HAL module driver
- * @{
- */
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @defgroup NAND_Private_Constants NAND Private Constants
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private macro -------------------------------------------------------------*/
-/** @defgroup NAND_Private_Macros NAND Private Macros
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup NAND_Exported_Functions NAND Exported Functions
- * @{
- */
-
-/** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
- @verbatim
- ==============================================================================
- ##### NAND Initialization and de-initialization functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to initialize/de-initialize
- the NAND memory
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Perform NAND memory Initialization sequence
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @param ComSpace_Timing: pointer to Common space timing structure
- * @param AttSpace_Timing: pointer to Attribute space timing structure
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FSMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FSMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
-{
- /* Check the NAND handle state */
- if(hnand == NULL)
- {
- return HAL_ERROR;
- }
-
- if(hnand->State == HAL_NAND_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- hnand->Lock = HAL_UNLOCKED;
- /* Initialize the low level hardware (MSP) */
- HAL_NAND_MspInit(hnand);
- }
-
- /* Initialize NAND control Interface */
- FSMC_NAND_Init(hnand->Instance, &(hnand->Init));
-
- /* Initialize NAND common space timing Interface */
- FSMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
-
- /* Initialize NAND attribute space timing Interface */
- FSMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
-
- /* Enable the NAND device */
- __FSMC_NAND_ENABLE(hnand->Instance, hnand->Init.NandBank);
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Perform NAND memory De-Initialization sequence
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
-{
- /* Initialize the low level hardware (MSP) */
- HAL_NAND_MspDeInit(hnand);
-
- /* Configure the NAND registers with their reset values */
- FSMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
-
- /* Reset the NAND controller state */
- hnand->State = HAL_NAND_STATE_RESET;
-
- /* Release Lock */
- __HAL_UNLOCK(hnand);
-
- return HAL_OK;
-}
-
-/**
- * @brief NAND MSP Init
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @retval None
- */
-__weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hnand);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_NAND_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief NAND MSP DeInit
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @retval None
- */
-__weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hnand);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_NAND_MspDeInit could be implemented in the user file
- */
-}
-
-
-/**
- * @brief This function handles NAND device interrupt request.
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @retval HAL status
-*/
-void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
-{
- /* Check NAND interrupt Rising edge flag */
- if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_RISING_EDGE))
- {
- /* NAND interrupt callback*/
- HAL_NAND_ITCallback(hnand);
-
- /* Clear NAND interrupt Rising edge pending bit */
- __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_RISING_EDGE);
- }
-
- /* Check NAND interrupt Level flag */
- if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_LEVEL))
- {
- /* NAND interrupt callback*/
- HAL_NAND_ITCallback(hnand);
-
- /* Clear NAND interrupt Level pending bit */
- __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_LEVEL);
- }
-
- /* Check NAND interrupt Falling edge flag */
- if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FALLING_EDGE))
- {
- /* NAND interrupt callback*/
- HAL_NAND_ITCallback(hnand);
-
- /* Clear NAND interrupt Falling edge pending bit */
- __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FALLING_EDGE);
- }
-
- /* Check NAND interrupt FIFO empty flag */
- if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FEMPT))
- {
- /* NAND interrupt callback*/
- HAL_NAND_ITCallback(hnand);
-
- /* Clear NAND interrupt FIFO empty pending bit */
- __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FEMPT);
- }
-}
-
-/**
- * @brief NAND interrupt feature callback
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @retval None
- */
-__weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hnand);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_NAND_ITCallback could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
- * @brief Input Output and memory control functions
- *
- @verbatim
- ==============================================================================
- ##### NAND Input and Output functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to use and control the NAND
- memory
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Read the NAND memory electronic signature
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @param pNAND_ID: NAND ID structure
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
-{
- __IO uint32_t data = 0U;
- __IO uint32_t data1 = 0U;
- uint32_t deviceaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnand);
-
- /* Check the NAND controller state */
- if(hnand->State == HAL_NAND_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Identify the device address */
- if(hnand->Init.NandBank == FSMC_NAND_BANK2)
- {
- deviceaddress = NAND_DEVICE1;
- }
- else
- {
- deviceaddress = NAND_DEVICE2;
- }
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_BUSY;
-
- /* Send Read ID command sequence */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_READID;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
-
- /* Read the electronic signature from NAND flash */
- if (hnand->Init.MemoryDataWidth == FSMC_NAND_PCC_MEM_BUS_WIDTH_8)
- {
- data = *(__IO uint32_t *)deviceaddress;
-
- /* Return the data read */
- pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
- pNAND_ID->Device_Id = ADDR_2ND_CYCLE(data);
- pNAND_ID->Third_Id = ADDR_3RD_CYCLE(data);
- pNAND_ID->Fourth_Id = ADDR_4TH_CYCLE(data);
- }
- else
- {
- data = *(__IO uint32_t *)deviceaddress;
- data1 = *((__IO uint32_t *)deviceaddress + 4U);
-
- /* Return the data read */
- pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
- pNAND_ID->Device_Id = ADDR_3RD_CYCLE(data);
- pNAND_ID->Third_Id = ADDR_1ST_CYCLE(data1);
- pNAND_ID->Fourth_Id = ADDR_3RD_CYCLE(data1);
- }
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnand);
-
- return HAL_OK;
-}
-
-/**
- * @brief NAND memory reset
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
-{
- uint32_t deviceaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnand);
-
- /* Check the NAND controller state */
- if(hnand->State == HAL_NAND_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Identify the device address */
- if(hnand->Init.NandBank == FSMC_NAND_BANK2)
- {
- deviceaddress = NAND_DEVICE1;
- }
- else
- {
- deviceaddress = NAND_DEVICE2;
- }
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_BUSY;
-
- /* Send NAND reset command */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = 0xFF;
-
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnand);
-
- return HAL_OK;
-
-}
-
-/**
- * @brief Configure the device: Enter the physical parameters of the device
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @param pDeviceConfig : pointer to NAND_DeviceConfigTypeDef structure
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig)
-{
- hnand->Config.PageSize = pDeviceConfig->PageSize;
- hnand->Config.SpareAreaSize = pDeviceConfig->SpareAreaSize;
- hnand->Config.BlockSize = pDeviceConfig->BlockSize;
- hnand->Config.BlockNbr = pDeviceConfig->BlockNbr;
- hnand->Config.PlaneSize = pDeviceConfig->PlaneSize;
- hnand->Config.PlaneNbr = pDeviceConfig->PlaneNbr;
- hnand->Config.ExtraCommandEnable = pDeviceConfig->ExtraCommandEnable;
-
- return HAL_OK;
-}
-
-/**
- * @brief Read Page(s) from NAND memory block (8-bits addressing)
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @param pAddress : pointer to NAND address structure
- * @param pBuffer : pointer to destination read buffer
- * @param NumPageToRead : number of pages to read from block
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
-{
- __IO uint32_t index = 0U;
- uint32_t tickstart = 0U;
- uint32_t deviceaddress = 0U, size = 0U, numPagesRead = 0U, nandaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnand);
-
- /* Check the NAND controller state */
- if(hnand->State == HAL_NAND_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Identify the device address */
- if(hnand->Init.NandBank == FSMC_NAND_BANK2)
- {
- deviceaddress = NAND_DEVICE1;
- }
- else
- {
- deviceaddress = NAND_DEVICE2;
- }
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_BUSY;
-
- /* NAND raw address calculation */
- nandaddress = ARRAY_ADDRESS(pAddress, hnand);
-
- /* Page(s) read loop */
- while((NumPageToRead != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
- {
- /* update the buffer size */
- size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
-
- /* Send read page command sequence */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
-
- /* Cards with page size <= 512 bytes */
- if((hnand->Config.PageSize) <= 512U)
- {
- if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- }
- else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
- }
- }
- else /* (hnand->Config.PageSize) > 512 */
- {
- if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- }
- else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
- }
- }
-
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
-
- /* Check if an extra command is needed for reading pages */
- if(hnand->Config.ExtraCommandEnable == ENABLE)
- {
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Read status until NAND is ready */
- while(HAL_NAND_Read_Status(hnand) != NAND_READY)
- {
- if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Go back to read mode */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
- }
-
- /* Get Data into Buffer */
- for(; index < size; index++)
- {
- *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
- }
-
- /* Increment read pages number */
- numPagesRead++;
-
- /* Decrement pages to read */
- NumPageToRead--;
-
- /* Increment the NAND address */
- nandaddress = (uint32_t)(nandaddress + 1U);
- }
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnand);
-
- return HAL_OK;
-}
-
-/**
- * @brief Read Page(s) from NAND memory block (16-bits addressing)
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @param pAddress : pointer to NAND address structure
- * @param pBuffer : pointer to destination read buffer. pBuffer should be 16bits aligned
- * @param NumPageToRead : number of pages to read from block
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToRead)
-{
- __IO uint32_t index = 0U;
- uint32_t tickstart = 0U;
- uint32_t deviceaddress = 0U, size = 0U, numPagesRead = 0U, nandaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnand);
-
- /* Check the NAND controller state */
- if(hnand->State == HAL_NAND_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Identify the device address */
- if(hnand->Init.NandBank == FSMC_NAND_BANK2)
- {
- deviceaddress = NAND_DEVICE1;
- }
- else
- {
- deviceaddress = NAND_DEVICE2;
- }
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_BUSY;
-
- /* NAND raw address calculation */
- nandaddress = ARRAY_ADDRESS(pAddress, hnand);
-
- /* Page(s) read loop */
- while((NumPageToRead != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
- {
- /* update the buffer size */
- size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
-
- /* Send read page command sequence */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
-
- /* Cards with page size <= 512 bytes */
- if((hnand->Config.PageSize) <= 512U)
- {
- if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- }
- else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
- }
- }
- else /* (hnand->Config.PageSize) > 512 */
- {
- if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- }
- else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
- }
- }
-
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
-
- if(hnand->Config.ExtraCommandEnable == ENABLE)
- {
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Read status until NAND is ready */
- while(HAL_NAND_Read_Status(hnand) != NAND_READY)
- {
- if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Go back to read mode */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
- }
-
- /* Get Data into Buffer */
- for(; index < size; index++)
- {
- *(uint16_t *)pBuffer++ = *(uint16_t *)deviceaddress;
- }
-
- /* Increment read pages number */
- numPagesRead++;
-
- /* Decrement pages to read */
- NumPageToRead--;
-
- /* Increment the NAND address */
- nandaddress = (uint32_t)(nandaddress + 1U);
- }
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnand);
-
- return HAL_OK;
-}
-
-/**
- * @brief Write Page(s) to NAND memory block (8-bits addressing)
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @param pAddress : pointer to NAND address structure
- * @param pBuffer : pointer to source buffer to write
- * @param NumPageToWrite : number of pages to write to block
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
-{
- __IO uint32_t index = 0U;
- uint32_t tickstart = 0U;
- uint32_t deviceaddress = 0U, size = 0U, numPagesWritten = 0U, nandaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnand);
-
- /* Check the NAND controller state */
- if(hnand->State == HAL_NAND_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Identify the device address */
- if(hnand->Init.NandBank == FSMC_NAND_BANK2)
- {
- deviceaddress = NAND_DEVICE1;
- }
- else
- {
- deviceaddress = NAND_DEVICE2;
- }
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_BUSY;
-
- /* NAND raw address calculation */
- nandaddress = ARRAY_ADDRESS(pAddress, hnand);
-
- /* Page(s) write loop */
- while((NumPageToWrite != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
- {
- /* update the buffer size */
- size = hnand->Config.PageSize + ((hnand->Config.PageSize) * numPagesWritten);
-
- /* Send write page command sequence */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
-
- /* Cards with page size <= 512 bytes */
- if((hnand->Config.PageSize) <= 512U)
- {
- if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- }
- else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
- }
- }
- else /* (hnand->Config.PageSize) > 512 */
- {
- if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- }
- else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
- }
- }
-
-
- /* Write data to memory */
- for(; index < size; index++)
- {
- *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
- }
-
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
-
- /* Read status until NAND is ready */
- while(HAL_NAND_Read_Status(hnand) != NAND_READY)
- {
- /* Get tick */
- tickstart = HAL_GetTick();
-
- if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Increment written pages number */
- numPagesWritten++;
-
- /* Decrement pages to write */
- NumPageToWrite--;
-
- /* Increment the NAND address */
- nandaddress = (uint32_t)(nandaddress + 1U);
- }
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnand);
-
- return HAL_OK;
-}
-
-/**
- * @brief Write Page(s) to NAND memory block (16-bits addressing)
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @param pAddress : pointer to NAND address structure
- * @param pBuffer : pointer to source buffer to write. pBuffer should be 16bits aligned
- * @param NumPageToWrite : number of pages to write to block
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToWrite)
-{
- __IO uint32_t index = 0U;
- uint32_t tickstart = 0U;
- uint32_t deviceaddress = 0U, size = 0U, numPagesWritten = 0U, nandaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnand);
-
- /* Check the NAND controller state */
- if(hnand->State == HAL_NAND_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Identify the device address */
- if(hnand->Init.NandBank == FSMC_NAND_BANK2)
- {
- deviceaddress = NAND_DEVICE1;
- }
- else
- {
- deviceaddress = NAND_DEVICE2;
- }
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_BUSY;
-
- /* NAND raw address calculation */
- nandaddress = ARRAY_ADDRESS(pAddress, hnand);
-
- /* Page(s) write loop */
- while((NumPageToWrite != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
- {
- /* update the buffer size */
- size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesWritten);
-
- /* Send write page command sequence */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
-
- /* Cards with page size <= 512 bytes */
- if((hnand->Config.PageSize) <= 512U)
- {
- if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- }
- else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
- }
- }
- else /* (hnand->Config.PageSize) > 512 */
- {
- if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- }
- else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
- }
- }
-
- /* Write data to memory */
- for(; index < size; index++)
- {
- *(__IO uint16_t *)deviceaddress = *(uint16_t *)pBuffer++;
- }
-
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
-
- /* Read status until NAND is ready */
- while(HAL_NAND_Read_Status(hnand) != NAND_READY)
- {
- /* Get tick */
- tickstart = HAL_GetTick();
-
- if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Increment written pages number */
- numPagesWritten++;
-
- /* Decrement pages to write */
- NumPageToWrite--;
-
- /* Increment the NAND address */
- nandaddress = (uint32_t)(nandaddress + 1U);
- }
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnand);
-
- return HAL_OK;
-}
-
-/**
- * @brief Read Spare area(s) from NAND memory (8-bits addressing)
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @param pAddress : pointer to NAND address structure
- * @param pBuffer: pointer to source buffer to write
- * @param NumSpareAreaToRead: Number of spare area to read
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
-{
- __IO uint32_t index = 0U;
- uint32_t tickstart = 0U;
- uint32_t deviceaddress = 0U, size = 0U, numSpareAreaRead = 0U, nandaddress = 0U, columnaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnand);
-
- /* Check the NAND controller state */
- if(hnand->State == HAL_NAND_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Identify the device address */
- if(hnand->Init.NandBank == FSMC_NAND_BANK2)
- {
- deviceaddress = NAND_DEVICE1;
- }
- else
- {
- deviceaddress = NAND_DEVICE2;
- }
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_BUSY;
-
- /* NAND raw address calculation */
- nandaddress = ARRAY_ADDRESS(pAddress, hnand);
-
- /* Column in page address */
- columnaddress = COLUMN_ADDRESS(hnand);
-
- /* Spare area(s) read loop */
- while((NumSpareAreaToRead != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
- {
- /* update the buffer size */
- size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead);
-
- /* Cards with page size <= 512 bytes */
- if((hnand->Config.PageSize) <= 512U)
- {
- /* Send read spare area command sequence */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
-
- if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- }
- else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
- }
- }
- else /* (hnand->Config.PageSize) > 512 */
- {
- /* Send read spare area command sequence */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
-
- if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- }
- else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
- }
- }
-
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
-
- if(hnand->Config.ExtraCommandEnable == ENABLE)
- {
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Read status until NAND is ready */
- while(HAL_NAND_Read_Status(hnand) != NAND_READY)
- {
- if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Go back to read mode */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
- }
-
- /* Get Data into Buffer */
- for(; index < size; index++)
- {
- *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
- }
-
- /* Increment read spare areas number */
- numSpareAreaRead++;
-
- /* Decrement spare areas to read */
- NumSpareAreaToRead--;
-
- /* Increment the NAND address */
- nandaddress = (uint32_t)(nandaddress + 1U);
- }
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnand);
-
- return HAL_OK;
-}
-
-/**
- * @brief Read Spare area(s) from NAND memory (16-bits addressing)
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @param pAddress : pointer to NAND address structure
- * @param pBuffer: pointer to source buffer to write. pBuffer should be 16bits aligned.
- * @param NumSpareAreaToRead: Number of spare area to read
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaToRead)
-{
- __IO uint32_t index = 0U;
- uint32_t tickstart = 0U;
- uint32_t deviceaddress = 0U, size = 0U, numSpareAreaRead = 0U, nandaddress = 0U, columnaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnand);
-
- /* Check the NAND controller state */
- if(hnand->State == HAL_NAND_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Identify the device address */
- if(hnand->Init.NandBank == FSMC_NAND_BANK2)
- {
- deviceaddress = NAND_DEVICE1;
- }
- else
- {
- deviceaddress = NAND_DEVICE2;
- }
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_BUSY;
-
- /* NAND raw address calculation */
- nandaddress = ARRAY_ADDRESS(pAddress, hnand);
-
- /* Column in page address */
- columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2U);
-
- /* Spare area(s) read loop */
- while((NumSpareAreaToRead != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
- {
- /* update the buffer size */
- size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead);
-
- /* Cards with page size <= 512 bytes */
- if((hnand->Config.PageSize) <= 512U)
- {
- /* Send read spare area command sequence */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
-
- if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- }
- else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
- }
- }
- else /* (hnand->Config.PageSize) > 512 */
- {
- /* Send read spare area command sequence */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
-
- if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- }
- else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
- }
- }
-
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
-
- if(hnand->Config.ExtraCommandEnable == ENABLE)
- {
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Read status until NAND is ready */
- while(HAL_NAND_Read_Status(hnand) != NAND_READY)
- {
- if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Go back to read mode */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
- }
-
- /* Get Data into Buffer */
- for(; index < size; index++)
- {
- *(uint16_t *)pBuffer++ = *(uint16_t *)deviceaddress;
- }
-
- /* Increment read spare areas number */
- numSpareAreaRead++;
-
- /* Decrement spare areas to read */
- NumSpareAreaToRead--;
-
- /* Increment the NAND address */
- nandaddress = (uint32_t)(nandaddress + 1U);
- }
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnand);
-
- return HAL_OK;
-}
-
-/**
- * @brief Write Spare area(s) to NAND memory (8-bits addressing)
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @param pAddress : pointer to NAND address structure
- * @param pBuffer : pointer to source buffer to write
- * @param NumSpareAreaTowrite : number of spare areas to write to block
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
-{
- __IO uint32_t index = 0U;
- uint32_t tickstart = 0U;
- uint32_t deviceaddress = 0U, size = 0U, numSpareAreaWritten = 0U, nandaddress = 0U, columnaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnand);
-
- /* Check the NAND controller state */
- if(hnand->State == HAL_NAND_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Identify the device address */
- if(hnand->Init.NandBank == FSMC_NAND_BANK2)
- {
- deviceaddress = NAND_DEVICE1;
- }
- else
- {
- deviceaddress = NAND_DEVICE2;
- }
-
- /* Update the FSMC_NAND controller state */
- hnand->State = HAL_NAND_STATE_BUSY;
-
- /* Page address calculation */
- nandaddress = ARRAY_ADDRESS(pAddress, hnand);
-
- /* Column in page address */
- columnaddress = COLUMN_ADDRESS(hnand);
-
- /* Spare area(s) write loop */
- while((NumSpareAreaTowrite != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
- {
- /* update the buffer size */
- size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten);
-
- /* Cards with page size <= 512 bytes */
- if((hnand->Config.PageSize) <= 512U)
- {
- /* Send write Spare area command sequence */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
-
- if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- }
- else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
- }
- }
- else /* (hnand->Config.PageSize) > 512 */
- {
- /* Send write Spare area command sequence */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
-
- if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- }
- else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
- }
- }
-
- /* Write data to memory */
- for(; index < size; index++)
- {
- *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
- }
-
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Read status until NAND is ready */
- while(HAL_NAND_Read_Status(hnand) != NAND_READY)
- {
- if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Increment written spare areas number */
- numSpareAreaWritten++;
-
- /* Decrement spare areas to write */
- NumSpareAreaTowrite--;
-
- /* Increment the NAND address */
- nandaddress = (uint32_t)(nandaddress + 1U);
- }
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnand);
-
- return HAL_OK;
-}
-
-/**
- * @brief Write Spare area(s) to NAND memory (16-bits addressing)
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @param pAddress : pointer to NAND address structure
- * @param pBuffer : pointer to source buffer to write. pBuffer should be 16bits aligned.
- * @param NumSpareAreaTowrite : number of spare areas to write to block
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaTowrite)
-{
- __IO uint32_t index = 0U;
- uint32_t tickstart = 0U;
- uint32_t deviceaddress = 0U, size = 0U, numSpareAreaWritten = 0U, nandaddress = 0U, columnaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnand);
-
- /* Check the NAND controller state */
- if(hnand->State == HAL_NAND_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Identify the device address */
- if(hnand->Init.NandBank == FSMC_NAND_BANK2)
- {
- deviceaddress = NAND_DEVICE1;
- }
- else
- {
- deviceaddress = NAND_DEVICE2;
- }
-
- /* Update the FSMC_NAND controller state */
- hnand->State = HAL_NAND_STATE_BUSY;
-
- /* NAND raw address calculation */
- nandaddress = ARRAY_ADDRESS(pAddress, hnand);
-
- /* Column in page address */
- columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2U);
-
- /* Spare area(s) write loop */
- while((NumSpareAreaTowrite != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
- {
- /* update the buffer size */
- size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten);
-
- /* Cards with page size <= 512 bytes */
- if((hnand->Config.PageSize) <= 512U)
- {
- /* Send write Spare area command sequence */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
-
- if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- }
- else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
- }
- }
- else /* (hnand->Config.PageSize) > 512 */
- {
- /* Send write Spare area command sequence */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
-
- if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- }
- else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
- {
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
- }
- }
-
- /* Write data to memory */
- for(; index < size; index++)
- {
- *(__IO uint16_t *)deviceaddress = *(uint16_t *)pBuffer++;
- }
-
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
-
- /* Read status until NAND is ready */
- while(HAL_NAND_Read_Status(hnand) != NAND_READY)
- {
- /* Get tick */
- tickstart = HAL_GetTick();
-
- if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Increment written spare areas number */
- numSpareAreaWritten++;
-
- /* Decrement spare areas to write */
- NumSpareAreaTowrite--;
-
- /* Increment the NAND address */
- nandaddress = (uint32_t)(nandaddress + 1U);
- }
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnand);
-
- return HAL_OK;
-}
-
-/**
- * @brief NAND memory Block erase
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @param pAddress : pointer to NAND address structure
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
-{
- uint32_t deviceaddress = 0U;
- uint32_t tickstart = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnand);
-
- /* Check the NAND controller state */
- if(hnand->State == HAL_NAND_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Identify the device address */
- if(hnand->Init.NandBank == FSMC_NAND_BANK2)
- {
- deviceaddress = NAND_DEVICE1;
- }
- else
- {
- deviceaddress = NAND_DEVICE2;
- }
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_BUSY;
-
- /* Send Erase block command sequence */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0;
-
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
- *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
-
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1;
-
- /* Update the NAND controller state */
- hnand->State = HAL_NAND_STATE_READY;
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Read status until NAND is ready */
- while(HAL_NAND_Read_Status(hnand) != NAND_READY)
- {
- if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
- {
- /* Process unlocked */
- __HAL_UNLOCK(hnand);
-
- return HAL_TIMEOUT;
- }
- }
-
- /* Process unlocked */
- __HAL_UNLOCK(hnand);
-
- return HAL_OK;
-}
-
-/**
- * @brief NAND memory read status
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @retval NAND status
- */
-uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
-{
- uint32_t data = 0U;
- uint32_t deviceaddress = 0U;
-
- /* Identify the device address */
- if(hnand->Init.NandBank == FSMC_NAND_BANK2)
- {
- deviceaddress = NAND_DEVICE1;
- }
- else
- {
- deviceaddress = NAND_DEVICE2;
- }
-
- /* Send Read status operation command */
- *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS;
-
- /* Read status register data */
- data = *(__IO uint8_t *)deviceaddress;
-
- /* Return the status */
- if((data & NAND_ERROR) == NAND_ERROR)
- {
- return NAND_ERROR;
- }
- else if((data & NAND_READY) == NAND_READY)
- {
- return NAND_READY;
- }
-
- return NAND_BUSY;
-}
-
-/**
- * @brief Increment the NAND memory address
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @param pAddress: pointer to NAND address structure
- * @retval The new status of the increment address operation. It can be:
- * - NAND_VALID_ADDRESS: When the new address is valid address
- * - NAND_INVALID_ADDRESS: When the new address is invalid address
- */
-uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
-{
- uint32_t status = NAND_VALID_ADDRESS;
-
- /* Increment page address */
- pAddress->Page++;
-
- /* Check NAND address is valid */
- if(pAddress->Page == hnand->Config.BlockSize)
- {
- pAddress->Page = 0U;
- pAddress->Block++;
-
- if(pAddress->Block == hnand->Config.PlaneSize)
- {
- pAddress->Block = 0U;
- pAddress->Plane++;
-
- if(pAddress->Plane == (hnand->Config.PlaneNbr))
- {
- status = NAND_INVALID_ADDRESS;
- }
- }
- }
-
- return (status);
-}
-/**
- * @}
- */
-
-/** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
- * @brief management functions
- *
-@verbatim
- ==============================================================================
- ##### NAND Control functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to control dynamically
- the NAND interface.
-
-@endverbatim
- * @{
- */
-
-
-/**
- * @brief Enables dynamically NAND ECC feature.
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
-{
- /* Check the NAND controller state */
- if(hnand->State == HAL_NAND_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Update the NAND state */
- hnand->State = HAL_NAND_STATE_BUSY;
-
- /* Enable ECC feature */
- FSMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
-
- /* Update the NAND state */
- hnand->State = HAL_NAND_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Disables dynamically FSMC_NAND ECC feature.
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
-{
- /* Check the NAND controller state */
- if(hnand->State == HAL_NAND_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Update the NAND state */
- hnand->State = HAL_NAND_STATE_BUSY;
-
- /* Disable ECC feature */
- FSMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
-
- /* Update the NAND state */
- hnand->State = HAL_NAND_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Disables dynamically NAND ECC feature.
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @param ECCval: pointer to ECC value
- * @param Timeout: maximum timeout to wait
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
-{
- HAL_StatusTypeDef status = HAL_OK;
-
- /* Check the NAND controller state */
- if(hnand->State == HAL_NAND_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Update the NAND state */
- hnand->State = HAL_NAND_STATE_BUSY;
-
- /* Get NAND ECC value */
- status = FSMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
-
- /* Update the NAND state */
- hnand->State = HAL_NAND_STATE_READY;
-
- return status;
-}
-
-/**
- * @}
- */
-
-
-/** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
- * @brief Peripheral State functions
- *
-@verbatim
- ==============================================================================
- ##### NAND State functions #####
- ==============================================================================
- [..]
- This subsection permits to get in run-time the status of the NAND controller
- and the data flow.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief return the NAND state
- * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
- * the configuration information for NAND module.
- * @retval HAL state
- */
-HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
-{
- return hnand->State;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
-#endif /* HAL_NAND_MODULE_ENABLED */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_nor.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_nor.c
deleted file mode 100644
index d8607ca..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_nor.c
+++ /dev/null
@@ -1,1058 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_nor.c
- * @author MCD Application Team
- * @brief NOR HAL module driver.
- * This file provides a generic firmware to drive NOR memories mounted
- * as external device.
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- This driver is a generic layered driver which contains a set of APIs used to
- control NOR flash memories. It uses the FSMC layer functions to interface
- with NOR devices. This driver is used as follows:
-
- (+) NOR flash memory configuration sequence using the function HAL_NOR_Init()
- with control and timing parameters for both normal and extended mode.
-
- (+) Read NOR flash memory manufacturer code and device IDs using the function
- HAL_NOR_Read_ID(). The read information is stored in the NOR_ID_TypeDef
- structure declared by the function caller.
-
- (+) Access NOR flash memory by read/write data unit operations using the functions
- HAL_NOR_Read(), HAL_NOR_Program().
-
- (+) Perform NOR flash erase block/chip operations using the functions
- HAL_NOR_Erase_Block() and HAL_NOR_Erase_Chip().
-
- (+) Read the NOR flash CFI (common flash interface) IDs using the function
- HAL_NOR_Read_CFI(). The read information is stored in the NOR_CFI_TypeDef
- structure declared by the function caller.
-
- (+) You can also control the NOR device by calling the control APIs HAL_NOR_WriteOperation_Enable()/
- HAL_NOR_WriteOperation_Disable() to respectively enable/disable the NOR write operation
-
- (+) You can monitor the NOR device HAL state by calling the function
- HAL_NOR_GetState()
- [..]
- (@) This driver is a set of generic APIs which handle standard NOR flash operations.
- If a NOR flash device contains different operations and/or implementations,
- it should be implemented separately.
-
- *** NOR HAL driver macros list ***
- =============================================
- [..]
- Below the list of most used macros in NOR HAL driver.
-
- (+) NOR_WRITE : NOR memory write data to specified address
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#ifdef HAL_NOR_MODULE_ENABLED
-#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG) || defined(STM32F100xE)
-
-/** @defgroup NOR NOR
- * @brief NOR driver modules
- * @{
- */
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @defgroup NOR_Private_Constants NOR Private Constants
- * @{
- */
-
-/* Constants to define address to set to write a command */
-#define NOR_CMD_ADDRESS_FIRST (uint16_t)0x0555
-#define NOR_CMD_ADDRESS_FIRST_CFI (uint16_t)0x0055
-#define NOR_CMD_ADDRESS_SECOND (uint16_t)0x02AA
-#define NOR_CMD_ADDRESS_THIRD (uint16_t)0x0555
-#define NOR_CMD_ADDRESS_FOURTH (uint16_t)0x0555
-#define NOR_CMD_ADDRESS_FIFTH (uint16_t)0x02AA
-#define NOR_CMD_ADDRESS_SIXTH (uint16_t)0x0555
-
-/* Constants to define data to program a command */
-#define NOR_CMD_DATA_READ_RESET (uint16_t)0x00F0
-#define NOR_CMD_DATA_FIRST (uint16_t)0x00AA
-#define NOR_CMD_DATA_SECOND (uint16_t)0x0055
-#define NOR_CMD_DATA_AUTO_SELECT (uint16_t)0x0090
-#define NOR_CMD_DATA_PROGRAM (uint16_t)0x00A0
-#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD (uint16_t)0x0080
-#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH (uint16_t)0x00AA
-#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH (uint16_t)0x0055
-#define NOR_CMD_DATA_CHIP_ERASE (uint16_t)0x0010
-#define NOR_CMD_DATA_CFI (uint16_t)0x0098
-
-#define NOR_CMD_DATA_BUFFER_AND_PROG (uint8_t)0x25
-#define NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM (uint8_t)0x29
-#define NOR_CMD_DATA_BLOCK_ERASE (uint8_t)0x30
-
-/* Mask on NOR STATUS REGISTER */
-#define NOR_MASK_STATUS_DQ5 (uint16_t)0x0020
-#define NOR_MASK_STATUS_DQ6 (uint16_t)0x0040
-
-/**
- * @}
- */
-
-/* Private macro -------------------------------------------------------------*/
-/** @defgroup NOR_Private_Macros NOR Private Macros
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private variables ---------------------------------------------------------*/
-
-/** @defgroup NOR_Private_Variables NOR Private Variables
- * @{
- */
-
-static uint32_t uwNORMemoryDataWidth = NOR_MEMORY_8B;
-
-/**
- * @}
- */
-
-/* Private function prototypes -----------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
-
-/** @defgroup NOR_Exported_Functions NOR Exported Functions
- * @{
- */
-
-/** @defgroup NOR_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
- @verbatim
- ==============================================================================
- ##### NOR Initialization and de_initialization functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to initialize/de-initialize
- the NOR memory
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Perform the NOR memory Initialization sequence
- * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
- * the configuration information for NOR module.
- * @param Timing: pointer to NOR control timing structure
- * @param ExtTiming: pointer to NOR extended mode timing structure
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NOR_Init(NOR_HandleTypeDef *hnor, FSMC_NORSRAM_TimingTypeDef *Timing, FSMC_NORSRAM_TimingTypeDef *ExtTiming)
-{
- /* Check the NOR handle parameter */
- if(hnor == NULL)
- {
- return HAL_ERROR;
- }
-
- if(hnor->State == HAL_NOR_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- hnor->Lock = HAL_UNLOCKED;
-
- /* Initialize the low level hardware (MSP) */
- HAL_NOR_MspInit(hnor);
- }
-
- /* Initialize NOR control Interface */
- FSMC_NORSRAM_Init(hnor->Instance, &(hnor->Init));
-
- /* Initialize NOR timing Interface */
- FSMC_NORSRAM_Timing_Init(hnor->Instance, Timing, hnor->Init.NSBank);
-
- /* Initialize NOR extended mode timing Interface */
- FSMC_NORSRAM_Extended_Timing_Init(hnor->Extended, ExtTiming, hnor->Init.NSBank, hnor->Init.ExtendedMode);
-
- /* Enable the NORSRAM device */
- __FSMC_NORSRAM_ENABLE(hnor->Instance, hnor->Init.NSBank);
-
- /* Initialize NOR Memory Data Width*/
- if (hnor->Init.MemoryDataWidth == FSMC_NORSRAM_MEM_BUS_WIDTH_8)
- {
- uwNORMemoryDataWidth = NOR_MEMORY_8B;
- }
- else
- {
- uwNORMemoryDataWidth = NOR_MEMORY_16B;
- }
-
- /* Check the NOR controller state */
- hnor->State = HAL_NOR_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Perform NOR memory De-Initialization sequence
- * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
- * the configuration information for NOR module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NOR_DeInit(NOR_HandleTypeDef *hnor)
-{
- /* De-Initialize the low level hardware (MSP) */
- HAL_NOR_MspDeInit(hnor);
-
- /* Configure the NOR registers with their reset values */
- FSMC_NORSRAM_DeInit(hnor->Instance, hnor->Extended, hnor->Init.NSBank);
-
- /* Update the NOR controller state */
- hnor->State = HAL_NOR_STATE_RESET;
-
- /* Release Lock */
- __HAL_UNLOCK(hnor);
-
- return HAL_OK;
-}
-
-/**
- * @brief NOR MSP Init
- * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
- * the configuration information for NOR module.
- * @retval None
- */
-__weak void HAL_NOR_MspInit(NOR_HandleTypeDef *hnor)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hnor);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_NOR_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief NOR MSP DeInit
- * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
- * the configuration information for NOR module.
- * @retval None
- */
-__weak void HAL_NOR_MspDeInit(NOR_HandleTypeDef *hnor)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hnor);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_NOR_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @brief NOR MSP Wait fro Ready/Busy signal
- * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
- * the configuration information for NOR module.
- * @param Timeout: Maximum timeout value
- * @retval None
- */
-__weak void HAL_NOR_MspWait(NOR_HandleTypeDef *hnor, uint32_t Timeout)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hnor);
- UNUSED(Timeout);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_NOR_MspWait could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup NOR_Exported_Functions_Group2 Input and Output functions
- * @brief Input Output and memory control functions
- *
- @verbatim
- ==============================================================================
- ##### NOR Input and Output functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to use and control the NOR memory
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Read NOR flash IDs
- * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
- * the configuration information for NOR module.
- * @param pNOR_ID : pointer to NOR ID structure
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NOR_Read_ID(NOR_HandleTypeDef *hnor, NOR_IDTypeDef *pNOR_ID)
-{
- uint32_t deviceaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnor);
-
- /* Check the NOR controller state */
- if(hnor->State == HAL_NOR_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Select the NOR device address */
- if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
- {
- deviceaddress = NOR_MEMORY_ADRESS1;
- }
- else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
- {
- deviceaddress = NOR_MEMORY_ADRESS2;
- }
- else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
- {
- deviceaddress = NOR_MEMORY_ADRESS3;
- }
- else /* FSMC_NORSRAM_BANK4 */
- {
- deviceaddress = NOR_MEMORY_ADRESS4;
- }
-
- /* Update the NOR controller state */
- hnor->State = HAL_NOR_STATE_BUSY;
-
- /* Send read ID command */
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_AUTO_SELECT);
-
- /* Read the NOR IDs */
- pNOR_ID->Manufacturer_Code = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, MC_ADDRESS);
- pNOR_ID->Device_Code1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE1_ADDR);
- pNOR_ID->Device_Code2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE2_ADDR);
- pNOR_ID->Device_Code3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE3_ADDR);
-
- /* Check the NOR controller state */
- hnor->State = HAL_NOR_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnor);
-
- return HAL_OK;
-}
-
-/**
- * @brief Returns the NOR memory to Read mode.
- * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
- * the configuration information for NOR module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NOR_ReturnToReadMode(NOR_HandleTypeDef *hnor)
-{
- uint32_t deviceaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnor);
-
- /* Check the NOR controller state */
- if(hnor->State == HAL_NOR_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Select the NOR device address */
- if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
- {
- deviceaddress = NOR_MEMORY_ADRESS1;
- }
- else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
- {
- deviceaddress = NOR_MEMORY_ADRESS2;
- }
- else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
- {
- deviceaddress = NOR_MEMORY_ADRESS3;
- }
- else /* FSMC_NORSRAM_BANK4 */
- {
- deviceaddress = NOR_MEMORY_ADRESS4;
- }
-
- NOR_WRITE(deviceaddress, NOR_CMD_DATA_READ_RESET);
-
- /* Check the NOR controller state */
- hnor->State = HAL_NOR_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnor);
-
- return HAL_OK;
-}
-
-/**
- * @brief Read data from NOR memory
- * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
- * the configuration information for NOR module.
- * @param pAddress: pointer to Device address
- * @param pData : pointer to read data
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NOR_Read(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData)
-{
- uint32_t deviceaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnor);
-
- /* Check the NOR controller state */
- if(hnor->State == HAL_NOR_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Select the NOR device address */
- if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
- {
- deviceaddress = NOR_MEMORY_ADRESS1;
- }
- else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
- {
- deviceaddress = NOR_MEMORY_ADRESS2;
- }
- else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
- {
- deviceaddress = NOR_MEMORY_ADRESS3;
- }
- else /* FSMC_NORSRAM_BANK4 */
- {
- deviceaddress = NOR_MEMORY_ADRESS4;
- }
-
- /* Update the NOR controller state */
- hnor->State = HAL_NOR_STATE_BUSY;
-
- /* Send read data command */
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
- NOR_WRITE((uint32_t)pAddress, NOR_CMD_DATA_READ_RESET);
-
- /* Read the data */
- *pData = *(__IO uint32_t *)(uint32_t)pAddress;
-
- /* Check the NOR controller state */
- hnor->State = HAL_NOR_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnor);
-
- return HAL_OK;
-}
-
-/**
- * @brief Program data to NOR memory
- * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
- * the configuration information for NOR module.
- * @param pAddress: Device address
- * @param pData : pointer to the data to write
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NOR_Program(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData)
-{
- uint32_t deviceaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnor);
-
- /* Check the NOR controller state */
- if(hnor->State == HAL_NOR_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Select the NOR device address */
- if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
- {
- deviceaddress = NOR_MEMORY_ADRESS1;
- }
- else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
- {
- deviceaddress = NOR_MEMORY_ADRESS2;
- }
- else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
- {
- deviceaddress = NOR_MEMORY_ADRESS3;
- }
- else /* FSMC_NORSRAM_BANK4 */
- {
- deviceaddress = NOR_MEMORY_ADRESS4;
- }
-
- /* Update the NOR controller state */
- hnor->State = HAL_NOR_STATE_BUSY;
-
- /* Send program data command */
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_PROGRAM);
-
- /* Write the data */
- NOR_WRITE(pAddress, *pData);
-
- /* Check the NOR controller state */
- hnor->State = HAL_NOR_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnor);
-
- return HAL_OK;
-}
-
-/**
- * @brief Reads a block of data from the FSMC NOR memory.
- * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
- * the configuration information for NOR module.
- * @param uwAddress: NOR memory internal address to read from.
- * @param pData: pointer to the buffer that receives the data read from the
- * NOR memory.
- * @param uwBufferSize : number of Half word to read.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NOR_ReadBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize)
-{
- uint32_t deviceaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnor);
-
- /* Check the NOR controller state */
- if(hnor->State == HAL_NOR_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Select the NOR device address */
- if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
- {
- deviceaddress = NOR_MEMORY_ADRESS1;
- }
- else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
- {
- deviceaddress = NOR_MEMORY_ADRESS2;
- }
- else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
- {
- deviceaddress = NOR_MEMORY_ADRESS3;
- }
- else /* FSMC_NORSRAM_BANK4 */
- {
- deviceaddress = NOR_MEMORY_ADRESS4;
- }
-
- /* Update the NOR controller state */
- hnor->State = HAL_NOR_STATE_BUSY;
-
- /* Send read data command */
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
- NOR_WRITE(uwAddress, NOR_CMD_DATA_READ_RESET);
-
- /* Read buffer */
- while( uwBufferSize > 0U)
- {
- *pData++ = *(__IO uint16_t *)uwAddress;
- uwAddress += 2U;
- uwBufferSize--;
- }
-
- /* Check the NOR controller state */
- hnor->State = HAL_NOR_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnor);
-
- return HAL_OK;
-}
-
-/**
- * @brief Writes a half-word buffer to the FSMC NOR memory. This function
- * must be used only with S29GL128P NOR memory.
- * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
- * the configuration information for NOR module.
- * @param uwAddress: NOR memory internal address from which the data
- * @note Some NOR memory need Address aligned to xx bytes (can be aligned to
- * 64 bytes boundary for example).
- * @param pData: pointer to source data buffer.
- * @param uwBufferSize: number of Half words to write.
- * @note The maximum buffer size allowed is NOR memory dependent
- * (can be 64 Bytes max for example).
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NOR_ProgramBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize)
-{
- uint16_t * p_currentaddress = (uint16_t *)NULL;
- uint16_t * p_endaddress = (uint16_t *)NULL;
- uint32_t lastloadedaddress = 0U, deviceaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnor);
-
- /* Check the NOR controller state */
- if(hnor->State == HAL_NOR_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Select the NOR device address */
- if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
- {
- deviceaddress = NOR_MEMORY_ADRESS1;
- }
- else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
- {
- deviceaddress = NOR_MEMORY_ADRESS2;
- }
- else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
- {
- deviceaddress = NOR_MEMORY_ADRESS3;
- }
- else /* FSMC_NORSRAM_BANK4 */
- {
- deviceaddress = NOR_MEMORY_ADRESS4;
- }
-
- /* Update the NOR controller state */
- hnor->State = HAL_NOR_STATE_BUSY;
-
- /* Initialize variables */
- p_currentaddress = (uint16_t*)((uint32_t)(uwAddress));
- p_endaddress = p_currentaddress + (uwBufferSize-1U);
- lastloadedaddress = (uint32_t)(uwAddress);
-
- /* Issue unlock command sequence */
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
-
- /* Write Buffer Load Command */
- NOR_WRITE((uint32_t)(p_currentaddress), NOR_CMD_DATA_BUFFER_AND_PROG);
- NOR_WRITE((uint32_t)(p_currentaddress), (uwBufferSize-1U));
-
- /* Load Data into NOR Buffer */
- while(p_currentaddress <= p_endaddress)
- {
- /* Store last loaded address & data value (for polling) */
- lastloadedaddress = (uint32_t)p_currentaddress;
-
- NOR_WRITE(p_currentaddress, *pData++);
-
- p_currentaddress++;
- }
-
- NOR_WRITE((uint32_t)(lastloadedaddress), NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM);
-
- /* Check the NOR controller state */
- hnor->State = HAL_NOR_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnor);
-
- return HAL_OK;
-
-}
-
-/**
- * @brief Erase the specified block of the NOR memory
- * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
- * the configuration information for NOR module.
- * @param BlockAddress : Block to erase address
- * @param Address: Device address
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NOR_Erase_Block(NOR_HandleTypeDef *hnor, uint32_t BlockAddress, uint32_t Address)
-{
- uint32_t deviceaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnor);
-
- /* Check the NOR controller state */
- if(hnor->State == HAL_NOR_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Select the NOR device address */
- if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
- {
- deviceaddress = NOR_MEMORY_ADRESS1;
- }
- else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
- {
- deviceaddress = NOR_MEMORY_ADRESS2;
- }
- else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
- {
- deviceaddress = NOR_MEMORY_ADRESS3;
- }
- else /* FSMC_NORSRAM_BANK4 */
- {
- deviceaddress = NOR_MEMORY_ADRESS4;
- }
-
- /* Update the NOR controller state */
- hnor->State = HAL_NOR_STATE_BUSY;
-
- /* Send block erase command sequence */
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);
- NOR_WRITE((uint32_t)(BlockAddress + Address), NOR_CMD_DATA_BLOCK_ERASE);
-
- /* Check the NOR memory status and update the controller state */
- hnor->State = HAL_NOR_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnor);
-
- return HAL_OK;
-
-}
-
-/**
- * @brief Erase the entire NOR chip.
- * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
- * the configuration information for NOR module.
- * @param Address : Device address
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NOR_Erase_Chip(NOR_HandleTypeDef *hnor, uint32_t Address)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(Address);
-
- uint32_t deviceaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnor);
-
- /* Check the NOR controller state */
- if(hnor->State == HAL_NOR_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Select the NOR device address */
- if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
- {
- deviceaddress = NOR_MEMORY_ADRESS1;
- }
- else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
- {
- deviceaddress = NOR_MEMORY_ADRESS2;
- }
- else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
- {
- deviceaddress = NOR_MEMORY_ADRESS3;
- }
- else /* FSMC_NORSRAM_BANK4 */
- {
- deviceaddress = NOR_MEMORY_ADRESS4;
- }
-
- /* Update the NOR controller state */
- hnor->State = HAL_NOR_STATE_BUSY;
-
- /* Send NOR chip erase command sequence */
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SIXTH), NOR_CMD_DATA_CHIP_ERASE);
-
- /* Check the NOR memory status and update the controller state */
- hnor->State = HAL_NOR_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnor);
-
- return HAL_OK;
-}
-
-/**
- * @brief Read NOR flash CFI IDs
- * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
- * the configuration information for NOR module.
- * @param pNOR_CFI : pointer to NOR CFI IDs structure
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NOR_Read_CFI(NOR_HandleTypeDef *hnor, NOR_CFITypeDef *pNOR_CFI)
-{
- uint32_t deviceaddress = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hnor);
-
- /* Check the NOR controller state */
- if(hnor->State == HAL_NOR_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Select the NOR device address */
- if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
- {
- deviceaddress = NOR_MEMORY_ADRESS1;
- }
- else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
- {
- deviceaddress = NOR_MEMORY_ADRESS2;
- }
- else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
- {
- deviceaddress = NOR_MEMORY_ADRESS3;
- }
- else /* FSMC_NORSRAM_BANK4 */
- {
- deviceaddress = NOR_MEMORY_ADRESS4;
- }
-
- /* Update the NOR controller state */
- hnor->State = HAL_NOR_STATE_BUSY;
-
- /* Send read CFI query command */
- NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI), NOR_CMD_DATA_CFI);
-
- /* read the NOR CFI information */
- pNOR_CFI->CFI_1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI1_ADDRESS);
- pNOR_CFI->CFI_2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI2_ADDRESS);
- pNOR_CFI->CFI_3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI3_ADDRESS);
- pNOR_CFI->CFI_4 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI4_ADDRESS);
-
- /* Check the NOR controller state */
- hnor->State = HAL_NOR_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnor);
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup NOR_Exported_Functions_Group3 Control functions
- * @brief management functions
- *
-@verbatim
- ==============================================================================
- ##### NOR Control functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to control dynamically
- the NOR interface.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Enables dynamically NOR write operation.
- * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
- * the configuration information for NOR module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NOR_WriteOperation_Enable(NOR_HandleTypeDef *hnor)
-{
- /* Process Locked */
- __HAL_LOCK(hnor);
-
- /* Enable write operation */
- FSMC_NORSRAM_WriteOperation_Enable(hnor->Instance, hnor->Init.NSBank);
-
- /* Update the NOR controller state */
- hnor->State = HAL_NOR_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnor);
-
- return HAL_OK;
-}
-
-/**
- * @brief Disables dynamically NOR write operation.
- * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
- * the configuration information for NOR module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_NOR_WriteOperation_Disable(NOR_HandleTypeDef *hnor)
-{
- /* Process Locked */
- __HAL_LOCK(hnor);
-
- /* Update the SRAM controller state */
- hnor->State = HAL_NOR_STATE_BUSY;
-
- /* Disable write operation */
- FSMC_NORSRAM_WriteOperation_Disable(hnor->Instance, hnor->Init.NSBank);
-
- /* Update the NOR controller state */
- hnor->State = HAL_NOR_STATE_PROTECTED;
-
- /* Process unlocked */
- __HAL_UNLOCK(hnor);
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup NOR_Exported_Functions_Group4 State functions
- * @brief Peripheral State functions
- *
-@verbatim
- ==============================================================================
- ##### NOR State functions #####
- ==============================================================================
- [..]
- This subsection permits to get in run-time the status of the NOR controller
- and the data flow.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief return the NOR controller state
- * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
- * the configuration information for NOR module.
- * @retval NOR controller state
- */
-HAL_NOR_StateTypeDef HAL_NOR_GetState(NOR_HandleTypeDef *hnor)
-{
- return hnor->State;
-}
-
-/**
- * @brief Returns the NOR operation status.
- * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
- * the configuration information for NOR module.
- * @param Address: Device address
- * @param Timeout: NOR progamming Timeout
- * @retval NOR_Status: The returned value can be: HAL_NOR_STATUS_SUCCESS, HAL_NOR_STATUS_ERROR
- * or HAL_NOR_STATUS_TIMEOUT
- */
-HAL_NOR_StatusTypeDef HAL_NOR_GetStatus(NOR_HandleTypeDef *hnor, uint32_t Address, uint32_t Timeout)
-{
- HAL_NOR_StatusTypeDef status = HAL_NOR_STATUS_ONGOING;
- uint16_t tmp_sr1 = 0, tmp_sr2 = 0;
- uint32_t tickstart = 0U;
-
- /* Poll on NOR memory Ready/Busy signal ------------------------------------*/
- HAL_NOR_MspWait(hnor, Timeout);
-
- /* Get tick */
- tickstart = HAL_GetTick();
- while((status != HAL_NOR_STATUS_SUCCESS) && (status != HAL_NOR_STATUS_TIMEOUT))
- {
- /* Check for the Timeout */
- if(Timeout != HAL_MAX_DELAY)
- {
- if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
- {
- status = HAL_NOR_STATUS_TIMEOUT;
- }
- }
-
- /* Read NOR status register (DQ6 and DQ5) */
- tmp_sr1 = *(__IO uint16_t *)Address;
- tmp_sr2 = *(__IO uint16_t *)Address;
-
- /* If DQ6 did not toggle between the two reads then return NOR_Success */
- if((tmp_sr1 & NOR_MASK_STATUS_DQ6) == (tmp_sr2 & NOR_MASK_STATUS_DQ6))
- {
- return HAL_NOR_STATUS_SUCCESS;
- }
-
- if((tmp_sr1 & NOR_MASK_STATUS_DQ5) != NOR_MASK_STATUS_DQ5)
- {
- status = HAL_NOR_STATUS_ONGOING;
- }
-
- tmp_sr1 = *(__IO uint16_t *)Address;
- tmp_sr2 = *(__IO uint16_t *)Address;
-
- /* If DQ6 did not toggle between the two reads then return NOR_Success */
- if((tmp_sr1 & NOR_MASK_STATUS_DQ6) == (tmp_sr2 & NOR_MASK_STATUS_DQ6))
- {
- return HAL_NOR_STATUS_SUCCESS;
- }
- else if((tmp_sr1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5)
- {
- return HAL_NOR_STATUS_ERROR;
- }
- }
-
- /* Return the operation status */
- return status;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-/**
- * @}
- */
-#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG || STM32F100xE */
-#endif /* HAL_NOR_MODULE_ENABLED */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pccard.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pccard.c
deleted file mode 100644
index 0cf076d..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pccard.c
+++ /dev/null
@@ -1,746 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_pccard.c
- * @author MCD Application Team
- * @brief PCCARD HAL module driver.
- * This file provides a generic firmware to drive PCCARD memories mounted
- * as external device.
- *
- @verbatim
- ===============================================================================
- ##### How to use this driver #####
- ===============================================================================
- [..]
- This driver is a generic layered driver which contains a set of APIs used to
- control PCCARD/compact flash memories. It uses the FSMC/FSMC layer functions
- to interface with PCCARD devices. This driver is used for:
-
- (+) PCCARD/compact flash memory configuration sequence using the function
- HAL_PCCARD_Init() with control and timing parameters for both common and
- attribute spaces.
-
- (+) Read PCCARD/compact flash memory maker and device IDs using the function
- HAL_PCCARD_Read_ID(). The read information is stored in the CompactFlash_ID
- structure declared by the function caller.
-
- (+) Access PCCARD/compact flash memory by read/write operations using the functions
- HAL_PCCARD_Read_Sector()/HAL_PCCARD_Write_Sector(), to read/write sector.
-
- (+) Perform PCCARD/compact flash Reset chip operation using the function HAL_PCCARD_Reset().
-
- (+) Perform PCCARD/compact flash erase sector operation using the function
- HAL_PCCARD_Erase_Sector().
-
- (+) Read the PCCARD/compact flash status operation using the function HAL_PCCARD_ReadStatus().
-
- (+) You can monitor the PCCARD/compact flash device HAL state by calling the function
- HAL_PCCARD_GetState()
-
- [..]
- (@) This driver is a set of generic APIs which handle standard PCCARD/compact flash
- operations. If a PCCARD/compact flash device contains different operations
- and/or implementations, it should be implemented separately.
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#ifdef HAL_PCCARD_MODULE_ENABLED
-#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG)
-
-/** @defgroup PCCARD PCCARD
- * @brief PCCARD HAL module driver
- * @{
- */
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @defgroup PCCARD_Private_Constants PCCARD Private Constants
- * @{
- */
-
-#define PCCARD_TIMEOUT_READ_ID 0x0000FFFFU
-#define PCCARD_TIMEOUT_SECTOR 0x0000FFFFU
-#define PCCARD_TIMEOUT_STATUS 0x01000000U
-
-#define PCCARD_STATUS_OK (uint8_t)0x58
-#define PCCARD_STATUS_WRITE_OK (uint8_t)0x50
-/**
- * @}
- */
-
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Exported functions ---------------------------------------------------------*/
-
-/** @defgroup PCCARD_Exported_Functions PCCARD Exported Functions
- * @{
- */
-
-/** @defgroup PCCARD_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
- @verbatim
- ==============================================================================
- ##### PCCARD Initialization and de-initialization functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to initialize/de-initialize
- the PCCARD memory
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Perform the PCCARD memory Initialization sequence
- * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
- * the configuration information for PCCARD module.
- * @param ComSpaceTiming: Common space timing structure
- * @param AttSpaceTiming: Attribute space timing structure
- * @param IOSpaceTiming: IO space timing structure
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCCARD_Init(PCCARD_HandleTypeDef *hpccard, FSMC_NAND_PCC_TimingTypeDef *ComSpaceTiming, FSMC_NAND_PCC_TimingTypeDef *AttSpaceTiming, FSMC_NAND_PCC_TimingTypeDef *IOSpaceTiming)
-{
- /* Check the PCCARD controller state */
- if(hpccard == NULL)
- {
- return HAL_ERROR;
- }
-
- if(hpccard->State == HAL_PCCARD_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- hpccard->Lock = HAL_UNLOCKED;
-
- /* Initialize the low level hardware (MSP) */
- HAL_PCCARD_MspInit(hpccard);
- }
-
- /* Initialize the PCCARD state */
- hpccard->State = HAL_PCCARD_STATE_BUSY;
-
- /* Initialize PCCARD control Interface */
- FSMC_PCCARD_Init(hpccard->Instance, &(hpccard->Init));
-
- /* Init PCCARD common space timing Interface */
- FSMC_PCCARD_CommonSpace_Timing_Init(hpccard->Instance, ComSpaceTiming);
-
- /* Init PCCARD attribute space timing Interface */
- FSMC_PCCARD_AttributeSpace_Timing_Init(hpccard->Instance, AttSpaceTiming);
-
- /* Init PCCARD IO space timing Interface */
- FSMC_PCCARD_IOSpace_Timing_Init(hpccard->Instance, IOSpaceTiming);
-
- /* Enable the PCCARD device */
- __FSMC_PCCARD_ENABLE(hpccard->Instance);
-
- /* Update the PCCARD state */
- hpccard->State = HAL_PCCARD_STATE_READY;
-
- return HAL_OK;
-
-}
-
-/**
- * @brief Perform the PCCARD memory De-initialization sequence
- * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
- * the configuration information for PCCARD module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCCARD_DeInit(PCCARD_HandleTypeDef *hpccard)
-{
- /* De-Initialize the low level hardware (MSP) */
- HAL_PCCARD_MspDeInit(hpccard);
-
- /* Configure the PCCARD registers with their reset values */
- FSMC_PCCARD_DeInit(hpccard->Instance);
-
- /* Update the PCCARD controller state */
- hpccard->State = HAL_PCCARD_STATE_RESET;
-
- /* Release Lock */
- __HAL_UNLOCK(hpccard);
-
- return HAL_OK;
-}
-
-/**
- * @brief PCCARD MSP Init
- * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
- * the configuration information for PCCARD module.
- * @retval None
- */
-__weak void HAL_PCCARD_MspInit(PCCARD_HandleTypeDef *hpccard)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hpccard);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_PCCARD_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief PCCARD MSP DeInit
- * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
- * the configuration information for PCCARD module.
- * @retval None
- */
-__weak void HAL_PCCARD_MspDeInit(PCCARD_HandleTypeDef *hpccard)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hpccard);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_PCCARD_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup PCCARD_Exported_Functions_Group2 Input Output and memory functions
- * @brief Input Output and memory control functions
- *
- @verbatim
- ==============================================================================
- ##### PCCARD Input Output and memory functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to use and control the PCCARD memory
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Read Compact Flash's ID.
- * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
- * the configuration information for PCCARD module.
- * @param CompactFlash_ID: Compact flash ID structure.
- * @param pStatus: pointer to compact flash status
- * @retval HAL status
- *
- */
-HAL_StatusTypeDef HAL_PCCARD_Read_ID(PCCARD_HandleTypeDef *hpccard, uint8_t CompactFlash_ID[], uint8_t *pStatus)
-{
- uint32_t timeout = PCCARD_TIMEOUT_READ_ID, index = 0U;
- uint8_t status = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hpccard);
-
- /* Check the PCCARD controller state */
- if(hpccard->State == HAL_PCCARD_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Update the PCCARD controller state */
- hpccard->State = HAL_PCCARD_STATE_BUSY;
-
- /* Initialize the CF status */
- *pStatus = PCCARD_READY;
-
- /* Send the Identify Command */
- *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD) = 0xECECU;
-
- /* Read CF IDs and timeout treatment */
- do
- {
- /* Read the CF status */
- status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
-
- timeout--;
- }while((status != PCCARD_STATUS_OK) && timeout);
-
- if(timeout == 0U)
- {
- *pStatus = PCCARD_TIMEOUT_ERROR;
- }
- else
- {
- /* Read CF ID bytes */
- for(index = 0U; index < 16U; index++)
- {
- CompactFlash_ID[index] = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_DATA);
- }
- }
-
- /* Update the PCCARD controller state */
- hpccard->State = HAL_PCCARD_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hpccard);
-
- return HAL_OK;
-}
-
-/**
- * @brief Read sector from PCCARD memory
- * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
- * the configuration information for PCCARD module.
- * @param pBuffer: pointer to destination read buffer
- * @param SectorAddress: Sector address to read
- * @param pStatus: pointer to CF status
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCCARD_Read_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress, uint8_t *pStatus)
-{
- uint32_t timeout = PCCARD_TIMEOUT_SECTOR, index = 0U;
- uint8_t status = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hpccard);
-
- /* Check the PCCARD controller state */
- if(hpccard->State == HAL_PCCARD_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Update the PCCARD controller state */
- hpccard->State = HAL_PCCARD_STATE_BUSY;
-
- /* Initialize CF status */
- *pStatus = PCCARD_READY;
-
- /* Set the parameters to write a sector */
- *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_HIGH) = (uint16_t)0x00;
- *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_COUNT) = ((uint16_t)0x0100) | ((uint16_t)SectorAddress);
- *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD) = (uint16_t)0xE4A0;
-
- do
- {
- /* wait till the Status = 0x80 */
- status = *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
- timeout--;
- }while((status == 0x80U) && timeout);
-
- if(timeout == 0U)
- {
- *pStatus = PCCARD_TIMEOUT_ERROR;
- }
-
- timeout = 0xFFFFU;
-
- do
- {
- /* wait till the Status = PCCARD_STATUS_OK */
- status = *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
- timeout--;
- }while((status != PCCARD_STATUS_OK) && timeout);
-
- if(timeout == 0U)
- {
- *pStatus = PCCARD_TIMEOUT_ERROR;
- }
-
- /* Read bytes */
- for(; index < PCCARD_SECTOR_SIZE; index++)
- {
- *(uint16_t *)pBuffer++ = *(uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR);
- }
-
- /* Update the PCCARD controller state */
- hpccard->State = HAL_PCCARD_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hpccard);
-
- return HAL_OK;
-}
-
-
-/**
- * @brief Write sector to PCCARD memory
- * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
- * the configuration information for PCCARD module.
- * @param pBuffer: pointer to source write buffer
- * @param SectorAddress: Sector address to write
- * @param pStatus: pointer to CF status
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCCARD_Write_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress, uint8_t *pStatus)
-{
- uint32_t timeout = PCCARD_TIMEOUT_SECTOR, index = 0U;
- uint8_t status = 0U;
-
- /* Process Locked */
- __HAL_LOCK(hpccard);
-
- /* Check the PCCARD controller state */
- if(hpccard->State == HAL_PCCARD_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Update the PCCARD controller state */
- hpccard->State = HAL_PCCARD_STATE_BUSY;
-
- /* Initialize CF status */
- *pStatus = PCCARD_READY;
-
- /* Set the parameters to write a sector */
- *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_HIGH) = (uint16_t)0x00;
- *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_COUNT) = ((uint16_t)0x0100) | ((uint16_t)SectorAddress);
- *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD) = (uint16_t)0x30A0;
-
- do
- {
- /* Wait till the Status = PCCARD_STATUS_OK */
- status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
- timeout--;
- }while((status != PCCARD_STATUS_OK) && timeout);
-
- if(timeout == 0U)
- {
- *pStatus = PCCARD_TIMEOUT_ERROR;
- }
-
- /* Write bytes */
- for(; index < PCCARD_SECTOR_SIZE; index++)
- {
- *(uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR) = *(uint16_t *)pBuffer++;
- }
-
- do
- {
- /* Wait till the Status = PCCARD_STATUS_WRITE_OK */
- status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
- timeout--;
- }while((status != PCCARD_STATUS_WRITE_OK) && timeout);
-
- if(timeout == 0U)
- {
- *pStatus = PCCARD_TIMEOUT_ERROR;
- }
-
- /* Update the PCCARD controller state */
- hpccard->State = HAL_PCCARD_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hpccard);
-
- return HAL_OK;
-}
-
-
-/**
- * @brief Erase sector from PCCARD memory
- * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
- * the configuration information for PCCARD module.
- * @param SectorAddress: Sector address to erase
- * @param pStatus: pointer to CF status
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCCARD_Erase_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t SectorAddress, uint8_t *pStatus)
-{
- uint32_t timeout = 0x400U;
- uint8_t status = 0;
-
- /* Process Locked */
- __HAL_LOCK(hpccard);
-
- /* Check the PCCARD controller state */
- if(hpccard->State == HAL_PCCARD_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Update the PCCARD controller state */
- hpccard->State = HAL_PCCARD_STATE_BUSY;
-
- /* Initialize CF status */
- *pStatus = PCCARD_READY;
-
- /* Set the parameters to write a sector */
- *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_LOW) = 0x00;
- *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_HIGH) = 0x00;
- *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_NUMBER) = SectorAddress;
- *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_COUNT) = 0x01;
- *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CARD_HEAD) = 0xA0;
- *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD) = ATA_ERASE_SECTOR_CMD;
-
- /* wait till the CF is ready */
- status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
-
- while((status != PCCARD_STATUS_WRITE_OK) && timeout)
- {
- status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
- timeout--;
- }
-
- if(timeout == 0U)
- {
- *pStatus = PCCARD_TIMEOUT_ERROR;
- }
-
- /* Check the PCCARD controller state */
- hpccard->State = HAL_PCCARD_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hpccard);
-
- return HAL_OK;
-}
-
-/**
- * @brief Reset the PCCARD memory
- * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
- * the configuration information for PCCARD module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCCARD_Reset(PCCARD_HandleTypeDef *hpccard)
-{
- /* Process Locked */
- __HAL_LOCK(hpccard);
-
- /* Check the PCCARD controller state */
- if(hpccard->State == HAL_PCCARD_STATE_BUSY)
- {
- return HAL_BUSY;
- }
-
- /* Provide an SW reset and Read and verify the:
- - CF Configuration Option Register at address 0x98000200 --> 0x80
- - Card Configuration and Status Register at address 0x98000202 --> 0x00
- - Pin Replacement Register at address 0x98000204 --> 0x0C
- - Socket and Copy Register at address 0x98000206 --> 0x00
- */
-
- /* Check the PCCARD controller state */
- hpccard->State = HAL_PCCARD_STATE_BUSY;
-
- *(__IO uint8_t *)(PCCARD_ATTRIBUTE_SPACE_ADDRESS | ATA_CARD_CONFIGURATION) = 0x01;
-
- /* Check the PCCARD controller state */
- hpccard->State = HAL_PCCARD_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hpccard);
-
- return HAL_OK;
-}
-
-/**
- * @brief This function handles PCCARD device interrupt request.
- * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
- * the configuration information for PCCARD module.
- * @retval HAL status
-*/
-void HAL_PCCARD_IRQHandler(PCCARD_HandleTypeDef *hpccard)
-{
- /* Check PCCARD interrupt Rising edge flag */
- if(__FSMC_PCCARD_GET_FLAG(hpccard->Instance, FSMC_FLAG_RISING_EDGE))
- {
- /* PCCARD interrupt callback*/
- HAL_PCCARD_ITCallback(hpccard);
-
- /* Clear PCCARD interrupt Rising edge pending bit */
- __FSMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FSMC_FLAG_RISING_EDGE);
- }
-
- /* Check PCCARD interrupt Level flag */
- if(__FSMC_PCCARD_GET_FLAG(hpccard->Instance, FSMC_FLAG_LEVEL))
- {
- /* PCCARD interrupt callback*/
- HAL_PCCARD_ITCallback(hpccard);
-
- /* Clear PCCARD interrupt Level pending bit */
- __FSMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FSMC_FLAG_LEVEL);
- }
-
- /* Check PCCARD interrupt Falling edge flag */
- if(__FSMC_PCCARD_GET_FLAG(hpccard->Instance, FSMC_FLAG_FALLING_EDGE))
- {
- /* PCCARD interrupt callback*/
- HAL_PCCARD_ITCallback(hpccard);
-
- /* Clear PCCARD interrupt Falling edge pending bit */
- __FSMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FSMC_FLAG_FALLING_EDGE);
- }
-
- /* Check PCCARD interrupt FIFO empty flag */
- if(__FSMC_PCCARD_GET_FLAG(hpccard->Instance, FSMC_FLAG_FEMPT))
- {
- /* PCCARD interrupt callback*/
- HAL_PCCARD_ITCallback(hpccard);
-
- /* Clear PCCARD interrupt FIFO empty pending bit */
- __FSMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FSMC_FLAG_FEMPT);
- }
-
-}
-
-/**
- * @brief PCCARD interrupt feature callback
- * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
- * the configuration information for PCCARD module.
- * @retval None
- */
-__weak void HAL_PCCARD_ITCallback(PCCARD_HandleTypeDef *hpccard)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hpccard);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_PCCARD_ITCallback could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup PCCARD_Exported_Functions_Group3 Peripheral State functions
- * @brief Peripheral State functions
- *
-@verbatim
- ==============================================================================
- ##### PCCARD Peripheral State functions #####
- ==============================================================================
- [..]
- This subsection permits to get in run-time the status of the PCCARD controller
- and the data flow.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief return the PCCARD controller state
- * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
- * the configuration information for PCCARD module.
- * @retval HAL state
- */
-HAL_PCCARD_StateTypeDef HAL_PCCARD_GetState(PCCARD_HandleTypeDef *hpccard)
-{
- return hpccard->State;
-}
-
-/**
- * @brief Get the compact flash memory status
- * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
- * the configuration information for PCCARD module.
- * @retval New status of the CF operation. This parameter can be:
- * - CompactFlash_TIMEOUT_ERROR: when the previous operation generate
- * a Timeout error
- * - CompactFlash_READY: when memory is ready for the next operation
- *
- */
-HAL_PCCARD_StatusTypeDef HAL_PCCARD_GetStatus(PCCARD_HandleTypeDef *hpccard)
-{
- uint32_t timeout = PCCARD_TIMEOUT_STATUS, status_cf = 0;
-
- /* Check the PCCARD controller state */
- if(hpccard->State == HAL_PCCARD_STATE_BUSY)
- {
- return HAL_PCCARD_STATUS_ONGOING;
- }
-
- status_cf = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
-
- while((status_cf == PCCARD_BUSY) && timeout)
- {
- status_cf = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
- timeout--;
- }
-
- if(timeout == 0U)
- {
- status_cf = PCCARD_TIMEOUT_ERROR;
- }
-
- /* Return the operation status */
- return (HAL_PCCARD_StatusTypeDef) status_cf;
-}
-
-/**
- * @brief Reads the Compact Flash memory status using the Read status command
- * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
- * the configuration information for PCCARD module.
- * @retval The status of the Compact Flash memory. This parameter can be:
- * - CompactFlash_BUSY: when memory is busy
- * - CompactFlash_READY: when memory is ready for the next operation
- * - CompactFlash_ERROR: when the previous operation gererates error
- */
-HAL_PCCARD_StatusTypeDef HAL_PCCARD_ReadStatus(PCCARD_HandleTypeDef *hpccard)
-{
- uint8_t data = 0U, status_cf = PCCARD_BUSY;
-
- /* Check the PCCARD controller state */
- if(hpccard->State == HAL_PCCARD_STATE_BUSY)
- {
- return HAL_PCCARD_STATUS_ONGOING;
- }
-
- /* Read status operation */
- data = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
-
- if((data & PCCARD_TIMEOUT_ERROR) == PCCARD_TIMEOUT_ERROR)
- {
- status_cf = PCCARD_TIMEOUT_ERROR;
- }
- else if((data & PCCARD_READY) == PCCARD_READY)
- {
- status_cf = PCCARD_READY;
- }
-
- return (HAL_PCCARD_StatusTypeDef) status_cf;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-/**
- * @}
- */
-
-#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
-#endif /* HAL_PCCARD_MODULE_ENABLED */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd.c
deleted file mode 100644
index ca32983..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd.c
+++ /dev/null
@@ -1,1424 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_pcd.c
- * @author MCD Application Team
- * @brief PCD HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the USB Peripheral Controller:
- * + Initialization and de-initialization functions
- * + IO operation functions
- * + Peripheral Control functions
- * + Peripheral State functions
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- The PCD HAL driver can be used as follows:
-
- (#) Declare a PCD_HandleTypeDef handle structure, for example:
- PCD_HandleTypeDef hpcd;
-
- (#) Fill parameters of Init structure in HCD handle
-
- (#) Call HAL_PCD_Init() API to initialize the HCD peripheral (Core, Device core, ...)
-
- (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:
- (##) Enable the PCD/USB Low Level interface clock using the following macro
- (+++) __HAL_RCC_USB_CLK_ENABLE(); For USB Device FS peripheral available
- on STM32F102xx and STM32F103xx devices
- (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); For USB OTG FS peripheral available
- on STM32F105xx and STM32F107xx devices
-
- (##) Initialize the related GPIO clocks
- (##) Configure PCD pin-out
- (##) Configure PCD NVIC interrupt
-
- (#)Associate the Upper USB device stack to the HAL PCD Driver:
- (##) hpcd.pData = pdev;
-
- (#)Enable HCD transmission and reception:
- (##) HAL_PCD_Start();
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-
-
-#ifdef HAL_PCD_MODULE_ENABLED
-
-#if defined(STM32F102x6) || defined(STM32F102xB) || \
- defined(STM32F103x6) || defined(STM32F103xB) || \
- defined(STM32F103xE) || defined(STM32F103xG) || \
- defined(STM32F105xC) || defined(STM32F107xC)
-
-/** @defgroup PCD PCD
- * @brief PCD HAL module driver
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup PCD_Private_Macros PCD Private Macros
- * @{
- */
-#define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b))
-#define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b))
-/**
- * @}
- */
-
-/* Private functions ---------------------------------------------------------*/
-/** @defgroup PCD_Private_Functions PCD Private Functions
- * @{
- */
-#if defined (USB_OTG_FS)
-static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
-#endif /* USB_OTG_FS */
-
-#if defined (USB)
-static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
-#endif /* USB */
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup PCD_Exported_Functions PCD Exported Functions
- * @{
- */
-
-/** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
- ===============================================================================
- ##### Initialization and de-initialization functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the PCD according to the specified
- * parameters in the PCD_InitTypeDef and create the associated handle.
- * @param hpcd: PCD handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
-{
- uint32_t index = 0U;
-
- /* Check the PCD handle allocation */
- if(hpcd == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
-
- if(hpcd->State == HAL_PCD_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- hpcd->Lock = HAL_UNLOCKED;
-
- /* Init the low level hardware : GPIO, CLOCK, NVIC... */
- HAL_PCD_MspInit(hpcd);
- }
-
- hpcd->State = HAL_PCD_STATE_BUSY;
-
- /* Disable the Interrupts */
- __HAL_PCD_DISABLE(hpcd);
-
- /*Init the Core (common init.) */
- USB_CoreInit(hpcd->Instance, hpcd->Init);
-
- /* Force Device Mode*/
- USB_SetCurrentMode(hpcd->Instance , USB_DEVICE_MODE);
-
- /* Init endpoints structures */
- for (index = 0U; index < 15U ; index++)
- {
- /* Init ep structure */
- hpcd->IN_ep[index].is_in = 1U;
- hpcd->IN_ep[index].num = index;
- hpcd->IN_ep[index].tx_fifo_num = index;
- /* Control until ep is actvated */
- hpcd->IN_ep[index].type = EP_TYPE_CTRL;
- hpcd->IN_ep[index].maxpacket = 0U;
- hpcd->IN_ep[index].xfer_buff = 0U;
- hpcd->IN_ep[index].xfer_len = 0U;
- }
-
- for (index = 0U; index < 15U ; index++)
- {
- hpcd->OUT_ep[index].is_in = 0U;
- hpcd->OUT_ep[index].num = index;
- hpcd->IN_ep[index].tx_fifo_num = index;
- /* Control until ep is activated */
- hpcd->OUT_ep[index].type = EP_TYPE_CTRL;
- hpcd->OUT_ep[index].maxpacket = 0U;
- hpcd->OUT_ep[index].xfer_buff = 0U;
- hpcd->OUT_ep[index].xfer_len = 0U;
- }
-
- /* Init Device */
- USB_DevInit(hpcd->Instance, hpcd->Init);
-
- hpcd->USB_Address = 0U;
- hpcd->State= HAL_PCD_STATE_READY;
-
- USB_DevDisconnect (hpcd->Instance);
- return HAL_OK;
-}
-
-/**
- * @brief DeInitializes the PCD peripheral
- * @param hpcd: PCD handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
-{
- /* Check the PCD handle allocation */
- if(hpcd == NULL)
- {
- return HAL_ERROR;
- }
-
- hpcd->State = HAL_PCD_STATE_BUSY;
-
- /* Stop Device */
- HAL_PCD_Stop(hpcd);
-
- /* DeInit the low level hardware */
- HAL_PCD_MspDeInit(hpcd);
-
- hpcd->State = HAL_PCD_STATE_RESET;
-
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the PCD MSP.
- * @param hpcd: PCD handle
- * @retval None
- */
-__weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hpcd);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_PCD_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief DeInitializes PCD MSP.
- * @param hpcd: PCD handle
- * @retval None
- */
-__weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hpcd);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_PCD_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup PCD_Exported_Functions_Group2 IO operation functions
- * @brief Data transfers functions
- *
-@verbatim
- ===============================================================================
- ##### IO operation functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to manage the PCD data
- transfers.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Start The USB Device.
- * @param hpcd: PCD handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
-{
- __HAL_LOCK(hpcd);
- HAL_PCDEx_SetConnectionState (hpcd, 1);
- USB_DevConnect (hpcd->Instance);
- __HAL_PCD_ENABLE(hpcd);
- __HAL_UNLOCK(hpcd);
- return HAL_OK;
-}
-
-/**
- * @brief Stop The USB Device.
- * @param hpcd: PCD handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
-{
- __HAL_LOCK(hpcd);
- __HAL_PCD_DISABLE(hpcd);
- USB_StopDevice(hpcd->Instance);
- USB_DevDisconnect (hpcd->Instance);
- __HAL_UNLOCK(hpcd);
- return HAL_OK;
-}
-
-#if defined (USB_OTG_FS)
-/**
- * @brief This function handles PCD interrupt request.
- * @param hpcd: PCD handle
- * @retval HAL status
- */
-void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
-{
- USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
- uint32_t index = 0U, ep_intr = 0U, epint = 0U, epnum = 0U;
- uint32_t fifoemptymsk = 0U, temp = 0U;
- USB_OTG_EPTypeDef *ep = NULL;
-
- /* ensure that we are in device mode */
- if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
- {
- /* avoid spurious interrupt */
- if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
- {
- return;
- }
-
- if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
- {
- /* incorrect mode, acknowledge the interrupt */
- __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
- }
-
- if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
- {
- epnum = 0U;
-
- /* Read in the device interrupt bits */
- ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
-
- while ( ep_intr )
- {
- if (ep_intr & 0x1U)
- {
- epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum);
-
- if(( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
- {
- CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
-
- HAL_PCD_DataOutStageCallback(hpcd, epnum);
- }
-
- if(( epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
- {
- /* Inform the upper layer that a setup packet is available */
- HAL_PCD_SetupStageCallback(hpcd);
- CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
- }
-
- if(( epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
- {
- CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
- }
- }
- epnum++;
- ep_intr >>= 1U;
- }
- }
-
- if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
- {
- /* Read in the device interrupt bits */
- ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
-
- epnum = 0U;
-
- while ( ep_intr )
- {
- if (ep_intr & 0x1U) /* In ITR */
- {
- epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum);
-
- if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
- {
- fifoemptymsk = 0x1U << epnum;
- USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
-
- CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
-
- HAL_PCD_DataInStageCallback(hpcd, epnum);
- }
- if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
- {
- CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
- }
- if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
- {
- CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
- }
- if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
- {
- CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
- }
- if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
- {
- CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
- }
- if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
- {
- PCD_WriteEmptyTxFifo(hpcd , epnum);
- }
- }
- epnum++;
- ep_intr >>= 1U;
- }
- }
-
- /* Handle Resume Interrupt */
- if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
- {
- /* Clear the Remote Wake-up signalling */
- USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
-
- HAL_PCD_ResumeCallback(hpcd);
-
- __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
- }
-
- /* Handle Suspend Interrupt */
- if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
- {
- if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
- {
-
- HAL_PCD_SuspendCallback(hpcd);
- }
- __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
- }
-
- /* Handle Reset Interrupt */
- if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
- {
- USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
- USB_FlushTxFifo(hpcd->Instance , 0x10U);
-
- for (index = 0U; index < hpcd->Init.dev_endpoints ; index++)
- {
- USBx_INEP(index)->DIEPINT = 0xFFU;
- USBx_OUTEP(index)->DOEPINT = 0xFFU;
- }
- USBx_DEVICE->DAINT = 0xFFFFFFFFU;
- USBx_DEVICE->DAINTMSK |= 0x10001U;
-
- USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
- USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
-
- /* Set Default Address to 0 */
- USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
-
- /* setup EP0 to receive SETUP packets */
- USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
-
- __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
- }
-
- /* Handle Enumeration done Interrupt */
- if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
- {
- USB_ActivateSetup(hpcd->Instance);
- hpcd->Instance->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
-
- hpcd->Init.speed = USB_OTG_SPEED_FULL;
- hpcd->Init.ep0_mps = USB_OTG_FS_MAX_PACKET_SIZE ;
- hpcd->Instance->GUSBCFG |= (uint32_t)((USBD_FS_TRDT_VALUE << 10U) & USB_OTG_GUSBCFG_TRDT);
-
- HAL_PCD_ResetCallback(hpcd);
-
- __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
- }
-
- /* Handle RxQLevel Interrupt */
- if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
- {
- USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
- temp = USBx->GRXSTSP;
- ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
-
- if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) == STS_DATA_UPDT)
- {
- if((temp & USB_OTG_GRXSTSP_BCNT) != 0U)
- {
- USB_ReadPacket(USBx, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4U);
- ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
- ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
- }
- }
- else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) == STS_SETUP_UPDT)
- {
- USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
- ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
- }
- USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
- }
-
- /* Handle SOF Interrupt */
- if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
- {
- HAL_PCD_SOFCallback(hpcd);
- __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
- }
-
- /* Handle Incomplete ISO IN Interrupt */
- if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
- {
- HAL_PCD_ISOINIncompleteCallback(hpcd, epnum);
- __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
- }
-
- /* Handle Incomplete ISO OUT Interrupt */
- if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
- {
- HAL_PCD_ISOOUTIncompleteCallback(hpcd, epnum);
- __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
- }
-
- /* Handle Connection event Interrupt */
- if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
- {
- HAL_PCD_ConnectCallback(hpcd);
- __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
- }
-
- /* Handle Disconnection event Interrupt */
- if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
- {
- temp = hpcd->Instance->GOTGINT;
-
- if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
- {
- HAL_PCD_DisconnectCallback(hpcd);
- }
- hpcd->Instance->GOTGINT |= temp;
- }
- }
-}
-#endif /* USB_OTG_FS */
-
-#if defined (USB)
-/**
- * @brief This function handles PCD interrupt request.
- * @param hpcd: PCD handle
- * @retval HAL status
- */
-void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
-{
- if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_CTR))
- {
- /* servicing of the endpoint correct transfer interrupt */
- /* clear of the CTR flag into the sub */
- PCD_EP_ISR_Handler(hpcd);
- }
-
- if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_RESET))
- {
- __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
- HAL_PCD_ResetCallback(hpcd);
- HAL_PCD_SetAddress(hpcd, 0U);
- }
-
- if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_PMAOVR))
- {
- __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
- }
- if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ERR))
- {
- __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
- }
-
- if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP))
- {
- hpcd->Instance->CNTR &= ~(USB_CNTR_LP_MODE);
- hpcd->Instance->CNTR &= ~(USB_CNTR_FSUSP);
-
- HAL_PCD_ResumeCallback(hpcd);
-
- __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
- }
-
- if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SUSP))
- {
- /* Force low-power mode in the macrocell */
- hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
-
- /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
- __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
-
- hpcd->Instance->CNTR |= USB_CNTR_LP_MODE;
- if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP) == 0U)
- {
- HAL_PCD_SuspendCallback(hpcd);
- }
- }
-
- if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SOF))
- {
- __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
- HAL_PCD_SOFCallback(hpcd);
- }
-
- if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ESOF))
- {
- /* clear ESOF flag in ISTR */
- __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
- }
-}
-#endif /* USB */
-
-/**
- * @brief Data out stage callbacks
- * @param hpcd: PCD handle
- * @param epnum: endpoint number
- * @retval None
- */
- __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hpcd);
- UNUSED(epnum);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_PCD_DataOutStageCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Data IN stage callbacks
- * @param hpcd: PCD handle
- * @param epnum: endpoint number
- * @retval None
- */
- __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hpcd);
- UNUSED(epnum);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_PCD_DataInStageCallback could be implemented in the user file
- */
-}
-/**
- * @brief Setup stage callback
- * @param hpcd: PCD handle
- * @retval None
- */
- __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hpcd);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_PCD_SetupStageCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief USB Start Of Frame callbacks
- * @param hpcd: PCD handle
- * @retval None
- */
- __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hpcd);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_PCD_SOFCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief USB Reset callbacks
- * @param hpcd: PCD handle
- * @retval None
- */
- __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hpcd);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_PCD_ResetCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Suspend event callbacks
- * @param hpcd: PCD handle
- * @retval None
- */
- __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hpcd);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_PCD_SuspendCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Resume event callbacks
- * @param hpcd: PCD handle
- * @retval None
- */
- __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hpcd);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_PCD_ResumeCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Incomplete ISO OUT callbacks
- * @param hpcd: PCD handle
- * @param epnum: endpoint number
- * @retval None
- */
- __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hpcd);
- UNUSED(epnum);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Incomplete ISO IN callbacks
- * @param hpcd: PCD handle
- * @param epnum: endpoint number
- * @retval None
- */
- __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hpcd);
- UNUSED(epnum);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Connection event callbacks
- * @param hpcd: PCD handle
- * @retval None
- */
- __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hpcd);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_PCD_ConnectCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Disconnection event callbacks
- * @param hpcd: PCD handle
- * @retval None
- */
- __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hpcd);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_PCD_DisconnectCallback could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
- * @brief management functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral Control functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to control the PCD data
- transfers.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Connect the USB device
- * @param hpcd: PCD handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
-{
- __HAL_LOCK(hpcd);
- HAL_PCDEx_SetConnectionState (hpcd, 1);
- USB_DevConnect(hpcd->Instance);
- __HAL_UNLOCK(hpcd);
- return HAL_OK;
-}
-
-/**
- * @brief Disconnect the USB device
- * @param hpcd: PCD handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
-{
- __HAL_LOCK(hpcd);
- HAL_PCDEx_SetConnectionState (hpcd, 0U);
- USB_DevDisconnect(hpcd->Instance);
- __HAL_UNLOCK(hpcd);
- return HAL_OK;
-}
-
-/**
- * @brief Set the USB Device address
- * @param hpcd: PCD handle
- * @param address: new device address
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
-{
- __HAL_LOCK(hpcd);
- hpcd->USB_Address = address;
- USB_SetDevAddress(hpcd->Instance, address);
- __HAL_UNLOCK(hpcd);
- return HAL_OK;
-}
-/**
- * @brief Open and configure an endpoint
- * @param hpcd: PCD handle
- * @param ep_addr: endpoint address
- * @param ep_mps: endpoint max packet size
- * @param ep_type: endpoint type
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
-{
- HAL_StatusTypeDef ret = HAL_OK;
- PCD_EPTypeDef *ep = NULL;
-
- if ((ep_addr & 0x80U) == 0x80U)
- {
- ep = &hpcd->IN_ep[ep_addr & 0x7FU];
- }
- else
- {
- ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
- }
- ep->num = ep_addr & 0x7FU;
-
- ep->is_in = (0x80U & ep_addr) != 0U;
- ep->maxpacket = ep_mps;
- ep->type = ep_type;
-
- __HAL_LOCK(hpcd);
- USB_ActivateEndpoint(hpcd->Instance , ep);
- __HAL_UNLOCK(hpcd);
- return ret;
-}
-
-/**
- * @brief Deactivate an endpoint
- * @param hpcd: PCD handle
- * @param ep_addr: endpoint address
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
-{
- PCD_EPTypeDef *ep = NULL;
-
- if ((ep_addr & 0x80U) == 0x80U)
- {
- ep = &hpcd->IN_ep[ep_addr & 0x7FU];
- }
- else
- {
- ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
- }
- ep->num = ep_addr & 0x7FU;
-
- ep->is_in = (0x80U & ep_addr) != 0U;
-
- __HAL_LOCK(hpcd);
- USB_DeactivateEndpoint(hpcd->Instance , ep);
- __HAL_UNLOCK(hpcd);
- return HAL_OK;
-}
-
-
-/**
- * @brief Receive an amount of data
- * @param hpcd: PCD handle
- * @param ep_addr: endpoint address
- * @param pBuf: pointer to the reception buffer
- * @param len: amount of data to be received
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
-{
- PCD_EPTypeDef *ep = NULL;
-
- ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
-
- /*setup and start the Xfer */
- ep->xfer_buff = pBuf;
- ep->xfer_len = len;
- ep->xfer_count = 0U;
- ep->is_in = 0U;
- ep->num = ep_addr & 0x7FU;
-
- if ((ep_addr & 0x7FU) == 0U)
- {
- USB_EP0StartXfer(hpcd->Instance , ep);
- }
- else
- {
- USB_EPStartXfer(hpcd->Instance , ep);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Get Received Data Size
- * @param hpcd: PCD handle
- * @param ep_addr: endpoint address
- * @retval Data Size
- */
-uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
-{
- return hpcd->OUT_ep[ep_addr & 0xF].xfer_count;
-}
-/**
- * @brief Send an amount of data
- * @param hpcd: PCD handle
- * @param ep_addr: endpoint address
- * @param pBuf: pointer to the transmission buffer
- * @param len: amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
-{
- PCD_EPTypeDef *ep = NULL;
-
- ep = &hpcd->IN_ep[ep_addr & 0x7FU];
-
- /*setup and start the Xfer */
- ep->xfer_buff = pBuf;
- ep->xfer_len = len;
- ep->xfer_count = 0U;
- ep->is_in = 1U;
- ep->num = ep_addr & 0x7FU;
-
- if ((ep_addr & 0x7FU) == 0U)
- {
- USB_EP0StartXfer(hpcd->Instance , ep);
- }
- else
- {
- USB_EPStartXfer(hpcd->Instance , ep);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Set a STALL condition over an endpoint
- * @param hpcd: PCD handle
- * @param ep_addr: endpoint address
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
-{
- PCD_EPTypeDef *ep = NULL;
-
- if ((0x80U & ep_addr) == 0x80U)
- {
- ep = &hpcd->IN_ep[ep_addr & 0x7FU];
- }
- else
- {
- ep = &hpcd->OUT_ep[ep_addr];
- }
-
- ep->is_stall = 1U;
- ep->num = ep_addr & 0x7FU;
- ep->is_in = ((ep_addr & 0x80U) == 0x80U);
-
- __HAL_LOCK(hpcd);
- USB_EPSetStall(hpcd->Instance , ep);
- if((ep_addr & 0x7FU) == 0U)
- {
- USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
- }
- __HAL_UNLOCK(hpcd);
-
- return HAL_OK;
-}
-
-/**
- * @brief Clear a STALL condition over in an endpoint
- * @param hpcd: PCD handle
- * @param ep_addr: endpoint address
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
-{
- PCD_EPTypeDef *ep = NULL;
-
- if ((0x80U & ep_addr) == 0x80U)
- {
- ep = &hpcd->IN_ep[ep_addr & 0x7FU];
- }
- else
- {
- ep = &hpcd->OUT_ep[ep_addr];
- }
-
- ep->is_stall = 0U;
- ep->num = ep_addr & 0x7FU;
- ep->is_in = ((ep_addr & 0x80U) == 0x80U);
-
- __HAL_LOCK(hpcd);
- USB_EPClearStall(hpcd->Instance , ep);
- __HAL_UNLOCK(hpcd);
-
- return HAL_OK;
-}
-
-/**
- * @brief Flush an endpoint
- * @param hpcd: PCD handle
- * @param ep_addr: endpoint address
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
-{
- __HAL_LOCK(hpcd);
-
- if ((ep_addr & 0x80U) == 0x80U)
- {
- USB_FlushTxFifo(hpcd->Instance, ep_addr & 0x7FU);
- }
- else
- {
- USB_FlushRxFifo(hpcd->Instance);
- }
-
- __HAL_UNLOCK(hpcd);
-
- return HAL_OK;
-}
-
-/**
- * @brief HAL_PCD_ActivateRemoteWakeup : active remote wakeup signalling
- * @param hpcd: PCD handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
-{
- return(USB_ActivateRemoteWakeup(hpcd->Instance));
-}
-
-/**
- * @brief HAL_PCD_DeActivateRemoteWakeup : de-active remote wakeup signalling
- * @param hpcd: PCD handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
-{
- return(USB_DeActivateRemoteWakeup(hpcd->Instance));
-}
-/**
- * @}
- */
-
-/** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
- * @brief Peripheral State functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral State functions #####
- ===============================================================================
- [..]
- This subsection permits to get in run-time the status of the peripheral
- and the data flow.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Return the PCD state
- * @param hpcd: PCD handle
- * @retval HAL state
- */
-PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
-{
- return hpcd->State;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup PCD_Private_Functions
- * @{
- */
-#if defined (USB_OTG_FS)
-/**
- * @brief DCD_WriteEmptyTxFifo
- * check FIFO for the next packet to be loaded
- * @param hpcd: PCD handle
- * @param epnum : endpoint number
- * This parameter can be a value from 0 to 15
- * @retval HAL status
- */
-static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
-{
- USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
- USB_OTG_EPTypeDef *ep = NULL;
- int32_t len = 0;
- uint32_t len32b = 0U;
- uint32_t fifoemptymsk = 0U;
-
- ep = &hpcd->IN_ep[epnum];
- len = ep->xfer_len - ep->xfer_count;
-
- if (len > ep->maxpacket)
- {
- len = ep->maxpacket;
- }
-
- len32b = (len + 3U) / 4U;
-
- while ((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b &&
- ep->xfer_count < ep->xfer_len &&
- ep->xfer_len != 0U)
- {
- /* Write the FIFO */
- len = ep->xfer_len - ep->xfer_count;
-
- if ((uint32_t)len > ep->maxpacket)
- {
- len = ep->maxpacket;
- }
- len32b = (len + 3U) / 4U;
-
- USB_WritePacket(USBx, ep->xfer_buff, epnum, len);
-
- ep->xfer_buff += len;
- ep->xfer_count += len;
- }
-
- if(len <= 0)
- {
- fifoemptymsk = 0x01U << epnum;
- USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
-
- }
-
- return HAL_OK;
-}
-#endif /* USB_OTG_FS */
-
-#if defined (USB)
-/**
- * @brief This function handles PCD Endpoint interrupt request.
- * @param hpcd: PCD handle
- * @retval HAL status
- */
-static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
-{
- PCD_EPTypeDef *ep = NULL;
- uint16_t count = 0;
- uint8_t epindex = 0;
- __IO uint16_t wIstr = 0;
- __IO uint16_t wEPVal = 0;
-
- /* stay in loop while pending interrupts */
- while (((wIstr = hpcd->Instance->ISTR) & USB_ISTR_CTR) != 0)
- {
- /* extract highest priority endpoint number */
- epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
-
- if (epindex == 0)
- {
- /* Decode and service control endpoint interrupt */
-
- /* DIR bit = origin of the interrupt */
- if ((wIstr & USB_ISTR_DIR) == 0)
- {
- /* DIR = 0 */
-
- /* DIR = 0 => IN int */
- /* DIR = 0 implies that (EP_CTR_TX = 1) always */
- PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
- ep = &hpcd->IN_ep[0];
-
- ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
- ep->xfer_buff += ep->xfer_count;
-
- /* TX COMPLETE */
- HAL_PCD_DataInStageCallback(hpcd, 0U);
-
-
- if((hpcd->USB_Address > 0U)&& ( ep->xfer_len == 0U))
- {
- hpcd->Instance->DADDR = (hpcd->USB_Address | USB_DADDR_EF);
- hpcd->USB_Address = 0U;
- }
-
- }
- else
- {
- /* DIR = 1 */
-
- /* DIR = 1 & CTR_RX => SETUP or OUT int */
- /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
- ep = &hpcd->OUT_ep[0U];
- wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
-
- if ((wEPVal & USB_EP_SETUP) != 0U)
- {
- /* Get SETUP Packet*/
- ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
- USB_ReadPMA(hpcd->Instance, (uint8_t*)hpcd->Setup ,ep->pmaadress , ep->xfer_count);
- /* SETUP bit kept frozen while CTR_RX = 1*/
- PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
-
- /* Process SETUP Packet*/
- HAL_PCD_SetupStageCallback(hpcd);
- }
-
- else if ((wEPVal & USB_EP_CTR_RX) != 0U)
- {
- PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
- /* Get Control Data OUT Packet*/
- ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
-
- if (ep->xfer_count != 0U)
- {
- USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, ep->xfer_count);
- ep->xfer_buff+=ep->xfer_count;
- }
-
- /* Process Control Data OUT Packet*/
- HAL_PCD_DataOutStageCallback(hpcd, 0U);
-
- PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
- PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
- }
- }
- }
- else
- {
- /* Decode and service non control endpoints interrupt */
-
- /* process related endpoint register */
- wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
- if ((wEPVal & USB_EP_CTR_RX) != 0U)
- {
- /* clear int flag */
- PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
- ep = &hpcd->OUT_ep[epindex];
-
- /* OUT double Buffering*/
- if (ep->doublebuffer == 0U)
- {
- count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
- if (count != 0U)
- {
- USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
- }
- }
- else
- {
- if (PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX)
- {
- /*read from endpoint BUF0Addr buffer*/
- count = PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
- if (count != 0U)
- {
- USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
- }
- }
- else
- {
- /*read from endpoint BUF1Addr buffer*/
- count = PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
- if (count != 0U)
- {
- USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
- }
- }
- PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_OUT);
- }
- /*multi-packet on the NON control OUT endpoint*/
- ep->xfer_count+=count;
- ep->xfer_buff+=count;
-
- if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
- {
- /* RX COMPLETE */
- HAL_PCD_DataOutStageCallback(hpcd, ep->num);
- }
- else
- {
- HAL_PCD_EP_Receive(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
- }
-
- } /* if((wEPVal & EP_CTR_RX) */
-
- if ((wEPVal & USB_EP_CTR_TX) != 0U)
- {
- ep = &hpcd->IN_ep[epindex];
-
- /* clear int flag */
- PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
-
- /* IN double Buffering*/
- if (ep->doublebuffer == 0U)
- {
- ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
- if (ep->xfer_count != 0U)
- {
- USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, ep->xfer_count);
- }
- }
- else
- {
- if (PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_TX)
- {
- /*read from endpoint BUF0Addr buffer*/
- ep->xfer_count = PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
- if (ep->xfer_count != 0U)
- {
- USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, ep->xfer_count);
- }
- }
- else
- {
- /*read from endpoint BUF1Addr buffer*/
- ep->xfer_count = PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
- if (ep->xfer_count != 0U)
- {
- USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, ep->xfer_count);
- }
- }
- PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_IN);
- }
- /*multi-packet on the NON control IN endpoint*/
- ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
- ep->xfer_buff+=ep->xfer_count;
-
- /* Zero Length Packet? */
- if (ep->xfer_len == 0U)
- {
- /* TX COMPLETE */
- HAL_PCD_DataInStageCallback(hpcd, ep->num);
- }
- else
- {
- HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
- }
- }
- }
- }
- return HAL_OK;
-}
-#endif /* USB */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* STM32F102x6 || STM32F102xB || */
- /* STM32F103x6 || STM32F103xB || */
- /* STM32F103xE || STM32F103xG || */
- /* STM32F105xC || STM32F107xC */
-
-#endif /* HAL_PCD_MODULE_ENABLED */
-
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd_ex.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd_ex.c
deleted file mode 100644
index fb8013e..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd_ex.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_pcd_ex.c
- * @author MCD Application Team
- * @brief Extended PCD HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the USB Peripheral Controller:
- * + Extended features functions: Update FIFO configuration,
- * PMA configuration for EPs
- *
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#ifdef HAL_PCD_MODULE_ENABLED
-
-#if defined(STM32F102x6) || defined(STM32F102xB) || \
- defined(STM32F103x6) || defined(STM32F103xB) || \
- defined(STM32F103xE) || defined(STM32F103xG) || \
- defined(STM32F105xC) || defined(STM32F107xC)
-
-
-/** @defgroup PCDEx PCDEx
- * @brief PCD Extended HAL module driver
- * @{
- */
-
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup PCDEx_Exported_Functions PCDEx Exported Functions
- * @{
- */
-
-/** @defgroup PCDEx_Exported_Functions_Group1 Peripheral Control functions
- * @brief PCDEx control functions
- *
-@verbatim
- ===============================================================================
- ##### Extended Peripheral Control functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Update FIFO (USB_OTG_FS)
- (+) Update PMA configuration (USB)
-
-@endverbatim
- * @{
- */
-
-#if defined (USB_OTG_FS)
-/**
- * @brief Set Tx FIFO
- * @param hpcd: PCD handle
- * @param fifo: The number of Tx fifo
- * @param size: Fifo size
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size)
-{
- uint8_t index = 0;
- uint32_t Tx_Offset = 0U;
-
- /* TXn min size = 16 words. (n : Transmit FIFO index)
- When a TxFIFO is not used, the Configuration should be as follows:
- case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes)
- --> Txm can use the space allocated for Txn.
- case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes)
- --> Txn should be configured with the minimum space of 16 words
- The FIFO is used optimally when used TxFIFOs are allocated in the top
- of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
- When DMA is used 3n * FIFO locations should be reserved for internal DMA registers */
-
- Tx_Offset = hpcd->Instance->GRXFSIZ;
-
- if(fifo == 0U)
- {
- hpcd->Instance->DIEPTXF0_HNPTXFSIZ = (size << 16U) | Tx_Offset;
- }
- else
- {
- Tx_Offset += (hpcd->Instance->DIEPTXF0_HNPTXFSIZ) >> 16U;
- for(index = 0; index < (fifo - 1); index++)
- {
- Tx_Offset += (hpcd->Instance->DIEPTXF[index] >> 16U);
- }
-
- /* Multiply Tx_Size by 2 to get higher performance */
- hpcd->Instance->DIEPTXF[fifo - 1U] = (size << 16U) | Tx_Offset;
-
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Set Rx FIFO
- * @param hpcd: PCD handle
- * @param size: Size of Rx fifo
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size)
-{
- hpcd->Instance->GRXFSIZ = size;
- return HAL_OK;
-}
-#endif /* USB_OTG_FS */
-
-#if defined (USB)
-/**
- * @brief Configure PMA for EP
- * @param hpcd : Device instance
- * @param ep_addr: endpoint address
- * @param ep_kind: endpoint Kind
- * USB_SNG_BUF: Single Buffer used
- * USB_DBL_BUF: Double Buffer used
- * @param pmaadress: EP address in The PMA: In case of single buffer endpoint
- * this parameter is 16-bit value providing the address
- * in PMA allocated to endpoint.
- * In case of double buffer endpoint this parameter
- * is a 32-bit value providing the endpoint buffer 0 address
- * in the LSB part of 32-bit value and endpoint buffer 1 address
- * in the MSB part of 32-bit value.
- * @retval HAL status
- */
-
-HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd,
- uint16_t ep_addr,
- uint16_t ep_kind,
- uint32_t pmaadress)
-
-{
- PCD_EPTypeDef *ep = NULL;
-
- /* initialize ep structure*/
- if ((ep_addr & 0x80U) == 0x80U)
- {
- ep = &hpcd->IN_ep[ep_addr & 0x7FU];
- }
- else
- {
- ep = &hpcd->OUT_ep[ep_addr];
- }
-
- /* Here we check if the endpoint is single or double Buffer*/
- if (ep_kind == PCD_SNG_BUF)
- {
- /*Single Buffer*/
- ep->doublebuffer = 0U;
- /*Configure te PMA*/
- ep->pmaadress = (uint16_t)pmaadress;
- }
- else /*USB_DBL_BUF*/
- {
- /*Double Buffer Endpoint*/
- ep->doublebuffer = 1U;
- /*Configure the PMA*/
- ep->pmaaddr0 = pmaadress & 0x0000FFFFU;
- ep->pmaaddr1 = (pmaadress & 0xFFFF0000U) >> 16U;
- }
-
- return HAL_OK;
-}
-#endif /* USB */
-/**
- * @}
- */
-
-/** @defgroup PCDEx_Exported_Functions_Group2 Peripheral State functions
- * @brief Manage device connection state
- * @{
- */
-/**
- * @brief Software Device Connection,
- * this function is not required by USB OTG FS peripheral, it is used
- * only by USB Device FS peripheral.
- * @param hpcd: PCD handle
- * @param state: connection state (0 : disconnected / 1: connected)
- * @retval None
- */
-__weak void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hpcd);
- UNUSED(state);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_PCDEx_SetConnectionState could be implemented in the user file
- */
-}
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* STM32F102x6 || STM32F102xB || */
- /* STM32F103x6 || STM32F103xB || */
- /* STM32F103xE || STM32F103xG || */
- /* STM32F105xC || STM32F107xC */
-
-#endif /* HAL_PCD_MODULE_ENABLED */
-
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c
deleted file mode 100644
index 44d6613..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c
+++ /dev/null
@@ -1,637 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_pwr.c
- * @author MCD Application Team
- * @brief PWR HAL module driver.
- *
- * This file provides firmware functions to manage the following
- * functionalities of the Power Controller (PWR) peripheral:
- * + Initialization/de-initialization functions
- * + Peripheral Control functions
- *
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup PWR PWR
- * @brief PWR HAL module driver
- * @{
- */
-
-#ifdef HAL_PWR_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-
-/** @defgroup PWR_Private_Constants PWR Private Constants
- * @{
- */
-
-/** @defgroup PWR_PVD_Mode_Mask PWR PVD Mode Mask
- * @{
- */
-#define PVD_MODE_IT 0x00010000U
-#define PVD_MODE_EVT 0x00020000U
-#define PVD_RISING_EDGE 0x00000001U
-#define PVD_FALLING_EDGE 0x00000002U
-/**
- * @}
- */
-
-
-/** @defgroup PWR_register_alias_address PWR Register alias address
- * @{
- */
-/* ------------- PWR registers bit address in the alias region ---------------*/
-#define PWR_OFFSET (PWR_BASE - PERIPH_BASE)
-#define PWR_CR_OFFSET 0x00U
-#define PWR_CSR_OFFSET 0x04U
-#define PWR_CR_OFFSET_BB (PWR_OFFSET + PWR_CR_OFFSET)
-#define PWR_CSR_OFFSET_BB (PWR_OFFSET + PWR_CSR_OFFSET)
-/**
- * @}
- */
-
-/** @defgroup PWR_CR_register_alias PWR CR Register alias address
- * @{
- */
-/* --- CR Register ---*/
-/* Alias word address of LPSDSR bit */
-#define LPSDSR_BIT_NUMBER PWR_CR_LPDS_Pos
-#define CR_LPSDSR_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32U) + (LPSDSR_BIT_NUMBER * 4U)))
-
-/* Alias word address of DBP bit */
-#define DBP_BIT_NUMBER PWR_CR_DBP_Pos
-#define CR_DBP_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32U) + (DBP_BIT_NUMBER * 4U)))
-
-/* Alias word address of PVDE bit */
-#define PVDE_BIT_NUMBER PWR_CR_PVDE_Pos
-#define CR_PVDE_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32U) + (PVDE_BIT_NUMBER * 4U)))
-
-/**
- * @}
- */
-
-/** @defgroup PWR_CSR_register_alias PWR CSR Register alias address
- * @{
- */
-
-/* --- CSR Register ---*/
-/* Alias word address of EWUP1 bit */
-#define CSR_EWUP_BB(VAL) ((uint32_t)(PERIPH_BB_BASE + (PWR_CSR_OFFSET_BB * 32U) + (POSITION_VAL(VAL) * 4U)))
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @defgroup PWR_Private_Functions PWR Private Functions
- * brief WFE cortex command overloaded for HAL_PWR_EnterSTOPMode usage only (see Workaround section)
- * @{
- */
-static void PWR_OverloadWfe(void);
-
-/* Private functions ---------------------------------------------------------*/
-__NOINLINE
-static void PWR_OverloadWfe(void)
-{
- __asm volatile( "wfe" );
- __asm volatile( "nop" );
-}
-
-/**
- * @}
- */
-
-
-/** @defgroup PWR_Exported_Functions PWR Exported Functions
- * @{
- */
-
-/** @defgroup PWR_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and de-initialization functions
- *
-@verbatim
- ===============================================================================
- ##### Initialization and de-initialization functions #####
- ===============================================================================
- [..]
- After reset, the backup domain (RTC registers, RTC backup data
- registers) is protected against possible unwanted
- write accesses.
- To enable access to the RTC Domain and RTC registers, proceed as follows:
- (+) Enable the Power Controller (PWR) APB1 interface clock using the
- __HAL_RCC_PWR_CLK_ENABLE() macro.
- (+) Enable access to RTC domain using the HAL_PWR_EnableBkUpAccess() function.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Deinitializes the PWR peripheral registers to their default reset values.
- * @retval None
- */
-void HAL_PWR_DeInit(void)
-{
- __HAL_RCC_PWR_FORCE_RESET();
- __HAL_RCC_PWR_RELEASE_RESET();
-}
-
-/**
- * @brief Enables access to the backup domain (RTC registers, RTC
- * backup data registers ).
- * @note If the HSE divided by 128 is used as the RTC clock, the
- * Backup Domain Access should be kept enabled.
- * @retval None
- */
-void HAL_PWR_EnableBkUpAccess(void)
-{
- /* Enable access to RTC and backup registers */
- *(__IO uint32_t *) CR_DBP_BB = (uint32_t)ENABLE;
-}
-
-/**
- * @brief Disables access to the backup domain (RTC registers, RTC
- * backup data registers).
- * @note If the HSE divided by 128 is used as the RTC clock, the
- * Backup Domain Access should be kept enabled.
- * @retval None
- */
-void HAL_PWR_DisableBkUpAccess(void)
-{
- /* Disable access to RTC and backup registers */
- *(__IO uint32_t *) CR_DBP_BB = (uint32_t)DISABLE;
-}
-
-/**
- * @}
- */
-
-/** @defgroup PWR_Exported_Functions_Group2 Peripheral Control functions
- * @brief Low Power modes configuration functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral Control functions #####
- ===============================================================================
-
- *** PVD configuration ***
- =========================
- [..]
- (+) The PVD is used to monitor the VDD power supply by comparing it to a
- threshold selected by the PVD Level (PLS[2:0] bits in the PWR_CR).
-
- (+) A PVDO flag is available to indicate if VDD/VDDA is higher or lower
- than the PVD threshold. This event is internally connected to the EXTI
- line16 and can generate an interrupt if enabled. This is done through
- __HAL_PVD_EXTI_ENABLE_IT() macro.
- (+) The PVD is stopped in Standby mode.
-
- *** WakeUp pin configuration ***
- ================================
- [..]
- (+) WakeUp pin is used to wake up the system from Standby mode. This pin is
- forced in input pull-down configuration and is active on rising edges.
- (+) There is one WakeUp pin:
- WakeUp Pin 1 on PA.00.
-
- [..]
-
- *** Low Power modes configuration ***
- =====================================
- [..]
- The device features 3 low-power modes:
- (+) Sleep mode: CPU clock off, all peripherals including Cortex-M3 core peripherals like
- NVIC, SysTick, etc. are kept running
- (+) Stop mode: All clocks are stopped
- (+) Standby mode: 1.8V domain powered off
-
-
- *** Sleep mode ***
- ==================
- [..]
- (+) Entry:
- The Sleep mode is entered by using the HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFx)
- functions with
- (++) PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction
- (++) PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction
-
- (+) Exit:
- (++) WFI entry mode, Any peripheral interrupt acknowledged by the nested vectored interrupt
- controller (NVIC) can wake up the device from Sleep mode.
- (++) WFE entry mode, Any wakeup event can wake up the device from Sleep mode.
- (+++) Any peripheral interrupt w/o NVIC configuration & SEVONPEND bit set in the Cortex (HAL_PWR_EnableSEVOnPend)
- (+++) Any EXTI Line (Internal or External) configured in Event mode
-
- *** Stop mode ***
- =================
- [..]
- The Stop mode is based on the Cortex-M3 deepsleep mode combined with peripheral
- clock gating. The voltage regulator can be configured either in normal or low-power mode.
- In Stop mode, all clocks in the 1.8 V domain are stopped, the PLL, the HSI and the HSE RC
- oscillators are disabled. SRAM and register contents are preserved.
- In Stop mode, all I/O pins keep the same state as in Run mode.
-
- (+) Entry:
- The Stop mode is entered using the HAL_PWR_EnterSTOPMode(PWR_REGULATOR_VALUE, PWR_SLEEPENTRY_WFx )
- function with:
- (++) PWR_REGULATOR_VALUE= PWR_MAINREGULATOR_ON: Main regulator ON.
- (++) PWR_REGULATOR_VALUE= PWR_LOWPOWERREGULATOR_ON: Low Power regulator ON.
- (++) PWR_SLEEPENTRY_WFx= PWR_SLEEPENTRY_WFI: enter STOP mode with WFI instruction
- (++) PWR_SLEEPENTRY_WFx= PWR_SLEEPENTRY_WFE: enter STOP mode with WFE instruction
- (+) Exit:
- (++) WFI entry mode, Any EXTI Line (Internal or External) configured in Interrupt mode with NVIC configured
- (++) WFE entry mode, Any EXTI Line (Internal or External) configured in Event mode.
-
- *** Standby mode ***
- ====================
- [..]
- The Standby mode allows to achieve the lowest power consumption. It is based on the
- Cortex-M3 deepsleep mode, with the voltage regulator disabled. The 1.8 V domain is
- consequently powered off. The PLL, the HSI oscillator and the HSE oscillator are also
- switched off. SRAM and register contents are lost except for registers in the Backup domain
- and Standby circuitry
-
- (+) Entry:
- (++) The Standby mode is entered using the HAL_PWR_EnterSTANDBYMode() function.
- (+) Exit:
- (++) WKUP pin rising edge, RTC alarm event rising edge, external Reset in
- NRSTpin, IWDG Reset
-
- *** Auto-wakeup (AWU) from low-power mode ***
- =============================================
- [..]
-
- (+) The MCU can be woken up from low-power mode by an RTC Alarm event,
- without depending on an external interrupt (Auto-wakeup mode).
-
- (+) RTC auto-wakeup (AWU) from the Stop and Standby modes
-
- (++) To wake up from the Stop mode with an RTC alarm event, it is necessary to
- configure the RTC to generate the RTC alarm using the HAL_RTC_SetAlarm_IT() function.
-
- *** PWR Workarounds linked to Silicon Limitation ***
- ====================================================
- [..]
- Below the list of all silicon limitations known on STM32F1xx prouct.
-
- (#)Workarounds Implemented inside PWR HAL Driver
- (##)Debugging Stop mode with WFE entry - overloaded the WFE by an internal function
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD).
- * @param sConfigPVD: pointer to an PWR_PVDTypeDef structure that contains the configuration
- * information for the PVD.
- * @note Refer to the electrical characteristics of your device datasheet for
- * more details about the voltage threshold corresponding to each
- * detection level.
- * @retval None
- */
-void HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD)
-{
- /* Check the parameters */
- assert_param(IS_PWR_PVD_LEVEL(sConfigPVD->PVDLevel));
- assert_param(IS_PWR_PVD_MODE(sConfigPVD->Mode));
-
- /* Set PLS[7:5] bits according to PVDLevel value */
- MODIFY_REG(PWR->CR, PWR_CR_PLS, sConfigPVD->PVDLevel);
-
- /* Clear any previous config. Keep it clear if no event or IT mode is selected */
- __HAL_PWR_PVD_EXTI_DISABLE_EVENT();
- __HAL_PWR_PVD_EXTI_DISABLE_IT();
- __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE();
- __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();
-
- /* Configure interrupt mode */
- if((sConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT)
- {
- __HAL_PWR_PVD_EXTI_ENABLE_IT();
- }
-
- /* Configure event mode */
- if((sConfigPVD->Mode & PVD_MODE_EVT) == PVD_MODE_EVT)
- {
- __HAL_PWR_PVD_EXTI_ENABLE_EVENT();
- }
-
- /* Configure the edge */
- if((sConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE)
- {
- __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE();
- }
-
- if((sConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE)
- {
- __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE();
- }
-}
-
-/**
- * @brief Enables the Power Voltage Detector(PVD).
- * @retval None
- */
-void HAL_PWR_EnablePVD(void)
-{
- /* Enable the power voltage detector */
- *(__IO uint32_t *) CR_PVDE_BB = (uint32_t)ENABLE;
-}
-
-/**
- * @brief Disables the Power Voltage Detector(PVD).
- * @retval None
- */
-void HAL_PWR_DisablePVD(void)
-{
- /* Disable the power voltage detector */
- *(__IO uint32_t *) CR_PVDE_BB = (uint32_t)DISABLE;
-}
-
-/**
- * @brief Enables the WakeUp PINx functionality.
- * @param WakeUpPinx: Specifies the Power Wake-Up pin to enable.
- * This parameter can be one of the following values:
- * @arg PWR_WAKEUP_PIN1
- * @retval None
- */
-void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinx)
-{
- /* Check the parameter */
- assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
- /* Enable the EWUPx pin */
- *(__IO uint32_t *) CSR_EWUP_BB(WakeUpPinx) = (uint32_t)ENABLE;
-}
-
-/**
- * @brief Disables the WakeUp PINx functionality.
- * @param WakeUpPinx: Specifies the Power Wake-Up pin to disable.
- * This parameter can be one of the following values:
- * @arg PWR_WAKEUP_PIN1
- * @retval None
- */
-void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)
-{
- /* Check the parameter */
- assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
- /* Disable the EWUPx pin */
- *(__IO uint32_t *) CSR_EWUP_BB(WakeUpPinx) = (uint32_t)DISABLE;
-}
-
-/**
- * @brief Enters Sleep mode.
- * @note In Sleep mode, all I/O pins keep the same state as in Run mode.
- * @param Regulator: Regulator state as no effect in SLEEP mode - allows to support portability from legacy software
- * @param SLEEPEntry: Specifies if SLEEP mode is entered with WFI or WFE instruction.
- * When WFI entry is used, tick interrupt have to be disabled if not desired as
- * the interrupt wake up source.
- * This parameter can be one of the following values:
- * @arg PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction
- * @arg PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction
- * @retval None
- */
-void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
-{
- /* Check the parameters */
- /* No check on Regulator because parameter not used in SLEEP mode */
- /* Prevent unused argument(s) compilation warning */
- UNUSED(Regulator);
-
- assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry));
-
- /* Clear SLEEPDEEP bit of Cortex System Control Register */
- CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
-
- /* Select SLEEP mode entry -------------------------------------------------*/
- if(SLEEPEntry == PWR_SLEEPENTRY_WFI)
- {
- /* Request Wait For Interrupt */
- __WFI();
- }
- else
- {
- /* Request Wait For Event */
- __SEV();
- __WFE();
- __WFE();
- }
-}
-
-/**
- * @brief Enters Stop mode.
- * @note In Stop mode, all I/O pins keep the same state as in Run mode.
- * @note When exiting Stop mode by using an interrupt or a wakeup event,
- * HSI RC oscillator is selected as system clock.
- * @note When the voltage regulator operates in low power mode, an additional
- * startup delay is incurred when waking up from Stop mode.
- * By keeping the internal regulator ON during Stop mode, the consumption
- * is higher although the startup time is reduced.
- * @param Regulator: Specifies the regulator state in Stop mode.
- * This parameter can be one of the following values:
- * @arg PWR_MAINREGULATOR_ON: Stop mode with regulator ON
- * @arg PWR_LOWPOWERREGULATOR_ON: Stop mode with low power regulator ON
- * @param STOPEntry: Specifies if Stop mode in entered with WFI or WFE instruction.
- * This parameter can be one of the following values:
- * @arg PWR_STOPENTRY_WFI: Enter Stop mode with WFI instruction
- * @arg PWR_STOPENTRY_WFE: Enter Stop mode with WFE instruction
- * @retval None
- */
-void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
-{
- /* Check the parameters */
- assert_param(IS_PWR_REGULATOR(Regulator));
- assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
-
- /* Clear PDDS bit in PWR register to specify entering in STOP mode when CPU enter in Deepsleep */
- CLEAR_BIT(PWR->CR, PWR_CR_PDDS);
-
- /* Select the voltage regulator mode by setting LPDS bit in PWR register according to Regulator parameter value */
- MODIFY_REG(PWR->CR, PWR_CR_LPDS, Regulator);
-
- /* Set SLEEPDEEP bit of Cortex System Control Register */
- SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
-
- /* Select Stop mode entry --------------------------------------------------*/
- if(STOPEntry == PWR_STOPENTRY_WFI)
- {
- /* Request Wait For Interrupt */
- __WFI();
- }
- else
- {
- /* Request Wait For Event */
- __SEV();
- PWR_OverloadWfe(); /* WFE redefine locally */
- PWR_OverloadWfe(); /* WFE redefine locally */
- }
- /* Reset SLEEPDEEP bit of Cortex System Control Register */
- CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
-}
-
-/**
- * @brief Enters Standby mode.
- * @note In Standby mode, all I/O pins are high impedance except for:
- * - Reset pad (still available)
- * - TAMPER pin if configured for tamper or calibration out.
- * - WKUP pin (PA0) if enabled.
- * @retval None
- */
-void HAL_PWR_EnterSTANDBYMode(void)
-{
- /* Select Standby mode */
- SET_BIT(PWR->CR, PWR_CR_PDDS);
-
- /* Set SLEEPDEEP bit of Cortex System Control Register */
- SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
-
- /* This option is used to ensure that store operations are completed */
-#if defined ( __CC_ARM)
- __force_stores();
-#endif
- /* Request Wait For Interrupt */
- __WFI();
-}
-
-
-/**
- * @brief Indicates Sleep-On-Exit when returning from Handler mode to Thread mode.
- * @note Set SLEEPONEXIT bit of SCR register. When this bit is set, the processor
- * re-enters SLEEP mode when an interruption handling is over.
- * Setting this bit is useful when the processor is expected to run only on
- * interruptions handling.
- * @retval None
- */
-void HAL_PWR_EnableSleepOnExit(void)
-{
- /* Set SLEEPONEXIT bit of Cortex System Control Register */
- SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
-}
-
-
-/**
- * @brief Disables Sleep-On-Exit feature when returning from Handler mode to Thread mode.
- * @note Clears SLEEPONEXIT bit of SCR register. When this bit is set, the processor
- * re-enters SLEEP mode when an interruption handling is over.
- * @retval None
- */
-void HAL_PWR_DisableSleepOnExit(void)
-{
- /* Clear SLEEPONEXIT bit of Cortex System Control Register */
- CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
-}
-
-
-/**
- * @brief Enables CORTEX M3 SEVONPEND bit.
- * @note Sets SEVONPEND bit of SCR register. When this bit is set, this causes
- * WFE to wake up when an interrupt moves from inactive to pended.
- * @retval None
- */
-void HAL_PWR_EnableSEVOnPend(void)
-{
- /* Set SEVONPEND bit of Cortex System Control Register */
- SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
-}
-
-
-/**
- * @brief Disables CORTEX M3 SEVONPEND bit.
- * @note Clears SEVONPEND bit of SCR register. When this bit is set, this causes
- * WFE to wake up when an interrupt moves from inactive to pended.
- * @retval None
- */
-void HAL_PWR_DisableSEVOnPend(void)
-{
- /* Clear SEVONPEND bit of Cortex System Control Register */
- CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
-}
-
-
-
-/**
- * @brief This function handles the PWR PVD interrupt request.
- * @note This API should be called under the PVD_IRQHandler().
- * @retval None
- */
-void HAL_PWR_PVD_IRQHandler(void)
-{
- /* Check PWR exti flag */
- if(__HAL_PWR_PVD_EXTI_GET_FLAG() != RESET)
- {
- /* PWR PVD interrupt user callback */
- HAL_PWR_PVDCallback();
-
- /* Clear PWR Exti pending bit */
- __HAL_PWR_PVD_EXTI_CLEAR_FLAG();
- }
-}
-
-/**
- * @brief PWR PVD interrupt callback
- * @retval None
- */
-__weak void HAL_PWR_PVDCallback(void)
-{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_PWR_PVDCallback could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* HAL_PWR_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c
deleted file mode 100644
index e146d9b..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c
+++ /dev/null
@@ -1,1416 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_rcc.c
- * @author MCD Application Team
- * @brief RCC HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Reset and Clock Control (RCC) peripheral:
- * + Initialization and de-initialization functions
- * + Peripheral Control functions
- *
- @verbatim
- ==============================================================================
- ##### RCC specific features #####
- ==============================================================================
- [..]
- After reset the device is running from Internal High Speed oscillator
- (HSI 8MHz) with Flash 0 wait state, Flash prefetch buffer is enabled,
- and all peripherals are off except internal SRAM, Flash and JTAG.
- (+) There is no prescaler on High speed (AHB) and Low speed (APB) buses;
- all peripherals mapped on these buses are running at HSI speed.
- (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
- (+) All GPIOs are in input floating state, except the JTAG pins which
- are assigned to be used for debug purpose.
- [..] Once the device started from reset, the user application has to:
- (+) Configure the clock source to be used to drive the System clock
- (if the application needs higher frequency/performance)
- (+) Configure the System clock frequency and Flash settings
- (+) Configure the AHB and APB buses prescalers
- (+) Enable the clock for the peripheral(s) to be used
- (+) Configure the clock source(s) for peripherals whose clocks are not
- derived from the System clock (I2S, RTC, ADC, USB OTG FS)
-
- ##### RCC Limitations #####
- ==============================================================================
- [..]
- A delay between an RCC peripheral clock enable and the effective peripheral
- enabling should be taken into account in order to manage the peripheral read/write
- from/to registers.
- (+) This delay depends on the peripheral mapping.
- (++) AHB & APB peripherals, 1 dummy read is necessary
-
- [..]
- Workarounds:
- (#) For AHB & APB peripherals, a dummy read to the peripheral register has been
- inserted in each __HAL_RCC_PPP_CLK_ENABLE() macro.
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
-*/
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup RCC RCC
-* @brief RCC HAL module driver
- * @{
- */
-
-#ifdef HAL_RCC_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @defgroup RCC_Private_Constants RCC Private Constants
- * @{
- */
-/**
- * @}
- */
-/* Private macro -------------------------------------------------------------*/
-/** @defgroup RCC_Private_Macros RCC Private Macros
- * @{
- */
-
-#define MCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
-#define MCO1_GPIO_PORT GPIOA
-#define MCO1_PIN GPIO_PIN_8
-
-/**
- * @}
- */
-
-/* Private variables ---------------------------------------------------------*/
-/** @defgroup RCC_Private_Variables RCC Private Variables
- * @{
- */
-/**
- * @}
- */
-
-/* Private function prototypes -----------------------------------------------*/
-static void RCC_Delay(uint32_t mdelay);
-
-/* Exported functions --------------------------------------------------------*/
-
-/** @defgroup RCC_Exported_Functions RCC Exported Functions
- * @{
- */
-
-/** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
- @verbatim
- ===============================================================================
- ##### Initialization and de-initialization functions #####
- ===============================================================================
- [..]
- This section provides functions allowing to configure the internal/external oscillators
- (HSE, HSI, LSE, LSI, PLL, CSS and MCO) and the System buses clocks (SYSCLK, AHB, APB1
- and APB2).
-
- [..] Internal/external clock and PLL configuration
- (#) HSI (high-speed internal), 8 MHz factory-trimmed RC used directly or through
- the PLL as System clock source.
- (#) LSI (low-speed internal), ~40 KHz low consumption RC used as IWDG and/or RTC
- clock source.
-
- (#) HSE (high-speed external), 4 to 24 MHz (STM32F100xx) or 4 to 16 MHz (STM32F101x/STM32F102x/STM32F103x) or 3 to 25 MHz (STM32F105x/STM32F107x) crystal oscillator used directly or
- through the PLL as System clock source. Can be used also as RTC clock source.
-
- (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source.
-
- (#) PLL (clocked by HSI or HSE), featuring different output clocks:
- (++) The first output is used to generate the high speed system clock (up to 72 MHz for STM32F10xxx or up to 24 MHz for STM32F100xx)
- (++) The second output is used to generate the clock for the USB OTG FS (48 MHz)
-
- (#) CSS (Clock security system), once enable using the macro __HAL_RCC_CSS_ENABLE()
- and if a HSE clock failure occurs(HSE used directly or through PLL as System
- clock source), the System clocks automatically switched to HSI and an interrupt
- is generated if enabled. The interrupt is linked to the Cortex-M3 NMI
- (Non-Maskable Interrupt) exception vector.
-
- (#) MCO1 (microcontroller clock output), used to output SYSCLK, HSI,
- HSE or PLL clock (divided by 2) on PA8 pin + PLL2CLK, PLL3CLK/2, PLL3CLK and XTI for STM32F105x/STM32F107x
-
- [..] System, AHB and APB buses clocks configuration
- (#) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
- HSE and PLL.
- The AHB clock (HCLK) is derived from System clock through configurable
- prescaler and used to clock the CPU, memory and peripherals mapped
- on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
- from AHB clock through configurable prescalers and used to clock
- the peripherals mapped on these buses. You can use
- "@ref HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
-
- -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
- (+@) RTC: RTC clock can be derived either from the LSI, LSE or HSE clock
- divided by 128.
- (+@) USB OTG FS and RTC: USB OTG FS require a frequency equal to 48 MHz
- to work correctly. This clock is derived of the main PLL through PLL Multiplier.
- (+@) I2S interface on STM32F105x/STM32F107x can be derived from PLL3CLK
- (+@) IWDG clock which is always the LSI clock.
-
- (#) For STM32F10xxx, the maximum frequency of the SYSCLK and HCLK/PCLK2 is 72 MHz, PCLK1 36 MHz.
- For STM32F100xx, the maximum frequency of the SYSCLK and HCLK/PCLK1/PCLK2 is 24 MHz.
- Depending on the SYSCLK frequency, the flash latency should be adapted accordingly.
- @endverbatim
- * @{
- */
-
-/*
- Additional consideration on the SYSCLK based on Latency settings:
- +-----------------------------------------------+
- | Latency | SYSCLK clock frequency (MHz) |
- |---------------|-------------------------------|
- |0WS(1CPU cycle)| 0 < SYSCLK <= 24 |
- |---------------|-------------------------------|
- |1WS(2CPU cycle)| 24 < SYSCLK <= 48 |
- |---------------|-------------------------------|
- |2WS(3CPU cycle)| 48 < SYSCLK <= 72 |
- +-----------------------------------------------+
- */
-
-/**
- * @brief Resets the RCC clock configuration to the default reset state.
- * @note The default reset state of the clock configuration is given below:
- * - HSI ON and used as system clock source
- * - HSE, PLL, PLL2 and PLL3 are OFF
- * - AHB, APB1 and APB2 prescaler set to 1.
- * - CSS and MCO1 OFF
- * - All interrupts disabled
- * - All flags are cleared
- * @note This function does not modify the configuration of the
- * - Peripheral clocks
- * - LSI, LSE and RTC clocks
- * @retval HAL_StatusTypeDef
- */
-HAL_StatusTypeDef HAL_RCC_DeInit(void)
-{
- uint32_t tickstart;
-
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Set HSION bit */
- SET_BIT(RCC->CR, RCC_CR_HSION);
-
- /* Wait till HSI is ready */
- while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET)
- {
- if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Set HSITRIM bits to the reset value */
- MODIFY_REG(RCC->CR, RCC_CR_HSITRIM, (0x10U << RCC_CR_HSITRIM_Pos));
-
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Reset CFGR register */
- CLEAR_REG(RCC->CFGR);
-
- /* Wait till clock switch is ready */
- while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RESET)
- {
- if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Update the SystemCoreClock global variable */
- SystemCoreClock = HSI_VALUE;
-
- /* Adapt Systick interrupt period */
- if(HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)
- {
- return HAL_ERROR;
- }
-
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Second step is to clear PLLON bit */
- CLEAR_BIT(RCC->CR, RCC_CR_PLLON);
-
- /* Wait till PLL is disabled */
- while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET)
- {
- if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Ensure to reset PLLSRC and PLLMUL bits */
- CLEAR_REG(RCC->CFGR);
-
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Reset HSEON & CSSON bits */
- CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_CSSON);
-
- /* Wait till HSE is disabled */
- while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != RESET)
- {
- if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Reset HSEBYP bit */
- CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
-
-#if defined(RCC_PLL2_SUPPORT)
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Clear PLL2ON bit */
- CLEAR_BIT(RCC->CR, RCC_CR_PLL2ON);
-
- /* Wait till PLL2 is disabled */
- while (READ_BIT(RCC->CR, RCC_CR_PLL2RDY) != RESET)
- {
- if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
-#endif /* RCC_PLL2_SUPPORT */
-
-#if defined(RCC_PLLI2S_SUPPORT)
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Clear PLL3ON bit */
- CLEAR_BIT(RCC->CR, RCC_CR_PLL3ON);
-
- /* Wait till PLL3 is disabled */
- while (READ_BIT(RCC->CR, RCC_CR_PLL3RDY) != RESET)
- {
- if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
-#endif /* RCC_PLLI2S_SUPPORT */
-
-#if defined(RCC_CFGR2_PREDIV1)
- /* Reset CFGR2 register */
- CLEAR_REG(RCC->CFGR2);
-#endif /* RCC_CFGR2_PREDIV1 */
-
- /* Reset all CSR flags */
- SET_BIT(RCC->CSR, RCC_CSR_RMVF);
-
- /* Disable all interrupts */
- CLEAR_REG(RCC->CIR);
-
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the RCC Oscillators according to the specified parameters in the
- * RCC_OscInitTypeDef.
- * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
- * contains the configuration information for the RCC Oscillators.
- * @note The PLL is not disabled when used as system clock.
- * @note The PLL is not disabled when USB OTG FS clock is enabled (specific to devices with USB FS)
- * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
- * supported by this macro. User should request a transition to LSE Off
- * first and then LSE On or LSE Bypass.
- * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
- * supported by this macro. User should request a transition to HSE Off
- * first and then HSE On or HSE Bypass.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
-{
- uint32_t tickstart = 0U;
-
- /* Check the parameters */
- assert_param(RCC_OscInitStruct != NULL);
- assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
-
- /*------------------------------- HSE Configuration ------------------------*/
- if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
- {
- /* Check the parameters */
- assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
-
- /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
- if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE)
- || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE)))
- {
- if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
- {
- return HAL_ERROR;
- }
- }
- else
- {
- /* Set the new HSE configuration ---------------------------------------*/
- __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
-
-
- /* Check the HSE State */
- if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
- {
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Wait till HSE is ready */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
- {
- if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
- else
- {
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Wait till HSE is disabled */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
- {
- if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
- }
- }
- /*----------------------------- HSI Configuration --------------------------*/
- if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
- {
- /* Check the parameters */
- assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
- assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
-
- /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
- if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI)
- || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI_DIV2)))
- {
- /* When HSI is used as system clock it will not disabled */
- if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON))
- {
- return HAL_ERROR;
- }
- /* Otherwise, just the calibration is allowed */
- else
- {
- /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
- __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
- }
- }
- else
- {
- /* Check the HSI State */
- if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
- {
- /* Enable the Internal High Speed oscillator (HSI). */
- __HAL_RCC_HSI_ENABLE();
-
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Wait till HSI is ready */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
- {
- if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
- __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
- }
- else
- {
- /* Disable the Internal High Speed oscillator (HSI). */
- __HAL_RCC_HSI_DISABLE();
-
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Wait till HSI is disabled */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET)
- {
- if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
- }
- }
- /*------------------------------ LSI Configuration -------------------------*/
- if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
- {
- /* Check the parameters */
- assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
-
- /* Check the LSI State */
- if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
- {
- /* Enable the Internal Low Speed oscillator (LSI). */
- __HAL_RCC_LSI_ENABLE();
-
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Wait till LSI is ready */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)
- {
- if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- /* To have a fully stabilized clock in the specified range, a software delay of 1ms
- should be added.*/
- RCC_Delay(1);
- }
- else
- {
- /* Disable the Internal Low Speed oscillator (LSI). */
- __HAL_RCC_LSI_DISABLE();
-
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Wait till LSI is disabled */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)
- {
- if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
- }
- /*------------------------------ LSE Configuration -------------------------*/
- if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
- {
- FlagStatus pwrclkchanged = RESET;
-
- /* Check the parameters */
- assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
-
- /* Update LSE configuration in Backup Domain control register */
- /* Requires to enable write access to Backup Domain of necessary */
- if(__HAL_RCC_PWR_IS_CLK_DISABLED())
- {
- __HAL_RCC_PWR_CLK_ENABLE();
- pwrclkchanged = SET;
- }
-
- if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
- {
- /* Enable write access to Backup domain */
- SET_BIT(PWR->CR, PWR_CR_DBP);
-
- /* Wait for Backup domain Write protection disable */
- tickstart = HAL_GetTick();
-
- while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
- {
- if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
-
- /* Set the new LSE configuration -----------------------------------------*/
- __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
- /* Check the LSE State */
- if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
- {
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Wait till LSE is ready */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
- {
- if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
- else
- {
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Wait till LSE is disabled */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
- {
- if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
-
- /* Require to disable power clock if necessary */
- if(pwrclkchanged == SET)
- {
- __HAL_RCC_PWR_CLK_DISABLE();
- }
- }
-
-#if defined(RCC_CR_PLL2ON)
- /*-------------------------------- PLL2 Configuration -----------------------*/
- /* Check the parameters */
- assert_param(IS_RCC_PLL2(RCC_OscInitStruct->PLL2.PLL2State));
- if ((RCC_OscInitStruct->PLL2.PLL2State) != RCC_PLL2_NONE)
- {
- /* This bit can not be cleared if the PLL2 clock is used indirectly as system
- clock (i.e. it is used as PLL clock entry that is used as system clock). */
- if((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
- (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
- ((READ_BIT(RCC->CFGR2,RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
- {
- return HAL_ERROR;
- }
- else
- {
- if((RCC_OscInitStruct->PLL2.PLL2State) == RCC_PLL2_ON)
- {
- /* Check the parameters */
- assert_param(IS_RCC_PLL2_MUL(RCC_OscInitStruct->PLL2.PLL2MUL));
- assert_param(IS_RCC_HSE_PREDIV2(RCC_OscInitStruct->PLL2.HSEPrediv2Value));
-
- /* Prediv2 can be written only when the PLLI2S is disabled. */
- /* Return an error only if new value is different from the programmed value */
- if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLL3ON) && \
- (__HAL_RCC_HSE_GET_PREDIV2() != RCC_OscInitStruct->PLL2.HSEPrediv2Value))
- {
- return HAL_ERROR;
- }
-
- /* Disable the main PLL2. */
- __HAL_RCC_PLL2_DISABLE();
-
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Wait till PLL2 is disabled */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
- {
- if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Configure the HSE prediv2 factor --------------------------------*/
- __HAL_RCC_HSE_PREDIV2_CONFIG(RCC_OscInitStruct->PLL2.HSEPrediv2Value);
-
- /* Configure the main PLL2 multiplication factors. */
- __HAL_RCC_PLL2_CONFIG(RCC_OscInitStruct->PLL2.PLL2MUL);
-
- /* Enable the main PLL2. */
- __HAL_RCC_PLL2_ENABLE();
-
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Wait till PLL2 is ready */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) == RESET)
- {
- if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
- else
- {
- /* Set PREDIV1 source to HSE */
- CLEAR_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC);
-
- /* Disable the main PLL2. */
- __HAL_RCC_PLL2_DISABLE();
-
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Wait till PLL2 is disabled */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
- {
- if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
- }
- }
-
-#endif /* RCC_CR_PLL2ON */
- /*-------------------------------- PLL Configuration -----------------------*/
- /* Check the parameters */
- assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
- if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
- {
- /* Check if the PLL is used as system clock or not */
- if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
- {
- if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
- {
- /* Check the parameters */
- assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
- assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL));
-
- /* Disable the main PLL. */
- __HAL_RCC_PLL_DISABLE();
-
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Wait till PLL is disabled */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
- {
- if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Configure the HSE prediv factor --------------------------------*/
- /* It can be written only when the PLL is disabled. Not used in PLL source is different than HSE */
- if(RCC_OscInitStruct->PLL.PLLSource == RCC_PLLSOURCE_HSE)
- {
- /* Check the parameter */
- assert_param(IS_RCC_HSE_PREDIV(RCC_OscInitStruct->HSEPredivValue));
-#if defined(RCC_CFGR2_PREDIV1SRC)
- assert_param(IS_RCC_PREDIV1_SOURCE(RCC_OscInitStruct->Prediv1Source));
-
- /* Set PREDIV1 source */
- SET_BIT(RCC->CFGR2, RCC_OscInitStruct->Prediv1Source);
-#endif /* RCC_CFGR2_PREDIV1SRC */
-
- /* Set PREDIV1 Value */
- __HAL_RCC_HSE_PREDIV_CONFIG(RCC_OscInitStruct->HSEPredivValue);
- }
-
- /* Configure the main PLL clock source and multiplication factors. */
- __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
- RCC_OscInitStruct->PLL.PLLMUL);
- /* Enable the main PLL. */
- __HAL_RCC_PLL_ENABLE();
-
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Wait till PLL is ready */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
- {
- if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
- else
- {
- /* Disable the main PLL. */
- __HAL_RCC_PLL_DISABLE();
-
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Wait till PLL is disabled */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
- {
- if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
- }
- else
- {
- return HAL_ERROR;
- }
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the CPU, AHB and APB buses clocks according to the specified
- * parameters in the RCC_ClkInitStruct.
- * @param RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that
- * contains the configuration information for the RCC peripheral.
- * @param FLatency FLASH Latency
- * The value of this parameter depend on device used within the same series
- * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
- * and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function
- *
- * @note The HSI is used (enabled by hardware) as system clock source after
- * start-up from Reset, wake-up from STOP and STANDBY mode, or in case
- * of failure of the HSE used directly or indirectly as system clock
- * (if the Clock Security System CSS is enabled).
- *
- * @note A switch from one clock source to another occurs only if the target
- * clock source is ready (clock stable after start-up delay or PLL locked).
- * If a clock source which is not yet ready is selected, the switch will
- * occur when the clock source will be ready.
- * You can use @ref HAL_RCC_GetClockConfig() function to know which clock is
- * currently used as system clock source.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
-{
- uint32_t tickstart = 0U;
-
- /* Check the parameters */
- assert_param(RCC_ClkInitStruct != NULL);
- assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
- assert_param(IS_FLASH_LATENCY(FLatency));
-
- /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
- must be correctly programmed according to the frequency of the CPU clock
- (HCLK) of the device. */
-
-#if defined(FLASH_ACR_LATENCY)
- /* Increasing the number of wait states because of higher CPU frequency */
- if(FLatency > (FLASH->ACR & FLASH_ACR_LATENCY))
- {
- /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
- __HAL_FLASH_SET_LATENCY(FLatency);
-
- /* Check that the new number of wait states is taken into account to access the Flash
- memory by reading the FLASH_ACR register */
- if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
- {
- return HAL_ERROR;
- }
- }
-
-#endif /* FLASH_ACR_LATENCY */
- /*-------------------------- HCLK Configuration --------------------------*/
- if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
- {
- /* Set the highest APBx dividers in order to ensure that we do not go through
- a non-spec phase whatever we decrease or increase HCLK. */
- if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
- {
- MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_HCLK_DIV16);
- }
-
- if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
- {
- MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, (RCC_HCLK_DIV16 << 3));
- }
-
- /* Set the new HCLK clock divider */
- assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
- MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
- }
-
- /*------------------------- SYSCLK Configuration ---------------------------*/
- if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
- {
- assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
-
- /* HSE is selected as System Clock Source */
- if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
- {
- /* Check the HSE ready flag */
- if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
- {
- return HAL_ERROR;
- }
- }
- /* PLL is selected as System Clock Source */
- else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
- {
- /* Check the PLL ready flag */
- if(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
- {
- return HAL_ERROR;
- }
- }
- /* HSI is selected as System Clock Source */
- else
- {
- /* Check the HSI ready flag */
- if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
- {
- return HAL_ERROR;
- }
- }
- __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource);
-
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
- {
- while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSE)
- {
- if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
- else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
- {
- while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
- {
- if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
- else
- {
- while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI)
- {
- if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
- }
-#if defined(FLASH_ACR_LATENCY)
- /* Decreasing the number of wait states because of lower CPU frequency */
- if(FLatency < (FLASH->ACR & FLASH_ACR_LATENCY))
- {
- /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
- __HAL_FLASH_SET_LATENCY(FLatency);
-
- /* Check that the new number of wait states is taken into account to access the Flash
- memory by reading the FLASH_ACR register */
- if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
- {
- return HAL_ERROR;
- }
- }
-#endif /* FLASH_ACR_LATENCY */
-
- /*-------------------------- PCLK1 Configuration ---------------------------*/
- if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
- {
- assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
- MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
- }
-
- /*-------------------------- PCLK2 Configuration ---------------------------*/
- if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
- {
- assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
- MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3));
- }
-
- /* Update the SystemCoreClock global variable */
- SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE)>> RCC_CFGR_HPRE_Pos];
-
- /* Configure the source of time base considering new system clocks settings*/
- HAL_InitTick (TICK_INT_PRIORITY);
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
- * @brief RCC clocks control functions
- *
- @verbatim
- ===============================================================================
- ##### Peripheral Control functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to control the RCC Clocks
- frequencies.
-
- @endverbatim
- * @{
- */
-
-/**
- * @brief Selects the clock source to output on MCO pin.
- * @note MCO pin should be configured in alternate function mode.
- * @param RCC_MCOx specifies the output direction for the clock source.
- * This parameter can be one of the following values:
- * @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8).
- * @param RCC_MCOSource specifies the clock source to output.
- * This parameter can be one of the following values:
- * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected as MCO clock
- * @arg @ref RCC_MCO1SOURCE_SYSCLK System clock selected as MCO clock
- * @arg @ref RCC_MCO1SOURCE_HSI HSI selected as MCO clock
- * @arg @ref RCC_MCO1SOURCE_HSE HSE selected as MCO clock
- @if STM32F105xC
- * @arg @ref RCC_MCO1SOURCE_PLLCLK PLL clock divided by 2 selected as MCO source
- * @arg @ref RCC_MCO1SOURCE_PLL2CLK PLL2 clock selected as MCO source
- * @arg @ref RCC_MCO1SOURCE_PLL3CLK_DIV2 PLL3 clock divided by 2 selected as MCO source
- * @arg @ref RCC_MCO1SOURCE_EXT_HSE XT1 external 3-25 MHz oscillator clock selected as MCO source
- * @arg @ref RCC_MCO1SOURCE_PLL3CLK PLL3 clock selected as MCO source
- @endif
- @if STM32F107xC
- * @arg @ref RCC_MCO1SOURCE_PLLCLK PLL clock divided by 2 selected as MCO source
- * @arg @ref RCC_MCO1SOURCE_PLL2CLK PLL2 clock selected as MCO source
- * @arg @ref RCC_MCO1SOURCE_PLL3CLK_DIV2 PLL3 clock divided by 2 selected as MCO source
- * @arg @ref RCC_MCO1SOURCE_EXT_HSE XT1 external 3-25 MHz oscillator clock selected as MCO source
- * @arg @ref RCC_MCO1SOURCE_PLL3CLK PLL3 clock selected as MCO source
- @endif
- * @param RCC_MCODiv specifies the MCO DIV.
- * This parameter can be one of the following values:
- * @arg @ref RCC_MCODIV_1 no division applied to MCO clock
- * @retval None
- */
-void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
-{
- GPIO_InitTypeDef gpio = {0U};
-
- /* Check the parameters */
- assert_param(IS_RCC_MCO(RCC_MCOx));
- assert_param(IS_RCC_MCODIV(RCC_MCODiv));
- assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
-
- /* Prevent unused argument(s) compilation warning */
- UNUSED(RCC_MCOx);
- UNUSED(RCC_MCODiv);
-
- /* Configure the MCO1 pin in alternate function mode */
- gpio.Mode = GPIO_MODE_AF_PP;
- gpio.Speed = GPIO_SPEED_FREQ_HIGH;
- gpio.Pull = GPIO_NOPULL;
- gpio.Pin = MCO1_PIN;
-
- /* MCO1 Clock Enable */
- MCO1_CLK_ENABLE();
-
- HAL_GPIO_Init(MCO1_GPIO_PORT, &gpio);
-
- /* Configure the MCO clock source */
- __HAL_RCC_MCO1_CONFIG(RCC_MCOSource, RCC_MCODiv);
-}
-
-/**
- * @brief Enables the Clock Security System.
- * @note If a failure is detected on the HSE oscillator clock, this oscillator
- * is automatically disabled and an interrupt is generated to inform the
- * software about the failure (Clock Security System Interrupt, CSSI),
- * allowing the MCU to perform rescue operations. The CSSI is linked to
- * the Cortex-M3 NMI (Non-Maskable Interrupt) exception vector.
- * @retval None
- */
-void HAL_RCC_EnableCSS(void)
-{
- *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)ENABLE;
-}
-
-/**
- * @brief Disables the Clock Security System.
- * @retval None
- */
-void HAL_RCC_DisableCSS(void)
-{
- *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)DISABLE;
-}
-
-/**
- * @brief Returns the SYSCLK frequency
- * @note The system frequency computed by this function is not the real
- * frequency in the chip. It is calculated based on the predefined
- * constant and the selected clock source:
- * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
- * @note If SYSCLK source is HSE, function returns a value based on HSE_VALUE
- * divided by PREDIV factor(**)
- * @note If SYSCLK source is PLL, function returns a value based on HSE_VALUE
- * divided by PREDIV factor(**) or HSI_VALUE(*) multiplied by the PLL factor.
- * @note (*) HSI_VALUE is a constant defined in stm32f1xx_hal_conf.h file (default value
- * 8 MHz) but the real value may vary depending on the variations
- * in voltage and temperature.
- * @note (**) HSE_VALUE is a constant defined in stm32f1xx_hal_conf.h file (default value
- * 8 MHz), user has to ensure that HSE_VALUE is same as the real
- * frequency of the crystal used. Otherwise, this function may
- * have wrong result.
- *
- * @note The result of this function could be not correct when using fractional
- * value for HSE crystal.
- *
- * @note This function can be used by the user application to compute the
- * baud-rate for the communication peripherals or configure other parameters.
- *
- * @note Each time SYSCLK changes, this function must be called to update the
- * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
- *
- * @retval SYSCLK frequency
- */
-uint32_t HAL_RCC_GetSysClockFreq(void)
-{
-#if defined(RCC_CFGR2_PREDIV1SRC)
- const uint8_t aPLLMULFactorTable[14] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 13};
- const uint8_t aPredivFactorTable[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
-#else
- const uint8_t aPLLMULFactorTable[16] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16};
-#if defined(RCC_CFGR2_PREDIV1)
- const uint8_t aPredivFactorTable[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
-#else
- const uint8_t aPredivFactorTable[2] = {1, 2};
-#endif /*RCC_CFGR2_PREDIV1*/
-
-#endif
- uint32_t tmpreg = 0U, prediv = 0U, pllclk = 0U, pllmul = 0U;
- uint32_t sysclockfreq = 0U;
-#if defined(RCC_CFGR2_PREDIV1SRC)
- uint32_t prediv2 = 0U, pll2mul = 0U;
-#endif /*RCC_CFGR2_PREDIV1SRC*/
-
- tmpreg = RCC->CFGR;
-
- /* Get SYSCLK source -------------------------------------------------------*/
- switch (tmpreg & RCC_CFGR_SWS)
- {
- case RCC_SYSCLKSOURCE_STATUS_HSE: /* HSE used as system clock */
- {
- sysclockfreq = HSE_VALUE;
- break;
- }
- case RCC_SYSCLKSOURCE_STATUS_PLLCLK: /* PLL used as system clock */
- {
- pllmul = aPLLMULFactorTable[(uint32_t)(tmpreg & RCC_CFGR_PLLMULL) >> RCC_CFGR_PLLMULL_Pos];
- if ((tmpreg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
- {
-#if defined(RCC_CFGR2_PREDIV1)
- prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV1) >> RCC_CFGR2_PREDIV1_Pos];
-#else
- prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR & RCC_CFGR_PLLXTPRE) >> RCC_CFGR_PLLXTPRE_Pos];
-#endif /*RCC_CFGR2_PREDIV1*/
-#if defined(RCC_CFGR2_PREDIV1SRC)
-
- if(HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC))
- {
- /* PLL2 selected as Prediv1 source */
- /* PLLCLK = PLL2CLK / PREDIV1 * PLLMUL with PLL2CLK = HSE/PREDIV2 * PLL2MUL */
- prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
- pll2mul = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> RCC_CFGR2_PLL2MUL_Pos) + 2;
- pllclk = (uint32_t)(((uint64_t)HSE_VALUE * (uint64_t)pll2mul * (uint64_t)pllmul) / ((uint64_t)prediv2 * (uint64_t)prediv));
- }
- else
- {
- /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
- pllclk = (uint32_t)((HSE_VALUE * pllmul) / prediv);
- }
-
- /* If PLLMUL was set to 13 means that it was to cover the case PLLMUL 6.5 (avoid using float) */
- /* In this case need to divide pllclk by 2 */
- if (pllmul == aPLLMULFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> RCC_CFGR_PLLMULL_Pos])
- {
- pllclk = pllclk / 2;
- }
-#else
- /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
- pllclk = (uint32_t)((HSE_VALUE * pllmul) / prediv);
-#endif /*RCC_CFGR2_PREDIV1SRC*/
- }
- else
- {
- /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */
- pllclk = (uint32_t)((HSI_VALUE >> 1) * pllmul);
- }
- sysclockfreq = pllclk;
- break;
- }
- case RCC_SYSCLKSOURCE_STATUS_HSI: /* HSI used as system clock source */
- default: /* HSI used as system clock */
- {
- sysclockfreq = HSI_VALUE;
- break;
- }
- }
- return sysclockfreq;
-}
-
-/**
- * @brief Returns the HCLK frequency
- * @note Each time HCLK changes, this function must be called to update the
- * right HCLK value. Otherwise, any configuration based on this function will be incorrect.
- *
- * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
- * and updated within this function
- * @retval HCLK frequency
- */
-uint32_t HAL_RCC_GetHCLKFreq(void)
-{
- return SystemCoreClock;
-}
-
-/**
- * @brief Returns the PCLK1 frequency
- * @note Each time PCLK1 changes, this function must be called to update the
- * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
- * @retval PCLK1 frequency
- */
-uint32_t HAL_RCC_GetPCLK1Freq(void)
-{
- /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
- return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos]);
-}
-
-/**
- * @brief Returns the PCLK2 frequency
- * @note Each time PCLK2 changes, this function must be called to update the
- * right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
- * @retval PCLK2 frequency
- */
-uint32_t HAL_RCC_GetPCLK2Freq(void)
-{
- /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
- return (HAL_RCC_GetHCLKFreq()>> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos]);
-}
-
-/**
- * @brief Configures the RCC_OscInitStruct according to the internal
- * RCC configuration registers.
- * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
- * will be configured.
- * @retval None
- */
-void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
-{
- /* Check the parameters */
- assert_param(RCC_OscInitStruct != NULL);
-
- /* Set all possible values for the Oscillator type parameter ---------------*/
- RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI \
- | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
-
-#if defined(RCC_CFGR2_PREDIV1SRC)
- /* Get the Prediv1 source --------------------------------------------------*/
- RCC_OscInitStruct->Prediv1Source = READ_BIT(RCC->CFGR2,RCC_CFGR2_PREDIV1SRC);
-#endif /* RCC_CFGR2_PREDIV1SRC */
-
- /* Get the HSE configuration -----------------------------------------------*/
- if((RCC->CR &RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
- {
- RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
- }
- else if((RCC->CR &RCC_CR_HSEON) == RCC_CR_HSEON)
- {
- RCC_OscInitStruct->HSEState = RCC_HSE_ON;
- }
- else
- {
- RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
- }
- RCC_OscInitStruct->HSEPredivValue = __HAL_RCC_HSE_GET_PREDIV();
-
- /* Get the HSI configuration -----------------------------------------------*/
- if((RCC->CR &RCC_CR_HSION) == RCC_CR_HSION)
- {
- RCC_OscInitStruct->HSIState = RCC_HSI_ON;
- }
- else
- {
- RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
- }
-
- RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR & RCC_CR_HSITRIM) >> RCC_CR_HSITRIM_Pos);
-
- /* Get the LSE configuration -----------------------------------------------*/
- if((RCC->BDCR &RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
- {
- RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
- }
- else if((RCC->BDCR &RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
- {
- RCC_OscInitStruct->LSEState = RCC_LSE_ON;
- }
- else
- {
- RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
- }
-
- /* Get the LSI configuration -----------------------------------------------*/
- if((RCC->CSR &RCC_CSR_LSION) == RCC_CSR_LSION)
- {
- RCC_OscInitStruct->LSIState = RCC_LSI_ON;
- }
- else
- {
- RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
- }
-
-
- /* Get the PLL configuration -----------------------------------------------*/
- if((RCC->CR &RCC_CR_PLLON) == RCC_CR_PLLON)
- {
- RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
- }
- else
- {
- RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
- }
- RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLSRC);
- RCC_OscInitStruct->PLL.PLLMUL = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLMULL);
-#if defined(RCC_CR_PLL2ON)
- /* Get the PLL2 configuration -----------------------------------------------*/
- if((RCC->CR &RCC_CR_PLL2ON) == RCC_CR_PLL2ON)
- {
- RCC_OscInitStruct->PLL2.PLL2State = RCC_PLL2_ON;
- }
- else
- {
- RCC_OscInitStruct->PLL2.PLL2State = RCC_PLL2_OFF;
- }
- RCC_OscInitStruct->PLL2.HSEPrediv2Value = __HAL_RCC_HSE_GET_PREDIV2();
- RCC_OscInitStruct->PLL2.PLL2MUL = (uint32_t)(RCC->CFGR2 & RCC_CFGR2_PLL2MUL);
-#endif /* RCC_CR_PLL2ON */
-}
-
-/**
- * @brief Get the RCC_ClkInitStruct according to the internal
- * RCC configuration registers.
- * @param RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that
- * contains the current clock configuration.
- * @param pFLatency Pointer on the Flash Latency.
- * @retval None
- */
-void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency)
-{
- /* Check the parameters */
- assert_param(RCC_ClkInitStruct != NULL);
- assert_param(pFLatency != NULL);
-
- /* Set all possible values for the Clock type parameter --------------------*/
- RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
-
- /* Get the SYSCLK configuration --------------------------------------------*/
- RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW);
-
- /* Get the HCLK configuration ----------------------------------------------*/
- RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE);
-
- /* Get the APB1 configuration ----------------------------------------------*/
- RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE1);
-
- /* Get the APB2 configuration ----------------------------------------------*/
- RCC_ClkInitStruct->APB2CLKDivider = (uint32_t)((RCC->CFGR & RCC_CFGR_PPRE2) >> 3);
-
-#if defined(FLASH_ACR_LATENCY)
- /* Get the Flash Wait State (Latency) configuration ------------------------*/
- *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
-#else
- /* For VALUE lines devices, only LATENCY_0 can be set*/
- *pFLatency = (uint32_t)FLASH_LATENCY_0;
-#endif
-}
-
-/**
- * @brief This function handles the RCC CSS interrupt request.
- * @note This API should be called under the NMI_Handler().
- * @retval None
- */
-void HAL_RCC_NMI_IRQHandler(void)
-{
- /* Check RCC CSSF flag */
- if(__HAL_RCC_GET_IT(RCC_IT_CSS))
- {
- /* RCC Clock Security System interrupt user callback */
- HAL_RCC_CSSCallback();
-
- /* Clear RCC CSS pending bit */
- __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
- }
-}
-
-/**
- * @brief This function provides delay (in milliseconds) based on CPU cycles method.
- * @param mdelay: specifies the delay time length, in milliseconds.
- * @retval None
- */
-static void RCC_Delay(uint32_t mdelay)
-{
- __IO uint32_t Delay = mdelay * (SystemCoreClock / 8U / 1000U);
- do
- {
- __NOP();
- }
- while (Delay --);
-}
-
-/**
- * @brief RCC Clock Security System interrupt callback
- * @retval none
- */
-__weak void HAL_RCC_CSSCallback(void)
-{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_RCC_CSSCallback could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* HAL_RCC_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c
deleted file mode 100644
index 65db17b..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c
+++ /dev/null
@@ -1,879 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_rcc_ex.c
- * @author MCD Application Team
- * @brief Extended RCC HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities RCC extension peripheral:
- * + Extended Peripheral Control functions
- *
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#ifdef HAL_RCC_MODULE_ENABLED
-
-/** @defgroup RCCEx RCCEx
- * @brief RCC Extension HAL module driver.
- * @{
- */
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @defgroup RCCEx_Private_Constants RCCEx Private Constants
- * @{
- */
-/**
- * @}
- */
-
-/* Private macro -------------------------------------------------------------*/
-/** @defgroup RCCEx_Private_Macros RCCEx Private Macros
- * @{
- */
-/**
- * @}
- */
-
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
-
-/** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
- * @{
- */
-
-/** @defgroup RCCEx_Exported_Functions_Group1 Peripheral Control functions
- * @brief Extended Peripheral Control functions
- *
-@verbatim
- ===============================================================================
- ##### Extended Peripheral Control functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to control the RCC Clocks
- frequencies.
- [..]
- (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
- select the RTC clock source; in this case the Backup domain will be reset in
- order to modify the RTC Clock source, as consequence RTC registers (including
- the backup registers) are set to their reset values.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the
- * RCC_PeriphCLKInitTypeDef.
- * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
- * contains the configuration information for the Extended Peripherals clocks(RTC clock).
- *
- * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
- * the RTC clock source; in this case the Backup domain will be reset in
- * order to modify the RTC Clock source, as consequence RTC registers (including
- * the backup registers) are set to their reset values.
- *
- * @note In case of STM32F105xC or STM32F107xC devices, PLLI2S will be enabled if requested on
- * one of 2 I2S interfaces. When PLLI2S is enabled, you need to call HAL_RCCEx_DisablePLLI2S to
- * manually disable it.
- *
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
-{
- uint32_t tickstart = 0U, temp_reg = 0U;
-#if defined(STM32F105xC) || defined(STM32F107xC)
- uint32_t pllactive = 0U;
-#endif /* STM32F105xC || STM32F107xC */
-
- /* Check the parameters */
- assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
-
- /*------------------------------- RTC/LCD Configuration ------------------------*/
- if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC))
- {
- /* check for RTC Parameters used to output RTCCLK */
- assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
-
- FlagStatus pwrclkchanged = RESET;
-
- /* As soon as function is called to change RTC clock source, activation of the
- power domain is done. */
- /* Requires to enable write access to Backup Domain of necessary */
- if(__HAL_RCC_PWR_IS_CLK_DISABLED())
- {
- __HAL_RCC_PWR_CLK_ENABLE();
- pwrclkchanged = SET;
- }
-
- if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
- {
- /* Enable write access to Backup domain */
- SET_BIT(PWR->CR, PWR_CR_DBP);
-
- /* Wait for Backup domain Write protection disable */
- tickstart = HAL_GetTick();
-
- while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
- {
- if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
-
- /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
- temp_reg = (RCC->BDCR & RCC_BDCR_RTCSEL);
- if((temp_reg != 0x00000000U) && (temp_reg != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
- {
- /* Store the content of BDCR register before the reset of Backup Domain */
- temp_reg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
- /* RTC Clock selection can be changed only if the Backup Domain is reset */
- __HAL_RCC_BACKUPRESET_FORCE();
- __HAL_RCC_BACKUPRESET_RELEASE();
- /* Restore the Content of BDCR register */
- RCC->BDCR = temp_reg;
-
- /* Wait for LSERDY if LSE was enabled */
- if (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSEON))
- {
- /* Get Start Tick */
- tickstart = HAL_GetTick();
-
- /* Wait till LSE is ready */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
- {
- if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
- }
- __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
-
- /* Require to disable power clock if necessary */
- if(pwrclkchanged == SET)
- {
- __HAL_RCC_PWR_CLK_DISABLE();
- }
- }
-
- /*------------------------------ ADC clock Configuration ------------------*/
- if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
- {
- /* Check the parameters */
- assert_param(IS_RCC_ADCPLLCLK_DIV(PeriphClkInit->AdcClockSelection));
-
- /* Configure the ADC clock source */
- __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
- }
-
-#if defined(STM32F105xC) || defined(STM32F107xC)
- /*------------------------------ I2S2 Configuration ------------------------*/
- if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S2) == RCC_PERIPHCLK_I2S2)
- {
- /* Check the parameters */
- assert_param(IS_RCC_I2S2CLKSOURCE(PeriphClkInit->I2s2ClockSelection));
-
- /* Configure the I2S2 clock source */
- __HAL_RCC_I2S2_CONFIG(PeriphClkInit->I2s2ClockSelection);
- }
-
- /*------------------------------ I2S3 Configuration ------------------------*/
- if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S3) == RCC_PERIPHCLK_I2S3)
- {
- /* Check the parameters */
- assert_param(IS_RCC_I2S3CLKSOURCE(PeriphClkInit->I2s3ClockSelection));
-
- /* Configure the I2S3 clock source */
- __HAL_RCC_I2S3_CONFIG(PeriphClkInit->I2s3ClockSelection);
- }
-
- /*------------------------------ PLL I2S Configuration ----------------------*/
- /* Check that PLLI2S need to be enabled */
- if (HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_I2S2SRC) || HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
- {
- /* Update flag to indicate that PLL I2S should be active */
- pllactive = 1;
- }
-
- /* Check if PLL I2S need to be enabled */
- if (pllactive == 1)
- {
- /* Enable PLL I2S only if not active */
- if (HAL_IS_BIT_CLR(RCC->CR, RCC_CR_PLL3ON))
- {
- /* Check the parameters */
- assert_param(IS_RCC_PLLI2S_MUL(PeriphClkInit->PLLI2S.PLLI2SMUL));
- assert_param(IS_RCC_HSE_PREDIV2(PeriphClkInit->PLLI2S.HSEPrediv2Value));
-
- /* Prediv2 can be written only when the PLL2 is disabled. */
- /* Return an error only if new value is different from the programmed value */
- if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLL2ON) && \
- (__HAL_RCC_HSE_GET_PREDIV2() != PeriphClkInit->PLLI2S.HSEPrediv2Value))
- {
- return HAL_ERROR;
- }
-
- /* Configure the HSE prediv2 factor --------------------------------*/
- __HAL_RCC_HSE_PREDIV2_CONFIG(PeriphClkInit->PLLI2S.HSEPrediv2Value);
-
- /* Configure the main PLLI2S multiplication factors. */
- __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SMUL);
-
- /* Enable the main PLLI2S. */
- __HAL_RCC_PLLI2S_ENABLE();
-
- /* Get Start Tick*/
- tickstart = HAL_GetTick();
-
- /* Wait till PLLI2S is ready */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
- {
- if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
- else
- {
- /* Return an error only if user wants to change the PLLI2SMUL whereas PLLI2S is active */
- if (READ_BIT(RCC->CFGR2, RCC_CFGR2_PLL3MUL) != PeriphClkInit->PLLI2S.PLLI2SMUL)
- {
- return HAL_ERROR;
- }
- }
- }
-#endif /* STM32F105xC || STM32F107xC */
-
-#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
- || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
- || defined(STM32F105xC) || defined(STM32F107xC)
- /*------------------------------ USB clock Configuration ------------------*/
- if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB)
- {
- /* Check the parameters */
- assert_param(IS_RCC_USBPLLCLK_DIV(PeriphClkInit->UsbClockSelection));
-
- /* Configure the USB clock source */
- __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
- }
-#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
-
- return HAL_OK;
-}
-
-/**
- * @brief Get the PeriphClkInit according to the internal
- * RCC configuration registers.
- * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
- * returns the configuration information for the Extended Peripherals clocks(RTC, I2S, ADC clocks).
- * @retval None
- */
-void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
-{
- uint32_t srcclk = 0U;
-
- /* Set all possible values for the extended clock type parameter------------*/
- PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_RTC;
-
- /* Get the RTC configuration -----------------------------------------------*/
- srcclk = __HAL_RCC_GET_RTC_SOURCE();
- /* Source clock is LSE or LSI*/
- PeriphClkInit->RTCClockSelection = srcclk;
-
- /* Get the ADC clock configuration -----------------------------------------*/
- PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_ADC;
- PeriphClkInit->AdcClockSelection = __HAL_RCC_GET_ADC_SOURCE();
-
-#if defined(STM32F105xC) || defined(STM32F107xC)
- /* Get the I2S2 clock configuration -----------------------------------------*/
- PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S2;
- PeriphClkInit->I2s2ClockSelection = __HAL_RCC_GET_I2S2_SOURCE();
-
- /* Get the I2S3 clock configuration -----------------------------------------*/
- PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S3;
- PeriphClkInit->I2s3ClockSelection = __HAL_RCC_GET_I2S3_SOURCE();
-
-#endif /* STM32F105xC || STM32F107xC */
-
-#if defined(STM32F103xE) || defined(STM32F103xG)
- /* Get the I2S2 clock configuration -----------------------------------------*/
- PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S2;
- PeriphClkInit->I2s2ClockSelection = RCC_I2S2CLKSOURCE_SYSCLK;
-
- /* Get the I2S3 clock configuration -----------------------------------------*/
- PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S3;
- PeriphClkInit->I2s3ClockSelection = RCC_I2S3CLKSOURCE_SYSCLK;
-
-#endif /* STM32F103xE || STM32F103xG */
-
-#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
- || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
- || defined(STM32F105xC) || defined(STM32F107xC)
- /* Get the USB clock configuration -----------------------------------------*/
- PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
- PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
-#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
-}
-
-/**
- * @brief Returns the peripheral clock frequency
- * @note Returns 0 if peripheral clock is unknown
- * @param PeriphClk Peripheral clock identifier
- * This parameter can be one of the following values:
- * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock
- * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock
- @if STM32F103xE
- * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
- * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
- * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
- @endif
- @if STM32F103xG
- * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
- * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
- * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
- * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
- @endif
- @if STM32F105xC
- * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
- * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
- * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
- * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
- * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
- * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
- * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
- * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
- @endif
- @if STM32F107xC
- * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
- * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
- * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
- * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
- * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
- * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
- * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
- * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
- @endif
- @if STM32F102xx
- * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
- @endif
- @if STM32F103xx
- * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
- @endif
- * @retval Frequency in Hz (0: means that no available frequency for the peripheral)
- */
-uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
-{
-#if defined(STM32F105xC) || defined(STM32F107xC)
- const uint8_t aPLLMULFactorTable[14] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 13};
- const uint8_t aPredivFactorTable[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
-
- uint32_t prediv1 = 0U, pllclk = 0U, pllmul = 0U;
- uint32_t pll2mul = 0U, pll3mul = 0U, prediv2 = 0U;
-#endif /* STM32F105xC || STM32F107xC */
-#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6) || \
- defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)
- const uint8_t aPLLMULFactorTable[16] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16};
- const uint8_t aPredivFactorTable[2] = {1, 2};
-
- uint32_t prediv1 = 0U, pllclk = 0U, pllmul = 0U;
-#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG */
- uint32_t temp_reg = 0U, frequency = 0U;
-
- /* Check the parameters */
- assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
-
- switch (PeriphClk)
- {
-#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
- || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
- || defined(STM32F105xC) || defined(STM32F107xC)
- case RCC_PERIPHCLK_USB:
- {
- /* Get RCC configuration ------------------------------------------------------*/
- temp_reg = RCC->CFGR;
-
- /* Check if PLL is enabled */
- if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLLON))
- {
- pllmul = aPLLMULFactorTable[(uint32_t)(temp_reg & RCC_CFGR_PLLMULL) >> RCC_CFGR_PLLMULL_Pos];
- if ((temp_reg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
- {
-#if defined(STM32F105xC) || defined(STM32F107xC) || defined(STM32F100xB)\
- || defined(STM32F100xE)
- prediv1 = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV1) >> RCC_CFGR2_PREDIV1_Pos];
-#else
- prediv1 = aPredivFactorTable[(uint32_t)(RCC->CFGR & RCC_CFGR_PLLXTPRE) >> RCC_CFGR_PLLXTPRE_Pos];
-#endif /* STM32F105xC || STM32F107xC || STM32F100xB || STM32F100xE */
-
-#if defined(STM32F105xC) || defined(STM32F107xC)
- if(HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC))
- {
- /* PLL2 selected as Prediv1 source */
- /* PLLCLK = PLL2CLK / PREDIV1 * PLLMUL with PLL2CLK = HSE/PREDIV2 * PLL2MUL */
- prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
- pll2mul = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> RCC_CFGR2_PLL2MUL_Pos) + 2;
- pllclk = (uint32_t)((((HSE_VALUE / prediv2) * pll2mul) / prediv1) * pllmul);
- }
- else
- {
- /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
- pllclk = (uint32_t)((HSE_VALUE / prediv1) * pllmul);
- }
-
- /* If PLLMUL was set to 13 means that it was to cover the case PLLMUL 6.5 (avoid using float) */
- /* In this case need to divide pllclk by 2 */
- if (pllmul == aPLLMULFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> RCC_CFGR_PLLMULL_Pos])
- {
- pllclk = pllclk / 2;
- }
-#else
- if ((temp_reg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
- {
- /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
- pllclk = (uint32_t)((HSE_VALUE / prediv1) * pllmul);
- }
-#endif /* STM32F105xC || STM32F107xC */
- }
- else
- {
- /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */
- pllclk = (uint32_t)((HSI_VALUE >> 1) * pllmul);
- }
-
- /* Calcul of the USB frequency*/
-#if defined(STM32F105xC) || defined(STM32F107xC)
- /* USBCLK = PLLVCO = (2 x PLLCLK) / USB prescaler */
- if (__HAL_RCC_GET_USB_SOURCE() == RCC_USBCLKSOURCE_PLL_DIV2)
- {
- /* Prescaler of 2 selected for USB */
- frequency = pllclk;
- }
- else
- {
- /* Prescaler of 3 selected for USB */
- frequency = (2 * pllclk) / 3;
- }
-#else
- /* USBCLK = PLLCLK / USB prescaler */
- if (__HAL_RCC_GET_USB_SOURCE() == RCC_USBCLKSOURCE_PLL)
- {
- /* No prescaler selected for USB */
- frequency = pllclk;
- }
- else
- {
- /* Prescaler of 1.5 selected for USB */
- frequency = (pllclk * 2) / 3;
- }
-#endif
- }
- break;
- }
-#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
-#if defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
- case RCC_PERIPHCLK_I2S2:
- {
-#if defined(STM32F103xE) || defined(STM32F103xG)
- /* SYSCLK used as source clock for I2S2 */
- frequency = HAL_RCC_GetSysClockFreq();
-#else
- if (__HAL_RCC_GET_I2S2_SOURCE() == RCC_I2S2CLKSOURCE_SYSCLK)
- {
- /* SYSCLK used as source clock for I2S2 */
- frequency = HAL_RCC_GetSysClockFreq();
- }
- else
- {
- /* Check if PLLI2S is enabled */
- if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON))
- {
- /* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */
- prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
- pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 2;
- frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul));
- }
- }
-#endif /* STM32F103xE || STM32F103xG */
- break;
- }
- case RCC_PERIPHCLK_I2S3:
- {
-#if defined(STM32F103xE) || defined(STM32F103xG)
- /* SYSCLK used as source clock for I2S3 */
- frequency = HAL_RCC_GetSysClockFreq();
-#else
- if (__HAL_RCC_GET_I2S3_SOURCE() == RCC_I2S3CLKSOURCE_SYSCLK)
- {
- /* SYSCLK used as source clock for I2S3 */
- frequency = HAL_RCC_GetSysClockFreq();
- }
- else
- {
- /* Check if PLLI2S is enabled */
- if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON))
- {
- /* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */
- prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
- pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 2;
- frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul));
- }
- }
-#endif /* STM32F103xE || STM32F103xG */
- break;
- }
-#endif /* STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
- case RCC_PERIPHCLK_RTC:
- {
- /* Get RCC BDCR configuration ------------------------------------------------------*/
- temp_reg = RCC->BDCR;
-
- /* Check if LSE is ready if RTC clock selection is LSE */
- if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSERDY)))
- {
- frequency = LSE_VALUE;
- }
- /* Check if LSI is ready if RTC clock selection is LSI */
- else if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)))
- {
- frequency = LSI_VALUE;
- }
- else if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_HSE_DIV128) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)))
- {
- frequency = HSE_VALUE / 128U;
- }
- /* Clock not enabled for RTC*/
- else
- {
- frequency = 0U;
- }
- break;
- }
- case RCC_PERIPHCLK_ADC:
- {
- frequency = HAL_RCC_GetPCLK2Freq() / (((__HAL_RCC_GET_ADC_SOURCE() >> RCC_CFGR_ADCPRE_Pos) + 1) * 2);
- break;
- }
- default:
- {
- break;
- }
- }
- return(frequency);
-}
-
-/**
- * @}
- */
-
-#if defined(STM32F105xC) || defined(STM32F107xC)
-/** @defgroup RCCEx_Exported_Functions_Group2 PLLI2S Management function
- * @brief PLLI2S Management functions
- *
-@verbatim
- ===============================================================================
- ##### Extended PLLI2S Management functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to control the PLLI2S
- activation or deactivation
-@endverbatim
- * @{
- */
-
-/**
- * @brief Enable PLLI2S
- * @param PLLI2SInit pointer to an RCC_PLLI2SInitTypeDef structure that
- * contains the configuration information for the PLLI2S
- * @note The PLLI2S configuration not modified if used by I2S2 or I2S3 Interface.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef *PLLI2SInit)
-{
- uint32_t tickstart = 0U;
-
- /* Check that PLL I2S has not been already enabled by I2S2 or I2S3*/
- if (HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S2SRC) && HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
- {
- /* Check the parameters */
- assert_param(IS_RCC_PLLI2S_MUL(PLLI2SInit->PLLI2SMUL));
- assert_param(IS_RCC_HSE_PREDIV2(PLLI2SInit->HSEPrediv2Value));
-
- /* Prediv2 can be written only when the PLL2 is disabled. */
- /* Return an error only if new value is different from the programmed value */
- if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLL2ON) && \
- (__HAL_RCC_HSE_GET_PREDIV2() != PLLI2SInit->HSEPrediv2Value))
- {
- return HAL_ERROR;
- }
-
- /* Disable the main PLLI2S. */
- __HAL_RCC_PLLI2S_DISABLE();
-
- /* Get Start Tick*/
- tickstart = HAL_GetTick();
-
- /* Wait till PLLI2S is ready */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
- {
- if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Configure the HSE prediv2 factor --------------------------------*/
- __HAL_RCC_HSE_PREDIV2_CONFIG(PLLI2SInit->HSEPrediv2Value);
-
-
- /* Configure the main PLLI2S multiplication factors. */
- __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SMUL);
-
- /* Enable the main PLLI2S. */
- __HAL_RCC_PLLI2S_ENABLE();
-
- /* Get Start Tick*/
- tickstart = HAL_GetTick();
-
- /* Wait till PLLI2S is ready */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
- {
- if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
- else
- {
- /* PLLI2S cannot be modified as already used by I2S2 or I2S3 */
- return HAL_ERROR;
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Disable PLLI2S
- * @note PLLI2S is not disabled if used by I2S2 or I2S3 Interface.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RCCEx_DisablePLLI2S(void)
-{
- uint32_t tickstart = 0U;
-
- /* Disable PLL I2S as not requested by I2S2 or I2S3*/
- if (HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S2SRC) && HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
- {
- /* Disable the main PLLI2S. */
- __HAL_RCC_PLLI2S_DISABLE();
-
- /* Get Start Tick*/
- tickstart = HAL_GetTick();
-
- /* Wait till PLLI2S is ready */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
- {
- if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
- else
- {
- /* PLLI2S is currently used by I2S2 or I2S3. Cannot be disabled.*/
- return HAL_ERROR;
- }
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup RCCEx_Exported_Functions_Group3 PLL2 Management function
- * @brief PLL2 Management functions
- *
-@verbatim
- ===============================================================================
- ##### Extended PLL2 Management functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to control the PLL2
- activation or deactivation
-@endverbatim
- * @{
- */
-
-/**
- * @brief Enable PLL2
- * @param PLL2Init pointer to an RCC_PLL2InitTypeDef structure that
- * contains the configuration information for the PLL2
- * @note The PLL2 configuration not modified if used indirectly as system clock.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RCCEx_EnablePLL2(RCC_PLL2InitTypeDef *PLL2Init)
-{
- uint32_t tickstart = 0U;
-
- /* This bit can not be cleared if the PLL2 clock is used indirectly as system
- clock (i.e. it is used as PLL clock entry that is used as system clock). */
- if((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
- (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
- ((READ_BIT(RCC->CFGR2,RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
- {
- return HAL_ERROR;
- }
- else
- {
- /* Check the parameters */
- assert_param(IS_RCC_PLL2_MUL(PLL2Init->PLL2MUL));
- assert_param(IS_RCC_HSE_PREDIV2(PLL2Init->HSEPrediv2Value));
-
- /* Prediv2 can be written only when the PLLI2S is disabled. */
- /* Return an error only if new value is different from the programmed value */
- if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLL3ON) && \
- (__HAL_RCC_HSE_GET_PREDIV2() != PLL2Init->HSEPrediv2Value))
- {
- return HAL_ERROR;
- }
-
- /* Disable the main PLL2. */
- __HAL_RCC_PLL2_DISABLE();
-
- /* Get Start Tick*/
- tickstart = HAL_GetTick();
-
- /* Wait till PLL2 is disabled */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
- {
- if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Configure the HSE prediv2 factor --------------------------------*/
- __HAL_RCC_HSE_PREDIV2_CONFIG(PLL2Init->HSEPrediv2Value);
-
- /* Configure the main PLL2 multiplication factors. */
- __HAL_RCC_PLL2_CONFIG(PLL2Init->PLL2MUL);
-
- /* Enable the main PLL2. */
- __HAL_RCC_PLL2_ENABLE();
-
- /* Get Start Tick*/
- tickstart = HAL_GetTick();
-
- /* Wait till PLL2 is ready */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) == RESET)
- {
- if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Disable PLL2
- * @note PLL2 is not disabled if used indirectly as system clock.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RCCEx_DisablePLL2(void)
-{
- uint32_t tickstart = 0U;
-
- /* This bit can not be cleared if the PLL2 clock is used indirectly as system
- clock (i.e. it is used as PLL clock entry that is used as system clock). */
- if((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
- (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
- ((READ_BIT(RCC->CFGR2,RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
- {
- return HAL_ERROR;
- }
- else
- {
- /* Disable the main PLL2. */
- __HAL_RCC_PLL2_DISABLE();
-
- /* Get Start Tick*/
- tickstart = HAL_GetTick();
-
- /* Wait till PLL2 is disabled */
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
- {
- if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
- }
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-#endif /* STM32F105xC || STM32F107xC */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* HAL_RCC_MODULE_ENABLED */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc.c
deleted file mode 100644
index bf6f9da..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc.c
+++ /dev/null
@@ -1,1718 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_rtc.c
- * @author MCD Application Team
- * @brief RTC HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Real Time Clock (RTC) peripheral:
- * + Initialization and de-initialization functions
- * + RTC Time and Date functions
- * + RTC Alarm functions
- * + Peripheral Control functions
- * + Peripheral State functions
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==================================================================
- [..]
- (+) Enable the RTC domain access (see description in the section above).
- (+) Configure the RTC Prescaler (Asynchronous prescaler to generate RTC 1Hz time base)
- using the HAL_RTC_Init() function.
-
- *** Time and Date configuration ***
- ===================================
- [..]
- (+) To configure the RTC Calendar (Time and Date) use the HAL_RTC_SetTime()
- and HAL_RTC_SetDate() functions.
- (+) To read the RTC Calendar, use the HAL_RTC_GetTime() and HAL_RTC_GetDate() functions.
-
- *** Alarm configuration ***
- ===========================
- [..]
- (+) To configure the RTC Alarm use the HAL_RTC_SetAlarm() function.
- You can also configure the RTC Alarm with interrupt mode using the HAL_RTC_SetAlarm_IT() function.
- (+) To read the RTC Alarm, use the HAL_RTC_GetAlarm() function.
-
- *** Tamper configuration ***
- ============================
- [..]
- (+) Enable the RTC Tamper and configure the Tamper Level using the
- HAL_RTCEx_SetTamper() function. You can configure RTC Tamper with interrupt
- mode using HAL_RTCEx_SetTamper_IT() function.
- (+) The TAMPER1 alternate function can be mapped to PC13
-
- *** Backup Data Registers configuration ***
- ===========================================
- [..]
- (+) To write to the RTC Backup Data registers, use the HAL_RTCEx_BKUPWrite()
- function.
- (+) To read the RTC Backup Data registers, use the HAL_RTCEx_BKUPRead()
- function.
-
- ##### WARNING: Drivers Restrictions #####
- ==================================================================
- [..] RTC version used on STM32F1 families is version V1. All the features supported by V2
- (other families) will be not supported on F1.
- [..] As on V2, main RTC features are managed by HW. But on F1, date feature is completely
- managed by SW.
- [..] Then, there are some restrictions compared to other families:
- (+) Only format 24 hours supported in HAL (format 12 hours not supported)
- (+) Date is saved in SRAM. Then, when MCU is in STOP or STANDBY mode, date will be lost.
- User should implement a way to save date before entering in low power mode (an
- example is provided with firmware package based on backup registers)
- (+) Date is automatically updated each time a HAL_RTC_GetTime or HAL_RTC_GetDate is called.
- (+) Alarm detection is limited to 1 day. It will expire only 1 time (no alarm repetition, need
- to program a new alarm)
-
- ##### Backup Domain Operating Condition #####
- ==============================================================================
- [..] The real-time clock (RTC) and the RTC backup registers can be powered
- from the VBAT voltage when the main VDD supply is powered off.
- To retain the content of the RTC backup registers and supply the RTC
- when VDD is turned off, VBAT pin can be connected to an optional
- standby voltage supplied by a battery or by another source.
-
- [..] To allow the RTC operating even when the main digital supply (VDD) is turned
- off, the VBAT pin powers the following blocks:
- (+) The RTC
- (+) The LSE oscillator
- (+) PC13 I/O
-
- [..] When the backup domain is supplied by VDD (analog switch connected to VDD),
- the following pins are available:
- (+) PC13 can be used as a Tamper pin
-
- [..] When the backup domain is supplied by VBAT (analog switch connected to VBAT
- because VDD is not present), the following pins are available:
- (+) PC13 can be used as the Tamper pin
-
- ##### Backup Domain Reset #####
- ==================================================================
- [..] The backup domain reset sets all RTC registers and the RCC_BDCR register
- to their reset values.
- [..] A backup domain reset is generated when one of the following events occurs:
- (#) Software reset, triggered by setting the BDRST bit in the
- RCC Backup domain control register (RCC_BDCR).
- (#) VDD or VBAT power on, if both supplies have previously been powered off.
- (#) Tamper detection event resets all data backup registers.
-
- ##### Backup Domain Access #####
- ==================================================================
- [..] After reset, the backup domain (RTC registers, RTC backup data
- registers and backup SRAM) is protected against possible unwanted write
- accesses.
- [..] To enable access to the RTC Domain and RTC registers, proceed as follows:
- (+) Call the function HAL_RCCEx_PeriphCLKConfig in using RCC_PERIPHCLK_RTC for
- PeriphClockSelection and select RTCClockSelection (LSE, LSI or HSE)
- (+) Enable the BKP clock in using __HAL_RCC_BKP_CLK_ENABLE()
-
- ##### RTC and low power modes #####
- ==================================================================
- [..] The MCU can be woken up from a low power mode by an RTC alternate
- function.
- [..] The RTC alternate functions are the RTC alarms (Alarm A),
- and RTC tamper event detection.
- These RTC alternate functions can wake up the system from the Stop and
- Standby low power modes.
- [..] The system can also wake up from low power modes without depending
- on an external interrupt (Auto-wakeup mode), by using the RTC alarm.
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup RTC RTC
- * @brief RTC HAL module driver
- * @{
- */
-
-#ifdef HAL_RTC_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @defgroup RTC_Private_Constants RTC Private Constants
- * @{
- */
-#define RTC_ALARM_RESETVALUE_REGISTER (uint16_t)0xFFFF
-#define RTC_ALARM_RESETVALUE 0xFFFFFFFFU
-
-/**
- * @}
- */
-
-/* Private macro -------------------------------------------------------------*/
-/** @defgroup RTC_Private_Macros RTC Private Macros
- * @{
- */
-/**
- * @}
- */
-
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @defgroup RTC_Private_Functions RTC Private Functions
- * @{
- */
-static uint32_t RTC_ReadTimeCounter(RTC_HandleTypeDef* hrtc);
-static HAL_StatusTypeDef RTC_WriteTimeCounter(RTC_HandleTypeDef* hrtc, uint32_t TimeCounter);
-static uint32_t RTC_ReadAlarmCounter(RTC_HandleTypeDef* hrtc);
-static HAL_StatusTypeDef RTC_WriteAlarmCounter(RTC_HandleTypeDef* hrtc, uint32_t AlarmCounter);
-static HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef* hrtc);
-static HAL_StatusTypeDef RTC_ExitInitMode(RTC_HandleTypeDef* hrtc);
-static uint8_t RTC_ByteToBcd2(uint8_t Value);
-static uint8_t RTC_Bcd2ToByte(uint8_t Value);
-static uint8_t RTC_IsLeapYear(uint16_t nYear);
-static void RTC_DateUpdate(RTC_HandleTypeDef* hrtc, uint32_t DayElapsed);
-static uint8_t RTC_WeekDayNum(uint32_t nYear, uint8_t nMonth, uint8_t nDay);
-
-/**
- * @}
- */
-
-/* Private functions ---------------------------------------------------------*/
-/** @defgroup RTC_Exported_Functions RTC Exported Functions
- * @{
- */
-
-/** @defgroup RTC_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
- ===============================================================================
- ##### Initialization and de-initialization functions #####
- ===============================================================================
- [..] This section provides functions allowing to initialize and configure the
- RTC Prescaler (Asynchronous), disable RTC registers Write protection,
- enter and exit the RTC initialization mode,
- RTC registers synchronization check and reference clock detection enable.
- (#) The RTC Prescaler should be programmed to generate the RTC 1Hz time base.
- (#) All RTC registers are Write protected. Writing to the RTC registers
- is enabled by setting the CNF bit in the RTC_CRL register.
- (#) To read the calendar after wakeup from low power modes (Standby or Stop)
- the software must first wait for the RSF bit (Register Synchronized Flag)
- in the RTC_CRL register to be set by hardware.
- The HAL_RTC_WaitForSynchro() function implements the above software
- sequence (RSF clear and RSF check).
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the RTC peripheral
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc)
-{
- uint32_t prescaler = 0U;
- /* Check input parameters */
- if(hrtc == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance));
- assert_param(IS_RTC_CALIB_OUTPUT(hrtc->Init.OutPut));
- assert_param(IS_RTC_ASYNCH_PREDIV(hrtc->Init.AsynchPrediv));
-
- if(hrtc->State == HAL_RTC_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- hrtc->Lock = HAL_UNLOCKED;
-
- /* Initialize RTC MSP */
- HAL_RTC_MspInit(hrtc);
- }
-
- /* Set RTC state */
- hrtc->State = HAL_RTC_STATE_BUSY;
-
- /* Waiting for synchro */
- if(HAL_RTC_WaitForSynchro(hrtc) != HAL_OK)
- {
- /* Set RTC state */
- hrtc->State = HAL_RTC_STATE_ERROR;
-
- return HAL_ERROR;
- }
-
- /* Set Initialization mode */
- if(RTC_EnterInitMode(hrtc) != HAL_OK)
- {
- /* Set RTC state */
- hrtc->State = HAL_RTC_STATE_ERROR;
-
- return HAL_ERROR;
- }
- else
- {
- /* Clear Flags Bits */
- CLEAR_BIT(hrtc->Instance->CRL, (RTC_FLAG_OW | RTC_FLAG_ALRAF | RTC_FLAG_SEC));
-
- if(hrtc->Init.OutPut != RTC_OUTPUTSOURCE_NONE)
- {
- /* Disable the selected Tamper pin */
- CLEAR_BIT(BKP->CR, BKP_CR_TPE);
- }
-
- /* Set the signal which will be routed to RTC Tamper pin*/
- MODIFY_REG(BKP->RTCCR, (BKP_RTCCR_CCO | BKP_RTCCR_ASOE | BKP_RTCCR_ASOS), hrtc->Init.OutPut);
-
- if (hrtc->Init.AsynchPrediv != RTC_AUTO_1_SECOND)
- {
- /* RTC Prescaler provided directly by end-user*/
- prescaler = hrtc->Init.AsynchPrediv;
- }
- else
- {
- /* RTC Prescaler will be automatically calculated to get 1 second timebase */
- /* Get the RTCCLK frequency */
- prescaler = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_RTC);
-
- /* Check that RTC clock is enabled*/
- if (prescaler == 0U)
- {
- /* Should not happen. Frequency is not available*/
- hrtc->State = HAL_RTC_STATE_ERROR;
- return HAL_ERROR;
- }
- else
- {
- /* RTC period = RTCCLK/(RTC_PR + 1) */
- prescaler = prescaler - 1U;
- }
- }
-
- /* Configure the RTC_PRLH / RTC_PRLL */
- MODIFY_REG(hrtc->Instance->PRLH, RTC_PRLH_PRL, (prescaler >> 16U));
- MODIFY_REG(hrtc->Instance->PRLL, RTC_PRLL_PRL, (prescaler & RTC_PRLL_PRL));
-
- /* Wait for synchro */
- if(RTC_ExitInitMode(hrtc) != HAL_OK)
- {
- hrtc->State = HAL_RTC_STATE_ERROR;
-
- return HAL_ERROR;
- }
-
- /* Initialize date to 1st of January 2000 */
- hrtc->DateToUpdate.Year = 0x00U;
- hrtc->DateToUpdate.Month = RTC_MONTH_JANUARY;
- hrtc->DateToUpdate.Date = 0x01U;
-
- /* Set RTC state */
- hrtc->State = HAL_RTC_STATE_READY;
-
- return HAL_OK;
- }
-}
-
-/**
- * @brief DeInitializes the RTC peripheral
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @note This function does not reset the RTC Backup Data registers.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTC_DeInit(RTC_HandleTypeDef *hrtc)
-{
- /* Check input parameters */
- if(hrtc == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance));
-
- /* Set RTC state */
- hrtc->State = HAL_RTC_STATE_BUSY;
-
- /* Set Initialization mode */
- if(RTC_EnterInitMode(hrtc) != HAL_OK)
- {
- /* Set RTC state */
- hrtc->State = HAL_RTC_STATE_ERROR;
-
- /* Release Lock */
- __HAL_UNLOCK(hrtc);
-
- return HAL_ERROR;
- }
- else
- {
- CLEAR_REG(hrtc->Instance->CNTL);
- CLEAR_REG(hrtc->Instance->CNTH);
- WRITE_REG(hrtc->Instance->PRLL, 0x00008000U);
- CLEAR_REG(hrtc->Instance->PRLH);
-
- /* Reset All CRH/CRL bits */
- CLEAR_REG(hrtc->Instance->CRH);
- CLEAR_REG(hrtc->Instance->CRL);
-
- if(RTC_ExitInitMode(hrtc) != HAL_OK)
- {
- hrtc->State = HAL_RTC_STATE_ERROR;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_ERROR;
- }
- }
-
- /* Wait for synchro*/
- HAL_RTC_WaitForSynchro(hrtc);
-
- /* Clear RSF flag */
- CLEAR_BIT(hrtc->Instance->CRL, RTC_FLAG_RSF);
-
- /* De-Initialize RTC MSP */
- HAL_RTC_MspDeInit(hrtc);
-
- hrtc->State = HAL_RTC_STATE_RESET;
-
- /* Release Lock */
- __HAL_UNLOCK(hrtc);
-
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the RTC MSP.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @retval None
- */
-__weak void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hrtc);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_RTC_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief DeInitializes the RTC MSP.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @retval None
- */
-__weak void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hrtc);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_RTC_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup RTC_Exported_Functions_Group2 Time and Date functions
- * @brief RTC Time and Date functions
- *
-@verbatim
- ===============================================================================
- ##### RTC Time and Date functions #####
- ===============================================================================
-
- [..] This section provides functions allowing to configure Time and Date features
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Sets RTC current time.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @param sTime: Pointer to Time structure
- * @param Format: Specifies the format of the entered parameters.
- * This parameter can be one of the following values:
- * @arg RTC_FORMAT_BIN: Binary data format
- * @arg RTC_FORMAT_BCD: BCD data format
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
-{
- uint32_t counter_time = 0U, counter_alarm = 0U;
-
- /* Check input parameters */
- if((hrtc == NULL) || (sTime == NULL))
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_RTC_FORMAT(Format));
-
- /* Process Locked */
- __HAL_LOCK(hrtc);
-
- hrtc->State = HAL_RTC_STATE_BUSY;
-
- if(Format == RTC_FORMAT_BIN)
- {
- assert_param(IS_RTC_HOUR24(sTime->Hours));
- assert_param(IS_RTC_MINUTES(sTime->Minutes));
- assert_param(IS_RTC_SECONDS(sTime->Seconds));
-
- counter_time = (uint32_t)(((uint32_t)sTime->Hours * 3600U) + \
- ((uint32_t)sTime->Minutes * 60U) + \
- ((uint32_t)sTime->Seconds));
- }
- else
- {
- assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sTime->Hours)));
- assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sTime->Minutes)));
- assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sTime->Seconds)));
-
- counter_time = (((uint32_t)(RTC_Bcd2ToByte(sTime->Hours)) * 3600U) + \
- ((uint32_t)(RTC_Bcd2ToByte(sTime->Minutes)) * 60U) + \
- ((uint32_t)(RTC_Bcd2ToByte(sTime->Seconds))));
- }
-
- /* Write time counter in RTC registers */
- if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
- {
- /* Set RTC state */
- hrtc->State = HAL_RTC_STATE_ERROR;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_ERROR;
- }
- else
- {
- /* Clear Second and overflow flags */
- CLEAR_BIT(hrtc->Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW));
-
- /* Read current Alarm counter in RTC registers */
- counter_alarm = RTC_ReadAlarmCounter(hrtc);
-
- /* Set again alarm to match with new time if enabled */
- if (counter_alarm != RTC_ALARM_RESETVALUE)
- {
- if(counter_alarm < counter_time)
- {
- /* Add 1 day to alarm counter*/
- counter_alarm += (uint32_t)(24U * 3600U);
-
- /* Write new Alarm counter in RTC registers */
- if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
- {
- /* Set RTC state */
- hrtc->State = HAL_RTC_STATE_ERROR;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_ERROR;
- }
- }
- }
-
- hrtc->State = HAL_RTC_STATE_READY;
-
- __HAL_UNLOCK(hrtc);
-
- return HAL_OK;
- }
-}
-
-/**
- * @brief Gets RTC current time.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @param sTime: Pointer to Time structure
- * @param Format: Specifies the format of the entered parameters.
- * This parameter can be one of the following values:
- * @arg RTC_FORMAT_BIN: Binary data format
- * @arg RTC_FORMAT_BCD: BCD data format
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
-{
- uint32_t counter_time = 0U, counter_alarm = 0U, days_elapsed = 0U, hours = 0U;
-
- /* Check input parameters */
- if((hrtc == NULL) || (sTime == NULL))
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_RTC_FORMAT(Format));
-
- /* Check if counter overflow occurred */
- if (__HAL_RTC_OVERFLOW_GET_FLAG(hrtc, RTC_FLAG_OW))
- {
- return HAL_ERROR;
- }
-
- /* Read the time counter*/
- counter_time = RTC_ReadTimeCounter(hrtc);
-
- /* Fill the structure fields with the read parameters */
- hours = counter_time / 3600U;
- sTime->Minutes = (uint8_t)((counter_time % 3600U) / 60U);
- sTime->Seconds = (uint8_t)((counter_time % 3600U) % 60U);
-
- if (hours >= 24U)
- {
- /* Get number of days elapsed from last calculation */
- days_elapsed = (hours / 24U);
-
- /* Set Hours in RTC_TimeTypeDef structure*/
- sTime->Hours = (hours % 24U);
-
- /* Read Alarm counter in RTC registers */
- counter_alarm = RTC_ReadAlarmCounter(hrtc);
-
- /* Calculate remaining time to reach alarm (only if set and not yet expired)*/
- if ((counter_alarm != RTC_ALARM_RESETVALUE) && (counter_alarm > counter_time))
- {
- counter_alarm -= counter_time;
- }
- else
- {
- /* In case of counter_alarm < counter_time */
- /* Alarm expiration already occurred but alarm not deactivated */
- counter_alarm = RTC_ALARM_RESETVALUE;
- }
-
- /* Set updated time in decreasing counter by number of days elapsed */
- counter_time -= (days_elapsed * 24U * 3600U);
-
- /* Write time counter in RTC registers */
- if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
- {
- return HAL_ERROR;
- }
-
- /* Set updated alarm to be set */
- if (counter_alarm != RTC_ALARM_RESETVALUE)
- {
- counter_alarm += counter_time;
-
- /* Write time counter in RTC registers */
- if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
- {
- return HAL_ERROR;
- }
- }
- else
- {
- /* Alarm already occurred. Set it to reset values to avoid unexpected expiration */
- if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
- {
- return HAL_ERROR;
- }
- }
-
- /* Update date */
- RTC_DateUpdate(hrtc, days_elapsed);
- }
- else
- {
- sTime->Hours = hours;
- }
-
- /* Check the input parameters format */
- if(Format != RTC_FORMAT_BIN)
- {
- /* Convert the time structure parameters to BCD format */
- sTime->Hours = (uint8_t)RTC_ByteToBcd2(sTime->Hours);
- sTime->Minutes = (uint8_t)RTC_ByteToBcd2(sTime->Minutes);
- sTime->Seconds = (uint8_t)RTC_ByteToBcd2(sTime->Seconds);
- }
-
- return HAL_OK;
-}
-
-
-/**
- * @brief Sets RTC current date.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @param sDate: Pointer to date structure
- * @param Format: specifies the format of the entered parameters.
- * This parameter can be one of the following values:
- * @arg RTC_FORMAT_BIN: Binary data format
- * @arg RTC_FORMAT_BCD: BCD data format
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
-{
- uint32_t counter_time = 0U, counter_alarm = 0U, hours = 0U;
-
- /* Check input parameters */
- if((hrtc == NULL) || (sDate == NULL))
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_RTC_FORMAT(Format));
-
- /* Process Locked */
- __HAL_LOCK(hrtc);
-
- hrtc->State = HAL_RTC_STATE_BUSY;
-
- if(Format == RTC_FORMAT_BIN)
- {
- assert_param(IS_RTC_YEAR(sDate->Year));
- assert_param(IS_RTC_MONTH(sDate->Month));
- assert_param(IS_RTC_DATE(sDate->Date));
-
- /* Change the current date */
- hrtc->DateToUpdate.Year = sDate->Year;
- hrtc->DateToUpdate.Month = sDate->Month;
- hrtc->DateToUpdate.Date = sDate->Date;
- }
- else
- {
- assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(sDate->Year)));
- assert_param(IS_RTC_MONTH(RTC_Bcd2ToByte(sDate->Month)));
- assert_param(IS_RTC_DATE(RTC_Bcd2ToByte(sDate->Date)));
-
- /* Change the current date */
- hrtc->DateToUpdate.Year = RTC_Bcd2ToByte(sDate->Year);
- hrtc->DateToUpdate.Month = RTC_Bcd2ToByte(sDate->Month);
- hrtc->DateToUpdate.Date = RTC_Bcd2ToByte(sDate->Date);
- }
-
- /* WeekDay set by user can be ignored because automatically calculated */
- hrtc->DateToUpdate.WeekDay = RTC_WeekDayNum(hrtc->DateToUpdate.Year, hrtc->DateToUpdate.Month, hrtc->DateToUpdate.Date);
- sDate->WeekDay = hrtc->DateToUpdate.WeekDay;
-
- /* Reset time to be aligned on the same day */
- /* Read the time counter*/
- counter_time = RTC_ReadTimeCounter(hrtc);
-
- /* Fill the structure fields with the read parameters */
- hours = counter_time / 3600U;
- if (hours > 24U)
- {
- /* Set updated time in decreasing counter by number of days elapsed */
- counter_time -= ((hours / 24U) * 24U * 3600U);
- /* Write time counter in RTC registers */
- if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
- {
- /* Set RTC state */
- hrtc->State = HAL_RTC_STATE_ERROR;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_ERROR;
- }
-
- /* Read current Alarm counter in RTC registers */
- counter_alarm = RTC_ReadAlarmCounter(hrtc);
-
- /* Set again alarm to match with new time if enabled */
- if (counter_alarm != RTC_ALARM_RESETVALUE)
- {
- if(counter_alarm < counter_time)
- {
- /* Add 1 day to alarm counter*/
- counter_alarm += (uint32_t)(24U * 3600U);
-
- /* Write new Alarm counter in RTC registers */
- if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
- {
- /* Set RTC state */
- hrtc->State = HAL_RTC_STATE_ERROR;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_ERROR;
- }
- }
- }
-
-
- }
-
- hrtc->State = HAL_RTC_STATE_READY ;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_OK;
-}
-
-/**
- * @brief Gets RTC current date.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @param sDate: Pointer to Date structure
- * @param Format: Specifies the format of the entered parameters.
- * This parameter can be one of the following values:
- * @arg RTC_FORMAT_BIN: Binary data format
- * @arg RTC_FORMAT_BCD: BCD data format
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
-{
- RTC_TimeTypeDef stime = {0U};
-
- /* Check input parameters */
- if((hrtc == NULL) || (sDate == NULL))
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_RTC_FORMAT(Format));
-
- /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
- if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
- {
- return HAL_ERROR;
- }
-
- /* Fill the structure fields with the read parameters */
- sDate->WeekDay = hrtc->DateToUpdate.WeekDay;
- sDate->Year = hrtc->DateToUpdate.Year;
- sDate->Month = hrtc->DateToUpdate.Month;
- sDate->Date = hrtc->DateToUpdate.Date;
-
- /* Check the input parameters format */
- if(Format != RTC_FORMAT_BIN)
- {
- /* Convert the date structure parameters to BCD format */
- sDate->Year = (uint8_t)RTC_ByteToBcd2(sDate->Year);
- sDate->Month = (uint8_t)RTC_ByteToBcd2(sDate->Month);
- sDate->Date = (uint8_t)RTC_ByteToBcd2(sDate->Date);
- }
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup RTC_Exported_Functions_Group3 Alarm functions
- * @brief RTC Alarm functions
- *
-@verbatim
- ===============================================================================
- ##### RTC Alarm functions #####
- ===============================================================================
-
- [..] This section provides functions allowing to configure Alarm feature
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Sets the specified RTC Alarm.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @param sAlarm: Pointer to Alarm structure
- * @param Format: Specifies the format of the entered parameters.
- * This parameter can be one of the following values:
- * @arg RTC_FORMAT_BIN: Binary data format
- * @arg RTC_FORMAT_BCD: BCD data format
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
-{
- uint32_t counter_alarm = 0U, counter_time;
- RTC_TimeTypeDef stime = {0U};
-
- /* Check input parameters */
- if((hrtc == NULL) || (sAlarm == NULL))
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_RTC_FORMAT(Format));
- assert_param(IS_RTC_ALARM(sAlarm->Alarm));
-
- /* Process Locked */
- __HAL_LOCK(hrtc);
-
- hrtc->State = HAL_RTC_STATE_BUSY;
-
- /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
- if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
- {
- return HAL_ERROR;
- }
-
- /* Convert time in seconds */
- counter_time = (uint32_t)(((uint32_t)stime.Hours * 3600U) + \
- ((uint32_t)stime.Minutes * 60U) + \
- ((uint32_t)stime.Seconds));
-
- if(Format == RTC_FORMAT_BIN)
- {
- assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours));
- assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes));
- assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds));
-
- counter_alarm = (uint32_t)(((uint32_t)sAlarm->AlarmTime.Hours * 3600U) + \
- ((uint32_t)sAlarm->AlarmTime.Minutes * 60U) + \
- ((uint32_t)sAlarm->AlarmTime.Seconds));
- }
- else
- {
- assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
- assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)));
- assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
-
- counter_alarm = (((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)) * 3600U) + \
- ((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)) * 60U) + \
- ((uint32_t)RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
- }
-
- /* Check that requested alarm should expire in the same day (otherwise add 1 day) */
- if (counter_alarm < counter_time)
- {
- /* Add 1 day to alarm counter*/
- counter_alarm += (uint32_t)(24U * 3600U);
- }
-
- /* Write Alarm counter in RTC registers */
- if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
- {
- /* Set RTC state */
- hrtc->State = HAL_RTC_STATE_ERROR;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_ERROR;
- }
- else
- {
- hrtc->State = HAL_RTC_STATE_READY;
-
- __HAL_UNLOCK(hrtc);
-
- return HAL_OK;
- }
-}
-
-/**
- * @brief Sets the specified RTC Alarm with Interrupt
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @param sAlarm: Pointer to Alarm structure
- * @param Format: Specifies the format of the entered parameters.
- * This parameter can be one of the following values:
- * @arg RTC_FORMAT_BIN: Binary data format
- * @arg RTC_FORMAT_BCD: BCD data format
- * @note The HAL_RTC_SetTime() must be called before enabling the Alarm feature.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
-{
- uint32_t counter_alarm = 0U, counter_time;
- RTC_TimeTypeDef stime = {0U};
-
- /* Check input parameters */
- if((hrtc == NULL) || (sAlarm == NULL))
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_RTC_FORMAT(Format));
- assert_param(IS_RTC_ALARM(sAlarm->Alarm));
-
- /* Process Locked */
- __HAL_LOCK(hrtc);
-
- hrtc->State = HAL_RTC_STATE_BUSY;
-
- /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
- if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
- {
- return HAL_ERROR;
- }
-
- /* Convert time in seconds */
- counter_time = (uint32_t)(((uint32_t)stime.Hours * 3600U) + \
- ((uint32_t)stime.Minutes * 60U) + \
- ((uint32_t)stime.Seconds));
-
- if(Format == RTC_FORMAT_BIN)
- {
- assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours));
- assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes));
- assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds));
-
- counter_alarm = (uint32_t)(((uint32_t)sAlarm->AlarmTime.Hours * 3600U) + \
- ((uint32_t)sAlarm->AlarmTime.Minutes * 60U) + \
- ((uint32_t)sAlarm->AlarmTime.Seconds));
- }
- else
- {
- assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
- assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)));
- assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
-
- counter_alarm = (((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)) * 3600U) + \
- ((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)) * 60U) + \
- ((uint32_t)RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
- }
-
- /* Check that requested alarm should expire in the same day (otherwise add 1 day) */
- if (counter_alarm < counter_time)
- {
- /* Add 1 day to alarm counter*/
- counter_alarm += (uint32_t)(24U * 3600U);
- }
-
- /* Write alarm counter in RTC registers */
- if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
- {
- /* Set RTC state */
- hrtc->State = HAL_RTC_STATE_ERROR;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_ERROR;
- }
- else
- {
- /* Clear flag alarm A */
- __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
-
- /* Configure the Alarm interrupt */
- __HAL_RTC_ALARM_ENABLE_IT(hrtc,RTC_IT_ALRA);
-
- /* RTC Alarm Interrupt Configuration: EXTI configuration */
- __HAL_RTC_ALARM_EXTI_ENABLE_IT();
-
- __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE();
-
- hrtc->State = HAL_RTC_STATE_READY;
-
- __HAL_UNLOCK(hrtc);
-
- return HAL_OK;
- }
-}
-
-/**
- * @brief Gets the RTC Alarm value and masks.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @param sAlarm: Pointer to Date structure
- * @param Alarm: Specifies the Alarm.
- * This parameter can be one of the following values:
- * @arg RTC_ALARM_A: Alarm
- * @param Format: Specifies the format of the entered parameters.
- * This parameter can be one of the following values:
- * @arg RTC_FORMAT_BIN: Binary data format
- * @arg RTC_FORMAT_BCD: BCD data format
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTC_GetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Alarm, uint32_t Format)
-{
- uint32_t counter_alarm = 0U;
-
- /* Prevent unused argument(s) compilation warning */
- UNUSED(Alarm);
-
- /* Check input parameters */
- if((hrtc == NULL) || (sAlarm == NULL))
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_RTC_FORMAT(Format));
- assert_param(IS_RTC_ALARM(Alarm));
-
- /* Read Alarm counter in RTC registers */
- counter_alarm = RTC_ReadAlarmCounter(hrtc);
-
- /* Fill the structure with the read parameters */
- /* Set hours in a day range (between 0 to 24)*/
- sAlarm->AlarmTime.Hours = (uint32_t)((counter_alarm / 3600U) % 24U);
- sAlarm->AlarmTime.Minutes = (uint32_t)((counter_alarm % 3600U) / 60U);
- sAlarm->AlarmTime.Seconds = (uint32_t)((counter_alarm % 3600U) % 60U);
-
- if(Format != RTC_FORMAT_BIN)
- {
- sAlarm->AlarmTime.Hours = RTC_ByteToBcd2(sAlarm->AlarmTime.Hours);
- sAlarm->AlarmTime.Minutes = RTC_ByteToBcd2(sAlarm->AlarmTime.Minutes);
- sAlarm->AlarmTime.Seconds = RTC_ByteToBcd2(sAlarm->AlarmTime.Seconds);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Deactive the specified RTC Alarm
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @param Alarm: Specifies the Alarm.
- * This parameter can be one of the following values:
- * @arg RTC_ALARM_A: AlarmA
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef *hrtc, uint32_t Alarm)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(Alarm);
-
- /* Check the parameters */
- assert_param(IS_RTC_ALARM(Alarm));
-
- /* Check input parameters */
- if(hrtc == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hrtc);
-
- hrtc->State = HAL_RTC_STATE_BUSY;
-
- /* In case of interrupt mode is used, the interrupt source must disabled */
- __HAL_RTC_ALARM_DISABLE_IT(hrtc, RTC_IT_ALRA);
-
- /* Set Initialization mode */
- if(RTC_EnterInitMode(hrtc) != HAL_OK)
- {
- /* Set RTC state */
- hrtc->State = HAL_RTC_STATE_ERROR;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_ERROR;
- }
- else
- {
- /* Clear flag alarm A */
- __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
-
- /* Set to default values ALRH & ALRL registers */
- WRITE_REG(hrtc->Instance->ALRH, RTC_ALARM_RESETVALUE_REGISTER);
- WRITE_REG(hrtc->Instance->ALRL, RTC_ALARM_RESETVALUE_REGISTER);
-
- /* RTC Alarm Interrupt Configuration: Disable EXTI configuration */
- __HAL_RTC_ALARM_EXTI_DISABLE_IT();
-
- /* Wait for synchro */
- if(RTC_ExitInitMode(hrtc) != HAL_OK)
- {
- hrtc->State = HAL_RTC_STATE_ERROR;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_ERROR;
- }
- }
- hrtc->State = HAL_RTC_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_OK;
-}
-
-/**
- * @brief This function handles Alarm interrupt request.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @retval None
- */
-void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef* hrtc)
-{
- if(__HAL_RTC_ALARM_GET_IT_SOURCE(hrtc, RTC_IT_ALRA))
- {
- /* Get the status of the Interrupt */
- if(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) != (uint32_t)RESET)
- {
- /* AlarmA callback */
- HAL_RTC_AlarmAEventCallback(hrtc);
-
- /* Clear the Alarm interrupt pending bit */
- __HAL_RTC_ALARM_CLEAR_FLAG(hrtc,RTC_FLAG_ALRAF);
- }
- }
-
- /* Clear the EXTI's line Flag for RTC Alarm */
- __HAL_RTC_ALARM_EXTI_CLEAR_FLAG();
-
- /* Change RTC state */
- hrtc->State = HAL_RTC_STATE_READY;
-}
-
-/**
- * @brief Alarm A callback.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @retval None
- */
-__weak void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hrtc);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_RTC_AlarmAEventCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief This function handles AlarmA Polling request.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @param Timeout: Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout)
-{
- uint32_t tickstart = HAL_GetTick();
-
- /* Check input parameters */
- if(hrtc == NULL)
- {
- return HAL_ERROR;
- }
-
- while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) == RESET)
- {
- if(Timeout != HAL_MAX_DELAY)
- {
- if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
- {
- hrtc->State = HAL_RTC_STATE_TIMEOUT;
- return HAL_TIMEOUT;
- }
- }
- }
-
- /* Clear the Alarm interrupt pending bit */
- __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
-
- /* Change RTC state */
- hrtc->State = HAL_RTC_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup RTC_Exported_Functions_Group4 Peripheral State functions
- * @brief Peripheral State functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral State functions #####
- ===============================================================================
- [..]
- This subsection provides functions allowing to
- (+) Get RTC state
-
-@endverbatim
- * @{
- */
-/**
- * @brief Returns the RTC state.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @retval HAL state
- */
-HAL_RTCStateTypeDef HAL_RTC_GetState(RTC_HandleTypeDef* hrtc)
-{
- return hrtc->State;
-}
-
-/**
- * @}
- */
-
-/** @defgroup RTC_Exported_Functions_Group5 Peripheral Control functions
- * @brief Peripheral Control functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral Control functions #####
- ===============================================================================
- [..]
- This subsection provides functions allowing to
- (+) Wait for RTC Time and Date Synchronization
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Waits until the RTC registers (RTC_CNT, RTC_ALR and RTC_PRL)
- * are synchronized with RTC APB clock.
- * @note This function must be called before any read operation after an APB reset
- * or an APB clock stop.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTC_WaitForSynchro(RTC_HandleTypeDef* hrtc)
-{
- uint32_t tickstart = 0U;
-
- /* Check input parameters */
- if(hrtc == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Clear RSF flag */
- CLEAR_BIT(hrtc->Instance->CRL, RTC_FLAG_RSF);
-
- tickstart = HAL_GetTick();
-
- /* Wait the registers to be synchronised */
- while((hrtc->Instance->CRL & RTC_FLAG_RSF) == (uint32_t)RESET)
- {
- if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-
-/**
- * @}
- */
-
-/** @addtogroup RTC_Private_Functions
- * @{
- */
-
-
-/**
- * @brief Read the time counter available in RTC_CNT registers.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @retval Time counter
- */
-static uint32_t RTC_ReadTimeCounter(RTC_HandleTypeDef* hrtc)
-{
- uint16_t high1 = 0U, high2 = 0U, low = 0U;
- uint32_t timecounter = 0U;
-
- high1 = READ_REG(hrtc->Instance->CNTH & RTC_CNTH_RTC_CNT);
- low = READ_REG(hrtc->Instance->CNTL & RTC_CNTL_RTC_CNT);
- high2 = READ_REG(hrtc->Instance->CNTH & RTC_CNTH_RTC_CNT);
-
- if (high1 != high2)
- { /* In this case the counter roll over during reading of CNTL and CNTH registers,
- read again CNTL register then return the counter value */
- timecounter = (((uint32_t) high2 << 16U) | READ_REG(hrtc->Instance->CNTL & RTC_CNTL_RTC_CNT));
- }
- else
- { /* No counter roll over during reading of CNTL and CNTH registers, counter
- value is equal to first value of CNTL and CNTH */
- timecounter = (((uint32_t) high1 << 16U) | low);
- }
-
- return timecounter;
-}
-
-/**
- * @brief Write the time counter in RTC_CNT registers.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @param TimeCounter: Counter to write in RTC_CNT registers
- * @retval HAL status
- */
-static HAL_StatusTypeDef RTC_WriteTimeCounter(RTC_HandleTypeDef* hrtc, uint32_t TimeCounter)
-{
- HAL_StatusTypeDef status = HAL_OK;
-
- /* Set Initialization mode */
- if(RTC_EnterInitMode(hrtc) != HAL_OK)
- {
- status = HAL_ERROR;
- }
- else
- {
- /* Set RTC COUNTER MSB word */
- WRITE_REG(hrtc->Instance->CNTH, (TimeCounter >> 16U));
- /* Set RTC COUNTER LSB word */
- WRITE_REG(hrtc->Instance->CNTL, (TimeCounter & RTC_CNTL_RTC_CNT));
-
- /* Wait for synchro */
- if(RTC_ExitInitMode(hrtc) != HAL_OK)
- {
- status = HAL_ERROR;
- }
- }
-
- return status;
-}
-
-/**
- * @brief Read the time counter available in RTC_ALR registers.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @retval Time counter
- */
-static uint32_t RTC_ReadAlarmCounter(RTC_HandleTypeDef* hrtc)
-{
- uint16_t high1 = 0U, low = 0U;
-
- high1 = READ_REG(hrtc->Instance->ALRH & RTC_CNTH_RTC_CNT);
- low = READ_REG(hrtc->Instance->ALRL & RTC_CNTL_RTC_CNT);
-
- return (((uint32_t) high1 << 16U) | low);
-}
-
-/**
- * @brief Write the time counter in RTC_ALR registers.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @param AlarmCounter: Counter to write in RTC_ALR registers
- * @retval HAL status
- */
-static HAL_StatusTypeDef RTC_WriteAlarmCounter(RTC_HandleTypeDef* hrtc, uint32_t AlarmCounter)
-{
- HAL_StatusTypeDef status = HAL_OK;
-
- /* Set Initialization mode */
- if(RTC_EnterInitMode(hrtc) != HAL_OK)
- {
- status = HAL_ERROR;
- }
- else
- {
- /* Set RTC COUNTER MSB word */
- WRITE_REG(hrtc->Instance->ALRH, (AlarmCounter >> 16U));
- /* Set RTC COUNTER LSB word */
- WRITE_REG(hrtc->Instance->ALRL, (AlarmCounter & RTC_ALRL_RTC_ALR));
-
- /* Wait for synchro */
- if(RTC_ExitInitMode(hrtc) != HAL_OK)
- {
- status = HAL_ERROR;
- }
- }
-
- return status;
-}
-
-/**
- * @brief Enters the RTC Initialization mode.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @retval HAL status
- */
-static HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef* hrtc)
-{
- uint32_t tickstart = 0U;
-
- tickstart = HAL_GetTick();
- /* Wait till RTC is in INIT state and if Time out is reached exit */
- while((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
- {
- if((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
-
- /* Disable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
-
-
- return HAL_OK;
-}
-
-/**
- * @brief Exit the RTC Initialization mode.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @retval HAL status
- */
-static HAL_StatusTypeDef RTC_ExitInitMode(RTC_HandleTypeDef* hrtc)
-{
- uint32_t tickstart = 0U;
-
- /* Disable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
-
- tickstart = HAL_GetTick();
- /* Wait till RTC is in INIT state and if Time out is reached exit */
- while((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
- {
- if((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
- {
- return HAL_TIMEOUT;
- }
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Converts a 2 digit decimal to BCD format.
- * @param Value: Byte to be converted
- * @retval Converted byte
- */
-static uint8_t RTC_ByteToBcd2(uint8_t Value)
-{
- uint32_t bcdhigh = 0U;
-
- while(Value >= 10U)
- {
- bcdhigh++;
- Value -= 10U;
- }
-
- return ((uint8_t)(bcdhigh << 4U) | Value);
-}
-
-/**
- * @brief Converts from 2 digit BCD to Binary.
- * @param Value: BCD value to be converted
- * @retval Converted word
- */
-static uint8_t RTC_Bcd2ToByte(uint8_t Value)
-{
- uint32_t tmp = 0U;
- tmp = ((uint8_t)(Value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10U;
- return (tmp + (Value & (uint8_t)0x0F));
-}
-
-/**
- * @brief Updates date when time is 23:59:59.
- * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @param DayElapsed: Number of days elapsed from last date update
- * @retval None
- */
-static void RTC_DateUpdate(RTC_HandleTypeDef* hrtc, uint32_t DayElapsed)
-{
- uint32_t year = 0U, month = 0U, day = 0U;
- uint32_t loop = 0U;
-
- /* Get the current year*/
- year = hrtc->DateToUpdate.Year;
-
- /* Get the current month and day */
- month = hrtc->DateToUpdate.Month;
- day = hrtc->DateToUpdate.Date;
-
- for (loop = 0U; loop < DayElapsed; loop++)
- {
- if((month == 1U) || (month == 3U) || (month == 5U) || (month == 7U) || \
- (month == 8U) || (month == 10U) || (month == 12U))
- {
- if(day < 31U)
- {
- day++;
- }
- /* Date structure member: day = 31 */
- else
- {
- if(month != 12U)
- {
- month++;
- day = 1U;
- }
- /* Date structure member: day = 31 & month =12 */
- else
- {
- month = 1U;
- day = 1U;
- year++;
- }
- }
- }
- else if((month == 4U) || (month == 6U) || (month == 9U) || (month == 11U))
- {
- if(day < 30U)
- {
- day++;
- }
- /* Date structure member: day = 30 */
- else
- {
- month++;
- day = 1U;
- }
- }
- else if(month == 2U)
- {
- if(day < 28U)
- {
- day++;
- }
- else if(day == 28U)
- {
- /* Leap year */
- if(RTC_IsLeapYear(year))
- {
- day++;
- }
- else
- {
- month++;
- day = 1U;
- }
- }
- else if(day == 29U)
- {
- month++;
- day = 1U;
- }
- }
- }
-
- /* Update year */
- hrtc->DateToUpdate.Year = year;
-
- /* Update day and month */
- hrtc->DateToUpdate.Month = month;
- hrtc->DateToUpdate.Date = day;
-
- /* Update day of the week */
- hrtc->DateToUpdate.WeekDay = RTC_WeekDayNum(year, month, day);
-}
-
-/**
- * @brief Check whether the passed year is Leap or not.
- * @param nYear year to check
- * @retval 1: leap year
- * 0: not leap year
- */
-static uint8_t RTC_IsLeapYear(uint16_t nYear)
-{
- if((nYear % 4U) != 0U)
- {
- return 0U;
- }
-
- if((nYear % 100U) != 0U)
- {
- return 1U;
- }
-
- if((nYear % 400U) == 0U)
- {
- return 1U;
- }
- else
- {
- return 0U;
- }
-}
-
-/**
- * @brief Determines the week number, the day number and the week day number.
- * @param nYear year to check
- * @param nMonth Month to check
- * @param nDay Day to check
- * @note Day is calculated with hypothesis that year > 2000
- * @retval Value which can take one of the following parameters:
- * @arg RTC_WEEKDAY_MONDAY
- * @arg RTC_WEEKDAY_TUESDAY
- * @arg RTC_WEEKDAY_WEDNESDAY
- * @arg RTC_WEEKDAY_THURSDAY
- * @arg RTC_WEEKDAY_FRIDAY
- * @arg RTC_WEEKDAY_SATURDAY
- * @arg RTC_WEEKDAY_SUNDAY
- */
-static uint8_t RTC_WeekDayNum(uint32_t nYear, uint8_t nMonth, uint8_t nDay)
-{
- uint32_t year = 0U, weekday = 0U;
-
- year = 2000U + nYear;
-
- if(nMonth < 3U)
- {
- /*D = { [(23 x month)/9] + day + 4 + year + [(year-1)/4] - [(year-1)/100] + [(year-1)/400] } mod 7*/
- weekday = (((23U * nMonth)/9U) + nDay + 4U + year + ((year-1U)/4U) - ((year-1U)/100U) + ((year-1U)/400U)) % 7U;
- }
- else
- {
- /*D = { [(23 x month)/9] + day + 4 + year + [year/4] - [year/100] + [year/400] - 2 } mod 7*/
- weekday = (((23U * nMonth)/9U) + nDay + 4U + year + (year/4U) - (year/100U) + (year/400U) - 2U ) % 7U;
- }
-
- return (uint8_t)weekday;
-}
-
-/**
- * @}
- */
-
-#endif /* HAL_RTC_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc_ex.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc_ex.c
deleted file mode 100644
index 4f42b81..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc_ex.c
+++ /dev/null
@@ -1,591 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_rtc_ex.c
- * @author MCD Application Team
- * @brief Extended RTC HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Real Time Clock (RTC) Extension peripheral:
- * + RTC Tamper functions
- * + Extension Control functions
- * + Extension RTC features functions
- *
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#ifdef HAL_RTC_MODULE_ENABLED
-
-/** @defgroup RTCEx RTCEx
- * @brief RTC Extended HAL module driver
- * @{
- */
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/* Private macro -------------------------------------------------------------*/
-/** @defgroup RTCEx_Private_Macros RTCEx Private Macros
- * @{
- */
-/**
- * @}
- */
-
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
-
-/** @defgroup RTCEx_Exported_Functions RTCEx Exported Functions
- * @{
- */
-
-/** @defgroup RTCEx_Exported_Functions_Group1 RTC Tamper functions
- * @brief RTC Tamper functions
- *
-@verbatim
- ===============================================================================
- ##### RTC Tamper functions #####
- ===============================================================================
-
- [..] This section provides functions allowing to configure Tamper feature
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Sets Tamper
- * @note By calling this API we disable the tamper interrupt for all tampers.
- * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @param sTamper: Pointer to Tamper Structure.
- * @note Tamper can be enabled only if ASOE and CCO bit are reset
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTCEx_SetTamper(RTC_HandleTypeDef *hrtc, RTC_TamperTypeDef* sTamper)
-{
- /* Check input parameters */
- if((hrtc == NULL) || (sTamper == NULL))
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_RTC_TAMPER(sTamper->Tamper));
- assert_param(IS_RTC_TAMPER_TRIGGER(sTamper->Trigger));
-
- /* Process Locked */
- __HAL_LOCK(hrtc);
-
- hrtc->State = HAL_RTC_STATE_BUSY;
-
- if (HAL_IS_BIT_SET(BKP->RTCCR,(BKP_RTCCR_CCO | BKP_RTCCR_ASOE)))
- {
- hrtc->State = HAL_RTC_STATE_ERROR;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_ERROR;
- }
-
- MODIFY_REG(BKP->CR, (BKP_CR_TPE | BKP_CR_TPAL), (sTamper->Tamper | (sTamper->Trigger)));
-
- hrtc->State = HAL_RTC_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_OK;
-}
-
-/**
- * @brief Sets Tamper with interrupt.
- * @note By calling this API we force the tamper interrupt for all tampers.
- * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @param sTamper: Pointer to RTC Tamper.
- * @note Tamper can be enabled only if ASOE and CCO bit are reset
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTCEx_SetTamper_IT(RTC_HandleTypeDef *hrtc, RTC_TamperTypeDef* sTamper)
-{
- /* Check input parameters */
- if((hrtc == NULL) || (sTamper == NULL))
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_RTC_TAMPER(sTamper->Tamper));
- assert_param(IS_RTC_TAMPER_TRIGGER(sTamper->Trigger));
-
- /* Process Locked */
- __HAL_LOCK(hrtc);
-
- hrtc->State = HAL_RTC_STATE_BUSY;
-
- if (HAL_IS_BIT_SET(BKP->RTCCR,(BKP_RTCCR_CCO | BKP_RTCCR_ASOE)))
- {
- hrtc->State = HAL_RTC_STATE_ERROR;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_ERROR;
- }
-
- MODIFY_REG(BKP->CR, (BKP_CR_TPE | BKP_CR_TPAL), (sTamper->Tamper | (sTamper->Trigger)));
-
- /* Configure the Tamper Interrupt in the BKP->CSR */
- __HAL_RTC_TAMPER_ENABLE_IT(hrtc, RTC_IT_TAMP1);
-
- hrtc->State = HAL_RTC_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_OK;
-}
-
-/**
- * @brief Deactivates Tamper.
- * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @param Tamper: Selected tamper pin.
- * This parameter can be a value of @ref RTCEx_Tamper_Pins_Definitions
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTCEx_DeactivateTamper(RTC_HandleTypeDef *hrtc, uint32_t Tamper)
-{
- /* Check input parameters */
- if(hrtc == NULL)
- {
- return HAL_ERROR;
- }
- /* Prevent unused argument(s) compilation warning */
- UNUSED(Tamper);
-
- assert_param(IS_RTC_TAMPER(Tamper));
-
- /* Process Locked */
- __HAL_LOCK(hrtc);
-
- hrtc->State = HAL_RTC_STATE_BUSY;
-
- /* Disable the selected Tamper pin */
- CLEAR_BIT(BKP->CR, BKP_CR_TPE);
-
- /* Disable the Tamper Interrupt in the BKP->CSR */
- /* Configure the Tamper Interrupt in the BKP->CSR */
- __HAL_RTC_TAMPER_DISABLE_IT(hrtc, RTC_IT_TAMP1);
-
- /* Clear the Tamper interrupt pending bit */
- __HAL_RTC_TAMPER_CLEAR_FLAG(hrtc, RTC_FLAG_TAMP1F);
- SET_BIT(BKP->CSR, BKP_CSR_CTE);
-
- hrtc->State = HAL_RTC_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_OK;
-}
-
-/**
- * @brief This function handles Tamper interrupt request.
- * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @retval None
- */
-void HAL_RTCEx_TamperIRQHandler(RTC_HandleTypeDef *hrtc)
-{
- /* Get the status of the Interrupt */
- if(__HAL_RTC_TAMPER_GET_IT_SOURCE(hrtc, RTC_IT_TAMP1))
- {
- /* Get the TAMPER Interrupt enable bit and pending bit */
- if(__HAL_RTC_TAMPER_GET_FLAG(hrtc, RTC_FLAG_TAMP1F) != (uint32_t)RESET)
- {
- /* Tamper callback */
- HAL_RTCEx_Tamper1EventCallback(hrtc);
-
- /* Clear the Tamper interrupt pending bit */
- __HAL_RTC_TAMPER_CLEAR_FLAG(hrtc,RTC_FLAG_TAMP1F);
- }
- }
-
- /* Change RTC state */
- hrtc->State = HAL_RTC_STATE_READY;
-}
-
-/**
- * @brief Tamper 1 callback.
- * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @retval None
- */
-__weak void HAL_RTCEx_Tamper1EventCallback(RTC_HandleTypeDef *hrtc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hrtc);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_RTCEx_Tamper1EventCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief This function handles Tamper1 Polling.
- * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @param Timeout: Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTCEx_PollForTamper1Event(RTC_HandleTypeDef *hrtc, uint32_t Timeout)
-{
- uint32_t tickstart = HAL_GetTick();
-
- /* Check input parameters */
- if(hrtc == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Get the status of the Interrupt */
- while(__HAL_RTC_TAMPER_GET_FLAG(hrtc,RTC_FLAG_TAMP1F)== RESET)
- {
- if(Timeout != HAL_MAX_DELAY)
- {
- if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
- {
- hrtc->State = HAL_RTC_STATE_TIMEOUT;
- return HAL_TIMEOUT;
- }
- }
- }
-
- /* Clear the Tamper Flag */
- __HAL_RTC_TAMPER_CLEAR_FLAG(hrtc,RTC_FLAG_TAMP1F);
-
- /* Change RTC state */
- hrtc->State = HAL_RTC_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup RTCEx_Exported_Functions_Group2 RTC Second functions
- * @brief RTC Second functions
- *
-@verbatim
- ===============================================================================
- ##### RTC Second functions #####
- ===============================================================================
-
- [..] This section provides functions implementing second interupt handlers
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Sets Interrupt for second
- * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTCEx_SetSecond_IT(RTC_HandleTypeDef *hrtc)
-{
- /* Check input parameters */
- if(hrtc == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hrtc);
-
- hrtc->State = HAL_RTC_STATE_BUSY;
-
- /* Enable Second interuption */
- __HAL_RTC_SECOND_ENABLE_IT(hrtc, RTC_IT_SEC);
-
- hrtc->State = HAL_RTC_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_OK;
-}
-
-/**
- * @brief Deactivates Second.
- * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTCEx_DeactivateSecond(RTC_HandleTypeDef *hrtc)
-{
- /* Check input parameters */
- if(hrtc == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hrtc);
-
- hrtc->State = HAL_RTC_STATE_BUSY;
-
- /* Deactivate Second interuption*/
- __HAL_RTC_SECOND_DISABLE_IT(hrtc, RTC_IT_SEC);
-
- hrtc->State = HAL_RTC_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_OK;
-}
-
-/**
- * @brief This function handles second interrupt request.
- * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @retval None
- */
-void HAL_RTCEx_RTCIRQHandler(RTC_HandleTypeDef* hrtc)
-{
- if(__HAL_RTC_SECOND_GET_IT_SOURCE(hrtc, RTC_IT_SEC))
- {
- /* Get the status of the Interrupt */
- if(__HAL_RTC_SECOND_GET_FLAG(hrtc, RTC_FLAG_SEC))
- {
- /* Check if Overrun occurred */
- if (__HAL_RTC_SECOND_GET_FLAG(hrtc, RTC_FLAG_OW))
- {
- /* Second error callback */
- HAL_RTCEx_RTCEventErrorCallback(hrtc);
-
- /* Clear flag Second */
- __HAL_RTC_OVERFLOW_CLEAR_FLAG(hrtc, RTC_FLAG_OW);
-
- /* Change RTC state */
- hrtc->State = HAL_RTC_STATE_ERROR;
- }
- else
- {
- /* Second callback */
- HAL_RTCEx_RTCEventCallback(hrtc);
-
- /* Change RTC state */
- hrtc->State = HAL_RTC_STATE_READY;
- }
-
- /* Clear flag Second */
- __HAL_RTC_SECOND_CLEAR_FLAG(hrtc, RTC_FLAG_SEC);
- }
- }
-}
-
-/**
- * @brief Second event callback.
- * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @retval None
- */
-__weak void HAL_RTCEx_RTCEventCallback(RTC_HandleTypeDef *hrtc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hrtc);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_RTCEx_RTCEventCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Second event error callback.
- * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @retval None
- */
-__weak void HAL_RTCEx_RTCEventErrorCallback(RTC_HandleTypeDef *hrtc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hrtc);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_RTCEx_RTCEventErrorCallback could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup RTCEx_Exported_Functions_Group3 Extended Peripheral Control functions
- * @brief Extended Peripheral Control functions
- *
-@verbatim
- ===============================================================================
- ##### Extension Peripheral Control functions #####
- ===============================================================================
- [..]
- This subsection provides functions allowing to
- (+) Writes a data in a specified RTC Backup data register
- (+) Read a data in a specified RTC Backup data register
- (+) Sets the Smooth calibration parameters.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Writes a data in a specified RTC Backup data register.
- * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @param BackupRegister: RTC Backup data Register number.
- * This parameter can be: RTC_BKP_DRx where x can be from 1 to 10 (or 42) to
- * specify the register (depending devices).
- * @param Data: Data to be written in the specified RTC Backup data register.
- * @retval None
- */
-void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data)
-{
- uint32_t tmp = 0U;
-
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hrtc);
-
- /* Check the parameters */
- assert_param(IS_RTC_BKP(BackupRegister));
-
- tmp = (uint32_t)BKP_BASE;
- tmp += (BackupRegister * 4U);
-
- *(__IO uint32_t *) tmp = (Data & BKP_DR1_D);
-}
-
-/**
- * @brief Reads data from the specified RTC Backup data Register.
- * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
- * the configuration information for RTC.
- * @param BackupRegister: RTC Backup data Register number.
- * This parameter can be: RTC_BKP_DRx where x can be from 1 to 10 (or 42) to
- * specify the register (depending devices).
- * @retval Read value
- */
-uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister)
-{
- uint32_t backupregister = 0U;
- uint32_t pvalue = 0U;
-
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hrtc);
-
- /* Check the parameters */
- assert_param(IS_RTC_BKP(BackupRegister));
-
- backupregister = (uint32_t)BKP_BASE;
- backupregister += (BackupRegister * 4U);
-
- pvalue = (*(__IO uint32_t *)(backupregister)) & BKP_DR1_D;
-
- /* Read the specified register */
- return pvalue;
-}
-
-
-/**
- * @brief Sets the Smooth calibration parameters.
- * @param hrtc: RTC handle
- * @param SmoothCalibPeriod: Not used (only present for compatibility with another families)
- * @param SmoothCalibPlusPulses: Not used (only present for compatibility with another families)
- * @param SmouthCalibMinusPulsesValue: specifies the RTC Clock Calibration value.
- * This parameter must be a number between 0 and 0x7F.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_RTCEx_SetSmoothCalib(RTC_HandleTypeDef* hrtc, uint32_t SmoothCalibPeriod, uint32_t SmoothCalibPlusPulses, uint32_t SmouthCalibMinusPulsesValue)
-{
- /* Check input parameters */
- if(hrtc == NULL)
- {
- return HAL_ERROR;
- }
- /* Prevent unused argument(s) compilation warning */
- UNUSED(SmoothCalibPeriod);
- UNUSED(SmoothCalibPlusPulses);
-
- /* Check the parameters */
- assert_param(IS_RTC_SMOOTH_CALIB_MINUS(SmouthCalibMinusPulsesValue));
-
- /* Process Locked */
- __HAL_LOCK(hrtc);
-
- hrtc->State = HAL_RTC_STATE_BUSY;
-
- /* Sets RTC Clock Calibration value.*/
- MODIFY_REG(BKP->RTCCR, BKP_RTCCR_CAL, SmouthCalibMinusPulsesValue);
-
- /* Change RTC state */
- hrtc->State = HAL_RTC_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hrtc);
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* HAL_RTC_MODULE_ENABLED */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sd.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sd.c
deleted file mode 100644
index fd28df5..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sd.c
+++ /dev/null
@@ -1,2922 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_sd.c
- * @author MCD Application Team
- * @brief SD card HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Secure Digital (SD) peripheral:
- * + Initialization and de-initialization functions
- * + IO operation functions
- * + Peripheral Control functions
- * + SD card Control functions
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- This driver implements a high level communication layer for read and write from/to
- this memory. The needed STM32 hardware resources (SDIO and GPIO) are performed by
- the user in HAL_SD_MspInit() function (MSP layer).
- Basically, the MSP layer configuration should be the same as we provide in the
- examples.
- You can easily tailor this configuration according to hardware resources.
-
- [..]
- This driver is a generic layered driver for SDIO memories which uses the HAL
- SDIO driver functions to interface with SD and uSD cards devices.
- It is used as follows:
-
- (#)Initialize the SDIO low level resources by implement the HAL_SD_MspInit() API:
- (##) Enable the SDIO interface clock using __HAL_RCC_SDIO_CLK_ENABLE();
- (##) SDIO pins configuration for SD card
- (+++) Enable the clock for the SDIO GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
- (+++) Configure these SDIO pins as alternate function pull-up using HAL_GPIO_Init()
- and according to your pin assignment;
- (##) DMA Configuration if you need to use DMA process (HAL_SD_ReadBlocks_DMA()
- and HAL_SD_WriteBlocks_DMA() APIs).
- (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE();
- (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled.
- (##) NVIC configuration if you need to use interrupt process when using DMA transfer.
- (+++) Configure the SDIO and DMA interrupt priorities using functions
- HAL_NVIC_SetPriority(); DMA priority is superior to SDIO's priority
- (+++) Enable the NVIC DMA and SDIO IRQs using function HAL_NVIC_EnableIRQ()
- (+++) SDIO interrupts are managed using the macros __HAL_SD_ENABLE_IT()
- and __HAL_SD_DISABLE_IT() inside the communication process.
- (+++) SDIO interrupts pending bits are managed using the macros __HAL_SD_GET_IT()
- and __HAL_SD_CLEAR_IT()
- (##) NVIC configuration if you need to use interrupt process (HAL_SD_ReadBlocks_IT()
- and HAL_SD_WriteBlocks_IT() APIs).
- (+++) Configure the SDIO interrupt priorities using function
- HAL_NVIC_SetPriority();
- (+++) Enable the NVIC SDIO IRQs using function HAL_NVIC_EnableIRQ()
- (+++) SDIO interrupts are managed using the macros __HAL_SD_ENABLE_IT()
- and __HAL_SD_DISABLE_IT() inside the communication process.
- (+++) SDIO interrupts pending bits are managed using the macros __HAL_SD_GET_IT()
- and __HAL_SD_CLEAR_IT()
- (#) At this stage, you can perform SD read/write/erase operations after SD card initialization
-
-
- *** SD Card Initialization and configuration ***
- ================================================
- [..]
- To initialize the SD Card, use the HAL_SD_Init() function. It Initializes
- SDIO IP(STM32 side) and the SD Card, and put it into StandBy State (Ready for data transfer).
- This function provide the following operations:
-
- (#) Initialize the SDIO peripheral interface with defaullt configuration.
- The initialization process is done at 400KHz. You can change or adapt
- this frequency by adjusting the "ClockDiv" field.
- The SD Card frequency (SDIO_CK) is computed as follows:
-
- SDIO_CK = SDIOCLK / (ClockDiv + 2)
-
- In initialization mode and according to the SD Card standard,
- make sure that the SDIO_CK frequency doesn't exceed 400KHz.
-
- This phase of initialization is done through SDIO_Init() and
- SDIO_PowerState_ON() SDIO low level APIs.
-
- (#) Initialize the SD card. The API used is HAL_SD_InitCard().
- This phase allows the card initialization and identification
- and check the SD Card type (Standard Capacity or High Capacity)
- The initialization flow is compatible with SD standard.
-
- This API (HAL_SD_InitCard()) could be used also to reinitialize the card in case
- of plug-off plug-in.
-
- (#) Configure the SD Card Data transfer frequency. By Default, the card transfer
- frequency is set to 24MHz. You can change or adapt this frequency by adjusting
- the "ClockDiv" field.
- In transfer mode and according to the SD Card standard, make sure that the
- SDIO_CK frequency doesn't exceed 25MHz and 50MHz in High-speed mode switch.
- To be able to use a frequency higher than 24MHz, you should use the SDIO
- peripheral in bypass mode. Refer to the corresponding reference manual
- for more details.
-
- (#) Select the corresponding SD Card according to the address read with the step 2.
-
- (#) Configure the SD Card in wide bus mode: 4-bits data.
-
- *** SD Card Read operation ***
- ==============================
- [..]
- (+) You can read from SD card in polling mode by using function HAL_SD_ReadBlocks().
- This function allows the read of 512 bytes blocks.
- You can choose either one block read operation or multiple block read operation
- by adjusting the "NumberOfBlocks" parameter.
- After this, you have to ensure that the transfer is done correctly. The check is done
- through HAL_SD_GetCardState() function for SD card state.
-
- (+) You can read from SD card in DMA mode by using function HAL_SD_ReadBlocks_DMA().
- This function allows the read of 512 bytes blocks.
- You can choose either one block read operation or multiple block read operation
- by adjusting the "NumberOfBlocks" parameter.
- After this, you have to ensure that the transfer is done correctly. The check is done
- through HAL_SD_GetCardState() function for SD card state.
- You could also check the DMA transfer process through the SD Rx interrupt event.
-
- (+) You can read from SD card in Interrupt mode by using function HAL_SD_ReadBlocks_IT().
- This function allows the read of 512 bytes blocks.
- You can choose either one block read operation or multiple block read operation
- by adjusting the "NumberOfBlocks" parameter.
- After this, you have to ensure that the transfer is done correctly. The check is done
- through HAL_SD_GetCardState() function for SD card state.
- You could also check the IT transfer process through the SD Rx interrupt event.
-
- *** SD Card Write operation ***
- ===============================
- [..]
- (+) You can write to SD card in polling mode by using function HAL_SD_WriteBlocks().
- This function allows the read of 512 bytes blocks.
- You can choose either one block read operation or multiple block read operation
- by adjusting the "NumberOfBlocks" parameter.
- After this, you have to ensure that the transfer is done correctly. The check is done
- through HAL_SD_GetCardState() function for SD card state.
-
- (+) You can write to SD card in DMA mode by using function HAL_SD_WriteBlocks_DMA().
- This function allows the read of 512 bytes blocks.
- You can choose either one block read operation or multiple block read operation
- by adjusting the "NumberOfBlocks" parameter.
- After this, you have to ensure that the transfer is done correctly. The check is done
- through HAL_SD_GetCardState() function for SD card state.
- You could also check the DMA transfer process through the SD Tx interrupt event.
-
- (+) You can write to SD card in Interrupt mode by using function HAL_SD_WriteBlocks_IT().
- This function allows the read of 512 bytes blocks.
- You can choose either one block read operation or multiple block read operation
- by adjusting the "NumberOfBlocks" parameter.
- After this, you have to ensure that the transfer is done correctly. The check is done
- through HAL_SD_GetCardState() function for SD card state.
- You could also check the IT transfer process through the SD Tx interrupt event.
-
- *** SD card status ***
- ======================
- [..]
- (+) The SD Status contains status bits that are related to the SD Memory
- Card proprietary features. To get SD card status use the HAL_SD_GetCardStatus().
-
- *** SD card information ***
- ===========================
- [..]
- (+) To get SD card information, you can use the function HAL_SD_GetCardInfo().
- It returns useful information about the SD card such as block size, card type,
- block number ...
-
- *** SD card CSD register ***
- ============================
- [..]
- (+) The HAL_SD_GetCardCSD() API allows to get the parameters of the CSD register.
- Some of the CSD parameters are useful for card initialization and identification.
-
- *** SD card CID register ***
- ============================
- [..]
- (+) The HAL_SD_GetCardCID() API allows to get the parameters of the CID register.
- Some of the CSD parameters are useful for card initialization and identification.
-
- *** SD HAL driver macros list ***
- ==================================
- [..]
- Below the list of most used macros in SD HAL driver.
-
- (+) __HAL_SD_ENABLE : Enable the SD device
- (+) __HAL_SD_DISABLE : Disable the SD device
- (+) __HAL_SD_DMA_ENABLE: Enable the SDIO DMA transfer
- (+) __HAL_SD_DMA_DISABLE: Disable the SDIO DMA transfer
- (+) __HAL_SD_ENABLE_IT: Enable the SD device interrupt
- (+) __HAL_SD_DISABLE_IT: Disable the SD device interrupt
- (+) __HAL_SD_GET_FLAG:Check whether the specified SD flag is set or not
- (+) __HAL_SD_CLEAR_FLAG: Clear the SD's pending flags
-
- [..]
- (@) You can refer to the SD HAL driver header file for more useful macros
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-#if defined(STM32F103xE) || defined(STM32F103xG)
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup SD
- * @{
- */
-#ifdef HAL_SD_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @addtogroup SD_Private_Defines
- * @{
- */
-
-/**
- * @}
- */
-
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
-/** @defgroup SD_Private_Functions SD Private Functions
- * @{
- */
-static uint32_t SD_InitCard(SD_HandleTypeDef *hsd);
-static uint32_t SD_PowerON(SD_HandleTypeDef *hsd);
-static uint32_t SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus);
-static uint32_t SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus);
-static uint32_t SD_WideBus_Enable(SD_HandleTypeDef *hsd);
-static uint32_t SD_WideBus_Disable(SD_HandleTypeDef *hsd);
-static uint32_t SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR);
-static HAL_StatusTypeDef SD_PowerOFF(SD_HandleTypeDef *hsd);
-static HAL_StatusTypeDef SD_Write_IT(SD_HandleTypeDef *hsd);
-static HAL_StatusTypeDef SD_Read_IT(SD_HandleTypeDef *hsd);
-static void SD_DMATransmitCplt(DMA_HandleTypeDef *hdma);
-static void SD_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
-static void SD_DMAError(DMA_HandleTypeDef *hdma);
-static void SD_DMATxAbort(DMA_HandleTypeDef *hdma);
-static void SD_DMARxAbort(DMA_HandleTypeDef *hdma);
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup SD_Exported_Functions
- * @{
- */
-
-/** @addtogroup SD_Exported_Functions_Group1
- * @brief Initialization and de-initialization functions
- *
-@verbatim
- ==============================================================================
- ##### Initialization and de-initialization functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to initialize/de-initialize the SD
- card device to be ready for use.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the SD according to the specified parameters in the
- SD_HandleTypeDef and create the associated handle.
- * @param hsd: Pointer to the SD handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SD_Init(SD_HandleTypeDef *hsd)
-{
- /* Check the SD handle allocation */
- if(hsd == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_SDIO_ALL_INSTANCE(hsd->Instance));
- assert_param(IS_SDIO_CLOCK_EDGE(hsd->Init.ClockEdge));
- assert_param(IS_SDIO_CLOCK_BYPASS(hsd->Init.ClockBypass));
- assert_param(IS_SDIO_CLOCK_POWER_SAVE(hsd->Init.ClockPowerSave));
- assert_param(IS_SDIO_BUS_WIDE(hsd->Init.BusWide));
- assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(hsd->Init.HardwareFlowControl));
- assert_param(IS_SDIO_CLKDIV(hsd->Init.ClockDiv));
-
- if(hsd->State == HAL_SD_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- hsd->Lock = HAL_UNLOCKED;
- /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
- HAL_SD_MspInit(hsd);
- }
-
- hsd->State = HAL_SD_STATE_BUSY;
-
- /* Initialize the Card parameters */
- HAL_SD_InitCard(hsd);
-
- /* Initialize the error code */
- hsd->ErrorCode = HAL_DMA_ERROR_NONE;
-
- /* Initialize the SD operation */
- hsd->Context = SD_CONTEXT_NONE;
-
- /* Initialize the SD state */
- hsd->State = HAL_SD_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the SD Card.
- * @param hsd: Pointer to SD handle
- * @note This function initializes the SD card. It could be used when a card
- re-initialization is needed.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SD_InitCard(SD_HandleTypeDef *hsd)
-{
- uint32_t errorstate = HAL_SD_ERROR_NONE;
- SD_InitTypeDef Init;
-
- /* Default SDIO peripheral configuration for SD card initialization */
- Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
- Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
- Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
- Init.BusWide = SDIO_BUS_WIDE_1B;
- Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
- Init.ClockDiv = SDIO_INIT_CLK_DIV;
-
- /* Initialize SDIO peripheral interface with default configuration */
- SDIO_Init(hsd->Instance, Init);
-
- /* Disable SDIO Clock */
- __HAL_SD_DISABLE(hsd);
-
- /* Set Power State to ON */
- SDIO_PowerState_ON(hsd->Instance);
-
- /* Enable SDIO Clock */
- __HAL_SD_ENABLE(hsd);
-
- /* Required power up waiting time before starting the SD initialization
- sequence */
- HAL_Delay(2U);
-
- /* Identify card operating voltage */
- errorstate = SD_PowerON(hsd);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- hsd->State = HAL_SD_STATE_READY;
- hsd->ErrorCode |= errorstate;
- return HAL_ERROR;
- }
-
- /* Card initialization */
- errorstate = SD_InitCard(hsd);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- hsd->State = HAL_SD_STATE_READY;
- hsd->ErrorCode |= errorstate;
- return HAL_ERROR;
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief De-Initializes the SD card.
- * @param hsd: Pointer to SD handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SD_DeInit(SD_HandleTypeDef *hsd)
-{
- /* Check the SD handle allocation */
- if(hsd == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_SDIO_ALL_INSTANCE(hsd->Instance));
-
- hsd->State = HAL_SD_STATE_BUSY;
-
- /* Set SD power state to off */
- SD_PowerOFF(hsd);
-
- /* De-Initialize the MSP layer */
- HAL_SD_MspDeInit(hsd);
-
- hsd->ErrorCode = HAL_SD_ERROR_NONE;
- hsd->State = HAL_SD_STATE_RESET;
-
- return HAL_OK;
-}
-
-
-/**
- * @brief Initializes the SD MSP.
- * @param hsd: Pointer to SD handle
- * @retval None
- */
-__weak void HAL_SD_MspInit(SD_HandleTypeDef *hsd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hsd);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_SD_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief De-Initialize SD MSP.
- * @param hsd: Pointer to SD handle
- * @retval None
- */
-__weak void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hsd);
-
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_SD_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @addtogroup SD_Exported_Functions_Group2
- * @brief Data transfer functions
- *
-@verbatim
- ==============================================================================
- ##### IO operation functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to manage the data
- transfer from/to SD card.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Reads block(s) from a specified address in a card. The Data transfer
- * is managed by polling mode.
- * @note This API should be followed by a check on the card state through
- * HAL_SD_GetCardState().
- * @param hsd: Pointer to SD handle
- * @param pData: pointer to the buffer that will contain the received data
- * @param BlockAdd: Block Address from where data is to be read
- * @param NumberOfBlocks: Number of SD blocks to read
- * @param Timeout: Specify timeout value
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
-{
- SDIO_DataInitTypeDef config;
- uint32_t errorstate = HAL_SD_ERROR_NONE;
- uint32_t tickstart = HAL_GetTick();
- uint32_t count = 0U, *tempbuff = (uint32_t *)pData;
-
- if(NULL == pData)
- {
- hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
- return HAL_ERROR;
- }
-
- if(hsd->State == HAL_SD_STATE_READY)
- {
- hsd->ErrorCode = HAL_DMA_ERROR_NONE;
-
- if((BlockAdd + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
- {
- hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
- return HAL_ERROR;
- }
-
- hsd->State = HAL_SD_STATE_BUSY;
-
- /* Initialize data control register */
- hsd->Instance->DCTRL = 0U;
-
- if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
- {
- BlockAdd *= 512U;
- }
-
- /* Set Block Size for Card */
- errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Configure the SD DPSM (Data Path State Machine) */
- config.DataTimeOut = SDMMC_DATATIMEOUT;
- config.DataLength = NumberOfBlocks * BLOCKSIZE;
- config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
- config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
- config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
- config.DPSM = SDIO_DPSM_ENABLE;
- SDIO_ConfigData(hsd->Instance, &config);
-
- /* Read block(s) in polling mode */
- if(NumberOfBlocks > 1U)
- {
- hsd->Context = SD_CONTEXT_READ_MULTIPLE_BLOCK;
-
- /* Read Multi Block command */
- errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, BlockAdd);
- }
- else
- {
- hsd->Context = SD_CONTEXT_READ_SINGLE_BLOCK;
-
- /* Read Single Block command */
- errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, BlockAdd);
- }
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Poll on SDIO flags */
- while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_STA_STBITERR))
- {
- if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF))
- {
- /* Read data from SDIO Rx FIFO */
- for(count = 0U; count < 8U; count++)
- {
- *(tempbuff + count) = SDIO_ReadFIFO(hsd->Instance);
- }
- tempbuff += 8U;
- }
-
- if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= HAL_SD_ERROR_TIMEOUT;
- hsd->State= HAL_SD_STATE_READY;
- return HAL_TIMEOUT;
- }
- }
-
- /* Send stop transmission command in case of multiblock read */
- if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
- {
- if(hsd->SdCard.CardType != CARD_SECURED)
- {
- /* Send stop transmission command */
- errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
- }
- }
-
- /* Get error state */
- if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
- else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
- else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= HAL_SD_ERROR_RX_OVERRUN;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Empty FIFO if there is still any data */
- while ((__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXDAVL)))
- {
- *tempbuff = SDIO_ReadFIFO(hsd->Instance);
- tempbuff++;
-
- if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= HAL_SD_ERROR_TIMEOUT;
- hsd->State= HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
- }
-
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
-
- hsd->State = HAL_SD_STATE_READY;
-
- return HAL_OK;
- }
- else
- {
- hsd->ErrorCode |= HAL_SD_ERROR_BUSY;
- return HAL_ERROR;
- }
-}
-
-/**
- * @brief Allows to write block(s) to a specified address in a card. The Data
- * transfer is managed by polling mode.
- * @note This API should be followed by a check on the card state through
- * HAL_SD_GetCardState().
- * @param hsd: Pointer to SD handle
- * @param pData: pointer to the buffer that will contain the data to transmit
- * @param BlockAdd: Block Address where data will be written
- * @param NumberOfBlocks: Number of SD blocks to write
- * @param Timeout: Specify timeout value
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
-{
- SDIO_DataInitTypeDef config;
- uint32_t errorstate = HAL_SD_ERROR_NONE;
- uint32_t tickstart = HAL_GetTick();
- uint32_t count = 0U;
- uint32_t *tempbuff = (uint32_t *)pData;
-
- if(NULL == pData)
- {
- hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
- return HAL_ERROR;
- }
-
- if(hsd->State == HAL_SD_STATE_READY)
- {
- hsd->ErrorCode = HAL_DMA_ERROR_NONE;
-
- if((BlockAdd + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
- {
- hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
- return HAL_ERROR;
- }
-
- hsd->State = HAL_SD_STATE_BUSY;
-
- /* Initialize data control register */
- hsd->Instance->DCTRL = 0U;
-
- if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
- {
- BlockAdd *= 512U;
- }
-
- /* Set Block Size for Card */
- errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Write Blocks in Polling mode */
- if(NumberOfBlocks > 1U)
- {
- hsd->Context = SD_CONTEXT_WRITE_MULTIPLE_BLOCK;
-
- /* Write Multi Block command */
- errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, BlockAdd);
- }
- else
- {
- hsd->Context = SD_CONTEXT_WRITE_SINGLE_BLOCK;
-
- /* Write Single Block command */
- errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, BlockAdd);
- }
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Configure the SD DPSM (Data Path State Machine) */
- config.DataTimeOut = SDMMC_DATATIMEOUT;
- config.DataLength = NumberOfBlocks * BLOCKSIZE;
- config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
- config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
- config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
- config.DPSM = SDIO_DPSM_ENABLE;
- SDIO_ConfigData(hsd->Instance, &config);
-
- /* Write block(s) in polling mode */
- while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
- {
- if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXFIFOHE))
- {
- /* Write data to SDIO Tx FIFO */
- for(count = 0U; count < 8U; count++)
- {
- SDIO_WriteFIFO(hsd->Instance, (tempbuff + count));
- }
- tempbuff += 8U;
- }
-
- if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_TIMEOUT;
- }
- }
-
- /* Send stop transmission command in case of multiblock write */
- if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
- {
- if(hsd->SdCard.CardType != CARD_SECURED)
- {
- /* Send stop transmission command */
- errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
- }
- }
-
- /* Get error state */
- if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
- else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
- else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR))
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= HAL_SD_ERROR_TX_UNDERRUN;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
-
- hsd->State = HAL_SD_STATE_READY;
-
- return HAL_OK;
- }
- else
- {
- hsd->ErrorCode |= HAL_SD_ERROR_BUSY;
- return HAL_ERROR;
- }
-}
-
-/**
- * @brief Reads block(s) from a specified address in a card. The Data transfer
- * is managed in interrupt mode.
- * @note This API should be followed by a check on the card state through
- * HAL_SD_GetCardState().
- * @note You could also check the IT transfer process through the SD Rx
- * interrupt event.
- * @param hsd: Pointer to SD handle
- * @param pData: Pointer to the buffer that will contain the received data
- * @param BlockAdd: Block Address from where data is to be read
- * @param NumberOfBlocks: Number of blocks to read.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SD_ReadBlocks_IT(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
-{
- SDIO_DataInitTypeDef config;
- uint32_t errorstate = HAL_SD_ERROR_NONE;
-
- if(NULL == pData)
- {
- hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
- return HAL_ERROR;
- }
-
- if(hsd->State == HAL_SD_STATE_READY)
- {
- hsd->ErrorCode = HAL_DMA_ERROR_NONE;
-
- if((BlockAdd + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
- {
- hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
- return HAL_ERROR;
- }
-
- hsd->State = HAL_SD_STATE_BUSY;
-
- /* Initialize data control register */
- hsd->Instance->DCTRL = 0U;
-
- hsd->pRxBuffPtr = (uint32_t *)pData;
- hsd->RxXferSize = BLOCKSIZE * NumberOfBlocks;
-
- __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF | SDIO_IT_STBITERR));
-
- if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
- {
- BlockAdd *= 512U;
- }
-
- /* Configure the SD DPSM (Data Path State Machine) */
- config.DataTimeOut = SDMMC_DATATIMEOUT;
- config.DataLength = BLOCKSIZE * NumberOfBlocks;
- config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
- config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
- config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
- config.DPSM = SDIO_DPSM_ENABLE;
- SDIO_ConfigData(hsd->Instance, &config);
-
- /* Set Block Size for Card */
- errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Read Blocks in IT mode */
- if(NumberOfBlocks > 1U)
- {
- hsd->Context = (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_IT);
-
- /* Read Multi Block command */
- errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, BlockAdd);
- }
- else
- {
- hsd->Context = (SD_CONTEXT_READ_SINGLE_BLOCK | SD_CONTEXT_IT);
-
- /* Read Single Block command */
- errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, BlockAdd);
- }
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Writes block(s) to a specified address in a card. The Data transfer
- * is managed in interrupt mode.
- * @note This API should be followed by a check on the card state through
- * HAL_SD_GetCardState().
- * @note You could also check the IT transfer process through the SD Tx
- * interrupt event.
- * @param hsd: Pointer to SD handle
- * @param pData: Pointer to the buffer that will contain the data to transmit
- * @param BlockAdd: Block Address where data will be written
- * @param NumberOfBlocks: Number of blocks to write
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SD_WriteBlocks_IT(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
-{
- SDIO_DataInitTypeDef config;
- uint32_t errorstate = HAL_SD_ERROR_NONE;
-
- if(NULL == pData)
- {
- hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
- return HAL_ERROR;
- }
-
- if(hsd->State == HAL_SD_STATE_READY)
- {
- hsd->ErrorCode = HAL_DMA_ERROR_NONE;
-
- if((BlockAdd + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
- {
- hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
- return HAL_ERROR;
- }
-
- hsd->State = HAL_SD_STATE_BUSY;
-
- /* Initialize data control register */
- hsd->Instance->DCTRL = 0U;
-
- hsd->pTxBuffPtr = (uint32_t *)pData;
- hsd->TxXferSize = BLOCKSIZE * NumberOfBlocks;
-
- /* Enable transfer interrupts */
- __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE | SDIO_IT_STBITERR));
-
- if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
- {
- BlockAdd *= 512U;
- }
-
- /* Set Block Size for Card */
- errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Write Blocks in Polling mode */
- if(NumberOfBlocks > 1U)
- {
- hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK| SD_CONTEXT_IT);
-
- /* Write Multi Block command */
- errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, BlockAdd);
- }
- else
- {
- hsd->Context = (SD_CONTEXT_WRITE_SINGLE_BLOCK | SD_CONTEXT_IT);
-
- /* Write Single Block command */
- errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, BlockAdd);
- }
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Configure the SD DPSM (Data Path State Machine) */
- config.DataTimeOut = SDMMC_DATATIMEOUT;
- config.DataLength = BLOCKSIZE * NumberOfBlocks;
- config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
- config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
- config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
- config.DPSM = SDIO_DPSM_ENABLE;
- SDIO_ConfigData(hsd->Instance, &config);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Reads block(s) from a specified address in a card. The Data transfer
- * is managed by DMA mode.
- * @note This API should be followed by a check on the card state through
- * HAL_SD_GetCardState().
- * @note You could also check the DMA transfer process through the SD Rx
- * interrupt event.
- * @param hsd: Pointer SD handle
- * @param pData: Pointer to the buffer that will contain the received data
- * @param BlockAdd: Block Address from where data is to be read
- * @param NumberOfBlocks: Number of blocks to read.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
-{
- SDIO_DataInitTypeDef config;
- uint32_t errorstate = HAL_SD_ERROR_NONE;
-
- if(NULL == pData)
- {
- hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
- return HAL_ERROR;
- }
-
- if(hsd->State == HAL_SD_STATE_READY)
- {
- hsd->ErrorCode = HAL_DMA_ERROR_NONE;
-
- if((BlockAdd + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
- {
- hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
- return HAL_ERROR;
- }
-
- hsd->State = HAL_SD_STATE_BUSY;
-
- /* Initialize data control register */
- hsd->Instance->DCTRL = 0U;
-
- __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_IT_STBITERR));
-
- /* Set the DMA transfer complete callback */
- hsd->hdmarx->XferCpltCallback = SD_DMAReceiveCplt;
-
- /* Set the DMA error callback */
- hsd->hdmarx->XferErrorCallback = SD_DMAError;
-
- /* Set the DMA Abort callback */
- hsd->hdmarx->XferAbortCallback = NULL;
-
- /* Enable the DMA Channel */
- HAL_DMA_Start_IT(hsd->hdmarx, (uint32_t)&hsd->Instance->FIFO, (uint32_t)pData, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4);
-
- /* Enable SD DMA transfer */
- __HAL_SD_DMA_ENABLE(hsd);
-
- if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
- {
- BlockAdd *= 512U;
- }
-
- /* Configure the SD DPSM (Data Path State Machine) */
- config.DataTimeOut = SDMMC_DATATIMEOUT;
- config.DataLength = BLOCKSIZE * NumberOfBlocks;
- config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
- config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
- config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
- config.DPSM = SDIO_DPSM_ENABLE;
- SDIO_ConfigData(hsd->Instance, &config);
-
- /* Set Block Size for Card */
- errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Read Blocks in DMA mode */
- if(NumberOfBlocks > 1U)
- {
- hsd->Context = (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_DMA);
-
- /* Read Multi Block command */
- errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, BlockAdd);
- }
- else
- {
- hsd->Context = (SD_CONTEXT_READ_SINGLE_BLOCK | SD_CONTEXT_DMA);
-
- /* Read Single Block command */
- errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, BlockAdd);
- }
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Writes block(s) to a specified address in a card. The Data transfer
- * is managed by DMA mode.
- * @note This API should be followed by a check on the card state through
- * HAL_SD_GetCardState().
- * @note You could also check the DMA transfer process through the SD Tx
- * interrupt event.
- * @param hsd: Pointer to SD handle
- * @param pData: Pointer to the buffer that will contain the data to transmit
- * @param BlockAdd: Block Address where data will be written
- * @param NumberOfBlocks: Number of blocks to write
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
-{
- SDIO_DataInitTypeDef config;
- uint32_t errorstate = HAL_SD_ERROR_NONE;
-
- if(NULL == pData)
- {
- hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
- return HAL_ERROR;
- }
-
- if(hsd->State == HAL_SD_STATE_READY)
- {
- hsd->ErrorCode = HAL_DMA_ERROR_NONE;
-
- if((BlockAdd + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
- {
- hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
- return HAL_ERROR;
- }
-
- hsd->State = HAL_SD_STATE_BUSY;
-
- /* Initialize data control register */
- hsd->Instance->DCTRL = 0U;
-
- /* Enable SD Error interrupts */
- __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR));
-
- /* Set the DMA transfer complete callback */
- hsd->hdmatx->XferCpltCallback = SD_DMATransmitCplt;
-
- /* Set the DMA error callback */
- hsd->hdmatx->XferErrorCallback = SD_DMAError;
-
- /* Set the DMA Abort callback */
- hsd->hdmatx->XferAbortCallback = NULL;
-
- if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
- {
- BlockAdd *= 512U;
- }
-
- /* Set Block Size for Card */
- errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Write Blocks in Polling mode */
- if(NumberOfBlocks > 1U)
- {
- hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK | SD_CONTEXT_DMA);
-
- /* Write Multi Block command */
- errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, BlockAdd);
- }
- else
- {
- hsd->Context = (SD_CONTEXT_WRITE_SINGLE_BLOCK | SD_CONTEXT_DMA);
-
- /* Write Single Block command */
- errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, BlockAdd);
- }
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Enable SDIO DMA transfer */
- __HAL_SD_DMA_ENABLE(hsd);
-
- /* Enable the DMA Channel */
- HAL_DMA_Start_IT(hsd->hdmatx, (uint32_t)pData, (uint32_t)&hsd->Instance->FIFO, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4);
-
- /* Configure the SD DPSM (Data Path State Machine) */
- config.DataTimeOut = SDMMC_DATATIMEOUT;
- config.DataLength = BLOCKSIZE * NumberOfBlocks;
- config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
- config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
- config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
- config.DPSM = SDIO_DPSM_ENABLE;
- SDIO_ConfigData(hsd->Instance, &config);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Erases the specified memory area of the given SD card.
- * @note This API should be followed by a check on the card state through
- * HAL_SD_GetCardState().
- * @param hsd: Pointer to SD handle
- * @param BlockStartAdd: Start Block address
- * @param BlockEndAdd: End Block address
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
-{
- uint32_t errorstate = HAL_SD_ERROR_NONE;
-
- if(hsd->State == HAL_SD_STATE_READY)
- {
- hsd->ErrorCode = HAL_DMA_ERROR_NONE;
-
- if(BlockEndAdd < BlockStartAdd)
- {
- hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
- return HAL_ERROR;
- }
-
- if(BlockEndAdd > (hsd->SdCard.LogBlockNbr))
- {
- hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
- return HAL_ERROR;
- }
-
- hsd->State = HAL_SD_STATE_BUSY;
-
- /* Check if the card command class supports erase command */
- if(((hsd->SdCard.Class) & SDIO_CCCC_ERASE) == 0U)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= HAL_SD_ERROR_LOCK_UNLOCK_FAILED;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Get start and end block for high capacity cards */
- if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
- {
- BlockStartAdd *= 512U;
- BlockEndAdd *= 512U;
- }
-
- /* According to sd-card spec 1.0 ERASE_GROUP_START (CMD32) and erase_group_end(CMD33) */
- if(hsd->SdCard.CardType != CARD_SECURED)
- {
- /* Send CMD32 SD_ERASE_GRP_START with argument as addr */
- errorstate = SDMMC_CmdSDEraseStartAdd(hsd->Instance, BlockStartAdd);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- /* Send CMD33 SD_ERASE_GRP_END with argument as addr */
- errorstate = SDMMC_CmdSDEraseEndAdd(hsd->Instance, BlockEndAdd);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
- }
-
- /* Send CMD38 ERASE */
- errorstate = SDMMC_CmdErase(hsd->Instance);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- hsd->State = HAL_SD_STATE_READY;
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief This function handles SD card interrupt request.
- * @param hsd: Pointer to SD handle
- * @retval None
- */
-void HAL_SD_IRQHandler(SD_HandleTypeDef *hsd)
-{
- uint32_t errorstate = HAL_SD_ERROR_NONE;
-
- /* Check for SDIO interrupt flags */
- if(__HAL_SD_GET_FLAG(hsd, SDIO_IT_DATAEND) != RESET)
- {
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_DATAEND);
-
- __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
- SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR | SDIO_IT_STBITERR);
-
- if((hsd->Context & SD_CONTEXT_IT) != RESET)
- {
- if(((hsd->Context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != RESET) || ((hsd->Context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != RESET))
- {
- errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- hsd->ErrorCode |= errorstate;
- HAL_SD_ErrorCallback(hsd);
- }
- }
-
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
-
- hsd->State = HAL_SD_STATE_READY;
- if(((hsd->Context & SD_CONTEXT_READ_SINGLE_BLOCK) != RESET) || ((hsd->Context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != RESET))
- {
- HAL_SD_RxCpltCallback(hsd);
- }
- else
- {
- HAL_SD_TxCpltCallback(hsd);
- }
- }
- else if((hsd->Context & SD_CONTEXT_DMA) != RESET)
- {
- if((hsd->Context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != RESET)
- {
- errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- hsd->ErrorCode |= errorstate;
- HAL_SD_ErrorCallback(hsd);
- }
- }
- if(((hsd->Context & SD_CONTEXT_READ_SINGLE_BLOCK) == RESET) && ((hsd->Context & SD_CONTEXT_READ_MULTIPLE_BLOCK) == RESET))
- {
- /* Disable the DMA transfer for transmit request by setting the DMAEN bit
- in the SD DCTRL register */
- hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
-
- hsd->State = HAL_SD_STATE_READY;
-
- HAL_SD_TxCpltCallback(hsd);
- }
- }
- }
-
- else if(__HAL_SD_GET_FLAG(hsd, SDIO_IT_TXFIFOHE) != RESET)
- {
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_TXFIFOHE);
-
- SD_Write_IT(hsd);
- }
-
- else if(__HAL_SD_GET_FLAG(hsd, SDIO_IT_RXFIFOHF) != RESET)
- {
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_RXFIFOHF);
-
- SD_Read_IT(hsd);
- }
-
- else if(__HAL_SD_GET_FLAG(hsd, SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR) != RESET)
- {
- /* Set Error code */
- if(__HAL_SD_GET_FLAG(hsd, SDIO_IT_DCRCFAIL) != RESET)
- {
- hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL;
- }
- if(__HAL_SD_GET_FLAG(hsd, SDIO_IT_DTIMEOUT) != RESET)
- {
- hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT;
- }
- if(__HAL_SD_GET_FLAG(hsd, SDIO_IT_RXOVERR) != RESET)
- {
- hsd->ErrorCode |= HAL_SD_ERROR_RX_OVERRUN;
- }
- if(__HAL_SD_GET_FLAG(hsd, SDIO_IT_TXUNDERR) != RESET)
- {
- hsd->ErrorCode |= HAL_SD_ERROR_TX_UNDERRUN;
- }
- if(__HAL_SD_GET_FLAG(hsd, SDIO_IT_STBITERR) != RESET)
- {
- hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT;
- }
-
- /* Clear All flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS | SDIO_FLAG_STBITERR);
-
- /* Disable all interrupts */
- __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
- SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR |SDIO_IT_STBITERR);
-
- if((hsd->Context & SD_CONTEXT_DMA) != RESET)
- {
- /* Abort the SD DMA Streams */
- if(hsd->hdmatx != NULL)
- {
- /* Set the DMA Tx abort callback */
- hsd->hdmatx->XferAbortCallback = SD_DMATxAbort;
- /* Abort DMA in IT mode */
- if(HAL_DMA_Abort_IT(hsd->hdmatx) != HAL_OK)
- {
- SD_DMATxAbort(hsd->hdmatx);
- }
- }
- else if(hsd->hdmarx != NULL)
- {
- /* Set the DMA Rx abort callback */
- hsd->hdmarx->XferAbortCallback = SD_DMARxAbort;
- /* Abort DMA in IT mode */
- if(HAL_DMA_Abort_IT(hsd->hdmarx) != HAL_OK)
- {
- SD_DMARxAbort(hsd->hdmarx);
- }
- }
- else
- {
- hsd->ErrorCode = HAL_SD_ERROR_NONE;
- hsd->State = HAL_SD_STATE_READY;
- HAL_SD_AbortCallback(hsd);
- }
- }
- else if((hsd->Context & SD_CONTEXT_IT) != RESET)
- {
- /* Set the SD state to ready to be able to start again the process */
- hsd->State = HAL_SD_STATE_READY;
- HAL_SD_ErrorCallback(hsd);
- }
- }
-}
-
-/**
- * @brief return the SD state
- * @param hsd: Pointer to sd handle
- * @retval HAL state
- */
-HAL_SD_StateTypeDef HAL_SD_GetState(SD_HandleTypeDef *hsd)
-{
- return hsd->State;
-}
-
-/**
-* @brief Return the SD error code
-* @param hsd : Pointer to a SD_HandleTypeDef structure that contains
- * the configuration information.
-* @retval SD Error Code
-*/
-uint32_t HAL_SD_GetError(SD_HandleTypeDef *hsd)
-{
- return hsd->ErrorCode;
-}
-
-/**
- * @brief Tx Transfer completed callbacks
- * @param hsd: Pointer to SD handle
- * @retval None
- */
- __weak void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hsd);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_SD_TxCpltCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief Rx Transfer completed callbacks
- * @param hsd: Pointer SD handle
- * @retval None
- */
-__weak void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hsd);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_SD_RxCpltCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief SD error callbacks
- * @param hsd: Pointer SD handle
- * @retval None
- */
-__weak void HAL_SD_ErrorCallback(SD_HandleTypeDef *hsd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hsd);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_SD_ErrorCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief SD Abort callbacks
- * @param hsd: Pointer SD handle
- * @retval None
- */
-__weak void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hsd);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_SD_ErrorCallback can be implemented in the user file
- */
-}
-
-
-/**
- * @}
- */
-
-/** @addtogroup SD_Exported_Functions_Group3
- * @brief management functions
- *
-@verbatim
- ==============================================================================
- ##### Peripheral Control functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to control the SD card
- operations and get the related information
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Returns information the information of the card which are stored on
- * the CID register.
- * @param hsd: Pointer to SD handle
- * @param pCID: Pointer to a HAL_SD_CIDTypeDef structure that
- * contains all CID register parameters
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SD_GetCardCID(SD_HandleTypeDef *hsd, HAL_SD_CardCIDTypeDef *pCID)
-{
- uint32_t tmp = 0U;
-
- /* Byte 0 */
- tmp = (uint8_t)((hsd->CID[0U] & 0xFF000000U) >> 24U);
- pCID->ManufacturerID = tmp;
-
- /* Byte 1 */
- tmp = (uint8_t)((hsd->CID[0U] & 0x00FF0000U) >> 16U);
- pCID->OEM_AppliID = tmp << 8U;
-
- /* Byte 2 */
- tmp = (uint8_t)((hsd->CID[0U] & 0x000000FF00U) >> 8U);
- pCID->OEM_AppliID |= tmp;
-
- /* Byte 3 */
- tmp = (uint8_t)(hsd->CID[0U] & 0x000000FFU);
- pCID->ProdName1 = tmp << 24U;
-
- /* Byte 4 */
- tmp = (uint8_t)((hsd->CID[1U] & 0xFF000000U) >> 24U);
- pCID->ProdName1 |= tmp << 16;
-
- /* Byte 5 */
- tmp = (uint8_t)((hsd->CID[1U] & 0x00FF0000U) >> 16U);
- pCID->ProdName1 |= tmp << 8U;
-
- /* Byte 6 */
- tmp = (uint8_t)((hsd->CID[1U] & 0x0000FF00U) >> 8U);
- pCID->ProdName1 |= tmp;
-
- /* Byte 7 */
- tmp = (uint8_t)(hsd->CID[1U] & 0x000000FFU);
- pCID->ProdName2 = tmp;
-
- /* Byte 8 */
- tmp = (uint8_t)((hsd->CID[2U] & 0xFF000000U) >> 24U);
- pCID->ProdRev = tmp;
-
- /* Byte 9 */
- tmp = (uint8_t)((hsd->CID[2U] & 0x00FF0000U) >> 16U);
- pCID->ProdSN = tmp << 24U;
-
- /* Byte 10 */
- tmp = (uint8_t)((hsd->CID[2U] & 0x0000FF00U) >> 8U);
- pCID->ProdSN |= tmp << 16U;
-
- /* Byte 11 */
- tmp = (uint8_t)(hsd->CID[2U] & 0x000000FFU);
- pCID->ProdSN |= tmp << 8U;
-
- /* Byte 12 */
- tmp = (uint8_t)((hsd->CID[3U] & 0xFF000000U) >> 24U);
- pCID->ProdSN |= tmp;
-
- /* Byte 13 */
- tmp = (uint8_t)((hsd->CID[3U] & 0x00FF0000U) >> 16U);
- pCID->Reserved1 |= (tmp & 0xF0U) >> 4U;
- pCID->ManufactDate = (tmp & 0x0FU) << 8U;
-
- /* Byte 14 */
- tmp = (uint8_t)((hsd->CID[3U] & 0x0000FF00U) >> 8U);
- pCID->ManufactDate |= tmp;
-
- /* Byte 15 */
- tmp = (uint8_t)(hsd->CID[3U] & 0x000000FFU);
- pCID->CID_CRC = (tmp & 0xFEU) >> 1U;
- pCID->Reserved2 = 1U;
-
- return HAL_OK;
-}
-
-/**
- * @brief Returns information the information of the card which are stored on
- * the CSD register.
- * @param hsd: Pointer to SD handle
- * @param pCSD: Pointer to a HAL_SD_CardCSDTypeDef structure that
- * contains all CSD register parameters
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SD_GetCardCSD(SD_HandleTypeDef *hsd, HAL_SD_CardCSDTypeDef *pCSD)
-{
- uint32_t tmp = 0U;
-
- /* Byte 0 */
- tmp = (hsd->CSD[0U] & 0xFF000000U) >> 24U;
- pCSD->CSDStruct = (uint8_t)((tmp & 0xC0U) >> 6U);
- pCSD->SysSpecVersion = (uint8_t)((tmp & 0x3CU) >> 2U);
- pCSD->Reserved1 = tmp & 0x03U;
-
- /* Byte 1 */
- tmp = (hsd->CSD[0U] & 0x00FF0000U) >> 16U;
- pCSD->TAAC = (uint8_t)tmp;
-
- /* Byte 2 */
- tmp = (hsd->CSD[0U] & 0x0000FF00U) >> 8U;
- pCSD->NSAC = (uint8_t)tmp;
-
- /* Byte 3 */
- tmp = hsd->CSD[0U] & 0x000000FFU;
- pCSD->MaxBusClkFrec = (uint8_t)tmp;
-
- /* Byte 4 */
- tmp = (hsd->CSD[1U] & 0xFF000000U) >> 24U;
- pCSD->CardComdClasses = (uint16_t)(tmp << 4U);
-
- /* Byte 5 */
- tmp = (hsd->CSD[1U] & 0x00FF0000U) >> 16U;
- pCSD->CardComdClasses |= (uint16_t)((tmp & 0xF0U) >> 4U);
- pCSD->RdBlockLen = (uint8_t)(tmp & 0x0FU);
-
- /* Byte 6 */
- tmp = (hsd->CSD[1U] & 0x0000FF00U) >> 8U;
- pCSD->PartBlockRead = (uint8_t)((tmp & 0x80U) >> 7U);
- pCSD->WrBlockMisalign = (uint8_t)((tmp & 0x40U) >> 6U);
- pCSD->RdBlockMisalign = (uint8_t)((tmp & 0x20U) >> 5U);
- pCSD->DSRImpl = (uint8_t)((tmp & 0x10U) >> 4U);
- pCSD->Reserved2 = 0U; /*!< Reserved */
-
- if(hsd->SdCard.CardType == CARD_SDSC)
- {
- pCSD->DeviceSize = (tmp & 0x03U) << 10U;
-
- /* Byte 7 */
- tmp = (uint8_t)(hsd->CSD[1U] & 0x000000FFU);
- pCSD->DeviceSize |= (tmp) << 2U;
-
- /* Byte 8 */
- tmp = (uint8_t)((hsd->CSD[2U] & 0xFF000000U) >> 24U);
- pCSD->DeviceSize |= (tmp & 0xC0U) >> 6U;
-
- pCSD->MaxRdCurrentVDDMin = (tmp & 0x38U) >> 3U;
- pCSD->MaxRdCurrentVDDMax = (tmp & 0x07U);
-
- /* Byte 9 */
- tmp = (uint8_t)((hsd->CSD[2U] & 0x00FF0000U) >> 16U);
- pCSD->MaxWrCurrentVDDMin = (tmp & 0xE0U) >> 5U;
- pCSD->MaxWrCurrentVDDMax = (tmp & 0x1CU) >> 2U;
- pCSD->DeviceSizeMul = (tmp & 0x03U) << 1U;
- /* Byte 10 */
- tmp = (uint8_t)((hsd->CSD[2U] & 0x0000FF00U) >> 8U);
- pCSD->DeviceSizeMul |= (tmp & 0x80U) >> 7U;
-
- hsd->SdCard.BlockNbr = (pCSD->DeviceSize + 1U) ;
- hsd->SdCard.BlockNbr *= (1U << (pCSD->DeviceSizeMul + 2U));
- hsd->SdCard.BlockSize = 1U << (pCSD->RdBlockLen);
-
- hsd->SdCard.LogBlockNbr = (hsd->SdCard.BlockNbr) * ((hsd->SdCard.BlockSize) / 512U);
- hsd->SdCard.LogBlockSize = 512U;
- }
- else if(hsd->SdCard.CardType == CARD_SDHC_SDXC)
- {
- /* Byte 7 */
- tmp = (uint8_t)(hsd->CSD[1U] & 0x000000FFU);
- pCSD->DeviceSize = (tmp & 0x3FU) << 16U;
-
- /* Byte 8 */
- tmp = (uint8_t)((hsd->CSD[2U] & 0xFF000000U) >> 24U);
-
- pCSD->DeviceSize |= (tmp << 8U);
-
- /* Byte 9 */
- tmp = (uint8_t)((hsd->CSD[2U] & 0x00FF0000U) >> 16U);
-
- pCSD->DeviceSize |= (tmp);
-
- /* Byte 10 */
- tmp = (uint8_t)((hsd->CSD[2U] & 0x0000FF00U) >> 8U);
-
- hsd->SdCard.LogBlockNbr = hsd->SdCard.BlockNbr = (((uint64_t)pCSD->DeviceSize + 1U) * 1024U);
- hsd->SdCard.LogBlockSize = hsd->SdCard.BlockSize = 512U;
- }
- else
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
-
- pCSD->EraseGrSize = (tmp & 0x40U) >> 6U;
- pCSD->EraseGrMul = (tmp & 0x3FU) << 1U;
-
- /* Byte 11 */
- tmp = (uint8_t)(hsd->CSD[2U] & 0x000000FFU);
- pCSD->EraseGrMul |= (tmp & 0x80U) >> 7U;
- pCSD->WrProtectGrSize = (tmp & 0x7FU);
-
- /* Byte 12 */
- tmp = (uint8_t)((hsd->CSD[3U] & 0xFF000000U) >> 24U);
- pCSD->WrProtectGrEnable = (tmp & 0x80U) >> 7U;
- pCSD->ManDeflECC = (tmp & 0x60U) >> 5U;
- pCSD->WrSpeedFact = (tmp & 0x1CU) >> 2U;
- pCSD->MaxWrBlockLen = (tmp & 0x03U) << 2U;
-
- /* Byte 13 */
- tmp = (uint8_t)((hsd->CSD[3U] & 0x00FF0000U) >> 16U);
- pCSD->MaxWrBlockLen |= (tmp & 0xC0U) >> 6U;
- pCSD->WriteBlockPaPartial = (tmp & 0x20U) >> 5U;
- pCSD->Reserved3 = 0U;
- pCSD->ContentProtectAppli = (tmp & 0x01U);
-
- /* Byte 14 */
- tmp = (uint8_t)((hsd->CSD[3U] & 0x0000FF00U) >> 8U);
- pCSD->FileFormatGrouop = (tmp & 0x80U) >> 7U;
- pCSD->CopyFlag = (tmp & 0x40U) >> 6U;
- pCSD->PermWrProtect = (tmp & 0x20U) >> 5U;
- pCSD->TempWrProtect = (tmp & 0x10U) >> 4U;
- pCSD->FileFormat = (tmp & 0x0CU) >> 2U;
- pCSD->ECC = (tmp & 0x03U);
-
- /* Byte 15 */
- tmp = (uint8_t)(hsd->CSD[3U] & 0x000000FFU);
- pCSD->CSD_CRC = (tmp & 0xFEU) >> 1U;
- pCSD->Reserved4 = 1U;
-
- return HAL_OK;
-}
-
-/**
- * @brief Gets the SD status info.
- * @param hsd: Pointer to SD handle
- * @param pStatus: Pointer to the HAL_SD_CardStatusTypeDef structure that
- * will contain the SD card status information
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypeDef *pStatus)
-{
- uint32_t tmp = 0U;
- uint32_t sd_status[16U];
- uint32_t errorstate = HAL_SD_ERROR_NONE;
-
- errorstate = SD_SendSDStatus(hsd, sd_status);
- if(errorstate != HAL_OK)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->ErrorCode |= errorstate;
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
- else
- {
- /* Byte 0 */
- tmp = (sd_status[0U] & 0xC0U) >> 6U;
- pStatus->DataBusWidth = (uint8_t)tmp;
-
- /* Byte 0 */
- tmp = (sd_status[0U] & 0x20U) >> 5U;
- pStatus->SecuredMode = (uint8_t)tmp;
-
- /* Byte 2 */
- tmp = (sd_status[0U] & 0x00FF0000U) >> 16U;
- pStatus->CardType = (uint16_t)(tmp << 8U);
-
- /* Byte 3 */
- tmp = (sd_status[0U] & 0xFF000000U) >> 24U;
- pStatus->CardType |= (uint16_t)tmp;
-
- /* Byte 4 */
- tmp = (sd_status[1U] & 0xFFU);
- pStatus->ProtectedAreaSize = (uint32_t)(tmp << 24U);
-
- /* Byte 5 */
- tmp = (sd_status[1U] & 0xFF00U) >> 8U;
- pStatus->ProtectedAreaSize |= (uint32_t)(tmp << 16U);
-
- /* Byte 6 */
- tmp = (sd_status[1U] & 0xFF0000U) >> 16U;
- pStatus->ProtectedAreaSize |= (uint32_t)(tmp << 8U);
-
- /* Byte 7 */
- tmp = (sd_status[1U] & 0xFF000000U) >> 24U;
- pStatus->ProtectedAreaSize |= (uint32_t)tmp;
-
- /* Byte 8 */
- tmp = (sd_status[2U] & 0xFFU);
- pStatus->SpeedClass = (uint8_t)tmp;
-
- /* Byte 9 */
- tmp = (sd_status[2U] & 0xFF00U) >> 8U;
- pStatus->PerformanceMove = (uint8_t)tmp;
-
- /* Byte 10 */
- tmp = (sd_status[2U] & 0xF00000U) >> 20U;
- pStatus->AllocationUnitSize = (uint8_t)tmp;
-
- /* Byte 11 */
- tmp = (sd_status[2U] & 0xFF000000U) >> 24U;
- pStatus->EraseSize = (uint16_t)(tmp << 8U);
-
- /* Byte 12 */
- tmp = (sd_status[3U] & 0xFFU);
- pStatus->EraseSize |= (uint16_t)tmp;
-
- /* Byte 13 */
- tmp = (sd_status[3U] & 0xFC00U) >> 10U;
- pStatus->EraseTimeout = (uint8_t)tmp;
-
- /* Byte 13 */
- tmp = (sd_status[3U] & 0x0300U) >> 8U;
- pStatus->EraseOffset = (uint8_t)tmp;
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Gets the SD card info.
- * @param hsd: Pointer to SD handle
- * @param pCardInfo: Pointer to the HAL_SD_CardInfoTypeDef structure that
- * will contain the SD card status information
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SD_GetCardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypeDef *pCardInfo)
-{
- pCardInfo->CardType = (uint32_t)(hsd->SdCard.CardType);
- pCardInfo->CardVersion = (uint32_t)(hsd->SdCard.CardVersion);
- pCardInfo->Class = (uint32_t)(hsd->SdCard.Class);
- pCardInfo->RelCardAdd = (uint32_t)(hsd->SdCard.RelCardAdd);
- pCardInfo->BlockNbr = (uint32_t)(hsd->SdCard.BlockNbr);
- pCardInfo->BlockSize = (uint32_t)(hsd->SdCard.BlockSize);
- pCardInfo->LogBlockNbr = (uint32_t)(hsd->SdCard.LogBlockNbr);
- pCardInfo->LogBlockSize = (uint32_t)(hsd->SdCard.LogBlockSize);
-
- return HAL_OK;
-}
-
-/**
- * @brief Enables wide bus operation for the requested card if supported by
- * card.
- * @param hsd: Pointer to SD handle
- * @param WideMode: Specifies the SD card wide bus mode
- * This parameter can be one of the following values:
- * @arg SDIO_BUS_WIDE_8B: 8-bit data transfer
- * @arg SDIO_BUS_WIDE_4B: 4-bit data transfer
- * @arg SDIO_BUS_WIDE_1B: 1-bit data transfer
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SD_ConfigWideBusOperation(SD_HandleTypeDef *hsd, uint32_t WideMode)
-{
- SDIO_InitTypeDef Init;
- uint32_t errorstate = HAL_SD_ERROR_NONE;
-
- /* Check the parameters */
- assert_param(IS_SDIO_BUS_WIDE(WideMode));
-
- /* Chnage Satte */
- hsd->State = HAL_SD_STATE_BUSY;
-
- if(hsd->SdCard.CardType != CARD_SECURED)
- {
- if(WideMode == SDIO_BUS_WIDE_8B)
- {
- hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
- }
- else if(WideMode == SDIO_BUS_WIDE_4B)
- {
- errorstate = SD_WideBus_Enable(hsd);
-
- hsd->ErrorCode |= errorstate;
- }
- else if(WideMode == SDIO_BUS_WIDE_1B)
- {
- errorstate = SD_WideBus_Disable(hsd);
-
- hsd->ErrorCode |= errorstate;
- }
- else
- {
- /* WideMode is not a valid argument*/
- hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
- }
- }
- else
- {
- /* MMC Card does not support this feature */
- hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
- }
-
- if(hsd->ErrorCode != HAL_SD_ERROR_NONE)
- {
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
- hsd->State = HAL_SD_STATE_READY;
- return HAL_ERROR;
- }
- else
- {
- /* Configure the SDIO peripheral */
- Init.ClockEdge = hsd->Init.ClockEdge;
- Init.ClockBypass = hsd->Init.ClockBypass;
- Init.ClockPowerSave = hsd->Init.ClockPowerSave;
- Init.BusWide = WideMode;
- Init.HardwareFlowControl = hsd->Init.HardwareFlowControl;
- Init.ClockDiv = hsd->Init.ClockDiv;
- SDIO_Init(hsd->Instance, Init);
- }
-
- /* Change State */
- hsd->State = HAL_SD_STATE_READY;
-
- return HAL_OK;
-}
-
-
-/**
- * @brief Gets the current sd card data state.
- * @param hsd: pointer to SD handle
- * @retval Card state
- */
-HAL_SD_CardStateTypeDef HAL_SD_GetCardState(SD_HandleTypeDef *hsd)
-{
- HAL_SD_CardStateTypeDef cardstate = HAL_SD_CARD_TRANSFER;
- uint32_t errorstate = HAL_SD_ERROR_NONE;
- uint32_t resp1 = 0;
-
- errorstate = SD_SendStatus(hsd, &resp1);
- if(errorstate != HAL_OK)
- {
- hsd->ErrorCode |= errorstate;
- }
-
- cardstate = (HAL_SD_CardStateTypeDef)((resp1 >> 9U) & 0x0FU);
-
- return cardstate;
-}
-
-/**
- * @brief Abort the current transfer and disable the SD.
- * @param hsd: pointer to a SD_HandleTypeDef structure that contains
- * the configuration information for SD module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SD_Abort(SD_HandleTypeDef *hsd)
-{
- HAL_SD_CardStateTypeDef CardState;
-
- /* DIsable All interrupts */
- __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
- SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
-
- /* Clear All flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
-
- if((hsd->hdmatx != NULL) || (hsd->hdmarx != NULL))
- {
- /* Disable the SD DMA request */
- hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
-
- /* Abort the SD DMA Tx Stream */
- if(hsd->hdmatx != NULL)
- {
- HAL_DMA_Abort(hsd->hdmatx);
- }
- /* Abort the SD DMA Rx Stream */
- if(hsd->hdmarx != NULL)
- {
- HAL_DMA_Abort(hsd->hdmarx);
- }
- }
-
- hsd->State = HAL_SD_STATE_READY;
- CardState = HAL_SD_GetCardState(hsd);
- if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
- {
- hsd->ErrorCode = SDMMC_CmdStopTransfer(hsd->Instance);
- }
- if(hsd->ErrorCode != HAL_SD_ERROR_NONE)
- {
- return HAL_ERROR;
- }
- return HAL_OK;
-}
-
-/**
- * @brief Abort the current transfer and disable the SD (IT mode).
- * @param hsd: pointer to a SD_HandleTypeDef structure that contains
- * the configuration information for SD module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SD_Abort_IT(SD_HandleTypeDef *hsd)
-{
- HAL_SD_CardStateTypeDef CardState;
-
- /* DIsable All interrupts */
- __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
- SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
-
- /* Clear All flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
-
- if((hsd->hdmatx != NULL) || (hsd->hdmarx != NULL))
- {
- /* Disable the SD DMA request */
- hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
-
- /* Abort the SD DMA Tx Stream */
- if(hsd->hdmatx != NULL)
- {
- hsd->hdmatx->XferAbortCallback = SD_DMATxAbort;
- if(HAL_DMA_Abort_IT(hsd->hdmatx) != HAL_OK)
- {
- hsd->hdmatx = NULL;
- }
- }
- /* Abort the SD DMA Rx Stream */
- if(hsd->hdmarx != NULL)
- {
- hsd->hdmarx->XferAbortCallback = SD_DMARxAbort;
- if(HAL_DMA_Abort_IT(hsd->hdmarx) != HAL_OK)
- {
- hsd->hdmarx = NULL;
- }
- }
- }
-
- /* No transfer ongoing on both DMA channels*/
- if((hsd->hdmatx == NULL) && (hsd->hdmarx == NULL))
- {
- CardState = HAL_SD_GetCardState(hsd);
- hsd->State = HAL_SD_STATE_READY;
- if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
- {
- hsd->ErrorCode = SDMMC_CmdStopTransfer(hsd->Instance);
- }
- if(hsd->ErrorCode != HAL_SD_ERROR_NONE)
- {
- return HAL_ERROR;
- }
- else
- {
- HAL_SD_AbortCallback(hsd);
- }
- }
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private function ----------------------------------------------------------*/
-/** @addtogroup SD_Private_Functions
- * @{
- */
-
-/**
- * @brief DMA SD transmit process complete callback
- * @param hdma: DMA handle
- * @retval None
- */
-static void SD_DMATransmitCplt(DMA_HandleTypeDef *hdma)
-{
- SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
-
- /* Enable DATAEND Interrupt */
- __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DATAEND));
-}
-
-/**
- * @brief DMA SD receive process complete callback
- * @param hdma: DMA handle
- * @retval None
- */
-static void SD_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
-{
- SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
- uint32_t errorstate = HAL_SD_ERROR_NONE;
-
- /* Send stop command in multiblock write */
- if(hsd->Context == (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_DMA))
- {
- errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- hsd->ErrorCode |= errorstate;
- HAL_SD_ErrorCallback(hsd);
- }
- }
-
- /* Disable the DMA transfer for transmit request by setting the DMAEN bit
- in the SD DCTRL register */
- hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
-
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
-
- hsd->State = HAL_SD_STATE_READY;
-
- HAL_SD_RxCpltCallback(hsd);
-}
-
-/**
- * @brief DMA SD communication error callback
- * @param hdma: DMA handle
- * @retval None
- */
-static void SD_DMAError(DMA_HandleTypeDef *hdma)
-{
- SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
- HAL_SD_CardStateTypeDef CardState;
-
- if((hsd->hdmarx->ErrorCode == HAL_DMA_ERROR_TE) || (hsd->hdmatx->ErrorCode == HAL_DMA_ERROR_TE))
- {
- /* Clear All flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
-
- /* Disable All interrupts */
- __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
- SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
-
- hsd->ErrorCode |= HAL_SD_ERROR_DMA;
- CardState = HAL_SD_GetCardState(hsd);
- if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
- {
- hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance);
- }
-
- hsd->State= HAL_SD_STATE_READY;
- }
-
- HAL_SD_ErrorCallback(hsd);
-}
-
-/**
- * @brief DMA SD Tx Abort callback
- * @param hdma: DMA handle
- * @retval None
- */
-static void SD_DMATxAbort(DMA_HandleTypeDef *hdma)
-{
- SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
- HAL_SD_CardStateTypeDef CardState;
-
- if(hsd->hdmatx != NULL)
- {
- hsd->hdmatx = NULL;
- }
-
- /* All DMA channels are aborted */
- if(hsd->hdmarx == NULL)
- {
- CardState = HAL_SD_GetCardState(hsd);
- hsd->ErrorCode = HAL_SD_ERROR_NONE;
- hsd->State = HAL_SD_STATE_READY;
- if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
- {
- hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance);
-
- if(hsd->ErrorCode != HAL_SD_ERROR_NONE)
- {
- HAL_SD_AbortCallback(hsd);
- }
- else
- {
- HAL_SD_ErrorCallback(hsd);
- }
- }
- }
-}
-
-/**
- * @brief DMA SD Rx Abort callback
- * @param hdma: DMA handle
- * @retval None
- */
-static void SD_DMARxAbort(DMA_HandleTypeDef *hdma)
-{
- SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
- HAL_SD_CardStateTypeDef CardState;
-
- if(hsd->hdmarx != NULL)
- {
- hsd->hdmarx = NULL;
- }
-
- /* All DMA channels are aborted */
- if(hsd->hdmatx == NULL)
- {
- CardState = HAL_SD_GetCardState(hsd);
- hsd->ErrorCode = HAL_SD_ERROR_NONE;
- hsd->State = HAL_SD_STATE_READY;
- if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
- {
- hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance);
-
- if(hsd->ErrorCode != HAL_SD_ERROR_NONE)
- {
- HAL_SD_AbortCallback(hsd);
- }
- else
- {
- HAL_SD_ErrorCallback(hsd);
- }
- }
- }
-}
-
-
-/**
- * @brief Initializes the sd card.
- * @param hsd: Pointer to SD handle
- * @retval SD Card error state
- */
-static uint32_t SD_InitCard(SD_HandleTypeDef *hsd)
-{
- HAL_SD_CardCSDTypeDef CSD;
- uint32_t errorstate = HAL_SD_ERROR_NONE;
- uint16_t sd_rca = 1U;
-
- /* Check the power State */
- if(SDIO_GetPowerState(hsd->Instance) == 0U)
- {
- /* Power off */
- return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;
- }
-
- if(hsd->SdCard.CardType != CARD_SECURED)
- {
- /* Send CMD2 ALL_SEND_CID */
- errorstate = SDMMC_CmdSendCID(hsd->Instance);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- return errorstate;
- }
- else
- {
- /* Get Card identification number data */
- hsd->CID[0U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
- hsd->CID[1U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP2);
- hsd->CID[2U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP3);
- hsd->CID[3U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP4);
- }
- }
-
- if(hsd->SdCard.CardType != CARD_SECURED)
- {
- /* Send CMD3 SET_REL_ADDR with argument 0 */
- /* SD Card publishes its RCA. */
- errorstate = SDMMC_CmdSetRelAdd(hsd->Instance, &sd_rca);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- return errorstate;
- }
- }
- if(hsd->SdCard.CardType != CARD_SECURED)
- {
- /* Get the SD card RCA */
- hsd->SdCard.RelCardAdd = sd_rca;
-
- /* Send CMD9 SEND_CSD with argument as card's RCA */
- errorstate = SDMMC_CmdSendCSD(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- return errorstate;
- }
- else
- {
- /* Get Card Specific Data */
- hsd->CSD[0U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
- hsd->CSD[1U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP2);
- hsd->CSD[2U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP3);
- hsd->CSD[3U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP4);
- }
- }
-
- /* Get the Card Class */
- hsd->SdCard.Class = (SDIO_GetResponse(hsd->Instance, SDIO_RESP2) >> 20U);
-
- /* Get CSD parameters */
- HAL_SD_GetCardCSD(hsd, &CSD);
-
- /* Select the Card */
- errorstate = SDMMC_CmdSelDesel(hsd->Instance, (uint32_t)(((uint32_t)hsd->SdCard.RelCardAdd) << 16U));
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- return errorstate;
- }
-
- /* Configure SDIO peripheral interface */
- SDIO_Init(hsd->Instance, hsd->Init);
-
- /* All cards are initialized */
- return HAL_SD_ERROR_NONE;
-}
-
-/**
- * @brief Enquires cards about their operating voltage and configures clock
- * controls and stores SD information that will be needed in future
- * in the SD handle.
- * @param hsd: Pointer to SD handle
- * @retval error state
- */
-static uint32_t SD_PowerON(SD_HandleTypeDef *hsd)
-{
- __IO uint32_t count = 0U;
- uint32_t response = 0U, validvoltage = 0U;
- uint32_t errorstate = HAL_SD_ERROR_NONE;
-
- /* CMD0: GO_IDLE_STATE */
- errorstate = SDMMC_CmdGoIdleState(hsd->Instance);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- return errorstate;
- }
-
- /* CMD8: SEND_IF_COND: Command available only on V2.0 cards */
- errorstate = SDMMC_CmdOperCond(hsd->Instance);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- hsd->SdCard.CardVersion = CARD_V1_X;
-
- /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */
- while(validvoltage == 0U)
- {
- if(count++ == SDMMC_MAX_VOLT_TRIAL)
- {
- return HAL_SD_ERROR_INVALID_VOLTRANGE;
- }
-
- /* SEND CMD55 APP_CMD with RCA as 0 */
- errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0U);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- return HAL_SD_ERROR_UNSUPPORTED_FEATURE;
- }
-
- /* Send CMD41 */
- errorstate = SDMMC_CmdAppOperCommand(hsd->Instance, SDMMC_STD_CAPACITY);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- return HAL_SD_ERROR_UNSUPPORTED_FEATURE;
- }
-
- /* Get command response */
- response = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
-
- /* Get operating voltage*/
- validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
- }
- /* Card type is SDSC */
- hsd->SdCard.CardType = CARD_SDSC;
- }
- else
- {
- hsd->SdCard.CardVersion = CARD_V2_X;
-
- /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */
- while(validvoltage == 0U)
- {
- if(count++ == SDMMC_MAX_VOLT_TRIAL)
- {
- return HAL_SD_ERROR_INVALID_VOLTRANGE;
- }
-
- /* SEND CMD55 APP_CMD with RCA as 0 */
- errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0U);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- return errorstate;
- }
-
- /* Send CMD41 */
- errorstate = SDMMC_CmdAppOperCommand(hsd->Instance, SDMMC_HIGH_CAPACITY);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- return errorstate;
- }
-
- /* Get command response */
- response = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
-
- /* Get operating voltage*/
- validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
- }
-
- if((response & SDMMC_HIGH_CAPACITY) == SDMMC_HIGH_CAPACITY) /* (response &= SD_HIGH_CAPACITY) */
- {
- hsd->SdCard.CardType = CARD_SDHC_SDXC;
- }
- else
- {
- hsd->SdCard.CardType = CARD_SDSC;
- }
- }
-
- return HAL_SD_ERROR_NONE;
-}
-
-/**
- * @brief Turns the SDIO output signals off.
- * @param hsd: Pointer to SD handle
- * @retval HAL status
- */
-static HAL_StatusTypeDef SD_PowerOFF(SD_HandleTypeDef *hsd)
-{
- /* Set Power State to OFF */
- SDIO_PowerState_OFF(hsd->Instance);
-
- return HAL_OK;
-}
-
-/**
- * @brief Send Status info command.
- * @param hsd: pointer to SD handle
- * @param pSDstatus: Pointer to the buffer that will contain the SD card status
- * SD Status register)
- * @retval error state
- */
-static uint32_t SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus)
-{
- SDIO_DataInitTypeDef config;
- uint32_t errorstate = HAL_SD_ERROR_NONE;
- uint32_t tickstart = HAL_GetTick();
- uint32_t count = 0U;
-
- /* Check SD response */
- if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
- {
- return HAL_SD_ERROR_LOCK_UNLOCK_FAILED;
- }
-
- /* Set block size for card if it is not equal to current block size for card */
- errorstate = SDMMC_CmdBlockLength(hsd->Instance, 64U);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- hsd->ErrorCode |= HAL_SD_ERROR_NONE;
- return errorstate;
- }
-
- /* Send CMD55 */
- errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- hsd->ErrorCode |= HAL_SD_ERROR_NONE;
- return errorstate;
- }
-
- /* Configure the SD DPSM (Data Path State Machine) */
- config.DataTimeOut = SDMMC_DATATIMEOUT;
- config.DataLength = 64U;
- config.DataBlockSize = SDIO_DATABLOCK_SIZE_64B;
- config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
- config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
- config.DPSM = SDIO_DPSM_ENABLE;
- SDIO_ConfigData(hsd->Instance, &config);
-
- /* Send ACMD13 (SD_APP_STAUS) with argument as card's RCA */
- errorstate = SDMMC_CmdStatusRegister(hsd->Instance);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- hsd->ErrorCode |= HAL_SD_ERROR_NONE;
- return errorstate;
- }
-
- /* Get status data */
- while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND))
- {
- if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF))
- {
- for(count = 0U; count < 8U; count++)
- {
- *(pSDstatus + count) = SDIO_ReadFIFO(hsd->Instance);
- }
-
- pSDstatus += 8U;
- }
-
- if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT)
- {
- return HAL_SD_ERROR_TIMEOUT;
- }
- }
-
- if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
- {
- return HAL_SD_ERROR_DATA_TIMEOUT;
- }
- else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
- {
- return HAL_SD_ERROR_DATA_CRC_FAIL;
- }
- else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))
- {
- return HAL_SD_ERROR_RX_OVERRUN;
- }
-
- while ((__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXDAVL)))
- {
- *pSDstatus = SDIO_ReadFIFO(hsd->Instance);
- pSDstatus++;
-
- if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT)
- {
- return HAL_SD_ERROR_TIMEOUT;
- }
- }
-
- /* Clear all the static status flags*/
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
-
- return HAL_SD_ERROR_NONE;
-}
-
-/**
- * @brief Returns the current card's status.
- * @param hsd: Pointer to SD handle
- * @param pCardStatus: pointer to the buffer that will contain the SD card
- * status (Card Status register)
- * @retval error state
- */
-static uint32_t SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus)
-{
- uint32_t errorstate = HAL_SD_ERROR_NONE;
-
- if(pCardStatus == NULL)
- {
- return HAL_SD_ERROR_PARAM;
- }
-
- /* Send Status command */
- errorstate = SDMMC_CmdSendStatus(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
- if(errorstate != HAL_OK)
- {
- return errorstate;
- }
-
- /* Get SD card status */
- *pCardStatus = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
-
- return HAL_SD_ERROR_NONE;
-}
-
-/**
- * @brief Enables the SDIO wide bus mode.
- * @param hsd: pointer to SD handle
- * @retval error state
- */
-static uint32_t SD_WideBus_Enable(SD_HandleTypeDef *hsd)
-{
- uint32_t scr[2U] = {0U, 0U};
- uint32_t errorstate = HAL_SD_ERROR_NONE;
-
- if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
- {
- return HAL_SD_ERROR_LOCK_UNLOCK_FAILED;
- }
-
- /* Get SCR Register */
- errorstate = SD_FindSCR(hsd, scr);
- if(errorstate != HAL_OK)
- {
- return errorstate;
- }
-
- /* If requested card supports wide bus operation */
- if((scr[1U] & SDMMC_WIDE_BUS_SUPPORT) != SDMMC_ALLZERO)
- {
- /* Send CMD55 APP_CMD with argument as card's RCA.*/
- errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
- if(errorstate != HAL_OK)
- {
- return errorstate;
- }
-
- /* Send ACMD6 APP_CMD with argument as 2 for wide bus mode */
- errorstate = SDMMC_CmdBusWidth(hsd->Instance, 2U);
- if(errorstate != HAL_OK)
- {
- return errorstate;
- }
-
- return HAL_SD_ERROR_NONE;
- }
- else
- {
- return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;
- }
-}
-
-/**
- * @brief Disables the SDIO wide bus mode.
- * @param hsd: Pointer to SD handle
- * @retval error state
- */
-static uint32_t SD_WideBus_Disable(SD_HandleTypeDef *hsd)
-{
- uint32_t scr[2U] = {0U, 0U};
- uint32_t errorstate = HAL_SD_ERROR_NONE;
-
- if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
- {
- return HAL_SD_ERROR_LOCK_UNLOCK_FAILED;
- }
-
- /* Get SCR Register */
- errorstate = SD_FindSCR(hsd, scr);
- if(errorstate != HAL_OK)
- {
- return errorstate;
- }
-
- /* If requested card supports 1 bit mode operation */
- if((scr[1U] & SDMMC_SINGLE_BUS_SUPPORT) != SDMMC_ALLZERO)
- {
- /* Send CMD55 APP_CMD with argument as card's RCA */
- errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
- if(errorstate != HAL_OK)
- {
- return errorstate;
- }
-
- /* Send ACMD6 APP_CMD with argument as 0 for single bus mode */
- errorstate = SDMMC_CmdBusWidth(hsd->Instance, 0U);
- if(errorstate != HAL_OK)
- {
- return errorstate;
- }
-
- return HAL_SD_ERROR_NONE;
- }
- else
- {
- return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;
- }
-}
-
-
-/**
- * @brief Finds the SD card SCR register value.
- * @param hsd: Pointer to SD handle
- * @param pSCR: pointer to the buffer that will contain the SCR value
- * @retval error state
- */
-static uint32_t SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR)
-{
- SDIO_DataInitTypeDef config;
- uint32_t errorstate = HAL_SD_ERROR_NONE;
- uint32_t tickstart = HAL_GetTick();
- uint32_t index = 0U;
- uint32_t tempscr[2U] = {0U, 0U};
-
- /* Set Block Size To 8 Bytes */
- errorstate = SDMMC_CmdBlockLength(hsd->Instance, 8U);
- if(errorstate != HAL_OK)
- {
- return errorstate;
- }
-
- /* Send CMD55 APP_CMD with argument as card's RCA */
- errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)((hsd->SdCard.RelCardAdd) << 16U));
- if(errorstate != HAL_OK)
- {
- return errorstate;
- }
-
- config.DataTimeOut = SDMMC_DATATIMEOUT;
- config.DataLength = 8U;
- config.DataBlockSize = SDIO_DATABLOCK_SIZE_8B;
- config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
- config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
- config.DPSM = SDIO_DPSM_ENABLE;
- SDIO_ConfigData(hsd->Instance, &config);
-
- /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */
- errorstate = SDMMC_CmdSendSCR(hsd->Instance);
- if(errorstate != HAL_OK)
- {
- return errorstate;
- }
-
- while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND))
- {
- if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXDAVL))
- {
- *(tempscr + index) = SDIO_ReadFIFO(hsd->Instance);
- index++;
- }
-
- if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT)
- {
- return HAL_SD_ERROR_TIMEOUT;
- }
- }
-
- if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
- {
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT);
-
- return HAL_SD_ERROR_DATA_TIMEOUT;
- }
- else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
- {
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL);
-
- return HAL_SD_ERROR_DATA_CRC_FAIL;
- }
- else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))
- {
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR);
-
- return HAL_SD_ERROR_RX_OVERRUN;
- }
- else
- {
- /* No error flag set */
- /* Clear all the static flags */
- __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
-
- *(pSCR + 1U) = ((tempscr[0U] & SDMMC_0TO7BITS) << 24U) | ((tempscr[0U] & SDMMC_8TO15BITS) << 8U) |\
- ((tempscr[0U] & SDMMC_16TO23BITS) >> 8U) | ((tempscr[0U] & SDMMC_24TO31BITS) >> 24U);
-
- *(pSCR) = ((tempscr[1U] & SDMMC_0TO7BITS) << 24U) | ((tempscr[1U] & SDMMC_8TO15BITS) << 8U) |\
- ((tempscr[1U] & SDMMC_16TO23BITS) >> 8U) | ((tempscr[1U] & SDMMC_24TO31BITS) >> 24U);
- }
-
- return HAL_SD_ERROR_NONE;
-}
-
-/**
- * @brief Wrap up reading in non-blocking mode.
- * @param hsd: pointer to a SD_HandleTypeDef structure that contains
- * the configuration information.
- * @retval HAL status
- */
-static HAL_StatusTypeDef SD_Read_IT(SD_HandleTypeDef *hsd)
-{
- uint32_t count = 0U;
- uint32_t* tmp;
-
- tmp = (uint32_t*)hsd->pRxBuffPtr;
-
- /* Read data from SDIO Rx FIFO */
- for(count = 0U; count < 8U; count++)
- {
- *(tmp + count) = SDIO_ReadFIFO(hsd->Instance);
- }
-
- hsd->pRxBuffPtr += 8U;
-
- return HAL_OK;
-}
-
-/**
- * @brief Wrap up writing in non-blocking mode.
- * @param hsd: pointer to a SD_HandleTypeDef structure that contains
- * the configuration information.
- * @retval HAL status
- */
-static HAL_StatusTypeDef SD_Write_IT(SD_HandleTypeDef *hsd)
-{
- uint32_t count = 0U;
- uint32_t* tmp;
-
- tmp = (uint32_t*)hsd->pTxBuffPtr;
-
- /* Write data to SDIO Tx FIFO */
- for(count = 0U; count < 8U; count++)
- {
- SDIO_WriteFIFO(hsd->Instance, (tmp + count));
- }
-
- hsd->pTxBuffPtr += 8U;
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-#endif /* STM32F103xE || STM32F103xG */
-
-#endif /* HAL_SD_MODULE_ENABLED */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_smartcard.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_smartcard.c
deleted file mode 100644
index 12369ad..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_smartcard.c
+++ /dev/null
@@ -1,1900 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_smartcard.c
- * @author MCD Application Team
- * @brief SMARTCARD HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the SMARTCARD peripheral:
- * + Initialization and de-initialization functions
- * + IO operation functions
- * + Peripheral Control functions
- * + Peripheral State and Errors functions
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- The SMARTCARD HAL driver can be used as follows:
-
- (#) Declare a SMARTCARD_HandleTypeDef handle structure.
- (#) Initialize the SMARTCARD low level resources by implementing the HAL_SMARTCARD_MspInit() API:
- (##) Enable the USARTx interface clock.
- (##) SMARTCARD pins configuration:
- (+++) Enable the clock for the SMARTCARD GPIOs.
- (+++) Configure the SMARTCARD pins as alternate function pull-up.
- (##) NVIC configuration if you need to use interrupt process (HAL_SMARTCARD_Transmit_IT()
- and HAL_SMARTCARD_Receive_IT() APIs):
- (+++) Configure the USARTx interrupt priority.
- (+++) Enable the NVIC USART IRQ handle.
- (##) DMA Configuration if you need to use DMA process (HAL_SMARTCARD_Transmit_DMA()
- and HAL_SMARTCARD_Receive_DMA() APIs):
- (+++) Declare a DMA handle structure for the Tx/Rx channel.
- (+++) Enable the DMAx interface clock.
- (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
- (+++) Configure the DMA Tx/Rx channel.
- (+++) Associate the initialized DMA handle to the SMARTCARD DMA Tx/Rx handle.
- (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
- (+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
- (used for last byte sending completion detection in DMA non circular mode)
-
- (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
- flow control and Mode(Receiver/Transmitter) in the SMARTCARD Init structure.
-
- (#) Initialize the SMARTCARD registers by calling the HAL_SMARTCARD_Init() API:
- (++) These APIs configure also the low level Hardware GPIO, CLOCK, CORTEX...etc)
- by calling the customized HAL_SMARTCARD_MspInit() API.
- [..]
- (@)The specific SMARTCARD interrupts (Transmission complete interrupt,
- RXNE interrupt and Error Interrupts) will be managed using the macros
- __HAL_SMARTCARD_ENABLE_IT() and __HAL_SMARTCARD_DISABLE_IT() inside the transmit and receive process.
-
- [..]
- Three operation modes are available within this driver:
-
- *** Polling mode IO operation ***
- =================================
- [..]
- (+) Send an amount of data in blocking mode using HAL_SMARTCARD_Transmit()
- (+) Receive an amount of data in blocking mode using HAL_SMARTCARD_Receive()
- *** Interrupt mode IO operation ***
- ===================================
- [..]
- (+) Send an amount of data in non blocking mode using HAL_SMARTCARD_Transmit_IT()
- (+) At transmission end of transfer HAL_SMARTCARD_TxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_SMARTCARD_TxCpltCallback
- (+) Receive an amount of data in non blocking mode using HAL_SMARTCARD_Receive_IT()
- (+) At reception end of transfer HAL_SMARTCARD_RxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_SMARTCARD_RxCpltCallback
- (+) In case of transfer Error, HAL_SMARTCARD_ErrorCallback() function is executed and user can
- add his own code by customization of function pointer HAL_SMARTCARD_ErrorCallback
-
- *** DMA mode IO operation ***
- ==============================
- [..]
- (+) Send an amount of data in non blocking mode (DMA) using HAL_SMARTCARD_Transmit_DMA()
- (+) At transmission end of transfer HAL_SMARTCARD_TxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_SMARTCARD_TxCpltCallback
- (+) Receive an amount of data in non blocking mode (DMA) using HAL_SMARTCARD_Receive_DMA()
- (+) At reception end of transfer HAL_SMARTCARD_RxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_SMARTCARD_RxCpltCallback
- (+) In case of transfer Error, HAL_SMARTCARD_ErrorCallback() function is executed and user can
- add his own code by customization of function pointer HAL_SMARTCARD_ErrorCallback
-
- *** SMARTCARD HAL driver macros list ***
- =============================================
- [..]
- Below the list of most used macros in SMARTCARD HAL driver.
-
- (+) __HAL_SMARTCARD_ENABLE: Enable the SMARTCARD peripheral
- (+) __HAL_SMARTCARD_DISABLE: Disable the SMARTCARD peripheral
- (+) __HAL_SMARTCARD_GET_FLAG : Check whether the specified SMARTCARD flag is set or not
- (+) __HAL_SMARTCARD_CLEAR_FLAG : Clear the specified SMARTCARD pending flag
- (+) __HAL_SMARTCARD_ENABLE_IT: Enable the specified SMARTCARD interrupt
- (+) __HAL_SMARTCARD_DISABLE_IT: Disable the specified SMARTCARD interrupt
-
- [..]
- (@) You can refer to the SMARTCARD HAL driver header file for more useful macros
-
- @endverbatim
- [..]
- (@) Additionnal remark: If the parity is enabled, then the MSB bit of the data written
- in the data register is transmitted but is changed by the parity bit.
- Depending on the frame length defined by the M bit (8-bits or 9-bits),
- the possible SMARTCARD frame formats are as listed in the following table:
- +-------------------------------------------------------------+
- | M bit | PCE bit | SMARTCARD frame |
- |---------------------|---------------------------------------|
- | 1 | 1 | | SB | 8 bit data | PB | STB | |
- +-------------------------------------------------------------+
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup SMARTCARD SMARTCARD
- * @brief HAL SMARTCARD module driver
- * @{
- */
-#ifdef HAL_SMARTCARD_MODULE_ENABLED
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @addtogroup SMARTCARD_Private_Constants
- * @{
- */
-/**
- * @}
- */
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @addtogroup SMARTCARD_Private_Functions
- * @{
- */
-static void SMARTCARD_EndTxTransfer(SMARTCARD_HandleTypeDef *hsc);
-static void SMARTCARD_EndRxTransfer(SMARTCARD_HandleTypeDef *hsc);
-static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc);
-static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc);
-static HAL_StatusTypeDef SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard);
-static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc);
-static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma);
-static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
-static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma);
-static void SMARTCARD_DMAAbortOnError(DMA_HandleTypeDef *hdma);
-static void SMARTCARD_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
-static void SMARTCARD_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
-static void SMARTCARD_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
-static void SMARTCARD_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
-static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout);
-/**
- * @}
- */
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup SMARTCARD_Exported_Functions SMARTCARD Exported Functions
- * @{
- */
-
-/** @defgroup SMARTCARD_Exported_Functions_Group1 SmartCard Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
- ==============================================================================
- ##### Initialization and Configuration functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to initialize the USART
- in Smartcard mode.
- [..]
- The Smartcard interface is designed to support asynchronous protocol Smartcards as
- defined in the ISO 7816-3 standard.
- [..]
- The USART can provide a clock to the smartcard through the SCLK output.
- In smartcard mode, SCLK is not associated to the communication but is simply derived
- from the internal peripheral input clock through a 5-bit prescaler.
- [..]
- (+) For the Smartcard mode only these parameters can be configured:
- (++) Baud Rate
- (++) Word Length => Should be 9 bits (8 bits + parity)
- (++) Stop Bit
- (++) Parity: => Should be enabled
- (++) USART polarity
- (++) USART phase
- (++) USART LastBit
- (++) Receiver/transmitter modes
- (++) Prescaler
- (++) GuardTime
- (++) NACKState: The Smartcard NACK state
-
- (+) Recommended SmartCard interface configuration to get the Answer to Reset from the Card:
- (++) Word Length = 9 Bits
- (++) 1.5 Stop Bit
- (++) Even parity
- (++) BaudRate = 12096 baud
- (++) Tx and Rx enabled
- [..]
- Please refer to the ISO 7816-3 specification for more details.
-
- [..]
- (@) It is also possible to choose 0.5 stop bit for receiving but it is recommended
- to use 1.5 stop bits for both transmitting and receiving to avoid switching
- between the two configurations.
- [..]
- The HAL_SMARTCARD_Init() function follows the USART SmartCard configuration
- procedure (details for the procedure are available in reference manual (RM0329)).
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the SmartCard mode according to the specified
- * parameters in the SMARTCARD_InitTypeDef and create the associated handle.
- * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for SMARTCARD module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc)
-{
- /* Check the SMARTCARD handle allocation */
- if (hsc == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
-
-
- if (hsc->gState == HAL_SMARTCARD_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- hsc->Lock = HAL_UNLOCKED;
-
- /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
- HAL_SMARTCARD_MspInit(hsc);
- }
-
- hsc->gState = HAL_SMARTCARD_STATE_BUSY;
-
- /* Set the Prescaler */
- MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_PSC, hsc->Init.Prescaler);
-
- /* Set the Guard Time */
- MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_GT, ((hsc->Init.GuardTime) << 8U));
-
- /* Set the Smartcard Communication parameters */
- SMARTCARD_SetConfig(hsc);
-
- /* In SmartCard mode, the following bits must be kept cleared:
- - LINEN bit in the USART_CR2 register
- - HDSEL and IREN bits in the USART_CR3 register.*/
- CLEAR_BIT(hsc->Instance->CR2, USART_CR2_LINEN);
- CLEAR_BIT(hsc->Instance->CR3, (USART_CR3_IREN | USART_CR3_HDSEL));
-
- /* Enable the SMARTCARD Parity Error Interrupt */
- SET_BIT(hsc->Instance->CR1, USART_CR1_PEIE);
-
- /* Enable the SMARTCARD Framing Error Interrupt */
- SET_BIT(hsc->Instance->CR3, USART_CR3_EIE);
-
- /* Enable the Peripheral */
- __HAL_SMARTCARD_ENABLE(hsc);
-
- /* Configure the Smartcard NACK state */
- MODIFY_REG(hsc->Instance->CR3, USART_CR3_NACK, hsc->Init.NACKState);
-
- /* Enable the SC mode by setting the SCEN bit in the CR3 register */
- hsc->Instance->CR3 |= (USART_CR3_SCEN);
-
- /* Initialize the SMARTCARD state*/
- hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
- hsc->gState = HAL_SMARTCARD_STATE_READY;
- hsc->RxState = HAL_SMARTCARD_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief DeInitializes the USART SmartCard peripheral
- * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for SMARTCARD module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef *hsc)
-{
- /* Check the SMARTCARD handle allocation */
- if (hsc == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
-
- hsc->gState = HAL_SMARTCARD_STATE_BUSY;
-
- /* DeInit the low level hardware */
- HAL_SMARTCARD_MspDeInit(hsc);
-
- hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
- hsc->gState = HAL_SMARTCARD_STATE_RESET;
- hsc->RxState = HAL_SMARTCARD_STATE_RESET;
-
- /* Release Lock */
- __HAL_UNLOCK(hsc);
-
- return HAL_OK;
-}
-
-/**
- * @brief SMARTCARD MSP Init.
- * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for SMARTCARD module.
- * @retval None
- */
-__weak void HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef *hsc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hsc);
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_SMARTCARD_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief SMARTCARD MSP DeInit
- * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for SMARTCARD module.
- * @retval None
- */
-__weak void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hsc);
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_SMARTCARD_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup SMARTCARD_Exported_Functions_Group2 IO operation functions
- * @brief SMARTCARD Transmit and Receive functions
- *
-@verbatim
- ===============================================================================
- ##### IO operation functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to manage the SMARTCARD data transfers.
-
- [..]
- (#) Smartcard is a single wire half duplex communication protocol.
- The Smartcard interface is designed to support asynchronous protocol Smartcards as
- defined in the ISO 7816-3 standard.
- (#) The USART should be configured as:
- (++) 8 bits plus parity: where M=1 and PCE=1 in the USART_CR1 register
- (++) 1.5 stop bits when transmitting and receiving: where STOP=11 in the USART_CR2 register.
-
- (#) There are two modes of transfer:
- (++) Blocking mode: The communication is performed in polling mode.
- The HAL status of all data processing is returned by the same function
- after finishing transfer.
- (++) Non Blocking mode: The communication is performed using Interrupts
- or DMA, These APIs return the HAL status.
- The end of the data processing will be indicated through the
- dedicated SMARTCARD IRQ when using Interrupt mode or the DMA IRQ when
- using DMA mode.
- The HAL_SMARTCARD_TxCpltCallback(), HAL_SMARTCARD_RxCpltCallback() user callbacks
- will be executed respectively at the end of the Transmit or Receive process
- The HAL_SMARTCARD_ErrorCallback() user callback will be executed when a communication error is detected
-
- (#) Blocking mode APIs are :
- (++) HAL_SMARTCARD_Transmit()
- (++) HAL_SMARTCARD_Receive()
-
- (#) Non Blocking mode APIs with Interrupt are :
- (++) HAL_SMARTCARD_Transmit_IT()
- (++) HAL_SMARTCARD_Receive_IT()
- (++) HAL_SMARTCARD_IRQHandler()
-
- (#) Non Blocking mode functions with DMA are :
- (++) HAL_SMARTCARD_Transmit_DMA()
- (++) HAL_SMARTCARD_Receive_DMA()
-
- (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
- (++) HAL_SMARTCARD_TxCpltCallback()
- (++) HAL_SMARTCARD_RxCpltCallback()
- (++) HAL_SMARTCARD_ErrorCallback()
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Send an amount of data in blocking mode
- * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for SMARTCARD module.
- * @param pData: pointer to data buffer
- * @param Size: amount of data to be sent
- * @param Timeout: Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout)
-{
- uint32_t tickstart = 0U;
-
- if (hsc->gState == HAL_SMARTCARD_STATE_READY)
- {
- if ((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hsc);
-
- hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
- hsc->gState = HAL_SMARTCARD_STATE_BUSY_TX;
-
- /* Init tickstart for timeout managment */
- tickstart = HAL_GetTick();
-
- hsc->TxXferSize = Size;
- hsc->TxXferCount = Size;
- while (hsc->TxXferCount > 0U)
- {
- hsc->TxXferCount--;
- if (SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- hsc->Instance->DR = *(uint8_t *) pData;
- pData += 1U;
- }
-
- if (SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
-
- /* At end of Tx process, restore hsc->gState to Ready */
- hsc->gState = HAL_SMARTCARD_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hsc);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receive an amount of data in blocking mode
- * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for SMARTCARD module.
- * @param pData: pointer to data buffer
- * @param Size: amount of data to be received
- * @param Timeout: Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout)
-{
- uint32_t tickstart = 0U;
-
- if (hsc->RxState == HAL_SMARTCARD_STATE_READY)
- {
- if ((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hsc);
-
- hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
- hsc->RxState = HAL_SMARTCARD_STATE_BUSY_RX;
-
- /* Init tickstart for timeout managment */
- tickstart = HAL_GetTick();
-
- hsc->RxXferSize = Size;
- hsc->RxXferCount = Size;
-
- /* Check the remain data to be received */
- while (hsc->RxXferCount > 0U)
- {
- hsc->RxXferCount--;
- if (SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- *(uint8_t *) pData = (uint8_t)hsc->Instance->DR;
- pData += 1U;
- }
-
- /* At end of Rx process, restore hsc->RxState to Ready */
- hsc->RxState = HAL_SMARTCARD_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hsc);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Send an amount of data in non blocking mode
- * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for SMARTCARD module.
- * @param pData: pointer to data buffer
- * @param Size: amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
-{
- /* Check that a Tx process is not already ongoing */
- if (hsc->gState == HAL_SMARTCARD_STATE_READY)
- {
- if ((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
- /* Process Locked */
- __HAL_LOCK(hsc);
-
- hsc->pTxBuffPtr = pData;
- hsc->TxXferSize = Size;
- hsc->TxXferCount = Size;
-
- hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
- hsc->gState = HAL_SMARTCARD_STATE_BUSY_TX;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hsc);
-
- /* Enable the SMARTCARD Parity Error Interrupt */
- SET_BIT(hsc->Instance->CR1, USART_CR1_PEIE);
-
- /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
-
- /* Enable the SMARTCARD Transmit data register empty Interrupt */
- SET_BIT(hsc->Instance->CR1, USART_CR1_TXEIE);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receive an amount of data in non blocking mode
- * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for SMARTCARD module.
- * @param pData: pointer to data buffer
- * @param Size: amount of data to be received
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
-{
- /* Check that a Rx process is not already ongoing */
- if (hsc->RxState == HAL_SMARTCARD_STATE_READY)
- {
- if ((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hsc);
-
- hsc->pRxBuffPtr = pData;
- hsc->RxXferSize = Size;
- hsc->RxXferCount = Size;
-
- hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
- hsc->RxState = HAL_SMARTCARD_STATE_BUSY_RX;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hsc);
-
- /* Enable the SMARTCARD Parity Error and Data Register not empty Interrupts */
- SET_BIT(hsc->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
-
- /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
- SET_BIT(hsc->Instance->CR3, USART_CR3_EIE);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Send an amount of data in non blocking mode
- * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for SMARTCARD module.
- * @param pData: pointer to data buffer
- * @param Size: amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
-{
- uint32_t *tmp;
-
- /* Check that a Tx process is not already ongoing */
- if (hsc->gState == HAL_SMARTCARD_STATE_READY)
- {
- if ((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hsc);
-
- hsc->pTxBuffPtr = pData;
- hsc->TxXferSize = Size;
- hsc->TxXferCount = Size;
-
- hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
- hsc->gState = HAL_SMARTCARD_STATE_BUSY_TX;
-
- /* Set the SMARTCARD DMA transfer complete callback */
- hsc->hdmatx->XferCpltCallback = SMARTCARD_DMATransmitCplt;
-
- /* Set the DMA error callback */
- hsc->hdmatx->XferErrorCallback = SMARTCARD_DMAError;
-
- /* Set the DMA abort callback */
- hsc->hdmatx->XferAbortCallback = NULL;
-
- /* Enable the SMARTCARD transmit DMA Channel */
- tmp = (uint32_t *)&pData;
- HAL_DMA_Start_IT(hsc->hdmatx, *(uint32_t *)tmp, (uint32_t)&hsc->Instance->DR, Size);
-
- /* Clear the TC flag in the SR register by writing 0 to it */
- __HAL_SMARTCARD_CLEAR_FLAG(hsc, SMARTCARD_FLAG_TC);
-
- /* Process Unlocked */
- __HAL_UNLOCK(hsc);
-
- /* Enable the DMA transfer for transmit request by setting the DMAT bit
- in the SMARTCARD CR3 register */
- SET_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receive an amount of data in non blocking mode
- * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for SMARTCARD module.
- * @param pData: pointer to data buffer
- * @param Size: amount of data to be received
- * @note When the SMARTCARD parity is enabled (PCE = 1) the data received contain the parity bit.s
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
-{
- uint32_t *tmp;
-
- /* Check that a Rx process is not already ongoing */
- if (hsc->RxState == HAL_SMARTCARD_STATE_READY)
- {
- if ((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hsc);
-
- hsc->pRxBuffPtr = pData;
- hsc->RxXferSize = Size;
-
- hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
- hsc->RxState = HAL_SMARTCARD_STATE_BUSY_RX;
-
- /* Set the SMARTCARD DMA transfer complete callback */
- hsc->hdmarx->XferCpltCallback = SMARTCARD_DMAReceiveCplt;
-
- /* Set the DMA error callback */
- hsc->hdmarx->XferErrorCallback = SMARTCARD_DMAError;
-
- /* Set the DMA abort callback */
- hsc->hdmatx->XferAbortCallback = NULL;
-
- /* Enable the DMA Channel */
- tmp = (uint32_t *)&pData;
- HAL_DMA_Start_IT(hsc->hdmarx, (uint32_t)&hsc->Instance->DR, *(uint32_t *)tmp, Size);
-
- /* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */
- __HAL_SMARTCARD_CLEAR_OREFLAG(hsc);
-
- /* Process Unlocked */
- __HAL_UNLOCK(hsc);
-
- /* Enable the SMARTCARD Parity Error Interrupt */
- SET_BIT(hsc->Instance->CR1, USART_CR1_PEIE);
-
- /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
- SET_BIT(hsc->Instance->CR3, USART_CR3_EIE);
-
- /* Enable the DMA transfer for the receiver request by setting the DMAR bit
- in the SMARTCARD CR3 register */
- SET_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Abort ongoing transfers (blocking mode).
- * @param hsc SMARTCARD handle.
- * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
- * - Set handle State to READY
- * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_SMARTCARD_Abort(SMARTCARD_HandleTypeDef *hsc)
-{
- /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
-
- /* Disable the SMARTCARD DMA Tx request if enabled */
- if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT))
- {
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
-
- /* Abort the SMARTCARD DMA Tx channel: use blocking DMA Abort API (no callback) */
- if (hsc->hdmatx != NULL)
- {
- /* Set the SMARTCARD DMA Abort callback to Null.
- No call back execution at end of DMA abort procedure */
- hsc->hdmatx->XferAbortCallback = NULL;
-
- HAL_DMA_Abort(hsc->hdmatx);
- }
- }
-
- /* Disable the SMARTCARD DMA Rx request if enabled */
- if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
- {
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the SMARTCARD DMA Rx channel: use blocking DMA Abort API (no callback) */
- if (hsc->hdmarx != NULL)
- {
- /* Set the SMARTCARD DMA Abort callback to Null.
- No call back execution at end of DMA abort procedure */
- hsc->hdmarx->XferAbortCallback = NULL;
-
- HAL_DMA_Abort(hsc->hdmarx);
- }
- }
-
- /* Reset Tx and Rx transfer counters */
- hsc->TxXferCount = 0x00U;
- hsc->RxXferCount = 0x00U;
-
- /* Reset ErrorCode */
- hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
-
- /* Restore hsc->RxState and hsc->gState to Ready */
- hsc->RxState = HAL_SMARTCARD_STATE_READY;
- hsc->gState = HAL_SMARTCARD_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing Transmit transfer (blocking mode).
- * @param hsc SMARTCARD handle.
- * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
- * - Set handle State to READY
- * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit(SMARTCARD_HandleTypeDef *hsc)
-{
- /* Disable TXEIE and TCIE interrupts */
- CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
-
- /* Disable the SMARTCARD DMA Tx request if enabled */
- if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT))
- {
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
-
- /* Abort the SMARTCARD DMA Tx channel: use blocking DMA Abort API (no callback) */
- if (hsc->hdmatx != NULL)
- {
- /* Set the SMARTCARD DMA Abort callback to Null.
- No call back execution at end of DMA abort procedure */
- hsc->hdmatx->XferAbortCallback = NULL;
-
- HAL_DMA_Abort(hsc->hdmatx);
- }
- }
-
- /* Reset Tx transfer counter */
- hsc->TxXferCount = 0x00U;
-
- /* Restore hsc->gState to Ready */
- hsc->gState = HAL_SMARTCARD_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing Receive transfer (blocking mode).
- * @param hsc SMARTCARD handle.
- * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
- * - Set handle State to READY
- * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive(SMARTCARD_HandleTypeDef *hsc)
-{
- /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
-
- /* Disable the SMARTCARD DMA Rx request if enabled */
- if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
- {
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the SMARTCARD DMA Rx channel: use blocking DMA Abort API (no callback) */
- if (hsc->hdmarx != NULL)
- {
- /* Set the SMARTCARD DMA Abort callback to Null.
- No call back execution at end of DMA abort procedure */
- hsc->hdmarx->XferAbortCallback = NULL;
-
- HAL_DMA_Abort(hsc->hdmarx);
- }
- }
-
- /* Reset Rx transfer counter */
- hsc->RxXferCount = 0x00U;
-
- /* Restore hsc->RxState to Ready */
- hsc->RxState = HAL_SMARTCARD_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing transfers (Interrupt mode).
- * @param hsc SMARTCARD handle.
- * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
- * - Set handle State to READY
- * - At abort completion, call user abort complete callback
- * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
- * considered as completed only when user abort complete callback is executed (not when exiting function).
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_SMARTCARD_Abort_IT(SMARTCARD_HandleTypeDef *hsc)
-{
- uint32_t AbortCplt = 0x01U;
-
- /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
-
- /* If DMA Tx and/or DMA Rx Handles are associated to SMARTCARD Handle, DMA Abort complete callbacks should be initialised
- before any call to DMA Abort functions */
- /* DMA Tx Handle is valid */
- if (hsc->hdmatx != NULL)
- {
- /* Set DMA Abort Complete callback if SMARTCARD DMA Tx request if enabled.
- Otherwise, set it to NULL */
- if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT))
- {
- hsc->hdmatx->XferAbortCallback = SMARTCARD_DMATxAbortCallback;
- }
- else
- {
- hsc->hdmatx->XferAbortCallback = NULL;
- }
- }
- /* DMA Rx Handle is valid */
- if (hsc->hdmarx != NULL)
- {
- /* Set DMA Abort Complete callback if SMARTCARD DMA Rx request if enabled.
- Otherwise, set it to NULL */
- if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
- {
- hsc->hdmarx->XferAbortCallback = SMARTCARD_DMARxAbortCallback;
- }
- else
- {
- hsc->hdmarx->XferAbortCallback = NULL;
- }
- }
-
- /* Disable the SMARTCARD DMA Tx request if enabled */
- if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT))
- {
- /* Disable DMA Tx at SMARTCARD level */
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
-
- /* Abort the SMARTCARD DMA Tx channel : use non blocking DMA Abort API (callback) */
- if (hsc->hdmatx != NULL)
- {
- /* SMARTCARD Tx DMA Abort callback has already been initialised :
- will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */
-
- /* Abort DMA TX */
- if (HAL_DMA_Abort_IT(hsc->hdmatx) != HAL_OK)
- {
- hsc->hdmatx->XferAbortCallback = NULL;
- }
- else
- {
- AbortCplt = 0x00U;
- }
- }
- }
-
- /* Disable the SMARTCARD DMA Rx request if enabled */
- if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
- {
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the SMARTCARD DMA Rx channel : use non blocking DMA Abort API (callback) */
- if (hsc->hdmarx != NULL)
- {
- /* SMARTCARD Rx DMA Abort callback has already been initialised :
- will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */
-
- /* Abort DMA RX */
- if (HAL_DMA_Abort_IT(hsc->hdmarx) != HAL_OK)
- {
- hsc->hdmarx->XferAbortCallback = NULL;
- AbortCplt = 0x01U;
- }
- else
- {
- AbortCplt = 0x00U;
- }
- }
- }
-
- /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
- if (AbortCplt == 0x01U)
- {
- /* Reset Tx and Rx transfer counters */
- hsc->TxXferCount = 0x00U;
- hsc->RxXferCount = 0x00U;
-
- /* Reset ErrorCode */
- hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
-
- /* Restore hsc->gState and hsc->RxState to Ready */
- hsc->gState = HAL_SMARTCARD_STATE_READY;
- hsc->RxState = HAL_SMARTCARD_STATE_READY;
-
- /* As no DMA to be aborted, call directly user Abort complete callback */
- HAL_SMARTCARD_AbortCpltCallback(hsc);
- }
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing Transmit transfer (Interrupt mode).
- * @param hsc SMARTCARD handle.
- * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
- * - Set handle State to READY
- * - At abort completion, call user abort complete callback
- * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
- * considered as completed only when user abort complete callback is executed (not when exiting function).
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit_IT(SMARTCARD_HandleTypeDef *hsc)
-{
- /* Disable TXEIE and TCIE interrupts */
- CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
-
- /* Disable the SMARTCARD DMA Tx request if enabled */
- if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT))
- {
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
-
- /* Abort the SMARTCARD DMA Tx channel : use blocking DMA Abort API (no callback) */
- if (hsc->hdmatx != NULL)
- {
- /* Set the SMARTCARD DMA Abort callback :
- will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */
- hsc->hdmatx->XferAbortCallback = SMARTCARD_DMATxOnlyAbortCallback;
-
- /* Abort DMA TX */
- if (HAL_DMA_Abort_IT(hsc->hdmatx) != HAL_OK)
- {
- /* Call Directly hsc->hdmatx->XferAbortCallback function in case of error */
- hsc->hdmatx->XferAbortCallback(hsc->hdmatx);
- }
- }
- else
- {
- /* Reset Tx transfer counter */
- hsc->TxXferCount = 0x00U;
-
- /* Restore hsc->gState to Ready */
- hsc->gState = HAL_SMARTCARD_STATE_READY;
-
- /* As no DMA to be aborted, call directly user Abort complete callback */
- HAL_SMARTCARD_AbortTransmitCpltCallback(hsc);
- }
- }
- else
- {
- /* Reset Tx transfer counter */
- hsc->TxXferCount = 0x00U;
-
- /* Restore hsc->gState to Ready */
- hsc->gState = HAL_SMARTCARD_STATE_READY;
-
- /* As no DMA to be aborted, call directly user Abort complete callback */
- HAL_SMARTCARD_AbortTransmitCpltCallback(hsc);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing Receive transfer (Interrupt mode).
- * @param hsc SMARTCARD handle.
- * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
- * - Set handle State to READY
- * - At abort completion, call user abort complete callback
- * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
- * considered as completed only when user abort complete callback is executed (not when exiting function).
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive_IT(SMARTCARD_HandleTypeDef *hsc)
-{
- /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
-
- /* Disable the SMARTCARD DMA Rx request if enabled */
- if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
- {
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the SMARTCARD DMA Rx channel : use blocking DMA Abort API (no callback) */
- if (hsc->hdmarx != NULL)
- {
- /* Set the SMARTCARD DMA Abort callback :
- will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */
- hsc->hdmarx->XferAbortCallback = SMARTCARD_DMARxOnlyAbortCallback;
-
- /* Abort DMA RX */
- if (HAL_DMA_Abort_IT(hsc->hdmarx) != HAL_OK)
- {
- /* Call Directly hsc->hdmarx->XferAbortCallback function in case of error */
- hsc->hdmarx->XferAbortCallback(hsc->hdmarx);
- }
- }
- else
- {
- /* Reset Rx transfer counter */
- hsc->RxXferCount = 0x00U;
-
- /* Restore hsc->RxState to Ready */
- hsc->RxState = HAL_SMARTCARD_STATE_READY;
-
- /* As no DMA to be aborted, call directly user Abort complete callback */
- HAL_SMARTCARD_AbortReceiveCpltCallback(hsc);
- }
- }
- else
- {
- /* Reset Rx transfer counter */
- hsc->RxXferCount = 0x00U;
-
- /* Restore hsc->RxState to Ready */
- hsc->RxState = HAL_SMARTCARD_STATE_READY;
-
- /* As no DMA to be aborted, call directly user Abort complete callback */
- HAL_SMARTCARD_AbortReceiveCpltCallback(hsc);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief This function handles SMARTCARD interrupt request.
- * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for SMARTCARD module.
- * @retval None
- */
-void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc)
-{
- uint32_t isrflags = READ_REG(hsc->Instance->SR);
- uint32_t cr1its = READ_REG(hsc->Instance->CR1);
- uint32_t cr3its = READ_REG(hsc->Instance->CR3);
- uint32_t dmarequest = 0x00U;
- uint32_t errorflags = 0x00U;
-
- /* If no error occurs */
- errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
- if (errorflags == RESET)
- {
- /* SMARTCARD in mode Receiver -------------------------------------------------*/
- if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
- {
- SMARTCARD_Receive_IT(hsc);
- return;
- }
- }
-
- /* If some errors occur */
- if ((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
- {
- /* SMARTCARD parity error interrupt occurred ---------------------------*/
- if (((isrflags & SMARTCARD_FLAG_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
- {
- hsc->ErrorCode |= HAL_SMARTCARD_ERROR_PE;
- }
-
- /* SMARTCARD noise error interrupt occurred ----------------------------*/
- if (((isrflags & SMARTCARD_FLAG_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
- {
- hsc->ErrorCode |= HAL_SMARTCARD_ERROR_NE;
- }
-
- /* SMARTCARD frame error interrupt occurred ----------------------------*/
- if (((isrflags & SMARTCARD_FLAG_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
- {
- hsc->ErrorCode |= HAL_SMARTCARD_ERROR_FE;
- }
-
- /* SMARTCARD Over-Run interrupt occurred -------------------------------*/
- if (((isrflags & SMARTCARD_FLAG_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
- {
- hsc->ErrorCode |= HAL_SMARTCARD_ERROR_ORE;
- }
-
- /* Call SMARTCARD Error Call back function if need be ------------------*/
- if (hsc->ErrorCode != HAL_SMARTCARD_ERROR_NONE)
- {
- /* SMARTCARD in mode Receiver ----------------------------------------*/
- if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
- {
- SMARTCARD_Receive_IT(hsc);
- }
-
- /* If Overrun error occurs, or if any error occurs in DMA mode reception,
- consider error as blocking */
- dmarequest = HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR);
- if (((hsc->ErrorCode & HAL_SMARTCARD_ERROR_ORE) != RESET) || dmarequest)
- {
- /* Blocking error : transfer is aborted
- Set the SMARTCARD state ready to be able to start again the process,
- Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
- SMARTCARD_EndRxTransfer(hsc);
-
- /* Disable the SMARTCARD DMA Rx request if enabled */
- if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
- {
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the SMARTCARD DMA Rx channel */
- if (hsc->hdmarx != NULL)
- {
- /* Set the SMARTCARD DMA Abort callback :
- will lead to call HAL_SMARTCARD_ErrorCallback() at end of DMA abort procedure */
- hsc->hdmarx->XferAbortCallback = SMARTCARD_DMAAbortOnError;
- if (HAL_DMA_Abort_IT(hsc->hdmarx) != HAL_OK)
- {
- /* Call Directly XferAbortCallback function in case of error */
- hsc->hdmarx->XferAbortCallback(hsc->hdmarx);
- }
- }
- else
- {
- /* Call user error callback */
- HAL_SMARTCARD_ErrorCallback(hsc);
- }
- }
- else
- {
- /* Call user error callback */
- HAL_SMARTCARD_ErrorCallback(hsc);
- }
- }
- else
- {
- /* Non Blocking error : transfer could go on.
- Error is notified to user through user error callback */
- HAL_SMARTCARD_ErrorCallback(hsc);
- hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
- }
- }
- return;
- } /* End if some error occurs */
-
- /* SMARTCARD in mode Transmitter -------------------------------------------*/
- if (((isrflags & SMARTCARD_FLAG_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
- {
- SMARTCARD_Transmit_IT(hsc);
- return;
- }
-
- /* SMARTCARD in mode Transmitter (transmission end) ------------------------*/
- if (((isrflags & SMARTCARD_FLAG_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
- {
- SMARTCARD_EndTransmit_IT(hsc);
- return;
- }
-}
-
-/**
- * @brief Tx Transfer completed callbacks
- * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for SMARTCARD module.
- * @retval None
- */
-__weak void HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef *hsc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hsc);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_SMARTCARD_TxCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Rx Transfer completed callbacks
- * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for SMARTCARD module.
- * @retval None
- */
-__weak void HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef *hsc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hsc);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_SMARTCARD_RxCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief SMARTCARD error callbacks
- * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for SMARTCARD module.
- * @retval None
- */
-__weak void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hsc);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_SMARTCARD_ErrorCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief SMARTCARD Abort Complete callback.
- * @param hsc SMARTCARD handle.
- * @retval None
- */
-__weak void HAL_SMARTCARD_AbortCpltCallback(SMARTCARD_HandleTypeDef *hsc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hsc);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_SMARTCARD_AbortCpltCallback can be implemented in the user file.
- */
-}
-
-/**
- * @brief SMARTCARD Abort Transmit Complete callback.
- * @param hsc SMARTCARD handle.
- * @retval None
- */
-__weak void HAL_SMARTCARD_AbortTransmitCpltCallback(SMARTCARD_HandleTypeDef *hsc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hsc);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_SMARTCARD_AbortTransmitCpltCallback can be implemented in the user file.
- */
-}
-
-/**
- * @brief SMARTCARD Abort ReceiveComplete callback.
- * @param hsc SMARTCARD handle.
- * @retval None
- */
-__weak void HAL_SMARTCARD_AbortReceiveCpltCallback(SMARTCARD_HandleTypeDef *hsc)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hsc);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_SMARTCARD_AbortReceiveCpltCallback can be implemented in the user file.
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup SMARTCARD_Exported_Functions_Group3 Peripheral State and Errors functions
- * @brief SMARTCARD State and Errors functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral State and Errors functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to control the SmartCard.
- (+) HAL_SMARTCARD_GetState() API can be helpful to check in run-time the state of the SmartCard peripheral.
- (+) HAL_SMARTCARD_GetError() check in run-time errors that could be occurred during communication.
-@endverbatim
- * @{
- */
-
-/**
- * @brief return the SMARTCARD state
- * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for SMARTCARD module.
- * @retval HAL state
- */
-HAL_SMARTCARD_StateTypeDef HAL_SMARTCARD_GetState(SMARTCARD_HandleTypeDef *hsc)
-{
- uint32_t temp1 = 0x00U, temp2 = 0x00U;
- temp1 = hsc->gState;
- temp2 = hsc->RxState;
-
- return (HAL_SMARTCARD_StateTypeDef)(temp1 | temp2);
-}
-
-/**
- * @brief Return the SMARTCARD error code
- * @param hsc : pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for the specified SMARTCARD.
- * @retval SMARTCARD Error Code
- */
-uint32_t HAL_SMARTCARD_GetError(SMARTCARD_HandleTypeDef *hsc)
-{
- return hsc->ErrorCode;
-}
-
-/**
- * @}
- */
-
-/**
- * @brief DMA SMARTCARD transmit process complete callback
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma)
-{
- SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
- hsc->TxXferCount = 0U;
-
- /* Disable the DMA transfer for transmit request by setting the DMAT bit
- in the USART CR3 register */
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
-
- /* Enable the SMARTCARD Transmit Complete Interrupt */
- SET_BIT(hsc->Instance->CR1, USART_CR1_TCIE);
-}
-
-/**
- * @brief DMA SMARTCARD receive process complete callback
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
-{
- SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
- hsc->RxXferCount = 0U;
-
- /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
-
- /* Disable the DMA transfer for the receiver request by setting the DMAR bit
- in the USART CR3 register */
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
-
- /* At end of Rx process, restore hsc->RxState to Ready */
- hsc->RxState = HAL_SMARTCARD_STATE_READY;
-
- HAL_SMARTCARD_RxCpltCallback(hsc);
-}
-
-/**
- * @brief DMA SMARTCARD communication error callback
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma)
-{
- uint32_t dmarequest = 0x00U;
- SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
- hsc->RxXferCount = 0U;
- hsc->TxXferCount = 0U;
- hsc->ErrorCode = HAL_SMARTCARD_ERROR_DMA;
-
- /* Stop SMARTCARD DMA Tx request if ongoing */
- dmarequest = HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT);
- if ((hsc->gState == HAL_SMARTCARD_STATE_BUSY_TX) && dmarequest)
- {
- SMARTCARD_EndTxTransfer(hsc);
- }
-
- /* Stop SMARTCARD DMA Rx request if ongoing */
- dmarequest = HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR);
- if ((hsc->RxState == HAL_SMARTCARD_STATE_BUSY_RX) && dmarequest)
- {
- SMARTCARD_EndRxTransfer(hsc);
- }
-
- HAL_SMARTCARD_ErrorCallback(hsc);
-}
-
-/**
- * @brief This function handles SMARTCARD Communication Timeout.
- * @param hsc: SMARTCARD handle
- * @param Flag: specifies the SMARTCARD flag to check.
- * @param Status: The new Flag status (SET or RESET).
- * @param Timeout: Timeout duration
- * @param Tickstart: tick start value
- * @retval HAL status
- */
-static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
-{
- /* Wait until flag is set */
- while ((__HAL_SMARTCARD_GET_FLAG(hsc, Flag) ? SET : RESET) == Status)
- {
- /* Check for the Timeout */
- if (Timeout != HAL_MAX_DELAY)
- {
- if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
- {
- /* Disable TXE and RXNE interrupts for the interrupt process */
- CLEAR_BIT(hsc->Instance->CR1, USART_CR1_TXEIE);
- CLEAR_BIT(hsc->Instance->CR1, USART_CR1_RXNEIE);
-
- hsc->gState = HAL_SMARTCARD_STATE_READY;
- hsc->RxState = HAL_SMARTCARD_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hsc);
-
- return HAL_TIMEOUT;
- }
- }
- }
- return HAL_OK;
-}
-
-/**
- * @brief End ongoing Tx transfer on SMARTCARD peripheral (following error detection or Transmit completion).
- * @param hsc: SMARTCARD handle.
- * @retval None
- */
-static void SMARTCARD_EndTxTransfer(SMARTCARD_HandleTypeDef *hsc)
-{
- /* At end of Tx process, restore hsc->gState to Ready */
- hsc->gState = HAL_SMARTCARD_STATE_READY;
-
- /* Disable TXEIE and TCIE interrupts */
- CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
-}
-
-
-/**
- * @brief End ongoing Rx transfer on SMARTCARD peripheral (following error detection or Reception completion).
- * @param hsc: SMARTCARD handle.
- * @retval None
- */
-static void SMARTCARD_EndRxTransfer(SMARTCARD_HandleTypeDef *hsc)
-{
- /* At end of Rx process, restore hsc->RxState to Ready */
- hsc->RxState = HAL_SMARTCARD_STATE_READY;
-
- /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
-}
-
-
-
-/**
- * @brief DMA SMARTCARD communication abort callback, when initiated by HAL services on Error
- * (To be called at end of DMA Abort procedure following error occurrence).
- * @param hdma DMA handle.
- * @retval None
- */
-static void SMARTCARD_DMAAbortOnError(DMA_HandleTypeDef *hdma)
-{
- SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
- hsc->RxXferCount = 0x00U;
- hsc->TxXferCount = 0x00U;
-
- HAL_SMARTCARD_ErrorCallback(hsc);
-}
-
-/**
- * @brief DMA SMARTCARD Tx communication abort callback, when initiated by user
- * (To be called at end of DMA Tx Abort procedure following user abort request).
- * @note When this callback is executed, User Abort complete call back is called only if no
- * Abort still ongoing for Rx DMA Handle.
- * @param hdma DMA handle.
- * @retval None
- */
-static void SMARTCARD_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
-{
- SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
- hsc->hdmatx->XferAbortCallback = NULL;
-
- /* Check if an Abort process is still ongoing */
- if (hsc->hdmarx != NULL)
- {
- if (hsc->hdmarx->XferAbortCallback != NULL)
- {
- return;
- }
- }
-
- /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
- hsc->TxXferCount = 0x00U;
- hsc->RxXferCount = 0x00U;
-
- /* Reset ErrorCode */
- hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
-
- /* Restore hsc->gState and hsc->RxState to Ready */
- hsc->gState = HAL_SMARTCARD_STATE_READY;
- hsc->RxState = HAL_SMARTCARD_STATE_READY;
-
- /* Call user Abort complete callback */
- HAL_SMARTCARD_AbortCpltCallback(hsc);
-}
-
-/**
- * @brief DMA SMARTCARD Rx communication abort callback, when initiated by user
- * (To be called at end of DMA Rx Abort procedure following user abort request).
- * @note When this callback is executed, User Abort complete call back is called only if no
- * Abort still ongoing for Tx DMA Handle.
- * @param hdma DMA handle.
- * @retval None
- */
-static void SMARTCARD_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
-{
- SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
- hsc->hdmarx->XferAbortCallback = NULL;
-
- /* Check if an Abort process is still ongoing */
- if (hsc->hdmatx != NULL)
- {
- if (hsc->hdmatx->XferAbortCallback != NULL)
- {
- return;
- }
- }
-
- /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
- hsc->TxXferCount = 0x00U;
- hsc->RxXferCount = 0x00U;
-
- /* Reset ErrorCode */
- hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
-
- /* Restore hsc->gState and hsc->RxState to Ready */
- hsc->gState = HAL_SMARTCARD_STATE_READY;
- hsc->RxState = HAL_SMARTCARD_STATE_READY;
-
- /* Call user Abort complete callback */
- HAL_SMARTCARD_AbortCpltCallback(hsc);
-}
-
-/**
- * @brief DMA SMARTCARD Tx communication abort callback, when initiated by user by a call to
- * HAL_SMARTCARD_AbortTransmit_IT API (Abort only Tx transfer)
- * (This callback is executed at end of DMA Tx Abort procedure following user abort request,
- * and leads to user Tx Abort Complete callback execution).
- * @param hdma DMA handle.
- * @retval None
- */
-static void SMARTCARD_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
-{
- SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
- hsc->TxXferCount = 0x00U;
-
- /* Restore hsc->gState to Ready */
- hsc->gState = HAL_SMARTCARD_STATE_READY;
-
- /* Call user Abort complete callback */
- HAL_SMARTCARD_AbortTransmitCpltCallback(hsc);
-}
-
-/**
- * @brief DMA SMARTCARD Rx communication abort callback, when initiated by user by a call to
- * HAL_SMARTCARD_AbortReceive_IT API (Abort only Rx transfer)
- * (This callback is executed at end of DMA Rx Abort procedure following user abort request,
- * and leads to user Rx Abort Complete callback execution).
- * @param hdma DMA handle.
- * @retval None
- */
-static void SMARTCARD_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
-{
- SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
- hsc->RxXferCount = 0x00U;
-
- /* Restore hsc->RxState to Ready */
- hsc->RxState = HAL_SMARTCARD_STATE_READY;
-
- /* Call user Abort complete callback */
- HAL_SMARTCARD_AbortReceiveCpltCallback(hsc);
-}
-
-/**
- * @brief Send an amount of data in non blocking mode
- * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for SMARTCARD module.
- * @retval HAL status
- */
-static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc)
-{
- /* Check that a Tx process is ongoing */
- if (hsc->gState == HAL_SMARTCARD_STATE_BUSY_TX)
- {
- hsc->Instance->DR = *(uint8_t *) hsc->pTxBuffPtr;
- hsc->pTxBuffPtr += 1U;
-
- if (--hsc->TxXferCount == 0U)
- {
- /* Disable the SMARTCARD Transmit data register empty Interrupt */
- CLEAR_BIT(hsc->Instance->CR1, USART_CR1_TXEIE);
-
- /* Enable the SMARTCARD Transmit Complete Interrupt */
- SET_BIT(hsc->Instance->CR1, USART_CR1_TCIE);
- }
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Wraps up transmission in non blocking mode.
- * @param hsmartcard: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for the specified SMARTCARD module.
- * @retval HAL status
- */
-static HAL_StatusTypeDef SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard)
-{
- /* Disable the SMARTCARD Transmit Complete Interrupt */
- CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_TCIE);
-
- /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
- CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE);
-
- /* Tx process is ended, restore hsmartcard->gState to Ready */
- hsmartcard->gState = HAL_SMARTCARD_STATE_READY;
-
- HAL_SMARTCARD_TxCpltCallback(hsmartcard);
-
- return HAL_OK;
-}
-
-/**
- * @brief Receive an amount of data in non blocking mode
- * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for SMARTCARD module.
- * @retval HAL status
- */
-static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc)
-{
- /* Check that a Rx process is ongoing */
- if (hsc->RxState == HAL_SMARTCARD_STATE_BUSY_RX)
- {
- *(uint8_t *) hsc->pRxBuffPtr = (uint8_t)hsc->Instance->DR;
- hsc->pRxBuffPtr += 1U;
-
- if (--hsc->RxXferCount == 0U)
- {
- CLEAR_BIT(hsc->Instance->CR1, USART_CR1_RXNEIE);
-
- /* Disable the SMARTCARD Parity Error Interrupt */
- CLEAR_BIT(hsc->Instance->CR1, USART_CR1_PEIE);
-
- /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
- CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
-
- /* Rx process is completed, restore hsc->RxState to Ready */
- hsc->RxState = HAL_SMARTCARD_STATE_READY;
-
- HAL_SMARTCARD_RxCpltCallback(hsc);
-
- return HAL_OK;
- }
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Configure the SMARTCARD peripheral
- * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
- * the configuration information for SMARTCARD module.
- * @retval None
- */
-static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc)
-{
- uint32_t tmpreg = 0x00U;
-
- /* Check the parameters */
- assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
- assert_param(IS_SMARTCARD_POLARITY(hsc->Init.CLKPolarity));
- assert_param(IS_SMARTCARD_PHASE(hsc->Init.CLKPhase));
- assert_param(IS_SMARTCARD_LASTBIT(hsc->Init.CLKLastBit));
- assert_param(IS_SMARTCARD_BAUDRATE(hsc->Init.BaudRate));
- assert_param(IS_SMARTCARD_WORD_LENGTH(hsc->Init.WordLength));
- assert_param(IS_SMARTCARD_STOPBITS(hsc->Init.StopBits));
- assert_param(IS_SMARTCARD_PARITY(hsc->Init.Parity));
- assert_param(IS_SMARTCARD_MODE(hsc->Init.Mode));
- assert_param(IS_SMARTCARD_NACK_STATE(hsc->Init.NACKState));
-
-
- /* The LBCL, CPOL and CPHA bits have to be selected when both the transmitter and the
- receiver are disabled (TE=RE=0) to ensure that the clock pulses function correctly. */
- CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
-
- /*---------------------------- USART CR2 Configuration ---------------------*/
- tmpreg = hsc->Instance->CR2;
- /* Clear CLKEN, CPOL, CPHA and LBCL bits */
- tmpreg &= (uint32_t)~((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_LBCL));
- /* Configure the SMARTCARD Clock, CPOL, CPHA and LastBit -----------------------*/
- /* Set CPOL bit according to hsc->Init.CLKPolarity value */
- /* Set CPHA bit according to hsc->Init.CLKPhase value */
- /* Set LBCL bit according to hsc->Init.CLKLastBit value */
- /* Set Stop Bits: Set STOP[13:12] bits according to hsc->Init.StopBits value */
- tmpreg |= (uint32_t)(USART_CR2_CLKEN | hsc->Init.CLKPolarity |
- hsc->Init.CLKPhase | hsc->Init.CLKLastBit | hsc->Init.StopBits);
- /* Write to USART CR2 */
- WRITE_REG(hsc->Instance->CR2, (uint32_t)tmpreg);
-
- tmpreg = hsc->Instance->CR2;
-
- /* Clear STOP[13:12] bits */
- tmpreg &= (uint32_t)~((uint32_t)USART_CR2_STOP);
-
- /* Set Stop Bits: Set STOP[13:12] bits according to hsc->Init.StopBits value */
- tmpreg |= (uint32_t)(hsc->Init.StopBits);
-
- /* Write to USART CR2 */
- WRITE_REG(hsc->Instance->CR2, (uint32_t)tmpreg);
-
- /*-------------------------- USART CR1 Configuration -----------------------*/
- tmpreg = hsc->Instance->CR1;
-
- /* Clear M, PCE, PS, TE and RE bits */
- tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \
- USART_CR1_RE));
-
- /* Configure the SMARTCARD Word Length, Parity and mode:
- Set the M bits according to hsc->Init.WordLength value
- Set PCE and PS bits according to hsc->Init.Parity value
- Set TE and RE bits according to hsc->Init.Mode value */
- tmpreg |= (uint32_t)hsc->Init.WordLength | hsc->Init.Parity | hsc->Init.Mode;
-
- /* Write to USART CR1 */
- WRITE_REG(hsc->Instance->CR1, (uint32_t)tmpreg);
-
- /*-------------------------- USART CR3 Configuration -----------------------*/
- /* Clear CTSE and RTSE bits */
- CLEAR_BIT(hsc->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE));
-
- /*-------------------------- USART BRR Configuration -----------------------*/
-
- if (hsc->Instance == USART1)
- {
- hsc->Instance->BRR = SMARTCARD_BRR(HAL_RCC_GetPCLK2Freq(), hsc->Init.BaudRate);
- }
- else
- {
- hsc->Instance->BRR = SMARTCARD_BRR(HAL_RCC_GetPCLK1Freq(), hsc->Init.BaudRate);
- }
-}
-
-/**
- * @}
- */
-
-#endif /* HAL_SMARTCARD_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c
deleted file mode 100644
index af8e357..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c
+++ /dev/null
@@ -1,3264 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_spi.c
- * @author MCD Application Team
- * @brief SPI HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Serial Peripheral Interface (SPI) peripheral:
- * + Initialization and de-initialization functions
- * + IO operation functions
- * + Peripheral Control functions
- * + Peripheral State functions
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- The SPI HAL driver can be used as follows:
-
- (#) Declare a SPI_HandleTypeDef handle structure, for example:
- SPI_HandleTypeDef hspi;
-
- (#)Initialize the SPI low level resources by implementing the HAL_SPI_MspInit() API:
- (##) Enable the SPIx interface clock
- (##) SPI pins configuration
- (+++) Enable the clock for the SPI GPIOs
- (+++) Configure these SPI pins as alternate function push-pull
- (##) NVIC configuration if you need to use interrupt process
- (+++) Configure the SPIx interrupt priority
- (+++) Enable the NVIC SPI IRQ handle
- (##) DMA Configuration if you need to use DMA process
- (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive Channel
- (+++) Enable the DMAx clock
- (+++) Configure the DMA handle parameters
- (+++) Configure the DMA Tx or Rx Channel
- (+++) Associate the initilalized hdma_tx(or _rx) handle to the hspi DMA Tx (or Rx) handle
- (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx or Rx Channel
-
- (#) Program the Mode, BidirectionalMode , Data size, Baudrate Prescaler, NSS
- management, Clock polarity and phase, FirstBit and CRC configuration in the hspi Init structure.
-
- (#) Initialize the SPI registers by calling the HAL_SPI_Init() API:
- (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
- by calling the customized HAL_SPI_MspInit() API.
- [..]
- Circular mode restriction:
- (#) The DMA circular mode cannot be used when the SPI is configured in these modes:
- (##) Master 2Lines RxOnly
- (##) Master 1Line Rx
- (#) The CRC feature is not managed when the DMA circular mode is enabled
- (#) When the SPI DMA Pause/Stop features are used, we must use the following APIs
- the HAL_SPI_DMAPause()/ HAL_SPI_DMAStop() only under the SPI callbacks
- [..]
- Master Receive mode restriction:
- (#) In Master unidirectional receive-only mode (MSTR =1, BIDIMODE=0, RXONLY=0) or
- bidirectional receive mode (MSTR=1, BIDIMODE=1, BIDIOE=0), to ensure that the SPI
- does not initiate a new transfer the following procedure has to be respected:
- (##) HAL_SPI_DeInit()
- (##) HAL_SPI_Init()
-
- @endverbatim
-
- Using the HAL it is not possible to reach all supported SPI frequency with the differents SPI Modes,
- the following tables resume the max SPI frequency reached with data size 8bits/16bits,
- according to frequency used on APBx Peripheral Clock (fPCLK) used by the SPI instance :
-
- DataSize = SPI_DATASIZE_8BIT:
- +--------------------------------------------------------------------------------------------------+
- | | | 2Lines Fullduplex | 2Lines RxOnly | 1Line |
- | Process | Tranfert mode |-----------------------|-----------------------|-----------------------|
- | | | Master | Slave | Master | Slave | Master | Slave |
- |==================================================================================================|
- | T | Polling | fPCLK/2 | fPCLK/16 | NA | NA | NA | NA |
- | X |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
- | / | Interrupt | fPCLK/8 | fPCLK/32 | NA | NA | NA | NA |
- | R |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
- | X | DMA | fPCLK/2 | fPCLK/4 | NA | NA | NA | NA |
- |=========|================|===========|===========|===========|===========|===========|===========|
- | | Polling | fPCLK/4 | fPCLK/8 | fPCLK/8 | fPCLK/16 | fPCLK/64 | fPCLK/2 |
- | |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
- | R | Interrupt | fPCLK/8 | fPCLK/16 | fPCLK/32 | fPCLK/16 | fPCLK/64 | fPCLK/4 |
- | X |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
- | | DMA | fPCLK/2 | fPCLK/16 | fPCLK/8 | fPCLK/16 | fPCLK/64 | fPCLK/2 |
- |=========|================|===========|===========|===========|===========|===========|===========|
- | | Polling | fPCLK/2 | fPCLK/2 | NA | NA | fPCLK/2 | fPCLK/32 |
- | |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
- | T | Interrupt | fPCLK/8 | fPCLK/16 | NA | NA | fPCLK/2 | fPCLK/64 |
- | X |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
- | | DMA | fPCLK/2 | fPCLK/4 | NA | NA | fPCLK/2 | fPCLK/32 |
- +--------------------------------------------------------------------------------------------------+
-
- DataSize = SPI_DATASIZE_16BIT:
- +--------------------------------------------------------------------------------------------------+
- | | | 2Lines Fullduplex | 2Lines RxOnly | 1Line |
- | Process | Tranfert mode |-----------------------|-----------------------|-----------------------|
- | | | Master | Slave | Master | Slave | Master | Slave |
- |==================================================================================================|
- | T | Polling | fPCLK/4 | fPCLK/4 | NA | NA | NA | NA |
- | X |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
- | / | Interrupt | fPCLK/8 | fPCLK/16 | NA | NA | NA | NA |
- | R |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
- | X | DMA | fPCLK/2 | fPCLK/4 | NA | NA | NA | NA |
- |=========|================|===========|===========|===========|===========|===========|===========|
- | | Polling | fPCLK/4 | fPCLK/8 | fPCLK/4 | fPCLK/8 | fPCLK/64 | fPCLK/2 |
- | |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
- | R | Interrupt | fPCLK/8 | fPCLK/8 | fPCLK/128 | fPCLK/8 | fPCLK/128 | fPCLK/4 |
- | X |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
- | | DMA | fPCLK/2 | fPCLK/2 | fPCLK/128 | fPCLK/16 | fPCLK/64 | fPCLK/2 |
- |=========|================|===========|===========|===========|===========|===========|===========|
- | | Polling | fPCLK/2 | fPCLK/4 | NA | NA | fPCLK/4 | fPCLK/8 |
- | |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
- | T | Interrupt | fPCLK/4 | fPCLK/8 | NA | NA | fPCLK/4 | fPCLK/4 |
- | X |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
- | | DMA | fPCLK/2 | fPCLK/2 | NA | NA | fPCLK/4 | fPCLK/8 |
- +--------------------------------------------------------------------------------------------------+
- [..]
- (@) The max SPI frequency depend on SPI data size (8bits, 16bits),
- SPI mode(2 Lines fullduplex, 2 lines RxOnly, 1 line TX/RX) and Process mode (Polling, IT, DMA).
- (@)
- (+@) TX/RX processes are HAL_SPI_TransmitReceive(), HAL_SPI_TransmitReceive_IT() and HAL_SPI_TransmitReceive_DMA()
- (+@) RX processes are HAL_SPI_Receive(), HAL_SPI_Receive_IT() and HAL_SPI_Receive_DMA()
- (+@) TX processes are HAL_SPI_Transmit(), HAL_SPI_Transmit_IT() and HAL_SPI_Transmit_DMA()
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-/** @defgroup SPI SPI
- * @brief SPI HAL module driver
- * @{
- */
-#ifdef HAL_SPI_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private defines -----------------------------------------------------------*/
-/** @defgroup SPI_Private_Constants SPI Private Constants
- * @{
- */
-#define SPI_DEFAULT_TIMEOUT 100U
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @addtogroup SPI_Private_Functions
- * @{
- */
-static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
-static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
-static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma);
-static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma);
-static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma);
-static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma);
-static void SPI_DMAError(DMA_HandleTypeDef *hdma);
-static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma);
-static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
-static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
-static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, uint32_t State, uint32_t Timeout, uint32_t Tickstart);
-static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
-static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
-static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
-static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
-static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
-static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
-static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
-static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
-#if (USE_SPI_CRC != 0U)
-static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi);
-static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi);
-static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi);
-static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi);
-#endif /* USE_SPI_CRC */
-static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi);
-static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi);
-static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi);
-static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi);
-static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi);
-static HAL_StatusTypeDef SPI_CheckFlag_BSY(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart);
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup SPI_Exported_Functions SPI Exported Functions
- * @{
- */
-
-/** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
- ===============================================================================
- ##### Initialization and de-initialization functions #####
- ===============================================================================
- [..] This subsection provides a set of functions allowing to initialize and
- de-initialize the SPIx peripheral:
-
- (+) User must implement HAL_SPI_MspInit() function in which he configures
- all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
-
- (+) Call the function HAL_SPI_Init() to configure the selected device with
- the selected configuration:
- (++) Mode
- (++) Direction
- (++) Data Size
- (++) Clock Polarity and Phase
- (++) NSS Management
- (++) BaudRate Prescaler
- (++) FirstBit
- (++) TIMode
- (++) CRC Calculation
- (++) CRC Polynomial if CRC enabled
-
- (+) Call the function HAL_SPI_DeInit() to restore the default configuration
- of the selected SPIx peripheral.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initialize the SPI according to the specified parameters
- * in the SPI_InitTypeDef and initialize the associated handle.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval HAL status
- */
-__weak HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
-{
- /* Check the SPI handle allocation */
- if(hspi == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
- assert_param(IS_SPI_MODE(hspi->Init.Mode));
- assert_param(IS_SPI_DIRECTION(hspi->Init.Direction));
- assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize));
- assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity));
- assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase));
- assert_param(IS_SPI_NSS(hspi->Init.NSS));
- assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
- assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit));
-
-#if (USE_SPI_CRC != 0U)
- assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation));
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial));
- }
-#else
- hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
-#endif /* USE_SPI_CRC */
-
- if(hspi->State == HAL_SPI_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- hspi->Lock = HAL_UNLOCKED;
-
- /* Init the low level hardware : GPIO, CLOCK, NVIC... */
- HAL_SPI_MspInit(hspi);
- }
-
- hspi->State = HAL_SPI_STATE_BUSY;
-
- /* Disable the selected SPI peripheral */
- __HAL_SPI_DISABLE(hspi);
-
- /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/
- /* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management,
- Communication speed, First bit and CRC calculation state */
- WRITE_REG(hspi->Instance->CR1, (hspi->Init.Mode | hspi->Init.Direction | hspi->Init.DataSize |
- hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) |
- hspi->Init.BaudRatePrescaler | hspi->Init.FirstBit | hspi->Init.CRCCalculation) );
-
- /* Configure : NSS management */
- WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) | hspi->Init.TIMode));
-
-#if (USE_SPI_CRC != 0U)
- /*---------------------------- SPIx CRCPOLY Configuration ------------------*/
- /* Configure : CRC Polynomial */
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- WRITE_REG(hspi->Instance->CRCPR, hspi->Init.CRCPolynomial);
- }
-#endif /* USE_SPI_CRC */
-
-#if defined(SPI_I2SCFGR_I2SMOD)
- /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */
- CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD);
-#endif /* SPI_I2SCFGR_I2SMOD */
-
- hspi->ErrorCode = HAL_SPI_ERROR_NONE;
- hspi->State = HAL_SPI_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief De Initialize the SPI peripheral.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi)
-{
- /* Check the SPI handle allocation */
- if(hspi == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check SPI Instance parameter */
- assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
-
- hspi->State = HAL_SPI_STATE_BUSY;
-
- /* Disable the SPI Peripheral Clock */
- __HAL_SPI_DISABLE(hspi);
-
- /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
- HAL_SPI_MspDeInit(hspi);
-
- hspi->ErrorCode = HAL_SPI_ERROR_NONE;
- hspi->State = HAL_SPI_STATE_RESET;
-
- /* Release Lock */
- __HAL_UNLOCK(hspi);
-
- return HAL_OK;
-}
-
-/**
- * @brief Initialize the SPI MSP.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-__weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hspi);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_SPI_MspInit should be implemented in the user file
- */
-}
-
-/**
- * @brief De-Initialize the SPI MSP.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-__weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hspi);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_SPI_MspDeInit should be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup SPI_Exported_Functions_Group2 IO operation functions
- * @brief Data transfers functions
- *
-@verbatim
- ==============================================================================
- ##### IO operation functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to manage the SPI
- data transfers.
-
- [..] The SPI supports master and slave mode :
-
- (#) There are two modes of transfer:
- (++) Blocking mode: The communication is performed in polling mode.
- The HAL status of all data processing is returned by the same function
- after finishing transfer.
- (++) No-Blocking mode: The communication is performed using Interrupts
- or DMA, These APIs return the HAL status.
- The end of the data processing will be indicated through the
- dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when
- using DMA mode.
- The HAL_SPI_TxCpltCallback(), HAL_SPI_RxCpltCallback() and HAL_SPI_TxRxCpltCallback() user callbacks
- will be executed respectively at the end of the transmit or Receive process
- The HAL_SPI_ErrorCallback()user callback will be executed when a communication error is detected
-
- (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA)
- exist for 1Line (simplex) and 2Lines (full duplex) modes.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Transmit an amount of data in blocking mode.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @param pData: pointer to data buffer
- * @param Size: amount of data to be sent
- * @param Timeout: Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
-{
- uint32_t tickstart = 0U;
- HAL_StatusTypeDef errorcode = HAL_OK;
-
- /* Check Direction parameter */
- assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
-
- /* Process Locked */
- __HAL_LOCK(hspi);
-
- /* Init tickstart for timeout management*/
- tickstart = HAL_GetTick();
-
- if(hspi->State != HAL_SPI_STATE_READY)
- {
- errorcode = HAL_BUSY;
- goto error;
- }
-
- if((pData == NULL ) || (Size == 0U))
- {
- errorcode = HAL_ERROR;
- goto error;
- }
-
- /* Set the transaction information */
- hspi->State = HAL_SPI_STATE_BUSY_TX;
- hspi->ErrorCode = HAL_SPI_ERROR_NONE;
- hspi->pTxBuffPtr = (uint8_t *)pData;
- hspi->TxXferSize = Size;
- hspi->TxXferCount = Size;
-
- /*Init field not used in handle to zero */
- hspi->pRxBuffPtr = (uint8_t *)NULL;
- hspi->RxXferSize = 0U;
- hspi->RxXferCount = 0U;
- hspi->TxISR = NULL;
- hspi->RxISR = NULL;
-
- /* Configure communication direction : 1Line */
- if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
- {
- SPI_1LINE_TX(hspi);
- }
-
-#if (USE_SPI_CRC != 0U)
- /* Reset CRC Calculation */
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- SPI_RESET_CRC(hspi);
- }
-#endif /* USE_SPI_CRC */
-
- /* Check if the SPI is already enabled */
- if((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
- {
- /* Enable SPI peripheral */
- __HAL_SPI_ENABLE(hspi);
- }
-
- /* Transmit data in 16 Bit mode */
- if(hspi->Init.DataSize == SPI_DATASIZE_16BIT)
- {
- if((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01))
- {
- hspi->Instance->DR = *((uint16_t *)pData);
- pData += sizeof(uint16_t);
- hspi->TxXferCount--;
- }
- /* Transmit data in 16 Bit mode */
- while (hspi->TxXferCount > 0U)
- {
- /* Wait until TXE flag is set to send data */
- if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
- {
- hspi->Instance->DR = *((uint16_t *)pData);
- pData += sizeof(uint16_t);
- hspi->TxXferCount--;
- }
- else
- {
- /* Timeout management */
- if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout)))
- {
- errorcode = HAL_TIMEOUT;
- goto error;
- }
- }
- }
- }
- /* Transmit data in 8 Bit mode */
- else
- {
- if((hspi->Init.Mode == SPI_MODE_SLAVE)|| (hspi->TxXferCount == 0x01))
- {
- *((__IO uint8_t*)&hspi->Instance->DR) = (*pData);
- pData += sizeof(uint8_t);
- hspi->TxXferCount--;
- }
- while (hspi->TxXferCount > 0U)
- {
- /* Wait until TXE flag is set to send data */
- if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
- {
- *((__IO uint8_t*)&hspi->Instance->DR) = (*pData);
- pData += sizeof(uint8_t);
- hspi->TxXferCount--;
- }
- else
- {
- /* Timeout management */
- if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout)))
- {
- errorcode = HAL_TIMEOUT;
- goto error;
- }
- }
- }
- }
-
- /* Wait until TXE flag */
- if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_TXE, SET, Timeout, tickstart) != HAL_OK)
- {
- errorcode = HAL_TIMEOUT;
- goto error;
- }
-
- /* Check Busy flag */
- if(SPI_CheckFlag_BSY(hspi, Timeout, tickstart) != HAL_OK)
- {
- errorcode = HAL_ERROR;
- hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
- goto error;
- }
-
- /* Clear overrun flag in 2 Lines communication mode because received is not read */
- if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
- {
- __HAL_SPI_CLEAR_OVRFLAG(hspi);
- }
-#if (USE_SPI_CRC != 0U)
- /* Enable CRC Transmission */
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
- }
-#endif /* USE_SPI_CRC */
-
- if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
- {
- errorcode = HAL_ERROR;
- }
-
-error:
- hspi->State = HAL_SPI_STATE_READY;
- /* Process Unlocked */
- __HAL_UNLOCK(hspi);
- return errorcode;
-}
-
-/**
- * @brief Receive an amount of data in blocking mode.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @param pData: pointer to data buffer
- * @param Size: amount of data to be received
- * @param Timeout: Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
-{
-#if (USE_SPI_CRC != 0U)
- __IO uint16_t tmpreg = 0U;
-#endif /* USE_SPI_CRC */
- uint32_t tickstart = 0U;
- HAL_StatusTypeDef errorcode = HAL_OK;
-
- if((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES))
- {
- hspi->State = HAL_SPI_STATE_BUSY_RX;
- /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
- return HAL_SPI_TransmitReceive(hspi,pData,pData,Size,Timeout);
- }
-
- /* Process Locked */
- __HAL_LOCK(hspi);
-
- /* Init tickstart for timeout management*/
- tickstart = HAL_GetTick();
-
- if(hspi->State != HAL_SPI_STATE_READY)
- {
- errorcode = HAL_BUSY;
- goto error;
- }
-
- if((pData == NULL ) || (Size == 0U))
- {
- errorcode = HAL_ERROR;
- goto error;
- }
-
- /* Set the transaction information */
- hspi->State = HAL_SPI_STATE_BUSY_RX;
- hspi->ErrorCode = HAL_SPI_ERROR_NONE;
- hspi->pRxBuffPtr = (uint8_t *)pData;
- hspi->RxXferSize = Size;
- hspi->RxXferCount = Size;
-
- /*Init field not used in handle to zero */
- hspi->pTxBuffPtr = (uint8_t *)NULL;
- hspi->TxXferSize = 0U;
- hspi->TxXferCount = 0U;
- hspi->RxISR = NULL;
- hspi->TxISR = NULL;
-
-#if (USE_SPI_CRC != 0U)
- /* Reset CRC Calculation */
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- SPI_RESET_CRC(hspi);
- /* this is done to handle the CRCNEXT before the latest data */
- hspi->RxXferCount--;
- }
-#endif /* USE_SPI_CRC */
-
- /* Configure communication direction: 1Line */
- if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
- {
- SPI_1LINE_RX(hspi);
- }
-
- /* Check if the SPI is already enabled */
- if((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
- {
- /* Enable SPI peripheral */
- __HAL_SPI_ENABLE(hspi);
- }
-
- /* Receive data in 8 Bit mode */
- if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)
- {
- /* Transfer loop */
- while(hspi->RxXferCount > 0U)
- {
- /* Check the RXNE flag */
- if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))
- {
- /* read the received data */
- (* (uint8_t *)pData)= *(__IO uint8_t *)&hspi->Instance->DR;
- pData += sizeof(uint8_t);
- hspi->RxXferCount--;
- }
- else
- {
- /* Timeout management */
- if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout)))
- {
- errorcode = HAL_TIMEOUT;
- goto error;
- }
- }
- }
- }
- else
- {
- /* Transfer loop */
- while(hspi->RxXferCount > 0U)
- {
- /* Check the RXNE flag */
- if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))
- {
- *((uint16_t*)pData) = hspi->Instance->DR;
- pData += sizeof(uint16_t);
- hspi->RxXferCount--;
- }
- else
- {
- /* Timeout management */
- if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout)))
- {
- errorcode = HAL_TIMEOUT;
- goto error;
- }
- }
- }
- }
-
-#if (USE_SPI_CRC != 0U)
- /* Handle the CRC Transmission */
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- /* freeze the CRC before the latest data */
- SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
-
- /* Read the latest data */
- if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
- {
- /* the latest data has not been received */
- errorcode = HAL_TIMEOUT;
- goto error;
- }
-
- /* Receive last data in 16 Bit mode */
- if(hspi->Init.DataSize == SPI_DATASIZE_16BIT)
- {
- *((uint16_t*)pData) = hspi->Instance->DR;
- }
- /* Receive last data in 8 Bit mode */
- else
- {
- (*(uint8_t *)pData) = *(__IO uint8_t *)&hspi->Instance->DR;
- }
-
- /* Wait the CRC data */
- if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
- errorcode = HAL_TIMEOUT;
- goto error;
- }
-
- /* Read CRC to Flush DR and RXNE flag */
- tmpreg = hspi->Instance->DR;
- /* To avoid GCC warning */
- UNUSED(tmpreg);
- }
-#endif /* USE_SPI_CRC */
-
- /* Check the end of the transaction */
- if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
- {
- /* Disable SPI peripheral */
- __HAL_SPI_DISABLE(hspi);
- }
-
-#if (USE_SPI_CRC != 0U)
- /* Check if CRC error occurred */
- if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
- {
- /* Check if CRC error is valid or not (workaround to be applied or not) */
- if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
-
- /* Reset CRC Calculation */
- SPI_RESET_CRC(hspi);
- }
- else
- {
- __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
- }
- }
-#endif /* USE_SPI_CRC */
-
- if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
- {
- errorcode = HAL_ERROR;
- }
-
-error :
- hspi->State = HAL_SPI_STATE_READY;
- __HAL_UNLOCK(hspi);
- return errorcode;
-}
-
-/**
- * @brief Transmit and Receive an amount of data in blocking mode.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @param pTxData: pointer to transmission data buffer
- * @param pRxData: pointer to reception data buffer
- * @param Size: amount of data to be sent and received
- * @param Timeout: Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
-{
- uint32_t tmp = 0U, tmp1 = 0U;
-#if (USE_SPI_CRC != 0U)
- __IO uint16_t tmpreg1 = 0U;
-#endif /* USE_SPI_CRC */
- uint32_t tickstart = 0U;
- /* Variable used to alternate Rx and Tx during transfer */
- uint32_t txallowed = 1U;
- HAL_StatusTypeDef errorcode = HAL_OK;
-
- /* Check Direction parameter */
- assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
-
- /* Process Locked */
- __HAL_LOCK(hspi);
-
- /* Init tickstart for timeout management*/
- tickstart = HAL_GetTick();
-
- tmp = hspi->State;
- tmp1 = hspi->Init.Mode;
-
- if(!((tmp == HAL_SPI_STATE_READY) || \
- ((tmp1 == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp == HAL_SPI_STATE_BUSY_RX))))
- {
- errorcode = HAL_BUSY;
- goto error;
- }
-
- if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
- {
- errorcode = HAL_ERROR;
- goto error;
- }
-
- /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
- if(hspi->State == HAL_SPI_STATE_READY)
- {
- hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
- }
-
- /* Set the transaction information */
- hspi->ErrorCode = HAL_SPI_ERROR_NONE;
- hspi->pRxBuffPtr = (uint8_t *)pRxData;
- hspi->RxXferCount = Size;
- hspi->RxXferSize = Size;
- hspi->pTxBuffPtr = (uint8_t *)pTxData;
- hspi->TxXferCount = Size;
- hspi->TxXferSize = Size;
-
- /*Init field not used in handle to zero */
- hspi->RxISR = NULL;
- hspi->TxISR = NULL;
-
-#if (USE_SPI_CRC != 0U)
- /* Reset CRC Calculation */
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- SPI_RESET_CRC(hspi);
- }
-#endif /* USE_SPI_CRC */
-
- /* Check if the SPI is already enabled */
- if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
- {
- /* Enable SPI peripheral */
- __HAL_SPI_ENABLE(hspi);
- }
-
- /* Transmit and Receive data in 16 Bit mode */
- if(hspi->Init.DataSize == SPI_DATASIZE_16BIT)
- {
- if((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01U))
- {
- hspi->Instance->DR = *((uint16_t *)pTxData);
- pTxData += sizeof(uint16_t);
- hspi->TxXferCount--;
- }
- while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
- {
- /* Check TXE flag */
- if(txallowed && (hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)))
- {
- hspi->Instance->DR = *((uint16_t *)pTxData);
- pTxData += sizeof(uint16_t);
- hspi->TxXferCount--;
- /* Next Data is a reception (Rx). Tx not allowed */
- txallowed = 0U;
-
-#if (USE_SPI_CRC != 0U)
- /* Enable CRC Transmission */
- if((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
- {
- SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
- }
-#endif /* USE_SPI_CRC */
- }
-
- /* Check RXNE flag */
- if((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)))
- {
- *((uint16_t *)pRxData) = hspi->Instance->DR;
- pRxData += sizeof(uint16_t);
- hspi->RxXferCount--;
- /* Next Data is a Transmission (Tx). Tx is allowed */
- txallowed = 1U;
- }
- if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout))
- {
- errorcode = HAL_TIMEOUT;
- goto error;
- }
- }
- }
- /* Transmit and Receive data in 8 Bit mode */
- else
- {
- if((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01U))
- {
- *((__IO uint8_t*)&hspi->Instance->DR) = (*pTxData);
- pTxData += sizeof(uint8_t);
- hspi->TxXferCount--;
- }
- while((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
- {
- /* check TXE flag */
- if(txallowed && (hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)))
- {
- *(__IO uint8_t *)&hspi->Instance->DR = (*pTxData++);
- hspi->TxXferCount--;
- /* Next Data is a reception (Rx). Tx not allowed */
- txallowed = 0U;
-
-#if (USE_SPI_CRC != 0U)
- /* Enable CRC Transmission */
- if((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
- {
- SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
- }
-#endif /* USE_SPI_CRC */
- }
-
- /* Wait until RXNE flag is reset */
- if((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)))
- {
- (*(uint8_t *)pRxData++) = hspi->Instance->DR;
- hspi->RxXferCount--;
- /* Next Data is a Transmission (Tx). Tx is allowed */
- txallowed = 1U;
- }
- if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout))
- {
- errorcode = HAL_TIMEOUT;
- goto error;
- }
- }
- }
-
-#if (USE_SPI_CRC != 0U)
- /* Read CRC from DR to close CRC calculation process */
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- /* Wait until TXE flag */
- if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
- {
- /* Error on the CRC reception */
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
- errorcode = HAL_TIMEOUT;
- goto error;
- }
- /* Read CRC */
- tmpreg1 = hspi->Instance->DR;
- /* To avoid GCC warning */
- UNUSED(tmpreg1);
- }
-
- /* Check if CRC error occurred */
- if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
- {
- /* Check if CRC error is valid or not (workaround to be applied or not) */
- if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
-
- /* Reset CRC Calculation */
- SPI_RESET_CRC(hspi);
-
- errorcode = HAL_ERROR;
- }
- else
- {
- __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
- }
- }
-#endif /* USE_SPI_CRC */
-
- /* Wait until TXE flag */
- if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_TXE, SET, Timeout, tickstart) != HAL_OK)
- {
- errorcode = HAL_TIMEOUT;
- goto error;
- }
-
- /* Check Busy flag */
- if(SPI_CheckFlag_BSY(hspi, Timeout, tickstart) != HAL_OK)
- {
- errorcode = HAL_ERROR;
- hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
- goto error;
- }
-
- /* Clear overrun flag in 2 Lines communication mode because received is not read */
- if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
- {
- __HAL_SPI_CLEAR_OVRFLAG(hspi);
- }
-
-error :
- hspi->State = HAL_SPI_STATE_READY;
- __HAL_UNLOCK(hspi);
- return errorcode;
-}
-
-/**
- * @brief Transmit an amount of data in non-blocking mode with Interrupt.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @param pData: pointer to data buffer
- * @param Size: amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
-{
- HAL_StatusTypeDef errorcode = HAL_OK;
-
- /* Check Direction parameter */
- assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
-
- /* Process Locked */
- __HAL_LOCK(hspi);
-
- if((pData == NULL) || (Size == 0U))
- {
- errorcode = HAL_ERROR;
- goto error;
- }
-
- if(hspi->State != HAL_SPI_STATE_READY)
- {
- errorcode = HAL_BUSY;
- goto error;
- }
-
- /* Set the transaction information */
- hspi->State = HAL_SPI_STATE_BUSY_TX;
- hspi->ErrorCode = HAL_SPI_ERROR_NONE;
- hspi->pTxBuffPtr = (uint8_t *)pData;
- hspi->TxXferSize = Size;
- hspi->TxXferCount = Size;
-
- /* Init field not used in handle to zero */
- hspi->pRxBuffPtr = (uint8_t *)NULL;
- hspi->RxXferSize = 0U;
- hspi->RxXferCount = 0U;
- hspi->RxISR = NULL;
-
- /* Set the function for IT treatment */
- if(hspi->Init.DataSize > SPI_DATASIZE_8BIT )
- {
- hspi->TxISR = SPI_TxISR_16BIT;
- }
- else
- {
- hspi->TxISR = SPI_TxISR_8BIT;
- }
-
- /* Configure communication direction : 1Line */
- if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
- {
- SPI_1LINE_TX(hspi);
- }
-
-#if (USE_SPI_CRC != 0U)
- /* Reset CRC Calculation */
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- SPI_RESET_CRC(hspi);
- }
-#endif /* USE_SPI_CRC */
-
- if (hspi->Init.Direction == SPI_DIRECTION_2LINES)
- {
- /* Enable TXE interrupt */
- __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE));
- }
- else
- {
- /* Enable TXE and ERR interrupt */
- __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR));
- }
-
- /* Check if the SPI is already enabled */
- if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
- {
- /* Enable SPI peripheral */
- __HAL_SPI_ENABLE(hspi);
- }
-
-error :
- __HAL_UNLOCK(hspi);
- return errorcode;
-}
-
-/**
- * @brief Receive an amount of data in non-blocking mode with Interrupt.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @param pData: pointer to data buffer
- * @param Size: amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
-{
- HAL_StatusTypeDef errorcode = HAL_OK;
-
- if((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER))
- {
- hspi->State = HAL_SPI_STATE_BUSY_RX;
- /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
- return HAL_SPI_TransmitReceive_IT(hspi, pData, pData, Size);
- }
-
- /* Process Locked */
- __HAL_LOCK(hspi);
-
- if(hspi->State != HAL_SPI_STATE_READY)
- {
- errorcode = HAL_BUSY;
- goto error;
- }
-
- if((pData == NULL) || (Size == 0U))
- {
- errorcode = HAL_ERROR;
- goto error;
- }
-
- /* Set the transaction information */
- hspi->State = HAL_SPI_STATE_BUSY_RX;
- hspi->ErrorCode = HAL_SPI_ERROR_NONE;
- hspi->pRxBuffPtr = (uint8_t *)pData;
- hspi->RxXferSize = Size;
- hspi->RxXferCount = Size;
-
- /* Init field not used in handle to zero */
- hspi->pTxBuffPtr = (uint8_t *)NULL;
- hspi->TxXferSize = 0U;
- hspi->TxXferCount = 0U;
- hspi->TxISR = NULL;
-
- /* Set the function for IT treatment */
- if(hspi->Init.DataSize > SPI_DATASIZE_8BIT )
- {
- hspi->RxISR = SPI_RxISR_16BIT;
- }
- else
- {
- hspi->RxISR = SPI_RxISR_8BIT;
- }
-
- /* Configure communication direction : 1Line */
- if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
- {
- SPI_1LINE_RX(hspi);
- }
-
-#if (USE_SPI_CRC != 0U)
- /* Reset CRC Calculation */
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- SPI_RESET_CRC(hspi);
- }
-#endif /* USE_SPI_CRC */
-
- /* Enable TXE and ERR interrupt */
- __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
-
- /* Note : The SPI must be enabled after unlocking current process
- to avoid the risk of SPI interrupt handle execution before current
- process unlock */
-
- /* Check if the SPI is already enabled */
- if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
- {
- /* Enable SPI peripheral */
- __HAL_SPI_ENABLE(hspi);
- }
-
-error :
- /* Process Unlocked */
- __HAL_UNLOCK(hspi);
- return errorcode;
-}
-
-/**
- * @brief Transmit and Receive an amount of data in non-blocking mode with Interrupt.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @param pTxData: pointer to transmission data buffer
- * @param pRxData: pointer to reception data buffer
- * @param Size: amount of data to be sent and received
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
-{
- uint32_t tmp = 0U, tmp1 = 0U;
- HAL_StatusTypeDef errorcode = HAL_OK;
-
- /* Check Direction parameter */
- assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
-
- /* Process locked */
- __HAL_LOCK(hspi);
-
- tmp = hspi->State;
- tmp1 = hspi->Init.Mode;
-
- if(!((tmp == HAL_SPI_STATE_READY) || \
- ((tmp1 == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp == HAL_SPI_STATE_BUSY_RX))))
- {
- errorcode = HAL_BUSY;
- goto error;
- }
-
- if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0U))
- {
- errorcode = HAL_ERROR;
- goto error;
- }
-
- /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
- if(hspi->State == HAL_SPI_STATE_READY)
- {
- hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
- }
-
- /* Set the transaction information */
- hspi->ErrorCode = HAL_SPI_ERROR_NONE;
- hspi->pTxBuffPtr = (uint8_t *)pTxData;
- hspi->TxXferSize = Size;
- hspi->TxXferCount = Size;
- hspi->pRxBuffPtr = (uint8_t *)pRxData;
- hspi->RxXferSize = Size;
- hspi->RxXferCount = Size;
-
- /* Set the function for IT treatment */
- if(hspi->Init.DataSize > SPI_DATASIZE_8BIT )
- {
- hspi->RxISR = SPI_2linesRxISR_16BIT;
- hspi->TxISR = SPI_2linesTxISR_16BIT;
- }
- else
- {
- hspi->RxISR = SPI_2linesRxISR_8BIT;
- hspi->TxISR = SPI_2linesTxISR_8BIT;
- }
-
-#if (USE_SPI_CRC != 0U)
- /* Reset CRC Calculation */
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- SPI_RESET_CRC(hspi);
- }
-#endif /* USE_SPI_CRC */
-
- /* Enable TXE, RXNE and ERR interrupt */
- __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
-
- /* Check if the SPI is already enabled */
- if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
- {
- /* Enable SPI peripheral */
- __HAL_SPI_ENABLE(hspi);
- }
-
-error :
- /* Process Unlocked */
- __HAL_UNLOCK(hspi);
- return errorcode;
-}
-
-/**
- * @brief Transmit an amount of data in non-blocking mode with DMA.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @param pData: pointer to data buffer
- * @param Size: amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
-{
- HAL_StatusTypeDef errorcode = HAL_OK;
-
- /* Check Direction parameter */
- assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
-
- /* Process Locked */
- __HAL_LOCK(hspi);
-
- if(hspi->State != HAL_SPI_STATE_READY)
- {
- errorcode = HAL_BUSY;
- goto error;
- }
-
- if((pData == NULL) || (Size == 0U))
- {
- errorcode = HAL_ERROR;
- goto error;
- }
-
- /* Set the transaction information */
- hspi->State = HAL_SPI_STATE_BUSY_TX;
- hspi->ErrorCode = HAL_SPI_ERROR_NONE;
- hspi->pTxBuffPtr = (uint8_t *)pData;
- hspi->TxXferSize = Size;
- hspi->TxXferCount = Size;
-
- /* Init field not used in handle to zero */
- hspi->pRxBuffPtr = (uint8_t *)NULL;
- hspi->TxISR = NULL;
- hspi->RxISR = NULL;
- hspi->RxXferSize = 0U;
- hspi->RxXferCount = 0U;
-
- /* Configure communication direction : 1Line */
- if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
- {
- SPI_1LINE_TX(hspi);
- }
-
-#if (USE_SPI_CRC != 0U)
- /* Reset CRC Calculation */
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- SPI_RESET_CRC(hspi);
- }
-#endif /* USE_SPI_CRC */
-
- /* Set the SPI TxDMA Half transfer complete callback */
- hspi->hdmatx->XferHalfCpltCallback = SPI_DMAHalfTransmitCplt;
-
- /* Set the SPI TxDMA transfer complete callback */
- hspi->hdmatx->XferCpltCallback = SPI_DMATransmitCplt;
-
- /* Set the DMA error callback */
- hspi->hdmatx->XferErrorCallback = SPI_DMAError;
-
- /* Set the DMA AbortCpltCallback */
- hspi->hdmatx->XferAbortCallback = NULL;
-
- /* Enable the Tx DMA Stream */
- HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, hspi->TxXferCount);
-
- /* Check if the SPI is already enabled */
- if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
- {
- /* Enable SPI peripheral */
- __HAL_SPI_ENABLE(hspi);
- }
-
- /* Enable the SPI Error Interrupt Bit */
- SET_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
-
- /* Enable Tx DMA Request */
- SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
-
-error :
- /* Process Unlocked */
- __HAL_UNLOCK(hspi);
- return errorcode;
-}
-
-/**
- * @brief Receive an amount of data in non-blocking mode with DMA.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @param pData: pointer to data buffer
- * @note When the CRC feature is enabled the pData Length must be Size + 1.
- * @param Size: amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
-{
- HAL_StatusTypeDef errorcode = HAL_OK;
-
- if((hspi->Init.Direction == SPI_DIRECTION_2LINES)&&(hspi->Init.Mode == SPI_MODE_MASTER))
- {
- hspi->State = HAL_SPI_STATE_BUSY_RX;
- /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
- return HAL_SPI_TransmitReceive_DMA(hspi, pData, pData, Size);
- }
-
- /* Process Locked */
- __HAL_LOCK(hspi);
-
- if(hspi->State != HAL_SPI_STATE_READY)
- {
- errorcode = HAL_BUSY;
- goto error;
- }
-
- if((pData == NULL) || (Size == 0U))
- {
- errorcode = HAL_ERROR;
- goto error;
- }
-
- /* Set the transaction information */
- hspi->State = HAL_SPI_STATE_BUSY_RX;
- hspi->ErrorCode = HAL_SPI_ERROR_NONE;
- hspi->pRxBuffPtr = (uint8_t *)pData;
- hspi->RxXferSize = Size;
- hspi->RxXferCount = Size;
-
- /*Init field not used in handle to zero */
- hspi->RxISR = NULL;
- hspi->TxISR = NULL;
- hspi->TxXferSize = 0U;
- hspi->TxXferCount = 0U;
-
- /* Configure communication direction : 1Line */
- if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
- {
- SPI_1LINE_RX(hspi);
- }
-
-#if (USE_SPI_CRC != 0U)
- /* Reset CRC Calculation */
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- SPI_RESET_CRC(hspi);
- }
-#endif /* USE_SPI_CRC */
-
- /* Set the SPI RxDMA Half transfer complete callback */
- hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
-
- /* Set the SPI Rx DMA transfer complete callback */
- hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;
-
- /* Set the DMA error callback */
- hspi->hdmarx->XferErrorCallback = SPI_DMAError;
-
- /* Set the DMA AbortCpltCallback */
- hspi->hdmarx->XferAbortCallback = NULL;
-
- /* Enable the Rx DMA Stream */
- HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount);
-
- /* Check if the SPI is already enabled */
- if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
- {
- /* Enable SPI peripheral */
- __HAL_SPI_ENABLE(hspi);
- }
-
- /* Enable the SPI Error Interrupt Bit */
- SET_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
-
- /* Enable Rx DMA Request */
- SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
-
-error:
- /* Process Unlocked */
- __HAL_UNLOCK(hspi);
- return errorcode;
-}
-
-/**
- * @brief Transmit and Receive an amount of data in non-blocking mode with DMA.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @param pTxData: pointer to transmission data buffer
- * @param pRxData: pointer to reception data buffer
- * @note When the CRC feature is enabled the pRxData Length must be Size + 1
- * @param Size: amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
-{
- uint32_t tmp = 0U, tmp1 = 0U;
- HAL_StatusTypeDef errorcode = HAL_OK;
-
- /* Check Direction parameter */
- assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
-
- /* Process locked */
- __HAL_LOCK(hspi);
-
- tmp = hspi->State;
- tmp1 = hspi->Init.Mode;
- if(!((tmp == HAL_SPI_STATE_READY) ||
- ((tmp1 == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp == HAL_SPI_STATE_BUSY_RX))))
- {
- errorcode = HAL_BUSY;
- goto error;
- }
-
- if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0U))
- {
- errorcode = HAL_ERROR;
- goto error;
- }
-
- /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
- if(hspi->State == HAL_SPI_STATE_READY)
- {
- hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
- }
-
- /* Set the transaction information */
- hspi->ErrorCode = HAL_SPI_ERROR_NONE;
- hspi->pTxBuffPtr = (uint8_t*)pTxData;
- hspi->TxXferSize = Size;
- hspi->TxXferCount = Size;
- hspi->pRxBuffPtr = (uint8_t*)pRxData;
- hspi->RxXferSize = Size;
- hspi->RxXferCount = Size;
-
- /* Init field not used in handle to zero */
- hspi->RxISR = NULL;
- hspi->TxISR = NULL;
-
-#if (USE_SPI_CRC != 0U)
- /* Reset CRC Calculation */
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- SPI_RESET_CRC(hspi);
- }
-#endif /* USE_SPI_CRC */
-
- /* Check if we are in Rx only or in Rx/Tx Mode and configure the DMA transfer complete callback */
- if(hspi->State == HAL_SPI_STATE_BUSY_RX)
- {
- /* Set the SPI Rx DMA Half transfer complete callback */
- hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
- hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;
- }
- else
- {
- /* Set the SPI Tx/Rx DMA Half transfer complete callback */
- hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt;
- hspi->hdmarx->XferCpltCallback = SPI_DMATransmitReceiveCplt;
- }
-
- /* Set the DMA error callback */
- hspi->hdmarx->XferErrorCallback = SPI_DMAError;
-
- /* Set the DMA AbortCpltCallback */
- hspi->hdmarx->XferAbortCallback = NULL;
-
- /* Enable the Rx DMA Stream */
- HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount);
-
- /* Enable Rx DMA Request */
- SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
-
- /* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing
- is performed in DMA reception complete callback */
- hspi->hdmatx->XferHalfCpltCallback = NULL;
- hspi->hdmatx->XferCpltCallback = NULL;
- hspi->hdmatx->XferErrorCallback = NULL;
- hspi->hdmatx->XferAbortCallback = NULL;
-
- /* Enable the Tx DMA Stream */
- HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, hspi->TxXferCount);
-
- /* Check if the SPI is already enabled */
- if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
- {
- /* Enable SPI peripheral */
- __HAL_SPI_ENABLE(hspi);
- }
- /* Enable the SPI Error Interrupt Bit */
- SET_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
-
- /* Enable Tx DMA Request */
- SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
-
-error :
- /* Process Unlocked */
- __HAL_UNLOCK(hspi);
- return errorcode;
-}
-
-/**
- * @brief Abort ongoing transfer (blocking mode).
- * @param hspi SPI handle.
- * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx),
- * started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable SPI Interrupts (depending of transfer direction)
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
- * - Set handle State to READY
- * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
- * @note Once transfer is aborted, the __HAL_SPI_CLEAR_OVRFLAG() macro must be called in user application
- * before starting new SPI receive process.
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi)
-{
- __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
-
- /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */
- if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE))
- {
- hspi->TxISR = SPI_AbortTx_ISR;
- }
-
- if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE))
- {
- hspi->RxISR = SPI_AbortRx_ISR;
- }
-
- /* Clear ERRIE interrupts in case of DMA Mode */
- CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
-
- /* Disable the SPI DMA Tx or SPI DMA Rx request if enabled */
- if ((HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN)) || (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN)))
- {
- /* Abort the SPI DMA Tx channel : use blocking DMA Abort API (no callback) */
- if(hspi->hdmatx != NULL)
- {
- /* Set the SPI DMA Abort callback :
- will lead to call HAL_SPI_AbortCpltCallback() at end of DMA abort procedure */
- hspi->hdmatx->XferAbortCallback = NULL;
-
- /* Abort DMA Tx Handle linked to SPI Peripheral */
- HAL_DMA_Abort(hspi->hdmatx);
-
- /* Disable Tx DMA Request */
- CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN));
-
- /* Wait until TXE flag is set */
- do
- {
- if(count-- == 0U)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
- break;
- }
- }
- while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
- }
- /* Abort the SPI DMA Rx channel : use blocking DMA Abort API (no callback) */
- if(hspi->hdmarx != NULL)
- {
- /* Set the SPI DMA Abort callback :
- will lead to call HAL_SPI_AbortCpltCallback() at end of DMA abort procedure */
- hspi->hdmarx->XferAbortCallback = NULL;
-
- /* Abort DMA Rx Handle linked to SPI Peripheral */
- HAL_DMA_Abort(hspi->hdmarx);
-
- /* Disable peripheral */
- __HAL_SPI_DISABLE(hspi);
-
- /* Disable Rx DMA Request */
- CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_RXDMAEN));
-
- }
- }
- /* Reset Tx and Rx transfer counters */
- hspi->RxXferCount = 0U;
- hspi->TxXferCount = 0U;
-
- /* Reset errorCode */
- hspi->ErrorCode = HAL_SPI_ERROR_NONE;
-
- /* Clear the Error flags in the SR register */
- __HAL_SPI_CLEAR_OVRFLAG(hspi);
-
- /* Restore hspi->state to ready */
- hspi->State = HAL_SPI_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing transfer (Interrupt mode).
- * @param hspi SPI handle.
- * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx),
- * started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable SPI Interrupts (depending of transfer direction)
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
- * - Set handle State to READY
- * - At abort completion, call user abort complete callback
- * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
- * considered as completed only when user abort complete callback is executed (not when exiting function).
- * @note Once transfer is aborted, the __HAL_SPI_CLEAR_OVRFLAG() macro must be called in user application
- * before starting new SPI receive process.
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi)
-{
- uint32_t abortcplt;
-
- /* Change Rx and Tx Irq Handler to Disable TXEIE, RXNEIE and ERRIE interrupts */
- if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE))
- {
- hspi->TxISR = SPI_AbortTx_ISR;
- }
-
- if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE))
- {
- hspi->RxISR = SPI_AbortRx_ISR;
- }
-
- /* Clear ERRIE interrupts in case of DMA Mode */
- CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
-
- abortcplt = 1U;
-
- /* If DMA Tx and/or DMA Rx Handles are associated to SPI Handle, DMA Abort complete callbacks should be initialised
- before any call to DMA Abort functions */
- /* DMA Tx Handle is valid */
- if(hspi->hdmatx != NULL)
- {
- /* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
- Otherwise, set it to NULL */
- if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN))
- {
- hspi->hdmatx->XferAbortCallback = SPI_DMATxAbortCallback;
- }
- else
- {
- hspi->hdmatx->XferAbortCallback = NULL;
- }
- }
- /* DMA Rx Handle is valid */
- if(hspi->hdmarx != NULL)
- {
- /* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
- Otherwise, set it to NULL */
- if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN))
- {
- hspi->hdmarx->XferAbortCallback = SPI_DMARxAbortCallback;
- }
- else
- {
- hspi->hdmarx->XferAbortCallback = NULL;
- }
- }
-
- /* Disable the SPI DMA Tx or the SPI Rx request if enabled */
- if((HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN)) && (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN)))
- {
- /* Abort the SPI DMA Tx channel */
- if(hspi->hdmatx != NULL)
- {
- /* Abort DMA Tx Handle linked to SPI Peripheral */
- if(HAL_DMA_Abort_IT(hspi->hdmatx) != HAL_OK)
- {
- hspi->hdmatx->XferAbortCallback = NULL;
- }
- else
- {
- abortcplt = 0U;
- }
- }
- /* Abort the SPI DMA Rx channel */
- if(hspi->hdmarx != NULL)
- {
- /* Abort DMA Rx Handle linked to SPI Peripheral */
- if(HAL_DMA_Abort_IT(hspi->hdmarx)!= HAL_OK)
- {
- hspi->hdmarx->XferAbortCallback = NULL;
- abortcplt = 1U;
- }
- else
- {
- abortcplt = 0U;
- }
- }
- }
-
- /* Disable the SPI DMA Tx or the SPI Rx request if enabled */
- if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN))
- {
- /* Abort the SPI DMA Tx channel */
- if(hspi->hdmatx != NULL)
- {
- /* Abort DMA Tx Handle linked to SPI Peripheral */
- if(HAL_DMA_Abort_IT(hspi->hdmatx) != HAL_OK)
- {
- hspi->hdmatx->XferAbortCallback = NULL;
- }
- else
- {
- abortcplt = 0U;
- }
- }
- }
- /* Disable the SPI DMA Tx or the SPI Rx request if enabled */
- if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN))
- {
- /* Abort the SPI DMA Rx channel */
- if(hspi->hdmarx != NULL)
- {
- /* Abort DMA Rx Handle linked to SPI Peripheral */
- if(HAL_DMA_Abort_IT(hspi->hdmarx)!= HAL_OK)
- {
- hspi->hdmarx->XferAbortCallback = NULL;
- }
- else
- {
- abortcplt = 0U;
- }
- }
- }
-
- if(abortcplt == 1U)
- {
- /* Reset Tx and Rx transfer counters */
- hspi->RxXferCount = 0U;
- hspi->TxXferCount = 0U;
-
- /* Reset errorCode */
- hspi->ErrorCode = HAL_SPI_ERROR_NONE;
-
- /* Clear the Error flags in the SR register */
- __HAL_SPI_CLEAR_OVRFLAG(hspi);
-
- /* Restore hspi->State to Ready */
- hspi->State = HAL_SPI_STATE_READY;
-
- /* As no DMA to be aborted, call directly user Abort complete callback */
- HAL_SPI_AbortCpltCallback(hspi);
- }
- return HAL_OK;
-}
-
-/**
- * @brief Pause the DMA Transfer.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for the specified SPI module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi)
-{
- /* Process Locked */
- __HAL_LOCK(hspi);
-
- /* Disable the SPI DMA Tx & Rx requests */
- CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
-
- /* Process Unlocked */
- __HAL_UNLOCK(hspi);
-
- return HAL_OK;
-}
-
-/**
- * @brief Resume the DMA Transfer.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for the specified SPI module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi)
-{
- /* Process Locked */
- __HAL_LOCK(hspi);
-
- /* Enable the SPI DMA Tx & Rx requests */
- SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
-
- /* Process Unlocked */
- __HAL_UNLOCK(hspi);
-
- return HAL_OK;
-}
-
-/**
- * @brief Stop the DMA Transfer.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for the specified SPI module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi)
-{
- /* The Lock is not implemented on this API to allow the user application
- to call the HAL SPI API under callbacks HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback():
- when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
- and the correspond call back is executed HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback()
- */
-
- /* Abort the SPI DMA tx Stream */
- if(hspi->hdmatx != NULL)
- {
- HAL_DMA_Abort(hspi->hdmatx);
- }
- /* Abort the SPI DMA rx Stream */
- if(hspi->hdmarx != NULL)
- {
- HAL_DMA_Abort(hspi->hdmarx);
- }
-
- /* Disable the SPI DMA Tx & Rx requests */
- CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
- hspi->State = HAL_SPI_STATE_READY;
- return HAL_OK;
-}
-
-/**
- * @brief Handle SPI interrupt request.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for the specified SPI module.
- * @retval None
- */
-void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
-{
- uint32_t itsource = hspi->Instance->CR2;
- uint32_t itflag = hspi->Instance->SR;
-
- /* SPI in mode Receiver ----------------------------------------------------*/
- if(((itflag & SPI_FLAG_OVR) == RESET) &&
- ((itflag & SPI_FLAG_RXNE) != RESET) && ((itsource & SPI_IT_RXNE) != RESET))
- {
- hspi->RxISR(hspi);
- return;
- }
-
- /* SPI in mode Transmitter -------------------------------------------------*/
- if(((itflag & SPI_FLAG_TXE) != RESET) && ((itsource & SPI_IT_TXE) != RESET))
- {
- hspi->TxISR(hspi);
- return;
- }
-
- /* SPI in Error Treatment --------------------------------------------------*/
- if(((itflag & (SPI_FLAG_MODF | SPI_FLAG_OVR)) != RESET) && ((itsource & SPI_IT_ERR) != RESET))
- {
- /* SPI Overrun error interrupt occurred ----------------------------------*/
- if((itflag & SPI_FLAG_OVR) != RESET)
- {
- if(hspi->State != HAL_SPI_STATE_BUSY_TX)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR);
- __HAL_SPI_CLEAR_OVRFLAG(hspi);
- }
- else
- {
- __HAL_SPI_CLEAR_OVRFLAG(hspi);
- return;
- }
- }
-
- /* SPI Mode Fault error interrupt occurred -------------------------------*/
- if((itflag & SPI_FLAG_MODF) != RESET)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF);
- __HAL_SPI_CLEAR_MODFFLAG(hspi);
- }
-
- if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
- {
- /* Disable all interrupts */
- __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE | SPI_IT_TXE | SPI_IT_ERR);
-
- hspi->State = HAL_SPI_STATE_READY;
- /* Disable the SPI DMA requests if enabled */
- if ((HAL_IS_BIT_SET(itsource, SPI_CR2_TXDMAEN))||(HAL_IS_BIT_SET(itsource, SPI_CR2_RXDMAEN)))
- {
- CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN));
-
- /* Abort the SPI DMA Rx channel */
- if(hspi->hdmarx != NULL)
- {
- /* Set the SPI DMA Abort callback :
- will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
- hspi->hdmarx->XferAbortCallback = SPI_DMAAbortOnError;
- HAL_DMA_Abort_IT(hspi->hdmarx);
- }
- /* Abort the SPI DMA Tx channel */
- if(hspi->hdmatx != NULL)
- {
- /* Set the SPI DMA Abort callback :
- will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
- hspi->hdmatx->XferAbortCallback = SPI_DMAAbortOnError;
- HAL_DMA_Abort_IT(hspi->hdmatx);
- }
- }
- else
- {
- /* Call user error callback */
- HAL_SPI_ErrorCallback(hspi);
- }
- }
- return;
- }
-}
-
-/**
- * @brief Tx Transfer completed callback.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-__weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hspi);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_SPI_TxCpltCallback should be implemented in the user file
- */
-}
-
-/**
- * @brief Rx Transfer completed callback.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-__weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hspi);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_SPI_RxCpltCallback should be implemented in the user file
- */
-}
-
-/**
- * @brief Tx and Rx Transfer completed callback.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-__weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hspi);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_SPI_TxRxCpltCallback should be implemented in the user file
- */
-}
-
-/**
- * @brief Tx Half Transfer completed callback.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-__weak void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hspi);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_SPI_TxHalfCpltCallback should be implemented in the user file
- */
-}
-
-/**
- * @brief Rx Half Transfer completed callback.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-__weak void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hspi);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_SPI_RxHalfCpltCallback() should be implemented in the user file
- */
-}
-
-/**
- * @brief Tx and Rx Half Transfer callback.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-__weak void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hspi);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_SPI_TxRxHalfCpltCallback() should be implemented in the user file
- */
-}
-
-/**
- * @brief SPI error callback.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
- __weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hspi);
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_SPI_ErrorCallback should be implemented in the user file
- */
- /* NOTE : The ErrorCode parameter in the hspi handle is updated by the SPI processes
- and user can use HAL_SPI_GetError() API to check the latest error occurred
- */
-}
-
-/**
- * @brief SPI Abort Complete callback.
- * @param hspi SPI handle.
- * @retval None
- */
-__weak void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hspi);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_SPI_AbortCpltCallback can be implemented in the user file.
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions
- * @brief SPI control functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral State and Errors functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to control the SPI.
- (+) HAL_SPI_GetState() API can be helpful to check in run-time the state of the SPI peripheral
- (+) HAL_SPI_GetError() check in run-time Errors occurring during communication
-@endverbatim
- * @{
- */
-
-/**
- * @brief Return the SPI handle state.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval SPI state
- */
-HAL_SPI_StateTypeDef HAL_SPI_GetState(SPI_HandleTypeDef *hspi)
-{
- /* Return SPI handle state */
- return hspi->State;
-}
-
-/**
- * @brief Return the SPI error code.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval SPI error code in bitmap format
- */
-uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi)
-{
- /* Return SPI ErrorCode */
- return hspi->ErrorCode;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup SPI_Private_Functions
- * @brief Private functions
- * @{
- */
-
-/**
- * @brief DMA SPI transmit process complete callback.
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
-{
- SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- uint32_t tickstart = 0U;
-
- /* Init tickstart for timeout managment*/
- tickstart = HAL_GetTick();
-
- /* DMA Normal Mode */
- if((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC)
- {
- /* Disable Tx DMA Request */
- CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
-
- /* Check the end of the transaction */
- if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
- }
-
- /* Clear overrun flag in 2 Lines communication mode because received data is not read */
- if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
- {
- __HAL_SPI_CLEAR_OVRFLAG(hspi);
- }
-
- hspi->TxXferCount = 0U;
- hspi->State = HAL_SPI_STATE_READY;
-
- if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
- {
- HAL_SPI_ErrorCallback(hspi);
- return;
- }
- }
- HAL_SPI_TxCpltCallback(hspi);
-}
-
-/**
- * @brief DMA SPI receive process complete callback.
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
-{
- SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-#if (USE_SPI_CRC != 0U)
- uint32_t tickstart = 0U;
- __IO uint16_t tmpreg = 0U;
-
- /* Init tickstart for timeout management*/
- tickstart = HAL_GetTick();
-#endif /* USE_SPI_CRC */
-
- if((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC)
- {
-#if (USE_SPI_CRC != 0U)
- /* CRC handling */
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- /* Wait until RXNE flag */
- if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SPI_FLAG_RXNE, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
- {
- /* Error on the CRC reception */
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
- }
- /* Read CRC */
- tmpreg = hspi->Instance->DR;
- /* To avoid GCC warning */
- UNUSED(tmpreg);
- }
-#endif /* USE_SPI_CRC */
-
- /* Disable Rx/Tx DMA Request (done by default to handle the case master rx direction 2 lines) */
- CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
-
- /* Check the end of the transaction */
- if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
- {
- /* Disable SPI peripheral */
- __HAL_SPI_DISABLE(hspi);
- }
-
- hspi->RxXferCount = 0U;
- hspi->State = HAL_SPI_STATE_READY;
-
-#if (USE_SPI_CRC != 0U)
- /* Check if CRC error occurred */
- if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
- {
- /* Check if CRC error is valid or not (workaround to be applied or not) */
- if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
-
- /* Reset CRC Calculation */
- SPI_RESET_CRC(hspi);
- }
- else
- {
- __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
- }
- }
-#endif /* USE_SPI_CRC */
-
- if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
- {
- HAL_SPI_ErrorCallback(hspi);
- return;
- }
- }
- HAL_SPI_RxCpltCallback(hspi);
-}
-
-/**
- * @brief DMA SPI transmit receive process complete callback.
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma)
-{
- SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- uint32_t tickstart = 0U;
-#if (USE_SPI_CRC != 0U)
- __IO int16_t tmpreg = 0U;
-#endif /* USE_SPI_CRC */
- /* Init tickstart for timeout management*/
- tickstart = HAL_GetTick();
-
- if((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC)
- {
-#if (USE_SPI_CRC != 0U)
- /* CRC handling */
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- /* Wait the CRC data */
- if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
- }
- /* Read CRC to Flush DR and RXNE flag */
- tmpreg = hspi->Instance->DR;
- /* To avoid GCC warning */
- UNUSED(tmpreg);
- }
-#endif /* USE_SPI_CRC */
- /* Check the end of the transaction */
- if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
- }
-
- /* Disable Rx/Tx DMA Request */
- CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
-
- hspi->TxXferCount = 0U;
- hspi->RxXferCount = 0U;
- hspi->State = HAL_SPI_STATE_READY;
-
-#if (USE_SPI_CRC != 0U)
- /* Check if CRC error occurred */
- if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
- {
- /* Check if CRC error is valid or not (workaround to be applied or not) */
- if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
-
- /* Reset CRC Calculation */
- SPI_RESET_CRC(hspi);
- }
- else
- {
- __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
- }
- }
-#endif /* USE_SPI_CRC */
-
- if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
- {
- HAL_SPI_ErrorCallback(hspi);
- return;
- }
- }
- HAL_SPI_TxRxCpltCallback(hspi);
-}
-
-/**
- * @brief DMA SPI half transmit process complete callback.
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma)
-{
- SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- HAL_SPI_TxHalfCpltCallback(hspi);
-}
-
-/**
- * @brief DMA SPI half receive process complete callback
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma)
-{
- SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- HAL_SPI_RxHalfCpltCallback(hspi);
-}
-
-/**
- * @brief DMA SPI half transmit receive process complete callback.
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma)
-{
- SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- HAL_SPI_TxRxHalfCpltCallback(hspi);
-}
-
-/**
- * @brief DMA SPI communication error callback.
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void SPI_DMAError(DMA_HandleTypeDef *hdma)
-{
- SPI_HandleTypeDef* hspi = (SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
-/* Stop the disable DMA transfer on SPI side */
- CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
-
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
- hspi->State = HAL_SPI_STATE_READY;
- HAL_SPI_ErrorCallback(hspi);
-}
-
-/**
- * @brief DMA SPI communication abort callback, when initiated by HAL services on Error
- * (To be called at end of DMA Abort procedure following error occurrence).
- * @param hdma DMA handle.
- * @retval None
- */
-static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma)
-{
- SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- hspi->RxXferCount = 0U;
- hspi->TxXferCount = 0U;
-
- HAL_SPI_ErrorCallback(hspi);
-}
-
-/**
- * @brief DMA SPI Tx communication abort callback, when initiated by user
- * (To be called at end of DMA Tx Abort procedure following user abort request).
- * @note When this callback is executed, User Abort complete call back is called only if no
- * Abort still ongoing for Rx DMA Handle.
- * @param hdma DMA handle.
- * @retval None
- */
-static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
-{
- __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
- SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- hspi->hdmatx->XferAbortCallback = NULL;
-
- /* Disable Tx DMA Request */
- CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN );
-
- /* Wait until TXE flag is set */
- do
- {
- if(count-- == 0U)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
- break;
- }
- }
- while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
-
- /* Check if an Abort process is still ongoing */
- if(hspi->hdmarx != NULL)
- {
- if(hspi->hdmarx->XferAbortCallback != NULL)
- {
- return;
- }
- }
-
- /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
- hspi->RxXferCount = 0U;
- hspi->TxXferCount = 0U;
-
- /* Reset errorCode */
- hspi->ErrorCode = HAL_SPI_ERROR_NONE;
-
- /* Restore hspi->State to Ready */
- hspi->State = HAL_SPI_STATE_READY;
-
- /* Call user Abort complete callback */
- HAL_SPI_AbortCpltCallback(hspi);
-}
-
-/**
- * @brief DMA SPI Rx communication abort callback, when initiated by user
- * (To be called at end of DMA Rx Abort procedure following user abort request).
- * @note When this callback is executed, User Abort complete call back is called only if no
- * Abort still ongoing for Tx DMA Handle.
- * @param hdma DMA handle.
- * @retval None
- */
-static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
-{
- SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- /* Disable SPI Peripheral */
- __HAL_SPI_DISABLE(hspi);
-
- hspi->hdmarx->XferAbortCallback = NULL;
-
- /* Disable Rx DMA Request */
- CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
-
- /* Check if an Abort process is still ongoing */
- if(hspi->hdmatx != NULL)
- {
- if(hspi->hdmatx->XferAbortCallback != NULL)
- {
- return;
- }
- }
-
- /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
- hspi->RxXferCount = 0U;
- hspi->TxXferCount = 0U;
-
- /* Reset errorCode */
- hspi->ErrorCode = HAL_SPI_ERROR_NONE;
-
- /* Clear the Error flags in the SR register */
- __HAL_SPI_CLEAR_OVRFLAG(hspi);
-
- /* Restore hspi->State to Ready */
- hspi->State = HAL_SPI_STATE_READY;
-
- /* Call user Abort complete callback */
- HAL_SPI_AbortCpltCallback(hspi);
-}
-
-/**
- * @brief Rx 8-bit handler for Transmit and Receive in Interrupt mode.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
-{
- /* Receive data in 8bit mode */
- *hspi->pRxBuffPtr++ = *((__IO uint8_t *)&hspi->Instance->DR);
- hspi->RxXferCount--;
-
- /* check end of the reception */
- if(hspi->RxXferCount == 0U)
- {
-#if (USE_SPI_CRC != 0U)
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- hspi->RxISR = SPI_2linesRxISR_8BITCRC;
- return;
- }
-#endif /* USE_SPI_CRC */
-
- /* Disable RXNE interrupt */
- __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
-
- if(hspi->TxXferCount == 0U)
- {
- SPI_CloseRxTx_ISR(hspi);
- }
- }
-}
-
-#if (USE_SPI_CRC != 0U)
-/**
- * @brief Rx 8-bit handler for Transmit and Receive in Interrupt mode.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi)
-{
- __IO uint8_t tmpreg = 0U;
-
- /* Read data register to flush CRC */
- tmpreg = *((__IO uint8_t *)&hspi->Instance->DR);
-
- /* To avoid GCC warning */
-
- UNUSED(tmpreg);
-
- /* Disable RXNE interrupt */
- __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
-
- if(hspi->TxXferCount == 0U)
- {
- SPI_CloseRxTx_ISR(hspi);
- }
-}
-#endif /* USE_SPI_CRC */
-
-/**
- * @brief Tx 8-bit handler for Transmit and Receive in Interrupt mode.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
-{
- *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr++);
- hspi->TxXferCount--;
-
- /* check the end of the transmission */
- if(hspi->TxXferCount == 0U)
- {
-#if (USE_SPI_CRC != 0U)
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
- __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
- return;
- }
-#endif /* USE_SPI_CRC */
-
- /* Disable TXE interrupt */
- __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
-
- if(hspi->RxXferCount == 0U)
- {
- SPI_CloseRxTx_ISR(hspi);
- }
- }
-}
-
-/**
- * @brief Rx 16-bit handler for Transmit and Receive in Interrupt mode.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
-{
- /* Receive data in 16 Bit mode */
- *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;
- hspi->pRxBuffPtr += sizeof(uint16_t);
- hspi->RxXferCount--;
-
- if(hspi->RxXferCount == 0U)
- {
-#if (USE_SPI_CRC != 0U)
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- hspi->RxISR = SPI_2linesRxISR_16BITCRC;
- return;
- }
-#endif /* USE_SPI_CRC */
-
- /* Disable RXNE interrupt */
- __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE);
-
- if(hspi->TxXferCount == 0U)
- {
- SPI_CloseRxTx_ISR(hspi);
- }
- }
-}
-
-#if (USE_SPI_CRC != 0U)
-/**
- * @brief Manage the CRC 16-bit receive for Transmit and Receive in Interrupt mode.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi)
-{
- /* Receive data in 16 Bit mode */
- __IO uint16_t tmpreg = 0U;
-
- /* Read data register to flush CRC */
- tmpreg = hspi->Instance->DR;
-
- /* To avoid GCC warning */
- UNUSED(tmpreg);
-
- /* Disable RXNE interrupt */
- __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE);
-
- SPI_CloseRxTx_ISR(hspi);
-}
-#endif /* USE_SPI_CRC */
-
-/**
- * @brief Tx 16-bit handler for Transmit and Receive in Interrupt mode.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
-{
- /* Transmit data in 16 Bit mode */
- hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
- hspi->pTxBuffPtr += sizeof(uint16_t);
- hspi->TxXferCount--;
-
- /* Enable CRC Transmission */
- if(hspi->TxXferCount == 0U)
- {
-#if (USE_SPI_CRC != 0U)
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
- __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
- return;
- }
-#endif /* USE_SPI_CRC */
-
- /* Disable TXE interrupt */
- __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
-
- if(hspi->RxXferCount == 0U)
- {
- SPI_CloseRxTx_ISR(hspi);
- }
- }
-}
-
-#if (USE_SPI_CRC != 0U)
-/**
- * @brief Manage the CRC 8-bit receive in Interrupt context.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi)
-{
- __IO uint8_t tmpreg = 0U;
-
- /* Read data register to flush CRC */
- tmpreg = *((__IO uint8_t*)&hspi->Instance->DR);
-
- /* To avoid GCC warning */
- UNUSED(tmpreg);
-
- SPI_CloseRx_ISR(hspi);
-}
-#endif /* USE_SPI_CRC */
-
-/**
- * @brief Manage the receive 8-bit in Interrupt context.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
-{
- *hspi->pRxBuffPtr++ = (*(__IO uint8_t *)&hspi->Instance->DR);
- hspi->RxXferCount--;
-
-#if (USE_SPI_CRC != 0U)
- /* Enable CRC Transmission */
- if((hspi->RxXferCount == 1U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
- {
- SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
- }
-#endif /* USE_SPI_CRC */
-
- if(hspi->RxXferCount == 0U)
- {
-#if (USE_SPI_CRC != 0U)
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- hspi->RxISR = SPI_RxISR_8BITCRC;
- return;
- }
-#endif /* USE_SPI_CRC */
- SPI_CloseRx_ISR(hspi);
- }
-}
-
-#if (USE_SPI_CRC != 0U)
-/**
- * @brief Manage the CRC 16-bit receive in Interrupt context.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi)
-{
- __IO uint16_t tmpreg = 0U;
-
- /* Read data register to flush CRC */
- tmpreg = hspi->Instance->DR;
-
- /* To avoid GCC warning */
- UNUSED(tmpreg);
-
- /* Disable RXNE and ERR interrupt */
- __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
-
- SPI_CloseRx_ISR(hspi);
-}
-#endif /* USE_SPI_CRC */
-
-/**
- * @brief Manage the 16-bit receive in Interrupt context.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
-{
- *((uint16_t *)hspi->pRxBuffPtr) = hspi->Instance->DR;
- hspi->pRxBuffPtr += sizeof(uint16_t);
- hspi->RxXferCount--;
-
-#if (USE_SPI_CRC != 0U)
- /* Enable CRC Transmission */
- if((hspi->RxXferCount == 1U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
- {
- SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
- }
-#endif /* USE_SPI_CRC */
-
- if(hspi->RxXferCount == 0U)
- {
-#if (USE_SPI_CRC != 0U)
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- hspi->RxISR = SPI_RxISR_16BITCRC;
- return;
- }
-#endif /* USE_SPI_CRC */
- SPI_CloseRx_ISR(hspi);
- }
-}
-
-/**
- * @brief Handle the data 8-bit transmit in Interrupt mode.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
-{
- *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr++);
- hspi->TxXferCount--;
-
- if(hspi->TxXferCount == 0U)
- {
-#if (USE_SPI_CRC != 0U)
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- /* Enable CRC Transmission */
- SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
- }
-#endif /* USE_SPI_CRC */
- SPI_CloseTx_ISR(hspi);
- }
-}
-
-/**
- * @brief Handle the data 16-bit transmit in Interrupt mode.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
-{
- /* Transmit data in 16 Bit mode */
- hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
- hspi->pTxBuffPtr += sizeof(uint16_t);
- hspi->TxXferCount--;
-
- if(hspi->TxXferCount == 0U)
- {
-#if (USE_SPI_CRC != 0U)
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- /* Enable CRC Transmission */
- SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
- }
-#endif /* USE_SPI_CRC */
- SPI_CloseTx_ISR(hspi);
- }
-}
-
-/**
- * @brief Handle SPI Communication Timeout.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @param Flag: SPI flag to check
- * @param State: flag state to check
- * @param Timeout: Timeout duration
- * @param Tickstart: tick start value
- * @retval HAL status
- */
-static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, uint32_t State, uint32_t Timeout, uint32_t Tickstart)
-{
- while((((hspi->Instance->SR & Flag) == (Flag)) ? SET : RESET) != State)
- {
- if(Timeout != HAL_MAX_DELAY)
- {
- if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) >= Timeout))
- {
- /* Disable the SPI and reset the CRC: the CRC value should be cleared
- on both master and slave sides in order to resynchronize the master
- and slave for their respective CRC calculation */
-
- /* Disable TXE, RXNE and ERR interrupts for the interrupt process */
- __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
-
- if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
- {
- /* Disable SPI peripheral */
- __HAL_SPI_DISABLE(hspi);
- }
-
- /* Reset CRC Calculation */
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- SPI_RESET_CRC(hspi);
- }
-
- hspi->State= HAL_SPI_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hspi);
-
- return HAL_TIMEOUT;
- }
- }
- }
-
- return HAL_OK;
-}
-/**
- * @brief Handle to check BSY flag before start a new transaction.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @param Timeout: Timeout duration
- * @param Tickstart: tick start value
- * @retval HAL status
- */
-static HAL_StatusTypeDef SPI_CheckFlag_BSY(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart)
-{
- /* Control the BSY flag */
- if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, Timeout, Tickstart) != HAL_OK)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
- return HAL_TIMEOUT;
- }
- return HAL_OK;
-}
-
-/**
- * @brief Handle the end of the RXTX transaction.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi)
-{
- uint32_t tickstart = 0U;
- __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
- /* Init tickstart for timeout managment*/
- tickstart = HAL_GetTick();
-
- /* Disable ERR interrupt */
- __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR);
-
- /* Wait until TXE flag is set */
- do
- {
- if(count-- == 0U)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
- break;
- }
- }
- while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
-
- /* Check the end of the transaction */
- if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart)!=HAL_OK)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
- }
-
- /* Clear overrun flag in 2 Lines communication mode because received is not read */
- if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
- {
- __HAL_SPI_CLEAR_OVRFLAG(hspi);
- }
-
-#if (USE_SPI_CRC != 0U)
- /* Check if CRC error occurred */
- if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
- {
- /* Check if CRC error is valid or not (workaround to be applied or not) */
- if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
- {
- hspi->State = HAL_SPI_STATE_READY;
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
-
- /* Reset CRC Calculation */
- SPI_RESET_CRC(hspi);
-
- HAL_SPI_ErrorCallback(hspi);
- }
- else
- {
- __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
- }
- }
- else
- {
-#endif /* USE_SPI_CRC */
- if(hspi->ErrorCode == HAL_SPI_ERROR_NONE)
- {
- if(hspi->State == HAL_SPI_STATE_BUSY_RX)
- {
- hspi->State = HAL_SPI_STATE_READY;
- HAL_SPI_RxCpltCallback(hspi);
- }
- else
- {
- hspi->State = HAL_SPI_STATE_READY;
- HAL_SPI_TxRxCpltCallback(hspi);
- }
- }
- else
- {
- hspi->State = HAL_SPI_STATE_READY;
- HAL_SPI_ErrorCallback(hspi);
- }
-#if (USE_SPI_CRC != 0U)
- }
-#endif /* USE_SPI_CRC */
-}
-
-/**
- * @brief Handle the end of the RX transaction.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi)
-{
- /* Disable RXNE and ERR interrupt */
- __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
-
- /* Check the end of the transaction */
- if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
- {
- /* Disable SPI peripheral */
- __HAL_SPI_DISABLE(hspi);
- }
-
- /* Clear overrun flag in 2 Lines communication mode because received is not read */
- if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
- {
- __HAL_SPI_CLEAR_OVRFLAG(hspi);
- }
- hspi->State = HAL_SPI_STATE_READY;
-
-#if (USE_SPI_CRC != 0U)
- /* Check if CRC error occurred */
- if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
- {
- /* Check if CRC error is valid or not (workaround to be applied or not) */
- if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
-
- /* Reset CRC Calculation */
- SPI_RESET_CRC(hspi);
-
- HAL_SPI_ErrorCallback(hspi);
- }
- else
- {
- __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
- }
- }
- else
- {
-#endif /* USE_SPI_CRC */
- if(hspi->ErrorCode == HAL_SPI_ERROR_NONE)
- {
- HAL_SPI_RxCpltCallback(hspi);
- }
- else
- {
- HAL_SPI_ErrorCallback(hspi);
- }
-#if (USE_SPI_CRC != 0U)
- }
-#endif /* USE_SPI_CRC */
-}
-
-/**
- * @brief Handle the end of the TX transaction.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi)
-{
- uint32_t tickstart = 0U;
- __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
-
- /* Init tickstart for timeout management*/
- tickstart = HAL_GetTick();
-
- /* Wait until TXE flag is set */
- do
- {
- if(count-- == 0U)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
- break;
- }
- }
- while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
-
- /* Disable TXE and ERR interrupt */
- __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR));
-
- /* Check Busy flag */
- if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
- }
-
- /* Clear overrun flag in 2 Lines communication mode because received is not read */
- if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
- {
- __HAL_SPI_CLEAR_OVRFLAG(hspi);
- }
-
- hspi->State = HAL_SPI_STATE_READY;
- if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
- {
- HAL_SPI_ErrorCallback(hspi);
- }
- else
- {
- HAL_SPI_TxCpltCallback(hspi);
- }
-}
-
-/**
- * @}
- */
-
-/**
- * @brief Handle abort a Tx or Rx transaction.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi)
-{
- __IO uint32_t tmpreg = 0U;
- __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
-
- /* Wait until TXE flag is set */
- do
- {
- if(count-- == 0U)
- {
- SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
- break;
- }
- }
- while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
-
- /* Disable SPI Peripheral */
- __HAL_SPI_DISABLE(hspi);
-
- /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */
- CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXEIE | SPI_CR2_RXNEIE | SPI_CR2_ERRIE));
-
- /* Flush DR Register */
- tmpreg = (*(__IO uint32_t *)&hspi->Instance->DR);
-
- /* To avoid GCC warning */
- UNUSED(tmpreg);
-}
-
-/**
- * @brief Handle abort a Tx or Rx transaction.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi)
-{
- /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */
- CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXEIE | SPI_CR2_RXNEIE | SPI_CR2_ERRIE));
-
- /* Disable SPI Peripheral */
- __HAL_SPI_DISABLE(hspi);
-}
-
-/**
- * @brief Checks if encountered CRC error could be corresponding to wrongly detected errors
- * according to SPI instance, Device type, and revision ID.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval CRC error validity (SPI_INVALID_CRC_ERROR or SPI_VALID_CRC_ERROR).
-*/
-__weak uint8_t SPI_ISCRCErrorValid(SPI_HandleTypeDef *hspi)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hspi);
-
- return (SPI_VALID_CRC_ERROR);
-}
-/**
- * @}
- */
-#endif /* HAL_SPI_MODULE_ENABLED */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi_ex.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi_ex.c
deleted file mode 100644
index 86cab57..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi_ex.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_spi_ex.c
- * @author MCD Application Team
- * @brief Extended SPI HAL module driver.
- *
- * This file provides firmware functions to manage the following
- * functionalities SPI extension peripheral:
- * + Extended Peripheral Control functions
- *
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup SPI
- * @{
- */
-#ifdef HAL_SPI_MODULE_ENABLED
-
-/** @defgroup SPI_Private_Variables SPI Private Variables
- * @{
- */
-#if (USE_SPI_CRC != 0U)
-/* Variable used to determine if device is impacted by implementation of workaround
- related to wrong CRC errors detection on SPI2. Conditions in which this workaround has to be applied, are:
- - STM32F101CDE/STM32F103CDE
- - Revision ID : Z
- - SPI2
- - In receive only mode, with CRC calculation enabled, at the end of the CRC reception,
- the software needs to check the CRCERR flag. If it is found set, read back the SPI_RXCRC:
- + If the value is 0, the complete data transfer is successful.
- + Otherwise, one or more errors have been detected during the data transfer by CPU or DMA.
- If CRCERR is found reset, the complete data transfer is considered successful.
-*/
-uint8_t uCRCErrorWorkaroundCheck = 0U;
-#endif /* USE_SPI_CRC */
-/**
- * @}
- */
-
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
-
-/** @addtogroup SPI_Exported_Functions
- * @{
- */
-
-/** @addtogroup SPI_Exported_Functions_Group1
- *
- * @{
- */
-
-/**
- * @brief Initializes the SPI according to the specified parameters
- * in the SPI_InitTypeDef and create the associated handle.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
-{
- /* Check the SPI handle allocation */
- if(hspi == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
- assert_param(IS_SPI_MODE(hspi->Init.Mode));
- assert_param(IS_SPI_DIRECTION(hspi->Init.Direction));
- assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize));
- assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity));
- assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase));
- assert_param(IS_SPI_NSS(hspi->Init.NSS));
- assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
- assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit));
-
-#if (USE_SPI_CRC != 0U)
- assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation));
- if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
- {
- assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial));
- }
-#else
- hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
-#endif /* USE_SPI_CRC */
-
- if(hspi->State == HAL_SPI_STATE_RESET)
- {
- /* Init the low level hardware : GPIO, CLOCK, NVIC... */
- HAL_SPI_MspInit(hspi);
- }
-
- hspi->State = HAL_SPI_STATE_BUSY;
-
- /* Disble the selected SPI peripheral */
- __HAL_SPI_DISABLE(hspi);
-
- /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/
- /* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management,
- Communication speed, First bit and CRC calculation state */
- WRITE_REG(hspi->Instance->CR1, (hspi->Init.Mode | hspi->Init.Direction | hspi->Init.DataSize |
- hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) |
- hspi->Init.BaudRatePrescaler | hspi->Init.FirstBit | hspi->Init.CRCCalculation) );
-
- /* Configure : NSS management */
- WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) | hspi->Init.TIMode));
-
- /*---------------------------- SPIx CRCPOLY Configuration ------------------*/
- /* Configure : CRC Polynomial */
- WRITE_REG(hspi->Instance->CRCPR, hspi->Init.CRCPolynomial);
-
-#if defined(SPI_I2SCFGR_I2SMOD)
- /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */
- CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD);
-#endif /* SPI_I2SCFGR_I2SMOD */
-
-#if (USE_SPI_CRC != 0U)
-#if defined (STM32F101xE) || defined (STM32F103xE)
- /* Check RevisionID value for identifying if Device is Rev Z (0x0001) in order to enable workaround for
- CRC errors wrongly detected */
- /* Pb is that ES_STM32F10xxCDE also identify an issue in Debug registers access while not in Debug mode.
- Revision ID information is only available in Debug mode, so Workaround could not be implemented
- to distinguish Rev Z devices (issue present) from more recent version (issue fixed).
- So, in case of Revison Z F101 or F103 devices, below variable should be assigned to 1 */
- uCRCErrorWorkaroundCheck = 0U;
-#else
- uCRCErrorWorkaroundCheck = 0U;
-#endif /* STM32F101xE || STM32F103xE */
-#endif /* USE_SPI_CRC */
-
- hspi->ErrorCode = HAL_SPI_ERROR_NONE;
- hspi->State = HAL_SPI_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup SPI_Private_Functions
- * @{
- */
-#if (USE_SPI_CRC != 0U)
-/**
- * @brief Checks if encountered CRC error could be corresponding to wrongly detected errors
- * according to SPI instance, Device type, and revision ID.
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval CRC error validity (SPI_INVALID_CRC_ERROR or SPI_VALID_CRC_ERROR).
-*/
-uint8_t SPI_ISCRCErrorValid(SPI_HandleTypeDef *hspi)
-{
-#if defined(STM32F101xE) || defined(STM32F103xE)
- /* Check how to handle this CRC error (workaround to be applied or not) */
- /* If CRC errors could be wrongly detected (issue 2.15.2 in STM32F10xxC/D/E silicon limitations ES (DocID14732 Rev 13) */
- if((uCRCErrorWorkaroundCheck != 0U) && (hspi->Instance == SPI2))
- {
- if(hspi->Instance->RXCRCR == 0U)
- {
- return (SPI_INVALID_CRC_ERROR);
- }
- }
- return (SPI_VALID_CRC_ERROR);
-#else
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hspi);
-
- return (SPI_VALID_CRC_ERROR);
-#endif
-}
-#endif /* USE_SPI_CRC */
-
-/**
- * @}
- */
-
-#endif /* HAL_SPI_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sram.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sram.c
deleted file mode 100644
index dc861cc..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sram.c
+++ /dev/null
@@ -1,690 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_sram.c
- * @author MCD Application Team
- * @brief SRAM HAL module driver.
- * This file provides a generic firmware to drive SRAM memories
- * mounted as external device.
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- This driver is a generic layered driver which contains a set of APIs used to
- control SRAM memories. It uses the FSMC layer functions to interface
- with SRAM devices.
- The following sequence should be followed to configure the FSMC to interface
- with SRAM/PSRAM memories:
-
- (#) Declare a SRAM_HandleTypeDef handle structure, for example:
- SRAM_HandleTypeDef hsram; and:
-
- (++) Fill the SRAM_HandleTypeDef handle "Init" field with the allowed
- values of the structure member.
-
- (++) Fill the SRAM_HandleTypeDef handle "Instance" field with a predefined
- base register instance for NOR or SRAM device
-
- (++) Fill the SRAM_HandleTypeDef handle "Extended" field with a predefined
- base register instance for NOR or SRAM extended mode
-
- (#) Declare two FSMC_NORSRAM_TimingTypeDef structures, for both normal and extended
- mode timings; for example:
- FSMC_NORSRAM_TimingTypeDef Timing and FSMC_NORSRAM_TimingTypeDef ExTiming;
- and fill its fields with the allowed values of the structure member.
-
- (#) Initialize the SRAM Controller by calling the function HAL_SRAM_Init(). This function
- performs the following sequence:
-
- (##) MSP hardware layer configuration using the function HAL_SRAM_MspInit()
- (##) Control register configuration using the FSMC NORSRAM interface function
- FSMC_NORSRAM_Init()
- (##) Timing register configuration using the FSMC NORSRAM interface function
- FSMC_NORSRAM_Timing_Init()
- (##) Extended mode Timing register configuration using the FSMC NORSRAM interface function
- FSMC_NORSRAM_Extended_Timing_Init()
- (##) Enable the SRAM device using the macro __FSMC_NORSRAM_ENABLE()
-
- (#) At this stage you can perform read/write accesses from/to the memory connected
- to the NOR/SRAM Bank. You can perform either polling or DMA transfer using the
- following APIs:
- (++) HAL_SRAM_Read()/HAL_SRAM_Write() for polling read/write access
- (++) HAL_SRAM_Read_DMA()/HAL_SRAM_Write_DMA() for DMA read/write transfer
-
- (#) You can also control the SRAM device by calling the control APIs HAL_SRAM_WriteOperation_Enable()/
- HAL_SRAM_WriteOperation_Disable() to respectively enable/disable the SRAM write operation
-
- (#) You can continuously monitor the SRAM device HAL state by calling the function
- HAL_SRAM_GetState()
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#ifdef HAL_SRAM_MODULE_ENABLED
-
-#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG) || defined(STM32F100xE)
-
-/** @defgroup SRAM SRAM
- * @brief SRAM driver modules
- * @{
- */
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-
-/** @defgroup SRAM_Exported_Functions SRAM Exported Functions
- * @{
- */
-
-/** @defgroup SRAM_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions.
- *
- @verbatim
- ==============================================================================
- ##### SRAM Initialization and de_initialization functions #####
- ==============================================================================
- [..] This section provides functions allowing to initialize/de-initialize
- the SRAM memory
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Performs the SRAM device initialization sequence
- * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
- * the configuration information for SRAM module.
- * @param Timing: Pointer to SRAM control timing structure
- * @param ExtTiming: Pointer to SRAM extended mode timing structure
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SRAM_Init(SRAM_HandleTypeDef *hsram, FSMC_NORSRAM_TimingTypeDef *Timing, FSMC_NORSRAM_TimingTypeDef *ExtTiming)
-{
- /* Check the SRAM handle parameter */
- if(hsram == NULL)
- {
- return HAL_ERROR;
- }
-
- if(hsram->State == HAL_SRAM_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- hsram->Lock = HAL_UNLOCKED;
-
- /* Initialize the low level hardware (MSP) */
- HAL_SRAM_MspInit(hsram);
- }
-
- /* Initialize SRAM control Interface */
- FSMC_NORSRAM_Init(hsram->Instance, &(hsram->Init));
-
- /* Initialize SRAM timing Interface */
- FSMC_NORSRAM_Timing_Init(hsram->Instance, Timing, hsram->Init.NSBank);
-
- /* Initialize SRAM extended mode timing Interface */
- FSMC_NORSRAM_Extended_Timing_Init(hsram->Extended, ExtTiming, hsram->Init.NSBank, hsram->Init.ExtendedMode);
-
- /* Enable the NORSRAM device */
- __FSMC_NORSRAM_ENABLE(hsram->Instance, hsram->Init.NSBank);
-
- return HAL_OK;
-}
-
-/**
- * @brief Performs the SRAM device De-initialization sequence.
- * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
- * the configuration information for SRAM module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SRAM_DeInit(SRAM_HandleTypeDef *hsram)
-{
- /* De-Initialize the low level hardware (MSP) */
- HAL_SRAM_MspDeInit(hsram);
-
- /* Configure the SRAM registers with their reset values */
- FSMC_NORSRAM_DeInit(hsram->Instance, hsram->Extended, hsram->Init.NSBank);
-
- hsram->State = HAL_SRAM_STATE_RESET;
-
- /* Release Lock */
- __HAL_UNLOCK(hsram);
-
- return HAL_OK;
-}
-
-/**
- * @brief SRAM MSP Init.
- * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
- * the configuration information for SRAM module.
- * @retval None
- */
-__weak void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hsram);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_SRAM_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief SRAM MSP DeInit.
- * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
- * the configuration information for SRAM module.
- * @retval None
- */
-__weak void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef *hsram)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hsram);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_SRAM_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @brief DMA transfer complete callback.
- * @param hdma: pointer to a SRAM_HandleTypeDef structure that contains
- * the configuration information for SRAM module.
- * @retval None
- */
-__weak void HAL_SRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hdma);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_SRAM_DMA_XferCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief DMA transfer complete error callback.
- * @param hdma: pointer to a SRAM_HandleTypeDef structure that contains
- * the configuration information for SRAM module.
- * @retval None
- */
-__weak void HAL_SRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hdma);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_SRAM_DMA_XferErrorCallback could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup SRAM_Exported_Functions_Group2 Input Output and memory control functions
- * @brief Input Output and memory control functions
- *
- @verbatim
- ==============================================================================
- ##### SRAM Input and Output functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to use and control the SRAM memory
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Reads 8-bit buffer from SRAM memory.
- * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
- * the configuration information for SRAM module.
- * @param pAddress: Pointer to read start address
- * @param pDstBuffer: Pointer to destination buffer
- * @param BufferSize: Size of the buffer to read from memory
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SRAM_Read_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pDstBuffer, uint32_t BufferSize)
-{
- __IO uint8_t * psramaddress = (uint8_t *)pAddress;
-
- /* Process Locked */
- __HAL_LOCK(hsram);
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_BUSY;
-
- /* Read data from memory */
- for(; BufferSize != 0U; BufferSize--)
- {
- *pDstBuffer = *(__IO uint8_t *)psramaddress;
- pDstBuffer++;
- psramaddress++;
- }
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hsram);
-
- return HAL_OK;
-}
-
-/**
- * @brief Writes 8-bit buffer to SRAM memory.
- * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
- * the configuration information for SRAM module.
- * @param pAddress: Pointer to write start address
- * @param pSrcBuffer: Pointer to source buffer to write
- * @param BufferSize: Size of the buffer to write to memory
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SRAM_Write_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pSrcBuffer, uint32_t BufferSize)
-{
- __IO uint8_t * psramaddress = (uint8_t *)pAddress;
-
- /* Check the SRAM controller state */
- if(hsram->State == HAL_SRAM_STATE_PROTECTED)
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hsram);
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_BUSY;
-
- /* Write data to memory */
- for(; BufferSize != 0U; BufferSize--)
- {
- *(__IO uint8_t *)psramaddress = *pSrcBuffer;
- pSrcBuffer++;
- psramaddress++;
- }
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hsram);
-
- return HAL_OK;
-}
-
-/**
- * @brief Reads 16-bit buffer from SRAM memory.
- * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
- * the configuration information for SRAM module.
- * @param pAddress: Pointer to read start address
- * @param pDstBuffer: Pointer to destination buffer
- * @param BufferSize: Size of the buffer to read from memory
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SRAM_Read_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pDstBuffer, uint32_t BufferSize)
-{
- __IO uint16_t * psramaddress = (uint16_t *)pAddress;
-
- /* Process Locked */
- __HAL_LOCK(hsram);
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_BUSY;
-
- /* Read data from memory */
- for(; BufferSize != 0U; BufferSize--)
- {
- *pDstBuffer = *(__IO uint16_t *)psramaddress;
- pDstBuffer++;
- psramaddress++;
- }
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hsram);
-
- return HAL_OK;
-}
-
-/**
- * @brief Writes 16-bit buffer to SRAM memory.
- * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
- * the configuration information for SRAM module.
- * @param pAddress: Pointer to write start address
- * @param pSrcBuffer: Pointer to source buffer to write
- * @param BufferSize: Size of the buffer to write to memory
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SRAM_Write_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pSrcBuffer, uint32_t BufferSize)
-{
- __IO uint16_t * psramaddress = (uint16_t *)pAddress;
-
- /* Check the SRAM controller state */
- if(hsram->State == HAL_SRAM_STATE_PROTECTED)
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hsram);
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_BUSY;
-
- /* Write data to memory */
- for(; BufferSize != 0U; BufferSize--)
- {
- *(__IO uint16_t *)psramaddress = *pSrcBuffer;
- pSrcBuffer++;
- psramaddress++;
- }
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hsram);
-
- return HAL_OK;
-}
-
-/**
- * @brief Reads 32-bit buffer from SRAM memory.
- * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
- * the configuration information for SRAM module.
- * @param pAddress: Pointer to read start address
- * @param pDstBuffer: Pointer to destination buffer
- * @param BufferSize: Size of the buffer to read from memory
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SRAM_Read_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize)
-{
- /* Process Locked */
- __HAL_LOCK(hsram);
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_BUSY;
-
- /* Read data from memory */
- for(; BufferSize != 0U; BufferSize--)
- {
- *pDstBuffer = *(__IO uint32_t *)pAddress;
- pDstBuffer++;
- pAddress++;
- }
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hsram);
-
- return HAL_OK;
-}
-
-/**
- * @brief Writes 32-bit buffer to SRAM memory.
- * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
- * the configuration information for SRAM module.
- * @param pAddress: Pointer to write start address
- * @param pSrcBuffer: Pointer to source buffer to write
- * @param BufferSize: Size of the buffer to write to memory
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SRAM_Write_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize)
-{
- /* Check the SRAM controller state */
- if(hsram->State == HAL_SRAM_STATE_PROTECTED)
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hsram);
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_BUSY;
-
- /* Write data to memory */
- for(; BufferSize != 0U; BufferSize--)
- {
- *(__IO uint32_t *)pAddress = *pSrcBuffer;
- pSrcBuffer++;
- pAddress++;
- }
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hsram);
-
- return HAL_OK;
-}
-
-/**
- * @brief Reads a Words data from the SRAM memory using DMA transfer.
- * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
- * the configuration information for SRAM module.
- * @param pAddress: Pointer to read start address
- * @param pDstBuffer: Pointer to destination buffer
- * @param BufferSize: Size of the buffer to read from memory
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SRAM_Read_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize)
-{
- /* Process Locked */
- __HAL_LOCK(hsram);
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_BUSY;
-
- /* Configure DMA user callbacks */
- hsram->hdma->XferCpltCallback = HAL_SRAM_DMA_XferCpltCallback;
- hsram->hdma->XferErrorCallback = HAL_SRAM_DMA_XferErrorCallback;
-
- /* Enable the DMA Channel */
- HAL_DMA_Start_IT(hsram->hdma, (uint32_t)pAddress, (uint32_t)pDstBuffer, (uint32_t)BufferSize);
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hsram);
-
- return HAL_OK;
-}
-
-/**
- * @brief Writes a Words data buffer to SRAM memory using DMA transfer.
- * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
- * the configuration information for SRAM module.
- * @param pAddress: Pointer to write start address
- * @param pSrcBuffer: Pointer to source buffer to write
- * @param BufferSize: Size of the buffer to write to memory
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SRAM_Write_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize)
-{
- /* Check the SRAM controller state */
- if(hsram->State == HAL_SRAM_STATE_PROTECTED)
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hsram);
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_BUSY;
-
- /* Configure DMA user callbacks */
- hsram->hdma->XferCpltCallback = HAL_SRAM_DMA_XferCpltCallback;
- hsram->hdma->XferErrorCallback = HAL_SRAM_DMA_XferErrorCallback;
-
- /* Enable the DMA Channel */
- HAL_DMA_Start_IT(hsram->hdma, (uint32_t)pSrcBuffer, (uint32_t)pAddress, (uint32_t)BufferSize);
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hsram);
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup SRAM_Exported_Functions_Group3 Control functions
- * @brief Control functions
- *
-@verbatim
- ==============================================================================
- ##### SRAM Control functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to control dynamically
- the SRAM interface.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Enables dynamically SRAM write operation.
- * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
- * the configuration information for SRAM module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SRAM_WriteOperation_Enable(SRAM_HandleTypeDef *hsram)
-{
- /* Process Locked */
- __HAL_LOCK(hsram);
-
- /* Enable write operation */
- FSMC_NORSRAM_WriteOperation_Enable(hsram->Instance, hsram->Init.NSBank);
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_READY;
-
- /* Process unlocked */
- __HAL_UNLOCK(hsram);
-
- return HAL_OK;
-}
-
-/**
- * @brief Disables dynamically SRAM write operation.
- * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
- * the configuration information for SRAM module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_SRAM_WriteOperation_Disable(SRAM_HandleTypeDef *hsram)
-{
- /* Process Locked */
- __HAL_LOCK(hsram);
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_BUSY;
-
- /* Disable write operation */
- FSMC_NORSRAM_WriteOperation_Disable(hsram->Instance, hsram->Init.NSBank);
-
- /* Update the SRAM controller state */
- hsram->State = HAL_SRAM_STATE_PROTECTED;
-
- /* Process unlocked */
- __HAL_UNLOCK(hsram);
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup SRAM_Exported_Functions_Group4 Peripheral State functions
- * @brief Peripheral State functions
- *
-@verbatim
- ==============================================================================
- ##### SRAM State functions #####
- ==============================================================================
- [..]
- This subsection permits to get in run-time the status of the SRAM controller
- and the data flow.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Returns the SRAM controller state
- * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
- * the configuration information for SRAM module.
- * @retval HAL state
- */
-HAL_SRAM_StateTypeDef HAL_SRAM_GetState(SRAM_HandleTypeDef *hsram)
-{
- return hsram->State;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG || STM32F100xE */
-#endif /* HAL_SRAM_MODULE_ENABLED */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c
deleted file mode 100644
index 8bf9926..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c
+++ /dev/null
@@ -1,1773 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_tim_ex.c
- * @author MCD Application Team
- * @brief TIM HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Timer Extended peripheral:
- * + Time Hall Sensor Interface Initialization
- * + Time Hall Sensor Interface Start
- * + Time Complementary signal bread and dead time configuration
- * + Time Master and Slave synchronization configuration
- * + Timer remapping capabilities configuration
- @verbatim
- ==============================================================================
- ##### TIMER Extended features #####
- ==============================================================================
- [..]
- The Timer Extended features include:
- (#) Complementary outputs with programmable dead-time for :
- (++) Output Compare
- (++) PWM generation (Edge and Center-aligned Mode)
- (++) One-pulse mode output
- (#) Synchronization circuit to control the timer with external signals and to
- interconnect several timers together.
- (#) Break input to put the timer output signals in reset state or in a known state.
- (#) Supports incremental (quadrature) encoder and hall-sensor circuitry for
- positioning purposes
-
- ##### How to use this driver #####
- ==============================================================================
- [..]
- (#) Initialize the TIM low level resources by implementing the following functions
- depending from feature used :
- (++) Complementary Output Compare : HAL_TIM_OC_MspInit()
- (++) Complementary PWM generation : HAL_TIM_PWM_MspInit()
- (++) Complementary One-pulse mode output : HAL_TIM_OnePulse_MspInit()
- (++) Hall Sensor output : HAL_TIMEx_HallSensor_MspInit()
-
- (#) Initialize the TIM low level resources :
- (##) Enable the TIM interface clock using __HAL_RCC_TIMx_CLK_ENABLE();
- (##) TIM pins configuration
- (+++) Enable the clock for the TIM GPIOs using the following function:
- __HAL_RCC_GPIOx_CLK_ENABLE();
- (+++) Configure these TIM pins in Alternate function mode using HAL_GPIO_Init();
-
- (#) The external Clock can be configured, if needed (the default clock is the
- internal clock from the APBx), using the following function:
- HAL_TIM_ConfigClockSource, the clock configuration should be done before
- any start function.
-
- (#) Configure the TIM in the desired functioning mode using one of the
- initialization function of this driver:
- (++) HAL_TIMEx_HallSensor_Init and HAL_TIMEx_ConfigCommutationEvent: to use the
- Timer Hall Sensor Interface and the commutation event with the corresponding
- Interrupt and DMA request if needed (Note that One Timer is used to interface
- with the Hall sensor Interface and another Timer should be used to use
- the commutation event).
-
- (#) Activate the TIM peripheral using one of the start functions:
- (++) Complementary Output Compare : HAL_TIMEx_OCN_Start(), HAL_TIMEx_OCN_Start_DMA(), HAL_TIMEx_OCN_Start_IT()
- (++) Complementary PWM generation : HAL_TIMEx_PWMN_Start(), HAL_TIMEx_PWMN_Start_DMA(), HAL_TIMEx_PWMN_Start_IT()
- (++) Complementary One-pulse mode output : HAL_TIMEx_OnePulseN_Start(), HAL_TIMEx_OnePulseN_Start_IT()
- (++) Hall Sensor output : HAL_TIMEx_HallSensor_Start(), HAL_TIMEx_HallSensor_Start_DMA(), HAL_TIMEx_HallSensor_Start_IT().
-
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
-*/
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup TIMEx TIMEx
- * @brief TIM Extended HAL module driver
- * @{
- */
-
-#ifdef HAL_TIM_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-
-#if defined (STM32F100xB) || defined (STM32F100xE) || \
- defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
- defined (STM32F105xC) || defined (STM32F107xC)
-/** @defgroup TIMEx_Private_Functions TIMEx Private Functions
- * @{
- */
-static void TIM_CCxNChannelCmd(TIM_TypeDef* TIMx, uint32_t Channel, uint32_t ChannelNState);
-/**
- * @}
- */
-#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
- /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
- /* defined(STM32F105xC) || defined(STM32F107xC) */
-
-/* Exported functions ---------------------------------------------------------*/
-
-/** @defgroup TIMEx_Exported_Functions TIMEx Exported Functions
- * @{
- */
-
-
-/** @defgroup TIMEx_Exported_Functions_Group1 Timer Hall Sensor functions
- * @brief Timer Hall Sensor functions
- *
-@verbatim
- ==============================================================================
- ##### Timer Hall Sensor functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to:
- (+) Initialize and configure TIM HAL Sensor.
- (+) De-initialize TIM HAL Sensor.
- (+) Start the Hall Sensor Interface.
- (+) Stop the Hall Sensor Interface.
- (+) Start the Hall Sensor Interface and enable interrupts.
- (+) Stop the Hall Sensor Interface and disable interrupts.
- (+) Start the Hall Sensor Interface and enable DMA transfers.
- (+) Stop the Hall Sensor Interface and disable DMA transfers.
-
-@endverbatim
- * @{
- */
-/**
- * @brief Initializes the TIM Hall Sensor Interface and create the associated handle.
- * @param htim : TIM Encoder Interface handle
- * @param sConfig : TIM Hall Sensor configuration structure
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, TIM_HallSensor_InitTypeDef* sConfig)
-{
- TIM_OC_InitTypeDef OC_Config;
-
- /* Check the TIM handle allocation */
- if(htim == NULL)
- {
- return HAL_ERROR;
- }
-
- assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
- assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
- assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
- assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload));
- assert_param(IS_TIM_IC_POLARITY(sConfig->IC1Polarity));
- assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler));
- assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter));
-
- if(htim->State == HAL_TIM_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- htim->Lock = HAL_UNLOCKED;
-
- /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
- HAL_TIMEx_HallSensor_MspInit(htim);
- }
-
- /* Set the TIM state */
- htim->State= HAL_TIM_STATE_BUSY;
-
- /* Configure the Time base in the Encoder Mode */
- TIM_Base_SetConfig(htim->Instance, &htim->Init);
-
- /* Configure the Channel 1 as Input Channel to interface with the three Outputs of the Hall sensor */
- TIM_TI1_SetConfig(htim->Instance, sConfig->IC1Polarity, TIM_ICSELECTION_TRC, sConfig->IC1Filter);
-
- /* Reset the IC1PSC Bits */
- htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC;
- /* Set the IC1PSC value */
- htim->Instance->CCMR1 |= sConfig->IC1Prescaler;
-
- /* Enable the Hall sensor interface (XOR function of the three inputs) */
- htim->Instance->CR2 |= TIM_CR2_TI1S;
-
- /* Select the TIM_TS_TI1F_ED signal as Input trigger for the TIM */
- htim->Instance->SMCR &= ~TIM_SMCR_TS;
- htim->Instance->SMCR |= TIM_TS_TI1F_ED;
-
- /* Use the TIM_TS_TI1F_ED signal to reset the TIM counter each edge detection */
- htim->Instance->SMCR &= ~TIM_SMCR_SMS;
- htim->Instance->SMCR |= TIM_SLAVEMODE_RESET;
-
- /* Program channel 2 in PWM 2 mode with the desired Commutation_Delay*/
- OC_Config.OCFastMode = TIM_OCFAST_DISABLE;
- OC_Config.OCIdleState = TIM_OCIDLESTATE_RESET;
- OC_Config.OCMode = TIM_OCMODE_PWM2;
- OC_Config.OCNIdleState = TIM_OCNIDLESTATE_RESET;
- OC_Config.OCNPolarity = TIM_OCNPOLARITY_HIGH;
- OC_Config.OCPolarity = TIM_OCPOLARITY_HIGH;
- OC_Config.Pulse = sConfig->Commutation_Delay;
-
- TIM_OC2_SetConfig(htim->Instance, &OC_Config);
-
- /* Select OC2REF as trigger output on TRGO: write the MMS bits in the TIMx_CR2
- register to 101 */
- htim->Instance->CR2 &= ~TIM_CR2_MMS;
- htim->Instance->CR2 |= TIM_TRGO_OC2REF;
-
- /* Initialize the TIM state*/
- htim->State= HAL_TIM_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief DeInitializes the TIM Hall Sensor interface
- * @param htim : TIM Hall Sensor handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim)
-{
- /* Check the parameters */
- assert_param(IS_TIM_INSTANCE(htim->Instance));
-
- htim->State = HAL_TIM_STATE_BUSY;
-
- /* Disable the TIM Peripheral Clock */
- __HAL_TIM_DISABLE(htim);
-
- /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
- HAL_TIMEx_HallSensor_MspDeInit(htim);
-
- /* Change TIM state */
- htim->State = HAL_TIM_STATE_RESET;
-
- /* Release Lock */
- __HAL_UNLOCK(htim);
-
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the TIM Hall Sensor MSP.
- * @param htim : TIM handle
- * @retval None
- */
-__weak void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(htim);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_TIMEx_HallSensor_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief DeInitializes TIM Hall Sensor MSP.
- * @param htim : TIM handle
- * @retval None
- */
-__weak void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(htim);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_TIMEx_HallSensor_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @brief Starts the TIM Hall Sensor Interface.
- * @param htim : TIM Hall Sensor handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim)
-{
- /* Check the parameters */
- assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
-
- /* Enable the Input Capture channel 1
- (in the Hall Sensor Interface the 3 possible channels that are used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
- TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
-
- /* Enable the Peripheral */
- __HAL_TIM_ENABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Stops the TIM Hall sensor Interface.
- * @param htim : TIM Hall Sensor handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim)
-{
- /* Check the parameters */
- assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
-
- /* Disable the Input Capture channel 1
- (in the Hall Sensor Interface the 3 possible channels that are used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
- TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
-
- /* Disable the Peripheral */
- __HAL_TIM_DISABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Starts the TIM Hall Sensor Interface in interrupt mode.
- * @param htim : TIM Hall Sensor handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim)
-{
- /* Check the parameters */
- assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
-
- /* Enable the capture compare Interrupts 1 event */
- __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
-
- /* Enable the Input Capture channel 1
- (in the Hall Sensor Interface the 3 possible channels that are used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
- TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
-
- /* Enable the Peripheral */
- __HAL_TIM_ENABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Stops the TIM Hall Sensor Interface in interrupt mode.
- * @param htim : TIM handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim)
-{
- /* Check the parameters */
- assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
-
- /* Disable the Input Capture channel 1
- (in the Hall Sensor Interface the 3 possible channels that are used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
- TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
-
- /* Disable the capture compare Interrupts event */
- __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
-
- /* Disable the Peripheral */
- __HAL_TIM_DISABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Starts the TIM Hall Sensor Interface in DMA mode.
- * @param htim : TIM Hall Sensor handle
- * @param pData : The destination Buffer address.
- * @param Length : The length of data to be transferred from TIM peripheral to memory.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length)
-{
- /* Check the parameters */
- assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
-
- if((htim->State == HAL_TIM_STATE_BUSY))
- {
- return HAL_BUSY;
- }
- else if((htim->State == HAL_TIM_STATE_READY))
- {
- if(((uint32_t)pData == 0U) && (Length > 0U))
- {
- return HAL_ERROR;
- }
- else
- {
- htim->State = HAL_TIM_STATE_BUSY;
- }
- }
- /* Enable the Input Capture channel 1
- (in the Hall Sensor Interface the 3 possible channels that are used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
- TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
-
- /* Set the DMA Input Capture 1 Callback */
- htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt;
- /* Set the DMA error callback */
- htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
-
- /* Enable the DMA channel for Capture 1*/
- HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData, Length);
-
- /* Enable the capture compare 1 Interrupt */
- __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
-
- /* Enable the Peripheral */
- __HAL_TIM_ENABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Stops the TIM Hall Sensor Interface in DMA mode.
- * @param htim : TIM handle
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim)
-{
- /* Check the parameters */
- assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
-
- /* Disable the Input Capture channel 1
- (in the Hall Sensor Interface the 3 possible channels that are used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
- TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
-
-
- /* Disable the capture compare Interrupts 1 event */
- __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
-
- /* Disable the Peripheral */
- __HAL_TIM_DISABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-#if defined (STM32F100xB) || defined (STM32F100xE) || \
- defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
- defined (STM32F105xC) || defined (STM32F107xC)
-
-/** @defgroup TIMEx_Exported_Functions_Group2 Timer Complementary Output Compare functions
- * @brief Timer Complementary Output Compare functions
- *
-@verbatim
- ==============================================================================
- ##### Timer Complementary Output Compare functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to:
- (+) Start the Complementary Output Compare/PWM.
- (+) Stop the Complementary Output Compare/PWM.
- (+) Start the Complementary Output Compare/PWM and enable interrupts.
- (+) Stop the Complementary Output Compare/PWM and disable interrupts.
- (+) Start the Complementary Output Compare/PWM and enable DMA transfers.
- (+) Stop the Complementary Output Compare/PWM and disable DMA transfers.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Starts the TIM Output Compare signal generation on the complementary
- * output.
- * @param htim : TIM Output Compare handle
- * @param Channel : TIM Channel to be enabled
- * This parameter can be one of the following values:
- * @arg TIM_CHANNEL_1: TIM Channel 1 selected
- * @arg TIM_CHANNEL_2: TIM Channel 2 selected
- * @arg TIM_CHANNEL_3: TIM Channel 3 selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
- /* Check the parameters */
- assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
- /* Enable the Capture compare channel N */
- TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
-
- /* Enable the Main Ouput */
- __HAL_TIM_MOE_ENABLE(htim);
-
- /* Enable the Peripheral */
- __HAL_TIM_ENABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Stops the TIM Output Compare signal generation on the complementary
- * output.
- * @param htim : TIM handle
- * @param Channel : TIM Channel to be disabled
- * This parameter can be one of the following values:
- * @arg TIM_CHANNEL_1: TIM Channel 1 selected
- * @arg TIM_CHANNEL_2: TIM Channel 2 selected
- * @arg TIM_CHANNEL_3: TIM Channel 3 selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
- /* Check the parameters */
- assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
- /* Disable the Capture compare channel N */
- TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
-
- /* Disable the Main Ouput */
- __HAL_TIM_MOE_DISABLE(htim);
-
- /* Disable the Peripheral */
- __HAL_TIM_DISABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Starts the TIM Output Compare signal generation in interrupt mode
- * on the complementary output.
- * @param htim : TIM OC handle
- * @param Channel : TIM Channel to be enabled
- * This parameter can be one of the following values:
- * @arg TIM_CHANNEL_1: TIM Channel 1 selected
- * @arg TIM_CHANNEL_2: TIM Channel 2 selected
- * @arg TIM_CHANNEL_3: TIM Channel 3 selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
- /* Check the parameters */
- assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
- switch (Channel)
- {
- case TIM_CHANNEL_1:
- {
- /* Enable the TIM Output Compare interrupt */
- __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
- }
- break;
-
- case TIM_CHANNEL_2:
- {
- /* Enable the TIM Output Compare interrupt */
- __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
- }
- break;
-
- case TIM_CHANNEL_3:
- {
- /* Enable the TIM Output Compare interrupt */
- __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
- }
- break;
-
- default:
- break;
- }
-
- /* Enable the TIM Break interrupt */
- __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK);
-
- /* Enable the Capture compare channel N */
- TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
-
- /* Enable the Main Ouput */
- __HAL_TIM_MOE_ENABLE(htim);
-
- /* Enable the Peripheral */
- __HAL_TIM_ENABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Stops the TIM Output Compare signal generation in interrupt mode
- * on the complementary output.
- * @param htim : TIM Output Compare handle
- * @param Channel : TIM Channel to be disabled
- * This parameter can be one of the following values:
- * @arg TIM_CHANNEL_1: TIM Channel 1 selected
- * @arg TIM_CHANNEL_2: TIM Channel 2 selected
- * @arg TIM_CHANNEL_3: TIM Channel 3 selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
- uint32_t tmpccer = 0U;
-
- /* Check the parameters */
- assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
- switch (Channel)
- {
- case TIM_CHANNEL_1:
- {
- /* Disable the TIM Output Compare interrupt */
- __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
- }
- break;
-
- case TIM_CHANNEL_2:
- {
- /* Disable the TIM Output Compare interrupt */
- __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
- }
- break;
-
- case TIM_CHANNEL_3:
- {
- /* Disable the TIM Output Compare interrupt */
- __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
- }
- break;
-
- default:
- break;
- }
-
- /* Disable the Capture compare channel N */
- TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
-
- /* Disable the TIM Break interrupt (only if no more channel is active) */
- tmpccer = htim->Instance->CCER;
- if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == RESET)
- {
- __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK);
- }
-
- /* Disable the Main Ouput */
- __HAL_TIM_MOE_DISABLE(htim);
-
- /* Disable the Peripheral */
- __HAL_TIM_DISABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Starts the TIM Output Compare signal generation in DMA mode
- * on the complementary output.
- * @param htim : TIM Output Compare handle
- * @param Channel : TIM Channel to be enabled
- * This parameter can be one of the following values:
- * @arg TIM_CHANNEL_1: TIM Channel 1 selected
- * @arg TIM_CHANNEL_2: TIM Channel 2 selected
- * @arg TIM_CHANNEL_3: TIM Channel 3 selected
- * @param pData : The source Buffer address.
- * @param Length : The length of data to be transferred from memory to TIM peripheral
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length)
-{
- /* Check the parameters */
- assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
- if((htim->State == HAL_TIM_STATE_BUSY))
- {
- return HAL_BUSY;
- }
- else if((htim->State == HAL_TIM_STATE_READY))
- {
- if(((uint32_t)pData == 0U) && (Length > 0U))
- {
- return HAL_ERROR;
- }
- else
- {
- htim->State = HAL_TIM_STATE_BUSY;
- }
- }
- switch (Channel)
- {
- case TIM_CHANNEL_1:
- {
- /* Set the DMA Period elapsed callback */
- htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt;
-
- /* Set the DMA error callback */
- htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
-
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length);
-
- /* Enable the TIM Output Compare DMA request */
- __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
- }
- break;
-
- case TIM_CHANNEL_2:
- {
- /* Set the DMA Period elapsed callback */
- htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt;
-
- /* Set the DMA error callback */
- htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
-
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length);
-
- /* Enable the TIM Output Compare DMA request */
- __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
- }
- break;
-
- case TIM_CHANNEL_3:
- {
- /* Set the DMA Period elapsed callback */
- htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt;
-
- /* Set the DMA error callback */
- htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ;
-
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,Length);
-
- /* Enable the TIM Output Compare DMA request */
- __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
- }
- break;
-
- default:
- break;
- }
-
- /* Enable the Capture compare channel N */
- TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
-
- /* Enable the Main Ouput */
- __HAL_TIM_MOE_ENABLE(htim);
-
- /* Enable the Peripheral */
- __HAL_TIM_ENABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Stops the TIM Output Compare signal generation in DMA mode
- * on the complementary output.
- * @param htim : TIM Output Compare handle
- * @param Channel : TIM Channel to be disabled
- * This parameter can be one of the following values:
- * @arg TIM_CHANNEL_1: TIM Channel 1 selected
- * @arg TIM_CHANNEL_2: TIM Channel 2 selected
- * @arg TIM_CHANNEL_3: TIM Channel 3 selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
- /* Check the parameters */
- assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
- switch (Channel)
- {
- case TIM_CHANNEL_1:
- {
- /* Disable the TIM Output Compare DMA request */
- __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
- }
- break;
-
- case TIM_CHANNEL_2:
- {
- /* Disable the TIM Output Compare DMA request */
- __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
- }
- break;
-
- case TIM_CHANNEL_3:
- {
- /* Disable the TIM Output Compare DMA request */
- __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
- }
- break;
-
- default:
- break;
- }
-
- /* Disable the Capture compare channel N */
- TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
-
- /* Disable the Main Ouput */
- __HAL_TIM_MOE_DISABLE(htim);
-
- /* Disable the Peripheral */
- __HAL_TIM_DISABLE(htim);
-
- /* Change the htim state */
- htim->State = HAL_TIM_STATE_READY;
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup TIMEx_Exported_Functions_Group3 Timer Complementary PWM functions
- * @brief Timer Complementary PWM functions
- *
-@verbatim
- ==============================================================================
- ##### Timer Complementary PWM functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to:
- (+) Start the Complementary PWM.
- (+) Stop the Complementary PWM.
- (+) Start the Complementary PWM and enable interrupts.
- (+) Stop the Complementary PWM and disable interrupts.
- (+) Start the Complementary PWM and enable DMA transfers.
- (+) Stop the Complementary PWM and disable DMA transfers.
- (+) Start the Complementary Input Capture measurement.
- (+) Stop the Complementary Input Capture.
- (+) Start the Complementary Input Capture and enable interrupts.
- (+) Stop the Complementary Input Capture and disable interrupts.
- (+) Start the Complementary Input Capture and enable DMA transfers.
- (+) Stop the Complementary Input Capture and disable DMA transfers.
- (+) Start the Complementary One Pulse generation.
- (+) Stop the Complementary One Pulse.
- (+) Start the Complementary One Pulse and enable interrupts.
- (+) Stop the Complementary One Pulse and disable interrupts.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Starts the PWM signal generation on the complementary output.
- * @param htim : TIM handle
- * @param Channel : TIM Channel to be enabled
- * This parameter can be one of the following values:
- * @arg TIM_CHANNEL_1: TIM Channel 1 selected
- * @arg TIM_CHANNEL_2: TIM Channel 2 selected
- * @arg TIM_CHANNEL_3: TIM Channel 3 selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
- /* Check the parameters */
- assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
- /* Enable the complementary PWM output */
- TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
-
- /* Enable the Main Ouput */
- __HAL_TIM_MOE_ENABLE(htim);
-
- /* Enable the Peripheral */
- __HAL_TIM_ENABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Stops the PWM signal generation on the complementary output.
- * @param htim : TIM handle
- * @param Channel : TIM Channel to be disabled
- * This parameter can be one of the following values:
- * @arg TIM_CHANNEL_1: TIM Channel 1 selected
- * @arg TIM_CHANNEL_2: TIM Channel 2 selected
- * @arg TIM_CHANNEL_3: TIM Channel 3 selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
- /* Check the parameters */
- assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
- /* Disable the complementary PWM output */
- TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
-
- /* Disable the Main Ouput */
- __HAL_TIM_MOE_DISABLE(htim);
-
- /* Disable the Peripheral */
- __HAL_TIM_DISABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Starts the PWM signal generation in interrupt mode on the
- * complementary output.
- * @param htim : TIM handle
- * @param Channel : TIM Channel to be disabled
- * This parameter can be one of the following values:
- * @arg TIM_CHANNEL_1: TIM Channel 1 selected
- * @arg TIM_CHANNEL_2: TIM Channel 2 selected
- * @arg TIM_CHANNEL_3: TIM Channel 3 selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
- /* Check the parameters */
- assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
- switch (Channel)
- {
- case TIM_CHANNEL_1:
- {
- /* Enable the TIM Capture/Compare 1 interrupt */
- __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
- }
- break;
-
- case TIM_CHANNEL_2:
- {
- /* Enable the TIM Capture/Compare 2 interrupt */
- __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
- }
- break;
-
- case TIM_CHANNEL_3:
- {
- /* Enable the TIM Capture/Compare 3 interrupt */
- __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
- }
- break;
-
- default:
- break;
- }
-
- /* Enable the TIM Break interrupt */
- __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK);
-
- /* Enable the complementary PWM output */
- TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
-
- /* Enable the Main Ouput */
- __HAL_TIM_MOE_ENABLE(htim);
-
- /* Enable the Peripheral */
- __HAL_TIM_ENABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Stops the PWM signal generation in interrupt mode on the
- * complementary output.
- * @param htim : TIM handle
- * @param Channel : TIM Channel to be disabled
- * This parameter can be one of the following values:
- * @arg TIM_CHANNEL_1: TIM Channel 1 selected
- * @arg TIM_CHANNEL_2: TIM Channel 2 selected
- * @arg TIM_CHANNEL_3: TIM Channel 3 selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
- uint32_t tmpccer = 0U;
-
- /* Check the parameters */
- assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
- switch (Channel)
- {
- case TIM_CHANNEL_1:
- {
- /* Disable the TIM Capture/Compare 1 interrupt */
- __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
- }
- break;
-
- case TIM_CHANNEL_2:
- {
- /* Disable the TIM Capture/Compare 2 interrupt */
- __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
- }
- break;
-
- case TIM_CHANNEL_3:
- {
- /* Disable the TIM Capture/Compare 3 interrupt */
- __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
- }
- break;
-
- default:
- break;
- }
-
- /* Disable the complementary PWM output */
- TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
-
- /* Disable the TIM Break interrupt (only if no more channel is active) */
- tmpccer = htim->Instance->CCER;
- if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == RESET)
- {
- __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK);
- }
-
- /* Disable the Main Ouput */
- __HAL_TIM_MOE_DISABLE(htim);
-
- /* Disable the Peripheral */
- __HAL_TIM_DISABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Starts the TIM PWM signal generation in DMA mode on the
- * complementary output
- * @param htim : TIM handle
- * @param Channel : TIM Channel to be enabled
- * This parameter can be one of the following values:
- * @arg TIM_CHANNEL_1: TIM Channel 1 selected
- * @arg TIM_CHANNEL_2: TIM Channel 2 selected
- * @arg TIM_CHANNEL_3: TIM Channel 3 selected
- * @param pData : The source Buffer address.
- * @param Length : The length of data to be transferred from memory to TIM peripheral
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length)
-{
- /* Check the parameters */
- assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
- if((htim->State == HAL_TIM_STATE_BUSY))
- {
- return HAL_BUSY;
- }
- else if((htim->State == HAL_TIM_STATE_READY))
- {
- if(((uint32_t)pData == 0U) && (Length > 0U))
- {
- return HAL_ERROR;
- }
- else
- {
- htim->State = HAL_TIM_STATE_BUSY;
- }
- }
- switch (Channel)
- {
- case TIM_CHANNEL_1:
- {
- /* Set the DMA Period elapsed callback */
- htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt;
-
- /* Set the DMA error callback */
- htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
-
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length);
-
- /* Enable the TIM Capture/Compare 1 DMA request */
- __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
- }
- break;
-
- case TIM_CHANNEL_2:
- {
- /* Set the DMA Period elapsed callback */
- htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt;
-
- /* Set the DMA error callback */
- htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
-
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length);
-
- /* Enable the TIM Capture/Compare 2 DMA request */
- __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
- }
- break;
-
- case TIM_CHANNEL_3:
- {
- /* Set the DMA Period elapsed callback */
- htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt;
-
- /* Set the DMA error callback */
- htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ;
-
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,Length);
-
- /* Enable the TIM Capture/Compare 3 DMA request */
- __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
- }
- break;
-
- default:
- break;
- }
-
- /* Enable the complementary PWM output */
- TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
-
- /* Enable the Main Ouput */
- __HAL_TIM_MOE_ENABLE(htim);
-
- /* Enable the Peripheral */
- __HAL_TIM_ENABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Stops the TIM PWM signal generation in DMA mode on the complementary
- * output
- * @param htim : TIM handle
- * @param Channel : TIM Channel to be disabled
- * This parameter can be one of the following values:
- * @arg TIM_CHANNEL_1: TIM Channel 1 selected
- * @arg TIM_CHANNEL_2: TIM Channel 2 selected
- * @arg TIM_CHANNEL_3: TIM Channel 3 selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
- /* Check the parameters */
- assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
- switch (Channel)
- {
- case TIM_CHANNEL_1:
- {
- /* Disable the TIM Capture/Compare 1 DMA request */
- __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
- }
- break;
-
- case TIM_CHANNEL_2:
- {
- /* Disable the TIM Capture/Compare 2 DMA request */
- __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
- }
- break;
-
- case TIM_CHANNEL_3:
- {
- /* Disable the TIM Capture/Compare 3 DMA request */
- __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
- }
- break;
-
- default:
- break;
- }
-
- /* Disable the complementary PWM output */
- TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
-
- /* Disable the Main Ouput */
- __HAL_TIM_MOE_DISABLE(htim);
-
- /* Disable the Peripheral */
- __HAL_TIM_DISABLE(htim);
-
- /* Change the htim state */
- htim->State = HAL_TIM_STATE_READY;
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup TIMEx_Exported_Functions_Group4 Timer Complementary One Pulse functions
- * @brief Timer Complementary One Pulse functions
- *
-@verbatim
- ==============================================================================
- ##### Timer Complementary One Pulse functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to:
- (+) Start the Complementary One Pulse generation.
- (+) Stop the Complementary One Pulse.
- (+) Start the Complementary One Pulse and enable interrupts.
- (+) Stop the Complementary One Pulse and disable interrupts.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Starts the TIM One Pulse signal generation on the complemetary
- * output.
- * @param htim : TIM One Pulse handle
- * @param OutputChannel : TIM Channel to be enabled
- * This parameter can be one of the following values:
- * @arg TIM_CHANNEL_1: TIM Channel 1 selected
- * @arg TIM_CHANNEL_2: TIM Channel 2 selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
-{
- /* Check the parameters */
- assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
-
- /* Enable the complementary One Pulse output */
- TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE);
-
- /* Enable the Main Ouput */
- __HAL_TIM_MOE_ENABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Stops the TIM One Pulse signal generation on the complementary
- * output.
- * @param htim : TIM One Pulse handle
- * @param OutputChannel : TIM Channel to be disabled
- * This parameter can be one of the following values:
- * @arg TIM_CHANNEL_1: TIM Channel 1 selected
- * @arg TIM_CHANNEL_2: TIM Channel 2 selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
-{
-
- /* Check the parameters */
- assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
-
- /* Disable the complementary One Pulse output */
- TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE);
-
- /* Disable the Main Ouput */
- __HAL_TIM_MOE_DISABLE(htim);
-
- /* Disable the Peripheral */
- __HAL_TIM_DISABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Starts the TIM One Pulse signal generation in interrupt mode on the
- * complementary channel.
- * @param htim : TIM One Pulse handle
- * @param OutputChannel : TIM Channel to be enabled
- * This parameter can be one of the following values:
- * @arg TIM_CHANNEL_1: TIM Channel 1 selected
- * @arg TIM_CHANNEL_2: TIM Channel 2 selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
-{
- /* Check the parameters */
- assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
-
- /* Enable the TIM Capture/Compare 1 interrupt */
- __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
-
- /* Enable the TIM Capture/Compare 2 interrupt */
- __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
-
- /* Enable the complementary One Pulse output */
- TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE);
-
- /* Enable the Main Ouput */
- __HAL_TIM_MOE_ENABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Stops the TIM One Pulse signal generation in interrupt mode on the
- * complementary channel.
- * @param htim : TIM One Pulse handle
- * @param OutputChannel : TIM Channel to be disabled
- * This parameter can be one of the following values:
- * @arg TIM_CHANNEL_1: TIM Channel 1 selected
- * @arg TIM_CHANNEL_2: TIM Channel 2 selected
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
-{
- /* Check the parameters */
- assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
-
- /* Disable the TIM Capture/Compare 1 interrupt */
- __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
-
- /* Disable the TIM Capture/Compare 2 interrupt */
- __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
-
- /* Disable the complementary One Pulse output */
- TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE);
-
- /* Disable the Main Ouput */
- __HAL_TIM_MOE_DISABLE(htim);
-
- /* Disable the Peripheral */
- __HAL_TIM_DISABLE(htim);
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
- /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
- /* defined(STM32F105xC) || defined(STM32F107xC) */
-
-/** @defgroup TIMEx_Exported_Functions_Group5 Peripheral Control functions
- * @brief Peripheral Control functions
- *
-@verbatim
- ==============================================================================
- ##### Peripheral Control functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to:
- (+) Configure the commutation event in case of use of the Hall sensor interface.
- (+) Configure Complementary channels, break features and dead time.
- (+) Configure Master synchronization.
-
-@endverbatim
- * @{
- */
-
-#if defined (STM32F100xB) || defined (STM32F100xE) || \
- defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
- defined (STM32F105xC) || defined (STM32F107xC)
-
-/**
- * @brief Configure the TIM commutation event sequence.
- * @note: this function is mandatory to use the commutation event in order to
- * update the configuration at each commutation detection on the TRGI input of the Timer,
- * the typical use of this feature is with the use of another Timer(interface Timer)
- * configured in Hall sensor interface, this interface Timer will generate the
- * commutation at its TRGO output (connected to Timer used in this function) each time
- * the TI1 of the Interface Timer detect a commutation at its input TI1.
- * @param htim : TIM handle
- * @param InputTrigger : the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
- * This parameter can be one of the following values:
- * @arg TIM_TS_ITR0: Internal trigger 0 selected
- * @arg TIM_TS_ITR1: Internal trigger 1 selected
- * @arg TIM_TS_ITR2: Internal trigger 2 selected
- * @arg TIM_TS_ITR3: Internal trigger 3 selected
- * @arg TIM_TS_NONE: No trigger is needed
- * @param CommutationSource : the Commutation Event source
- * This parameter can be one of the following values:
- * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
- * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource)
-{
- /* Check the parameters */
- assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
- assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
-
- __HAL_LOCK(htim);
-
- if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
- (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
- {
- /* Select the Input trigger */
- htim->Instance->SMCR &= ~TIM_SMCR_TS;
- htim->Instance->SMCR |= InputTrigger;
- }
-
- /* Select the Capture Compare preload feature */
- htim->Instance->CR2 |= TIM_CR2_CCPC;
- /* Select the Commutation event source */
- htim->Instance->CR2 &= ~TIM_CR2_CCUS;
- htim->Instance->CR2 |= CommutationSource;
-
- __HAL_UNLOCK(htim);
-
- return HAL_OK;
-}
-
-/**
- * @brief Configure the TIM commutation event sequence with interrupt.
- * @note: this function is mandatory to use the commutation event in order to
- * update the configuration at each commutation detection on the TRGI input of the Timer,
- * the typical use of this feature is with the use of another Timer(interface Timer)
- * configured in Hall sensor interface, this interface Timer will generate the
- * commutation at its TRGO output (connected to Timer used in this function) each time
- * the TI1 of the Interface Timer detect a commutation at its input TI1.
- * @param htim : TIM handle
- * @param InputTrigger : the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
- * This parameter can be one of the following values:
- * @arg TIM_TS_ITR0: Internal trigger 0 selected
- * @arg TIM_TS_ITR1: Internal trigger 1 selected
- * @arg TIM_TS_ITR2: Internal trigger 2 selected
- * @arg TIM_TS_ITR3: Internal trigger 3 selected
- * @arg TIM_TS_NONE: No trigger is needed
- * @param CommutationSource : the Commutation Event source
- * This parameter can be one of the following values:
- * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
- * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent_IT(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource)
-{
- /* Check the parameters */
- assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
- assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
-
- __HAL_LOCK(htim);
-
- if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
- (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
- {
- /* Select the Input trigger */
- htim->Instance->SMCR &= ~TIM_SMCR_TS;
- htim->Instance->SMCR |= InputTrigger;
- }
-
- /* Select the Capture Compare preload feature */
- htim->Instance->CR2 |= TIM_CR2_CCPC;
- /* Select the Commutation event source */
- htim->Instance->CR2 &= ~TIM_CR2_CCUS;
- htim->Instance->CR2 |= CommutationSource;
-
- /* Enable the Commutation Interrupt Request */
- __HAL_TIM_ENABLE_IT(htim, TIM_IT_COM);
-
- __HAL_UNLOCK(htim);
-
- return HAL_OK;
-}
-
-/**
- * @brief Configure the TIM commutation event sequence with DMA.
- * @note: this function is mandatory to use the commutation event in order to
- * update the configuration at each commutation detection on the TRGI input of the Timer,
- * the typical use of this feature is with the use of another Timer(interface Timer)
- * configured in Hall sensor interface, this interface Timer will generate the
- * commutation at its TRGO output (connected to Timer used in this function) each time
- * the TI1 of the Interface Timer detect a commutation at its input TI1.
- * @note: The user should configure the DMA in his own software, in This function only the COMDE bit is set
- * @param htim : TIM handle
- * @param InputTrigger : the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
- * This parameter can be one of the following values:
- * @arg TIM_TS_ITR0: Internal trigger 0 selected
- * @arg TIM_TS_ITR1: Internal trigger 1 selected
- * @arg TIM_TS_ITR2: Internal trigger 2 selected
- * @arg TIM_TS_ITR3: Internal trigger 3 selected
- * @arg TIM_TS_NONE: No trigger is needed
- * @param CommutationSource : the Commutation Event source
- * This parameter can be one of the following values:
- * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
- * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent_DMA(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource)
-{
- /* Check the parameters */
- assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
- assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
-
- __HAL_LOCK(htim);
-
- if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
- (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
- {
- /* Select the Input trigger */
- htim->Instance->SMCR &= ~TIM_SMCR_TS;
- htim->Instance->SMCR |= InputTrigger;
- }
-
- /* Select the Capture Compare preload feature */
- htim->Instance->CR2 |= TIM_CR2_CCPC;
- /* Select the Commutation event source */
- htim->Instance->CR2 &= ~TIM_CR2_CCUS;
- htim->Instance->CR2 |= CommutationSource;
-
- /* Enable the Commutation DMA Request */
- /* Set the DMA Commutation Callback */
- htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt;
- /* Set the DMA error callback */
- htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError;
-
- /* Enable the Commutation DMA Request */
- __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_COM);
-
- __HAL_UNLOCK(htim);
-
- return HAL_OK;
-}
-
-/**
- * @brief Configures the Break feature, dead time, Lock level, OSSI/OSSR State
- * and the AOE(automatic output enable).
- * @param htim : TIM handle
- * @param sBreakDeadTimeConfig : pointer to a TIM_ConfigBreakDeadConfigTypeDef structure that
- * contains the BDTR Register configuration information for the TIM peripheral.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim,
- TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig)
-{
- uint32_t tmpbdtr = 0U;
-
- /* Check the parameters */
- assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance));
- assert_param(IS_TIM_OSSR_STATE(sBreakDeadTimeConfig->OffStateRunMode));
- assert_param(IS_TIM_OSSI_STATE(sBreakDeadTimeConfig->OffStateIDLEMode));
- assert_param(IS_TIM_LOCK_LEVEL(sBreakDeadTimeConfig->LockLevel));
- assert_param(IS_TIM_DEADTIME(sBreakDeadTimeConfig->DeadTime));
- assert_param(IS_TIM_BREAK_STATE(sBreakDeadTimeConfig->BreakState));
- assert_param(IS_TIM_BREAK_POLARITY(sBreakDeadTimeConfig->BreakPolarity));
- assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(sBreakDeadTimeConfig->AutomaticOutput));
-
- /* Process Locked */
- __HAL_LOCK(htim);
-
- /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State,
- the OSSI State, the dead time value and the Automatic Output Enable Bit */
-
- /* Set the BDTR bits */
- MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, sBreakDeadTimeConfig->DeadTime);
- MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, sBreakDeadTimeConfig->LockLevel);
- MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, sBreakDeadTimeConfig->OffStateIDLEMode);
- MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, sBreakDeadTimeConfig->OffStateRunMode);
- MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, sBreakDeadTimeConfig->BreakState);
- MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, sBreakDeadTimeConfig->BreakPolarity);
- MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, sBreakDeadTimeConfig->AutomaticOutput);
- MODIFY_REG(tmpbdtr, TIM_BDTR_MOE, sBreakDeadTimeConfig->AutomaticOutput);
-
- /* Set TIMx_BDTR */
- htim->Instance->BDTR = tmpbdtr;
-
- __HAL_UNLOCK(htim);
-
- return HAL_OK;
-}
-
-#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
- /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
- /* defined(STM32F105xC) || defined(STM32F107xC) */
-
-/**
- * @brief Configures the TIM in master mode.
- * @param htim : TIM handle.
- * @param sMasterConfig : pointer to a TIM_MasterConfigTypeDef structure that
- * contains the selected trigger output (TRGO) and the Master/Slave
- * mode.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim, TIM_MasterConfigTypeDef * sMasterConfig)
-{
- /* Check the parameters */
- assert_param(IS_TIM_MASTER_INSTANCE(htim->Instance));
- assert_param(IS_TIM_TRGO_SOURCE(sMasterConfig->MasterOutputTrigger));
- assert_param(IS_TIM_MSM_STATE(sMasterConfig->MasterSlaveMode));
-
- __HAL_LOCK(htim);
-
- htim->State = HAL_TIM_STATE_BUSY;
-
- /* Reset the MMS Bits */
- htim->Instance->CR2 &= ~TIM_CR2_MMS;
- /* Select the TRGO source */
- htim->Instance->CR2 |= sMasterConfig->MasterOutputTrigger;
-
- /* Reset the MSM Bit */
- htim->Instance->SMCR &= ~TIM_SMCR_MSM;
- /* Set or Reset the MSM Bit */
- htim->Instance->SMCR |= sMasterConfig->MasterSlaveMode;
-
- htim->State = HAL_TIM_STATE_READY;
-
- __HAL_UNLOCK(htim);
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup TIMEx_Exported_Functions_Group6 Extension Callbacks functions
- * @brief Extension Callbacks functions
- *
-@verbatim
- ==============================================================================
- ##### Extension Callbacks functions #####
- ==============================================================================
- [..]
- This section provides Extension TIM callback functions:
- (+) Timer Commutation callback
- (+) Timer Break callback
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Hall commutation changed callback in non blocking mode
- * @param htim : TIM handle
- * @retval None
- */
-__weak void HAL_TIMEx_CommutationCallback(TIM_HandleTypeDef *htim)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(htim);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_TIMEx_CommutationCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Hall Break detection callback in non blocking mode
- * @param htim : TIM handle
- * @retval None
- */
-__weak void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(htim);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_TIMEx_BreakCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief TIM DMA Commutation callback.
- * @param hdma : pointer to DMA handle.
- * @retval None
- */
-void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma)
-{
- TIM_HandleTypeDef* htim = ( TIM_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- htim->State= HAL_TIM_STATE_READY;
-
- HAL_TIMEx_CommutationCallback(htim);
-}
-
-/**
- * @}
- */
-
-#if defined (STM32F100xB) || defined (STM32F100xE) || \
- defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
- defined (STM32F105xC) || defined (STM32F107xC)
-
-/** @defgroup TIMEx_Exported_Functions_Group7 Extension Peripheral State functions
- * @brief Extension Peripheral State functions
- *
-@verbatim
- ==============================================================================
- ##### Extension Peripheral State functions #####
- ==============================================================================
- [..]
- This subsection permit to get in run-time the status of the peripheral
- and the data flow.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Return the TIM Hall Sensor interface state
- * @param htim : TIM Hall Sensor handle
- * @retval HAL state
- */
-HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(TIM_HandleTypeDef *htim)
-{
- return htim->State;
-}
-
-/**
- * @}
- */
-#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
- /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
- /* defined(STM32F105xC) || defined(STM32F107xC) */
-
-/**
- * @}
- */
-
-#if defined (STM32F100xB) || defined (STM32F100xE) || \
- defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
- defined (STM32F105xC) || defined (STM32F107xC)
-
-/** @addtogroup TIMEx_Private_Functions
- * @{
- */
-
-/**
- * @brief Enables or disables the TIM Capture Compare Channel xN.
- * @param TIMx to select the TIM peripheral
- * @param 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 ChannelNState : specifies the TIM Channel CCxNE bit new state.
- * This parameter can be: TIM_CCxN_ENABLE or TIM_CCxN_Disable.
- * @retval None
- */
-static void TIM_CCxNChannelCmd(TIM_TypeDef* TIMx, uint32_t Channel, uint32_t ChannelNState)
-{
- uint32_t tmp = 0U;
-
- tmp = TIM_CCER_CC1NE << Channel;
-
- /* Reset the CCxNE Bit */
- TIMx->CCER &= ~tmp;
-
- /* Set or reset the CCxNE Bit */
- TIMx->CCER |= (uint32_t)(ChannelNState << Channel);
-}
-
-/**
- * @}
- */
-
-#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
- /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
- /* defined(STM32F105xC) || defined(STM32F107xC) */
-
-#endif /* HAL_TIM_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_rtc_alarm_template.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_rtc_alarm_template.c
deleted file mode 100644
index 8c1d856..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_rtc_alarm_template.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_timebase_rtc_alarm_template.c
- * @author MCD Application Team
- * @brief HAL time base based on the hardware RTC_ALARM.
- *
- * This file override the native HAL time base functions (defined as weak)
- * to use the RTC ALARM for time base generation:
- * + Intializes the RTC peripheral to increment the seconds registers each 1ms
- * + The alarm is configured to assert an interrupt when the RTC reaches 1ms
- * + HAL_IncTick is called at each Alarm event and the time is reset to 00:00:00
- * + HSE (default), LSE or LSI can be selected as RTC clock source
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- This file must be copied to the application folder and modified as follows:
- (#) Rename it to 'stm32f1xx_hal_timebase_rtc_alarm.c'
- (#) Add this file and the RTC HAL drivers to your project and uncomment
- HAL_RTC_MODULE_ENABLED define in stm32f1xx_hal_conf.h
-
- [..]
- (@) HAL RTC alarm and HAL RTC wakeup drivers can’t be used with low power modes:
- The wake up capability of the RTC may be intrusive in case of prior low power mode
- configuration requiring different wake up sources.
- Application/Example behavior is no more guaranteed
- (@) The stm32f1xx_hal_timebase_tim use is recommended for the Applications/Examples
- requiring low power modes
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup HAL_TimeBase_RTC_Alarm_Template HAL TimeBase RTC Alarm Template
- * @{
- */
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-
-/* Uncomment the line below to select the appropriate RTC Clock source for your application:
- + RTC_CLOCK_SOURCE_HSE: can be selected for applications requiring timing precision.
- + RTC_CLOCK_SOURCE_LSE: can be selected for applications with low constraint on timing
- precision.
- + RTC_CLOCK_SOURCE_LSI: can be selected for applications with low constraint on timing
- precision.
- */
-#define RTC_CLOCK_SOURCE_HSE
-/* #define RTC_CLOCK_SOURCE_LSE */
-/* #define RTC_CLOCK_SOURCE_LSI */
-
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-RTC_HandleTypeDef hRTC_Handle;
-/* Private function prototypes -----------------------------------------------*/
-void RTC_Alarm_IRQHandler(void);
-/* Private functions ---------------------------------------------------------*/
-
-/**
- * @brief This function configures the RTC_ALARMA as a time base source.
- * The time source is configured to have 1ms time base with a dedicated
- * Tick interrupt priority.
- * @note This function is called automatically at the beginning of program after
- * reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
- * @param TickPriority: Tick interrupt priority.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
-{
- __IO uint32_t counter = 0U;
-
- RCC_OscInitTypeDef RCC_OscInitStruct;
- RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
-
-#ifdef RTC_CLOCK_SOURCE_LSE
- /* Configue LSE as RTC clock soucre */
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
- RCC_OscInitStruct.LSEState = RCC_LSE_ON;
- PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
-#elif defined (RTC_CLOCK_SOURCE_LSI)
- /* Configue LSI as RTC clock soucre */
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
- RCC_OscInitStruct.LSIState = RCC_LSI_ON;
- PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
-#elif defined (RTC_CLOCK_SOURCE_HSE)
- /* Configue HSE as RTC clock soucre */
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
- RCC_OscInitStruct.HSEState = RCC_HSE_ON;
- PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV128;
-#else
-#error Please select the RTC Clock source
-#endif /* RTC_CLOCK_SOURCE_LSE */
-
- if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK)
- {
- PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
- if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) == HAL_OK)
- {
- /* Enable RTC Clock */
- __HAL_RCC_RTC_ENABLE();
-
- hRTC_Handle.Instance = RTC;
- /* Configure RTC time base to 10Khz */
- hRTC_Handle.Init.AsynchPrediv = (HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_RTC) / 10000) - 1;
- hRTC_Handle.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
- HAL_RTC_Init(&hRTC_Handle);
-
- /* Disable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle);
-
- /* Clear flag alarm A */
- __HAL_RTC_ALARM_CLEAR_FLAG(&hRTC_Handle, RTC_FLAG_ALRAF);
-
- counter = 0U;
- /* Wait till RTC ALRAF flag is set and if Time out is reached exit */
- while (__HAL_RTC_ALARM_GET_FLAG(&hRTC_Handle, RTC_FLAG_ALRAF) != RESET)
- {
- if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
- {
- return HAL_ERROR;
- }
- }
-
- /* Set RTC COUNTER MSB word */
- hRTC_Handle.Instance->ALRH = 0x00U;
- /* Set RTC COUNTER LSB word */
- hRTC_Handle.Instance->ALRL = 0x09U;
-
- /* RTC Alarm Interrupt Configuration: EXTI configuration */
- __HAL_RTC_ALARM_EXTI_ENABLE_IT();
- __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE();
-
- /* Clear Second and overflow flags */
- CLEAR_BIT(hRTC_Handle.Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW));
-
- /* Set RTC COUNTER MSB word */
- hRTC_Handle.Instance->CNTH = 0x00U;
- /* Set RTC COUNTER LSB word */
- hRTC_Handle.Instance->CNTL = 0x00U;
-
- /* Configure the Alarm interrupt */
- __HAL_RTC_ALARM_ENABLE_IT(&hRTC_Handle, RTC_IT_ALRA);
-
- /* Enable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle);
-
- /* Wait till RTC is in INIT state and if Time out is reached exit */
- counter = 0U;
- while ((hRTC_Handle.Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
- {
- if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
- {
- return HAL_ERROR;
- }
- }
-
- HAL_NVIC_SetPriority(RTC_Alarm_IRQn, TickPriority, 0U);
- HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
- return HAL_OK;
- }
- }
- return HAL_ERROR;
-}
-
-/**
- * @brief Suspend Tick increment.
- * @note Disable the tick increment by disabling RTC ALARM interrupt.
- * @param None
- * @retval None
- */
-void HAL_SuspendTick(void)
-{
- /* Disable RTC ALARM update Interrupt */
- __HAL_RTC_ALARM_DISABLE_IT(&hRTC_Handle, RTC_IT_ALRA);
-}
-
-/**
- * @brief Resume Tick increment.
- * @note Enable the tick increment by Enabling RTC ALARM interrupt.
- * @param None
- * @retval None
- */
-void HAL_ResumeTick(void)
-{
- __IO uint32_t counter = 0U;
-
- /* Disable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle);
-
- /* Set RTC COUNTER MSB word */
- hRTC_Handle.Instance->CNTH = 0x00U;
- /* Set RTC COUNTER LSB word */
- hRTC_Handle.Instance->CNTL = 0x00U;
-
- /* Clear Second and overflow flags */
- CLEAR_BIT(hRTC_Handle.Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW | RTC_FLAG_ALRAF));
-
- /* Enable RTC ALARM Update interrupt */
- __HAL_RTC_ALARM_ENABLE_IT(&hRTC_Handle, RTC_IT_ALRA);
-
- /* Enable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle);
-
- /* Wait till RTC is in INIT state and if Time out is reached exit */
- while ((hRTC_Handle.Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
- {
- if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
- {
- break;
- }
- }
-}
-
-/**
- * @brief ALARM A Event Callback in non blocking mode
- * @note This function is called when RTC_ALARM interrupt took place, inside
- * RTC_ALARM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
- * a global variable "uwTick" used as application time base.
- * @param hrtc : RTC handle
- * @retval None
- */
-void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
-{
- __IO uint32_t counter = 0U;
-
- HAL_IncTick();
-
- __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
-
- /* Set RTC COUNTER MSB word */
- WRITE_REG(hrtc->Instance->CNTH, 0x00U);
- /* Set RTC COUNTER LSB word */
- WRITE_REG(hrtc->Instance->CNTL, 0x00U);
-
- /* Clear Second and overflow flags */
- CLEAR_BIT(hrtc->Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW));
-
- /* Enable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
-
- /* Wait till RTC is in INIT state and if Time out is reached exit */
- while ((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
- {
- if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
- {
- break;
- }
- }
-}
-
-/**
- * @brief This function handles RTC ALARM interrupt request.
- * @retval None
- */
-void RTC_Alarm_IRQHandler(void)
-{
- HAL_RTC_AlarmIRQHandler(&hRTC_Handle);
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_tim_template.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_tim_template.c
deleted file mode 100644
index e3dbd2d..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_tim_template.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_timebase_tim_template.c
- * @author MCD Application Team
- * @brief HAL time base based on the hardware TIM Template.
- *
- * This file overrides the native HAL time base functions (defined as weak)
- * the TIM time base:
- * + Intializes the TIM peripheral generate a Period elapsed Event each 1ms
- * + HAL_IncTick is called inside HAL_TIM_PeriodElapsedCallback ie each 1ms
- *
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup HAL_TimeBase_TIM
- * @{
- */
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-TIM_HandleTypeDef TimHandle;
-/* Private function prototypes -----------------------------------------------*/
-void TIM2_IRQHandler(void);
-/* Private functions ---------------------------------------------------------*/
-
-/**
- * @brief This function configures the TIM2 as a time base source.
- * The time source is configured to have 1ms time base with a dedicated
- * Tick interrupt priority.
- * @note This function is called automatically at the beginning of program after
- * reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
- * @param TickPriority: Tick interrupt priority.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
-{
- RCC_ClkInitTypeDef clkconfig;
- uint32_t uwTimclock, uwAPB1Prescaler = 0U;
- uint32_t uwPrescalerValue = 0U;
- uint32_t pFLatency;
-
- /*Configure the TIM2 IRQ priority */
- HAL_NVIC_SetPriority(TIM2_IRQn, TickPriority, 0U);
-
- /* Enable the TIM2 global Interrupt */
- HAL_NVIC_EnableIRQ(TIM2_IRQn);
-
- /* Enable TIM2 clock */
- __HAL_RCC_TIM2_CLK_ENABLE();
-
- /* Get clock configuration */
- HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
-
- /* Get APB1 prescaler */
- uwAPB1Prescaler = clkconfig.APB1CLKDivider;
-
- /* Compute TIM2 clock */
- if (uwAPB1Prescaler == RCC_HCLK_DIV1)
- {
- uwTimclock = HAL_RCC_GetPCLK1Freq();
- }
- else
- {
- uwTimclock = 2 * HAL_RCC_GetPCLK1Freq();
- }
-
- /* Compute the prescaler value to have TIM2 counter clock equal to 1MHz */
- uwPrescalerValue = (uint32_t)((uwTimclock / 1000000U) - 1U);
-
- /* Initialize TIM2 */
- TimHandle.Instance = TIM2;
-
- /* Initialize TIMx peripheral as follow:
- + Period = [(TIM2CLK/1000) - 1]. to have a (1/1000) s time base.
- + Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
- + ClockDivision = 0
- + Counter direction = Up
- */
- TimHandle.Init.Period = (1000000U / 1000U) - 1U;
- TimHandle.Init.Prescaler = uwPrescalerValue;
- TimHandle.Init.ClockDivision = 0U;
- TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
- TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
- if (HAL_TIM_Base_Init(&TimHandle) == HAL_OK)
- {
- /* Start the TIM time Base generation in interrupt mode */
- return HAL_TIM_Base_Start_IT(&TimHandle);
- }
-
- /* Return function status */
- return HAL_ERROR;
-}
-
-/**
- * @brief Suspend Tick increment.
- * @note Disable the tick increment by disabling TIM2 update interrupt.
- * @retval None
- */
-void HAL_SuspendTick(void)
-{
- /* Disable TIM2 update Interrupt */
- __HAL_TIM_DISABLE_IT(&TimHandle, TIM_IT_UPDATE);
-}
-
-/**
- * @brief Resume Tick increment.
- * @note Enable the tick increment by Enabling TIM2 update interrupt.
- * @retval None
- */
-void HAL_ResumeTick(void)
-{
- /* Enable TIM2 Update interrupt */
- __HAL_TIM_ENABLE_IT(&TimHandle, TIM_IT_UPDATE);
-}
-
-/**
- * @brief Period elapsed callback in non blocking mode
- * @note This function is called when TIM2 interrupt took place, inside
- * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
- * a global variable "uwTick" used as application time base.
- * @param htim : TIM handle
- * @retval None
- */
-void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
-{
- HAL_IncTick();
-}
-
-/**
- * @brief This function handles TIM interrupt request.
- * @retval None
- */
-void TIM2_IRQHandler(void)
-{
- HAL_TIM_IRQHandler(&TimHandle);
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c
deleted file mode 100644
index ef18d11..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c
+++ /dev/null
@@ -1,2556 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_uart.c
- * @author MCD Application Team
- * @brief UART HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Universal Asynchronous Receiver Transmitter (UART) peripheral:
- * + Initialization and de-initialization functions
- * + IO operation functions
- * + Peripheral Control functions
- * + Peripheral State and Errors functions
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- The UART HAL driver can be used as follows:
-
- (#) Declare a UART_HandleTypeDef handle structure.
- (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API:
- (##) Enable the USARTx interface clock.
- (##) UART pins configuration:
- (+++) Enable the clock for the UART GPIOs.
- (+++) Configure the UART pins (TX as alternate function pull-up, RX as alternate function Input).
- (##) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT()
- and HAL_UART_Receive_IT() APIs):
- (+++) Configure the USARTx interrupt priority.
- (+++) Enable the NVIC USART IRQ handle.
- (##) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
- and HAL_UART_Receive_DMA() APIs):
- (+++) Declare a DMA handle structure for the Tx/Rx channel.
- (+++) Enable the DMAx interface clock.
- (+++) Configure the declared DMA handle structure with the required
- Tx/Rx parameters.
- (+++) Configure the DMA Tx/Rx channel.
- (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle.
- (+++) Configure the priority and enable the NVIC for the transfer complete
- interrupt on the DMA Tx/Rx channel.
- (+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
- (used for last byte sending completion detection in DMA non circular mode)
-
- (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
- flow control and Mode(Receiver/Transmitter) in the huart Init structure.
-
- (#) For the UART asynchronous mode, initialize the UART registers by calling
- the HAL_UART_Init() API.
-
- (#) For the UART Half duplex mode, initialize the UART registers by calling
- the HAL_HalfDuplex_Init() API.
-
- (#) For the LIN mode, initialize the UART registers by calling the HAL_LIN_Init() API.
-
- (#) For the Multi-Processor mode, initialize the UART registers by calling
- the HAL_MultiProcessor_Init() API.
-
- [..]
- (@) The specific UART interrupts (Transmission complete interrupt,
- RXNE interrupt and Error Interrupts) will be managed using the macros
- __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit
- and receive process.
-
- [..]
- (@) These APIs (HAL_UART_Init() and HAL_HalfDuplex_Init()) configure also the
- low level Hardware GPIO, CLOCK, CORTEX...etc) by calling the customized
- HAL_UART_MspInit() API.
-
- [..]
- Three operation modes are available within this driver:
-
- *** Polling mode IO operation ***
- =================================
- [..]
- (+) Send an amount of data in blocking mode using HAL_UART_Transmit()
- (+) Receive an amount of data in blocking mode using HAL_UART_Receive()
-
- *** Interrupt mode IO operation ***
- ===================================
- [..]
- (+) Send an amount of data in non blocking mode using HAL_UART_Transmit_IT()
- (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_UART_TxCpltCallback
- (+) Receive an amount of data in non blocking mode using HAL_UART_Receive_IT()
- (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_UART_RxCpltCallback
- (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
- add his own code by customization of function pointer HAL_UART_ErrorCallback
-
- *** DMA mode IO operation ***
- ==============================
- [..]
- (+) Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA()
- (+) At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback
- (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_UART_TxCpltCallback
- (+) Receive an amount of data in non blocking mode (DMA) using HAL_UART_Receive_DMA()
- (+) At reception end of half transfer HAL_UART_RxHalfCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_UART_RxHalfCpltCallback
- (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_UART_RxCpltCallback
- (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
- add his own code by customization of function pointer HAL_UART_ErrorCallback
- (+) Pause the DMA Transfer using HAL_UART_DMAPause()
- (+) Resume the DMA Transfer using HAL_UART_DMAResume()
- (+) Stop the DMA Transfer using HAL_UART_DMAStop()
-
- *** UART HAL driver macros list ***
- =============================================
- [..]
- Below the list of most used macros in UART HAL driver.
-
- (+) __HAL_UART_ENABLE: Enable the UART peripheral
- (+) __HAL_UART_DISABLE: Disable the UART peripheral
- (+) __HAL_UART_GET_FLAG : Check whether the specified UART flag is set or not
- (+) __HAL_UART_CLEAR_FLAG : Clear the specified UART pending flag
- (+) __HAL_UART_ENABLE_IT: Enable the specified UART interrupt
- (+) __HAL_UART_DISABLE_IT: Disable the specified UART interrupt
- (+) __HAL_UART_GET_IT_SOURCE: Check whether the specified UART interrupt has occurred or not
-
- [..]
- (@) You can refer to the UART HAL driver header file for more useful macros
- @endverbatim
- [..]
- (@) Additionnal remark: If the parity is enabled, then the MSB bit of the data written
- in the data register is transmitted but is changed by the parity bit.
- Depending on the frame length defined by the M bit (8-bits or 9-bits),
- the possible UART frame formats are as listed in the following table:
- +-------------------------------------------------------------+
- | M bit | PCE bit | UART frame |
- |---------------------|---------------------------------------|
- | 0 | 0 | | SB | 8 bit data | STB | |
- |---------|-----------|---------------------------------------|
- | 0 | 1 | | SB | 7 bit data | PB | STB | |
- |---------|-----------|---------------------------------------|
- | 1 | 0 | | SB | 9 bit data | STB | |
- |---------|-----------|---------------------------------------|
- | 1 | 1 | | SB | 8 bit data | PB | STB | |
- +-------------------------------------------------------------+
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup UART UART
- * @brief HAL UART module driver
- * @{
- */
-#ifdef HAL_UART_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @addtogroup UART_Private_Constants
- * @{
- */
-/**
- * @}
- */
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @addtogroup UART_Private_Functions
- * @{
- */
-static void UART_EndTxTransfer(UART_HandleTypeDef *huart);
-static void UART_EndRxTransfer(UART_HandleTypeDef *huart);
-static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
-static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
-static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
-static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
-static void UART_DMAError(DMA_HandleTypeDef *hdma);
-static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
-static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
-static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
-static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
-static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
-static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart);
-static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart);
-static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart);
-static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout);
-static void UART_SetConfig (UART_HandleTypeDef *huart);
-/**
- * @}
- */
-/* Exported functions ---------------------------------------------------------*/
-/** @defgroup UART_Exported_Functions UART Exported Functions
- * @{
- */
-
-/** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
- ==============================================================================
- ##### Initialization and Configuration functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
- in asynchronous mode.
- (+) For the asynchronous mode only these parameters can be configured:
- (++) Baud Rate
- (++) Word Length
- (++) Stop Bit
- (++) Parity: If the parity is enabled, then the MSB bit of the data written
- in the data register is transmitted but is changed by the parity bit.
- Depending on the frame length defined by the M bit (8-bits or 9-bits),
- please refer to Reference manual for possible UART frame formats.
- (++) Hardware flow control
- (++) Receiver/transmitter modes
- (++) Over Sampling Method
- [..]
- The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init() and HAL_MultiProcessor_Init() APIs
- follow respectively the UART asynchronous, UART Half duplex, LIN and Multi-Processor
- configuration procedures (details for the procedures are available in reference manuals
- (RM0008 for STM32F10Xxx MCUs and RM0041 for STM32F100xx MCUs)).
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the UART mode according to the specified parameters in
- * the UART_InitTypeDef and create the associated handle.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
-{
- /* Check the UART handle allocation */
- if(huart == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- if(huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
- {
- /* The hardware flow control is available only for USART1, USART2, USART3 */
- assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
- assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
- }
- else
- {
- assert_param(IS_UART_INSTANCE(huart->Instance));
- }
- assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
-#if defined(USART_CR1_OVER8)
- assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
-#endif /* USART_CR1_OVER8 */
-
- if(huart->gState == HAL_UART_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- huart->Lock = HAL_UNLOCKED;
-
- /* Init the low level hardware */
- HAL_UART_MspInit(huart);
- }
-
- huart->gState = HAL_UART_STATE_BUSY;
-
- /* Disable the peripheral */
- __HAL_UART_DISABLE(huart);
-
- /* Set the UART Communication parameters */
- UART_SetConfig(huart);
-
- /* In asynchronous mode, the following bits must be kept cleared:
- - LINEN and CLKEN bits in the USART_CR2 register,
- - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
- CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
- CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
-
- /* Enable the peripheral */
- __HAL_UART_ENABLE(huart);
-
- /* Initialize the UART state */
- huart->ErrorCode = HAL_UART_ERROR_NONE;
- huart->gState= HAL_UART_STATE_READY;
- huart->RxState= HAL_UART_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the half-duplex mode according to the specified
- * parameters in the UART_InitTypeDef and create the associated handle.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
-{
- /* Check the UART handle allocation */
- if(huart == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
- assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
-#if defined(USART_CR1_OVER8)
- assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
-#endif /* USART_CR1_OVER8 */
- if(huart->gState == HAL_UART_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- huart->Lock = HAL_UNLOCKED;
- /* Init the low level hardware */
- HAL_UART_MspInit(huart);
- }
-
- huart->gState = HAL_UART_STATE_BUSY;
-
- /* Disable the peripheral */
- __HAL_UART_DISABLE(huart);
-
- /* Set the UART Communication parameters */
- UART_SetConfig(huart);
-
- /* In half-duplex mode, the following bits must be kept cleared:
- - LINEN and CLKEN bits in the USART_CR2 register,
- - SCEN and IREN bits in the USART_CR3 register.*/
- CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
- CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN));
-
- /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
- SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
-
- /* Enable the peripheral */
- __HAL_UART_ENABLE(huart);
-
- /* Initialize the UART state*/
- huart->ErrorCode = HAL_UART_ERROR_NONE;
- huart->gState= HAL_UART_STATE_READY;
- huart->RxState= HAL_UART_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the LIN mode according to the specified
- * parameters in the UART_InitTypeDef and create the associated handle.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @param BreakDetectLength: Specifies the LIN break detection length.
- * This parameter can be one of the following values:
- * @arg UART_LINBREAKDETECTLENGTH_10B: 10-bit break detection
- * @arg UART_LINBREAKDETECTLENGTH_11B: 11-bit break detection
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength)
-{
- /* Check the UART handle allocation */
- if(huart == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the LIN UART instance */
- assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
- /* Check the Break detection length parameter */
- assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength));
- assert_param(IS_UART_LIN_WORD_LENGTH(huart->Init.WordLength));
-#if defined(USART_CR1_OVER8)
- assert_param(IS_UART_LIN_OVERSAMPLING(huart->Init.OverSampling));
-#endif /* USART_CR1_OVER8 */
-
- if(huart->gState == HAL_UART_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- huart->Lock = HAL_UNLOCKED;
- /* Init the low level hardware */
- HAL_UART_MspInit(huart);
- }
-
- huart->gState = HAL_UART_STATE_BUSY;
-
- /* Disable the peripheral */
- __HAL_UART_DISABLE(huart);
-
- /* Set the UART Communication parameters */
- UART_SetConfig(huart);
-
- /* In LIN mode, the following bits must be kept cleared:
- - CLKEN bits in the USART_CR2 register,
- - SCEN and IREN bits in the USART_CR3 register.*/
- CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN);
- CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN));
-
- /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
- SET_BIT(huart->Instance->CR2, USART_CR2_LINEN);
-
- /* Set the USART LIN Break detection length. */
- MODIFY_REG(huart->Instance->CR2, USART_CR2_LBDL, BreakDetectLength);
-
- /* Enable the peripheral */
- __HAL_UART_ENABLE(huart);
-
- /* Initialize the UART state*/
- huart->ErrorCode = HAL_UART_ERROR_NONE;
- huart->gState= HAL_UART_STATE_READY;
- huart->RxState= HAL_UART_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the Multi-Processor mode according to the specified
- * parameters in the UART_InitTypeDef and create the associated handle.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @param Address: USART address
- * @param WakeUpMethod: specifies the USART wake-up method.
- * This parameter can be one of the following values:
- * @arg UART_WAKEUPMETHOD_IDLELINE: Wake-up by an idle line detection
- * @arg UART_WAKEUPMETHOD_ADDRESSMARK: Wake-up by an address mark
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
-{
- /* Check the UART handle allocation */
- if(huart == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check UART instance capabilities */
- assert_param(IS_UART_MULTIPROCESSOR_INSTANCE(huart->Instance));
-
- /* Check the Address & wake up method parameters */
- assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
- assert_param(IS_UART_ADDRESS(Address));
- assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
-#if defined(USART_CR1_OVER8)
- assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
-#endif /* USART_CR1_OVER8 */
-
- if(huart->gState == HAL_UART_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- huart->Lock = HAL_UNLOCKED;
- /* Init the low level hardware */
- HAL_UART_MspInit(huart);
- }
-
- huart->gState = HAL_UART_STATE_BUSY;
-
- /* Disable the peripheral */
- __HAL_UART_DISABLE(huart);
-
- /* Set the UART Communication parameters */
- UART_SetConfig(huart);
-
- /* In Multi-Processor mode, the following bits must be kept cleared:
- - LINEN and CLKEN bits in the USART_CR2 register,
- - SCEN, HDSEL and IREN bits in the USART_CR3 register */
- CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
- CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
-
- /* Set the USART address node */
- MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, Address);
-
- /* Set the wake up method by setting the WAKE bit in the CR1 register */
- MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod);
-
- /* Enable the peripheral */
- __HAL_UART_ENABLE(huart);
-
- /* Initialize the UART state */
- huart->ErrorCode = HAL_UART_ERROR_NONE;
- huart->gState = HAL_UART_STATE_READY;
- huart->RxState = HAL_UART_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief DeInitializes the UART peripheral.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
-{
- /* Check the UART handle allocation */
- if(huart == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_UART_INSTANCE(huart->Instance));
-
- huart->gState = HAL_UART_STATE_BUSY;
-
- /* DeInit the low level hardware */
- HAL_UART_MspDeInit(huart);
-
- huart->ErrorCode = HAL_UART_ERROR_NONE;
- huart->gState = HAL_UART_STATE_RESET;
- huart->RxState = HAL_UART_STATE_RESET;
-
- /* Process Unlock */
- __HAL_UNLOCK(huart);
-
- return HAL_OK;
-}
-
-/**
- * @brief UART MSP Init.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval None
- */
-__weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(huart);
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_UART_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief UART MSP DeInit.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval None
- */
-__weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(huart);
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_UART_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup UART_Exported_Functions_Group2 IO operation functions
- * @brief UART Transmit and Receive functions
- *
-@verbatim
- ==============================================================================
- ##### IO operation functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to manage the UART asynchronous
- and Half duplex data transfers.
-
- (#) There are two modes of transfer:
- (++) Blocking mode: The communication is performed in polling mode.
- The HAL status of all data processing is returned by the same function
- after finishing transfer.
- (++) Non blocking mode: The communication is performed using Interrupts
- or DMA, these APIs return the HAL status.
- The end of the data processing will be indicated through the
- dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
- using DMA mode.
- The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
- will be executed respectively at the end of the transmit or receive process.
- The HAL_UART_ErrorCallback() user callback will be executed when
- a communication error is detected.
-
- (#) Blocking mode APIs are:
- (++) HAL_UART_Transmit()
- (++) HAL_UART_Receive()
-
- (#) Non Blocking mode APIs with Interrupt are:
- (++) HAL_UART_Transmit_IT()
- (++) HAL_UART_Receive_IT()
- (++) HAL_UART_IRQHandler()
-
- (#) Non Blocking mode functions with DMA are:
- (++) HAL_UART_Transmit_DMA()
- (++) HAL_UART_Receive_DMA()
- (++) HAL_UART_DMAPause()
- (++) HAL_UART_DMAResume()
- (++) HAL_UART_DMAStop()
-
- (#) A set of Transfer Complete Callbacks are provided in non blocking mode:
- (++) HAL_UART_TxHalfCpltCallback()
- (++) HAL_UART_TxCpltCallback()
- (++) HAL_UART_RxHalfCpltCallback()
- (++) HAL_UART_RxCpltCallback()
- (++) HAL_UART_ErrorCallback()
-
- [..]
- (@) In the Half duplex communication, it is forbidden to run the transmit
- and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX
- can't be useful.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Sends an amount of data in blocking mode.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @param pData: Pointer to data buffer
- * @param Size: Amount of data to be sent
- * @param Timeout: Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
-{
- uint16_t* tmp;
- uint32_t tickstart = 0U;
-
- /* Check that a Tx process is not already ongoing */
- if(huart->gState == HAL_UART_STATE_READY)
- {
- if((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(huart);
-
- huart->ErrorCode = HAL_UART_ERROR_NONE;
- huart->gState = HAL_UART_STATE_BUSY_TX;
-
- /* Init tickstart for timeout managment */
- tickstart = HAL_GetTick();
-
- huart->TxXferSize = Size;
- huart->TxXferCount = Size;
- while(huart->TxXferCount > 0U)
- {
- huart->TxXferCount--;
- if(huart->Init.WordLength == UART_WORDLENGTH_9B)
- {
- if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- tmp = (uint16_t*) pData;
- huart->Instance->DR = (*tmp & (uint16_t)0x01FF);
- if(huart->Init.Parity == UART_PARITY_NONE)
- {
- pData +=2U;
- }
- else
- {
- pData +=1U;
- }
- }
- else
- {
- if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- huart->Instance->DR = (*pData++ & (uint8_t)0xFF);
- }
- }
-
- if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
-
- /* At end of Tx process, restore huart->gState to Ready */
- huart->gState = HAL_UART_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(huart);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receive an amount of data in blocking mode.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @param pData: Pointer to data buffer
- * @param Size: Amount of data to be received
- * @param Timeout: Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
-{
- uint16_t* tmp;
- uint32_t tickstart = 0U;
-
- /* Check that a Rx process is not already ongoing */
- if(huart->RxState == HAL_UART_STATE_READY)
- {
- if((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(huart);
-
- huart->ErrorCode = HAL_UART_ERROR_NONE;
- huart->RxState = HAL_UART_STATE_BUSY_RX;
-
- /* Init tickstart for timeout managment */
- tickstart = HAL_GetTick();
-
- huart->RxXferSize = Size;
- huart->RxXferCount = Size;
-
- /* Check the remain data to be received */
- while(huart->RxXferCount > 0U)
- {
- huart->RxXferCount--;
- if(huart->Init.WordLength == UART_WORDLENGTH_9B)
- {
- if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- tmp = (uint16_t*)pData;
- if(huart->Init.Parity == UART_PARITY_NONE)
- {
- *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
- pData +=2U;
- }
- else
- {
- *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
- pData +=1U;
- }
-
- }
- else
- {
- if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- if(huart->Init.Parity == UART_PARITY_NONE)
- {
- *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
- }
- else
- {
- *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
- }
-
- }
- }
-
- /* At end of Rx process, restore huart->RxState to Ready */
- huart->RxState = HAL_UART_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(huart);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Sends an amount of data in non blocking mode.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @param pData: Pointer to data buffer
- * @param Size: Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
-{
- /* Check that a Tx process is not already ongoing */
- if(huart->gState == HAL_UART_STATE_READY)
- {
- if((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
- /* Process Locked */
- __HAL_LOCK(huart);
-
- huart->pTxBuffPtr = pData;
- huart->TxXferSize = Size;
- huart->TxXferCount = Size;
-
- huart->ErrorCode = HAL_UART_ERROR_NONE;
- huart->gState = HAL_UART_STATE_BUSY_TX;
-
- /* Process Unlocked */
- __HAL_UNLOCK(huart);
-
- /* Enable the UART Transmit data register empty Interrupt */
- __HAL_UART_ENABLE_IT(huart, UART_IT_TXE);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receives an amount of data in non blocking mode.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @param pData: Pointer to data buffer
- * @param Size: Amount of data to be received
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
-{
- /* Check that a Rx process is not already ongoing */
- if(huart->RxState == HAL_UART_STATE_READY)
- {
- if((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(huart);
-
- huart->pRxBuffPtr = pData;
- huart->RxXferSize = Size;
- huart->RxXferCount = Size;
-
- huart->ErrorCode = HAL_UART_ERROR_NONE;
- huart->RxState = HAL_UART_STATE_BUSY_RX;
-
- /* Process Unlocked */
- __HAL_UNLOCK(huart);
-
- /* Enable the UART Parity Error Interrupt */
- __HAL_UART_ENABLE_IT(huart, UART_IT_PE);
-
- /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
- __HAL_UART_ENABLE_IT(huart, UART_IT_ERR);
-
- /* Enable the UART Data Register not empty Interrupt */
- __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Sends an amount of data in non blocking mode.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @param pData: Pointer to data buffer
- * @param Size: Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
-{
- uint32_t *tmp;
-
- /* Check that a Tx process is not already ongoing */
- if(huart->gState == HAL_UART_STATE_READY)
- {
- if((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(huart);
-
- huart->pTxBuffPtr = pData;
- huart->TxXferSize = Size;
- huart->TxXferCount = Size;
-
- huart->ErrorCode = HAL_UART_ERROR_NONE;
- huart->gState = HAL_UART_STATE_BUSY_TX;
-
- /* Set the UART DMA transfer complete callback */
- huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
-
- /* Set the UART DMA Half transfer complete callback */
- huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
-
- /* Set the DMA error callback */
- huart->hdmatx->XferErrorCallback = UART_DMAError;
-
- /* Set the DMA abort callback */
- huart->hdmatx->XferAbortCallback = NULL;
-
- /* Enable the UART transmit DMA channel */
- tmp = (uint32_t*)&pData;
- HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->DR, Size);
-
- /* Clear the TC flag in the SR register by writing 0 to it */
- __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
-
- /* Process Unlocked */
- __HAL_UNLOCK(huart);
-
- /* Enable the DMA transfer for transmit request by setting the DMAT bit
- in the UART CR3 register */
- SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receives an amount of data in non blocking mode.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @param pData: Pointer to data buffer
- * @param Size: Amount of data to be received
- * @note When the UART parity is enabled (PCE = 1) the data received contain the parity bit.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
-{
- uint32_t *tmp;
-
- /* Check that a Rx process is not already ongoing */
- if(huart->RxState == HAL_UART_STATE_READY)
- {
- if((pData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(huart);
-
- huart->pRxBuffPtr = pData;
- huart->RxXferSize = Size;
-
- huart->ErrorCode = HAL_UART_ERROR_NONE;
- huart->RxState = HAL_UART_STATE_BUSY_RX;
-
- /* Set the UART DMA transfer complete callback */
- huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
-
- /* Set the UART DMA Half transfer complete callback */
- huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
-
- /* Set the DMA error callback */
- huart->hdmarx->XferErrorCallback = UART_DMAError;
-
- /* Set the DMA abort callback */
- huart->hdmarx->XferAbortCallback = NULL;
-
- /* Enable the DMA channel */
- tmp = (uint32_t*)&pData;
- HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->DR, *(uint32_t*)tmp, Size);
-
- /* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */
- __HAL_UART_CLEAR_OREFLAG(huart);
-
- /* Process Unlocked */
- __HAL_UNLOCK(huart);
-
- /* Enable the UART Parity Error Interrupt */
- SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
-
- /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
- SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
-
- /* Enable the DMA transfer for the receiver request by setting the DMAR bit
- in the UART CR3 register */
- SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Pauses the DMA Transfer.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
-{
- uint32_t dmarequest = 0x00U;
-
- /* Process Locked */
- __HAL_LOCK(huart);
-
- dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
- if((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
- {
- /* Disable the UART DMA Tx request */
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
- }
-
- dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
- if((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
- {
- /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
-
- /* Disable the UART DMA Rx request */
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
- }
-
- /* Process Unlocked */
- __HAL_UNLOCK(huart);
-
- return HAL_OK;
-}
-
-/**
- * @brief Resumes the DMA Transfer.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
-{
- /* Process Locked */
- __HAL_LOCK(huart);
-
- if(huart->gState == HAL_UART_STATE_BUSY_TX)
- {
- /* Enable the UART DMA Tx request */
- SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
- }
-
- if(huart->RxState == HAL_UART_STATE_BUSY_RX)
- {
- /* Clear the Overrun flag before resuming the Rx transfer*/
- __HAL_UART_CLEAR_OREFLAG(huart);
-
- /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */
- SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
- SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
-
- /* Enable the UART DMA Rx request */
- SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
- }
-
- /* Process Unlocked */
- __HAL_UNLOCK(huart);
-
- return HAL_OK;
-}
-
-/**
- * @brief Stops the DMA Transfer.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
-{
- uint32_t dmarequest = 0x00U;
- /* The Lock is not implemented on this API to allow the user application
- to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback():
- when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
- and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback()
- */
-
- /* Stop UART DMA Tx request if ongoing */
- dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
- if((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
- {
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
-
- /* Abort the UART DMA Tx channel */
- if(huart->hdmatx != NULL)
- {
- HAL_DMA_Abort(huart->hdmatx);
- }
- UART_EndTxTransfer(huart);
- }
-
- /* Stop UART DMA Rx request if ongoing */
- dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
- if((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
- {
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the UART DMA Rx channel */
- if(huart->hdmarx != NULL)
- {
- HAL_DMA_Abort(huart->hdmarx);
- }
- UART_EndRxTransfer(huart);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing transfers (blocking mode).
- * @param huart UART handle.
- * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
- * - Set handle State to READY
- * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart)
-{
- /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
-
- /* Disable the UART DMA Tx request if enabled */
- if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
- {
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
-
- /* Abort the UART DMA Tx channel: use blocking DMA Abort API (no callback) */
- if(huart->hdmatx != NULL)
- {
- /* Set the UART DMA Abort callback to Null.
- No call back execution at end of DMA abort procedure */
- huart->hdmatx->XferAbortCallback = NULL;
-
- HAL_DMA_Abort(huart->hdmatx);
- }
- }
-
- /* Disable the UART DMA Rx request if enabled */
- if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
- {
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the UART DMA Rx channel: use blocking DMA Abort API (no callback) */
- if(huart->hdmarx != NULL)
- {
- /* Set the UART DMA Abort callback to Null.
- No call back execution at end of DMA abort procedure */
- huart->hdmarx->XferAbortCallback = NULL;
-
- HAL_DMA_Abort(huart->hdmarx);
- }
- }
-
- /* Reset Tx and Rx transfer counters */
- huart->TxXferCount = 0x00U;
- huart->RxXferCount = 0x00U;
-
- /* Reset ErrorCode */
- huart->ErrorCode = HAL_UART_ERROR_NONE;
-
- /* Restore huart->RxState and huart->gState to Ready */
- huart->RxState = HAL_UART_STATE_READY;
- huart->gState = HAL_UART_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing Transmit transfer (blocking mode).
- * @param huart UART handle.
- * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
- * - Set handle State to READY
- * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart)
-{
- /* Disable TXEIE and TCIE interrupts */
- CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
-
- /* Disable the UART DMA Tx request if enabled */
- if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
- {
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
-
- /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
- if(huart->hdmatx != NULL)
- {
- /* Set the UART DMA Abort callback to Null.
- No call back execution at end of DMA abort procedure */
- huart->hdmatx->XferAbortCallback = NULL;
-
- HAL_DMA_Abort(huart->hdmatx);
- }
- }
-
- /* Reset Tx transfer counter */
- huart->TxXferCount = 0x00U;
-
- /* Restore huart->gState to Ready */
- huart->gState = HAL_UART_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing Receive transfer (blocking mode).
- * @param huart UART handle.
- * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
- * - Set handle State to READY
- * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart)
-{
- /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
-
- /* Disable the UART DMA Rx request if enabled */
- if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
- {
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
- if(huart->hdmarx != NULL)
- {
- /* Set the UART DMA Abort callback to Null.
- No call back execution at end of DMA abort procedure */
- huart->hdmarx->XferAbortCallback = NULL;
-
- HAL_DMA_Abort(huart->hdmarx);
- }
- }
-
- /* Reset Rx transfer counter */
- huart->RxXferCount = 0x00U;
-
- /* Restore huart->RxState to Ready */
- huart->RxState = HAL_UART_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing transfers (Interrupt mode).
- * @param huart UART handle.
- * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
- * - Set handle State to READY
- * - At abort completion, call user abort complete callback
- * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
- * considered as completed only when user abort complete callback is executed (not when exiting function).
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart)
-{
- uint32_t AbortCplt = 0x01U;
-
- /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
-
- /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised
- before any call to DMA Abort functions */
- /* DMA Tx Handle is valid */
- if(huart->hdmatx != NULL)
- {
- /* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
- Otherwise, set it to NULL */
- if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
- {
- huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback;
- }
- else
- {
- huart->hdmatx->XferAbortCallback = NULL;
- }
- }
- /* DMA Rx Handle is valid */
- if(huart->hdmarx != NULL)
- {
- /* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
- Otherwise, set it to NULL */
- if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
- {
- huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback;
- }
- else
- {
- huart->hdmarx->XferAbortCallback = NULL;
- }
- }
-
- /* Disable the UART DMA Tx request if enabled */
- if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
- {
- /* Disable DMA Tx at UART level */
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
-
- /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
- if(huart->hdmatx != NULL)
- {
- /* UART Tx DMA Abort callback has already been initialised :
- will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
-
- /* Abort DMA TX */
- if(HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
- {
- huart->hdmatx->XferAbortCallback = NULL;
- }
- else
- {
- AbortCplt = 0x00U;
- }
- }
- }
-
- /* Disable the UART DMA Rx request if enabled */
- if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
- {
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
- if(huart->hdmarx != NULL)
- {
- /* UART Rx DMA Abort callback has already been initialised :
- will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
-
- /* Abort DMA RX */
- if(HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
- {
- huart->hdmarx->XferAbortCallback = NULL;
- AbortCplt = 0x01U;
- }
- else
- {
- AbortCplt = 0x00U;
- }
- }
- }
-
- /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
- if(AbortCplt == 0x01U)
- {
- /* Reset Tx and Rx transfer counters */
- huart->TxXferCount = 0x00U;
- huart->RxXferCount = 0x00U;
-
- /* Reset ErrorCode */
- huart->ErrorCode = HAL_UART_ERROR_NONE;
-
- /* Restore huart->gState and huart->RxState to Ready */
- huart->gState = HAL_UART_STATE_READY;
- huart->RxState = HAL_UART_STATE_READY;
-
- /* As no DMA to be aborted, call directly user Abort complete callback */
- HAL_UART_AbortCpltCallback(huart);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing Transmit transfer (Interrupt mode).
- * @param huart UART handle.
- * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
- * - Set handle State to READY
- * - At abort completion, call user abort complete callback
- * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
- * considered as completed only when user abort complete callback is executed (not when exiting function).
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart)
-{
- /* Disable TXEIE and TCIE interrupts */
- CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
-
- /* Disable the UART DMA Tx request if enabled */
- if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
- {
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
-
- /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
- if(huart->hdmatx != NULL)
- {
- /* Set the UART DMA Abort callback :
- will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
- huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback;
-
- /* Abort DMA TX */
- if(HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
- {
- /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */
- huart->hdmatx->XferAbortCallback(huart->hdmatx);
- }
- }
- else
- {
- /* Reset Tx transfer counter */
- huart->TxXferCount = 0x00U;
-
- /* Restore huart->gState to Ready */
- huart->gState = HAL_UART_STATE_READY;
-
- /* As no DMA to be aborted, call directly user Abort complete callback */
- HAL_UART_AbortTransmitCpltCallback(huart);
- }
- }
- else
- {
- /* Reset Tx transfer counter */
- huart->TxXferCount = 0x00U;
-
- /* Restore huart->gState to Ready */
- huart->gState = HAL_UART_STATE_READY;
-
- /* As no DMA to be aborted, call directly user Abort complete callback */
- HAL_UART_AbortTransmitCpltCallback(huart);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing Receive transfer (Interrupt mode).
- * @param huart UART handle.
- * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
- * - Set handle State to READY
- * - At abort completion, call user abort complete callback
- * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
- * considered as completed only when user abort complete callback is executed (not when exiting function).
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart)
-{
- /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
-
- /* Disable the UART DMA Rx request if enabled */
- if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
- {
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
- if(huart->hdmarx != NULL)
- {
- /* Set the UART DMA Abort callback :
- will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
- huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback;
-
- /* Abort DMA RX */
- if(HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
- {
- /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
- huart->hdmarx->XferAbortCallback(huart->hdmarx);
- }
- }
- else
- {
- /* Reset Rx transfer counter */
- huart->RxXferCount = 0x00U;
-
- /* Restore huart->RxState to Ready */
- huart->RxState = HAL_UART_STATE_READY;
-
- /* As no DMA to be aborted, call directly user Abort complete callback */
- HAL_UART_AbortReceiveCpltCallback(huart);
- }
- }
- else
- {
- /* Reset Rx transfer counter */
- huart->RxXferCount = 0x00U;
-
- /* Restore huart->RxState to Ready */
- huart->RxState = HAL_UART_STATE_READY;
-
- /* As no DMA to be aborted, call directly user Abort complete callback */
- HAL_UART_AbortReceiveCpltCallback(huart);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief This function handles UART interrupt request.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval None
- */
-void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
-{
- uint32_t isrflags = READ_REG(huart->Instance->SR);
- uint32_t cr1its = READ_REG(huart->Instance->CR1);
- uint32_t cr3its = READ_REG(huart->Instance->CR3);
- uint32_t errorflags = 0x00U;
- uint32_t dmarequest = 0x00U;
-
- /* If no error occurs */
- errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
- if(errorflags == RESET)
- {
- /* UART in mode Receiver -------------------------------------------------*/
- if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
- {
- UART_Receive_IT(huart);
- return;
- }
- }
-
- /* If some errors occur */
- if((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
- {
- /* UART parity error interrupt occurred ----------------------------------*/
- if(((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
- {
- huart->ErrorCode |= HAL_UART_ERROR_PE;
- }
-
- /* UART noise error interrupt occurred -----------------------------------*/
- if(((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
- {
- huart->ErrorCode |= HAL_UART_ERROR_NE;
- }
-
- /* UART frame error interrupt occurred -----------------------------------*/
- if(((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
- {
- huart->ErrorCode |= HAL_UART_ERROR_FE;
- }
-
- /* UART Over-Run interrupt occurred --------------------------------------*/
- if(((isrflags & USART_SR_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
- {
- huart->ErrorCode |= HAL_UART_ERROR_ORE;
- }
-
- /* Call UART Error Call back function if need be --------------------------*/
- if(huart->ErrorCode != HAL_UART_ERROR_NONE)
- {
- /* UART in mode Receiver -----------------------------------------------*/
- if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
- {
- UART_Receive_IT(huart);
- }
-
- /* If Overrun error occurs, or if any error occurs in DMA mode reception,
- consider error as blocking */
- dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
- if(((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) || dmarequest)
- {
- /* Blocking error : transfer is aborted
- Set the UART state ready to be able to start again the process,
- Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
- UART_EndRxTransfer(huart);
-
- /* Disable the UART DMA Rx request if enabled */
- if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
- {
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the UART DMA Rx channel */
- if(huart->hdmarx != NULL)
- {
- /* Set the UART DMA Abort callback :
- will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
- huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
- if(HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
- {
- /* Call Directly XferAbortCallback function in case of error */
- huart->hdmarx->XferAbortCallback(huart->hdmarx);
- }
- }
- else
- {
- /* Call user error callback */
- HAL_UART_ErrorCallback(huart);
- }
- }
- else
- {
- /* Call user error callback */
- HAL_UART_ErrorCallback(huart);
- }
- }
- else
- {
- /* Non Blocking error : transfer could go on.
- Error is notified to user through user error callback */
- HAL_UART_ErrorCallback(huart);
- huart->ErrorCode = HAL_UART_ERROR_NONE;
- }
- }
- return;
- } /* End if some error occurs */
-
- /* UART in mode Transmitter ------------------------------------------------*/
- if(((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
- {
- UART_Transmit_IT(huart);
- return;
- }
-
- /* UART in mode Transmitter end --------------------------------------------*/
- if(((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
- {
- UART_EndTransmit_IT(huart);
- return;
- }
-}
-
-/**
- * @brief Tx Transfer completed callbacks.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval None
- */
- __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(huart);
- /* NOTE: This function Should not be modified, when the callback is needed,
- the HAL_UART_TxCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Tx Half Transfer completed callbacks.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval None
- */
- __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(huart);
- /* NOTE: This function Should not be modified, when the callback is needed,
- the HAL_UART_TxHalfCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Rx Transfer completed callbacks.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval None
- */
-__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(huart);
- /* NOTE: This function Should not be modified, when the callback is needed,
- the HAL_UART_RxCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Rx Half Transfer completed callbacks.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval None
- */
-__weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(huart);
- /* NOTE: This function Should not be modified, when the callback is needed,
- the HAL_UART_RxHalfCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief UART error callbacks.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval None
- */
- __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(huart);
- /* NOTE: This function Should not be modified, when the callback is needed,
- the HAL_UART_ErrorCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief UART Abort Complete callback.
- * @param huart UART handle.
- * @retval None
- */
-__weak void HAL_UART_AbortCpltCallback (UART_HandleTypeDef *huart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(huart);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_UART_AbortCpltCallback can be implemented in the user file.
- */
-}
-/**
- * @brief UART Abort Complete callback.
- * @param huart UART handle.
- * @retval None
- */
-__weak void HAL_UART_AbortTransmitCpltCallback (UART_HandleTypeDef *huart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(huart);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file.
- */
-}
-
-/**
- * @brief UART Abort Receive Complete callback.
- * @param huart UART handle.
- * @retval None
- */
-__weak void HAL_UART_AbortReceiveCpltCallback (UART_HandleTypeDef *huart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(huart);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file.
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
- * @brief UART control functions
- *
-@verbatim
- ==============================================================================
- ##### Peripheral Control functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to control the UART:
- (+) HAL_LIN_SendBreak() API can be helpful to transmit the break character.
- (+) HAL_MultiProcessor_EnterMuteMode() API can be helpful to enter the UART in mute mode.
- (+) HAL_MultiProcessor_ExitMuteMode() API can be helpful to exit the UART mute mode by software.
- (+) HAL_HalfDuplex_EnableTransmitter() API to enable the UART transmitter and disables the UART receiver in Half Duplex mode
- (+) HAL_HalfDuplex_EnableReceiver() API to enable the UART receiver and disables the UART transmitter in Half Duplex mode
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Transmits break characters.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
-{
- /* Check the parameters */
- assert_param(IS_UART_INSTANCE(huart->Instance));
-
- /* Process Locked */
- __HAL_LOCK(huart);
-
- huart->gState = HAL_UART_STATE_BUSY;
-
- /* Send break characters */
- SET_BIT(huart->Instance->CR1, USART_CR1_SBK);
-
- huart->gState = HAL_UART_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(huart);
-
- return HAL_OK;
-}
-
-/**
- * @brief Enters the UART in mute mode.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
-{
- /* Check the parameters */
- assert_param(IS_UART_INSTANCE(huart->Instance));
-
- /* Process Locked */
- __HAL_LOCK(huart);
-
- huart->gState = HAL_UART_STATE_BUSY;
-
- /* Enable the USART mute mode by setting the RWU bit in the CR1 register */
- SET_BIT(huart->Instance->CR1, USART_CR1_RWU);
-
- huart->gState = HAL_UART_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(huart);
-
- return HAL_OK;
-}
-
-/**
- * @brief Exits the UART mute mode: wake up software.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef *huart)
-{
- /* Check the parameters */
- assert_param(IS_UART_INSTANCE(huart->Instance));
-
- /* Process Locked */
- __HAL_LOCK(huart);
-
- huart->gState = HAL_UART_STATE_BUSY;
-
- /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */
- CLEAR_BIT(huart->Instance->CR1, USART_CR1_RWU);
-
- huart->gState = HAL_UART_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(huart);
-
- return HAL_OK;
-}
-
-/**
- * @brief Enables the UART transmitter and disables the UART receiver.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
-{
- uint32_t tmpreg = 0x00U;
-
- /* Process Locked */
- __HAL_LOCK(huart);
-
- huart->gState = HAL_UART_STATE_BUSY;
-
- /*-------------------------- USART CR1 Configuration -----------------------*/
- tmpreg = huart->Instance->CR1;
-
- /* Clear TE and RE bits */
- tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE));
-
- /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
- tmpreg |= (uint32_t)USART_CR1_TE;
-
- /* Write to USART CR1 */
- WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg);
-
- huart->gState = HAL_UART_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(huart);
-
- return HAL_OK;
-}
-
-/**
- * @brief Enables the UART receiver and disables the UART transmitter.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
-{
- uint32_t tmpreg = 0x00U;
-
- /* Process Locked */
- __HAL_LOCK(huart);
-
- huart->gState = HAL_UART_STATE_BUSY;
-
- /*-------------------------- USART CR1 Configuration -----------------------*/
- tmpreg = huart->Instance->CR1;
-
- /* Clear TE and RE bits */
- tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE));
-
- /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
- tmpreg |= (uint32_t)USART_CR1_RE;
-
- /* Write to USART CR1 */
- WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg);
-
- huart->gState = HAL_UART_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(huart);
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup UART_Exported_Functions_Group4 Peripheral State and Errors functions
- * @brief UART State and Errors functions
- *
-@verbatim
- ==============================================================================
- ##### Peripheral State and Errors functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to return the State of
- UART communication process, return Peripheral Errors occurred during communication
- process
- (+) HAL_UART_GetState() API can be helpful to check in run-time the state of the UART peripheral.
- (+) HAL_UART_GetError() check in run-time errors that could be occurred during communication.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Returns the UART state.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval HAL state
- */
-HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart)
-{
- uint32_t temp1= 0x00U, temp2 = 0x00U;
- temp1 = huart->gState;
- temp2 = huart->RxState;
-
- return (HAL_UART_StateTypeDef)(temp1 | temp2);
-}
-
-/**
- * @brief Return the UART error code
- * @param huart : pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART.
- * @retval UART Error Code
- */
-uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart)
-{
- return huart->ErrorCode;
-}
-
-/**
- * @}
- */
-
-/**
- * @brief DMA UART transmit process complete callback.
- * @param hdma: DMA handle
- * @retval None
- */
-static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
-{
- UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- /* DMA Normal mode*/
- if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
- {
- huart->TxXferCount = 0U;
-
- /* Disable the DMA transfer for transmit request by setting the DMAT bit
- in the UART CR3 register */
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
-
- /* Enable the UART Transmit Complete Interrupt */
- SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
-
- }
- /* DMA Circular mode */
- else
- {
- HAL_UART_TxCpltCallback(huart);
- }
-}
-
-/**
- * @brief DMA UART transmit process half complete callback
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
-{
- UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
-
- HAL_UART_TxHalfCpltCallback(huart);
-}
-
-/**
- * @brief DMA UART receive process complete callback.
- * @param hdma: DMA handle
- * @retval None
- */
-static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
-{
- UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- /* DMA Normal mode*/
- if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
- {
- huart->RxXferCount = 0U;
-
- /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
-
- /* Disable the DMA transfer for the receiver request by setting the DMAR bit
- in the UART CR3 register */
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
-
- /* At end of Rx process, restore huart->RxState to Ready */
- huart->RxState = HAL_UART_STATE_READY;
- }
- HAL_UART_RxCpltCallback(huart);
-}
-
-/**
- * @brief DMA UART receive process half complete callback
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
-{
- UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
- HAL_UART_RxHalfCpltCallback(huart);
-}
-
-/**
- * @brief DMA UART communication error callback.
- * @param hdma: DMA handle
- * @retval None
- */
-static void UART_DMAError(DMA_HandleTypeDef *hdma)
-{
- uint32_t dmarequest = 0x00U;
- UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- /* Stop UART DMA Tx request if ongoing */
- dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
- if((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
- {
- huart->TxXferCount = 0U;
- UART_EndTxTransfer(huart);
- }
-
- /* Stop UART DMA Rx request if ongoing */
- dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
- if((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
- {
- huart->RxXferCount = 0U;
- UART_EndRxTransfer(huart);
- }
-
- huart->ErrorCode |= HAL_UART_ERROR_DMA;
- HAL_UART_ErrorCallback(huart);
-}
-
-/**
- * @brief This function handles UART Communication Timeout.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @param Flag: specifies the UART flag to check.
- * @param Status: The new Flag status (SET or RESET).
- * @param Tickstart Tick start value
- * @param Timeout: Timeout duration
- * @retval HAL status
- */
-static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
-{
- /* Wait until flag is set */
- while((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status)
- {
- /* Check for the Timeout */
- if(Timeout != HAL_MAX_DELAY)
- {
- if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout))
- {
- /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
- CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
-
- huart->gState = HAL_UART_STATE_READY;
- huart->RxState = HAL_UART_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(huart);
-
- return HAL_TIMEOUT;
- }
- }
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion).
- * @param huart: UART handle.
- * @retval None
- */
-static void UART_EndTxTransfer(UART_HandleTypeDef *huart)
-{
- /* Disable TXEIE and TCIE interrupts */
- CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
-
- /* At end of Tx process, restore huart->gState to Ready */
- huart->gState = HAL_UART_STATE_READY;
-}
-
-/**
- * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
- * @param huart: UART handle.
- * @retval None
- */
-static void UART_EndRxTransfer(UART_HandleTypeDef *huart)
-{
- /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
-
- /* At end of Rx process, restore huart->RxState to Ready */
- huart->RxState = HAL_UART_STATE_READY;
-}
-
-/**
- * @brief DMA UART communication abort callback, when initiated by HAL services on Error
- * (To be called at end of DMA Abort procedure following error occurrence).
- * @param hdma DMA handle.
- * @retval None
- */
-static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
-{
- UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- huart->RxXferCount = 0x00U;
- huart->TxXferCount = 0x00U;
-
- HAL_UART_ErrorCallback(huart);
-}
-
-/**
- * @brief DMA UART Tx communication abort callback, when initiated by user
- * (To be called at end of DMA Tx Abort procedure following user abort request).
- * @note When this callback is executed, User Abort complete call back is called only if no
- * Abort still ongoing for Rx DMA Handle.
- * @param hdma DMA handle.
- * @retval None
- */
-static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
-{
- UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- huart->hdmatx->XferAbortCallback = NULL;
-
- /* Check if an Abort process is still ongoing */
- if(huart->hdmarx != NULL)
- {
- if(huart->hdmarx->XferAbortCallback != NULL)
- {
- return;
- }
- }
-
- /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
- huart->TxXferCount = 0x00U;
- huart->RxXferCount = 0x00U;
-
- /* Reset ErrorCode */
- huart->ErrorCode = HAL_UART_ERROR_NONE;
-
- /* Restore huart->gState and huart->RxState to Ready */
- huart->gState = HAL_UART_STATE_READY;
- huart->RxState = HAL_UART_STATE_READY;
-
- /* Call user Abort complete callback */
- HAL_UART_AbortCpltCallback(huart);
-}
-
-/**
- * @brief DMA UART Rx communication abort callback, when initiated by user
- * (To be called at end of DMA Rx Abort procedure following user abort request).
- * @note When this callback is executed, User Abort complete call back is called only if no
- * Abort still ongoing for Tx DMA Handle.
- * @param hdma DMA handle.
- * @retval None
- */
-static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
-{
- UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- huart->hdmarx->XferAbortCallback = NULL;
-
- /* Check if an Abort process is still ongoing */
- if(huart->hdmatx != NULL)
- {
- if(huart->hdmatx->XferAbortCallback != NULL)
- {
- return;
- }
- }
-
- /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
- huart->TxXferCount = 0x00U;
- huart->RxXferCount = 0x00U;
-
- /* Reset ErrorCode */
- huart->ErrorCode = HAL_UART_ERROR_NONE;
-
- /* Restore huart->gState and huart->RxState to Ready */
- huart->gState = HAL_UART_STATE_READY;
- huart->RxState = HAL_UART_STATE_READY;
-
- /* Call user Abort complete callback */
- HAL_UART_AbortCpltCallback(huart);
-}
-
-/**
- * @brief DMA UART Tx communication abort callback, when initiated by user by a call to
- * HAL_UART_AbortTransmit_IT API (Abort only Tx transfer)
- * (This callback is executed at end of DMA Tx Abort procedure following user abort request,
- * and leads to user Tx Abort Complete callback execution).
- * @param hdma DMA handle.
- * @retval None
- */
-static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
-{
- UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- huart->TxXferCount = 0x00U;
-
- /* Restore huart->gState to Ready */
- huart->gState = HAL_UART_STATE_READY;
-
- /* Call user Abort complete callback */
- HAL_UART_AbortTransmitCpltCallback(huart);
-}
-
-/**
- * @brief DMA UART Rx communication abort callback, when initiated by user by a call to
- * HAL_UART_AbortReceive_IT API (Abort only Rx transfer)
- * (This callback is executed at end of DMA Rx Abort procedure following user abort request,
- * and leads to user Rx Abort Complete callback execution).
- * @param hdma DMA handle.
- * @retval None
- */
-static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
-{
- UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- huart->RxXferCount = 0x00U;
-
- /* Restore huart->RxState to Ready */
- huart->RxState = HAL_UART_STATE_READY;
-
- /* Call user Abort complete callback */
- HAL_UART_AbortReceiveCpltCallback(huart);
-}
-
-/**
- * @brief Sends an amount of data in non blocking mode.
- * @param huart: Pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval HAL status
- */
-static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart)
-{
- uint16_t* tmp;
-
- /* Check that a Tx process is ongoing */
- if(huart->gState == HAL_UART_STATE_BUSY_TX)
- {
- if(huart->Init.WordLength == UART_WORDLENGTH_9B)
- {
- tmp = (uint16_t*) huart->pTxBuffPtr;
- huart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
- if(huart->Init.Parity == UART_PARITY_NONE)
- {
- huart->pTxBuffPtr += 2U;
- }
- else
- {
- huart->pTxBuffPtr += 1U;
- }
- }
- else
- {
- huart->Instance->DR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0x00FF);
- }
-
- if(--huart->TxXferCount == 0U)
- {
- /* Disable the UART Transmit Complete Interrupt */
- __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
-
- /* Enable the UART Transmit Complete Interrupt */
- __HAL_UART_ENABLE_IT(huart, UART_IT_TC);
- }
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Wraps up transmission in non blocking mode.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval HAL status
- */
-static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart)
-{
- /* Disable the UART Transmit Complete Interrupt */
- __HAL_UART_DISABLE_IT(huart, UART_IT_TC);
-
- /* Tx process is ended, restore huart->gState to Ready */
- huart->gState = HAL_UART_STATE_READY;
- HAL_UART_TxCpltCallback(huart);
-
- return HAL_OK;
-}
-
-/**
- * @brief Receives an amount of data in non blocking mode
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval HAL status
- */
-static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
-{
- uint16_t* tmp;
-
- /* Check that a Rx process is ongoing */
- if(huart->RxState == HAL_UART_STATE_BUSY_RX)
- {
- if(huart->Init.WordLength == UART_WORDLENGTH_9B)
- {
- tmp = (uint16_t*) huart->pRxBuffPtr;
- if(huart->Init.Parity == UART_PARITY_NONE)
- {
- *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
- huart->pRxBuffPtr += 2U;
- }
- else
- {
- *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
- huart->pRxBuffPtr += 1U;
- }
- }
- else
- {
- if(huart->Init.Parity == UART_PARITY_NONE)
- {
- *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
- }
- else
- {
- *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
- }
- }
-
- if(--huart->RxXferCount == 0U)
- {
- /* Disable the IRDA Data Register not empty Interrupt */
- __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
-
- /* Disable the UART Parity Error Interrupt */
- __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
- /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
- __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
-
- /* Rx process is completed, restore huart->RxState to Ready */
- huart->RxState = HAL_UART_STATE_READY;
-
- HAL_UART_RxCpltCallback(huart);
-
- return HAL_OK;
- }
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Configures the UART peripheral.
- * @param huart: pointer to a UART_HandleTypeDef structure that contains
- * the configuration information for the specified UART module.
- * @retval None
- */
-static void UART_SetConfig(UART_HandleTypeDef *huart)
-{
- uint32_t tmpreg = 0x00U;
-
- /* Check the parameters */
- assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
- assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
- assert_param(IS_UART_PARITY(huart->Init.Parity));
- assert_param(IS_UART_MODE(huart->Init.Mode));
-
- /*------- UART-associated USART registers setting : CR2 Configuration ------*/
- /* Configure the UART Stop Bits: Set STOP[13:12] bits according
- * to huart->Init.StopBits value */
- MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
-
- /*------- UART-associated USART registers setting : CR1 Configuration ------*/
- /* Configure the UART Word Length, Parity and mode:
- Set the M bits according to huart->Init.WordLength value
- Set PCE and PS bits according to huart->Init.Parity value
- Set TE and RE bits according to huart->Init.Mode value
- Set OVER8 bit according to huart->Init.OverSampling value */
-
-#if defined(USART_CR1_OVER8)
- tmpreg |= (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling;
- MODIFY_REG(huart->Instance->CR1,
- (uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8),
- tmpreg);
-#else
- tmpreg |= (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode;
- MODIFY_REG(huart->Instance->CR1,
- (uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE),
- tmpreg);
-#endif /* USART_CR1_OVER8 */
-
- /*------- UART-associated USART registers setting : CR3 Configuration ------*/
- /* Configure the UART HFC: Set CTSE and RTSE bits according to huart->Init.HwFlowCtl value */
- MODIFY_REG(huart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE), huart->Init.HwFlowCtl);
-
-#if defined(USART_CR1_OVER8)
- /* Check the Over Sampling */
- if(huart->Init.OverSampling == UART_OVERSAMPLING_8)
- {
- /*-------------------------- USART BRR Configuration ---------------------*/
- if(huart->Instance == USART1)
- {
- huart->Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate);
- }
- else
- {
- huart->Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate);
- }
- }
- else
- {
- /*-------------------------- USART BRR Configuration ---------------------*/
- if(huart->Instance == USART1)
- {
- huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate);
- }
- else
- {
- huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate);
- }
- }
-#else
- /*-------------------------- USART BRR Configuration ---------------------*/
- if(huart->Instance == USART1)
- {
- huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate);
- }
- else
- {
- huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate);
- }
-#endif /* USART_CR1_OVER8 */
-}
-
-/**
- * @}
- */
-
-#endif /* HAL_UART_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_usart.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_usart.c
deleted file mode 100644
index 268a4c7..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_usart.c
+++ /dev/null
@@ -1,2308 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_usart.c
- * @author MCD Application Team
- * @brief USART HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Universal Synchronous Asynchronous Receiver Transmitter (USART) peripheral:
- * + Initialization and de-initialization functions
- * + IO operation functions
- * + Peripheral Control functions
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- The USART HAL driver can be used as follows:
-
- (#) Declare a USART_HandleTypeDef handle structure.
- (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit () API:
- (##) Enable the USARTx interface clock.
- (##) USART pins configuration:
- (+++) Enable the clock for the USART GPIOs.
- (+++) Configure the USART pins (TX as alternate function pull-up, RX as alternate function Input).
- (##) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
- HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
- (+++) Configure the USARTx interrupt priority.
- (+++) Enable the NVIC USART IRQ handle.
- (##) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
- HAL_USART_Receive_DMA() and HAL_USART_TransmitReceive_DMA() APIs):
- (+++) Declare a DMA handle structure for the Tx/Rx channel.
- (+++) Enable the DMAx interface clock.
- (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
- (+++) Configure the DMA Tx/Rx channel.
- (+++) Associate the initialized DMA handle to the USART DMA Tx/Rx handle.
- (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
- (+++) Configure the priority and enable the NVIC for the transfer complete
- interrupt on the DMA Tx/Rx channel.
- (+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
- (used for last byte sending completion detection in DMA non circular mode)
-
- (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
- flow control and Mode(Receiver/Transmitter) in the husart Init structure.
-
- (#) Initialize the USART registers by calling the HAL_USART_Init() API:
- (++) These APIs configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
- by calling the customized HAL_USART_MspInit(&husart) API.
-
- -@@- The specific USART interrupts (Transmission complete interrupt,
- RXNE interrupt and Error Interrupts) will be managed using the macros
- __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
-
- (#) Three operation modes are available within this driver :
-
- *** Polling mode IO operation ***
- =================================
- [..]
- (+) Send an amount of data in blocking mode using HAL_USART_Transmit()
- (+) Receive an amount of data in blocking mode using HAL_USART_Receive()
-
- *** Interrupt mode IO operation ***
- ===================================
- [..]
- (+) Send an amount of data in non blocking mode using HAL_USART_Transmit_IT()
- (+) At transmission end of transfer HAL_USART_TxHalfCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_USART_TxCpltCallback
- (+) Receive an amount of data in non blocking mode using HAL_USART_Receive_IT()
- (+) At reception end of transfer HAL_USART_RxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_USART_RxCpltCallback
- (+) In case of transfer Error, HAL_USART_ErrorCallback() function is executed and user can
- add his own code by customization of function pointer HAL_USART_ErrorCallback
-
- *** DMA mode IO operation ***
- ==============================
- [..]
- (+) Send an amount of data in non blocking mode (DMA) using HAL_USART_Transmit_DMA()
- (+) At transmission end of half transfer HAL_USART_TxHalfCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_USART_TxHalfCpltCallback
- (+) At transmission end of transfer HAL_USART_TxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_USART_TxCpltCallback
- (+) Receive an amount of data in non blocking mode (DMA) using HAL_USART_Receive_DMA()
- (+) At reception end of half transfer HAL_USART_RxHalfCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_USART_RxHalfCpltCallback
- (+) At reception end of transfer HAL_USART_RxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_USART_RxCpltCallback
- (+) In case of transfer Error, HAL_USART_ErrorCallback() function is executed and user can
- add his own code by customization of function pointer HAL_USART_ErrorCallback
- (+) Pause the DMA Transfer using HAL_USART_DMAPause()
- (+) Resume the DMA Transfer using HAL_USART_DMAResume()
- (+) Stop the DMA Transfer using HAL_USART_DMAStop()
-
- *** USART HAL driver macros list ***
- =============================================
- [..]
- Below the list of most used macros in USART HAL driver.
-
- (+) __HAL_USART_ENABLE: Enable the USART peripheral
- (+) __HAL_USART_DISABLE: Disable the USART peripheral
- (+) __HAL_USART_GET_FLAG : Check whether the specified USART flag is set or not
- (+) __HAL_USART_CLEAR_FLAG : Clear the specified USART pending flag
- (+) __HAL_USART_ENABLE_IT: Enable the specified USART interrupt
- (+) __HAL_USART_DISABLE_IT: Disable the specified USART interrupt
-
- [..]
- (@) You can refer to the USART HAL driver header file for more useful macros
-
- @endverbatim
- [..]
- (@) Additionnal remark: If the parity is enabled, then the MSB bit of the data written
- in the data register is transmitted but is changed by the parity bit.
- Depending on the frame length defined by the M bit (8-bits or 9-bits),
- the possible USART frame formats are as listed in the following table:
- +-------------------------------------------------------------+
- | M bit | PCE bit | USART frame |
- |---------------------|---------------------------------------|
- | 0 | 0 | | SB | 8 bit data | STB | |
- |---------|-----------|---------------------------------------|
- | 0 | 1 | | SB | 7 bit data | PB | STB | |
- |---------|-----------|---------------------------------------|
- | 1 | 0 | | SB | 9 bit data | STB | |
- |---------|-----------|---------------------------------------|
- | 1 | 1 | | SB | 8 bit data | PB | STB | |
- +-------------------------------------------------------------+
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup USART USART
- * @brief HAL USART Synchronous module driver
- * @{
- */
-#ifdef HAL_USART_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @addtogroup USART_Private_Constants
- * @{
- */
-#define DUMMY_DATA 0xFFFFU
-#define USART_TIMEOUT_VALUE 22000U
-/**
- * @}
- */
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
-/** @addtogroup USART_Private_Functions
- * @{
- */
-static void USART_EndTxTransfer(USART_HandleTypeDef *husart);
-static void USART_EndRxTransfer(USART_HandleTypeDef *husart);
-static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart);
-static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart);
-static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart);
-static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart);
-static void USART_SetConfig (USART_HandleTypeDef *husart);
-static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
-static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
-static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
-static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
-static void USART_DMAError(DMA_HandleTypeDef *hdma);
-static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
-static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
-static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
-
-static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout);
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup USART_Exported_Functions USART Exported Functions
- * @{
- */
-
-/** @defgroup USART_Exported_Functions_Group1 USART Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
- ==============================================================================
- ##### Initialization and Configuration functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to initialize the USART
- in asynchronous and in synchronous modes.
- (+) For the asynchronous mode only these parameters can be configured:
- (++) Baud Rate
- (++) Word Length
- (++) Stop Bit
- (++) Parity: If the parity is enabled, then the MSB bit of the data written
- in the data register is transmitted but is changed by the parity bit.
- Depending on the frame length defined by the M bit (8-bits or 9-bits),
- please refer to Reference manual for possible USART frame formats.
- (++) USART polarity
- (++) USART phase
- (++) USART LastBit
- (++) Receiver/transmitter modes
-
- [..]
- The HAL_USART_Init() function follows the USART synchronous configuration
- procedure (details for the procedure are available in reference manuals
- (RM0008 for STM32F10Xxx MCUs and RM0041 for STM32F100xx MCUs)).
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the USART mode according to the specified
- * parameters in the USART_InitTypeDef and create the associated handle.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
-{
- /* Check the USART handle allocation */
- if(husart == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_USART_INSTANCE(husart->Instance));
-
- if(husart->State == HAL_USART_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- husart->Lock = HAL_UNLOCKED;
-
- /* Init the low level hardware */
- HAL_USART_MspInit(husart);
- }
-
- husart->State = HAL_USART_STATE_BUSY;
-
- /* Set the USART Communication parameters */
- USART_SetConfig(husart);
-
- /* In USART mode, the following bits must be kept cleared:
- - LINEN bit in the USART_CR2 register
- - HDSEL, SCEN and IREN bits in the USART_CR3 register */
- CLEAR_BIT(husart->Instance->CR2, USART_CR2_LINEN);
- CLEAR_BIT(husart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
-
- /* Enable the Peripheral */
- __HAL_USART_ENABLE(husart);
-
- /* Initialize the USART state */
- husart->ErrorCode = HAL_USART_ERROR_NONE;
- husart->State= HAL_USART_STATE_READY;
-
- return HAL_OK;
-}
-
-/**
- * @brief DeInitializes the USART peripheral.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
-{
- /* Check the USART handle allocation */
- if(husart == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_USART_INSTANCE(husart->Instance));
-
- husart->State = HAL_USART_STATE_BUSY;
-
- /* DeInit the low level hardware */
- HAL_USART_MspDeInit(husart);
-
- husart->ErrorCode = HAL_USART_ERROR_NONE;
- husart->State = HAL_USART_STATE_RESET;
-
- /* Release Lock */
- __HAL_UNLOCK(husart);
-
- return HAL_OK;
-}
-
-/**
- * @brief USART MSP Init.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval None
- */
-__weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(husart);
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_USART_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief USART MSP DeInit.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval None
- */
-__weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(husart);
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_USART_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup USART_Exported_Functions_Group2 IO operation functions
- * @brief USART Transmit and Receive functions
- *
-@verbatim
- ==============================================================================
- ##### IO operation functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to manage the USART synchronous
- data transfers.
-
- [..]
- The USART supports master mode only: it cannot receive or send data related to an input
- clock (SCLK is always an output).
-
- (#) There are two modes of transfer:
- (++) Blocking mode: The communication is performed in polling mode.
- The HAL status of all data processing is returned by the same function
- after finishing transfer.
- (++) No-Blocking mode: The communication is performed using Interrupts
- or DMA, These API's return the HAL status.
- The end of the data processing will be indicated through the
- dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
- using DMA mode.
- The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback()
- user callbacks
- will be executed respectively at the end of the transmit or Receive process
- The HAL_USART_ErrorCallback() user callback will be executed when a communication
- error is detected
-
- (#) Blocking mode APIs are :
- (++) HAL_USART_Transmit() in simplex mode
- (++) HAL_USART_Receive() in full duplex receive only
- (++) HAL_USART_TransmitReceive() in full duplex mode
-
- (#) Non Blocking mode APIs with Interrupt are :
- (++) HAL_USART_Transmit_IT()in simplex mode
- (++) HAL_USART_Receive_IT() in full duplex receive only
- (++) HAL_USART_TransmitReceive_IT() in full duplex mode
- (++) HAL_USART_IRQHandler()
-
- (#) Non Blocking mode functions with DMA are :
- (++) HAL_USART_Transmit_DMA()in simplex mode
- (++) HAL_USART_Receive_DMA() in full duplex receive only
- (++) HAL_USART_TransmitReceive_DMA() in full duplex mode
- (++) HAL_USART_DMAPause()
- (++) HAL_USART_DMAResume()
- (++) HAL_USART_DMAStop()
-
- (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
- (++) HAL_USART_TxHalfCpltCallback()
- (++) HAL_USART_TxCpltCallback()
- (++) HAL_USART_RxHalfCpltCallback()
- (++) HAL_USART_RxCpltCallback()
- (++) HAL_USART_ErrorCallback()
- (++) HAL_USART_TxRxCpltCallback()
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Simplex Send an amount of data in blocking mode.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @param pTxData: Pointer to data buffer
- * @param Size: Amount of data to be sent
- * @param Timeout: Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout)
-{
- uint16_t* tmp;
- uint32_t tickstart = 0U;
-
- if(husart->State == HAL_USART_STATE_READY)
- {
- if((pTxData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(husart);
-
- husart->ErrorCode = HAL_USART_ERROR_NONE;
- husart->State = HAL_USART_STATE_BUSY_TX;
-
- /* Init tickstart for timeout managment */
- tickstart = HAL_GetTick();
-
- husart->TxXferSize = Size;
- husart->TxXferCount = Size;
- while(husart->TxXferCount > 0U)
- {
- husart->TxXferCount--;
- if(husart->Init.WordLength == USART_WORDLENGTH_9B)
- {
- /* Wait for TC flag in order to write data in DR */
- if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- tmp = (uint16_t*) pTxData;
- WRITE_REG(husart->Instance->DR, (*tmp & (uint16_t)0x01FF));
- if(husart->Init.Parity == USART_PARITY_NONE)
- {
- pTxData += 2U;
- }
- else
- {
- pTxData += 1U;
- }
- }
- else
- {
- if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- WRITE_REG(husart->Instance->DR, (*pTxData++ & (uint8_t)0xFF));
- }
- }
-
- if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
-
- husart->State = HAL_USART_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(husart);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Full-Duplex Receive an amount of data in blocking mode.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @param pRxData: Pointer to data buffer
- * @param Size: Amount of data to be received
- * @param Timeout: Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
-{
- uint16_t* tmp;
- uint32_t tickstart = 0U;
-
- if(husart->State == HAL_USART_STATE_READY)
- {
- if((pRxData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
- /* Process Locked */
- __HAL_LOCK(husart);
-
- husart->ErrorCode = HAL_USART_ERROR_NONE;
- husart->State = HAL_USART_STATE_BUSY_RX;
-
- /* Init tickstart for timeout managment */
- tickstart = HAL_GetTick();
-
- husart->RxXferSize = Size;
- husart->RxXferCount = Size;
- /* Check the remain data to be received */
- while(husart->RxXferCount > 0U)
- {
- husart->RxXferCount--;
- if(husart->Init.WordLength == USART_WORDLENGTH_9B)
- {
- /* Wait until TXE flag is set to send dummy byte in order to generate the clock for the slave to send data */
- if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- /* Send dummy byte in order to generate clock */
- WRITE_REG(husart->Instance->DR, (DUMMY_DATA & (uint16_t)0x01FF));
-
- /* Wait for RXNE Flag */
- if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- tmp = (uint16_t*) pRxData ;
- if(husart->Init.Parity == USART_PARITY_NONE)
- {
- *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
- pRxData +=2U;
- }
- else
- {
- *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
- pRxData +=1U;
- }
- }
- else
- {
- /* Wait until TXE flag is set to send dummy byte in order to generate the clock for the slave to send data */
- if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
-
- /* Send Dummy Byte in order to generate clock */
- WRITE_REG(husart->Instance->DR, (DUMMY_DATA & (uint16_t)0x00FF));
-
- /* Wait until RXNE flag is set to receive the byte */
- if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- if(husart->Init.Parity == USART_PARITY_NONE)
- {
- /* Receive data */
- *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
- }
- else
- {
- /* Receive data */
- *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
- }
-
- }
- }
-
- husart->State = HAL_USART_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(husart);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Full-Duplex Send receive an amount of data in full-duplex mode (blocking mode).
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @param pTxData: Pointer to data transmitted buffer
- * @param pRxData: Pointer to data received buffer
- * @param Size: Amount of data to be sent
- * @param Timeout: Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
-{
- uint16_t* tmp;
- uint32_t tickstart = 0U;
-
- if(husart->State == HAL_USART_STATE_READY)
- {
- if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
- /* Process Locked */
- __HAL_LOCK(husart);
-
- husart->ErrorCode = HAL_USART_ERROR_NONE;
- husart->State = HAL_USART_STATE_BUSY_RX;
-
- /* Init tickstart for timeout managment */
- tickstart = HAL_GetTick();
-
- husart->RxXferSize = Size;
- husart->TxXferSize = Size;
- husart->TxXferCount = Size;
- husart->RxXferCount = Size;
-
- /* Check the remain data to be received */
- while(husart->TxXferCount > 0U)
- {
- husart->TxXferCount--;
- husart->RxXferCount--;
- if(husart->Init.WordLength == USART_WORDLENGTH_9B)
- {
- /* Wait for TC flag in order to write data in DR */
- if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- tmp = (uint16_t*) pTxData;
- WRITE_REG(husart->Instance->DR, (*tmp & (uint16_t)0x01FF));
- if(husart->Init.Parity == USART_PARITY_NONE)
- {
- pTxData += 2U;
- }
- else
- {
- pTxData += 1U;
- }
-
- /* Wait for RXNE Flag */
- if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- tmp = (uint16_t*) pRxData ;
- if(husart->Init.Parity == USART_PARITY_NONE)
- {
- *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
- pRxData += 2U;
- }
- else
- {
- *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
- pRxData += 1U;
- }
- }
- else
- {
- /* Wait for TC flag in order to write data in DR */
- if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- WRITE_REG(husart->Instance->DR, (*pTxData++ & (uint8_t)0x00FF));
-
- /* Wait for RXNE Flag */
- if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
- if(husart->Init.Parity == USART_PARITY_NONE)
- {
- /* Receive data */
- *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
- }
- else
- {
- /* Receive data */
- *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
- }
- }
- }
-
- husart->State = HAL_USART_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(husart);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Simplex Send an amount of data in non-blocking mode.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @param pTxData: Pointer to data buffer
- * @param Size: Amount of data to be sent
- * @retval HAL status
- * @note The USART errors are not managed to avoid the overrun error.
- */
-HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
-{
- /* Check that a Tx process is not already ongoing */
- if(husart->State == HAL_USART_STATE_READY)
- {
- if((pTxData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
- /* Process Locked */
- __HAL_LOCK(husart);
-
- husart->pTxBuffPtr = pTxData;
- husart->TxXferSize = Size;
- husart->TxXferCount = Size;
-
- husart->ErrorCode = HAL_USART_ERROR_NONE;
- husart->State = HAL_USART_STATE_BUSY_TX;
-
- /* The USART Error Interrupts: (Frame error, Noise error, Overrun error)
- are not managed by the USART transmit process to avoid the overrun interrupt
- when the USART mode is configured for transmit and receive "USART_MODE_TX_RX"
- to benefit for the frame error and noise interrupts the USART mode should be
- configured only for transmit "USART_MODE_TX"
- The __HAL_USART_ENABLE_IT(husart, USART_IT_ERR) can be used to enable the Frame error,
- Noise error interrupt */
-
- /* Process Unlocked */
- __HAL_UNLOCK(husart);
-
- /* Enable the USART Transmit Data Register Empty Interrupt */
- __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Simplex Receive an amount of data in non-blocking mode.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @param pRxData: Pointer to data buffer
- * @param Size: Amount of data to be received
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
-{
- if(husart->State == HAL_USART_STATE_READY)
- {
- if((pRxData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
- /* Process Locked */
- __HAL_LOCK(husart);
-
- husart->pRxBuffPtr = pRxData;
- husart->RxXferSize = Size;
- husart->RxXferCount = Size;
-
- husart->ErrorCode = HAL_USART_ERROR_NONE;
- husart->State = HAL_USART_STATE_BUSY_RX;
-
- /* Process Unlocked */
- __HAL_UNLOCK(husart);
-
- /* Enable the USART Data Register not empty Interrupt */
- __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE);
-
- /* Enable the USART Parity Error Interrupt */
- __HAL_USART_ENABLE_IT(husart, USART_IT_PE);
-
- /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
- __HAL_USART_ENABLE_IT(husart, USART_IT_ERR);
-
- /* Send dummy byte in order to generate the clock for the slave to send data */
- WRITE_REG(husart->Instance->DR, (DUMMY_DATA & (uint16_t)0x01FF));
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @param pTxData: Pointer to data transmitted buffer
- * @param pRxData: Pointer to data received buffer
- * @param Size: Amount of data to be received
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
-{
- if(husart->State == HAL_USART_STATE_READY)
- {
- if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
- /* Process Locked */
- __HAL_LOCK(husart);
-
- husart->pRxBuffPtr = pRxData;
- husart->RxXferSize = Size;
- husart->RxXferCount = Size;
- husart->pTxBuffPtr = pTxData;
- husart->TxXferSize = Size;
- husart->TxXferCount = Size;
-
- husart->ErrorCode = HAL_USART_ERROR_NONE;
- husart->State = HAL_USART_STATE_BUSY_TX_RX;
-
- /* Process Unlocked */
- __HAL_UNLOCK(husart);
-
- /* Enable the USART Data Register not empty Interrupt */
- __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE);
-
- /* Enable the USART Parity Error Interrupt */
- __HAL_USART_ENABLE_IT(husart, USART_IT_PE);
-
- /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
- __HAL_USART_ENABLE_IT(husart, USART_IT_ERR);
-
- /* Enable the USART Transmit Data Register Empty Interrupt */
- __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Simplex Send an amount of data in non-blocking mode.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @param pTxData: Pointer to data buffer
- * @param Size: Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
-{
- uint32_t *tmp;
-
- if(husart->State == HAL_USART_STATE_READY)
- {
- if((pTxData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
- /* Process Locked */
- __HAL_LOCK(husart);
-
- husart->pTxBuffPtr = pTxData;
- husart->TxXferSize = Size;
- husart->TxXferCount = Size;
-
- husart->ErrorCode = HAL_USART_ERROR_NONE;
- husart->State = HAL_USART_STATE_BUSY_TX;
-
- /* Set the USART DMA transfer complete callback */
- husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
-
- /* Set the USART DMA Half transfer complete callback */
- husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
-
- /* Set the DMA error callback */
- husart->hdmatx->XferErrorCallback = USART_DMAError;
-
- /* Set the DMA abort callback */
- husart->hdmatx->XferAbortCallback = NULL;
-
- /* Enable the USART transmit DMA channel */
- tmp = (uint32_t*)&pTxData;
- HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->DR, Size);
-
- /* Clear the TC flag in the SR register by writing 0 to it */
- __HAL_USART_CLEAR_FLAG(husart, USART_FLAG_TC);
-
- /* Process Unlocked */
- __HAL_UNLOCK(husart);
-
- /* Enable the DMA transfer for transmit request by setting the DMAT bit
- in the USART CR3 register */
- SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Full-Duplex Receive an amount of data in non-blocking mode.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @param pRxData: Pointer to data buffer
- * @param Size: Amount of data to be received
- * @retval HAL status
- * @note The USART DMA transmit channel must be configured in order to generate the clock for the slave.
- * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
- */
-HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
-{
- uint32_t *tmp;
-
- if(husart->State == HAL_USART_STATE_READY)
- {
- if((pRxData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(husart);
-
- husart->pRxBuffPtr = pRxData;
- husart->RxXferSize = Size;
- husart->pTxBuffPtr = pRxData;
- husart->TxXferSize = Size;
-
- husart->ErrorCode = HAL_USART_ERROR_NONE;
- husart->State = HAL_USART_STATE_BUSY_RX;
-
- /* Set the USART DMA Rx transfer complete callback */
- husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
-
- /* Set the USART DMA Half transfer complete callback */
- husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
-
- /* Set the USART DMA Rx transfer error callback */
- husart->hdmarx->XferErrorCallback = USART_DMAError;
-
- /* Set the DMA abort callback */
- husart->hdmarx->XferAbortCallback = NULL;
-
- /* Set the USART Tx DMA transfer complete callback as NULL because the communication closing
- is performed in DMA reception complete callback */
- husart->hdmatx->XferHalfCpltCallback = NULL;
- husart->hdmatx->XferCpltCallback = NULL;
-
- /* Set the DMA error callback */
- husart->hdmatx->XferErrorCallback = USART_DMAError;
-
- /* Set the DMA AbortCpltCallback */
- husart->hdmatx->XferAbortCallback = NULL;
-
- /* Enable the USART receive DMA channel */
- tmp = (uint32_t*)&pRxData;
- HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->DR, *(uint32_t*)tmp, Size);
-
- /* Enable the USART transmit DMA channel: the transmit channel is used in order
- to generate in the non-blocking mode the clock to the slave device,
- this mode isn't a simplex receive mode but a full-duplex receive one */
- HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->DR, Size);
-
- /* Clear the Overrun flag just before enabling the DMA Rx request: mandatory for the second transfer */
- __HAL_USART_CLEAR_OREFLAG(husart);
-
- /* Process Unlocked */
- __HAL_UNLOCK(husart);
-
- /* Enable the USART Parity Error Interrupt */
- SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
-
- /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
- SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
-
- /* Enable the DMA transfer for the receiver request by setting the DMAR bit
- in the USART CR3 register */
- SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
-
- /* Enable the DMA transfer for transmit request by setting the DMAT bit
- in the USART CR3 register */
- SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Full-Duplex Transmit Receive an amount of data in non-blocking mode.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @param pTxData: Pointer to data transmitted buffer
- * @param pRxData: Pointer to data received buffer
- * @param Size: Amount of data to be received
- * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
-{
- uint32_t *tmp;
-
- if(husart->State == HAL_USART_STATE_READY)
- {
- if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
- {
- return HAL_ERROR;
- }
- /* Process Locked */
- __HAL_LOCK(husart);
-
- husart->pRxBuffPtr = pRxData;
- husart->RxXferSize = Size;
- husart->pTxBuffPtr = pTxData;
- husart->TxXferSize = Size;
-
- husart->ErrorCode = HAL_USART_ERROR_NONE;
- husart->State = HAL_USART_STATE_BUSY_TX_RX;
-
- /* Set the USART DMA Rx transfer complete callback */
- husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
-
- /* Set the USART DMA Half transfer complete callback */
- husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
-
- /* Set the USART DMA Tx transfer complete callback */
- husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
-
- /* Set the USART DMA Half transfer complete callback */
- husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
-
- /* Set the USART DMA Tx transfer error callback */
- husart->hdmatx->XferErrorCallback = USART_DMAError;
-
- /* Set the USART DMA Rx transfer error callback */
- husart->hdmarx->XferErrorCallback = USART_DMAError;
-
- /* Set the DMA abort callback */
- husart->hdmarx->XferAbortCallback = NULL;
-
- /* Enable the USART receive DMA channel */
- tmp = (uint32_t*)&pRxData;
- HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->DR, *(uint32_t*)tmp, Size);
-
- /* Enable the USART transmit DMA channel */
- tmp = (uint32_t*)&pTxData;
- HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->DR, Size);
-
- /* Clear the TC flag in the SR register by writing 0 to it */
- __HAL_USART_CLEAR_FLAG(husart, USART_FLAG_TC);
-
- /* Clear the Overrun flag: mandatory for the second transfer in circular mode */
- __HAL_USART_CLEAR_OREFLAG(husart);
-
- /* Process Unlocked */
- __HAL_UNLOCK(husart);
-
- /* Enable the USART Parity Error Interrupt */
- SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
-
- /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
- SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
-
- /* Enable the DMA transfer for the receiver request by setting the DMAR bit
- in the USART CR3 register */
- SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
-
- /* Enable the DMA transfer for transmit request by setting the DMAT bit
- in the USART CR3 register */
- SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Pauses the DMA Transfer.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
-{
- /* Process Locked */
- __HAL_LOCK(husart);
-
- /* Disable the USART DMA Tx request */
- CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
-
- /* Process Unlocked */
- __HAL_UNLOCK(husart);
-
- return HAL_OK;
-}
-
-/**
- * @brief Resumes the DMA Transfer.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
-{
- /* Process Locked */
- __HAL_LOCK(husart);
-
- /* Enable the USART DMA Tx request */
- SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
-
- /* Process Unlocked */
- __HAL_UNLOCK(husart);
-
- return HAL_OK;
-}
-
-/**
- * @brief Stops the DMA Transfer.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
-{
- uint32_t dmarequest = 0x00U;
- /* The Lock is not implemented on this API to allow the user application
- to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback():
- when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
- and the correspond call back is executed HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback()
- */
-
- /* Stop USART DMA Tx request if ongoing */
- dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT);
- if((husart->State == HAL_USART_STATE_BUSY_TX) && dmarequest)
- {
- USART_EndTxTransfer(husart);
-
- /* Abort the USART DMA Tx channel */
- if(husart->hdmatx != NULL)
- {
- HAL_DMA_Abort(husart->hdmatx);
- }
-
- /* Disable the USART Tx DMA request */
- CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
- }
-
- /* Stop USART DMA Rx request if ongoing */
- dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR);
- if((husart->State == HAL_USART_STATE_BUSY_RX) && dmarequest)
- {
- USART_EndRxTransfer(husart);
-
- /* Abort the USART DMA Rx channel */
- if(husart->hdmarx != NULL)
- {
- HAL_DMA_Abort(husart->hdmarx);
- }
-
- /* Disable the USART Rx DMA request */
- CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing transfer (blocking mode).
- * @param husart USART handle.
- * @note This procedure could be used for aborting any ongoing transfer (either Tx or Rx,
- * as described by TransferType parameter) started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts (depending of transfer direction)
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
- * - Set handle State to READY
- * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_USART_Abort(USART_HandleTypeDef *husart)
-{
- /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
- CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
-
- /* Disable the USART DMA Tx request if enabled */
- if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
- {
- CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
-
- /* Abort the USART DMA Tx channel : use blocking DMA Abort API (no callback) */
- if(husart->hdmatx != NULL)
- {
- /* Set the USART DMA Abort callback to Null.
- No call back execution at end of DMA abort procedure */
- husart->hdmatx->XferAbortCallback = NULL;
-
- HAL_DMA_Abort(husart->hdmatx);
- }
- }
-
- /* Disable the USART DMA Rx request if enabled */
- if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
- {
- CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the USART DMA Rx channel : use blocking DMA Abort API (no callback) */
- if(husart->hdmarx != NULL)
- {
- /* Set the USART DMA Abort callback to Null.
- No call back execution at end of DMA abort procedure */
- husart->hdmarx->XferAbortCallback = NULL;
-
- HAL_DMA_Abort(husart->hdmarx);
- }
- }
-
- /* Reset Tx and Rx transfer counters */
- husart->TxXferCount = 0x00U;
- husart->RxXferCount = 0x00U;
-
- /* Restore husart->State to Ready */
- husart->State = HAL_USART_STATE_READY;
-
- /* Reset Handle ErrorCode to No Error */
- husart->ErrorCode = HAL_USART_ERROR_NONE;
-
- return HAL_OK;
-}
-
-/**
- * @brief Abort ongoing transfer (Interrupt mode).
- * @param husart USART handle.
- * @note This procedure could be used for aborting any ongoing transfer (either Tx or Rx,
- * as described by TransferType parameter) started in Interrupt or DMA mode.
- * This procedure performs following operations :
- * - Disable PPP Interrupts (depending of transfer direction)
- * - Disable the DMA transfer in the peripheral register (if enabled)
- * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
- * - Set handle State to READY
- * - At abort completion, call user abort complete callback
- * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
- * considered as completed only when user abort complete callback is executed (not when exiting function).
- * @retval HAL status
-*/
-HAL_StatusTypeDef HAL_USART_Abort_IT(USART_HandleTypeDef *husart)
-{
- uint32_t AbortCplt = 0x01U;
-
- /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
- CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
-
- /* If DMA Tx and/or DMA Rx Handles are associated to USART Handle, DMA Abort complete callbacks should be initialised
- before any call to DMA Abort functions */
- /* DMA Tx Handle is valid */
- if(husart->hdmatx != NULL)
- {
- /* Set DMA Abort Complete callback if USART DMA Tx request if enabled.
- Otherwise, set it to NULL */
- if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
- {
- husart->hdmatx->XferAbortCallback = USART_DMATxAbortCallback;
- }
- else
- {
- husart->hdmatx->XferAbortCallback = NULL;
- }
- }
- /* DMA Rx Handle is valid */
- if(husart->hdmarx != NULL)
- {
- /* Set DMA Abort Complete callback if USART DMA Rx request if enabled.
- Otherwise, set it to NULL */
- if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
- {
- husart->hdmarx->XferAbortCallback = USART_DMARxAbortCallback;
- }
- else
- {
- husart->hdmarx->XferAbortCallback = NULL;
- }
- }
-
- /* Disable the USART DMA Tx request if enabled */
- if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
- {
- /* Disable DMA Tx at USART level */
- CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
-
- /* Abort the USART DMA Tx channel : use non blocking DMA Abort API (callback) */
- if(husart->hdmatx != NULL)
- {
- /* USART Tx DMA Abort callback has already been initialised :
- will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
-
- /* Abort DMA TX */
- if(HAL_DMA_Abort_IT(husart->hdmatx) != HAL_OK)
- {
- husart->hdmatx->XferAbortCallback = NULL;
- }
- else
- {
- AbortCplt = 0x00U;
- }
- }
- }
-
- /* Disable the USART DMA Rx request if enabled */
- if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
- {
- CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the USART DMA Rx channel : use non blocking DMA Abort API (callback) */
- if(husart->hdmarx != NULL)
- {
- /* USART Rx DMA Abort callback has already been initialised :
- will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
-
- /* Abort DMA RX */
- if(HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
- {
- husart->hdmarx->XferAbortCallback = NULL;
- AbortCplt = 0x01U;
- }
- else
- {
- AbortCplt = 0x00U;
- }
- }
- }
-
- /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
- if(AbortCplt == 0x01U)
- {
- /* Reset Tx and Rx transfer counters */
- husart->TxXferCount = 0x00U;
- husart->RxXferCount = 0x00U;
-
- /* Reset errorCode */
- husart->ErrorCode = HAL_USART_ERROR_NONE;
-
- /* Restore husart->State to Ready */
- husart->State = HAL_USART_STATE_READY;
-
- /* As no DMA to be aborted, call directly user Abort complete callback */
- HAL_USART_AbortCpltCallback(husart);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief This function handles USART interrupt request.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval None
- */
-void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
-{
- uint32_t isrflags = READ_REG(husart->Instance->SR);
- uint32_t cr1its = READ_REG(husart->Instance->CR1);
- uint32_t cr3its = READ_REG(husart->Instance->CR3);
- uint32_t errorflags = 0x00U;
- uint32_t dmarequest = 0x00U;
-
- /* If no error occurs */
- errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
- if(errorflags == RESET)
- {
- /* USART in mode Receiver -------------------------------------------------*/
- if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
- {
- if(husart->State == HAL_USART_STATE_BUSY_RX)
- {
- USART_Receive_IT(husart);
- }
- else
- {
- USART_TransmitReceive_IT(husart);
- }
- return;
- }
- }
- /* If some errors occur */
- if((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
- {
- /* USART parity error interrupt occurred ----------------------------------*/
- if(((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
- {
- husart->ErrorCode |= HAL_USART_ERROR_PE;
- }
-
- /* USART noise error interrupt occurred --------------------------------*/
- if(((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
- {
- husart->ErrorCode |= HAL_USART_ERROR_NE;
- }
-
- /* USART frame error interrupt occurred --------------------------------*/
- if(((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
- {
- husart->ErrorCode |= HAL_USART_ERROR_FE;
- }
-
- /* USART Over-Run interrupt occurred -----------------------------------*/
- if(((isrflags & USART_SR_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
- {
- husart->ErrorCode |= HAL_USART_ERROR_ORE;
- }
-
- if(husart->ErrorCode != HAL_USART_ERROR_NONE)
- {
- /* USART in mode Receiver -----------------------------------------------*/
- if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
- {
- if(husart->State == HAL_USART_STATE_BUSY_RX)
- {
- USART_Receive_IT(husart);
- }
- else
- {
- USART_TransmitReceive_IT(husart);
- }
- }
- /* If Overrun error occurs, or if any error occurs in DMA mode reception,
- consider error as blocking */
- dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR);
- if(((husart->ErrorCode & HAL_USART_ERROR_ORE) != RESET) || dmarequest)
- {
- /* Set the USART state ready to be able to start again the process,
- Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
- USART_EndRxTransfer(husart);
-
- /* Disable the USART DMA Rx request if enabled */
- if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
- {
- CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
-
- /* Abort the USART DMA Rx channel */
- if(husart->hdmarx != NULL)
- {
- /* Set the USART DMA Abort callback :
- will lead to call HAL_USART_ErrorCallback() at end of DMA abort procedure */
- husart->hdmarx->XferAbortCallback = USART_DMAAbortOnError;
-
- if(HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
- {
- /* Call Directly XferAbortCallback function in case of error */
- husart->hdmarx->XferAbortCallback(husart->hdmarx);
- }
- }
- else
- {
- /* Call user error callback */
- HAL_USART_ErrorCallback(husart);
- }
- }
- else
- {
- /* Call user error callback */
- HAL_USART_ErrorCallback(husart);
- }
- }
- else
- {
- /* Call user error callback */
- HAL_USART_ErrorCallback(husart);
- husart->ErrorCode = HAL_USART_ERROR_NONE;
- }
- }
- return;
- }
-
- /* USART in mode Transmitter -----------------------------------------------*/
- if(((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
- {
- if(husart->State == HAL_USART_STATE_BUSY_TX)
- {
- USART_Transmit_IT(husart);
- }
- else
- {
- USART_TransmitReceive_IT(husart);
- }
- return;
- }
-
- /* USART in mode Transmitter (transmission end) ----------------------------*/
- if(((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
- {
- USART_EndTransmit_IT(husart);
- return;
- }
-}
-
-/**
- * @brief Tx Transfer completed callbacks.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval None
- */
-__weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(husart);
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_USART_TxCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Tx Half Transfer completed callbacks.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval None
- */
-__weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(husart);
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_USART_TxHalfCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Rx Transfer completed callbacks.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval None
- */
-__weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(husart);
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_USART_RxCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Rx Half Transfer completed callbacks.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval None
- */
-__weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(husart);
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_USART_RxHalfCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Tx/Rx Transfers completed callback for the non-blocking process.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval None
- */
-__weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(husart);
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_USART_TxRxCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief USART error callbacks.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval None
- */
-__weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(husart);
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_USART_ErrorCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief USART Abort Complete callback.
- * @param husart USART handle.
- * @retval None
- */
-__weak void HAL_USART_AbortCpltCallback (USART_HandleTypeDef *husart)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(husart);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_USART_AbortCpltCallback can be implemented in the user file.
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup USART_Exported_Functions_Group3 Peripheral State and Errors functions
- * @brief USART State and Errors functions
- *
-@verbatim
- ==============================================================================
- ##### Peripheral State and Errors functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to return the State of
- USART communication
- process, return Peripheral Errors occurred during communication process
- (+) HAL_USART_GetState() API can be helpful to check in run-time the state
- of the USART peripheral.
- (+) HAL_USART_GetError() check in run-time errors that could be occurred during
- communication.
-@endverbatim
- * @{
- */
-
-/**
- * @brief Returns the USART state.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval HAL state
- */
-HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart)
-{
- return husart->State;
-}
-
-/**
- * @brief Return the USART error code
- * @param husart : pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART.
- * @retval USART Error Code
- */
-uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart)
-{
- return husart->ErrorCode;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @defgroup USART_Private_Functions USART Private Functions
- * @brief USART Private functions
- * @{
- */
-/**
- * @brief DMA USART transmit process complete callback.
- * @param hdma: DMA handle
- * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
-{
- USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- /* DMA Normal mode */
- if(HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
- {
- husart->TxXferCount = 0U;
- if(husart->State == HAL_USART_STATE_BUSY_TX)
- {
- /* Disable the DMA transfer for transmit request by resetting the DMAT bit
- in the USART CR3 register */
- CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
-
- /* Enable the USART Transmit Complete Interrupt */
- __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
- }
- }
- /* DMA Circular mode */
- else
- {
- if(husart->State == HAL_USART_STATE_BUSY_TX)
- {
- HAL_USART_TxCpltCallback(husart);
- }
- }
-}
-
-/**
- * @brief DMA USART transmit process half complete callback
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
-{
- USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
-
- HAL_USART_TxHalfCpltCallback(husart);
-}
-
-/**
- * @brief DMA USART receive process complete callback.
- * @param hdma: DMA handle
- * @retval None
- */
-static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
-{
- USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- /* DMA Normal mode */
- if(HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
- {
- husart->RxXferCount = 0x00U;
-
- /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
- CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
- CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
-
- if(husart->State == HAL_USART_STATE_BUSY_RX)
- {
- /* Disable the DMA transfer for the Transmit/Receiver requests by setting the DMAT/DMAR bit
- in the USART CR3 register */
- CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
-
- husart->State= HAL_USART_STATE_READY;
- HAL_USART_RxCpltCallback(husart);
- }
- /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
- else
- {
- /* Disable the DMA transfer for the Transmit/receiver requests by setting the DMAT/DMAR bit
- in the USART CR3 register */
- CLEAR_BIT(husart->Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
-
- husart->State= HAL_USART_STATE_READY;
- HAL_USART_TxRxCpltCallback(husart);
- }
- }
- /* DMA circular mode */
- else
- {
- if(husart->State == HAL_USART_STATE_BUSY_RX)
- {
- HAL_USART_RxCpltCallback(husart);
- }
- /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
- else
- {
- HAL_USART_TxRxCpltCallback(husart);
- }
- }
-}
-
-/**
- * @brief DMA USART receive process half complete callback
- * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
- * the configuration information for the specified DMA module.
- * @retval None
- */
-static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
-{
- USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
-
- HAL_USART_RxHalfCpltCallback(husart);
-}
-
-/**
- * @brief DMA USART communication error callback.
- * @param hdma: DMA handle
- * @retval None
- */
-static void USART_DMAError(DMA_HandleTypeDef *hdma)
-{
- uint32_t dmarequest = 0x00U;
- USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- husart->RxXferCount = 0x00U;
- husart->TxXferCount = 0x00U;
-
- /* Stop USART DMA Tx request if ongoing */
- dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT);
- if((husart->State == HAL_USART_STATE_BUSY_TX) && dmarequest)
- {
- USART_EndTxTransfer(husart);
- }
-
- /* Stop USART DMA Rx request if ongoing */
- dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR);
- if((husart->State == HAL_USART_STATE_BUSY_RX) && dmarequest)
- {
- USART_EndRxTransfer(husart);
- }
-
- husart->ErrorCode |= HAL_USART_ERROR_DMA;
- husart->State= HAL_USART_STATE_READY;
-
- HAL_USART_ErrorCallback(husart);
-}
-
-/**
- * @brief This function handles USART Communication Timeout.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @param Flag: specifies the USART flag to check.
- * @param Status: The new Flag status (SET or RESET).
- * @param Tickstart: Tick start value.
- * @param Timeout: Timeout duration.
- * @retval HAL status
- */
-static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
-{
- /* Wait until flag is set */
- while((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status)
- {
- /* Check for the Timeout */
- if(Timeout != HAL_MAX_DELAY)
- {
- if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout))
- {
- /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
- __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
- __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
- __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
- __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
-
- husart->State= HAL_USART_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(husart);
-
- return HAL_TIMEOUT;
- }
- }
- }
- return HAL_OK;
-}
-
-/**
- * @brief End ongoing Tx transfer on USART peripheral (following error detection or Transmit completion).
- * @param husart: USART handle.
- * @retval None
- */
-static void USART_EndTxTransfer(USART_HandleTypeDef *husart)
-{
- /* Disable TXEIE and TCIE interrupts */
- CLEAR_BIT(husart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
-
- /* At end of Tx process, restore husart->State to Ready */
- husart->State = HAL_USART_STATE_READY;
-}
-
-/**
- * @brief End ongoing Rx transfer on USART peripheral (following error detection or Reception completion).
- * @param husart: USART handle.
- * @retval None
- */
-static void USART_EndRxTransfer(USART_HandleTypeDef *husart)
-{
- /* Disable RXNE, PE and ERR interrupts */
- CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
- CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
-
- /* At end of Rx process, restore husart->State to Ready */
- husart->State = HAL_USART_STATE_READY;
-}
-
-/**
- * @brief DMA USART communication abort callback, when initiated by HAL services on Error
- * (To be called at end of DMA Abort procedure following error occurrence).
- * @param hdma DMA handle.
- * @retval None
- */
-static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
-{
- USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- husart->RxXferCount = 0x00U;
- husart->TxXferCount = 0x00U;
-
- HAL_USART_ErrorCallback(husart);
-}
-
-/**
- * @brief DMA USART Tx communication abort callback, when initiated by user
- * (To be called at end of DMA Tx Abort procedure following user abort request).
- * @note When this callback is executed, User Abort complete call back is called only if no
- * Abort still ongoing for Rx DMA Handle.
- * @param hdma DMA handle.
- * @retval None
- */
-static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
-{
- USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- husart->hdmatx->XferAbortCallback = NULL;
-
- /* Check if an Abort process is still ongoing */
- if(husart->hdmarx != NULL)
- {
- if(husart->hdmarx->XferAbortCallback != NULL)
- {
- return;
- }
- }
-
- /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
- husart->TxXferCount = 0x00U;
- husart->RxXferCount = 0x00U;
-
- /* Reset errorCode */
- husart->ErrorCode = HAL_USART_ERROR_NONE;
-
- /* Restore husart->State to Ready */
- husart->State = HAL_USART_STATE_READY;
-
- /* Call user Abort complete callback */
- HAL_USART_AbortCpltCallback(husart);
-}
-
-/**
- * @brief DMA USART Rx communication abort callback, when initiated by user
- * (To be called at end of DMA Rx Abort procedure following user abort request).
- * @note When this callback is executed, User Abort complete call back is called only if no
- * Abort still ongoing for Tx DMA Handle.
- * @param hdma DMA handle.
- * @retval None
- */
-static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
-{
- USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
-
- husart->hdmarx->XferAbortCallback = NULL;
-
- /* Check if an Abort process is still ongoing */
- if(husart->hdmatx != NULL)
- {
- if(husart->hdmatx->XferAbortCallback != NULL)
- {
- return;
- }
- }
-
- /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
- husart->TxXferCount = 0x00U;
- husart->RxXferCount = 0x00U;
-
- /* Reset errorCode */
- husart->ErrorCode = HAL_USART_ERROR_NONE;
-
- /* Restore husart->State to Ready */
- husart->State = HAL_USART_STATE_READY;
-
- /* Call user Abort complete callback */
- HAL_USART_AbortCpltCallback(husart);
-}
-
-/**
- * @brief Simplex Send an amount of data in non-blocking mode.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval HAL status
- * @note The USART errors are not managed to avoid the overrun error.
- */
-static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart)
-{
- uint16_t* tmp;
-
- if(husart->State == HAL_USART_STATE_BUSY_TX)
- {
- if(husart->Init.WordLength == USART_WORDLENGTH_9B)
- {
- tmp = (uint16_t*) husart->pTxBuffPtr;
- WRITE_REG(husart->Instance->DR, (uint16_t)(*tmp & (uint16_t)0x01FF));
- if(husart->Init.Parity == USART_PARITY_NONE)
- {
- husart->pTxBuffPtr += 2U;
- }
- else
- {
- husart->pTxBuffPtr += 1U;
- }
- }
- else
- {
- WRITE_REG(husart->Instance->DR, (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0x00FF));
- }
-
- if(--husart->TxXferCount == 0U)
- {
- /* Disable the USART Transmit data register empty Interrupt */
- __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
-
- /* Enable the USART Transmit Complete Interrupt */
- __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
- }
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Wraps up transmission in non blocking mode.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval HAL status
- */
-static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart)
-{
- /* Disable the USART Transmit Complete Interrupt */
- __HAL_USART_DISABLE_IT(husart, USART_IT_TC);
-
- /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
- __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
-
- husart->State = HAL_USART_STATE_READY;
-
- HAL_USART_TxCpltCallback(husart);
-
- return HAL_OK;
-}
-
-/**
- * @brief Simplex Receive an amount of data in non-blocking mode.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval HAL status
- */
-static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart)
-{
- uint16_t* tmp;
- if(husart->State == HAL_USART_STATE_BUSY_RX)
- {
- if(husart->Init.WordLength == USART_WORDLENGTH_9B)
- {
- tmp = (uint16_t*) husart->pRxBuffPtr;
- if(husart->Init.Parity == USART_PARITY_NONE)
- {
- *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
- husart->pRxBuffPtr += 2U;
- }
- else
- {
- *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
- husart->pRxBuffPtr += 1U;
- }
- if(--husart->RxXferCount != 0x00U)
- {
- /* Send dummy byte in order to generate the clock for the slave to send the next data */
- WRITE_REG(husart->Instance->DR, (DUMMY_DATA & (uint16_t)0x01FF));
- }
- }
- else
- {
- if(husart->Init.Parity == USART_PARITY_NONE)
- {
- *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
- }
- else
- {
- *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
- }
-
- if(--husart->RxXferCount != 0x00U)
- {
- /* Send dummy byte in order to generate the clock for the slave to send the next data */
- WRITE_REG(husart->Instance->DR, (DUMMY_DATA & (uint16_t)0x00FF));
- }
- }
-
- if(husart->RxXferCount == 0U)
- {
- /* Disable the USART RXNE Interrupt */
- CLEAR_BIT(husart->Instance->CR1, USART_CR1_RXNEIE);
-
- /* Disable the USART Parity Error Interrupt */
- CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
-
- /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
- CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
-
- husart->State = HAL_USART_STATE_READY;
- HAL_USART_RxCpltCallback(husart);
-
- return HAL_OK;
- }
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval HAL status
- */
-static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart)
-{
- uint16_t* tmp;
-
- if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
- {
- if(husart->TxXferCount != 0x00U)
- {
- if(__HAL_USART_GET_FLAG(husart, USART_FLAG_TXE) != RESET)
- {
- if(husart->Init.WordLength == USART_WORDLENGTH_9B)
- {
- tmp = (uint16_t*) husart->pTxBuffPtr;
- WRITE_REG(husart->Instance->DR, (uint16_t)(*tmp & (uint16_t)0x01FF));
- if(husart->Init.Parity == USART_PARITY_NONE)
- {
- husart->pTxBuffPtr += 2U;
- }
- else
- {
- husart->pTxBuffPtr += 1U;
- }
- }
- else
- {
- WRITE_REG(husart->Instance->DR, (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0x00FF));
- }
- husart->TxXferCount--;
-
- /* Check the latest data transmitted */
- if(husart->TxXferCount == 0U)
- {
- CLEAR_BIT(husart->Instance->CR1, USART_CR1_TXEIE);
- }
- }
- }
-
- if(husart->RxXferCount != 0x00U)
- {
- if(__HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE) != RESET)
- {
- if(husart->Init.WordLength == USART_WORDLENGTH_9B)
- {
- tmp = (uint16_t*) husart->pRxBuffPtr;
- if(husart->Init.Parity == USART_PARITY_NONE)
- {
- *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
- husart->pRxBuffPtr += 2U;
- }
- else
- {
- *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
- husart->pRxBuffPtr += 1U;
- }
- }
- else
- {
- if(husart->Init.Parity == USART_PARITY_NONE)
- {
- *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
- }
- else
- {
- *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
- }
- }
- husart->RxXferCount--;
- }
- }
-
- /* Check the latest data received */
- if(husart->RxXferCount == 0U)
- {
- /* Disable the USART RXNE Interrupt */
- CLEAR_BIT(husart->Instance->CR1, USART_CR1_RXNEIE);
-
- /* Disable the USART Parity Error Interrupt */
- CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
-
- /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
- CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
-
- husart->State = HAL_USART_STATE_READY;
-
- HAL_USART_TxRxCpltCallback(husart);
-
- return HAL_OK;
- }
-
- return HAL_OK;
- }
- else
- {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Configures the USART pferipheral.
- * @param husart: pointer to a USART_HandleTypeDef structure that contains
- * the configuration information for the specified USART module.
- * @retval None
- */
-static void USART_SetConfig(USART_HandleTypeDef *husart)
-{
- /* Check the parameters */
- assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
- assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
- assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
- assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));
- assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
- assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
- assert_param(IS_USART_PARITY(husart->Init.Parity));
- assert_param(IS_USART_MODE(husart->Init.Mode));
-
- /* The LBCL, CPOL and CPHA bits have to be selected when both the transmitter and the
- receiver are disabled (TE=RE=0) to ensure that the clock pulses function correctly. */
- CLEAR_BIT(husart->Instance->CR1, ((uint32_t)(USART_CR1_TE | USART_CR1_RE)));
-
- /*---------------------------- USART CR2 Configuration ---------------------*/
- /* Configure the USART Clock, CPOL, CPHA and LastBit -----------------------*/
- /* Set CPOL bit according to husart->Init.CLKPolarity value */
- /* Set CPHA bit according to husart->Init.CLKPhase value */
- /* Set LBCL bit according to husart->Init.CLKLastBit value */
- /* Set Stop Bits: Set STOP[13:12] bits according to husart->Init.StopBits value */
- /* Write to USART CR2 */
- MODIFY_REG(husart->Instance->CR2,
- (uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP),
- ((uint32_t)(USART_CLOCK_ENABLE| husart->Init.CLKPolarity | husart->Init.CLKPhase| husart->Init.CLKLastBit | husart->Init.StopBits)));
-
- /*-------------------------- USART CR1 Configuration -----------------------*/
- /* Configure the USART Word Length, Parity and mode:
- Set the M bits according to husart->Init.WordLength value
- Set PCE and PS bits according to husart->Init.Parity value
- Set TE and RE bits according to husart->Init.Mode value */
- MODIFY_REG(husart->Instance->CR1,
- (uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE),
- (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode);
-
- /*-------------------------- USART CR3 Configuration -----------------------*/
- /* Clear CTSE and RTSE bits */
- CLEAR_BIT(husart->Instance->CR3, (uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE));
-
- /*-------------------------- USART BRR Configuration -----------------------*/
- if((husart->Instance == USART1))
- {
- husart->Instance->BRR = USART_BRR(HAL_RCC_GetPCLK2Freq(), husart->Init.BaudRate);
- }
- else
- {
- husart->Instance->BRR = USART_BRR(HAL_RCC_GetPCLK1Freq(), husart->Init.BaudRate);
- }
-}
-
-/**
- * @}
- */
-
-#endif /* HAL_USART_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_wwdg.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_wwdg.c
deleted file mode 100644
index 4f2cdca..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_wwdg.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_wwdg.c
- * @author MCD Application Team
- * @brief WWDG HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Window Watchdog (WWDG) peripheral:
- * + Initialization and de-initialization functions
- * + IO operation functions
- * + Peripheral State functions
- @verbatim
- ==============================================================================
- ##### WWDG specific features #####
- ==============================================================================
- [..]
- Once enabled the WWDG generates a system reset on expiry of a programmed
- time period, unless the program refreshes the counter (downcounter)
- before reaching 0x3F value (i.e. a reset is generated when the counter
- value rolls over from 0x40 to 0x3F).
-
- (+) An MCU reset is also generated if the counter value is refreshed
- before the counter has reached the refresh window value. This
- implies that the counter must be refreshed in a limited window.
- (+) Once enabled the WWDG cannot be disabled except by a system reset.
- (+) WWDGRST flag in RCC_CSR register can be used to inform when a WWDG
- reset occurs.
- (+) The WWDG counter input clock is derived from the APB clock divided
- by a programmable prescaler.
- (+) WWDG clock (Hz) = PCLK1 / (4096 * Prescaler)
- (+) WWDG timeout (mS) = 1000 * Counter / WWDG clock
- (+) WWDG Counter refresh is allowed between the following limits :
- (++) min time (mS) = 1000 * (Counter _ Window) / WWDG clock
- (++) max time (mS) = 1000 * (Counter _ 0x40) / WWDG clock
-
- (+) Min-max timeout value at 36 MHz(PCLK1): 910 us / 58.25 ms
-
- (+) The Early Wakeup Interrupt (EWI) can be used if specific safety
- operations or data logging must be performed before the actual reset is
- generated. When the downcounter reaches the value 0x40, an EWI interrupt
- is generated and the corresponding interrupt service routine (ISR) can
- be used to trigger specific actions (such as communications or data
- logging), before resetting the device.
- In some applications, the EWI interrupt can be used to manage a software
- system check and/or system recovery/graceful degradation, without
- generating a WWDG reset. In this case, the corresponding interrupt
- service routine (ISR) should reload the WWDG counter to avoid the WWDG
- reset, then trigger the required actions.
- Note:When the EWI interrupt cannot be served, e.g. due to a system lock
- in a higher priority task, the WWDG reset will eventually be generated.
-
- (+) Debug mode : When the microcontroller enters debug mode (core halted),
- the WWDG counter either continues to work normally or stops, depending
- on DBG_WWDG_STOP configuration bit in DBG module, accessible through
- __HAL_DBGMCU_FREEZE_WWDG() and __HAL_DBGMCU_UNFREEZE_WWDG() macros
-
- ##### How to use this driver #####
- ==============================================================================
- [..]
- (+) Enable WWDG APB1 clock using __HAL_RCC_WWDG_CLK_ENABLE().
-
- (+) Set the WWDG prescaler, refresh window, counter value and Early Wakeup
- Interrupt mode using using HAL_WWDG_Init() function.
- This enables WWDG peripheral and the downcounter starts downcounting
- from given counter value.
- Init function can be called again to modify all watchdog parameters,
- however if EWI mode has been set once, it can't be clear until next
- reset.
-
- (+) The application program must refresh the WWDG counter at regular
- intervals during normal operation to prevent an MCU reset using
- HAL_WWDG_Refresh() function. This operation must occur only when
- the counter is lower than the window value already programmed.
-
- (+) if Early Wakeup Interrupt mode is enable an interrupt is generated when
- the counter reaches 0x40. User can add his own code in weak function
- HAL_WWDG_EarlyWakeupCallback().
-
- *** WWDG HAL driver macros list ***
- ==================================
- [..]
- Below the list of most used macros in WWDG HAL driver.
-
- (+) __HAL_WWDG_GET_IT_SOURCE: Check the selected WWDG's interrupt source.
- (+) __HAL_WWDG_GET_FLAG: Get the selected WWDG's flag status.
- (+) __HAL_WWDG_CLEAR_FLAG: Clear the WWDG's pending flags.
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#ifdef HAL_WWDG_MODULE_ENABLED
-/** @defgroup WWDG WWDG
- * @brief WWDG HAL module driver.
- * @{
- */
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-
-/** @defgroup WWDG_Exported_Functions WWDG Exported Functions
- * @{
- */
-
-/** @defgroup WWDG_Exported_Functions_Group1 Initialization and Configuration functions
- * @brief Initialization and Configuration functions.
- *
-@verbatim
- ==============================================================================
- ##### Initialization and Configuration functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to:
- (+) Initialize and start the WWDG according to the specified parameters
- in the WWDG_InitTypeDef of associated handle.
- (+) Initialize the WWDG MSP.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initialize the WWDG according to the specified.
- * parameters in the WWDG_InitTypeDef of associated handle.
- * @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains
- * the configuration information for the specified WWDG module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg)
-{
- /* Check the WWDG handle allocation */
- if (hwwdg == NULL)
- {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_WWDG_ALL_INSTANCE(hwwdg->Instance));
- assert_param(IS_WWDG_PRESCALER(hwwdg->Init.Prescaler));
- assert_param(IS_WWDG_WINDOW(hwwdg->Init.Window));
- assert_param(IS_WWDG_COUNTER(hwwdg->Init.Counter));
- assert_param(IS_WWDG_EWI_MODE(hwwdg->Init.EWIMode));
-
- /* Init the low level hardware */
- HAL_WWDG_MspInit(hwwdg);
-
- /* Set WWDG Counter */
- WRITE_REG(hwwdg->Instance->CR, (WWDG_CR_WDGA | hwwdg->Init.Counter));
-
- /* Set WWDG Prescaler and Window */
- WRITE_REG(hwwdg->Instance->CFR, (hwwdg->Init.EWIMode | hwwdg->Init.Prescaler | hwwdg->Init.Window));
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Initialize the WWDG MSP.
- * @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains
- * the configuration information for the specified WWDG module.
- * @note When rewriting this function in user file, mechanism may be added
- * to avoid multiple initialize when HAL_WWDG_Init function is called
- * again to change parameters.
- * @retval None
- */
-__weak void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hwwdg);
-
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_WWDG_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup WWDG_Exported_Functions_Group2 IO operation functions
- * @brief IO operation functions
- *
-@verbatim
- ==============================================================================
- ##### IO operation functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to:
- (+) Refresh the WWDG.
- (+) Handle WWDG interrupt request and associated function callback.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Refresh the WWDG.
- * @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains
- * the configuration information for the specified WWDG module.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg)
-{
- /* Write to WWDG CR the WWDG Counter value to refresh with */
- WRITE_REG(hwwdg->Instance->CR, (hwwdg->Init.Counter));
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Handle WWDG interrupt request.
- * @note The Early Wakeup Interrupt (EWI) can be used if specific safety operations
- * or data logging must be performed before the actual reset is generated.
- * The EWI interrupt is enabled by calling HAL_WWDG_Init function with
- * EWIMode set to WWDG_EWI_ENABLE.
- * When the downcounter reaches the value 0x40, and EWI interrupt is
- * generated and the corresponding Interrupt Service Routine (ISR) can
- * be used to trigger specific actions (such as communications or data
- * logging), before resetting the device.
- * @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains
- * the configuration information for the specified WWDG module.
- * @retval None
- */
-void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg)
-{
- /* Check if Early Wakeup Interrupt is enable */
- if (__HAL_WWDG_GET_IT_SOURCE(hwwdg, WWDG_IT_EWI) != RESET)
- {
- /* Check if WWDG Early Wakeup Interrupt occurred */
- if (__HAL_WWDG_GET_FLAG(hwwdg, WWDG_FLAG_EWIF) != RESET)
- {
- /* Clear the WWDG Early Wakeup flag */
- __HAL_WWDG_CLEAR_FLAG(hwwdg, WWDG_FLAG_EWIF);
-
- /* Early Wakeup callback */
- HAL_WWDG_EarlyWakeupCallback(hwwdg);
- }
- }
-}
-
-/**
- * @brief WWDG Early Wakeup callback.
- * @param hwwdg : pointer to a WWDG_HandleTypeDef structure that contains
- * the configuration information for the specified WWDG module.
- * @retval None
- */
-__weak void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hwwdg);
-
- /* NOTE: This function should not be modified, when the callback is needed,
- the HAL_WWDG_EarlyWakeupCallback could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* HAL_WWDG_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_adc.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_adc.c
deleted file mode 100644
index e382d99..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_adc.c
+++ /dev/null
@@ -1,901 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_adc.c
- * @author MCD Application Team
- * @brief ADC LL module driver
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-#if defined(USE_FULL_LL_DRIVER)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_adc.h"
-#include "stm32f1xx_ll_bus.h"
-
-#ifdef USE_FULL_ASSERT
- #include "stm32_assert.h"
-#else
- #define assert_param(expr) ((void)0U)
-#endif
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined (ADC1) || defined (ADC2) || defined (ADC3)
-
-/** @addtogroup ADC_LL ADC
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-
-/** @addtogroup ADC_LL_Private_Macros
- * @{
- */
-
-/* Check of parameters for configuration of ADC hierarchical scope: */
-/* common to several ADC instances. */
-/* Check of parameters for configuration of ADC hierarchical scope: */
-/* ADC instance. */
-#define IS_LL_ADC_DATA_ALIGN(__DATA_ALIGN__) \
- ( ((__DATA_ALIGN__) == LL_ADC_DATA_ALIGN_RIGHT) \
- || ((__DATA_ALIGN__) == LL_ADC_DATA_ALIGN_LEFT) \
- )
-
-#define IS_LL_ADC_SCAN_SELECTION(__SCAN_SELECTION__) \
- ( ((__SCAN_SELECTION__) == LL_ADC_SEQ_SCAN_DISABLE) \
- || ((__SCAN_SELECTION__) == LL_ADC_SEQ_SCAN_ENABLE) \
- )
-
-#define IS_LL_ADC_SEQ_SCAN_MODE(__SEQ_SCAN_MODE__) \
- ( ((__SCAN_MODE__) == LL_ADC_SEQ_SCAN_DISABLE) \
- || ((__SCAN_MODE__) == LL_ADC_SEQ_SCAN_ENABLE) \
- )
-
-/* Check of parameters for configuration of ADC hierarchical scope: */
-/* ADC group regular */
-#if defined(ADC3)
-#define IS_LL_ADC_REG_TRIG_SOURCE(__ADC_INSTANCE__, __REG_TRIG_SOURCE__) \
- ((((__ADC_INSTANCE__) == ADC1) || ((__ADC_INSTANCE__) == ADC2)) \
- ? ( ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_SOFTWARE) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH3) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH1) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH2) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_CH2) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM3_TRGO) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM4_CH4) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_EXTI_LINE11) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM8_TRGO) \
- ) \
- : \
- ( ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_SOFTWARE) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH3) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM3_CH1) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_CH3) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM8_CH1) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM8_TRGO_ADC3) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM5_CH1) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM5_CH3) \
- ) \
- )
-#else
-#if defined (STM32F101xE) || defined (STM32F105xC) || defined (STM32F107xC)
-#define IS_LL_ADC_REG_TRIG_SOURCE(__REG_TRIG_SOURCE__) \
- ( ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_SOFTWARE) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH3) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH1) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH2) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_CH2) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM3_TRGO) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM4_CH4) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_EXTI_LINE11) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM8_TRGO) \
- )
-#else
-#define IS_LL_ADC_REG_TRIG_SOURCE(__REG_TRIG_SOURCE__) \
- ( ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_SOFTWARE) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH3) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH1) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH2) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_CH2) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM3_TRGO) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM4_CH4) \
- || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_EXTI_LINE11) \
- )
-#endif
-#endif
-#define IS_LL_ADC_REG_CONTINUOUS_MODE(__REG_CONTINUOUS_MODE__) \
- ( ((__REG_CONTINUOUS_MODE__) == LL_ADC_REG_CONV_SINGLE) \
- || ((__REG_CONTINUOUS_MODE__) == LL_ADC_REG_CONV_CONTINUOUS) \
- )
-
-#define IS_LL_ADC_REG_DMA_TRANSFER(__REG_DMA_TRANSFER__) \
- ( ((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_NONE) \
- || ((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_UNLIMITED) \
- )
-
-#define IS_LL_ADC_REG_SEQ_SCAN_LENGTH(__REG_SEQ_SCAN_LENGTH__) \
- ( ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_DISABLE) \
- || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_2RANKS) \
- || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_3RANKS) \
- || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_4RANKS) \
- || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_5RANKS) \
- || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_6RANKS) \
- || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_7RANKS) \
- || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_8RANKS) \
- || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_9RANKS) \
- || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_10RANKS) \
- || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_11RANKS) \
- || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_12RANKS) \
- || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_13RANKS) \
- || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_14RANKS) \
- || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_15RANKS) \
- || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_16RANKS) \
- )
-
-#define IS_LL_ADC_REG_SEQ_SCAN_DISCONT_MODE(__REG_SEQ_DISCONT_MODE__) \
- ( ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_DISABLE) \
- || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_1RANK) \
- || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_2RANKS) \
- || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_3RANKS) \
- || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_4RANKS) \
- || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_5RANKS) \
- || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_6RANKS) \
- || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_7RANKS) \
- || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_8RANKS) \
- )
-
-/* Check of parameters for configuration of ADC hierarchical scope: */
-/* ADC group injected */
-#if defined(ADC3)
-#define IS_LL_ADC_INJ_TRIG_SOURCE(__ADC_INSTANCE__, __INJ_TRIG_SOURCE__) \
- ((((__ADC_INSTANCE__) == ADC1) || ((__ADC_INSTANCE__) == ADC2)) \
- ? ( ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_SOFTWARE) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_TRGO) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_CH4) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_TRGO) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_CH1) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM3_CH4) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM4_TRGO) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_EXTI_LINE15) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM8_CH4) \
- ) \
- : \
- ( ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_SOFTWARE) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_TRGO) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_CH4) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM4_CH3) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM8_CH2) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM8_CH4_ADC3) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM5_TRGO) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM5_CH4) \
- ) \
- )
-#else
-#if defined (STM32F101xE) || defined (STM32F105xC) || defined (STM32F107xC)
-#define IS_LL_ADC_INJ_TRIG_SOURCE(__INJ_TRIG_SOURCE__) \
- ( ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_SOFTWARE) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_TRGO) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_CH4) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_TRGO) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_CH1) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM3_CH4) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM4_TRGO) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_EXTI_LINE15) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM8_CH4) \
- )
-#else
-#define IS_LL_ADC_INJ_TRIG_SOURCE(__INJ_TRIG_SOURCE__) \
- ( ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_SOFTWARE) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_TRGO) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_CH4) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_TRGO) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_CH1) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM3_CH4) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM4_TRGO) \
- || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_EXTI_LINE15) \
- )
-#endif
-#endif
-#define IS_LL_ADC_INJ_TRIG_AUTO(__INJ_TRIG_AUTO__) \
- ( ((__INJ_TRIG_AUTO__) == LL_ADC_INJ_TRIG_INDEPENDENT) \
- || ((__INJ_TRIG_AUTO__) == LL_ADC_INJ_TRIG_FROM_GRP_REGULAR) \
- )
-
-#define IS_LL_ADC_INJ_SEQ_SCAN_LENGTH(__INJ_SEQ_SCAN_LENGTH__) \
- ( ((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_DISABLE) \
- || ((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_ENABLE_2RANKS) \
- || ((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_ENABLE_3RANKS) \
- || ((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_ENABLE_4RANKS) \
- )
-
-#define IS_LL_ADC_INJ_SEQ_SCAN_DISCONT_MODE(__INJ_SEQ_DISCONT_MODE__) \
- ( ((__INJ_SEQ_DISCONT_MODE__) == LL_ADC_INJ_SEQ_DISCONT_DISABLE) \
- || ((__INJ_SEQ_DISCONT_MODE__) == LL_ADC_INJ_SEQ_DISCONT_1RANK) \
- )
-
-#if defined(ADC_MULTIMODE_SUPPORT)
-/* Check of parameters for configuration of ADC hierarchical scope: */
-/* multimode. */
-#define IS_LL_ADC_MULTI_MODE(__MULTI_MODE__) \
- ( ((__MULTI_MODE__) == LL_ADC_MULTI_INDEPENDENT) \
- || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_SIMULT) \
- || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_INTERL_FAST) \
- || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_INTERL_SLOW) \
- || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_INJ_SIMULT) \
- || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_INJ_ALTERN) \
- || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_SIM_INJ_SIM) \
- || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_SIM_INJ_ALT) \
- || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_INTFAST_INJ_SIM) \
- || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_INTSLOW_INJ_SIM) \
- )
-
-#define IS_LL_ADC_MULTI_MASTER_SLAVE(__MULTI_MASTER_SLAVE__) \
- ( ((__MULTI_MASTER_SLAVE__) == LL_ADC_MULTI_MASTER) \
- || ((__MULTI_MASTER_SLAVE__) == LL_ADC_MULTI_SLAVE) \
- || ((__MULTI_MASTER_SLAVE__) == LL_ADC_MULTI_MASTER_SLAVE) \
- )
-
-#endif /* ADC_MULTIMODE_SUPPORT */
-/**
- * @}
- */
-
-
-/* Private function prototypes -----------------------------------------------*/
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup ADC_LL_Exported_Functions
- * @{
- */
-
-/** @addtogroup ADC_LL_EF_Init
- * @{
- */
-
-/**
- * @brief De-initialize registers of all ADC instances belonging to
- * the same ADC common instance to their default reset values.
- * @param ADCxy_COMMON ADC common instance
- * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() )
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: ADC common registers are de-initialized
- * - ERROR: not applicable
- */
-ErrorStatus LL_ADC_CommonDeInit(ADC_Common_TypeDef *ADCxy_COMMON)
-{
- /* Check the parameters */
- assert_param(IS_ADC_COMMON_INSTANCE(ADCxy_COMMON));
-
- /* Force reset of ADC clock (core clock) */
- LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_ADC1);
-
- /* Release reset of ADC clock (core clock) */
- LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_ADC1);
-
- return SUCCESS;
-}
-
-/**
- * @brief Initialize some features of ADC common parameters
- * (all ADC instances belonging to the same ADC common instance)
- * and multimode (for devices with several ADC instances available).
- * @note The setting of ADC common parameters is conditioned to
- * ADC instances state:
- * All ADC instances belonging to the same ADC common instance
- * must be disabled.
- * @param ADCxy_COMMON ADC common instance
- * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() )
- * @param ADC_CommonInitStruct Pointer to a @ref LL_ADC_CommonInitTypeDef structure
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: ADC common registers are initialized
- * - ERROR: ADC common registers are not initialized
- */
-ErrorStatus LL_ADC_CommonInit(ADC_Common_TypeDef *ADCxy_COMMON, LL_ADC_CommonInitTypeDef *ADC_CommonInitStruct)
-{
- ErrorStatus status = SUCCESS;
-
- /* Check the parameters */
- assert_param(IS_ADC_COMMON_INSTANCE(ADCxy_COMMON));
-#if defined(ADC_MULTIMODE_SUPPORT)
- assert_param(IS_LL_ADC_MULTI_MODE(ADC_CommonInitStruct->Multimode));
-#endif /* ADC_MULTIMODE_SUPPORT */
-
- /* Note: Hardware constraint (refer to description of functions */
- /* "LL_ADC_SetCommonXXX()" and "LL_ADC_SetMultiXXX()"): */
- /* On this STM32 serie, setting of these features is conditioned to */
- /* ADC state: */
- /* All ADC instances of the ADC common group must be disabled. */
- if(__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(ADCxy_COMMON) == 0U)
- {
- /* Configuration of ADC hierarchical scope: */
- /* - common to several ADC */
- /* (all ADC instances belonging to the same ADC common instance) */
- /* - multimode (if several ADC instances available on the */
- /* selected device) */
- /* - Set ADC multimode configuration */
- /* - Set ADC multimode DMA transfer */
- /* - Set ADC multimode: delay between 2 sampling phases */
-#if defined(ADC_MULTIMODE_SUPPORT)
- if(ADC_CommonInitStruct->Multimode != LL_ADC_MULTI_INDEPENDENT)
- {
- MODIFY_REG(ADCxy_COMMON->CR1,
- ADC_CR1_DUALMOD,
- ADC_CommonInitStruct->Multimode
- );
- }
- else
- {
- MODIFY_REG(ADCxy_COMMON->CR1,
- ADC_CR1_DUALMOD,
- LL_ADC_MULTI_INDEPENDENT
- );
- }
-#endif
- }
- else
- {
- /* Initialization error: One or several ADC instances belonging to */
- /* the same ADC common instance are not disabled. */
- status = ERROR;
- }
-
- return status;
-}
-
-/**
- * @brief Set each @ref LL_ADC_CommonInitTypeDef field to default value.
- * @param ADC_CommonInitStruct Pointer to a @ref LL_ADC_CommonInitTypeDef structure
- * whose fields will be set to default values.
- * @retval None
- */
-void LL_ADC_CommonStructInit(LL_ADC_CommonInitTypeDef *ADC_CommonInitStruct)
-{
- /* Set ADC_CommonInitStruct fields to default values */
- /* Set fields of ADC common */
- /* (all ADC instances belonging to the same ADC common instance) */
-
-#if defined(ADC_MULTIMODE_SUPPORT)
- /* Set fields of ADC multimode */
- ADC_CommonInitStruct->Multimode = LL_ADC_MULTI_INDEPENDENT;
-#endif /* ADC_MULTIMODE_SUPPORT */
-}
-
-/**
- * @brief De-initialize registers of the selected ADC instance
- * to their default reset values.
- * @note To reset all ADC instances quickly (perform a hard reset),
- * use function @ref LL_ADC_CommonDeInit().
- * @param ADCx ADC instance
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: ADC registers are de-initialized
- * - ERROR: ADC registers are not de-initialized
- */
-ErrorStatus LL_ADC_DeInit(ADC_TypeDef *ADCx)
-{
- ErrorStatus status = SUCCESS;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(ADCx));
-
- /* Disable ADC instance if not already disabled. */
- if(LL_ADC_IsEnabled(ADCx) == 1U)
- {
- /* Set ADC group regular trigger source to SW start to ensure to not */
- /* have an external trigger event occurring during the conversion stop */
- /* ADC disable process. */
- LL_ADC_REG_SetTriggerSource(ADCx, LL_ADC_REG_TRIG_SOFTWARE);
-
- /* Set ADC group injected trigger source to SW start to ensure to not */
- /* have an external trigger event occurring during the conversion stop */
- /* ADC disable process. */
- LL_ADC_INJ_SetTriggerSource(ADCx, LL_ADC_INJ_TRIG_SOFTWARE);
-
- /* Disable the ADC instance */
- LL_ADC_Disable(ADCx);
- }
-
- /* Check whether ADC state is compliant with expected state */
- /* (hardware requirements of bits state to reset registers below) */
- if(READ_BIT(ADCx->CR2, ADC_CR2_ADON) == 0U)
- {
- /* ========== Reset ADC registers ========== */
- /* Reset register SR */
- CLEAR_BIT(ADCx->SR,
- ( LL_ADC_FLAG_STRT
- | LL_ADC_FLAG_JSTRT
- | LL_ADC_FLAG_EOS
- | LL_ADC_FLAG_JEOS
- | LL_ADC_FLAG_AWD1 )
- );
-
- /* Reset register CR1 */
- #if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
-
- CLEAR_BIT(ADCx->CR1,
- ( ADC_CR1_AWDEN | ADC_CR1_JAWDEN | ADC_CR1_DUALMOD
- | ADC_CR1_DISCNUM | ADC_CR1_JDISCEN | ADC_CR1_DISCEN
- | ADC_CR1_JAUTO | ADC_CR1_AWDSGL | ADC_CR1_SCAN
- | ADC_CR1_JEOCIE | ADC_CR1_AWDIE | ADC_CR1_EOCIE
- | ADC_CR1_AWDCH )
- );
- #else
-
- CLEAR_BIT(ADCx->CR1,
- ( ADC_CR1_AWDEN | ADC_CR1_JAWDEN | ADC_CR1_DISCNUM
- | ADC_CR1_JDISCEN | ADC_CR1_DISCEN | ADC_CR1_JAUTO
- | ADC_CR1_AWDSGL | ADC_CR1_SCAN | ADC_CR1_JEOCIE
- | ADC_CR1_AWDIE | ADC_CR1_EOCIE | ADC_CR1_AWDCH )
- );
- #endif
-
- /* Reset register CR2 */
- CLEAR_BIT(ADCx->CR2,
- ( ADC_CR2_TSVREFE
- | ADC_CR2_SWSTART | ADC_CR2_EXTTRIG | ADC_CR2_EXTSEL
- | ADC_CR2_JSWSTART | ADC_CR2_JEXTTRIG | ADC_CR2_JEXTSEL
- | ADC_CR2_ALIGN | ADC_CR2_DMA
- | ADC_CR2_RSTCAL | ADC_CR2_CAL
- | ADC_CR2_CONT | ADC_CR2_ADON )
- );
-
- /* Reset register SMPR1 */
- CLEAR_BIT(ADCx->SMPR1,
- ( ADC_SMPR1_SMP17 | ADC_SMPR1_SMP16
- | ADC_SMPR1_SMP15 | ADC_SMPR1_SMP14 | ADC_SMPR1_SMP13
- | ADC_SMPR1_SMP12 | ADC_SMPR1_SMP11 | ADC_SMPR1_SMP10)
- );
-
- /* Reset register SMPR2 */
- CLEAR_BIT(ADCx->SMPR2,
- ( ADC_SMPR2_SMP9
- | ADC_SMPR2_SMP8 | ADC_SMPR2_SMP7 | ADC_SMPR2_SMP6
- | ADC_SMPR2_SMP5 | ADC_SMPR2_SMP4 | ADC_SMPR2_SMP3
- | ADC_SMPR2_SMP2 | ADC_SMPR2_SMP1 | ADC_SMPR2_SMP0)
- );
-
- /* Reset register JOFR1 */
- CLEAR_BIT(ADCx->JOFR1, ADC_JOFR1_JOFFSET1);
- /* Reset register JOFR2 */
- CLEAR_BIT(ADCx->JOFR2, ADC_JOFR2_JOFFSET2);
- /* Reset register JOFR3 */
- CLEAR_BIT(ADCx->JOFR3, ADC_JOFR3_JOFFSET3);
- /* Reset register JOFR4 */
- CLEAR_BIT(ADCx->JOFR4, ADC_JOFR4_JOFFSET4);
-
- /* Reset register HTR */
- SET_BIT(ADCx->HTR, ADC_HTR_HT);
- /* Reset register LTR */
- CLEAR_BIT(ADCx->LTR, ADC_LTR_LT);
-
- /* Reset register SQR1 */
- CLEAR_BIT(ADCx->SQR1,
- ( ADC_SQR1_L
- | ADC_SQR1_SQ16
- | ADC_SQR1_SQ15 | ADC_SQR1_SQ14 | ADC_SQR1_SQ13)
- );
-
- /* Reset register SQR2 */
- CLEAR_BIT(ADCx->SQR2,
- ( ADC_SQR2_SQ12 | ADC_SQR2_SQ11 | ADC_SQR2_SQ10
- | ADC_SQR2_SQ9 | ADC_SQR2_SQ8 | ADC_SQR2_SQ7)
- );
-
-
- /* Reset register JSQR */
- CLEAR_BIT(ADCx->JSQR,
- ( ADC_JSQR_JL
- | ADC_JSQR_JSQ4 | ADC_JSQR_JSQ3
- | ADC_JSQR_JSQ2 | ADC_JSQR_JSQ1 )
- );
-
- /* Reset register DR */
- /* bits in access mode read only, no direct reset applicable */
-
- /* Reset registers JDR1, JDR2, JDR3, JDR4 */
- /* bits in access mode read only, no direct reset applicable */
-
- }
-
- return status;
-}
-
-/**
- * @brief Initialize some features of ADC instance.
- * @note These parameters have an impact on ADC scope: ADC instance.
- * Affects both group regular and group injected (availability
- * of ADC group injected depends on STM32 families).
- * Refer to corresponding unitary functions into
- * @ref ADC_LL_EF_Configuration_ADC_Instance .
- * @note The setting of these parameters by function @ref LL_ADC_Init()
- * is conditioned to ADC state:
- * ADC instance must be disabled.
- * This condition is applied to all ADC features, for efficiency
- * and compatibility over all STM32 families. However, the different
- * features can be set under different ADC state conditions
- * (setting possible with ADC enabled without conversion on going,
- * ADC enabled with conversion on going, ...)
- * Each feature can be updated afterwards with a unitary function
- * and potentially with ADC in a different state than disabled,
- * refer to description of each function for setting
- * conditioned to ADC state.
- * @note After using this function, some other features must be configured
- * using LL unitary functions.
- * The minimum configuration remaining to be done is:
- * - Set ADC group regular or group injected sequencer:
- * map channel on the selected sequencer rank.
- * Refer to function @ref LL_ADC_REG_SetSequencerRanks().
- * - Set ADC channel sampling time
- * Refer to function LL_ADC_SetChannelSamplingTime();
- * @param ADCx ADC instance
- * @param ADC_InitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: ADC registers are initialized
- * - ERROR: ADC registers are not initialized
- */
-ErrorStatus LL_ADC_Init(ADC_TypeDef *ADCx, LL_ADC_InitTypeDef *ADC_InitStruct)
-{
- ErrorStatus status = SUCCESS;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(ADCx));
-
- assert_param(IS_LL_ADC_DATA_ALIGN(ADC_InitStruct->DataAlignment));
- assert_param(IS_LL_ADC_SCAN_SELECTION(ADC_InitStruct->SequencersScanMode));
-
- /* Note: Hardware constraint (refer to description of this function): */
- /* ADC instance must be disabled. */
- if(LL_ADC_IsEnabled(ADCx) == 0U)
- {
- /* Configuration of ADC hierarchical scope: */
- /* - ADC instance */
- /* - Set ADC conversion data alignment */
- MODIFY_REG(ADCx->CR1,
- ADC_CR1_SCAN
- ,
- ADC_InitStruct->SequencersScanMode
- );
-
- MODIFY_REG(ADCx->CR2,
- ADC_CR2_ALIGN
- ,
- ADC_InitStruct->DataAlignment
- );
-
- }
- else
- {
- /* Initialization error: ADC instance is not disabled. */
- status = ERROR;
- }
- return status;
-}
-
-/**
- * @brief Set each @ref LL_ADC_InitTypeDef field to default value.
- * @param ADC_InitStruct Pointer to a @ref LL_ADC_InitTypeDef structure
- * whose fields will be set to default values.
- * @retval None
- */
-void LL_ADC_StructInit(LL_ADC_InitTypeDef *ADC_InitStruct)
-{
- /* Set ADC_InitStruct fields to default values */
- /* Set fields of ADC instance */
- ADC_InitStruct->DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;
-
- /* Enable scan mode to have a generic behavior with ADC of other */
- /* STM32 families, without this setting available: */
- /* ADC group regular sequencer and ADC group injected sequencer depend */
- /* only of their own configuration. */
- ADC_InitStruct->SequencersScanMode = LL_ADC_SEQ_SCAN_ENABLE;
-
-}
-
-/**
- * @brief Initialize some features of ADC group regular.
- * @note These parameters have an impact on ADC scope: ADC group regular.
- * Refer to corresponding unitary functions into
- * @ref ADC_LL_EF_Configuration_ADC_Group_Regular
- * (functions with prefix "REG").
- * @note The setting of these parameters by function @ref LL_ADC_Init()
- * is conditioned to ADC state:
- * ADC instance must be disabled.
- * This condition is applied to all ADC features, for efficiency
- * and compatibility over all STM32 families. However, the different
- * features can be set under different ADC state conditions
- * (setting possible with ADC enabled without conversion on going,
- * ADC enabled with conversion on going, ...)
- * Each feature can be updated afterwards with a unitary function
- * and potentially with ADC in a different state than disabled,
- * refer to description of each function for setting
- * conditioned to ADC state.
- * @note After using this function, other features must be configured
- * using LL unitary functions.
- * The minimum configuration remaining to be done is:
- * - Set ADC group regular or group injected sequencer:
- * map channel on the selected sequencer rank.
- * Refer to function @ref LL_ADC_REG_SetSequencerRanks().
- * - Set ADC channel sampling time
- * Refer to function LL_ADC_SetChannelSamplingTime();
- * @param ADCx ADC instance
- * @param ADC_REG_InitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: ADC registers are initialized
- * - ERROR: ADC registers are not initialized
- */
-ErrorStatus LL_ADC_REG_Init(ADC_TypeDef *ADCx, LL_ADC_REG_InitTypeDef *ADC_REG_InitStruct)
-{
- ErrorStatus status = SUCCESS;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(ADCx));
-#if defined(ADC3)
- assert_param(IS_LL_ADC_REG_TRIG_SOURCE(ADCx, ADC_REG_InitStruct->TriggerSource));
-#else
- assert_param(IS_LL_ADC_REG_TRIG_SOURCE(ADC_REG_InitStruct->TriggerSource));
-#endif
- assert_param(IS_LL_ADC_REG_SEQ_SCAN_LENGTH(ADC_REG_InitStruct->SequencerLength));
- if(ADC_REG_InitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE)
- {
- assert_param(IS_LL_ADC_REG_SEQ_SCAN_DISCONT_MODE(ADC_REG_InitStruct->SequencerDiscont));
- }
- assert_param(IS_LL_ADC_REG_CONTINUOUS_MODE(ADC_REG_InitStruct->ContinuousMode));
- assert_param(IS_LL_ADC_REG_DMA_TRANSFER(ADC_REG_InitStruct->DMATransfer));
-
- /* Note: Hardware constraint (refer to description of this function): */
- /* ADC instance must be disabled. */
- if(LL_ADC_IsEnabled(ADCx) == 0U)
- {
- /* Configuration of ADC hierarchical scope: */
- /* - ADC group regular */
- /* - Set ADC group regular trigger source */
- /* - Set ADC group regular sequencer length */
- /* - Set ADC group regular sequencer discontinuous mode */
- /* - Set ADC group regular continuous mode */
- /* - Set ADC group regular conversion data transfer: no transfer or */
- /* transfer by DMA, and DMA requests mode */
- /* Note: On this STM32 serie, ADC trigger edge is set when starting */
- /* ADC conversion. */
- /* Refer to function @ref LL_ADC_REG_StartConversionExtTrig(). */
- if(ADC_REG_InitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE)
- {
- MODIFY_REG(ADCx->CR1,
- ADC_CR1_DISCEN
- | ADC_CR1_DISCNUM
- ,
- ADC_REG_InitStruct->SequencerLength
- | ADC_REG_InitStruct->SequencerDiscont
- );
- }
- else
- {
- MODIFY_REG(ADCx->CR1,
- ADC_CR1_DISCEN
- | ADC_CR1_DISCNUM
- ,
- ADC_REG_InitStruct->SequencerLength
- | LL_ADC_REG_SEQ_DISCONT_DISABLE
- );
- }
-
- MODIFY_REG(ADCx->CR2,
- ADC_CR2_EXTSEL
- | ADC_CR2_CONT
- | ADC_CR2_DMA
- ,
- ADC_REG_InitStruct->TriggerSource
- | ADC_REG_InitStruct->ContinuousMode
- | ADC_REG_InitStruct->DMATransfer
- );
-
- /* Set ADC group regular sequencer length and scan direction */
- /* Note: Hardware constraint (refer to description of this function): */
- /* Note: If ADC instance feature scan mode is disabled */
- /* (refer to ADC instance initialization structure */
- /* parameter @ref SequencersScanMode */
- /* or function @ref LL_ADC_SetSequencersScanMode() ), */
- /* this parameter is discarded. */
- LL_ADC_REG_SetSequencerLength(ADCx, ADC_REG_InitStruct->SequencerLength);
- }
- else
- {
- /* Initialization error: ADC instance is not disabled. */
- status = ERROR;
- }
- return status;
-}
-
-/**
- * @brief Set each @ref LL_ADC_REG_InitTypeDef field to default value.
- * @param ADC_REG_InitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure
- * whose fields will be set to default values.
- * @retval None
- */
-void LL_ADC_REG_StructInit(LL_ADC_REG_InitTypeDef *ADC_REG_InitStruct)
-{
- /* Set ADC_REG_InitStruct fields to default values */
- /* Set fields of ADC group regular */
- /* Note: On this STM32 serie, ADC trigger edge is set when starting */
- /* ADC conversion. */
- /* Refer to function @ref LL_ADC_REG_StartConversionExtTrig(). */
- ADC_REG_InitStruct->TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;
- ADC_REG_InitStruct->SequencerLength = LL_ADC_REG_SEQ_SCAN_DISABLE;
- ADC_REG_InitStruct->SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
- ADC_REG_InitStruct->ContinuousMode = LL_ADC_REG_CONV_SINGLE;
- ADC_REG_InitStruct->DMATransfer = LL_ADC_REG_DMA_TRANSFER_NONE;
-}
-
-/**
- * @brief Initialize some features of ADC group injected.
- * @note These parameters have an impact on ADC scope: ADC group injected.
- * Refer to corresponding unitary functions into
- * @ref ADC_LL_EF_Configuration_ADC_Group_Regular
- * (functions with prefix "INJ").
- * @note The setting of these parameters by function @ref LL_ADC_Init()
- * is conditioned to ADC state:
- * ADC instance must be disabled.
- * This condition is applied to all ADC features, for efficiency
- * and compatibility over all STM32 families. However, the different
- * features can be set under different ADC state conditions
- * (setting possible with ADC enabled without conversion on going,
- * ADC enabled with conversion on going, ...)
- * Each feature can be updated afterwards with a unitary function
- * and potentially with ADC in a different state than disabled,
- * refer to description of each function for setting
- * conditioned to ADC state.
- * @note After using this function, other features must be configured
- * using LL unitary functions.
- * The minimum configuration remaining to be done is:
- * - Set ADC group injected sequencer:
- * map channel on the selected sequencer rank.
- * Refer to function @ref LL_ADC_INJ_SetSequencerRanks().
- * - Set ADC channel sampling time
- * Refer to function LL_ADC_SetChannelSamplingTime();
- * @param ADCx ADC instance
- * @param ADC_INJ_InitStruct Pointer to a @ref LL_ADC_INJ_InitTypeDef structure
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: ADC registers are initialized
- * - ERROR: ADC registers are not initialized
- */
-ErrorStatus LL_ADC_INJ_Init(ADC_TypeDef *ADCx, LL_ADC_INJ_InitTypeDef *ADC_INJ_InitStruct)
-{
- ErrorStatus status = SUCCESS;
-
- /* Check the parameters */
- assert_param(IS_ADC_ALL_INSTANCE(ADCx));
-#if defined(ADC3)
- assert_param(IS_LL_ADC_INJ_TRIG_SOURCE(ADCx, ADC_INJ_InitStruct->TriggerSource));
-#else
- assert_param(IS_LL_ADC_INJ_TRIG_SOURCE(ADC_INJ_InitStruct->TriggerSource));
-#endif
- assert_param(IS_LL_ADC_INJ_SEQ_SCAN_LENGTH(ADC_INJ_InitStruct->SequencerLength));
- if(ADC_INJ_InitStruct->SequencerLength != LL_ADC_INJ_SEQ_SCAN_DISABLE)
- {
- assert_param(IS_LL_ADC_INJ_SEQ_SCAN_DISCONT_MODE(ADC_INJ_InitStruct->SequencerDiscont));
- }
- assert_param(IS_LL_ADC_INJ_TRIG_AUTO(ADC_INJ_InitStruct->TrigAuto));
-
- /* Note: Hardware constraint (refer to description of this function): */
- /* ADC instance must be disabled. */
- if(LL_ADC_IsEnabled(ADCx) == 0U)
- {
- /* Configuration of ADC hierarchical scope: */
- /* - ADC group injected */
- /* - Set ADC group injected trigger source */
- /* - Set ADC group injected sequencer length */
- /* - Set ADC group injected sequencer discontinuous mode */
- /* - Set ADC group injected conversion trigger: independent or */
- /* from ADC group regular */
- /* Note: On this STM32 serie, ADC trigger edge is set when starting */
- /* ADC conversion. */
- /* Refer to function @ref LL_ADC_INJ_StartConversionExtTrig(). */
- if(ADC_INJ_InitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE)
- {
- MODIFY_REG(ADCx->CR1,
- ADC_CR1_JDISCEN
- | ADC_CR1_JAUTO
- ,
- ADC_INJ_InitStruct->SequencerDiscont
- | ADC_INJ_InitStruct->TrigAuto
- );
- }
- else
- {
- MODIFY_REG(ADCx->CR1,
- ADC_CR1_JDISCEN
- | ADC_CR1_JAUTO
- ,
- LL_ADC_REG_SEQ_DISCONT_DISABLE
- | ADC_INJ_InitStruct->TrigAuto
- );
- }
-
- MODIFY_REG(ADCx->CR2,
- ADC_CR2_JEXTSEL
- ,
- ADC_INJ_InitStruct->TriggerSource
- );
-
- /* Note: Hardware constraint (refer to description of this function): */
- /* Note: If ADC instance feature scan mode is disabled */
- /* (refer to ADC instance initialization structure */
- /* parameter @ref SequencersScanMode */
- /* or function @ref LL_ADC_SetSequencersScanMode() ), */
- /* this parameter is discarded. */
- LL_ADC_INJ_SetSequencerLength(ADCx, ADC_INJ_InitStruct->SequencerLength);
- }
- else
- {
- /* Initialization error: ADC instance is not disabled. */
- status = ERROR;
- }
- return status;
-}
-
-/**
- * @brief Set each @ref LL_ADC_INJ_InitTypeDef field to default value.
- * @param ADC_INJ_InitStruct Pointer to a @ref LL_ADC_INJ_InitTypeDef structure
- * whose fields will be set to default values.
- * @retval None
- */
-void LL_ADC_INJ_StructInit(LL_ADC_INJ_InitTypeDef *ADC_INJ_InitStruct)
-{
- /* Set ADC_INJ_InitStruct fields to default values */
- /* Set fields of ADC group injected */
- ADC_INJ_InitStruct->TriggerSource = LL_ADC_INJ_TRIG_SOFTWARE;
- ADC_INJ_InitStruct->SequencerLength = LL_ADC_INJ_SEQ_SCAN_DISABLE;
- ADC_INJ_InitStruct->SequencerDiscont = LL_ADC_INJ_SEQ_DISCONT_DISABLE;
- ADC_INJ_InitStruct->TrigAuto = LL_ADC_INJ_TRIG_INDEPENDENT;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* ADC1 || ADC2 || ADC3 */
-
-/**
- * @}
- */
-
-#endif /* USE_FULL_LL_DRIVER */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_crc.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_crc.c
deleted file mode 100644
index 11eb7d9..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_crc.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_crc.c
- * @author MCD Application Team
- * @brief CRC LL module driver.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-#if defined(USE_FULL_LL_DRIVER)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_crc.h"
-#include "stm32f1xx_ll_bus.h"
-
-#ifdef USE_FULL_ASSERT
-#include "stm32_assert.h"
-#else
-#define assert_param(expr) ((void)0U)
-#endif
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined (CRC)
-
-/** @addtogroup CRC_LL
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup CRC_LL_Exported_Functions
- * @{
- */
-
-/** @addtogroup CRC_LL_EF_Init
- * @{
- */
-
-/**
- * @brief De-initialize CRC registers (Registers restored to their default values).
- * @param CRCx CRC Instance
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: CRC registers are de-initialized
- * - ERROR: CRC registers are not de-initialized
- */
-ErrorStatus LL_CRC_DeInit(CRC_TypeDef *CRCx)
-{
- ErrorStatus status = SUCCESS;
-
- /* Check the parameters */
- assert_param(IS_CRC_ALL_INSTANCE(CRCx));
-
- if (CRCx == CRC)
- {
-
- /* Reset the CRC calculation unit */
- LL_CRC_ResetCRCCalculationUnit(CRCx);
-
- /* Reset IDR register */
- LL_CRC_Write_IDR(CRCx, 0x00U);
- }
- else
- {
- status = ERROR;
- }
-
- return (status);
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* defined (CRC) */
-
-/**
- * @}
- */
-
-#endif /* USE_FULL_LL_DRIVER */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_dac.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_dac.c
deleted file mode 100644
index 5aa0d05..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_dac.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_dac.c
- * @author MCD Application Team
- * @brief DAC LL module driver
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-#if defined(USE_FULL_LL_DRIVER)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_dac.h"
-#include "stm32f1xx_ll_bus.h"
-
-#ifdef USE_FULL_ASSERT
- #include "stm32_assert.h"
-#else
- #define assert_param(expr) ((void)0U)
-#endif
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined (DAC)
-
-/** @addtogroup DAC_LL DAC
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-
-/** @addtogroup DAC_LL_Private_Macros
- * @{
- */
-
-#define IS_LL_DAC_CHANNEL(__DACX__, __DAC_CHANNEL__) \
- ( \
- ((__DAC_CHANNEL__) == LL_DAC_CHANNEL_1) \
- || ((__DAC_CHANNEL__) == LL_DAC_CHANNEL_2) \
- )
-
-#define IS_LL_DAC_TRIGGER_SOURCE(__TRIGGER_SOURCE__) \
- ( ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_SOFTWARE) \
- || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM3_TRGO) \
- || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM15_TRGO) \
- || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM2_TRGO) \
- || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM4_TRGO) \
- || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM5_TRGO) \
- || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM6_TRGO) \
- || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM7_TRGO) \
- || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM8_TRGO) \
- || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_EXTI_LINE9) \
- )
-#define IS_LL_DAC_WAVE_AUTO_GENER_MODE(__WAVE_AUTO_GENERATION_MODE__) \
- ( ((__WAVE_AUTO_GENERATION_MODE__) == LL_DAC_WAVE_AUTO_GENERATION_NONE) \
- || ((__WAVE_AUTO_GENERATION_MODE__) == LL_DAC_WAVE_AUTO_GENERATION_NOISE) \
- || ((__WAVE_AUTO_GENERATION_MODE__) == LL_DAC_WAVE_AUTO_GENERATION_TRIANGLE) \
- )
-
-#define IS_LL_DAC_WAVE_AUTO_GENER_CONFIG(__WAVE_AUTO_GENERATION_CONFIG__) \
- ( ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BIT0) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS1_0) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS2_0) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS3_0) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS4_0) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS5_0) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS6_0) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS7_0) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS8_0) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS9_0) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS10_0) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS11_0) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_1) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_3) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_7) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_15) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_31) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_63) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_127) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_255) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_511) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_1023) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_2047) \
- || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_4095) \
- )
-
-#define IS_LL_DAC_OUTPUT_BUFFER(__OUTPUT_BUFFER__) \
- ( ((__OUTPUT_BUFFER__) == LL_DAC_OUTPUT_BUFFER_ENABLE) \
- || ((__OUTPUT_BUFFER__) == LL_DAC_OUTPUT_BUFFER_DISABLE) \
- )
-
-/**
- * @}
- */
-
-
-/* Private function prototypes -----------------------------------------------*/
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup DAC_LL_Exported_Functions
- * @{
- */
-
-/** @addtogroup DAC_LL_EF_Init
- * @{
- */
-
-/**
- * @brief De-initialize registers of the selected DAC instance
- * to their default reset values.
- * @param DACx DAC instance
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: DAC registers are de-initialized
- * - ERROR: not applicable
- */
-ErrorStatus LL_DAC_DeInit(DAC_TypeDef *DACx)
-{
- /* Check the parameters */
- assert_param(IS_DAC_ALL_INSTANCE(DACx));
-
- /* Force reset of DAC1 clock */
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_DAC1);
-
- /* Release reset of DAC1 clock */
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_DAC1);
- return SUCCESS;
-}
-
-/**
- * @brief Initialize some features of DAC instance.
- * @note The setting of these parameters by function @ref LL_DAC_Init()
- * is conditioned to DAC state:
- * DAC instance must be disabled.
- * @param DACx DAC instance
- * @param DAC_Channel This parameter can be one of the following values:
- * @arg @ref LL_DAC_CHANNEL_1
- * @arg @ref LL_DAC_CHANNEL_2
- * @param DAC_InitStruct Pointer to a @ref LL_DAC_InitTypeDef structure
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: DAC registers are initialized
- * - ERROR: DAC registers are not initialized
- */
-ErrorStatus LL_DAC_Init(DAC_TypeDef *DACx, uint32_t DAC_Channel, LL_DAC_InitTypeDef *DAC_InitStruct)
-{
- ErrorStatus status = SUCCESS;
-
- /* Check the parameters */
- assert_param(IS_DAC_ALL_INSTANCE(DACx));
- assert_param(IS_LL_DAC_CHANNEL(DACx, DAC_Channel));
- assert_param(IS_LL_DAC_TRIGGER_SOURCE(DAC_InitStruct->TriggerSource));
- assert_param(IS_LL_DAC_OUTPUT_BUFFER(DAC_InitStruct->OutputBuffer));
- assert_param(IS_LL_DAC_WAVE_AUTO_GENER_MODE(DAC_InitStruct->WaveAutoGeneration));
- if (DAC_InitStruct->WaveAutoGeneration != LL_DAC_WAVE_AUTO_GENERATION_NONE)
- {
- assert_param(IS_LL_DAC_WAVE_AUTO_GENER_CONFIG(DAC_InitStruct->WaveAutoGenerationConfig));
- }
-
- /* Note: Hardware constraint (refer to description of this function) */
- /* DAC instance must be disabled. */
- if(LL_DAC_IsEnabled(DACx, DAC_Channel) == 0U)
- {
- /* Configuration of DAC channel: */
- /* - TriggerSource */
- /* - WaveAutoGeneration */
- /* - OutputBuffer */
- if (DAC_InitStruct->WaveAutoGeneration != LL_DAC_WAVE_AUTO_GENERATION_NONE)
- {
- MODIFY_REG(DACx->CR,
- ( DAC_CR_TSEL1
- | DAC_CR_WAVE1
- | DAC_CR_MAMP1
- | DAC_CR_BOFF1
- ) << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)
- ,
- ( DAC_InitStruct->TriggerSource
- | DAC_InitStruct->WaveAutoGeneration
- | DAC_InitStruct->WaveAutoGenerationConfig
- | DAC_InitStruct->OutputBuffer
- ) << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)
- );
- }
- else
- {
- MODIFY_REG(DACx->CR,
- ( DAC_CR_TSEL1
- | DAC_CR_WAVE1
- | DAC_CR_BOFF1
- ) << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)
- ,
- ( DAC_InitStruct->TriggerSource
- | LL_DAC_WAVE_AUTO_GENERATION_NONE
- | DAC_InitStruct->OutputBuffer
- ) << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)
- );
- }
- }
- else
- {
- /* Initialization error: DAC instance is not disabled. */
- status = ERROR;
- }
- return status;
-}
-
-/**
- * @brief Set each @ref LL_DAC_InitTypeDef field to default value.
- * @param DAC_InitStruct pointer to a @ref LL_DAC_InitTypeDef structure
- * whose fields will be set to default values.
- * @retval None
- */
-void LL_DAC_StructInit(LL_DAC_InitTypeDef *DAC_InitStruct)
-{
- /* Set DAC_InitStruct fields to default values */
- DAC_InitStruct->TriggerSource = LL_DAC_TRIG_SOFTWARE;
- DAC_InitStruct->WaveAutoGeneration = LL_DAC_WAVE_AUTO_GENERATION_NONE;
- /* Note: Parameter discarded if wave auto generation is disabled, */
- /* set anyway to its default value. */
- DAC_InitStruct->WaveAutoGenerationConfig = LL_DAC_NOISE_LFSR_UNMASK_BIT0;
- DAC_InitStruct->OutputBuffer = LL_DAC_OUTPUT_BUFFER_ENABLE;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* DAC */
-
-/**
- * @}
- */
-
-#endif /* USE_FULL_LL_DRIVER */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_dma.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_dma.c
deleted file mode 100644
index f07c23c..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_dma.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_dma.c
- * @author MCD Application Team
- * @brief DMA LL module driver.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-#if defined(USE_FULL_LL_DRIVER)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_dma.h"
-#include "stm32f1xx_ll_bus.h"
-#ifdef USE_FULL_ASSERT
-#include "stm32_assert.h"
-#else
-#define assert_param(expr) ((void)0U)
-#endif
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined (DMA1) || defined (DMA2)
-
-/** @defgroup DMA_LL DMA
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-/** @addtogroup DMA_LL_Private_Macros
- * @{
- */
-#define IS_LL_DMA_DIRECTION(__VALUE__) (((__VALUE__) == LL_DMA_DIRECTION_PERIPH_TO_MEMORY) || \
- ((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_PERIPH) || \
- ((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_MEMORY))
-
-#define IS_LL_DMA_MODE(__VALUE__) (((__VALUE__) == LL_DMA_MODE_NORMAL) || \
- ((__VALUE__) == LL_DMA_MODE_CIRCULAR))
-
-#define IS_LL_DMA_PERIPHINCMODE(__VALUE__) (((__VALUE__) == LL_DMA_PERIPH_INCREMENT) || \
- ((__VALUE__) == LL_DMA_PERIPH_NOINCREMENT))
-
-#define IS_LL_DMA_MEMORYINCMODE(__VALUE__) (((__VALUE__) == LL_DMA_MEMORY_INCREMENT) || \
- ((__VALUE__) == LL_DMA_MEMORY_NOINCREMENT))
-
-#define IS_LL_DMA_PERIPHDATASIZE(__VALUE__) (((__VALUE__) == LL_DMA_PDATAALIGN_BYTE) || \
- ((__VALUE__) == LL_DMA_PDATAALIGN_HALFWORD) || \
- ((__VALUE__) == LL_DMA_PDATAALIGN_WORD))
-
-#define IS_LL_DMA_MEMORYDATASIZE(__VALUE__) (((__VALUE__) == LL_DMA_MDATAALIGN_BYTE) || \
- ((__VALUE__) == LL_DMA_MDATAALIGN_HALFWORD) || \
- ((__VALUE__) == LL_DMA_MDATAALIGN_WORD))
-
-#define IS_LL_DMA_NBDATA(__VALUE__) ((__VALUE__) <= 0x0000FFFFU)
-
-#define IS_LL_DMA_PRIORITY(__VALUE__) (((__VALUE__) == LL_DMA_PRIORITY_LOW) || \
- ((__VALUE__) == LL_DMA_PRIORITY_MEDIUM) || \
- ((__VALUE__) == LL_DMA_PRIORITY_HIGH) || \
- ((__VALUE__) == LL_DMA_PRIORITY_VERYHIGH))
-
-#if defined (DMA2)
-#define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL) ((((INSTANCE) == DMA1) && \
- (((CHANNEL) == LL_DMA_CHANNEL_1) || \
- ((CHANNEL) == LL_DMA_CHANNEL_2) || \
- ((CHANNEL) == LL_DMA_CHANNEL_3) || \
- ((CHANNEL) == LL_DMA_CHANNEL_4) || \
- ((CHANNEL) == LL_DMA_CHANNEL_5) || \
- ((CHANNEL) == LL_DMA_CHANNEL_6) || \
- ((CHANNEL) == LL_DMA_CHANNEL_7))) || \
- (((INSTANCE) == DMA2) && \
- (((CHANNEL) == LL_DMA_CHANNEL_1) || \
- ((CHANNEL) == LL_DMA_CHANNEL_2) || \
- ((CHANNEL) == LL_DMA_CHANNEL_3) || \
- ((CHANNEL) == LL_DMA_CHANNEL_4) || \
- ((CHANNEL) == LL_DMA_CHANNEL_5))))
-#else
-#define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL) ((((INSTANCE) == DMA1) && \
- (((CHANNEL) == LL_DMA_CHANNEL_1) || \
- ((CHANNEL) == LL_DMA_CHANNEL_2) || \
- ((CHANNEL) == LL_DMA_CHANNEL_3) || \
- ((CHANNEL) == LL_DMA_CHANNEL_4) || \
- ((CHANNEL) == LL_DMA_CHANNEL_5) || \
- ((CHANNEL) == LL_DMA_CHANNEL_6) || \
- ((CHANNEL) == LL_DMA_CHANNEL_7))))
-#endif
-/**
- * @}
- */
-
-/* Private function prototypes -----------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup DMA_LL_Exported_Functions
- * @{
- */
-
-/** @addtogroup DMA_LL_EF_Init
- * @{
- */
-
-/**
- * @brief De-initialize the DMA registers to their default reset values.
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: DMA registers are de-initialized
- * - ERROR: DMA registers are not de-initialized
- */
-uint32_t LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Channel)
-{
- DMA_Channel_TypeDef *tmp = (DMA_Channel_TypeDef *)DMA1_Channel1;
- ErrorStatus status = SUCCESS;
-
- /* Check the DMA Instance DMAx and Channel parameters*/
- assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel));
-
- tmp = (DMA_Channel_TypeDef *)(__LL_DMA_GET_CHANNEL_INSTANCE(DMAx, Channel));
-
- /* Disable the selected DMAx_Channely */
- CLEAR_BIT(tmp->CCR, DMA_CCR_EN);
-
- /* Reset DMAx_Channely control register */
- LL_DMA_WriteReg(tmp, CCR, 0U);
-
- /* Reset DMAx_Channely remaining bytes register */
- LL_DMA_WriteReg(tmp, CNDTR, 0U);
-
- /* Reset DMAx_Channely peripheral address register */
- LL_DMA_WriteReg(tmp, CPAR, 0U);
-
- /* Reset DMAx_Channely memory address register */
- LL_DMA_WriteReg(tmp, CMAR, 0U);
-
- if (Channel == LL_DMA_CHANNEL_1)
- {
- /* Reset interrupt pending bits for DMAx Channel1 */
- LL_DMA_ClearFlag_GI1(DMAx);
- }
- else if (Channel == LL_DMA_CHANNEL_2)
- {
- /* Reset interrupt pending bits for DMAx Channel2 */
- LL_DMA_ClearFlag_GI2(DMAx);
- }
- else if (Channel == LL_DMA_CHANNEL_3)
- {
- /* Reset interrupt pending bits for DMAx Channel3 */
- LL_DMA_ClearFlag_GI3(DMAx);
- }
- else if (Channel == LL_DMA_CHANNEL_4)
- {
- /* Reset interrupt pending bits for DMAx Channel4 */
- LL_DMA_ClearFlag_GI4(DMAx);
- }
- else if (Channel == LL_DMA_CHANNEL_5)
- {
- /* Reset interrupt pending bits for DMAx Channel5 */
- LL_DMA_ClearFlag_GI5(DMAx);
- }
-
- else if (Channel == LL_DMA_CHANNEL_6)
- {
- /* Reset interrupt pending bits for DMAx Channel6 */
- LL_DMA_ClearFlag_GI6(DMAx);
- }
- else if (Channel == LL_DMA_CHANNEL_7)
- {
- /* Reset interrupt pending bits for DMAx Channel7 */
- LL_DMA_ClearFlag_GI7(DMAx);
- }
- else
- {
- status = ERROR;
- }
-
- return status;
-}
-
-/**
- * @brief Initialize the DMA registers according to the specified parameters in DMA_InitStruct.
- * @note To convert DMAx_Channely Instance to DMAx Instance and Channely, use helper macros :
- * @arg @ref __LL_DMA_GET_INSTANCE
- * @arg @ref __LL_DMA_GET_CHANNEL
- * @param DMAx DMAx Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_DMA_CHANNEL_1
- * @arg @ref LL_DMA_CHANNEL_2
- * @arg @ref LL_DMA_CHANNEL_3
- * @arg @ref LL_DMA_CHANNEL_4
- * @arg @ref LL_DMA_CHANNEL_5
- * @arg @ref LL_DMA_CHANNEL_6
- * @arg @ref LL_DMA_CHANNEL_7
- * @param DMA_InitStruct pointer to a @ref LL_DMA_InitTypeDef structure.
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: DMA registers are initialized
- * - ERROR: Not applicable
- */
-uint32_t LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Channel, LL_DMA_InitTypeDef *DMA_InitStruct)
-{
- /* Check the DMA Instance DMAx and Channel parameters*/
- assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel));
-
- /* Check the DMA parameters from DMA_InitStruct */
- assert_param(IS_LL_DMA_DIRECTION(DMA_InitStruct->Direction));
- assert_param(IS_LL_DMA_MODE(DMA_InitStruct->Mode));
- assert_param(IS_LL_DMA_PERIPHINCMODE(DMA_InitStruct->PeriphOrM2MSrcIncMode));
- assert_param(IS_LL_DMA_MEMORYINCMODE(DMA_InitStruct->MemoryOrM2MDstIncMode));
- assert_param(IS_LL_DMA_PERIPHDATASIZE(DMA_InitStruct->PeriphOrM2MSrcDataSize));
- assert_param(IS_LL_DMA_MEMORYDATASIZE(DMA_InitStruct->MemoryOrM2MDstDataSize));
- assert_param(IS_LL_DMA_NBDATA(DMA_InitStruct->NbData));
- assert_param(IS_LL_DMA_PRIORITY(DMA_InitStruct->Priority));
-
- /*---------------------------- DMAx CCR Configuration ------------------------
- * Configure DMAx_Channely: data transfer direction, data transfer mode,
- * peripheral and memory increment mode,
- * data size alignment and priority level with parameters :
- * - Direction: DMA_CCR_DIR and DMA_CCR_MEM2MEM bits
- * - Mode: DMA_CCR_CIRC bit
- * - PeriphOrM2MSrcIncMode: DMA_CCR_PINC bit
- * - MemoryOrM2MDstIncMode: DMA_CCR_MINC bit
- * - PeriphOrM2MSrcDataSize: DMA_CCR_PSIZE[1:0] bits
- * - MemoryOrM2MDstDataSize: DMA_CCR_MSIZE[1:0] bits
- * - Priority: DMA_CCR_PL[1:0] bits
- */
- LL_DMA_ConfigTransfer(DMAx, Channel, DMA_InitStruct->Direction | \
- DMA_InitStruct->Mode | \
- DMA_InitStruct->PeriphOrM2MSrcIncMode | \
- DMA_InitStruct->MemoryOrM2MDstIncMode | \
- DMA_InitStruct->PeriphOrM2MSrcDataSize | \
- DMA_InitStruct->MemoryOrM2MDstDataSize | \
- DMA_InitStruct->Priority);
-
- /*-------------------------- DMAx CMAR Configuration -------------------------
- * Configure the memory or destination base address with parameter :
- * - MemoryOrM2MDstAddress: DMA_CMAR_MA[31:0] bits
- */
- LL_DMA_SetMemoryAddress(DMAx, Channel, DMA_InitStruct->MemoryOrM2MDstAddress);
-
- /*-------------------------- DMAx CPAR Configuration -------------------------
- * Configure the peripheral or source base address with parameter :
- * - PeriphOrM2MSrcAddress: DMA_CPAR_PA[31:0] bits
- */
- LL_DMA_SetPeriphAddress(DMAx, Channel, DMA_InitStruct->PeriphOrM2MSrcAddress);
-
- /*--------------------------- DMAx CNDTR Configuration -----------------------
- * Configure the peripheral base address with parameter :
- * - NbData: DMA_CNDTR_NDT[15:0] bits
- */
- LL_DMA_SetDataLength(DMAx, Channel, DMA_InitStruct->NbData);
-
- return SUCCESS;
-}
-
-/**
- * @brief Set each @ref LL_DMA_InitTypeDef field to default value.
- * @param DMA_InitStruct Pointer to a @ref LL_DMA_InitTypeDef structure.
- * @retval None
- */
-void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct)
-{
- /* Set DMA_InitStruct fields to default values */
- DMA_InitStruct->PeriphOrM2MSrcAddress = 0x00000000U;
- DMA_InitStruct->MemoryOrM2MDstAddress = 0x00000000U;
- DMA_InitStruct->Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
- DMA_InitStruct->Mode = LL_DMA_MODE_NORMAL;
- DMA_InitStruct->PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
- DMA_InitStruct->MemoryOrM2MDstIncMode = LL_DMA_MEMORY_NOINCREMENT;
- DMA_InitStruct->PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
- DMA_InitStruct->MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
- DMA_InitStruct->NbData = 0x00000000U;
- DMA_InitStruct->Priority = LL_DMA_PRIORITY_LOW;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* DMA1 || DMA2 */
-
-/**
- * @}
- */
-
-#endif /* USE_FULL_LL_DRIVER */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_exti.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_exti.c
deleted file mode 100644
index dacbc3f..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_exti.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_exti.c
- * @author MCD Application Team
- * @brief EXTI LL module driver.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-#if defined(USE_FULL_LL_DRIVER)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_exti.h"
-#ifdef USE_FULL_ASSERT
-#include "stm32_assert.h"
-#else
-#define assert_param(expr) ((void)0U)
-#endif
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined (EXTI)
-
-/** @defgroup EXTI_LL EXTI
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-/** @addtogroup EXTI_LL_Private_Macros
- * @{
- */
-
-#define IS_LL_EXTI_LINE_0_31(__VALUE__) (((__VALUE__) & ~LL_EXTI_LINE_ALL_0_31) == 0x00000000U)
-
-#define IS_LL_EXTI_MODE(__VALUE__) (((__VALUE__) == LL_EXTI_MODE_IT) \
- || ((__VALUE__) == LL_EXTI_MODE_EVENT) \
- || ((__VALUE__) == LL_EXTI_MODE_IT_EVENT))
-
-
-#define IS_LL_EXTI_TRIGGER(__VALUE__) (((__VALUE__) == LL_EXTI_TRIGGER_NONE) \
- || ((__VALUE__) == LL_EXTI_TRIGGER_RISING) \
- || ((__VALUE__) == LL_EXTI_TRIGGER_FALLING) \
- || ((__VALUE__) == LL_EXTI_TRIGGER_RISING_FALLING))
-
-/**
- * @}
- */
-
-/* Private function prototypes -----------------------------------------------*/
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup EXTI_LL_Exported_Functions
- * @{
- */
-
-/** @addtogroup EXTI_LL_EF_Init
- * @{
- */
-
-/**
- * @brief De-initialize the EXTI registers to their default reset values.
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: EXTI registers are de-initialized
- * - ERROR: not applicable
- */
-uint32_t LL_EXTI_DeInit(void)
-{
- /* Interrupt mask register set to default reset values */
- LL_EXTI_WriteReg(IMR, 0x00000000U);
- /* Event mask register set to default reset values */
- LL_EXTI_WriteReg(EMR, 0x00000000U);
- /* Rising Trigger selection register set to default reset values */
- LL_EXTI_WriteReg(RTSR, 0x00000000U);
- /* Falling Trigger selection register set to default reset values */
- LL_EXTI_WriteReg(FTSR, 0x00000000U);
- /* Software interrupt event register set to default reset values */
- LL_EXTI_WriteReg(SWIER, 0x00000000U);
- /* Pending register clear */
- LL_EXTI_WriteReg(PR, 0x000FFFFFU);
-
- return SUCCESS;
-}
-
-/**
- * @brief Initialize the EXTI registers according to the specified parameters in EXTI_InitStruct.
- * @param EXTI_InitStruct pointer to a @ref LL_EXTI_InitTypeDef structure.
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: EXTI registers are initialized
- * - ERROR: not applicable
- */
-uint32_t LL_EXTI_Init(LL_EXTI_InitTypeDef *EXTI_InitStruct)
-{
- ErrorStatus status = SUCCESS;
- /* Check the parameters */
- assert_param(IS_LL_EXTI_LINE_0_31(EXTI_InitStruct->Line_0_31));
- assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->LineCommand));
- assert_param(IS_LL_EXTI_MODE(EXTI_InitStruct->Mode));
-
- /* ENABLE LineCommand */
- if (EXTI_InitStruct->LineCommand != DISABLE)
- {
- assert_param(IS_LL_EXTI_TRIGGER(EXTI_InitStruct->Trigger));
-
- /* Configure EXTI Lines in range from 0 to 31 */
- if (EXTI_InitStruct->Line_0_31 != LL_EXTI_LINE_NONE)
- {
- switch (EXTI_InitStruct->Mode)
- {
- case LL_EXTI_MODE_IT:
- /* First Disable Event on provided Lines */
- LL_EXTI_DisableEvent_0_31(EXTI_InitStruct->Line_0_31);
- /* Then Enable IT on provided Lines */
- LL_EXTI_EnableIT_0_31(EXTI_InitStruct->Line_0_31);
- break;
- case LL_EXTI_MODE_EVENT:
- /* First Disable IT on provided Lines */
- LL_EXTI_DisableIT_0_31(EXTI_InitStruct->Line_0_31);
- /* Then Enable Event on provided Lines */
- LL_EXTI_EnableEvent_0_31(EXTI_InitStruct->Line_0_31);
- break;
- case LL_EXTI_MODE_IT_EVENT:
- /* Directly Enable IT & Event on provided Lines */
- LL_EXTI_EnableIT_0_31(EXTI_InitStruct->Line_0_31);
- LL_EXTI_EnableEvent_0_31(EXTI_InitStruct->Line_0_31);
- break;
- default:
- status = ERROR;
- break;
- }
- if (EXTI_InitStruct->Trigger != LL_EXTI_TRIGGER_NONE)
- {
- switch (EXTI_InitStruct->Trigger)
- {
- case LL_EXTI_TRIGGER_RISING:
- /* First Disable Falling Trigger on provided Lines */
- LL_EXTI_DisableFallingTrig_0_31(EXTI_InitStruct->Line_0_31);
- /* Then Enable Rising Trigger on provided Lines */
- LL_EXTI_EnableRisingTrig_0_31(EXTI_InitStruct->Line_0_31);
- break;
- case LL_EXTI_TRIGGER_FALLING:
- /* First Disable Rising Trigger on provided Lines */
- LL_EXTI_DisableRisingTrig_0_31(EXTI_InitStruct->Line_0_31);
- /* Then Enable Falling Trigger on provided Lines */
- LL_EXTI_EnableFallingTrig_0_31(EXTI_InitStruct->Line_0_31);
- break;
- case LL_EXTI_TRIGGER_RISING_FALLING:
- LL_EXTI_EnableRisingTrig_0_31(EXTI_InitStruct->Line_0_31);
- LL_EXTI_EnableFallingTrig_0_31(EXTI_InitStruct->Line_0_31);
- break;
- default:
- status = ERROR;
- break;
- }
- }
- }
- }
- /* DISABLE LineCommand */
- else
- {
- /* De-configure EXTI Lines in range from 0 to 31 */
- LL_EXTI_DisableIT_0_31(EXTI_InitStruct->Line_0_31);
- LL_EXTI_DisableEvent_0_31(EXTI_InitStruct->Line_0_31);
- }
- return status;
-}
-
-/**
- * @brief Set each @ref LL_EXTI_InitTypeDef field to default value.
- * @param EXTI_InitStruct Pointer to a @ref LL_EXTI_InitTypeDef structure.
- * @retval None
- */
-void LL_EXTI_StructInit(LL_EXTI_InitTypeDef *EXTI_InitStruct)
-{
- EXTI_InitStruct->Line_0_31 = LL_EXTI_LINE_NONE;
- EXTI_InitStruct->LineCommand = DISABLE;
- EXTI_InitStruct->Mode = LL_EXTI_MODE_IT;
- EXTI_InitStruct->Trigger = LL_EXTI_TRIGGER_FALLING;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* defined (EXTI) */
-
-/**
- * @}
- */
-
-#endif /* USE_FULL_LL_DRIVER */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_fsmc.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_fsmc.c
deleted file mode 100644
index 3edbdf3..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_fsmc.c
+++ /dev/null
@@ -1,929 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_fsmc.c
- * @author MCD Application Team
- * @brief FSMC Low Layer HAL module driver.
- *
- * This file provides firmware functions to manage the following
- * functionalities of the Flexible Static Memory Controller (FSMC) peripheral memories:
- * + Initialization/de-initialization functions
- * + Peripheral Control functions
- * + Peripheral State functions
- *
- @verbatim
- =============================================================================
- ##### FSMC peripheral features #####
- =============================================================================
- [..] The Flexible static memory controller (FSMC) includes following memory controllers:
- (+) The NOR/PSRAM memory controller
- (+) The PC Card memory controller
- (+) The NAND memory controller
- (PC Card and NAND controllers available only on STM32F101xE, STM32F103xE, STM32F101xG and STM32F103xG)
-
- [..] The FSMC functional block makes the interface with synchronous and asynchronous static
- memories and 16-bit PC memory cards. Its main purposes are:
- (+) to translate AHB transactions into the appropriate external device protocol.
- (+) to meet the access time requirements of the external memory devices.
-
- [..] All external memories share the addresses, data and control signals with the controller.
- Each external device is accessed by means of a unique Chip Select. The FSMC performs
- only one access at a time to an external device.
- The main features of the FSMC controller are the following:
- (+) Interface with static-memory mapped devices including:
- (++) Static random access memory (SRAM).
- (++) NOR Flash memory.
- (++) PSRAM (4 memory banks).
- (++) 16-bit PC Card compatible devices.
- (++) Two banks of NAND Flash memory with ECC hardware to check up to 8 Kbytes of
- data.
- (+) Independent Chip Select control for each memory bank.
- (+) Independent configuration for each memory bank.
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-#if defined(FSMC_BANK1)
-
-#if defined(HAL_SRAM_MODULE_ENABLED) || defined(HAL_NOR_MODULE_ENABLED) || defined(HAL_PCCARD_MODULE_ENABLED) || defined(HAL_NAND_MODULE_ENABLED)
-
-/** @defgroup FSMC_LL FSMC Low Layer
- * @brief FSMC driver modules
- * @{
- */
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-
-/** @defgroup FSMC_LL_Exported_Functions FSMC Low Layer Exported Functions
- * @{
- */
-
-/** @defgroup FSMC_NORSRAM FSMC NORSRAM Controller functions
- * @brief NORSRAM Controller functions
- *
- @verbatim
- ==============================================================================
- ##### How to use NORSRAM device driver #####
- ==============================================================================
-
- [..]
- This driver contains a set of APIs to interface with the FSMC NORSRAM banks in order
- to run the NORSRAM external devices.
-
- (+) FSMC NORSRAM bank reset using the function FSMC_NORSRAM_DeInit()
- (+) FSMC NORSRAM bank control configuration using the function FSMC_NORSRAM_Init()
- (+) FSMC NORSRAM bank timing configuration using the function FSMC_NORSRAM_Timing_Init()
- (+) FSMC NORSRAM bank extended timing configuration using the function
- FSMC_NORSRAM_Extended_Timing_Init()
- (+) FSMC NORSRAM bank enable/disable write operation using the functions
- FSMC_NORSRAM_WriteOperation_Enable()/FSMC_NORSRAM_WriteOperation_Disable()
-
-@endverbatim
- * @{
- */
-
-/** @addtogroup FSMC_LL_NORSRAM_Private_Functions_Group1
- * @brief Initialization and Configuration functions
- *
- @verbatim
- ==============================================================================
- ##### Initialization and de_initialization functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to:
- (+) Initialize and configure the FSMC NORSRAM interface
- (+) De-initialize the FSMC NORSRAM interface
- (+) Configure the FSMC clock and associated GPIOs
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initialize the FSMC_NORSRAM device according to the specified
- * control parameters in the FSMC_NORSRAM_InitTypeDef
- * @param Device: Pointer to NORSRAM device instance
- * @param Init: Pointer to NORSRAM Initialization structure
- * @retval HAL status
- */
-HAL_StatusTypeDef FSMC_NORSRAM_Init(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_InitTypeDef *Init)
-{
- /* Check the parameters */
- assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
- assert_param(IS_FSMC_NORSRAM_BANK(Init->NSBank));
- assert_param(IS_FSMC_MUX(Init->DataAddressMux));
- assert_param(IS_FSMC_MEMORY(Init->MemoryType));
- assert_param(IS_FSMC_NORSRAM_MEMORY_WIDTH(Init->MemoryDataWidth));
- assert_param(IS_FSMC_BURSTMODE(Init->BurstAccessMode));
- assert_param(IS_FSMC_WAIT_POLARITY(Init->WaitSignalPolarity));
- assert_param(IS_FSMC_WRAP_MODE(Init->WrapMode));
- assert_param(IS_FSMC_WAIT_SIGNAL_ACTIVE(Init->WaitSignalActive));
- assert_param(IS_FSMC_WRITE_OPERATION(Init->WriteOperation));
- assert_param(IS_FSMC_WAITE_SIGNAL(Init->WaitSignal));
- assert_param(IS_FSMC_EXTENDED_MODE(Init->ExtendedMode));
- assert_param(IS_FSMC_ASYNWAIT(Init->AsynchronousWait));
- assert_param(IS_FSMC_WRITE_BURST(Init->WriteBurst));
-
- /* Disable NORSRAM Device */
- __FSMC_NORSRAM_DISABLE(Device, Init->NSBank);
-
- /* Set NORSRAM device control parameters */
- if (Init->MemoryType == FSMC_MEMORY_TYPE_NOR)
- {
- MODIFY_REG(Device->BTCR[Init->NSBank], BCR_CLEAR_MASK, (uint32_t)(FSMC_NORSRAM_FLASH_ACCESS_ENABLE
- | Init->DataAddressMux
- | Init->MemoryType
- | Init->MemoryDataWidth
- | Init->BurstAccessMode
- | Init->WaitSignalPolarity
- | Init->WrapMode
- | Init->WaitSignalActive
- | Init->WriteOperation
- | Init->WaitSignal
- | Init->ExtendedMode
- | Init->AsynchronousWait
- | Init->WriteBurst
- )
- );
- }
- else
- {
- MODIFY_REG(Device->BTCR[Init->NSBank], BCR_CLEAR_MASK, (uint32_t)(FSMC_NORSRAM_FLASH_ACCESS_DISABLE
- | Init->DataAddressMux
- | Init->MemoryType
- | Init->MemoryDataWidth
- | Init->BurstAccessMode
- | Init->WaitSignalPolarity
- | Init->WrapMode
- | Init->WaitSignalActive
- | Init->WriteOperation
- | Init->WaitSignal
- | Init->ExtendedMode
- | Init->AsynchronousWait
- | Init->WriteBurst
- )
- );
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief DeInitialize the FSMC_NORSRAM peripheral
- * @param Device: Pointer to NORSRAM device instance
- * @param ExDevice: Pointer to NORSRAM extended mode device instance
- * @param Bank: NORSRAM bank number
- * @retval HAL status
- */
-HAL_StatusTypeDef FSMC_NORSRAM_DeInit(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank)
-{
- /* Check the parameters */
- assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
- assert_param(IS_FSMC_NORSRAM_EXTENDED_DEVICE(ExDevice));
- assert_param(IS_FSMC_NORSRAM_BANK(Bank));
-
- /* Disable the FSMC_NORSRAM device */
- __FSMC_NORSRAM_DISABLE(Device, Bank);
-
- /* De-initialize the FSMC_NORSRAM device */
- /* FSMC_NORSRAM_BANK1 */
- if(Bank == FSMC_NORSRAM_BANK1)
- {
- Device->BTCR[Bank] = 0x000030DBU;
- }
- /* FSMC_NORSRAM_BANK2, FSMC_NORSRAM_BANK3 or FSMC_NORSRAM_BANK4 */
- else
- {
- Device->BTCR[Bank] = 0x000030D2U;
- }
-
- Device->BTCR[Bank + 1U] = 0x0FFFFFFFU;
- ExDevice->BWTR[Bank] = 0x0FFFFFFFU;
-
- return HAL_OK;
-}
-
-
-/**
- * @brief Initialize the FSMC_NORSRAM Timing according to the specified
- * parameters in the FSMC_NORSRAM_TimingTypeDef
- * @param Device: Pointer to NORSRAM device instance
- * @param Timing: Pointer to NORSRAM Timing structure
- * @param Bank: NORSRAM bank number
- * @retval HAL status
- */
-HAL_StatusTypeDef FSMC_NORSRAM_Timing_Init(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank)
-{
- /* Check the parameters */
- assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
- assert_param(IS_FSMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
- assert_param(IS_FSMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
- assert_param(IS_FSMC_DATASETUP_TIME(Timing->DataSetupTime));
- assert_param(IS_FSMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
- assert_param(IS_FSMC_CLK_DIV(Timing->CLKDivision));
- assert_param(IS_FSMC_DATA_LATENCY(Timing->DataLatency));
- assert_param(IS_FSMC_ACCESS_MODE(Timing->AccessMode));
- assert_param(IS_FSMC_NORSRAM_BANK(Bank));
-
- /* Set FSMC_NORSRAM device timing parameters */
- MODIFY_REG(Device->BTCR[Bank + 1U], \
- BTR_CLEAR_MASK, \
- (uint32_t)(Timing->AddressSetupTime | \
- ((Timing->AddressHoldTime) << FSMC_BTRx_ADDHLD_Pos) | \
- ((Timing->DataSetupTime) << FSMC_BTRx_DATAST_Pos) | \
- ((Timing->BusTurnAroundDuration) << FSMC_BTRx_BUSTURN_Pos) | \
- (((Timing->CLKDivision) - 1U) << FSMC_BTRx_CLKDIV_Pos) | \
- (((Timing->DataLatency) - 2U) << FSMC_BTRx_DATLAT_Pos) | \
- (Timing->AccessMode)));
-
- return HAL_OK;
-}
-
-/**
- * @brief Initialize the FSMC_NORSRAM Extended mode Timing according to the specified
- * parameters in the FSMC_NORSRAM_TimingTypeDef
- * @param Device: Pointer to NORSRAM device instance
- * @param Timing: Pointer to NORSRAM Timing structure
- * @param Bank: NORSRAM bank number
- * @param ExtendedMode FSMC Extended Mode
- * This parameter can be one of the following values:
- * @arg FSMC_EXTENDED_MODE_DISABLE
- * @arg FSMC_EXTENDED_MODE_ENABLE
- * @retval HAL status
- */
-HAL_StatusTypeDef FSMC_NORSRAM_Extended_Timing_Init(FSMC_NORSRAM_EXTENDED_TypeDef *Device, FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, uint32_t ExtendedMode)
-{
- /* Check the parameters */
- assert_param(IS_FSMC_EXTENDED_MODE(ExtendedMode));
-
- /* Set NORSRAM device timing register for write configuration, if extended mode is used */
- if(ExtendedMode == FSMC_EXTENDED_MODE_ENABLE)
- {
- /* Check the parameters */
- assert_param(IS_FSMC_NORSRAM_EXTENDED_DEVICE(Device));
- assert_param(IS_FSMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
- assert_param(IS_FSMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
- assert_param(IS_FSMC_DATASETUP_TIME(Timing->DataSetupTime));
-#if defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG)
- assert_param(IS_FSMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
-#else
- assert_param(IS_FSMC_CLK_DIV(Timing->CLKDivision));
- assert_param(IS_FSMC_DATA_LATENCY(Timing->DataLatency));
-#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
- assert_param(IS_FSMC_ACCESS_MODE(Timing->AccessMode));
- assert_param(IS_FSMC_NORSRAM_BANK(Bank));
-
- /* Set NORSRAM device timing register for write configuration, if extended mode is used */
-#if defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG)
- MODIFY_REG(Device->BWTR[Bank], \
- BWTR_CLEAR_MASK, \
- (uint32_t)(Timing->AddressSetupTime | \
- ((Timing->AddressHoldTime) << FSMC_BWTRx_ADDHLD_Pos) | \
- ((Timing->DataSetupTime) << FSMC_BWTRx_DATAST_Pos) | \
- Timing->AccessMode | \
- ((Timing->BusTurnAroundDuration) << FSMC_BWTRx_BUSTURN_Pos)));
-#else
- MODIFY_REG(Device->BWTR[Bank], \
- BWTR_CLEAR_MASK, \
- (uint32_t)(Timing->AddressSetupTime | \
- ((Timing->AddressHoldTime) << FSMC_BWTRx_ADDHLD_Pos) | \
- ((Timing->DataSetupTime) << FSMC_BWTRx_DATAST_Pos) | \
- Timing->AccessMode | \
- (((Timing->CLKDivision) - 1U) << FSMC_BTRx_CLKDIV_Pos) | \
- (((Timing->DataLatency) - 2U) << FSMC_BWTRx_DATLAT_Pos)));
-#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
- }
- else
- {
- Device->BWTR[Bank] = 0x0FFFFFFFU;
- }
-
- return HAL_OK;
-}
-/**
- * @}
- */
-
-/** @defgroup FSMC_NORSRAM_Group2 Control functions
- * @brief management functions
- *
-@verbatim
- ==============================================================================
- ##### FSMC_NORSRAM Control functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to control dynamically
- the FSMC NORSRAM interface.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Enables dynamically FSMC_NORSRAM write operation.
- * @param Device: Pointer to NORSRAM device instance
- * @param Bank: NORSRAM bank number
- * @retval HAL status
- */
-HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Enable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank)
-{
- /* Check the parameters */
- assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
- assert_param(IS_FSMC_NORSRAM_BANK(Bank));
-
- /* Enable write operation */
- SET_BIT(Device->BTCR[Bank], FSMC_WRITE_OPERATION_ENABLE);
-
- return HAL_OK;
-}
-
-/**
- * @brief Disables dynamically FSMC_NORSRAM write operation.
- * @param Device: Pointer to NORSRAM device instance
- * @param Bank: NORSRAM bank number
- * @retval HAL status
- */
-HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Disable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank)
-{
- /* Check the parameters */
- assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
- assert_param(IS_FSMC_NORSRAM_BANK(Bank));
-
- /* Disable write operation */
- CLEAR_BIT(Device->BTCR[Bank], FSMC_WRITE_OPERATION_ENABLE);
-
- return HAL_OK;
-}
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#if (defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
-/** @defgroup FSMC_NAND FSMC NAND Controller functions
- * @brief NAND Controller functions
- *
- @verbatim
- ==============================================================================
- ##### How to use NAND device driver #####
- ==============================================================================
- [..]
- This driver contains a set of APIs to interface with the FSMC NAND banks in order
- to run the NAND external devices.
-
- (+) FSMC NAND bank reset using the function FSMC_NAND_DeInit()
- (+) FSMC NAND bank control configuration using the function FSMC_NAND_Init()
- (+) FSMC NAND bank common space timing configuration using the function
- FSMC_NAND_CommonSpace_Timing_Init()
- (+) FSMC NAND bank attribute space timing configuration using the function
- FSMC_NAND_AttributeSpace_Timing_Init()
- (+) FSMC NAND bank enable/disable ECC correction feature using the functions
- FSMC_NAND_ECC_Enable()/FSMC_NAND_ECC_Disable()
- (+) FSMC NAND bank get ECC correction code using the function FSMC_NAND_GetECC()
-
-@endverbatim
- * @{
- */
-
-/** @defgroup FSMC_NAND_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
- ==============================================================================
- ##### Initialization and de_initialization functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to:
- (+) Initialize and configure the FSMC NAND interface
- (+) De-initialize the FSMC NAND interface
- (+) Configure the FSMC clock and associated GPIOs
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the FSMC_NAND device according to the specified
- * control parameters in the FSMC_NAND_HandleTypeDef
- * @param Device: Pointer to NAND device instance
- * @param Init: Pointer to NAND Initialization structure
- * @retval HAL status
- */
-HAL_StatusTypeDef FSMC_NAND_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_InitTypeDef *Init)
-{
- /* Check the parameters */
- assert_param(IS_FSMC_NAND_DEVICE(Device));
- assert_param(IS_FSMC_NAND_BANK(Init->NandBank));
- assert_param(IS_FSMC_WAIT_FEATURE(Init->Waitfeature));
- assert_param(IS_FSMC_NAND_MEMORY_WIDTH(Init->MemoryDataWidth));
- assert_param(IS_FSMC_ECC_STATE(Init->EccComputation));
- assert_param(IS_FSMC_ECCPAGE_SIZE(Init->ECCPageSize));
- assert_param(IS_FSMC_TCLR_TIME(Init->TCLRSetupTime));
- assert_param(IS_FSMC_TAR_TIME(Init->TARSetupTime));
-
- /* Set NAND device control parameters */
- if (Init->NandBank == FSMC_NAND_BANK2)
- {
- /* NAND bank 2 registers configuration */
- MODIFY_REG(Device->PCR2, PCR_CLEAR_MASK, (Init->Waitfeature |
- FSMC_PCR_MEMORY_TYPE_NAND |
- Init->MemoryDataWidth |
- Init->EccComputation |
- Init->ECCPageSize |
- ((Init->TCLRSetupTime) << FSMC_PCRx_TCLR_Pos) |
- ((Init->TARSetupTime) << FSMC_PCRx_TAR_Pos)));
- }
- else
- {
- /* NAND bank 3 registers configuration */
- MODIFY_REG(Device->PCR3, PCR_CLEAR_MASK, (Init->Waitfeature |
- FSMC_PCR_MEMORY_TYPE_NAND |
- Init->MemoryDataWidth |
- Init->EccComputation |
- Init->ECCPageSize |
- ((Init->TCLRSetupTime) << FSMC_PCRx_TCLR_Pos) |
- ((Init->TARSetupTime) << FSMC_PCRx_TAR_Pos)));
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the FSMC_NAND Common space Timing according to the specified
- * parameters in the FSMC_NAND_PCC_TimingTypeDef
- * @param Device: Pointer to NAND device instance
- * @param Timing: Pointer to NAND timing structure
- * @param Bank: NAND bank number
- * @retval HAL status
- */
-HAL_StatusTypeDef FSMC_NAND_CommonSpace_Timing_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
-{
- /* Check the parameters */
- assert_param(IS_FSMC_NAND_DEVICE(Device));
- assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
- assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
- assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
- assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
- assert_param(IS_FSMC_NAND_BANK(Bank));
-
- /* Set FMC_NAND device timing parameters */
- if(Bank == FSMC_NAND_BANK2)
- {
- /* NAND bank 2 registers configuration */
- MODIFY_REG(Device->PMEM2, PMEM_CLEAR_MASK, (Timing->SetupTime | \
- ((Timing->WaitSetupTime) << FSMC_PMEMx_MEMWAITx_Pos) | \
- ((Timing->HoldSetupTime) << FSMC_PMEMx_MEMHOLDx_Pos) | \
- ((Timing->HiZSetupTime) << FSMC_PMEMx_MEMHIZx_Pos)));
- }
- else
- {
- /* NAND bank 3 registers configuration */
- MODIFY_REG(Device->PMEM3, PMEM_CLEAR_MASK, (Timing->SetupTime | \
- ((Timing->WaitSetupTime) << FSMC_PMEMx_MEMWAITx_Pos) | \
- ((Timing->HoldSetupTime) << FSMC_PMEMx_MEMHOLDx_Pos) | \
- ((Timing->HiZSetupTime) << FSMC_PMEMx_MEMHIZx_Pos)));
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the FSMC_NAND Attribute space Timing according to the specified
- * parameters in the FSMC_NAND_PCC_TimingTypeDef
- * @param Device: Pointer to NAND device instance
- * @param Timing: Pointer to NAND timing structure
- * @param Bank: NAND bank number
- * @retval HAL status
- */
-HAL_StatusTypeDef FSMC_NAND_AttributeSpace_Timing_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
-{
- /* Check the parameters */
- assert_param(IS_FSMC_NAND_DEVICE(Device));
- assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
- assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
- assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
- assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
- assert_param(IS_FSMC_NAND_BANK(Bank));
-
- /* Set FMC_NAND device timing parameters */
- if(Bank == FSMC_NAND_BANK2)
- {
- /* NAND bank 2 registers configuration */
- MODIFY_REG(Device->PATT2, PATT_CLEAR_MASK, (Timing->SetupTime | \
- ((Timing->WaitSetupTime) << FSMC_PATTx_ATTWAITx_Pos) | \
- ((Timing->HoldSetupTime) << FSMC_PATTx_ATTHOLDx_Pos) | \
- ((Timing->HiZSetupTime) << FSMC_PATTx_ATTHIZx_Pos)));
- }
- else
- {
- /* NAND bank 3 registers configuration */
- MODIFY_REG(Device->PATT3, PATT_CLEAR_MASK, (Timing->SetupTime | \
- ((Timing->WaitSetupTime) << FSMC_PATTx_ATTWAITx_Pos) | \
- ((Timing->HoldSetupTime) << FSMC_PATTx_ATTHOLDx_Pos) | \
- ((Timing->HiZSetupTime) << FSMC_PATTx_ATTHIZx_Pos)));
- }
-
- return HAL_OK;
-}
-
-
-/**
- * @brief DeInitializes the FSMC_NAND device
- * @param Device: Pointer to NAND device instance
- * @param Bank: NAND bank number
- * @retval HAL status
- */
-HAL_StatusTypeDef FSMC_NAND_DeInit(FSMC_NAND_TypeDef *Device, uint32_t Bank)
-{
- /* Check the parameters */
- assert_param(IS_FSMC_NAND_DEVICE(Device));
- assert_param(IS_FSMC_NAND_BANK(Bank));
-
- /* Disable the NAND Bank */
- __FSMC_NAND_DISABLE(Device, Bank);
-
- /* De-initialize the NAND Bank */
- if(Bank == FSMC_NAND_BANK2)
- {
- /* Set the FSMC_NAND_BANK2 registers to their reset values */
- WRITE_REG(Device->PCR2, 0x00000018U);
- WRITE_REG(Device->SR2, 0x00000040U);
- WRITE_REG(Device->PMEM2, 0xFCFCFCFCU);
- WRITE_REG(Device->PATT2, 0xFCFCFCFCU);
- }
- /* FSMC_Bank3_NAND */
- else
- {
- /* Set the FSMC_NAND_BANK3 registers to their reset values */
- WRITE_REG(Device->PCR3, 0x00000018U);
- WRITE_REG(Device->SR3, 0x00000040U);
- WRITE_REG(Device->PMEM3, 0xFCFCFCFCU);
- WRITE_REG(Device->PATT3, 0xFCFCFCFCU);
- }
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-
-/** @defgroup FSMC_NAND_Exported_Functions_Group2 Peripheral Control functions
- * @brief management functions
- *
-@verbatim
- ==============================================================================
- ##### FSMC_NAND Control functions #####
- ==============================================================================
- [..]
- This subsection provides a set of functions allowing to control dynamically
- the FSMC NAND interface.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Enables dynamically FSMC_NAND ECC feature.
- * @param Device: Pointer to NAND device instance
- * @param Bank: NAND bank number
- * @retval HAL status
- */
-HAL_StatusTypeDef FSMC_NAND_ECC_Enable(FSMC_NAND_TypeDef *Device, uint32_t Bank)
-{
- /* Check the parameters */
- assert_param(IS_FSMC_NAND_DEVICE(Device));
- assert_param(IS_FSMC_NAND_BANK(Bank));
-
- /* Enable ECC feature */
- if(Bank == FSMC_NAND_BANK2)
- {
- SET_BIT(Device->PCR2, FSMC_PCRx_ECCEN);
- }
- else
- {
- SET_BIT(Device->PCR3, FSMC_PCRx_ECCEN);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Disables dynamically FSMC_NAND ECC feature.
- * @param Device: Pointer to NAND device instance
- * @param Bank: NAND bank number
- * @retval HAL status
- */
-HAL_StatusTypeDef FSMC_NAND_ECC_Disable(FSMC_NAND_TypeDef *Device, uint32_t Bank)
-{
- /* Check the parameters */
- assert_param(IS_FSMC_NAND_DEVICE(Device));
- assert_param(IS_FSMC_NAND_BANK(Bank));
-
- /* Disable ECC feature */
- if(Bank == FSMC_NAND_BANK2)
- {
- CLEAR_BIT(Device->PCR2, FSMC_PCRx_ECCEN);
- }
- else
- {
- CLEAR_BIT(Device->PCR3, FSMC_PCRx_ECCEN);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Disables dynamically FSMC_NAND ECC feature.
- * @param Device: Pointer to NAND device instance
- * @param ECCval: Pointer to ECC value
- * @param Bank: NAND bank number
- * @param Timeout: Timeout wait value
- * @retval HAL status
- */
-HAL_StatusTypeDef FSMC_NAND_GetECC(FSMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank, uint32_t Timeout)
-{
- uint32_t tickstart = 0U;
-
- /* Check the parameters */
- assert_param(IS_FSMC_NAND_DEVICE(Device));
- assert_param(IS_FSMC_NAND_BANK(Bank));
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Wait until FIFO is empty */
- while(__FSMC_NAND_GET_FLAG(Device, Bank, FSMC_FLAG_FEMPT) == RESET)
- {
- /* Check for the Timeout */
- if(Timeout != HAL_MAX_DELAY)
- {
- if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
- {
- return HAL_TIMEOUT;
- }
- }
- }
-
- if(Bank == FSMC_NAND_BANK2)
- {
- /* Get the ECCR2 register value */
- *ECCval = (uint32_t)Device->ECCR2;
- }
- else
- {
- /* Get the ECCR3 register value */
- *ECCval = (uint32_t)Device->ECCR3;
- }
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @defgroup FSMC_PCCARD FSMC PCCARD Controller functions
- * @brief PCCARD Controller functions
- *
- @verbatim
- ==============================================================================
- ##### How to use PCCARD device driver #####
- ==============================================================================
- [..]
- This driver contains a set of APIs to interface with the FSMC PCCARD bank in order
- to run the PCCARD/compact flash external devices.
-
- (+) FSMC PCCARD bank reset using the function FSMC_PCCARD_DeInit()
- (+) FSMC PCCARD bank control configuration using the function FSMC_PCCARD_Init()
- (+) FSMC PCCARD bank common space timing configuration using the function
- FSMC_PCCARD_CommonSpace_Timing_Init()
- (+) FSMC PCCARD bank attribute space timing configuration using the function
- FSMC_PCCARD_AttributeSpace_Timing_Init()
- (+) FSMC PCCARD bank IO space timing configuration using the function
- FSMC_PCCARD_IOSpace_Timing_Init()
-
-@endverbatim
- * @{
- */
-
-/** @defgroup FSMC_PCCARD_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
- ==============================================================================
- ##### Initialization and de_initialization functions #####
- ==============================================================================
- [..]
- This section provides functions allowing to:
- (+) Initialize and configure the FSMC PCCARD interface
- (+) De-initialize the FSMC PCCARD interface
- (+) Configure the FSMC clock and associated GPIOs
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the FSMC_PCCARD device according to the specified
- * control parameters in the FSMC_PCCARD_HandleTypeDef
- * @param Device: Pointer to PCCARD device instance
- * @param Init: Pointer to PCCARD Initialization structure
- * @retval HAL status
- */
-HAL_StatusTypeDef FSMC_PCCARD_Init(FSMC_PCCARD_TypeDef *Device, FSMC_PCCARD_InitTypeDef *Init)
-{
- /* Check the parameters */
- assert_param(IS_FSMC_PCCARD_DEVICE(Device));
- assert_param(IS_FSMC_WAIT_FEATURE(Init->Waitfeature));
- assert_param(IS_FSMC_TCLR_TIME(Init->TCLRSetupTime));
- assert_param(IS_FSMC_TAR_TIME(Init->TARSetupTime));
-
- /* Set FSMC_PCCARD device control parameters */
- MODIFY_REG(Device->PCR4,
- (FSMC_PCRx_PTYP | FSMC_PCRx_PWAITEN | FSMC_PCRx_PWID |
- FSMC_PCRx_TCLR | FSMC_PCRx_TAR),
- (FSMC_PCR_MEMORY_TYPE_PCCARD |
- Init->Waitfeature |
- FSMC_NAND_PCC_MEM_BUS_WIDTH_16 |
- (Init->TCLRSetupTime << FSMC_PCRx_TCLR_Pos) |
- (Init->TARSetupTime << FSMC_PCRx_TAR_Pos)));
-
- return HAL_OK;
-
-}
-
-/**
- * @brief Initializes the FSMC_PCCARD Common space Timing according to the specified
- * parameters in the FSMC_NAND_PCC_TimingTypeDef
- * @param Device: Pointer to PCCARD device instance
- * @param Timing: Pointer to PCCARD timing structure
- * @retval HAL status
- */
-HAL_StatusTypeDef FSMC_PCCARD_CommonSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing)
-{
- /* Check the parameters */
- assert_param(IS_FSMC_PCCARD_DEVICE(Device));
- assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
- assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
- assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
- assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
-
- /* Set PCCARD timing parameters */
- MODIFY_REG(Device->PMEM4, PMEM_CLEAR_MASK,
- (Timing->SetupTime |
- ((Timing->WaitSetupTime) << FSMC_PMEMx_MEMWAITx_Pos) |
- ((Timing->HoldSetupTime) << FSMC_PMEMx_MEMHOLDx_Pos) |
- ((Timing->HiZSetupTime) << FSMC_PMEMx_MEMHIZx_Pos)));
-
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the FSMC_PCCARD Attribute space Timing according to the specified
- * parameters in the FSMC_NAND_PCC_TimingTypeDef
- * @param Device: Pointer to PCCARD device instance
- * @param Timing: Pointer to PCCARD timing structure
- * @retval HAL status
- */
-HAL_StatusTypeDef FSMC_PCCARD_AttributeSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing)
-{
- /* Check the parameters */
- assert_param(IS_FSMC_PCCARD_DEVICE(Device));
- assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
- assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
- assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
- assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
-
- /* Set PCCARD timing parameters */
- MODIFY_REG(Device->PATT4, PATT_CLEAR_MASK, \
- (Timing->SetupTime | \
- ((Timing->WaitSetupTime) << FSMC_PATTx_ATTWAITx_Pos) | \
- ((Timing->HoldSetupTime) << FSMC_PATTx_ATTHOLDx_Pos) | \
- ((Timing->HiZSetupTime) << FSMC_PATTx_ATTHIZx_Pos)));
-
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the FSMC_PCCARD IO space Timing according to the specified
- * parameters in the FSMC_NAND_PCC_TimingTypeDef
- * @param Device: Pointer to PCCARD device instance
- * @param Timing: Pointer to PCCARD timing structure
- * @retval HAL status
- */
-HAL_StatusTypeDef FSMC_PCCARD_IOSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing)
-{
- /* Check the parameters */
- assert_param(IS_FSMC_PCCARD_DEVICE(Device));
- assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
- assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
- assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
- assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
-
- /* Set FSMC_PCCARD device timing parameters */
- MODIFY_REG(Device->PIO4, PIO4_CLEAR_MASK, \
- (Timing->SetupTime | \
- (Timing->WaitSetupTime << FSMC_PIO4_IOWAIT4_Pos) | \
- (Timing->HoldSetupTime << FSMC_PIO4_IOHOLD4_Pos) | \
- (Timing->HiZSetupTime << FSMC_PIO4_IOHIZ4_Pos)));
-
- return HAL_OK;
-}
-
-/**
- * @brief DeInitializes the FSMC_PCCARD device
- * @param Device: Pointer to PCCARD device instance
- * @retval HAL status
- */
-HAL_StatusTypeDef FSMC_PCCARD_DeInit(FSMC_PCCARD_TypeDef *Device)
-{
- /* Check the parameters */
- assert_param(IS_FSMC_PCCARD_DEVICE(Device));
-
- /* Disable the FSMC_PCCARD device */
- __FSMC_PCCARD_DISABLE(Device);
-
- /* De-initialize the FSMC_PCCARD device */
- WRITE_REG(Device->PCR4, 0x00000018U);
- WRITE_REG(Device->SR4, 0x00000040U);
- WRITE_REG(Device->PMEM4, 0xFCFCFCFCU);
- WRITE_REG(Device->PATT4, 0xFCFCFCFCU);
- WRITE_REG(Device->PIO4, 0xFCFCFCFCU);
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* HAL_SRAM_MODULE_ENABLED || HAL_NOR_MODULE_ENABLED || HAL_NAND_MODULE_ENABLED || HAL_PCCARD_MODULE_ENABLED */
-
-#endif /* FSMC_BANK1 */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_gpio.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_gpio.c
deleted file mode 100644
index c182e59..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_gpio.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_gpio.c
- * @author MCD Application Team
- * @brief GPIO LL module driver.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-#if defined(USE_FULL_LL_DRIVER)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_gpio.h"
-#include "stm32f1xx_ll_bus.h"
-#ifdef USE_FULL_ASSERT
-#include "stm32_assert.h"
-#else
-#define assert_param(expr) ((void)0U)
-#endif
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined (GPIOA) || defined (GPIOB) || defined (GPIOC) || defined (GPIOD) || defined (GPIOE) || defined (GPIOF) || defined (GPIOG)
-
-/** @addtogroup GPIO_LL
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-/** @addtogroup GPIO_LL_Private_Macros
- * @{
- */
-
-#define IS_LL_GPIO_PIN(__VALUE__) ((((__VALUE__) & LL_GPIO_PIN_ALL)!= 0U) &&\
- (((__VALUE__) & (~LL_GPIO_PIN_ALL))== 0U))
-
-#define IS_LL_GPIO_MODE(__VALUE__) (((__VALUE__) == LL_GPIO_MODE_ANALOG) ||\
- ((__VALUE__) == LL_GPIO_MODE_FLOATING) ||\
- ((__VALUE__) == LL_GPIO_MODE_INPUT) ||\
- ((__VALUE__) == LL_GPIO_MODE_OUTPUT) ||\
- ((__VALUE__) == LL_GPIO_MODE_ALTERNATE))
-
-#define IS_LL_GPIO_SPEED(__VALUE__) (((__VALUE__) == LL_GPIO_SPEED_FREQ_LOW) ||\
- ((__VALUE__) == LL_GPIO_SPEED_FREQ_MEDIUM) ||\
- ((__VALUE__) == LL_GPIO_SPEED_FREQ_HIGH))
-
-#define IS_LL_GPIO_OUTPUT_TYPE(__VALUE__) (((__VALUE__) == LL_GPIO_OUTPUT_PUSHPULL) ||\
- ((__VALUE__) == LL_GPIO_OUTPUT_OPENDRAIN))
-
-#define IS_LL_GPIO_PULL(__VALUE__) (((__VALUE__) == LL_GPIO_PULL_DOWN) ||\
- ((__VALUE__) == LL_GPIO_PULL_UP))
-
-/**
- * @}
- */
-
-/* Private function prototypes -----------------------------------------------*/
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup GPIO_LL_Exported_Functions
- * @{
- */
-
-/** @addtogroup GPIO_LL_EF_Init
- * @{
- */
-
-/**
- * @brief De-initialize GPIO registers (Registers restored to their default values).
- * @param GPIOx GPIO Port
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: GPIO registers are de-initialized
- * - ERROR: Wrong GPIO Port
- */
-ErrorStatus LL_GPIO_DeInit(GPIO_TypeDef *GPIOx)
-{
- ErrorStatus status = SUCCESS;
-
- /* Check the parameters */
- assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
-
- /* Force and Release reset on clock of GPIOx Port */
- if (GPIOx == GPIOA)
- {
- LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOA);
- LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOA);
- }
- else if (GPIOx == GPIOB)
- {
- LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOB);
- LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOB);
- }
- else if (GPIOx == GPIOC)
- {
- LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOC);
- LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOC);
- }
- else if (GPIOx == GPIOD)
- {
- LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOD);
- LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOD);
- }
-#if defined(GPIOE)
- else if (GPIOx == GPIOE)
- {
- LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOE);
- LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOE);
- }
-#endif
-#if defined(GPIOF)
- else if (GPIOx == GPIOF)
- {
- LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOF);
- LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOF);
- }
-#endif
-#if defined(GPIOG)
- else if (GPIOx == GPIOG)
- {
- LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOG);
- LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOG);
- }
-#endif
- else
- {
- status = ERROR;
- }
-
- return (status);
-}
-
-/**
- * @brief Initialize GPIO registers according to the specified parameters in GPIO_InitStruct.
- * @param GPIOx GPIO Port
- * @param GPIO_InitStruct: pointer to a @ref LL_GPIO_InitTypeDef structure
- * that contains the configuration information for the specified GPIO peripheral.
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: GPIO registers are initialized according to GPIO_InitStruct content
- * - ERROR: Not applicable
- */
-ErrorStatus LL_GPIO_Init(GPIO_TypeDef *GPIOx, LL_GPIO_InitTypeDef *GPIO_InitStruct)
-{
- uint32_t pinmask;
- uint32_t pinpos;
- uint32_t currentpin;
-
- /* Check the parameters */
- assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
- assert_param(IS_LL_GPIO_PIN(GPIO_InitStruct->Pin));
-
- /* ------------------------- Configure the port pins ---------------- */
- /* Initialize pinpos on first pin set */
-
- pinmask = ((GPIO_InitStruct->Pin) << GPIO_PIN_MASK_POS) >> GPIO_PIN_NB;
- pinpos = POSITION_VAL(pinmask);
-
- /* Configure the port pins */
- while ((pinmask >> pinpos) != 0U)
- {
- /* skip if bit is not set */
- if ((pinmask & (1U << pinpos)) != 0U)
- {
- /* Get current io position */
- if (pinpos < GPIO_PIN_MASK_POS)
- {
- currentpin = (0x00000101U << pinpos);
- }
- else
- {
- currentpin = ((0x00010001U << (pinpos - GPIO_PIN_MASK_POS)) | 0x04000000U);
- }
-
- /* Check Pin Mode and Pin Pull parameters */
- assert_param(IS_LL_GPIO_MODE(GPIO_InitStruct->Mode));
- assert_param(IS_LL_GPIO_PULL(GPIO_InitStruct->Pull));
-
- /* Pin Mode configuration */
- LL_GPIO_SetPinMode(GPIOx, currentpin, GPIO_InitStruct->Mode);
-
- /* Pull-up Pull-down resistor configuration*/
- LL_GPIO_SetPinPull(GPIOx, currentpin, GPIO_InitStruct->Pull);
-
- if ((GPIO_InitStruct->Mode == LL_GPIO_MODE_OUTPUT) || (GPIO_InitStruct->Mode == LL_GPIO_MODE_ALTERNATE))
- {
- /* Check speed and Output mode parameters */
- assert_param(IS_LL_GPIO_SPEED(GPIO_InitStruct->Speed));
- assert_param(IS_LL_GPIO_OUTPUT_TYPE(GPIO_InitStruct->OutputType));
-
- /* Speed mode configuration */
- LL_GPIO_SetPinSpeed(GPIOx, currentpin, GPIO_InitStruct->Speed);
-
- /* Output mode configuration*/
- LL_GPIO_SetPinOutputType(GPIOx, currentpin, GPIO_InitStruct->OutputType);
- }
- }
- pinpos++;
- }
- return (SUCCESS);
-}
-
-/**
- * @brief Set each @ref LL_GPIO_InitTypeDef field to default value.
- * @param GPIO_InitStruct: pointer to a @ref LL_GPIO_InitTypeDef structure
- * whose fields will be set to default values.
- * @retval None
- */
-
-void LL_GPIO_StructInit(LL_GPIO_InitTypeDef *GPIO_InitStruct)
-{
- /* Reset GPIO init structure parameters values */
- GPIO_InitStruct->Pin = LL_GPIO_PIN_ALL;
- GPIO_InitStruct->Mode = LL_GPIO_MODE_FLOATING;
- GPIO_InitStruct->Speed = LL_GPIO_SPEED_FREQ_LOW;
- GPIO_InitStruct->OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
- GPIO_InitStruct->Pull = LL_GPIO_PULL_DOWN;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* defined (GPIOA) || defined (GPIOB) || defined (GPIOC) || defined (GPIOD) || defined (GPIOE) || defined (GPIOF) || defined (GPIOG) */
-
-/**
- * @}
- */
-
-#endif /* USE_FULL_LL_DRIVER */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_i2c.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_i2c.c
deleted file mode 100644
index ef7fedb..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_i2c.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_i2c.c
- * @author MCD Application Team
- * @brief I2C LL module driver.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-#if defined(USE_FULL_LL_DRIVER)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_i2c.h"
-#include "stm32f1xx_ll_bus.h"
-#include "stm32f1xx_ll_rcc.h"
-#ifdef USE_FULL_ASSERT
-#include "stm32_assert.h"
-#else
-#define assert_param(expr) ((void)0U)
-#endif
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined (I2C1) || defined (I2C2)
-
-/** @defgroup I2C_LL I2C
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-/** @addtogroup I2C_LL_Private_Macros
- * @{
- */
-
-#define IS_LL_I2C_PERIPHERAL_MODE(__VALUE__) (((__VALUE__) == LL_I2C_MODE_I2C) || \
- ((__VALUE__) == LL_I2C_MODE_SMBUS_HOST) || \
- ((__VALUE__) == LL_I2C_MODE_SMBUS_DEVICE) || \
- ((__VALUE__) == LL_I2C_MODE_SMBUS_DEVICE_ARP))
-
-#define IS_LL_I2C_CLOCK_SPEED(__VALUE__) (((__VALUE__) > 0U) && ((__VALUE__) <= LL_I2C_MAX_SPEED_FAST))
-
-#define IS_LL_I2C_DUTY_CYCLE(__VALUE__) (((__VALUE__) == LL_I2C_DUTYCYCLE_2) || \
- ((__VALUE__) == LL_I2C_DUTYCYCLE_16_9))
-
-#define IS_LL_I2C_OWN_ADDRESS1(__VALUE__) ((__VALUE__) <= 0x000003FFU)
-
-#define IS_LL_I2C_TYPE_ACKNOWLEDGE(__VALUE__) (((__VALUE__) == LL_I2C_ACK) || \
- ((__VALUE__) == LL_I2C_NACK))
-
-#define IS_LL_I2C_OWN_ADDRSIZE(__VALUE__) (((__VALUE__) == LL_I2C_OWNADDRESS1_7BIT) || \
- ((__VALUE__) == LL_I2C_OWNADDRESS1_10BIT))
-/**
- * @}
- */
-
-/* Private function prototypes -----------------------------------------------*/
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup I2C_LL_Exported_Functions
- * @{
- */
-
-/** @addtogroup I2C_LL_EF_Init
- * @{
- */
-
-/**
- * @brief De-initialize the I2C registers to their default reset values.
- * @param I2Cx I2C Instance.
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS I2C registers are de-initialized
- * - ERROR I2C registers are not de-initialized
- */
-uint32_t LL_I2C_DeInit(I2C_TypeDef *I2Cx)
-{
- ErrorStatus status = SUCCESS;
-
- /* Check the I2C Instance I2Cx */
- assert_param(IS_I2C_ALL_INSTANCE(I2Cx));
-
- if (I2Cx == I2C1)
- {
- /* Force reset of I2C clock */
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1);
-
- /* Release reset of I2C clock */
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1);
- }
-#if defined(I2C2)
- else if (I2Cx == I2C2)
- {
- /* Force reset of I2C clock */
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C2);
-
- /* Release reset of I2C clock */
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C2);
-
- }
-#endif /* I2C2 */
- else
- {
- status = ERROR;
- }
-
- return status;
-}
-
-/**
- * @brief Initialize the I2C registers according to the specified parameters in I2C_InitStruct.
- * @param I2Cx I2C Instance.
- * @param I2C_InitStruct pointer to a @ref LL_I2C_InitTypeDef structure.
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS I2C registers are initialized
- * - ERROR Not applicable
- */
-uint32_t LL_I2C_Init(I2C_TypeDef *I2Cx, LL_I2C_InitTypeDef *I2C_InitStruct)
-{
- LL_RCC_ClocksTypeDef rcc_clocks;
-
- /* Check the I2C Instance I2Cx */
- assert_param(IS_I2C_ALL_INSTANCE(I2Cx));
-
- /* Check the I2C parameters from I2C_InitStruct */
- assert_param(IS_LL_I2C_PERIPHERAL_MODE(I2C_InitStruct->PeripheralMode));
- assert_param(IS_LL_I2C_CLOCK_SPEED(I2C_InitStruct->ClockSpeed));
- assert_param(IS_LL_I2C_DUTY_CYCLE(I2C_InitStruct->DutyCycle));
- assert_param(IS_LL_I2C_OWN_ADDRESS1(I2C_InitStruct->OwnAddress1));
- assert_param(IS_LL_I2C_TYPE_ACKNOWLEDGE(I2C_InitStruct->TypeAcknowledge));
- assert_param(IS_LL_I2C_OWN_ADDRSIZE(I2C_InitStruct->OwnAddrSize));
-
- /* Disable the selected I2Cx Peripheral */
- LL_I2C_Disable(I2Cx);
-
- /* Retrieve Clock frequencies */
- LL_RCC_GetSystemClocksFreq(&rcc_clocks);
-
- /*---------------------------- I2Cx SCL Clock Speed Configuration ------------
- * Configure the SCL speed :
- * - ClockSpeed: I2C_CR2_FREQ[5:0], I2C_TRISE_TRISE[5:0], I2C_CCR_FS,
- * and I2C_CCR_CCR[11:0] bits
- * - DutyCycle: I2C_CCR_DUTY[7:0] bits
- */
- LL_I2C_ConfigSpeed(I2Cx, rcc_clocks.PCLK1_Frequency, I2C_InitStruct->ClockSpeed, I2C_InitStruct->DutyCycle);
-
- /*---------------------------- I2Cx OAR1 Configuration -----------------------
- * Disable, Configure and Enable I2Cx device own address 1 with parameters :
- * - OwnAddress1: I2C_OAR1_ADD[9:8], I2C_OAR1_ADD[7:1] and I2C_OAR1_ADD0 bits
- * - OwnAddrSize: I2C_OAR1_ADDMODE bit
- */
- LL_I2C_SetOwnAddress1(I2Cx, I2C_InitStruct->OwnAddress1, I2C_InitStruct->OwnAddrSize);
-
- /*---------------------------- I2Cx MODE Configuration -----------------------
- * Configure I2Cx peripheral mode with parameter :
- * - PeripheralMode: I2C_CR1_SMBUS, I2C_CR1_SMBTYPE and I2C_CR1_ENARP bits
- */
- LL_I2C_SetMode(I2Cx, I2C_InitStruct->PeripheralMode);
-
- /* Enable the selected I2Cx Peripheral */
- LL_I2C_Enable(I2Cx);
-
- /*---------------------------- I2Cx CR2 Configuration ------------------------
- * Configure the ACKnowledge or Non ACKnowledge condition
- * after the address receive match code or next received byte with parameter :
- * - TypeAcknowledge: I2C_CR2_NACK bit
- */
- LL_I2C_AcknowledgeNextData(I2Cx, I2C_InitStruct->TypeAcknowledge);
-
- return SUCCESS;
-}
-
-/**
- * @brief Set each @ref LL_I2C_InitTypeDef field to default value.
- * @param I2C_InitStruct Pointer to a @ref LL_I2C_InitTypeDef structure.
- * @retval None
- */
-void LL_I2C_StructInit(LL_I2C_InitTypeDef *I2C_InitStruct)
-{
- /* Set I2C_InitStruct fields to default values */
- I2C_InitStruct->PeripheralMode = LL_I2C_MODE_I2C;
- I2C_InitStruct->ClockSpeed = 5000U;
- I2C_InitStruct->DutyCycle = LL_I2C_DUTYCYCLE_2;
- I2C_InitStruct->OwnAddress1 = 0U;
- I2C_InitStruct->TypeAcknowledge = LL_I2C_NACK;
- I2C_InitStruct->OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* I2C1 || I2C2 */
-
-/**
- * @}
- */
-
-#endif /* USE_FULL_LL_DRIVER */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_pwr.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_pwr.c
deleted file mode 100644
index c60e7a3..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_pwr.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_pwr.c
- * @author MCD Application Team
- * @brief PWR LL module driver.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-#if defined(USE_FULL_LL_DRIVER)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_pwr.h"
-#include "stm32f1xx_ll_bus.h"
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined(PWR)
-
-/** @defgroup PWR_LL PWR
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup PWR_LL_Exported_Functions
- * @{
- */
-
-/** @addtogroup PWR_LL_EF_Init
- * @{
- */
-
-/**
- * @brief De-initialize the PWR registers to their default reset values.
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: PWR registers are de-initialized
- * - ERROR: not applicable
- */
-ErrorStatus LL_PWR_DeInit(void)
-{
- /* Force reset of PWR clock */
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_PWR);
-
- /* Release reset of PWR clock */
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_PWR);
-
- return SUCCESS;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-#endif /* defined(PWR) */
-/**
- * @}
- */
-
-#endif /* USE_FULL_LL_DRIVER */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rcc.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rcc.c
deleted file mode 100644
index fcc0ccb..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rcc.c
+++ /dev/null
@@ -1,489 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_rcc.c
- * @author MCD Application Team
- * @brief RCC LL module driver.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-#if defined(USE_FULL_LL_DRIVER)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_rcc.h"
-#ifdef USE_FULL_ASSERT
- #include "stm32_assert.h"
-#else
- #define assert_param(expr) ((void)0U)
-#endif /* USE_FULL_ASSERT */
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined(RCC)
-
-/** @defgroup RCC_LL RCC
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-/** @addtogroup RCC_LL_Private_Macros
- * @{
- */
-#if defined(RCC_PLLI2S_SUPPORT)
-#define IS_LL_RCC_I2S_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_I2S2_CLKSOURCE) \
- || ((__VALUE__) == LL_RCC_I2S3_CLKSOURCE))
-#endif /* RCC_PLLI2S_SUPPORT */
-
-#if defined(USB) || defined(USB_OTG_FS)
-#define IS_LL_RCC_USB_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_USB_CLKSOURCE))
-#endif /* USB */
-
-#define IS_LL_RCC_ADC_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_ADC_CLKSOURCE))
-/**
- * @}
- */
-
-/* Private function prototypes -----------------------------------------------*/
-/** @defgroup RCC_LL_Private_Functions RCC Private functions
- * @{
- */
-uint32_t RCC_GetSystemClockFreq(void);
-uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency);
-uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency);
-uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency);
-uint32_t RCC_PLL_GetFreqDomain_SYS(void);
-#if defined(RCC_PLLI2S_SUPPORT)
-uint32_t RCC_PLLI2S_GetFreqDomain_I2S(void);
-#endif /* RCC_PLLI2S_SUPPORT */
-#if defined(RCC_PLL2_SUPPORT)
-uint32_t RCC_PLL2_GetFreqClockFreq(void);
-#endif /* RCC_PLL2_SUPPORT */
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup RCC_LL_Exported_Functions
- * @{
- */
-
-/** @addtogroup RCC_LL_EF_Init
- * @{
- */
-
-/**
- * @brief Reset the RCC clock configuration to the default reset state.
- * @note The default reset state of the clock configuration is given below:
- * - HSI ON and used as system clock source
- * - HSE PLL, PLL2 & PLL3 are OFF
- * - AHB, APB1 and APB2 prescaler set to 1.
- * - CSS, MCO OFF
- * - All interrupts disabled
- * @note This function doesn't modify the configuration of the
- * - Peripheral clocks
- * - LSI, LSE and RTC clocks
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: RCC registers are de-initialized
- * - ERROR: not applicable
- */
-ErrorStatus LL_RCC_DeInit(void)
-{
- /* Set HSION bit */
- LL_RCC_HSI_Enable();
-
- /* Wait for HSI READY bit */
- while(LL_RCC_HSI_IsReady() != 1U)
- {}
-
- /* Configure HSI as system clock source */
- LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
-
- /* Wait till clock switch is ready */
- while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI)
- {}
-
- /* Reset PLLON bit */
- CLEAR_BIT(RCC->CR, RCC_CR_PLLON);
-
- /* Wait for PLL READY bit to be reset */
- while(LL_RCC_PLL_IsReady() != 0U)
- {}
-
- /* Reset CFGR register */
- LL_RCC_WriteReg(CFGR, 0x00000000U);
-
- /* Reset HSEON, HSEBYP & CSSON bits */
- CLEAR_BIT(RCC->CR, (RCC_CR_CSSON | RCC_CR_HSEON | RCC_CR_HSEBYP));
-
-#if defined(RCC_CR_PLL2ON)
- /* Reset PLL2ON bit */
- CLEAR_BIT(RCC->CR, RCC_CR_PLL2ON);
-#endif /* RCC_CR_PLL2ON */
-
-#if defined(RCC_CR_PLL3ON)
- /* Reset PLL3ON bit */
- CLEAR_BIT(RCC->CR, RCC_CR_PLL3ON);
-#endif /* RCC_CR_PLL3ON */
-
- /* Set HSITRIM bits to the reset value */
- LL_RCC_HSI_SetCalibTrimming(0x10U);
-
-#if defined(RCC_CFGR2_PREDIV1)
- /* Reset CFGR2 register */
- LL_RCC_WriteReg(CFGR2, 0x00000000U);
-#endif /* RCC_CFGR2_PREDIV1 */
-
- /* Disable all interrupts */
- LL_RCC_WriteReg(CIR, 0x00000000U);
-
- /* Clear reset flags */
- LL_RCC_ClearResetFlags();
-
- return SUCCESS;
-}
-
-/**
- * @}
- */
-
-/** @addtogroup RCC_LL_EF_Get_Freq
- * @brief Return the frequencies of different on chip clocks; System, AHB, APB1 and APB2 buses clocks
- * and different peripheral clocks available on the device.
- * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(**)
- * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(***)
- * @note If SYSCLK source is PLL, function returns values based on
- * HSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors.
- * @note (**) HSI_VALUE is a defined constant but the real value may vary
- * depending on the variations in voltage and temperature.
- * @note (***) HSE_VALUE is a defined constant, user has to ensure that
- * HSE_VALUE is same as the real frequency of the crystal used.
- * Otherwise, this function may have wrong result.
- * @note The result of this function could be incorrect when using fractional
- * value for HSE crystal.
- * @note This function can be used by the user application to compute the
- * baud-rate for the communication peripherals or configure other parameters.
- * @{
- */
-
-/**
- * @brief Return the frequencies of different on chip clocks; System, AHB, APB1 and APB2 buses clocks
- * @note Each time SYSCLK, HCLK, PCLK1 and/or PCLK2 clock changes, this function
- * must be called to update structure fields. Otherwise, any
- * configuration based on this function will be incorrect.
- * @param RCC_Clocks pointer to a @ref LL_RCC_ClocksTypeDef structure which will hold the clocks frequencies
- * @retval None
- */
-void LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef *RCC_Clocks)
-{
- /* Get SYSCLK frequency */
- RCC_Clocks->SYSCLK_Frequency = RCC_GetSystemClockFreq();
-
- /* HCLK clock frequency */
- RCC_Clocks->HCLK_Frequency = RCC_GetHCLKClockFreq(RCC_Clocks->SYSCLK_Frequency);
-
- /* PCLK1 clock frequency */
- RCC_Clocks->PCLK1_Frequency = RCC_GetPCLK1ClockFreq(RCC_Clocks->HCLK_Frequency);
-
- /* PCLK2 clock frequency */
- RCC_Clocks->PCLK2_Frequency = RCC_GetPCLK2ClockFreq(RCC_Clocks->HCLK_Frequency);
-}
-
-#if defined(RCC_CFGR2_I2S2SRC)
-/**
- * @brief Return I2Sx clock frequency
- * @param I2SxSource This parameter can be one of the following values:
- * @arg @ref LL_RCC_I2S2_CLKSOURCE
- * @arg @ref LL_RCC_I2S3_CLKSOURCE
- * @retval I2S clock frequency (in Hz)
- */
-uint32_t LL_RCC_GetI2SClockFreq(uint32_t I2SxSource)
-{
- uint32_t i2s_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
-
- /* Check parameter */
- assert_param(IS_LL_RCC_I2S_CLKSOURCE(I2SxSource));
-
- /* I2S1CLK clock frequency */
- switch (LL_RCC_GetI2SClockSource(I2SxSource))
- {
- case LL_RCC_I2S2_CLKSOURCE_SYSCLK: /*!< System clock selected as I2S clock source */
- case LL_RCC_I2S3_CLKSOURCE_SYSCLK:
- i2s_frequency = RCC_GetSystemClockFreq();
- break;
-
- case LL_RCC_I2S2_CLKSOURCE_PLLI2S_VCO: /*!< PLLI2S oscillator clock selected as I2S clock source */
- case LL_RCC_I2S3_CLKSOURCE_PLLI2S_VCO:
- default:
- i2s_frequency = RCC_PLLI2S_GetFreqDomain_I2S() * 2U;
- break;
- }
-
- return i2s_frequency;
-}
-#endif /* RCC_CFGR2_I2S2SRC */
-
-#if defined(USB) || defined(USB_OTG_FS)
-/**
- * @brief Return USBx clock frequency
- * @param USBxSource This parameter can be one of the following values:
- * @arg @ref LL_RCC_USB_CLKSOURCE
- * @retval USB clock frequency (in Hz)
- * @arg @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI), HSE or PLL is not ready
- */
-uint32_t LL_RCC_GetUSBClockFreq(uint32_t USBxSource)
-{
- uint32_t usb_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
-
- /* Check parameter */
- assert_param(IS_LL_RCC_USB_CLKSOURCE(USBxSource));
-
- /* USBCLK clock frequency */
- switch (LL_RCC_GetUSBClockSource(USBxSource))
- {
-#if defined(RCC_CFGR_USBPRE)
- case LL_RCC_USB_CLKSOURCE_PLL: /* PLL clock used as USB clock source */
- if (LL_RCC_PLL_IsReady())
- {
- usb_frequency = RCC_PLL_GetFreqDomain_SYS();
- }
- break;
-
- case LL_RCC_USB_CLKSOURCE_PLL_DIV_1_5: /* PLL clock divided by 1.5 used as USB clock source */
- default:
- if (LL_RCC_PLL_IsReady())
- {
- usb_frequency = (RCC_PLL_GetFreqDomain_SYS() * 3U) / 2U;
- }
- break;
-#endif /* RCC_CFGR_USBPRE */
-#if defined(RCC_CFGR_OTGFSPRE)
- /* USBCLK = PLLVCO/2
- = (2 x PLLCLK) / 2
- = PLLCLK */
- case LL_RCC_USB_CLKSOURCE_PLL_DIV_2: /* PLL clock used as USB clock source */
- if (LL_RCC_PLL_IsReady())
- {
- usb_frequency = RCC_PLL_GetFreqDomain_SYS();
- }
- break;
-
- /* USBCLK = PLLVCO/3
- = (2 x PLLCLK) / 3 */
- case LL_RCC_USB_CLKSOURCE_PLL_DIV_3: /* PLL clock divided by 3 used as USB clock source */
- default:
- if (LL_RCC_PLL_IsReady())
- {
- usb_frequency = (RCC_PLL_GetFreqDomain_SYS() * 2U) / 3U;
- }
- break;
-#endif /* RCC_CFGR_OTGFSPRE */
- }
-
- return usb_frequency;
-}
-#endif /* USB */
-
-/**
- * @brief Return ADCx clock frequency
- * @param ADCxSource This parameter can be one of the following values:
- * @arg @ref LL_RCC_ADC_CLKSOURCE
- * @retval ADC clock frequency (in Hz)
- */
-uint32_t LL_RCC_GetADCClockFreq(uint32_t ADCxSource)
-{
- uint32_t adc_prescaler = 0U;
- uint32_t adc_frequency = 0U;
-
- /* Check parameter */
- assert_param(IS_LL_RCC_ADC_CLKSOURCE(ADCxSource));
-
- /* Get ADC prescaler */
- adc_prescaler = LL_RCC_GetADCClockSource(ADCxSource);
-
- /* ADC frequency = PCLK2 frequency / ADC prescaler (2, 4, 6 or 8) */
- adc_frequency = RCC_GetPCLK2ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()))
- / (((adc_prescaler >> POSITION_VAL(ADCxSource)) + 1U) * 2U);
-
- return adc_frequency;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup RCC_LL_Private_Functions
- * @{
- */
-
-/**
- * @brief Return SYSTEM clock frequency
- * @retval SYSTEM clock frequency (in Hz)
- */
-uint32_t RCC_GetSystemClockFreq(void)
-{
- uint32_t frequency = 0U;
-
- /* Get SYSCLK source -------------------------------------------------------*/
- switch (LL_RCC_GetSysClkSource())
- {
- case LL_RCC_SYS_CLKSOURCE_STATUS_HSI: /* HSI used as system clock source */
- frequency = HSI_VALUE;
- break;
-
- case LL_RCC_SYS_CLKSOURCE_STATUS_HSE: /* HSE used as system clock source */
- frequency = HSE_VALUE;
- break;
-
- case LL_RCC_SYS_CLKSOURCE_STATUS_PLL: /* PLL used as system clock source */
- frequency = RCC_PLL_GetFreqDomain_SYS();
- break;
-
- default:
- frequency = HSI_VALUE;
- break;
- }
-
- return frequency;
-}
-
-/**
- * @brief Return HCLK clock frequency
- * @param SYSCLK_Frequency SYSCLK clock frequency
- * @retval HCLK clock frequency (in Hz)
- */
-uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency)
-{
- /* HCLK clock frequency */
- return __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, LL_RCC_GetAHBPrescaler());
-}
-
-/**
- * @brief Return PCLK1 clock frequency
- * @param HCLK_Frequency HCLK clock frequency
- * @retval PCLK1 clock frequency (in Hz)
- */
-uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency)
-{
- /* PCLK1 clock frequency */
- return __LL_RCC_CALC_PCLK1_FREQ(HCLK_Frequency, LL_RCC_GetAPB1Prescaler());
-}
-
-/**
- * @brief Return PCLK2 clock frequency
- * @param HCLK_Frequency HCLK clock frequency
- * @retval PCLK2 clock frequency (in Hz)
- */
-uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency)
-{
- /* PCLK2 clock frequency */
- return __LL_RCC_CALC_PCLK2_FREQ(HCLK_Frequency, LL_RCC_GetAPB2Prescaler());
-}
-
-/**
- * @brief Return PLL clock frequency used for system domain
- * @retval PLL clock frequency (in Hz)
- */
-uint32_t RCC_PLL_GetFreqDomain_SYS(void)
-{
- uint32_t pllinputfreq = 0U, pllsource = 0U;
-
- /* PLL_VCO = (HSE_VALUE, HSI_VALUE or PLL2 / PLL Predivider) * PLL Multiplicator */
-
- /* Get PLL source */
- pllsource = LL_RCC_PLL_GetMainSource();
-
- switch (pllsource)
- {
- case LL_RCC_PLLSOURCE_HSI_DIV_2: /* HSI used as PLL clock source */
- pllinputfreq = HSI_VALUE / 2U;
- break;
-
- case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
- pllinputfreq = HSE_VALUE / (LL_RCC_PLL_GetPrediv() + 1U);
- break;
-
-#if defined(RCC_PLL2_SUPPORT)
- case LL_RCC_PLLSOURCE_PLL2: /* PLL2 used as PLL clock source */
- pllinputfreq = RCC_PLL2_GetFreqClockFreq() / (LL_RCC_PLL_GetPrediv() + 1U);
- break;
-#endif /* RCC_PLL2_SUPPORT */
-
- default:
- pllinputfreq = HSI_VALUE / 2U;
- break;
- }
- return __LL_RCC_CALC_PLLCLK_FREQ(pllinputfreq, LL_RCC_PLL_GetMultiplicator());
-}
-
-#if defined(RCC_PLL2_SUPPORT)
-/**
- * @brief Return PLL clock frequency used for system domain
- * @retval PLL clock frequency (in Hz)
- */
-uint32_t RCC_PLL2_GetFreqClockFreq(void)
-{
- return __LL_RCC_CALC_PLL2CLK_FREQ(HSE_VALUE, LL_RCC_PLL2_GetMultiplicator(), LL_RCC_HSE_GetPrediv2());
-}
-#endif /* RCC_PLL2_SUPPORT */
-
-#if defined(RCC_PLLI2S_SUPPORT)
-/**
- * @brief Return PLL clock frequency used for system domain
- * @retval PLL clock frequency (in Hz)
- */
-uint32_t RCC_PLLI2S_GetFreqDomain_I2S(void)
-{
- return __LL_RCC_CALC_PLLI2SCLK_FREQ(HSE_VALUE, LL_RCC_PLLI2S_GetMultiplicator(), LL_RCC_HSE_GetPrediv2());
-}
-#endif /* RCC_PLLI2S_SUPPORT */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* defined(RCC) */
-
-/**
- * @}
- */
-
-#endif /* USE_FULL_LL_DRIVER */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rtc.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rtc.c
deleted file mode 100644
index 8fad26a..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rtc.c
+++ /dev/null
@@ -1,556 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_rtc.c
- * @author MCD Application Team
- * @brief RTC LL module driver.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-#if defined(USE_FULL_LL_DRIVER)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_rtc.h"
-#include "stm32f1xx_ll_cortex.h"
-#ifdef USE_FULL_ASSERT
-#include "stm32_assert.h"
-#else
-#define assert_param(expr) ((void)0U)
-#endif
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined(RTC)
-
-/** @addtogroup RTC_LL
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/** @addtogroup RTC_LL_Private_Constants
- * @{
- */
-/* Default values used for prescaler */
-#define RTC_ASYNCH_PRESC_DEFAULT 0x00007FFFU
-
-/* Values used for timeout */
-#define RTC_INITMODE_TIMEOUT 1000U /* 1s when tick set to 1ms */
-#define RTC_SYNCHRO_TIMEOUT 1000U /* 1s when tick set to 1ms */
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-/** @addtogroup RTC_LL_Private_Macros
- * @{
- */
-
-#define IS_LL_RTC_ASYNCH_PREDIV(__VALUE__) ((__VALUE__) <= 0xFFFFFU)
-
-#define IS_LL_RTC_FORMAT(__VALUE__) (((__VALUE__) == LL_RTC_FORMAT_BIN) \
- || ((__VALUE__) == LL_RTC_FORMAT_BCD))
-
-#define IS_LL_RTC_HOUR24(__HOUR__) ((__HOUR__) <= 23U)
-#define IS_LL_RTC_MINUTES(__MINUTES__) ((__MINUTES__) <= 59U)
-#define IS_LL_RTC_SECONDS(__SECONDS__) ((__SECONDS__) <= 59U)
-#define IS_LL_RTC_CALIB_OUTPUT(__OUTPUT__) (((__OUTPUT__) == LL_RTC_CALIB_OUTPUT_NONE) || \
- ((__OUTPUT__) == LL_RTC_CALIB_OUTPUT_RTCCLOCK) || \
- ((__OUTPUT__) == LL_RTC_CALIB_OUTPUT_ALARM) || \
- ((__OUTPUT__) == LL_RTC_CALIB_OUTPUT_SECOND))
-/**
- * @}
- */
-/* Private function prototypes -----------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup RTC_LL_Exported_Functions
- * @{
- */
-
-/** @addtogroup RTC_LL_EF_Init
- * @{
- */
-
-/**
- * @brief De-Initializes the RTC registers to their default reset values.
- * @note This function doesn't reset the RTC Clock source and RTC Backup Data
- * registers.
- * @param RTCx RTC Instance
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: RTC registers are de-initialized
- * - ERROR: RTC registers are not de-initialized
- */
-ErrorStatus LL_RTC_DeInit(RTC_TypeDef *RTCx)
-{
- ErrorStatus status = ERROR;
-
- /* Check the parameter */
- assert_param(IS_RTC_ALL_INSTANCE(RTCx));
-
- /* Disable the write protection for RTC registers */
- LL_RTC_DisableWriteProtection(RTCx);
-
- /* Set Initialization mode */
- if (LL_RTC_EnterInitMode(RTCx) != ERROR)
- {
- LL_RTC_WriteReg(RTCx,CNTL, 0x0000);
- LL_RTC_WriteReg(RTCx,CNTH, 0x0000);
- LL_RTC_WriteReg(RTCx,PRLH, 0x0000);
- LL_RTC_WriteReg(RTCx,PRLL, 0x8000);
- LL_RTC_WriteReg(RTCx,CRH, 0x0000);
- LL_RTC_WriteReg(RTCx,CRL, 0x0020);
-
- /* Reset Tamper and alternate functions configuration register */
- LL_RTC_WriteReg(BKP,RTCCR, 0x00000000U);
- LL_RTC_WriteReg(BKP,CR, 0x00000000U);
- LL_RTC_WriteReg(BKP,CSR, 0x00000000U);
-
- /* Exit Initialization Mode */
- if(LL_RTC_ExitInitMode(RTCx) == ERROR)
- {
- return ERROR;
- }
-
- /* Wait till the RTC RSF flag is set */
- status = LL_RTC_WaitForSynchro(RTCx);
-
- /* Clear RSF Flag */
- LL_RTC_ClearFlag_RS(RTCx);
- }
-
- /* Enable the write protection for RTC registers */
- LL_RTC_EnableWriteProtection(RTCx);
-
- return status;
-}
-
-/**
- * @brief Initializes the RTC registers according to the specified parameters
- * in RTC_InitStruct.
- * @param RTCx RTC Instance
- * @param RTC_InitStruct pointer to a @ref LL_RTC_InitTypeDef structure that contains
- * the configuration information for the RTC peripheral.
- * @note The RTC Prescaler register is write protected and can be written in
- * initialization mode only.
- * @note the user should call LL_RTC_StructInit() or the structure of Prescaler
- * need to be initialized before RTC init()
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: RTC registers are initialized
- * - ERROR: RTC registers are not initialized
- */
-ErrorStatus LL_RTC_Init(RTC_TypeDef *RTCx, LL_RTC_InitTypeDef *RTC_InitStruct)
-{
- ErrorStatus status = ERROR;
-
- /* Check the parameters */
- assert_param(IS_RTC_ALL_INSTANCE(RTCx));
- assert_param(IS_LL_RTC_ASYNCH_PREDIV(RTC_InitStruct->AsynchPrescaler));
- assert_param(IS_LL_RTC_CALIB_OUTPUT(RTC_InitStruct->OutPutSource));
- /* Waiting for synchro */
- if(LL_RTC_WaitForSynchro(RTCx) != ERROR)
- {
- /* Set Initialization mode */
- if (LL_RTC_EnterInitMode(RTCx) != ERROR)
- {
- /* Clear Flag Bits */
- LL_RTC_ClearFlag_ALR(RTCx);
- LL_RTC_ClearFlag_OW(RTCx);
- LL_RTC_ClearFlag_SEC(RTCx);
-
- if(RTC_InitStruct->OutPutSource != LL_RTC_CALIB_OUTPUT_NONE)
- {
- /* Disable the selected Tamper Pin */
- LL_RTC_TAMPER_Disable(BKP);
- }
- /* Set the signal which will be routed to RTC Tamper Pin */
- LL_RTC_SetOutputSource(BKP, RTC_InitStruct->OutPutSource);
-
- /* Configure Synchronous and Asynchronous prescaler factor */
- LL_RTC_SetAsynchPrescaler(RTCx, RTC_InitStruct->AsynchPrescaler);
-
- /* Exit Initialization Mode */
- LL_RTC_ExitInitMode(RTCx);
-
- status = SUCCESS;
- }
- }
- return status;
-}
-
-/**
- * @brief Set each @ref LL_RTC_InitTypeDef field to default value.
- * @param RTC_InitStruct pointer to a @ref LL_RTC_InitTypeDef structure which will be initialized.
- * @retval None
- */
-void LL_RTC_StructInit(LL_RTC_InitTypeDef *RTC_InitStruct)
-{
- /* Set RTC_InitStruct fields to default values */
- RTC_InitStruct->AsynchPrescaler = RTC_ASYNCH_PRESC_DEFAULT;
- RTC_InitStruct->OutPutSource = LL_RTC_CALIB_OUTPUT_NONE;
-}
-
-/**
- * @brief Set the RTC current time.
- * @param RTCx RTC Instance
- * @param RTC_Format This parameter can be one of the following values:
- * @arg @ref LL_RTC_FORMAT_BIN
- * @arg @ref LL_RTC_FORMAT_BCD
- * @param RTC_TimeStruct pointer to a RTC_TimeTypeDef structure that contains
- * the time configuration information for the RTC.
- * @note The user should call LL_RTC_TIME_StructInit() or the structure
- * of time need to be initialized before time init()
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: RTC Time register is configured
- * - ERROR: RTC Time register is not configured
- */
-ErrorStatus LL_RTC_TIME_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_TimeTypeDef *RTC_TimeStruct)
-{
- ErrorStatus status = ERROR;
- uint32_t counter_time = 0U;
-
- /* Check the parameters */
- assert_param(IS_RTC_ALL_INSTANCE(RTCx));
- assert_param(IS_LL_RTC_FORMAT(RTC_Format));
-
- if (RTC_Format == LL_RTC_FORMAT_BIN)
- {
- assert_param(IS_LL_RTC_HOUR24(RTC_TimeStruct->Hours));
- assert_param(IS_LL_RTC_MINUTES(RTC_TimeStruct->Minutes));
- assert_param(IS_LL_RTC_SECONDS(RTC_TimeStruct->Seconds));
- }
- else
- {
- assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Hours)));
- assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Minutes)));
- assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Seconds)));
- }
-
- /* Enter Initialization mode */
- if (LL_RTC_EnterInitMode(RTCx) != ERROR)
- {
- /* Check the input parameters format */
- if (RTC_Format != LL_RTC_FORMAT_BIN)
- {
- counter_time = (uint32_t)(((uint32_t)RTC_TimeStruct->Hours * 3600U) + \
- ((uint32_t)RTC_TimeStruct->Minutes * 60U) + \
- ((uint32_t)RTC_TimeStruct->Seconds));
- LL_RTC_TIME_Set(RTCx, counter_time);
- }
- else
- {
- counter_time = (((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Hours)) * 3600U) + \
- ((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Minutes)) * 60U) + \
- ((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Seconds))));
- LL_RTC_TIME_Set(RTCx, counter_time);
- }
- status = SUCCESS;
- }
- /* Exit Initialization mode */
- LL_RTC_ExitInitMode(RTCx);
-
- return status;
-}
-
-/**
- * @brief Set each @ref LL_RTC_TimeTypeDef field to default value (Time = 00h:00min:00sec).
- * @param RTC_TimeStruct pointer to a @ref LL_RTC_TimeTypeDef structure which will be initialized.
- * @retval None
- */
-void LL_RTC_TIME_StructInit(LL_RTC_TimeTypeDef *RTC_TimeStruct)
-{
- /* Time = 00h:00min:00sec */
- RTC_TimeStruct->Hours = 0U;
- RTC_TimeStruct->Minutes = 0U;
- RTC_TimeStruct->Seconds = 0U;
-}
-
-/**
- * @brief Set the RTC Alarm.
- * @param RTCx RTC Instance
- * @param RTC_Format This parameter can be one of the following values:
- * @arg @ref LL_RTC_FORMAT_BIN
- * @arg @ref LL_RTC_FORMAT_BCD
- * @param RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure that
- * contains the alarm configuration parameters.
- * @note the user should call LL_RTC_ALARM_StructInit() or the structure
- * of Alarm need to be initialized before Alarm init()
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: ALARM registers are configured
- * - ERROR: ALARM registers are not configured
- */
-ErrorStatus LL_RTC_ALARM_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_AlarmTypeDef *RTC_AlarmStruct)
-{
- ErrorStatus status = ERROR;
- uint32_t counter_alarm = 0U;
- /* Check the parameters */
- assert_param(IS_RTC_ALL_INSTANCE(RTCx));
- assert_param(IS_LL_RTC_FORMAT(RTC_Format));
-
- if (RTC_Format == LL_RTC_FORMAT_BIN)
- {
- assert_param(IS_LL_RTC_HOUR24(RTC_AlarmStruct->AlarmTime.Hours));
- assert_param(IS_LL_RTC_MINUTES(RTC_AlarmStruct->AlarmTime.Minutes));
- assert_param(IS_LL_RTC_SECONDS(RTC_AlarmStruct->AlarmTime.Seconds));
- }
- else
- {
- assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours)));
- assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Minutes)));
- assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Seconds)));
- }
-
- /* Enter Initialization mode */
- if (LL_RTC_EnterInitMode(RTCx) != ERROR)
- {
- /* Check the input parameters format */
- if (RTC_Format != LL_RTC_FORMAT_BIN)
- {
- counter_alarm = (uint32_t)(((uint32_t)RTC_AlarmStruct->AlarmTime.Hours * 3600U) + \
- ((uint32_t)RTC_AlarmStruct->AlarmTime.Minutes * 60U) + \
- ((uint32_t)RTC_AlarmStruct->AlarmTime.Seconds));
- LL_RTC_ALARM_Set(RTCx, counter_alarm);
- }
- else
- {
- counter_alarm = (((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours)) * 3600U) + \
- ((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Minutes)) * 60U) + \
- ((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Seconds))));
- LL_RTC_ALARM_Set(RTCx, counter_alarm);
- }
- status = SUCCESS;
- }
- /* Exit Initialization mode */
- LL_RTC_ExitInitMode(RTCx);
-
- return status;
-}
-
-/**
- * @brief Set each @ref LL_RTC_AlarmTypeDef of ALARM field to default value (Time = 00h:00mn:00sec /
- * Day = 1st day of the month/Mask = all fields are masked).
- * @param RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure which will be initialized.
- * @retval None
- */
-void LL_RTC_ALARM_StructInit(LL_RTC_AlarmTypeDef *RTC_AlarmStruct)
-{
- /* Alarm Time Settings : Time = 00h:00mn:00sec */
- RTC_AlarmStruct->AlarmTime.Hours = 0U;
- RTC_AlarmStruct->AlarmTime.Minutes = 0U;
- RTC_AlarmStruct->AlarmTime.Seconds = 0U;
-}
-
-/**
- * @brief Enters the RTC Initialization mode.
- * @param RTCx RTC Instance
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: RTC is in Init mode
- * - ERROR: RTC is not in Init mode
- */
-ErrorStatus LL_RTC_EnterInitMode(RTC_TypeDef *RTCx)
-{
- __IO uint32_t timeout = RTC_INITMODE_TIMEOUT;
- ErrorStatus status = SUCCESS;
- uint32_t tmp = 0U;
-
- /* Check the parameter */
- assert_param(IS_RTC_ALL_INSTANCE(RTCx));
-
- /* Wait till RTC is in INIT state and if Time out is reached exit */
- tmp = LL_RTC_IsActiveFlag_RTOF(RTCx);
- while ((timeout != 0U) && (tmp != 1U))
- {
- if (LL_SYSTICK_IsActiveCounterFlag() == 1U)
- {
- timeout --;
- }
- tmp = LL_RTC_IsActiveFlag_RTOF(RTCx);
- if (timeout == 0U)
- {
- status = ERROR;
- }
- }
-
- /* Disable the write protection for RTC registers */
- LL_RTC_DisableWriteProtection(RTCx);
-
- return status;
-}
-
-/**
- * @brief Exit the RTC Initialization mode.
- * @note When the initialization sequence is complete, the calendar restarts
- * counting after 4 RTCCLK cycles.
- * @param RTCx RTC Instance
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: RTC exited from in Init mode
- * - ERROR: Not applicable
- */
-ErrorStatus LL_RTC_ExitInitMode(RTC_TypeDef *RTCx)
-{
- __IO uint32_t timeout = RTC_INITMODE_TIMEOUT;
- ErrorStatus status = SUCCESS;
- uint32_t tmp = 0U;
-
- /* Check the parameter */
- assert_param(IS_RTC_ALL_INSTANCE(RTCx));
-
- /* Disable initialization mode */
- LL_RTC_EnableWriteProtection(RTCx);
-
- /* Wait till RTC is in INIT state and if Time out is reached exit */
- tmp = LL_RTC_IsActiveFlag_RTOF(RTCx);
- while ((timeout != 0U) && (tmp != 1U))
- {
- if (LL_SYSTICK_IsActiveCounterFlag() == 1U)
- {
- timeout --;
- }
- tmp = LL_RTC_IsActiveFlag_RTOF(RTCx);
- if (timeout == 0U)
- {
- status = ERROR;
- }
- }
- return status;
-}
-
-/**
- * @brief Set the Time Counter
- * @param RTCx RTC Instance
- * @param TimeCounter this value can be from 0 to 0xFFFFFFFF
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: RTC Counter register configured
- * - ERROR: Not applicable
- */
-ErrorStatus LL_RTC_TIME_SetCounter(RTC_TypeDef *RTCx, uint32_t TimeCounter)
-{
- ErrorStatus status = ERROR;
- /* Check the parameter */
- assert_param(IS_RTC_ALL_INSTANCE(RTCx));
-
- /* Enter Initialization mode */
- if (LL_RTC_EnterInitMode(RTCx) != ERROR)
- {
- LL_RTC_TIME_Set(RTCx, TimeCounter);
- status = SUCCESS;
- }
- /* Exit Initialization mode */
- LL_RTC_ExitInitMode(RTCx);
-
- return status;
-}
-
-/**
- * @brief Set Alarm Counter.
- * @param RTCx RTC Instance
- * @param AlarmCounter this value can be from 0 to 0xFFFFFFFF
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: RTC exited from in Init mode
- * - ERROR: Not applicable
- */
-ErrorStatus LL_RTC_ALARM_SetCounter(RTC_TypeDef *RTCx, uint32_t AlarmCounter)
-{
- ErrorStatus status = ERROR;
- /* Check the parameter */
- assert_param(IS_RTC_ALL_INSTANCE(RTCx));
-
- /* Enter Initialization mode */
- if (LL_RTC_EnterInitMode(RTCx) != ERROR)
- {
- LL_RTC_ALARM_Set(RTCx, AlarmCounter);
- status = SUCCESS;
- }
- /* Exit Initialization mode */
- LL_RTC_ExitInitMode(RTCx);
-
- return status;
-}
-
-/**
- * @brief Waits until the RTC registers are synchronized with RTC APB clock.
- * @note The RTC Resynchronization mode is write protected, use the
- * @ref LL_RTC_DisableWriteProtection before calling this function.
- * @param RTCx RTC Instance
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: RTC registers are synchronised
- * - ERROR: RTC registers are not synchronised
- */
-ErrorStatus LL_RTC_WaitForSynchro(RTC_TypeDef *RTCx)
-{
- __IO uint32_t timeout = RTC_SYNCHRO_TIMEOUT;
- ErrorStatus status = SUCCESS;
- uint32_t tmp = 0U;
-
- /* Check the parameter */
- assert_param(IS_RTC_ALL_INSTANCE(RTCx));
-
- /* Clear RSF flag */
- LL_RTC_ClearFlag_RS(RTCx);
-
- /* Wait the registers to be synchronised */
- tmp = LL_RTC_IsActiveFlag_RS(RTCx);
- while ((timeout != 0U) && (tmp != 0U))
- {
- if (LL_SYSTICK_IsActiveCounterFlag() == 1U)
- {
- timeout--;
- }
- tmp = LL_RTC_IsActiveFlag_RS(RTCx);
- if (timeout == 0U)
- {
- status = ERROR;
- }
- }
-
- return (status);
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* defined(RTC) */
-
-/**
- * @}
- */
-
-#endif /* USE_FULL_LL_DRIVER */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_sdmmc.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_sdmmc.c
deleted file mode 100644
index 567bf2d..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_sdmmc.c
+++ /dev/null
@@ -1,1500 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_sdmmc.c
- * @author MCD Application Team
- * @brief SDIO Low Layer HAL module driver.
- *
- * This file provides firmware functions to manage the following
- * functionalities of the SDIO peripheral:
- * + Initialization/de-initialization functions
- * + I/O operation functions
- * + Peripheral Control functions
- * + Peripheral State functions
- *
- @verbatim
- ==============================================================================
- ##### SDMMC peripheral features #####
- ==============================================================================
- [..] The SD/SDMMC MMC card host interface (SDMMC) provides an interface between the APB2
- peripheral bus and MultiMedia cards (MMCs), SD memory cards, SDMMC cards and CE-ATA
- devices.
-
- [..] The SDMMC features include the following:
- (+) Full compliance with MultiMedia Card System Specification Version 4.2. Card support
- for three different databus modes: 1-bit (default), 4-bit and 8-bit
- (+) Full compatibility with previous versions of MultiMedia Cards (forward compatibility)
- (+) Full compliance with SD Memory Card Specifications Version 2.0
- (+) Full compliance with SD I/O Card Specification Version 2.0: card support for two
- different data bus modes: 1-bit (default) and 4-bit
- (+) Full support of the CE-ATA features (full compliance with CE-ATA digital protocol
- Rev1.1)
- (+) Data transfer up to 48 MHz for the 8 bit mode
- (+) Data and command output enable signals to control external bidirectional drivers.
-
-
- ##### How to use this driver #####
- ==============================================================================
- [..]
- This driver is a considered as a driver of service for external devices drivers
- that interfaces with the SDMMC peripheral.
- According to the device used (SD card/ MMC card / SDMMC card ...), a set of APIs
- is used in the device's driver to perform SDMMC operations and functionalities.
-
- This driver is almost transparent for the final user, it is only used to implement other
- functionalities of the external device.
-
- [..]
- (+) The SDIO peripheral uses two clock signals:
- (++) SDIO adapter clock (SDIOCLK = HCLK)
- (++) AHB bus clock (HCLK/2)
-
- -@@- PCLK2 and SDMMC_CK clock frequencies must respect the following condition:
- Frequency(PCLK2) >= (3 / 8 x Frequency(SDMMC_CK))
-
- (+) Enable/Disable peripheral clock using RCC peripheral macros related to SDMMC
- peripheral.
-
- (+) Enable the Power ON State using the SDIO_PowerState_ON(SDIOx)
- function and disable it using the function SDIO_PowerState_OFF(SDIOx).
-
- (+) Enable/Disable the clock using the __SDIO_ENABLE()/__SDIO_DISABLE() macros.
-
- (+) Enable/Disable the peripheral interrupts using the macros __SDIO_ENABLE_IT(hsdio, IT)
- and __SDIO_DISABLE_IT(hsdio, IT) if you need to use interrupt mode.
-
- (+) When using the DMA mode
- (++) Configure the DMA in the MSP layer of the external device
- (++) Active the needed channel Request
- (++) Enable the DMA using __SDIO_DMA_ENABLE() macro or Disable it using the macro
- __SDIO_DMA_DISABLE().
-
- (+) To control the CPSM (Command Path State Machine) and send
- commands to the card use the SDIO_SendCommand(),
- SDIO_GetCommandResponse() and SDIO_GetResponse() functions. First, user has
- to fill the command structure (pointer to SDIO_CmdInitTypeDef) according
- to the selected command to be sent.
- The parameters that should be filled are:
- (++) Command Argument
- (++) Command Index
- (++) Command Response type
- (++) Command Wait
- (++) CPSM Status (Enable or Disable).
-
- -@@- To check if the command is well received, read the SDIO_CMDRESP
- register using the SDIO_GetCommandResponse().
- The SDMMC responses registers (SDIO_RESP1 to SDIO_RESP2), use the
- SDIO_GetResponse() function.
-
- (+) To control the DPSM (Data Path State Machine) and send/receive
- data to/from the card use the SDIO_ConfigData(), SDIO_GetDataCounter(),
- SDIO_ReadFIFO(), SDIO_WriteFIFO() and SDIO_GetFIFOCount() functions.
-
- *** Read Operations ***
- =======================
- [..]
- (#) First, user has to fill the data structure (pointer to
- SDIO_DataInitTypeDef) according to the selected data type to be received.
- The parameters that should be filled are:
- (++) Data TimeOut
- (++) Data Length
- (++) Data Block size
- (++) Data Transfer direction: should be from card (To SDMMC)
- (++) Data Transfer mode
- (++) DPSM Status (Enable or Disable)
-
- (#) Configure the SDMMC resources to receive the data from the card
- according to selected transfer mode (Refer to Step 8, 9 and 10).
-
- (#) Send the selected Read command (refer to step 11).
-
- (#) Use the SDIO flags/interrupts to check the transfer status.
-
- *** Write Operations ***
- ========================
- [..]
- (#) First, user has to fill the data structure (pointer to
- SDIO_DataInitTypeDef) according to the selected data type to be received.
- The parameters that should be filled are:
- (++) Data TimeOut
- (++) Data Length
- (++) Data Block size
- (++) Data Transfer direction: should be to card (To CARD)
- (++) Data Transfer mode
- (++) DPSM Status (Enable or Disable)
-
- (#) Configure the SDMMC resources to send the data to the card according to
- selected transfer mode.
-
- (#) Send the selected Write command.
-
- (#) Use the SDIO flags/interrupts to check the transfer status.
-
- *** Command management operations ***
- =====================================
- [..]
- (#) The commands used for Read/Write//Erase operations are managed in
- separate functions.
- Each function allows to send the needed command with the related argument,
- then check the response.
- By the same approach, you could implement a command and check the response.
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-
-#if defined(STM32F103xE) || defined(STM32F103xG)
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup SDMMC_LL SDMMC Low Layer
- * @brief Low layer module for SD
- * @{
- */
-#if defined (HAL_SD_MODULE_ENABLED) || defined(HAL_MMC_MODULE_ENABLED)
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-static uint32_t SDMMC_GetCmdError(SDIO_TypeDef *SDIOx);
-static uint32_t SDMMC_GetCmdResp1(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint32_t Timeout);
-static uint32_t SDMMC_GetCmdResp2(SDIO_TypeDef *SDIOx);
-static uint32_t SDMMC_GetCmdResp3(SDIO_TypeDef *SDIOx);
-static uint32_t SDMMC_GetCmdResp7(SDIO_TypeDef *SDIOx);
-static uint32_t SDMMC_GetCmdResp6(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint16_t *pRCA);
-
-/* Exported functions --------------------------------------------------------*/
-
-/** @defgroup SDMMC_LL_Exported_Functions SDMMC Low Layer Exported Functions
- * @{
- */
-
-/** @defgroup HAL_SDMMC_LL_Group1 Initialization de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
- ===============================================================================
- ##### Initialization/de-initialization functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the SDMMC according to the specified
- * parameters in the SDMMC_InitTypeDef and create the associated handle.
- * @param SDIOx: Pointer to SDMMC register base
- * @param Init: SDMMC initialization structure
- * @retval HAL status
- */
-HAL_StatusTypeDef SDIO_Init(SDIO_TypeDef *SDIOx, SDIO_InitTypeDef Init)
-{
- uint32_t tmpreg = 0U;
-
- /* Check the parameters */
- assert_param(IS_SDIO_ALL_INSTANCE(SDIOx));
- assert_param(IS_SDIO_CLOCK_EDGE(Init.ClockEdge));
- assert_param(IS_SDIO_CLOCK_BYPASS(Init.ClockBypass));
- assert_param(IS_SDIO_CLOCK_POWER_SAVE(Init.ClockPowerSave));
- assert_param(IS_SDIO_BUS_WIDE(Init.BusWide));
- assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(Init.HardwareFlowControl));
- assert_param(IS_SDIO_CLKDIV(Init.ClockDiv));
-
- /* Set SDMMC configuration parameters */
- tmpreg |= (Init.ClockEdge |\
- Init.ClockBypass |\
- Init.ClockPowerSave |\
- Init.BusWide |\
- Init.HardwareFlowControl |\
- Init.ClockDiv
- );
-
- /* Write to SDMMC CLKCR */
- MODIFY_REG(SDIOx->CLKCR, CLKCR_CLEAR_MASK, tmpreg);
-
- return HAL_OK;
-}
-
-
-/**
- * @}
- */
-
-/** @defgroup HAL_SDMMC_LL_Group2 IO operation functions
- * @brief Data transfers functions
- *
-@verbatim
- ===============================================================================
- ##### I/O operation functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to manage the SDMMC data
- transfers.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Read data (word) from Rx FIFO in blocking mode (polling)
- * @param SDIOx: Pointer to SDMMC register base
- * @retval HAL status
- */
-uint32_t SDIO_ReadFIFO(SDIO_TypeDef *SDIOx)
-{
- /* Read data from Rx FIFO */
- return (SDIOx->FIFO);
-}
-
-/**
- * @brief Write data (word) to Tx FIFO in blocking mode (polling)
- * @param SDIOx: Pointer to SDMMC register base
- * @param pWriteData: pointer to data to write
- * @retval HAL status
- */
-HAL_StatusTypeDef SDIO_WriteFIFO(SDIO_TypeDef *SDIOx, uint32_t *pWriteData)
-{
- /* Write data to FIFO */
- SDIOx->FIFO = *pWriteData;
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup HAL_SDMMC_LL_Group3 Peripheral Control functions
- * @brief management functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral Control functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to control the SDMMC data
- transfers.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Set SDMMC Power state to ON.
- * @param SDIOx: Pointer to SDMMC register base
- * @retval HAL status
- */
-HAL_StatusTypeDef SDIO_PowerState_ON(SDIO_TypeDef *SDIOx)
-{
- /* Set power state to ON */
- SDIOx->POWER = SDIO_POWER_PWRCTRL;
-
- return HAL_OK;
-}
-
-/**
- * @brief Set SDMMC Power state to OFF.
- * @param SDIOx: Pointer to SDMMC register base
- * @retval HAL status
- */
-HAL_StatusTypeDef SDIO_PowerState_OFF(SDIO_TypeDef *SDIOx)
-{
- /* Set power state to OFF */
- SDIOx->POWER = 0x00000000U;
-
- return HAL_OK;
-}
-
-/**
- * @brief Get SDMMC Power state.
- * @param SDIOx: Pointer to SDMMC register base
- * @retval Power status of the controller. The returned value can be one of the
- * following values:
- * - 0x00: Power OFF
- * - 0x02: Power UP
- * - 0x03: Power ON
- */
-uint32_t SDIO_GetPowerState(SDIO_TypeDef *SDIOx)
-{
- return (SDIOx->POWER & SDIO_POWER_PWRCTRL);
-}
-
-/**
- * @brief Configure the SDMMC command path according to the specified parameters in
- * SDIO_CmdInitTypeDef structure and send the command
- * @param SDIOx: Pointer to SDMMC register base
- * @param Command: pointer to a SDIO_CmdInitTypeDef structure that contains
- * the configuration information for the SDMMC command
- * @retval HAL status
- */
-HAL_StatusTypeDef SDIO_SendCommand(SDIO_TypeDef *SDIOx, SDIO_CmdInitTypeDef *Command)
-{
- uint32_t tmpreg = 0U;
-
- /* Check the parameters */
- assert_param(IS_SDIO_CMD_INDEX(Command->CmdIndex));
- assert_param(IS_SDIO_RESPONSE(Command->Response));
- assert_param(IS_SDIO_WAIT(Command->WaitForInterrupt));
- assert_param(IS_SDIO_CPSM(Command->CPSM));
-
- /* Set the SDMMC Argument value */
- SDIOx->ARG = Command->Argument;
-
- /* Set SDMMC command parameters */
- tmpreg |= (uint32_t)(Command->CmdIndex |\
- Command->Response |\
- Command->WaitForInterrupt |\
- Command->CPSM);
-
- /* Write to SDMMC CMD register */
- MODIFY_REG(SDIOx->CMD, CMD_CLEAR_MASK, tmpreg);
-
- return HAL_OK;
-}
-
-/**
- * @brief Return the command index of last command for which response received
- * @param SDIOx: Pointer to SDMMC register base
- * @retval Command index of the last command response received
- */
-uint8_t SDIO_GetCommandResponse(SDIO_TypeDef *SDIOx)
-{
- return (uint8_t)(SDIOx->RESPCMD);
-}
-
-
-/**
- * @brief Return the response received from the card for the last command
- * @param SDIOx: Pointer to SDMMC register base
- * @param Response: Specifies the SDMMC response register.
- * This parameter can be one of the following values:
- * @arg SDIO_RESP1: Response Register 1
- * @arg SDIO_RESP2: Response Register 2
- * @arg SDIO_RESP3: Response Register 3
- * @arg SDIO_RESP4: Response Register 4
- * @retval The Corresponding response register value
- */
-uint32_t SDIO_GetResponse(SDIO_TypeDef *SDIOx, uint32_t Response)
-{
- __IO uint32_t tmp = 0U;
-
- /* Check the parameters */
- assert_param(IS_SDIO_RESP(Response));
-
- /* Get the response */
- tmp = (uint32_t)&(SDIOx->RESP1) + Response;
-
- return (*(__IO uint32_t *) tmp);
-}
-
-/**
- * @brief Configure the SDMMC data path according to the specified
- * parameters in the SDIO_DataInitTypeDef.
- * @param SDIOx: Pointer to SDMMC register base
- * @param Data : pointer to a SDIO_DataInitTypeDef structure
- * that contains the configuration information for the SDMMC data.
- * @retval HAL status
- */
-HAL_StatusTypeDef SDIO_ConfigData(SDIO_TypeDef *SDIOx, SDIO_DataInitTypeDef* Data)
-{
- uint32_t tmpreg = 0U;
-
- /* Check the parameters */
- assert_param(IS_SDIO_DATA_LENGTH(Data->DataLength));
- assert_param(IS_SDIO_BLOCK_SIZE(Data->DataBlockSize));
- assert_param(IS_SDIO_TRANSFER_DIR(Data->TransferDir));
- assert_param(IS_SDIO_TRANSFER_MODE(Data->TransferMode));
- assert_param(IS_SDIO_DPSM(Data->DPSM));
-
- /* Set the SDMMC Data TimeOut value */
- SDIOx->DTIMER = Data->DataTimeOut;
-
- /* Set the SDMMC DataLength value */
- SDIOx->DLEN = Data->DataLength;
-
- /* Set the SDMMC data configuration parameters */
- tmpreg |= (uint32_t)(Data->DataBlockSize |\
- Data->TransferDir |\
- Data->TransferMode |\
- Data->DPSM);
-
- /* Write to SDMMC DCTRL */
- MODIFY_REG(SDIOx->DCTRL, DCTRL_CLEAR_MASK, tmpreg);
-
- return HAL_OK;
-
-}
-
-/**
- * @brief Returns number of remaining data bytes to be transferred.
- * @param SDIOx: Pointer to SDMMC register base
- * @retval Number of remaining data bytes to be transferred
- */
-uint32_t SDIO_GetDataCounter(SDIO_TypeDef *SDIOx)
-{
- return (SDIOx->DCOUNT);
-}
-
-/**
- * @brief Get the FIFO data
- * @param SDIOx: Pointer to SDMMC register base
- * @retval Data received
- */
-uint32_t SDIO_GetFIFOCount(SDIO_TypeDef *SDIOx)
-{
- return (SDIOx->FIFO);
-}
-
-/**
- * @brief Sets one of the two options of inserting read wait interval.
- * @param SDIOx: Pointer to SDMMC register base
- * @param SDIO_ReadWaitMode: SDMMC Read Wait operation mode.
- * This parameter can be:
- * @arg SDIO_READ_WAIT_MODE_CLK: Read Wait control by stopping SDMMCCLK
- * @arg SDIO_READ_WAIT_MODE_DATA2: Read Wait control using SDMMC_DATA2
- * @retval None
- */
-HAL_StatusTypeDef SDIO_SetSDMMCReadWaitMode(SDIO_TypeDef *SDIOx, uint32_t SDIO_ReadWaitMode)
-{
- /* Check the parameters */
- assert_param(IS_SDIO_READWAIT_MODE(SDIO_ReadWaitMode));
-
- /* Set SDMMC read wait mode */
- MODIFY_REG(SDIOx->DCTRL, SDIO_DCTRL_RWMOD, SDIO_ReadWaitMode);
-
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-
-/** @defgroup HAL_SDMMC_LL_Group4 Command management functions
- * @brief Data transfers functions
- *
-@verbatim
- ===============================================================================
- ##### Commands management functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to manage the needed commands.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Send the Data Block Lenght command and check the response
- * @param SDIOx: Pointer to SDMMC register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdBlockLength(SDIO_TypeDef *SDIOx, uint32_t BlockSize)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- /* Set Block Size for Card */
- sdmmc_cmdinit.Argument = (uint32_t)BlockSize;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_BLOCKLEN;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SET_BLOCKLEN, SDIO_CMDTIMEOUT);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Read Single Block command and check the response
- * @param SDIOx: Pointer to SDMMC register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdReadSingleBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- /* Set Block Size for Card */
- sdmmc_cmdinit.Argument = (uint32_t)ReadAdd;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_READ_SINGLE_BLOCK;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_READ_SINGLE_BLOCK, SDIO_CMDTIMEOUT);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Read Multi Block command and check the response
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdReadMultiBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- /* Set Block Size for Card */
- sdmmc_cmdinit.Argument = (uint32_t)ReadAdd;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_READ_MULT_BLOCK;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_READ_MULT_BLOCK, SDIO_CMDTIMEOUT);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Write Single Block command and check the response
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdWriteSingleBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- /* Set Block Size for Card */
- sdmmc_cmdinit.Argument = (uint32_t)WriteAdd;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_WRITE_SINGLE_BLOCK;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_WRITE_SINGLE_BLOCK, SDIO_CMDTIMEOUT);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Write Multi Block command and check the response
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdWriteMultiBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- /* Set Block Size for Card */
- sdmmc_cmdinit.Argument = (uint32_t)WriteAdd;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_WRITE_MULT_BLOCK;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_WRITE_MULT_BLOCK, SDIO_CMDTIMEOUT);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Start Address Erase command for SD and check the response
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdSDEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- /* Set Block Size for Card */
- sdmmc_cmdinit.Argument = (uint32_t)StartAdd;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_ERASE_GRP_START;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_ERASE_GRP_START, SDIO_CMDTIMEOUT);
-
- return errorstate;
-}
-
-/**
- * @brief Send the End Address Erase command for SD and check the response
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdSDEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- /* Set Block Size for Card */
- sdmmc_cmdinit.Argument = (uint32_t)EndAdd;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_ERASE_GRP_END;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_ERASE_GRP_END, SDIO_CMDTIMEOUT);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Start Address Erase command and check the response
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- /* Set Block Size for Card */
- sdmmc_cmdinit.Argument = (uint32_t)StartAdd;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE_GRP_START;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_ERASE_GRP_START, SDIO_CMDTIMEOUT);
-
- return errorstate;
-}
-
-/**
- * @brief Send the End Address Erase command and check the response
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- /* Set Block Size for Card */
- sdmmc_cmdinit.Argument = (uint32_t)EndAdd;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE_GRP_END;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_ERASE_GRP_END, SDIO_CMDTIMEOUT);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Erase command and check the response
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdErase(SDIO_TypeDef *SDIOx)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- /* Set Block Size for Card */
- sdmmc_cmdinit.Argument = 0U;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_ERASE, SDIO_MAXERASETIMEOUT);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Stop Transfer command and check the response.
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdStopTransfer(SDIO_TypeDef *SDIOx)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- /* Send CMD12 STOP_TRANSMISSION */
- sdmmc_cmdinit.Argument = 0U;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_STOP_TRANSMISSION;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_STOP_TRANSMISSION, 100000000U);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Select Deselect command and check the response.
- * @param SDIOx: Pointer to SDIO register base
- * @param addr: Address of the card to be selected
- * @retval HAL status
- */
-uint32_t SDMMC_CmdSelDesel(SDIO_TypeDef *SDIOx, uint64_t Addr)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- /* Send CMD7 SDMMC_SEL_DESEL_CARD */
- sdmmc_cmdinit.Argument = (uint32_t)Addr;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEL_DESEL_CARD;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SEL_DESEL_CARD, SDIO_CMDTIMEOUT);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Go Idle State command and check the response.
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdGoIdleState(SDIO_TypeDef *SDIOx)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- sdmmc_cmdinit.Argument = 0U;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_GO_IDLE_STATE;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_NO;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdError(SDIOx);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Operating Condition command and check the response.
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdOperCond(SDIO_TypeDef *SDIOx)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- /* Send CMD8 to verify SD card interface operating condition */
- /* Argument: - [31:12]: Reserved (shall be set to '0')
- - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
- - [7:0]: Check Pattern (recommended 0xAA) */
- /* CMD Response: R7 */
- sdmmc_cmdinit.Argument = SDMMC_CHECK_PATTERN;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SEND_EXT_CSD;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp7(SDIOx);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Application command to verify that that the next command
- * is an application specific com-mand rather than a standard command
- * and check the response.
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdAppCommand(SDIO_TypeDef *SDIOx, uint32_t Argument)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- sdmmc_cmdinit.Argument = (uint32_t)Argument;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_APP_CMD;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- /* If there is a HAL_ERROR, it is a MMC card, else
- it is a SD card: SD card 2.0 (voltage range mismatch)
- or SD card 1.x */
- errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_APP_CMD, SDIO_CMDTIMEOUT);
-
- return errorstate;
-}
-
-/**
- * @brief Send the command asking the accessed card to send its operating
- * condition register (OCR)
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdAppOperCommand(SDIO_TypeDef *SDIOx, uint32_t SdType)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- sdmmc_cmdinit.Argument = SDMMC_VOLTAGE_WINDOW_SD | SdType;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_OP_COND;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp3(SDIOx);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Bus Width command and check the response.
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdBusWidth(SDIO_TypeDef *SDIOx, uint32_t BusWidth)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- sdmmc_cmdinit.Argument = (uint32_t)BusWidth;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_APP_SD_SET_BUSWIDTH;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_APP_SD_SET_BUSWIDTH, SDIO_CMDTIMEOUT);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Send SCR command and check the response.
- * @param SDIOx: Pointer to SDMMC register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdSendSCR(SDIO_TypeDef *SDIOx)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- /* Send CMD51 SD_APP_SEND_SCR */
- sdmmc_cmdinit.Argument = 0U;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_SEND_SCR;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_APP_SEND_SCR, SDIO_CMDTIMEOUT);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Send CID command and check the response.
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdSendCID(SDIO_TypeDef *SDIOx)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- /* Send CMD2 ALL_SEND_CID */
- sdmmc_cmdinit.Argument = 0U;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ALL_SEND_CID;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_LONG;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp2(SDIOx);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Send CSD command and check the response.
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdSendCSD(SDIO_TypeDef *SDIOx, uint32_t Argument)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- /* Send CMD9 SEND_CSD */
- sdmmc_cmdinit.Argument = (uint32_t)Argument;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_CSD;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_LONG;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp2(SDIOx);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Send CSD command and check the response.
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdSetRelAdd(SDIO_TypeDef *SDIOx, uint16_t *pRCA)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- /* Send CMD3 SD_CMD_SET_REL_ADDR */
- sdmmc_cmdinit.Argument = 0U;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_REL_ADDR;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp6(SDIOx, SDMMC_CMD_SET_REL_ADDR, pRCA);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Status command and check the response.
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdSendStatus(SDIO_TypeDef *SDIOx, uint32_t Argument)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- sdmmc_cmdinit.Argument = (uint32_t)Argument;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_STATUS;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SEND_STATUS, SDIO_CMDTIMEOUT);
-
- return errorstate;
-}
-
-/**
- * @brief Send the Status register command and check the response.
- * @param SDIOx: Pointer to SDIO register base
- * @retval HAL status
- */
-uint32_t SDMMC_CmdStatusRegister(SDIO_TypeDef *SDIOx)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- sdmmc_cmdinit.Argument = 0U;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_STATUS;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_APP_STATUS, SDIO_CMDTIMEOUT);
-
- return errorstate;
-}
-
-/**
- * @brief Sends host capacity support information and activates the card's
- * initialization process. Send SDMMC_CMD_SEND_OP_COND command
- * @param SDIOx: Pointer to SDIO register base
- * @parame Argument: Argument used for the command
- * @retval HAL status
- */
-uint32_t SDMMC_CmdOpCondition(SDIO_TypeDef *SDIOx, uint32_t Argument)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- sdmmc_cmdinit.Argument = Argument;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_OP_COND;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp3(SDIOx);
-
- return errorstate;
-}
-
-/**
- * @brief Checks switchable function and switch card function. SDMMC_CMD_HS_SWITCH comand
- * @param SDIOx: Pointer to SDIO register base
- * @parame Argument: Argument used for the command
- * @retval HAL status
- */
-uint32_t SDMMC_CmdSwitch(SDIO_TypeDef *SDIOx, uint32_t Argument)
-{
- SDIO_CmdInitTypeDef sdmmc_cmdinit;
- uint32_t errorstate = SDMMC_ERROR_NONE;
-
- sdmmc_cmdinit.Argument = Argument;
- sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SWITCH;
- sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
- sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
- sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
- SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
-
- /* Check for error conditions */
- errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_HS_SWITCH, SDIO_CMDTIMEOUT);
-
- return errorstate;
-}
-
-/**
- * @}
- */
-
-/* Private function ----------------------------------------------------------*/
-/** @addtogroup SD_Private_Functions
- * @{
- */
-
-/**
- * @brief Checks for error conditions for CMD0.
- * @param hsd: SD handle
- * @retval SD Card error state
- */
-static uint32_t SDMMC_GetCmdError(SDIO_TypeDef *SDIOx)
-{
- /* 8 is the number of required instructions cycles for the below loop statement.
- The SDMMC_CMDTIMEOUT is expressed in ms */
- register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
-
- do
- {
- if (count-- == 0U)
- {
- return SDMMC_ERROR_TIMEOUT;
- }
-
- }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CMDSENT));
-
- /* Clear all the static flags */
- __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
-
- return SDMMC_ERROR_NONE;
-}
-
-/**
- * @brief Checks for error conditions for R1 response.
- * @param hsd: SD handle
- * @param SD_CMD: The sent command index
- * @retval SD Card error state
- */
-static uint32_t SDMMC_GetCmdResp1(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint32_t Timeout)
-{
- uint32_t response_r1;
-
- /* 8 is the number of required instructions cycles for the below loop statement.
- The Timeout is expressed in ms */
- register uint32_t count = Timeout * (SystemCoreClock / 8U /1000U);
-
- do
- {
- if (count-- == 0U)
- {
- return SDMMC_ERROR_TIMEOUT;
- }
-
- }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
-
- if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
- {
- __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
-
- return SDMMC_ERROR_CMD_RSP_TIMEOUT;
- }
- else if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
- {
- __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
-
- return SDMMC_ERROR_CMD_CRC_FAIL;
- }
-
- /* Check response received is of desired command */
- if(SDIO_GetCommandResponse(SDIOx) != SD_CMD)
- {
- return SDMMC_ERROR_CMD_CRC_FAIL;
- }
-
- /* Clear all the static flags */
- __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
-
- /* We have received response, retrieve it for analysis */
- response_r1 = SDIO_GetResponse(SDIOx, SDIO_RESP1);
-
- if((response_r1 & SDMMC_OCR_ERRORBITS) == SDMMC_ALLZERO)
- {
- return SDMMC_ERROR_NONE;
- }
- else if((response_r1 & SDMMC_OCR_ADDR_OUT_OF_RANGE) == SDMMC_OCR_ADDR_OUT_OF_RANGE)
- {
- return SDMMC_ERROR_ADDR_OUT_OF_RANGE;
- }
- else if((response_r1 & SDMMC_OCR_ADDR_MISALIGNED) == SDMMC_OCR_ADDR_MISALIGNED)
- {
- return SDMMC_ERROR_ADDR_MISALIGNED;
- }
- else if((response_r1 & SDMMC_OCR_BLOCK_LEN_ERR) == SDMMC_OCR_BLOCK_LEN_ERR)
- {
- return SDMMC_ERROR_BLOCK_LEN_ERR;
- }
- else if((response_r1 & SDMMC_OCR_ERASE_SEQ_ERR) == SDMMC_OCR_ERASE_SEQ_ERR)
- {
- return SDMMC_ERROR_ERASE_SEQ_ERR;
- }
- else if((response_r1 & SDMMC_OCR_BAD_ERASE_PARAM) == SDMMC_OCR_BAD_ERASE_PARAM)
- {
- return SDMMC_ERROR_BAD_ERASE_PARAM;
- }
- else if((response_r1 & SDMMC_OCR_WRITE_PROT_VIOLATION) == SDMMC_OCR_WRITE_PROT_VIOLATION)
- {
- return SDMMC_ERROR_WRITE_PROT_VIOLATION;
- }
- else if((response_r1 & SDMMC_OCR_LOCK_UNLOCK_FAILED) == SDMMC_OCR_LOCK_UNLOCK_FAILED)
- {
- return SDMMC_ERROR_LOCK_UNLOCK_FAILED;
- }
- else if((response_r1 & SDMMC_OCR_COM_CRC_FAILED) == SDMMC_OCR_COM_CRC_FAILED)
- {
- return SDMMC_ERROR_COM_CRC_FAILED;
- }
- else if((response_r1 & SDMMC_OCR_ILLEGAL_CMD) == SDMMC_OCR_ILLEGAL_CMD)
- {
- return SDMMC_ERROR_ILLEGAL_CMD;
- }
- else if((response_r1 & SDMMC_OCR_CARD_ECC_FAILED) == SDMMC_OCR_CARD_ECC_FAILED)
- {
- return SDMMC_ERROR_CARD_ECC_FAILED;
- }
- else if((response_r1 & SDMMC_OCR_CC_ERROR) == SDMMC_OCR_CC_ERROR)
- {
- return SDMMC_ERROR_CC_ERR;
- }
- else if((response_r1 & SDMMC_OCR_STREAM_READ_UNDERRUN) == SDMMC_OCR_STREAM_READ_UNDERRUN)
- {
- return SDMMC_ERROR_STREAM_READ_UNDERRUN;
- }
- else if((response_r1 & SDMMC_OCR_STREAM_WRITE_OVERRUN) == SDMMC_OCR_STREAM_WRITE_OVERRUN)
- {
- return SDMMC_ERROR_STREAM_WRITE_OVERRUN;
- }
- else if((response_r1 & SDMMC_OCR_CID_CSD_OVERWRITE) == SDMMC_OCR_CID_CSD_OVERWRITE)
- {
- return SDMMC_ERROR_CID_CSD_OVERWRITE;
- }
- else if((response_r1 & SDMMC_OCR_WP_ERASE_SKIP) == SDMMC_OCR_WP_ERASE_SKIP)
- {
- return SDMMC_ERROR_WP_ERASE_SKIP;
- }
- else if((response_r1 & SDMMC_OCR_CARD_ECC_DISABLED) == SDMMC_OCR_CARD_ECC_DISABLED)
- {
- return SDMMC_ERROR_CARD_ECC_DISABLED;
- }
- else if((response_r1 & SDMMC_OCR_ERASE_RESET) == SDMMC_OCR_ERASE_RESET)
- {
- return SDMMC_ERROR_ERASE_RESET;
- }
- else if((response_r1 & SDMMC_OCR_AKE_SEQ_ERROR) == SDMMC_OCR_AKE_SEQ_ERROR)
- {
- return SDMMC_ERROR_AKE_SEQ_ERR;
- }
- else
- {
- return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
- }
-}
-
-/**
- * @brief Checks for error conditions for R2 (CID or CSD) response.
- * @param hsd: SD handle
- * @retval SD Card error state
- */
-static uint32_t SDMMC_GetCmdResp2(SDIO_TypeDef *SDIOx)
-{
- /* 8 is the number of required instructions cycles for the below loop statement.
- The SDMMC_CMDTIMEOUT is expressed in ms */
- register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
-
- do
- {
- if (count-- == 0U)
- {
- return SDMMC_ERROR_TIMEOUT;
- }
-
- }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
-
- if (__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
- {
- __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
-
- return SDMMC_ERROR_CMD_RSP_TIMEOUT;
- }
- else if (__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
- {
- __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
-
- return SDMMC_ERROR_CMD_CRC_FAIL;
- }
- else
- {
- /* No error flag set */
- /* Clear all the static flags */
- __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
- }
-
- return SDMMC_ERROR_NONE;
-}
-
-/**
- * @brief Checks for error conditions for R3 (OCR) response.
- * @param hsd: SD handle
- * @retval SD Card error state
- */
-static uint32_t SDMMC_GetCmdResp3(SDIO_TypeDef *SDIOx)
-{
- /* 8 is the number of required instructions cycles for the below loop statement.
- The SDMMC_CMDTIMEOUT is expressed in ms */
- register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
-
- do
- {
- if (count-- == 0U)
- {
- return SDMMC_ERROR_TIMEOUT;
- }
-
- }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
-
- if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
- {
- __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
-
- return SDMMC_ERROR_CMD_RSP_TIMEOUT;
- }
- else
-
- {
- /* Clear all the static flags */
- __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
- }
-
- return SDMMC_ERROR_NONE;
-}
-
-/**
- * @brief Checks for error conditions for R6 (RCA) response.
- * @param hsd: SD handle
- * @param SD_CMD: The sent command index
- * @param pRCA: Pointer to the variable that will contain the SD card relative
- * address RCA
- * @retval SD Card error state
- */
-static uint32_t SDMMC_GetCmdResp6(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint16_t *pRCA)
-{
- uint32_t response_r1;
-
- /* 8 is the number of required instructions cycles for the below loop statement.
- The SDMMC_CMDTIMEOUT is expressed in ms */
- register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
-
- do
- {
- if (count-- == 0U)
- {
- return SDMMC_ERROR_TIMEOUT;
- }
-
- }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
-
- if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
- {
- __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
-
- return SDMMC_ERROR_CMD_RSP_TIMEOUT;
- }
- else if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
- {
- __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
-
- return SDMMC_ERROR_CMD_CRC_FAIL;
- }
-
- /* Check response received is of desired command */
- if(SDIO_GetCommandResponse(SDIOx) != SD_CMD)
- {
- return SDMMC_ERROR_CMD_CRC_FAIL;
- }
-
- /* Clear all the static flags */
- __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
-
- /* We have received response, retrieve it. */
- response_r1 = SDIO_GetResponse(SDIOx, SDIO_RESP1);
-
- if((response_r1 & (SDMMC_R6_GENERAL_UNKNOWN_ERROR | SDMMC_R6_ILLEGAL_CMD | SDMMC_R6_COM_CRC_FAILED)) == SDMMC_ALLZERO)
- {
- *pRCA = (uint16_t) (response_r1 >> 16);
-
- return SDMMC_ERROR_NONE;
- }
- else if((response_r1 & SDMMC_R6_ILLEGAL_CMD) == SDMMC_R6_ILLEGAL_CMD)
- {
- return SDMMC_ERROR_ILLEGAL_CMD;
- }
- else if((response_r1 & SDMMC_R6_COM_CRC_FAILED) == SDMMC_R6_COM_CRC_FAILED)
- {
- return SDMMC_ERROR_COM_CRC_FAILED;
- }
- else
- {
- return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
- }
-}
-
-/**
- * @brief Checks for error conditions for R7 response.
- * @param hsd: SD handle
- * @retval SD Card error state
- */
-static uint32_t SDMMC_GetCmdResp7(SDIO_TypeDef *SDIOx)
-{
- /* 8 is the number of required instructions cycles for the below loop statement.
- The SDIO_CMDTIMEOUT is expressed in ms */
- register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
-
- do
- {
- if (count-- == 0U)
- {
- return SDMMC_ERROR_TIMEOUT;
- }
-
- }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
-
- if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
- {
- /* Card is SD V2.0 compliant */
- __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CMDREND);
-
- return SDMMC_ERROR_CMD_RSP_TIMEOUT;
- }
-
- if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CMDREND))
- {
- /* Card is SD V2.0 compliant */
- __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CMDREND);
- }
-
- return SDMMC_ERROR_NONE;
-
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* STM32F103xE || STM32F103xG */
-
-#endif /* (HAL_SD_MODULE_ENABLED) || (HAL_MMC_MODULE_ENABLED) */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_spi.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_spi.c
deleted file mode 100644
index 9e11b67..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_spi.c
+++ /dev/null
@@ -1,560 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_spi.c
- * @author MCD Application Team
- * @brief SPI LL module driver.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-#if defined(USE_FULL_LL_DRIVER)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_spi.h"
-#include "stm32f1xx_ll_bus.h"
-#include "stm32f1xx_ll_rcc.h"
-
-#ifdef USE_FULL_ASSERT
-#include "stm32_assert.h"
-#else
-#define assert_param(expr) ((void)0U)
-#endif
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined (SPI1) || defined (SPI2) || defined (SPI3)
-
-/** @addtogroup SPI_LL
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup SPI_LL_Private_Constants SPI Private Constants
- * @{
- */
-/* SPI registers Masks */
-#define SPI_CR1_CLEAR_MASK (SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_MSTR | \
- SPI_CR1_BR | SPI_CR1_LSBFIRST | SPI_CR1_SSI | \
- SPI_CR1_SSM | SPI_CR1_RXONLY | SPI_CR1_DFF | \
- SPI_CR1_CRCNEXT | SPI_CR1_CRCEN | SPI_CR1_BIDIOE | \
- SPI_CR1_BIDIMODE)
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup SPI_LL_Private_Macros SPI Private Macros
- * @{
- */
-#define IS_LL_SPI_TRANSFER_DIRECTION(__VALUE__) (((__VALUE__) == LL_SPI_FULL_DUPLEX) \
- || ((__VALUE__) == LL_SPI_SIMPLEX_RX) \
- || ((__VALUE__) == LL_SPI_HALF_DUPLEX_RX) \
- || ((__VALUE__) == LL_SPI_HALF_DUPLEX_TX))
-
-#define IS_LL_SPI_MODE(__VALUE__) (((__VALUE__) == LL_SPI_MODE_MASTER) \
- || ((__VALUE__) == LL_SPI_MODE_SLAVE))
-
-#define IS_LL_SPI_DATAWIDTH(__VALUE__) (((__VALUE__) == LL_SPI_DATAWIDTH_8BIT) \
- || ((__VALUE__) == LL_SPI_DATAWIDTH_16BIT))
-
-#define IS_LL_SPI_POLARITY(__VALUE__) (((__VALUE__) == LL_SPI_POLARITY_LOW) \
- || ((__VALUE__) == LL_SPI_POLARITY_HIGH))
-
-#define IS_LL_SPI_PHASE(__VALUE__) (((__VALUE__) == LL_SPI_PHASE_1EDGE) \
- || ((__VALUE__) == LL_SPI_PHASE_2EDGE))
-
-#define IS_LL_SPI_NSS(__VALUE__) (((__VALUE__) == LL_SPI_NSS_SOFT) \
- || ((__VALUE__) == LL_SPI_NSS_HARD_INPUT) \
- || ((__VALUE__) == LL_SPI_NSS_HARD_OUTPUT))
-
-#define IS_LL_SPI_BAUDRATE(__VALUE__) (((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV2) \
- || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV4) \
- || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV8) \
- || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV16) \
- || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV32) \
- || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV64) \
- || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV128) \
- || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV256))
-
-#define IS_LL_SPI_BITORDER(__VALUE__) (((__VALUE__) == LL_SPI_LSB_FIRST) \
- || ((__VALUE__) == LL_SPI_MSB_FIRST))
-
-#define IS_LL_SPI_CRCCALCULATION(__VALUE__) (((__VALUE__) == LL_SPI_CRCCALCULATION_ENABLE) \
- || ((__VALUE__) == LL_SPI_CRCCALCULATION_DISABLE))
-
-#define IS_LL_SPI_CRC_POLYNOMIAL(__VALUE__) ((__VALUE__) >= 0x1U)
-
-/**
- * @}
- */
-
-/* Private function prototypes -----------------------------------------------*/
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup SPI_LL_Exported_Functions
- * @{
- */
-
-/** @addtogroup SPI_LL_EF_Init
- * @{
- */
-
-/**
- * @brief De-initialize the SPI registers to their default reset values.
- * @param SPIx SPI Instance
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: SPI registers are de-initialized
- * - ERROR: SPI registers are not de-initialized
- */
-ErrorStatus LL_SPI_DeInit(SPI_TypeDef *SPIx)
-{
- ErrorStatus status = ERROR;
-
- /* Check the parameters */
- assert_param(IS_SPI_ALL_INSTANCE(SPIx));
-
-#if defined(SPI1)
- if (SPIx == SPI1)
- {
- /* Force reset of SPI clock */
- LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
-
- /* Release reset of SPI clock */
- LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1);
-
- status = SUCCESS;
- }
-#endif /* SPI1 */
-#if defined(SPI2)
- if (SPIx == SPI2)
- {
- /* Force reset of SPI clock */
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
-
- /* Release reset of SPI clock */
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2);
-
- status = SUCCESS;
- }
-#endif /* SPI2 */
-#if defined(SPI3)
- if (SPIx == SPI3)
- {
- /* Force reset of SPI clock */
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI3);
-
- /* Release reset of SPI clock */
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI3);
-
- status = SUCCESS;
- }
-#endif /* SPI3 */
-
- return status;
-}
-
-/**
- * @brief Initialize the SPI registers according to the specified parameters in SPI_InitStruct.
- * @note As some bits in SPI configuration registers can only be written when the SPI is disabled (SPI_CR1_SPE bit =0),
- * SPI IP should be in disabled state prior calling this function. Otherwise, ERROR result will be returned.
- * @param SPIx SPI Instance
- * @param SPI_InitStruct pointer to a @ref LL_SPI_InitTypeDef structure
- * @retval An ErrorStatus enumeration value. (Return always SUCCESS)
- */
-ErrorStatus LL_SPI_Init(SPI_TypeDef *SPIx, LL_SPI_InitTypeDef *SPI_InitStruct)
-{
- ErrorStatus status = ERROR;
-
- /* Check the SPI Instance SPIx*/
- assert_param(IS_SPI_ALL_INSTANCE(SPIx));
-
- /* Check the SPI parameters from SPI_InitStruct*/
- assert_param(IS_LL_SPI_TRANSFER_DIRECTION(SPI_InitStruct->TransferDirection));
- assert_param(IS_LL_SPI_MODE(SPI_InitStruct->Mode));
- assert_param(IS_LL_SPI_DATAWIDTH(SPI_InitStruct->DataWidth));
- assert_param(IS_LL_SPI_POLARITY(SPI_InitStruct->ClockPolarity));
- assert_param(IS_LL_SPI_PHASE(SPI_InitStruct->ClockPhase));
- assert_param(IS_LL_SPI_NSS(SPI_InitStruct->NSS));
- assert_param(IS_LL_SPI_BAUDRATE(SPI_InitStruct->BaudRate));
- assert_param(IS_LL_SPI_BITORDER(SPI_InitStruct->BitOrder));
- assert_param(IS_LL_SPI_CRCCALCULATION(SPI_InitStruct->CRCCalculation));
-
- if (LL_SPI_IsEnabled(SPIx) == 0x00000000U)
- {
- /*---------------------------- SPIx CR1 Configuration ------------------------
- * Configure SPIx CR1 with parameters:
- * - TransferDirection: SPI_CR1_BIDIMODE, SPI_CR1_BIDIOE and SPI_CR1_RXONLY bits
- * - Master/Slave Mode: SPI_CR1_MSTR bit
- * - DataWidth: SPI_CR1_DFF bit
- * - ClockPolarity: SPI_CR1_CPOL bit
- * - ClockPhase: SPI_CR1_CPHA bit
- * - NSS management: SPI_CR1_SSM bit
- * - BaudRate prescaler: SPI_CR1_BR[2:0] bits
- * - BitOrder: SPI_CR1_LSBFIRST bit
- * - CRCCalculation: SPI_CR1_CRCEN bit
- */
- MODIFY_REG(SPIx->CR1,
- SPI_CR1_CLEAR_MASK,
- SPI_InitStruct->TransferDirection | SPI_InitStruct->Mode | SPI_InitStruct->DataWidth |
- SPI_InitStruct->ClockPolarity | SPI_InitStruct->ClockPhase |
- SPI_InitStruct->NSS | SPI_InitStruct->BaudRate |
- SPI_InitStruct->BitOrder | SPI_InitStruct->CRCCalculation);
-
- /*---------------------------- SPIx CR2 Configuration ------------------------
- * Configure SPIx CR2 with parameters:
- * - NSS management: SSOE bit
- */
- MODIFY_REG(SPIx->CR2, SPI_CR2_SSOE, (SPI_InitStruct->NSS >> 16U));
-
- /*---------------------------- SPIx CRCPR Configuration ----------------------
- * Configure SPIx CRCPR with parameters:
- * - CRCPoly: CRCPOLY[15:0] bits
- */
- if (SPI_InitStruct->CRCCalculation == LL_SPI_CRCCALCULATION_ENABLE)
- {
- assert_param(IS_LL_SPI_CRC_POLYNOMIAL(SPI_InitStruct->CRCPoly));
- LL_SPI_SetCRCPolynomial(SPIx, SPI_InitStruct->CRCPoly);
- }
- status = SUCCESS;
- }
-
-#if defined (SPI_I2S_SUPPORT)
- /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */
- CLEAR_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SMOD);
-#endif /* SPI_I2S_SUPPORT */
- return status;
-}
-
-/**
- * @brief Set each @ref LL_SPI_InitTypeDef field to default value.
- * @param SPI_InitStruct pointer to a @ref LL_SPI_InitTypeDef structure
- * whose fields will be set to default values.
- * @retval None
- */
-void LL_SPI_StructInit(LL_SPI_InitTypeDef *SPI_InitStruct)
-{
- /* Set SPI_InitStruct fields to default values */
- SPI_InitStruct->TransferDirection = LL_SPI_FULL_DUPLEX;
- SPI_InitStruct->Mode = LL_SPI_MODE_SLAVE;
- SPI_InitStruct->DataWidth = LL_SPI_DATAWIDTH_8BIT;
- SPI_InitStruct->ClockPolarity = LL_SPI_POLARITY_LOW;
- SPI_InitStruct->ClockPhase = LL_SPI_PHASE_1EDGE;
- SPI_InitStruct->NSS = LL_SPI_NSS_HARD_INPUT;
- SPI_InitStruct->BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2;
- SPI_InitStruct->BitOrder = LL_SPI_MSB_FIRST;
- SPI_InitStruct->CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
- SPI_InitStruct->CRCPoly = 7U;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#if defined(SPI_I2S_SUPPORT)
-/** @addtogroup I2S_LL
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup I2S_LL_Private_Constants I2S Private Constants
- * @{
- */
-/* I2S registers Masks */
-#define I2S_I2SCFGR_CLEAR_MASK (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | \
- SPI_I2SCFGR_CKPOL | SPI_I2SCFGR_I2SSTD | \
- SPI_I2SCFGR_I2SCFG | SPI_I2SCFGR_I2SMOD )
-
-#define I2S_I2SPR_CLEAR_MASK 0x0002U
-/**
- * @}
- */
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup I2S_LL_Private_Macros I2S Private Macros
- * @{
- */
-
-#define IS_LL_I2S_DATAFORMAT(__VALUE__) (((__VALUE__) == LL_I2S_DATAFORMAT_16B) \
- || ((__VALUE__) == LL_I2S_DATAFORMAT_16B_EXTENDED) \
- || ((__VALUE__) == LL_I2S_DATAFORMAT_24B) \
- || ((__VALUE__) == LL_I2S_DATAFORMAT_32B))
-
-#define IS_LL_I2S_CPOL(__VALUE__) (((__VALUE__) == LL_I2S_POLARITY_LOW) \
- || ((__VALUE__) == LL_I2S_POLARITY_HIGH))
-
-#define IS_LL_I2S_STANDARD(__VALUE__) (((__VALUE__) == LL_I2S_STANDARD_PHILIPS) \
- || ((__VALUE__) == LL_I2S_STANDARD_MSB) \
- || ((__VALUE__) == LL_I2S_STANDARD_LSB) \
- || ((__VALUE__) == LL_I2S_STANDARD_PCM_SHORT) \
- || ((__VALUE__) == LL_I2S_STANDARD_PCM_LONG))
-
-#define IS_LL_I2S_MODE(__VALUE__) (((__VALUE__) == LL_I2S_MODE_SLAVE_TX) \
- || ((__VALUE__) == LL_I2S_MODE_SLAVE_RX) \
- || ((__VALUE__) == LL_I2S_MODE_MASTER_TX) \
- || ((__VALUE__) == LL_I2S_MODE_MASTER_RX))
-
-#define IS_LL_I2S_MCLK_OUTPUT(__VALUE__) (((__VALUE__) == LL_I2S_MCLK_OUTPUT_ENABLE) \
- || ((__VALUE__) == LL_I2S_MCLK_OUTPUT_DISABLE))
-
-#define IS_LL_I2S_AUDIO_FREQ(__VALUE__) ((((__VALUE__) >= LL_I2S_AUDIOFREQ_8K) \
- && ((__VALUE__) <= LL_I2S_AUDIOFREQ_192K)) \
- || ((__VALUE__) == LL_I2S_AUDIOFREQ_DEFAULT))
-
-#define IS_LL_I2S_PRESCALER_LINEAR(__VALUE__) ((__VALUE__) >= 0x2U)
-
-#define IS_LL_I2S_PRESCALER_PARITY(__VALUE__) (((__VALUE__) == LL_I2S_PRESCALER_PARITY_EVEN) \
- || ((__VALUE__) == LL_I2S_PRESCALER_PARITY_ODD))
-/**
- * @}
- */
-
-/* Private function prototypes -----------------------------------------------*/
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup I2S_LL_Exported_Functions
- * @{
- */
-
-/** @addtogroup I2S_LL_EF_Init
- * @{
- */
-
-/**
- * @brief De-initialize the SPI/I2S registers to their default reset values.
- * @param SPIx SPI Instance
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: SPI registers are de-initialized
- * - ERROR: SPI registers are not de-initialized
- */
-ErrorStatus LL_I2S_DeInit(SPI_TypeDef *SPIx)
-{
- return LL_SPI_DeInit(SPIx);
-}
-
-/**
- * @brief Initializes the SPI/I2S registers according to the specified parameters in I2S_InitStruct.
- * @note As some bits in SPI configuration registers can only be written when the SPI is disabled (SPI_CR1_SPE bit =0),
- * SPI IP should be in disabled state prior calling this function. Otherwise, ERROR result will be returned.
- * @param SPIx SPI Instance
- * @param I2S_InitStruct pointer to a @ref LL_I2S_InitTypeDef structure
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: SPI registers are Initialized
- * - ERROR: SPI registers are not Initialized
- */
-ErrorStatus LL_I2S_Init(SPI_TypeDef *SPIx, LL_I2S_InitTypeDef *I2S_InitStruct)
-{
- uint16_t i2sdiv = 2U, i2sodd = 0U, packetlength = 1U;
- uint32_t tmp = 0U;
- uint32_t sourceclock = 0U;
-#if defined(I2S2_I2S3_CLOCK_FEATURE)
-#else
- LL_RCC_ClocksTypeDef rcc_clocks;
-#endif /* I2S2_I2S3_CLOCK_FEATURE */
- ErrorStatus status = ERROR;
-
- /* Check the I2S parameters */
- assert_param(IS_I2S_ALL_INSTANCE(SPIx));
- assert_param(IS_LL_I2S_MODE(I2S_InitStruct->Mode));
- assert_param(IS_LL_I2S_STANDARD(I2S_InitStruct->Standard));
- assert_param(IS_LL_I2S_DATAFORMAT(I2S_InitStruct->DataFormat));
- assert_param(IS_LL_I2S_MCLK_OUTPUT(I2S_InitStruct->MCLKOutput));
- assert_param(IS_LL_I2S_AUDIO_FREQ(I2S_InitStruct->AudioFreq));
- assert_param(IS_LL_I2S_CPOL(I2S_InitStruct->ClockPolarity));
-
- if (LL_I2S_IsEnabled(SPIx) == 0x00000000U)
- {
- /*---------------------------- SPIx I2SCFGR Configuration --------------------
- * Configure SPIx I2SCFGR with parameters:
- * - Mode: SPI_I2SCFGR_I2SCFG[1:0] bit
- * - Standard: SPI_I2SCFGR_I2SSTD[1:0] and SPI_I2SCFGR_PCMSYNC bits
- * - DataFormat: SPI_I2SCFGR_CHLEN and SPI_I2SCFGR_DATLEN bits
- * - ClockPolarity: SPI_I2SCFGR_CKPOL bit
- */
-
- /* Write to SPIx I2SCFGR */
- MODIFY_REG(SPIx->I2SCFGR,
- I2S_I2SCFGR_CLEAR_MASK,
- I2S_InitStruct->Mode | I2S_InitStruct->Standard |
- I2S_InitStruct->DataFormat | I2S_InitStruct->ClockPolarity |
- SPI_I2SCFGR_I2SMOD);
-
- /*---------------------------- SPIx I2SPR Configuration ----------------------
- * Configure SPIx I2SPR with parameters:
- * - MCLKOutput: SPI_I2SPR_MCKOE bit
- * - AudioFreq: SPI_I2SPR_I2SDIV[7:0] and SPI_I2SPR_ODD bits
- */
-
- /* If the requested audio frequency is not the default, compute the prescaler (i2sodd, i2sdiv)
- * else, default values are used: i2sodd = 0U, i2sdiv = 2U.
- */
- if (I2S_InitStruct->AudioFreq != LL_I2S_AUDIOFREQ_DEFAULT)
- {
- /* Check the frame length (For the Prescaler computing)
- * Default value: LL_I2S_DATAFORMAT_16B (packetlength = 1U).
- */
- if (I2S_InitStruct->DataFormat != LL_I2S_DATAFORMAT_16B)
- {
- /* Packet length is 32 bits */
- packetlength = 2U;
- }
-#if defined(I2S2_I2S3_CLOCK_FEATURE)
- /* If an external I2S clock has to be used, the specific define should be set
- in the project configuration or in the stm32f1xx_ll_rcc.h file */
- if(SPIx == SPI2)
- {
- /* Get the I2S source clock value */
- sourceclock = LL_RCC_GetI2SClockFreq(LL_RCC_I2S2_CLKSOURCE);
- }
- else /* SPI3 */
- {
- /* Get the I2S source clock value */
- sourceclock = LL_RCC_GetI2SClockFreq(LL_RCC_I2S3_CLKSOURCE);
- }
-#else
- /* I2S Clock source is System clock: Get System Clock frequency */
- LL_RCC_GetSystemClocksFreq(&rcc_clocks);
-
- /* Get the source clock value: based on System Clock value */
- sourceclock = rcc_clocks.SYSCLK_Frequency;
-#endif /* I2S2_I2S3_CLOCK_FEATURE */
- /* Compute the Real divider depending on the MCLK output state with a floating point */
- if (I2S_InitStruct->MCLKOutput == LL_I2S_MCLK_OUTPUT_ENABLE)
- {
- /* MCLK output is enabled */
- tmp = (uint16_t)(((((sourceclock / 256U) * 10U) / I2S_InitStruct->AudioFreq)) + 5U);
- }
- else
- {
- /* MCLK output is disabled */
- tmp = (uint16_t)(((((sourceclock / (32U * packetlength)) * 10U) / I2S_InitStruct->AudioFreq)) + 5U);
- }
-
- /* Remove the floating point */
- tmp = tmp / 10U;
-
- /* Check the parity of the divider */
- i2sodd = (uint16_t)(tmp & (uint16_t)0x0001U);
-
- /* Compute the i2sdiv prescaler */
- i2sdiv = (uint16_t)((tmp - i2sodd) / 2U);
-
- /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
- i2sodd = (uint16_t)(i2sodd << 8U);
- }
-
- /* Test if the divider is 1 or 0 or greater than 0xFF */
- if ((i2sdiv < 2U) || (i2sdiv > 0xFFU))
- {
- /* Set the default values */
- i2sdiv = 2U;
- i2sodd = 0U;
- }
-
- /* Write to SPIx I2SPR register the computed value */
- WRITE_REG(SPIx->I2SPR, i2sdiv | i2sodd | I2S_InitStruct->MCLKOutput);
-
- status = SUCCESS;
- }
- return status;
-}
-
-/**
- * @brief Set each @ref LL_I2S_InitTypeDef field to default value.
- * @param I2S_InitStruct pointer to a @ref LL_I2S_InitTypeDef structure
- * whose fields will be set to default values.
- * @retval None
- */
-void LL_I2S_StructInit(LL_I2S_InitTypeDef *I2S_InitStruct)
-{
- /*--------------- Reset I2S init structure parameters values -----------------*/
- I2S_InitStruct->Mode = LL_I2S_MODE_SLAVE_TX;
- I2S_InitStruct->Standard = LL_I2S_STANDARD_PHILIPS;
- I2S_InitStruct->DataFormat = LL_I2S_DATAFORMAT_16B;
- I2S_InitStruct->MCLKOutput = LL_I2S_MCLK_OUTPUT_DISABLE;
- I2S_InitStruct->AudioFreq = LL_I2S_AUDIOFREQ_DEFAULT;
- I2S_InitStruct->ClockPolarity = LL_I2S_POLARITY_LOW;
-}
-
-/**
- * @brief Set linear and parity prescaler.
- * @note To calculate value of PrescalerLinear(I2SDIV[7:0] bits) and PrescalerParity(ODD bit)\n
- * Check Audio frequency table and formulas inside Reference Manual (SPI/I2S).
- * @param SPIx SPI Instance
- * @param PrescalerLinear value: Min_Data=0x02 and Max_Data=0xFF.
- * @param PrescalerParity This parameter can be one of the following values:
- * @arg @ref LL_I2S_PRESCALER_PARITY_EVEN
- * @arg @ref LL_I2S_PRESCALER_PARITY_ODD
- * @retval None
- */
-void LL_I2S_ConfigPrescaler(SPI_TypeDef *SPIx, uint32_t PrescalerLinear, uint32_t PrescalerParity)
-{
- /* Check the I2S parameters */
- assert_param(IS_I2S_ALL_INSTANCE(SPIx));
- assert_param(IS_LL_I2S_PRESCALER_LINEAR(PrescalerLinear));
- assert_param(IS_LL_I2S_PRESCALER_PARITY(PrescalerParity));
-
- /* Write to SPIx I2SPR */
- MODIFY_REG(SPIx->I2SPR, SPI_I2SPR_I2SDIV | SPI_I2SPR_ODD, PrescalerLinear | (PrescalerParity << 8U));
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-#endif /* SPI_I2S_SUPPORT */
-
-#endif /* defined (SPI1) || defined (SPI2) || defined (SPI3) */
-
-/**
- * @}
- */
-
-#endif /* USE_FULL_LL_DRIVER */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_tim.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_tim.c
deleted file mode 100644
index 63ee597..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_tim.c
+++ /dev/null
@@ -1,1214 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_tim.c
- * @author MCD Application Team
- * @brief TIM LL module driver.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-#if defined(USE_FULL_LL_DRIVER)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_tim.h"
-#include "stm32f1xx_ll_bus.h"
-
-#ifdef USE_FULL_ASSERT
-#include "stm32_assert.h"
-#else
-#define assert_param(expr) ((void)0U)
-#endif
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined (TIM1) || defined (TIM2) || defined (TIM3) || defined (TIM4) || defined (TIM5) || defined (TIM6) || defined (TIM7) || defined (TIM8) || defined (TIM9) || defined (TIM10) || defined (TIM11) || defined (TIM12) || defined (TIM13) || defined (TIM14) || defined (TIM15) || defined (TIM16) || defined (TIM17)
-
-/** @addtogroup TIM_LL
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-/** @addtogroup TIM_LL_Private_Macros
- * @{
- */
-#define IS_LL_TIM_COUNTERMODE(__VALUE__) (((__VALUE__) == LL_TIM_COUNTERMODE_UP) \
- || ((__VALUE__) == LL_TIM_COUNTERMODE_DOWN) \
- || ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_UP) \
- || ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_DOWN) \
- || ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_UP_DOWN))
-
-#define IS_LL_TIM_CLOCKDIVISION(__VALUE__) (((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV1) \
- || ((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV2) \
- || ((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV4))
-
-#define IS_LL_TIM_OCMODE(__VALUE__) (((__VALUE__) == LL_TIM_OCMODE_FROZEN) \
- || ((__VALUE__) == LL_TIM_OCMODE_ACTIVE) \
- || ((__VALUE__) == LL_TIM_OCMODE_INACTIVE) \
- || ((__VALUE__) == LL_TIM_OCMODE_TOGGLE) \
- || ((__VALUE__) == LL_TIM_OCMODE_FORCED_INACTIVE) \
- || ((__VALUE__) == LL_TIM_OCMODE_FORCED_ACTIVE) \
- || ((__VALUE__) == LL_TIM_OCMODE_PWM1) \
- || ((__VALUE__) == LL_TIM_OCMODE_PWM2))
-
-#define IS_LL_TIM_OCSTATE(__VALUE__) (((__VALUE__) == LL_TIM_OCSTATE_DISABLE) \
- || ((__VALUE__) == LL_TIM_OCSTATE_ENABLE))
-
-#define IS_LL_TIM_OCPOLARITY(__VALUE__) (((__VALUE__) == LL_TIM_OCPOLARITY_HIGH) \
- || ((__VALUE__) == LL_TIM_OCPOLARITY_LOW))
-
-#define IS_LL_TIM_OCIDLESTATE(__VALUE__) (((__VALUE__) == LL_TIM_OCIDLESTATE_LOW) \
- || ((__VALUE__) == LL_TIM_OCIDLESTATE_HIGH))
-
-#define IS_LL_TIM_ACTIVEINPUT(__VALUE__) (((__VALUE__) == LL_TIM_ACTIVEINPUT_DIRECTTI) \
- || ((__VALUE__) == LL_TIM_ACTIVEINPUT_INDIRECTTI) \
- || ((__VALUE__) == LL_TIM_ACTIVEINPUT_TRC))
-
-#define IS_LL_TIM_ICPSC(__VALUE__) (((__VALUE__) == LL_TIM_ICPSC_DIV1) \
- || ((__VALUE__) == LL_TIM_ICPSC_DIV2) \
- || ((__VALUE__) == LL_TIM_ICPSC_DIV4) \
- || ((__VALUE__) == LL_TIM_ICPSC_DIV8))
-
-#define IS_LL_TIM_IC_FILTER(__VALUE__) (((__VALUE__) == LL_TIM_IC_FILTER_FDIV1) \
- || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N2) \
- || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N4) \
- || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N8) \
- || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV2_N6) \
- || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV2_N8) \
- || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV4_N6) \
- || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV4_N8) \
- || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV8_N6) \
- || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV8_N8) \
- || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N5) \
- || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N6) \
- || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N8) \
- || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N5) \
- || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N6) \
- || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N8))
-
-#define IS_LL_TIM_IC_POLARITY(__VALUE__) (((__VALUE__) == LL_TIM_IC_POLARITY_RISING) \
- || ((__VALUE__) == LL_TIM_IC_POLARITY_FALLING))
-
-#define IS_LL_TIM_ENCODERMODE(__VALUE__) (((__VALUE__) == LL_TIM_ENCODERMODE_X2_TI1) \
- || ((__VALUE__) == LL_TIM_ENCODERMODE_X2_TI2) \
- || ((__VALUE__) == LL_TIM_ENCODERMODE_X4_TI12))
-
-#define IS_LL_TIM_IC_POLARITY_ENCODER(__VALUE__) (((__VALUE__) == LL_TIM_IC_POLARITY_RISING) \
- || ((__VALUE__) == LL_TIM_IC_POLARITY_FALLING))
-
-#define IS_LL_TIM_OSSR_STATE(__VALUE__) (((__VALUE__) == LL_TIM_OSSR_DISABLE) \
- || ((__VALUE__) == LL_TIM_OSSR_ENABLE))
-
-#define IS_LL_TIM_OSSI_STATE(__VALUE__) (((__VALUE__) == LL_TIM_OSSI_DISABLE) \
- || ((__VALUE__) == LL_TIM_OSSI_ENABLE))
-
-#define IS_LL_TIM_LOCK_LEVEL(__VALUE__) (((__VALUE__) == LL_TIM_LOCKLEVEL_OFF) \
- || ((__VALUE__) == LL_TIM_LOCKLEVEL_1) \
- || ((__VALUE__) == LL_TIM_LOCKLEVEL_2) \
- || ((__VALUE__) == LL_TIM_LOCKLEVEL_3))
-
-#define IS_LL_TIM_BREAK_STATE(__VALUE__) (((__VALUE__) == LL_TIM_BREAK_DISABLE) \
- || ((__VALUE__) == LL_TIM_BREAK_ENABLE))
-
-#define IS_LL_TIM_BREAK_POLARITY(__VALUE__) (((__VALUE__) == LL_TIM_BREAK_POLARITY_LOW) \
- || ((__VALUE__) == LL_TIM_BREAK_POLARITY_HIGH))
-
-#define IS_LL_TIM_AUTOMATIC_OUTPUT_STATE(__VALUE__) (((__VALUE__) == LL_TIM_AUTOMATICOUTPUT_DISABLE) \
- || ((__VALUE__) == LL_TIM_AUTOMATICOUTPUT_ENABLE))
-/**
- * @}
- */
-
-
-/* Private function prototypes -----------------------------------------------*/
-/** @defgroup TIM_LL_Private_Functions TIM Private Functions
- * @{
- */
-static ErrorStatus OC1Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct);
-static ErrorStatus OC2Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct);
-static ErrorStatus OC3Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct);
-static ErrorStatus OC4Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct);
-static ErrorStatus IC1Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct);
-static ErrorStatus IC2Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct);
-static ErrorStatus IC3Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct);
-static ErrorStatus IC4Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct);
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup TIM_LL_Exported_Functions
- * @{
- */
-
-/** @addtogroup TIM_LL_EF_Init
- * @{
- */
-
-/**
- * @brief Set TIMx registers to their reset values.
- * @param TIMx Timer instance
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: TIMx registers are de-initialized
- * - ERROR: invalid TIMx instance
- */
-ErrorStatus LL_TIM_DeInit(TIM_TypeDef *TIMx)
-{
- ErrorStatus result = SUCCESS;
-
- /* Check the parameters */
- assert_param(IS_TIM_INSTANCE(TIMx));
-
- if (TIMx == TIM2)
- {
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM2);
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM2);
- }
-#if defined(TIM1)
- else if (TIMx == TIM1)
- {
- LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM1);
- LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM1);
- }
-#endif
-#if defined(TIM3)
- else if (TIMx == TIM3)
- {
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM3);
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM3);
- }
-#endif
-#if defined(TIM4)
- else if (TIMx == TIM4)
- {
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM4);
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM4);
- }
-#endif
-#if defined(TIM5)
- else if (TIMx == TIM5)
- {
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM5);
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM5);
- }
-#endif
-#if defined(TIM6)
- else if (TIMx == TIM6)
- {
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM6);
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM6);
- }
-#endif
-#if defined (TIM7)
- else if (TIMx == TIM7)
- {
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM7);
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM7);
- }
-#endif
-#if defined(TIM8)
- else if (TIMx == TIM8)
- {
- LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM8);
- LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM8);
- }
-#endif
-#if defined(TIM9)
- else if (TIMx == TIM9)
- {
- LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM9);
- LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM9);
- }
-#endif
-#if defined(TIM10)
- else if (TIMx == TIM10)
- {
- LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM10);
- LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM10);
- }
-#endif
-#if defined(TIM11)
- else if (TIMx == TIM11)
- {
- LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM11);
- LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM11);
- }
-#endif
-#if defined(TIM12)
- else if (TIMx == TIM12)
- {
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM12);
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM12);
- }
-#endif
-#if defined(TIM13)
- else if (TIMx == TIM13)
- {
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM13);
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM13);
- }
-#endif
-#if defined(TIM14)
- else if (TIMx == TIM14)
- {
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM14);
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM14);
- }
-#endif
-#if defined(TIM15)
- else if (TIMx == TIM15)
- {
- LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM15);
- LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM15);
- }
-#endif
-#if defined(TIM16)
- else if (TIMx == TIM16)
- {
- LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM16);
- LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM16);
- }
-#endif
-#if defined(TIM17)
- else if (TIMx == TIM17)
- {
- LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM17);
- LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM17);
- }
-#endif
- else
- {
- result = ERROR;
- }
-
- return result;
-}
-
-/**
- * @brief Set the fields of the time base unit configuration data structure
- * to their default values.
- * @param TIM_InitStruct pointer to a @ref LL_TIM_InitTypeDef structure (time base unit configuration data structure)
- * @retval None
- */
-void LL_TIM_StructInit(LL_TIM_InitTypeDef *TIM_InitStruct)
-{
- /* Set the default configuration */
- TIM_InitStruct->Prescaler = (uint16_t)0x0000;
- TIM_InitStruct->CounterMode = LL_TIM_COUNTERMODE_UP;
- TIM_InitStruct->Autoreload = 0xFFFFFFFFU;
- TIM_InitStruct->ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
- TIM_InitStruct->RepetitionCounter = (uint8_t)0x00;
-}
-
-/**
- * @brief Configure the TIMx time base unit.
- * @param TIMx Timer Instance
- * @param TIM_InitStruct pointer to a @ref LL_TIM_InitTypeDef structure (TIMx time base unit configuration data structure)
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: TIMx registers are de-initialized
- * - ERROR: not applicable
- */
-ErrorStatus LL_TIM_Init(TIM_TypeDef *TIMx, LL_TIM_InitTypeDef *TIM_InitStruct)
-{
- uint32_t tmpcr1 = 0U;
-
- /* Check the parameters */
- assert_param(IS_TIM_INSTANCE(TIMx));
- assert_param(IS_LL_TIM_COUNTERMODE(TIM_InitStruct->CounterMode));
- assert_param(IS_LL_TIM_CLOCKDIVISION(TIM_InitStruct->ClockDivision));
-
- tmpcr1 = LL_TIM_ReadReg(TIMx, CR1);
-
- if (IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx))
- {
- /* Select the Counter Mode */
- MODIFY_REG(tmpcr1, (TIM_CR1_DIR | TIM_CR1_CMS), TIM_InitStruct->CounterMode);
- }
-
- if (IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx))
- {
- /* Set the clock division */
- MODIFY_REG(tmpcr1, TIM_CR1_CKD, TIM_InitStruct->ClockDivision);
- }
-
- /* Write to TIMx CR1 */
- LL_TIM_WriteReg(TIMx, CR1, tmpcr1);
-
- /* Set the Autoreload value */
- LL_TIM_SetAutoReload(TIMx, TIM_InitStruct->Autoreload);
-
- /* Set the Prescaler value */
- LL_TIM_SetPrescaler(TIMx, TIM_InitStruct->Prescaler);
-
- if (IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx))
- {
- /* Set the Repetition Counter value */
- LL_TIM_SetRepetitionCounter(TIMx, TIM_InitStruct->RepetitionCounter);
- }
-
- /* Generate an update event to reload the Prescaler
- and the repetition counter value (if applicable) immediately */
- LL_TIM_GenerateEvent_UPDATE(TIMx);
-
- return SUCCESS;
-}
-
-/**
- * @brief Set the fields of the TIMx output channel configuration data
- * structure to their default values.
- * @param TIM_OC_InitStruct pointer to a @ref LL_TIM_OC_InitTypeDef structure (the output channel configuration data structure)
- * @retval None
- */
-void LL_TIM_OC_StructInit(LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct)
-{
- /* Set the default configuration */
- TIM_OC_InitStruct->OCMode = LL_TIM_OCMODE_FROZEN;
- TIM_OC_InitStruct->OCState = LL_TIM_OCSTATE_DISABLE;
- TIM_OC_InitStruct->OCNState = LL_TIM_OCSTATE_DISABLE;
- TIM_OC_InitStruct->CompareValue = 0x00000000U;
- TIM_OC_InitStruct->OCPolarity = LL_TIM_OCPOLARITY_HIGH;
- TIM_OC_InitStruct->OCNPolarity = LL_TIM_OCPOLARITY_HIGH;
- TIM_OC_InitStruct->OCIdleState = LL_TIM_OCIDLESTATE_LOW;
- TIM_OC_InitStruct->OCNIdleState = LL_TIM_OCIDLESTATE_LOW;
-}
-
-/**
- * @brief Configure the TIMx output channel.
- * @param TIMx Timer Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_TIM_CHANNEL_CH1
- * @arg @ref LL_TIM_CHANNEL_CH2
- * @arg @ref LL_TIM_CHANNEL_CH3
- * @arg @ref LL_TIM_CHANNEL_CH4
- * @param TIM_OC_InitStruct pointer to a @ref LL_TIM_OC_InitTypeDef structure (TIMx output channel configuration data structure)
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: TIMx output channel is initialized
- * - ERROR: TIMx output channel is not initialized
- */
-ErrorStatus LL_TIM_OC_Init(TIM_TypeDef *TIMx, uint32_t Channel, LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct)
-{
- ErrorStatus result = ERROR;
-
- switch (Channel)
- {
- case LL_TIM_CHANNEL_CH1:
- result = OC1Config(TIMx, TIM_OC_InitStruct);
- break;
- case LL_TIM_CHANNEL_CH2:
- result = OC2Config(TIMx, TIM_OC_InitStruct);
- break;
- case LL_TIM_CHANNEL_CH3:
- result = OC3Config(TIMx, TIM_OC_InitStruct);
- break;
- case LL_TIM_CHANNEL_CH4:
- result = OC4Config(TIMx, TIM_OC_InitStruct);
- break;
- default:
- break;
- }
-
- return result;
-}
-
-/**
- * @brief Set the fields of the TIMx input channel configuration data
- * structure to their default values.
- * @param TIM_ICInitStruct pointer to a @ref LL_TIM_IC_InitTypeDef structure (the input channel configuration data structure)
- * @retval None
- */
-void LL_TIM_IC_StructInit(LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
-{
- /* Set the default configuration */
- TIM_ICInitStruct->ICPolarity = LL_TIM_IC_POLARITY_RISING;
- TIM_ICInitStruct->ICActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI;
- TIM_ICInitStruct->ICPrescaler = LL_TIM_ICPSC_DIV1;
- TIM_ICInitStruct->ICFilter = LL_TIM_IC_FILTER_FDIV1;
-}
-
-/**
- * @brief Configure the TIMx input channel.
- * @param TIMx Timer Instance
- * @param Channel This parameter can be one of the following values:
- * @arg @ref LL_TIM_CHANNEL_CH1
- * @arg @ref LL_TIM_CHANNEL_CH2
- * @arg @ref LL_TIM_CHANNEL_CH3
- * @arg @ref LL_TIM_CHANNEL_CH4
- * @param TIM_IC_InitStruct pointer to a @ref LL_TIM_IC_InitTypeDef structure (TIMx input channel configuration data structure)
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: TIMx output channel is initialized
- * - ERROR: TIMx output channel is not initialized
- */
-ErrorStatus LL_TIM_IC_Init(TIM_TypeDef *TIMx, uint32_t Channel, LL_TIM_IC_InitTypeDef *TIM_IC_InitStruct)
-{
- ErrorStatus result = ERROR;
-
- switch (Channel)
- {
- case LL_TIM_CHANNEL_CH1:
- result = IC1Config(TIMx, TIM_IC_InitStruct);
- break;
- case LL_TIM_CHANNEL_CH2:
- result = IC2Config(TIMx, TIM_IC_InitStruct);
- break;
- case LL_TIM_CHANNEL_CH3:
- result = IC3Config(TIMx, TIM_IC_InitStruct);
- break;
- case LL_TIM_CHANNEL_CH4:
- result = IC4Config(TIMx, TIM_IC_InitStruct);
- break;
- default:
- break;
- }
-
- return result;
-}
-
-/**
- * @brief Fills each TIM_EncoderInitStruct field with its default value
- * @param TIM_EncoderInitStruct pointer to a @ref LL_TIM_ENCODER_InitTypeDef structure (encoder interface configuration data structure)
- * @retval None
- */
-void LL_TIM_ENCODER_StructInit(LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct)
-{
- /* Set the default configuration */
- TIM_EncoderInitStruct->EncoderMode = LL_TIM_ENCODERMODE_X2_TI1;
- TIM_EncoderInitStruct->IC1Polarity = LL_TIM_IC_POLARITY_RISING;
- TIM_EncoderInitStruct->IC1ActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI;
- TIM_EncoderInitStruct->IC1Prescaler = LL_TIM_ICPSC_DIV1;
- TIM_EncoderInitStruct->IC1Filter = LL_TIM_IC_FILTER_FDIV1;
- TIM_EncoderInitStruct->IC2Polarity = LL_TIM_IC_POLARITY_RISING;
- TIM_EncoderInitStruct->IC2ActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI;
- TIM_EncoderInitStruct->IC2Prescaler = LL_TIM_ICPSC_DIV1;
- TIM_EncoderInitStruct->IC2Filter = LL_TIM_IC_FILTER_FDIV1;
-}
-
-/**
- * @brief Configure the encoder interface of the timer instance.
- * @param TIMx Timer Instance
- * @param TIM_EncoderInitStruct pointer to a @ref LL_TIM_ENCODER_InitTypeDef structure (TIMx encoder interface configuration data structure)
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: TIMx registers are de-initialized
- * - ERROR: not applicable
- */
-ErrorStatus LL_TIM_ENCODER_Init(TIM_TypeDef *TIMx, LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct)
-{
- uint32_t tmpccmr1 = 0U;
- uint32_t tmpccer = 0U;
-
- /* Check the parameters */
- assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(TIMx));
- assert_param(IS_LL_TIM_ENCODERMODE(TIM_EncoderInitStruct->EncoderMode));
- assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_EncoderInitStruct->IC1Polarity));
- assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_EncoderInitStruct->IC1ActiveInput));
- assert_param(IS_LL_TIM_ICPSC(TIM_EncoderInitStruct->IC1Prescaler));
- assert_param(IS_LL_TIM_IC_FILTER(TIM_EncoderInitStruct->IC1Filter));
- assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_EncoderInitStruct->IC2Polarity));
- assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_EncoderInitStruct->IC2ActiveInput));
- assert_param(IS_LL_TIM_ICPSC(TIM_EncoderInitStruct->IC2Prescaler));
- assert_param(IS_LL_TIM_IC_FILTER(TIM_EncoderInitStruct->IC2Filter));
-
- /* Disable the CC1 and CC2: Reset the CC1E and CC2E Bits */
- TIMx->CCER &= (uint32_t)~(TIM_CCER_CC1E | TIM_CCER_CC2E);
-
- /* Get the TIMx CCMR1 register value */
- tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1);
-
- /* Get the TIMx CCER register value */
- tmpccer = LL_TIM_ReadReg(TIMx, CCER);
-
- /* Configure TI1 */
- tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC);
- tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1ActiveInput >> 16U);
- tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1Filter >> 16U);
- tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1Prescaler >> 16U);
-
- /* Configure TI2 */
- tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC2S | TIM_CCMR1_IC2F | TIM_CCMR1_IC2PSC);
- tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2ActiveInput >> 8U);
- tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2Filter >> 8U);
- tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2Prescaler >> 8U);
-
- /* Set TI1 and TI2 polarity and enable TI1 and TI2 */
- tmpccer &= (uint32_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP | TIM_CCER_CC2P | TIM_CCER_CC2NP);
- tmpccer |= (uint32_t)(TIM_EncoderInitStruct->IC1Polarity);
- tmpccer |= (uint32_t)(TIM_EncoderInitStruct->IC2Polarity << 4U);
- tmpccer |= (uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E);
-
- /* Set encoder mode */
- LL_TIM_SetEncoderMode(TIMx, TIM_EncoderInitStruct->EncoderMode);
-
- /* Write to TIMx CCMR1 */
- LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1);
-
- /* Write to TIMx CCER */
- LL_TIM_WriteReg(TIMx, CCER, tmpccer);
-
- return SUCCESS;
-}
-
-/**
- * @brief Set the fields of the TIMx Hall sensor interface configuration data
- * structure to their default values.
- * @param TIM_HallSensorInitStruct pointer to a @ref LL_TIM_HALLSENSOR_InitTypeDef structure (HALL sensor interface configuration data structure)
- * @retval None
- */
-void LL_TIM_HALLSENSOR_StructInit(LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct)
-{
- /* Set the default configuration */
- TIM_HallSensorInitStruct->IC1Polarity = LL_TIM_IC_POLARITY_RISING;
- TIM_HallSensorInitStruct->IC1Prescaler = LL_TIM_ICPSC_DIV1;
- TIM_HallSensorInitStruct->IC1Filter = LL_TIM_IC_FILTER_FDIV1;
- TIM_HallSensorInitStruct->CommutationDelay = 0U;
-}
-
-/**
- * @brief Configure the Hall sensor interface of the timer instance.
- * @note TIMx CH1, CH2 and CH3 inputs connected through a XOR
- * to the TI1 input channel
- * @note TIMx slave mode controller is configured in reset mode.
- Selected internal trigger is TI1F_ED.
- * @note Channel 1 is configured as input, IC1 is mapped on TRC.
- * @note Captured value stored in TIMx_CCR1 correspond to the time elapsed
- * between 2 changes on the inputs. It gives information about motor speed.
- * @note Channel 2 is configured in output PWM 2 mode.
- * @note Compare value stored in TIMx_CCR2 corresponds to the commutation delay.
- * @note OC2REF is selected as trigger output on TRGO.
- * @param TIMx Timer Instance
- * @param TIM_HallSensorInitStruct pointer to a @ref LL_TIM_HALLSENSOR_InitTypeDef structure (TIMx HALL sensor interface configuration data structure)
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: TIMx registers are de-initialized
- * - ERROR: not applicable
- */
-ErrorStatus LL_TIM_HALLSENSOR_Init(TIM_TypeDef *TIMx, LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct)
-{
- uint32_t tmpcr2 = 0U;
- uint32_t tmpccmr1 = 0U;
- uint32_t tmpccer = 0U;
- uint32_t tmpsmcr = 0U;
-
- /* Check the parameters */
- assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(TIMx));
- assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_HallSensorInitStruct->IC1Polarity));
- assert_param(IS_LL_TIM_ICPSC(TIM_HallSensorInitStruct->IC1Prescaler));
- assert_param(IS_LL_TIM_IC_FILTER(TIM_HallSensorInitStruct->IC1Filter));
-
- /* Disable the CC1 and CC2: Reset the CC1E and CC2E Bits */
- TIMx->CCER &= (uint32_t)~(TIM_CCER_CC1E | TIM_CCER_CC2E);
-
- /* Get the TIMx CR2 register value */
- tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
-
- /* Get the TIMx CCMR1 register value */
- tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1);
-
- /* Get the TIMx CCER register value */
- tmpccer = LL_TIM_ReadReg(TIMx, CCER);
-
- /* Get the TIMx SMCR register value */
- tmpsmcr = LL_TIM_ReadReg(TIMx, SMCR);
-
- /* Connect TIMx_CH1, CH2 and CH3 pins to the TI1 input */
- tmpcr2 |= TIM_CR2_TI1S;
-
- /* OC2REF signal is used as trigger output (TRGO) */
- tmpcr2 |= LL_TIM_TRGO_OC2REF;
-
- /* Configure the slave mode controller */
- tmpsmcr &= (uint32_t)~(TIM_SMCR_TS | TIM_SMCR_SMS);
- tmpsmcr |= LL_TIM_TS_TI1F_ED;
- tmpsmcr |= LL_TIM_SLAVEMODE_RESET;
-
- /* Configure input channel 1 */
- tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC);
- tmpccmr1 |= (uint32_t)(LL_TIM_ACTIVEINPUT_TRC >> 16U);
- tmpccmr1 |= (uint32_t)(TIM_HallSensorInitStruct->IC1Filter >> 16U);
- tmpccmr1 |= (uint32_t)(TIM_HallSensorInitStruct->IC1Prescaler >> 16U);
-
- /* Configure input channel 2 */
- tmpccmr1 &= (uint32_t)~(TIM_CCMR1_OC2M | TIM_CCMR1_OC2FE | TIM_CCMR1_OC2PE | TIM_CCMR1_OC2CE);
- tmpccmr1 |= (uint32_t)(LL_TIM_OCMODE_PWM2 << 8U);
-
- /* Set Channel 1 polarity and enable Channel 1 and Channel2 */
- tmpccer &= (uint32_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP | TIM_CCER_CC2P | TIM_CCER_CC2NP);
- tmpccer |= (uint32_t)(TIM_HallSensorInitStruct->IC1Polarity);
- tmpccer |= (uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E);
-
- /* Write to TIMx CR2 */
- LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
-
- /* Write to TIMx SMCR */
- LL_TIM_WriteReg(TIMx, SMCR, tmpsmcr);
-
- /* Write to TIMx CCMR1 */
- LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1);
-
- /* Write to TIMx CCER */
- LL_TIM_WriteReg(TIMx, CCER, tmpccer);
-
- /* Write to TIMx CCR2 */
- LL_TIM_OC_SetCompareCH2(TIMx, TIM_HallSensorInitStruct->CommutationDelay);
-
- return SUCCESS;
-}
-
-/**
- * @brief Set the fields of the Break and Dead Time configuration data structure
- * to their default values.
- * @param TIM_BDTRInitStruct pointer to a @ref LL_TIM_BDTR_InitTypeDef structure (Break and Dead Time configuration data structure)
- * @retval None
- */
-void LL_TIM_BDTR_StructInit(LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct)
-{
- /* Set the default configuration */
- TIM_BDTRInitStruct->OSSRState = LL_TIM_OSSR_DISABLE;
- TIM_BDTRInitStruct->OSSIState = LL_TIM_OSSI_DISABLE;
- TIM_BDTRInitStruct->LockLevel = LL_TIM_LOCKLEVEL_OFF;
- TIM_BDTRInitStruct->DeadTime = (uint8_t)0x00;
- TIM_BDTRInitStruct->BreakState = LL_TIM_BREAK_DISABLE;
- TIM_BDTRInitStruct->BreakPolarity = LL_TIM_BREAK_POLARITY_LOW;
- TIM_BDTRInitStruct->AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE;
-}
-
-/**
- * @brief Configure the Break and Dead Time feature of the timer instance.
- * @note As the bits AOE, BKP, BKE, OSSR, OSSI and DTG[7:0] can be write-locked
- * depending on the LOCK configuration, it can be necessary to configure all of
- * them during the first write access to the TIMx_BDTR register.
- * @note Macro @ref IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not
- * a timer instance provides a break input.
- * @param TIMx Timer Instance
- * @param TIM_BDTRInitStruct pointer to a @ref LL_TIM_BDTR_InitTypeDef structure(Break and Dead Time configuration data structure)
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: Break and Dead Time is initialized
- * - ERROR: not applicable
- */
-ErrorStatus LL_TIM_BDTR_Init(TIM_TypeDef *TIMx, LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct)
-{
- uint32_t tmpbdtr = 0;
-
- /* Check the parameters */
- assert_param(IS_TIM_BREAK_INSTANCE(TIMx));
- assert_param(IS_LL_TIM_OSSR_STATE(TIM_BDTRInitStruct->OSSRState));
- assert_param(IS_LL_TIM_OSSI_STATE(TIM_BDTRInitStruct->OSSIState));
- assert_param(IS_LL_TIM_LOCK_LEVEL(TIM_BDTRInitStruct->LockLevel));
- assert_param(IS_LL_TIM_BREAK_STATE(TIM_BDTRInitStruct->BreakState));
- assert_param(IS_LL_TIM_BREAK_POLARITY(TIM_BDTRInitStruct->BreakPolarity));
- assert_param(IS_LL_TIM_AUTOMATIC_OUTPUT_STATE(TIM_BDTRInitStruct->AutomaticOutput));
-
- /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State,
- the OSSI State, the dead time value and the Automatic Output Enable Bit */
-
- /* Set the BDTR bits */
- MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, TIM_BDTRInitStruct->DeadTime);
- MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, TIM_BDTRInitStruct->LockLevel);
- MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, TIM_BDTRInitStruct->OSSIState);
- MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, TIM_BDTRInitStruct->OSSRState);
- MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, TIM_BDTRInitStruct->BreakState);
- MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, TIM_BDTRInitStruct->BreakPolarity);
- MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, TIM_BDTRInitStruct->AutomaticOutput);
- MODIFY_REG(tmpbdtr, TIM_BDTR_MOE, TIM_BDTRInitStruct->AutomaticOutput);
-
- /* Set TIMx_BDTR */
- LL_TIM_WriteReg(TIMx, BDTR, tmpbdtr);
-
- return SUCCESS;
-}
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup TIM_LL_Private_Functions TIM Private Functions
- * @brief Private functions
- * @{
- */
-/**
- * @brief Configure the TIMx output channel 1.
- * @param TIMx Timer Instance
- * @param TIM_OCInitStruct pointer to the the TIMx output channel 1 configuration data structure
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: TIMx registers are de-initialized
- * - ERROR: not applicable
- */
-static ErrorStatus OC1Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct)
-{
- uint32_t tmpccmr1 = 0U;
- uint32_t tmpccer = 0U;
- uint32_t tmpcr2 = 0U;
-
- /* Check the parameters */
- assert_param(IS_TIM_CC1_INSTANCE(TIMx));
- assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode));
- assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState));
- assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity));
- assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState));
- assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity));
-
- /* Disable the Channel 1: Reset the CC1E Bit */
- CLEAR_BIT(TIMx->CCER, TIM_CCER_CC1E);
-
- /* Get the TIMx CCER register value */
- tmpccer = LL_TIM_ReadReg(TIMx, CCER);
-
- /* Get the TIMx CR2 register value */
- tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
-
- /* Get the TIMx CCMR1 register value */
- tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1);
-
- /* Reset Capture/Compare selection Bits */
- CLEAR_BIT(tmpccmr1, TIM_CCMR1_CC1S);
-
- /* Set the Output Compare Mode */
- MODIFY_REG(tmpccmr1, TIM_CCMR1_OC1M, TIM_OCInitStruct->OCMode);
-
- /* Set the Output Compare Polarity */
- MODIFY_REG(tmpccer, TIM_CCER_CC1P, TIM_OCInitStruct->OCPolarity);
-
- /* Set the Output State */
- MODIFY_REG(tmpccer, TIM_CCER_CC1E, TIM_OCInitStruct->OCState);
-
- if (IS_TIM_BREAK_INSTANCE(TIMx))
- {
- assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState));
- assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState));
-
- /* Set the complementary output Polarity */
- MODIFY_REG(tmpccer, TIM_CCER_CC1NP, TIM_OCInitStruct->OCNPolarity << 2U);
-
- /* Set the complementary output State */
- MODIFY_REG(tmpccer, TIM_CCER_CC1NE, TIM_OCInitStruct->OCNState << 2U);
-
- /* Set the Output Idle state */
- MODIFY_REG(tmpcr2, TIM_CR2_OIS1, TIM_OCInitStruct->OCIdleState);
-
- /* Set the complementary output Idle state */
- MODIFY_REG(tmpcr2, TIM_CR2_OIS1N, TIM_OCInitStruct->OCNIdleState << 1U);
- }
-
- /* Write to TIMx CR2 */
- LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
-
- /* Write to TIMx CCMR1 */
- LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1);
-
- /* Set the Capture Compare Register value */
- LL_TIM_OC_SetCompareCH1(TIMx, TIM_OCInitStruct->CompareValue);
-
- /* Write to TIMx CCER */
- LL_TIM_WriteReg(TIMx, CCER, tmpccer);
-
- return SUCCESS;
-}
-
-/**
- * @brief Configure the TIMx output channel 2.
- * @param TIMx Timer Instance
- * @param TIM_OCInitStruct pointer to the the TIMx output channel 2 configuration data structure
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: TIMx registers are de-initialized
- * - ERROR: not applicable
- */
-static ErrorStatus OC2Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct)
-{
- uint32_t tmpccmr1 = 0U;
- uint32_t tmpccer = 0U;
- uint32_t tmpcr2 = 0U;
-
- /* Check the parameters */
- assert_param(IS_TIM_CC2_INSTANCE(TIMx));
- assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode));
- assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState));
- assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity));
- assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState));
- assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity));
-
- /* Disable the Channel 2: Reset the CC2E Bit */
- CLEAR_BIT(TIMx->CCER, TIM_CCER_CC2E);
-
- /* Get the TIMx CCER register value */
- tmpccer = LL_TIM_ReadReg(TIMx, CCER);
-
- /* Get the TIMx CR2 register value */
- tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
-
- /* Get the TIMx CCMR1 register value */
- tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1);
-
- /* Reset Capture/Compare selection Bits */
- CLEAR_BIT(tmpccmr1, TIM_CCMR1_CC2S);
-
- /* Select the Output Compare Mode */
- MODIFY_REG(tmpccmr1, TIM_CCMR1_OC2M, TIM_OCInitStruct->OCMode << 8U);
-
- /* Set the Output Compare Polarity */
- MODIFY_REG(tmpccer, TIM_CCER_CC2P, TIM_OCInitStruct->OCPolarity << 4U);
-
- /* Set the Output State */
- MODIFY_REG(tmpccer, TIM_CCER_CC2E, TIM_OCInitStruct->OCState << 4U);
-
- if (IS_TIM_BREAK_INSTANCE(TIMx))
- {
- assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState));
- assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState));
-
- /* Set the complementary output Polarity */
- MODIFY_REG(tmpccer, TIM_CCER_CC2NP, TIM_OCInitStruct->OCNPolarity << 6U);
-
- /* Set the complementary output State */
- MODIFY_REG(tmpccer, TIM_CCER_CC2NE, TIM_OCInitStruct->OCNState << 6U);
-
- /* Set the Output Idle state */
- MODIFY_REG(tmpcr2, TIM_CR2_OIS2, TIM_OCInitStruct->OCIdleState << 2U);
-
- /* Set the complementary output Idle state */
- MODIFY_REG(tmpcr2, TIM_CR2_OIS2N, TIM_OCInitStruct->OCNIdleState << 3U);
- }
-
- /* Write to TIMx CR2 */
- LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
-
- /* Write to TIMx CCMR1 */
- LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1);
-
- /* Set the Capture Compare Register value */
- LL_TIM_OC_SetCompareCH2(TIMx, TIM_OCInitStruct->CompareValue);
-
- /* Write to TIMx CCER */
- LL_TIM_WriteReg(TIMx, CCER, tmpccer);
-
- return SUCCESS;
-}
-
-/**
- * @brief Configure the TIMx output channel 3.
- * @param TIMx Timer Instance
- * @param TIM_OCInitStruct pointer to the the TIMx output channel 3 configuration data structure
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: TIMx registers are de-initialized
- * - ERROR: not applicable
- */
-static ErrorStatus OC3Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct)
-{
- uint32_t tmpccmr2 = 0U;
- uint32_t tmpccer = 0U;
- uint32_t tmpcr2 = 0U;
-
- /* Check the parameters */
- assert_param(IS_TIM_CC3_INSTANCE(TIMx));
- assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode));
- assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState));
- assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity));
- assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState));
- assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity));
-
- /* Disable the Channel 3: Reset the CC3E Bit */
- CLEAR_BIT(TIMx->CCER, TIM_CCER_CC3E);
-
- /* Get the TIMx CCER register value */
- tmpccer = LL_TIM_ReadReg(TIMx, CCER);
-
- /* Get the TIMx CR2 register value */
- tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
-
- /* Get the TIMx CCMR2 register value */
- tmpccmr2 = LL_TIM_ReadReg(TIMx, CCMR2);
-
- /* Reset Capture/Compare selection Bits */
- CLEAR_BIT(tmpccmr2, TIM_CCMR2_CC3S);
-
- /* Select the Output Compare Mode */
- MODIFY_REG(tmpccmr2, TIM_CCMR2_OC3M, TIM_OCInitStruct->OCMode);
-
- /* Set the Output Compare Polarity */
- MODIFY_REG(tmpccer, TIM_CCER_CC3P, TIM_OCInitStruct->OCPolarity << 8U);
-
- /* Set the Output State */
- MODIFY_REG(tmpccer, TIM_CCER_CC3E, TIM_OCInitStruct->OCState << 8U);
-
- if (IS_TIM_BREAK_INSTANCE(TIMx))
- {
- assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState));
- assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState));
-
- /* Set the complementary output Polarity */
- MODIFY_REG(tmpccer, TIM_CCER_CC3NP, TIM_OCInitStruct->OCNPolarity << 10U);
-
- /* Set the complementary output State */
- MODIFY_REG(tmpccer, TIM_CCER_CC3NE, TIM_OCInitStruct->OCNState << 10U);
-
- /* Set the Output Idle state */
- MODIFY_REG(tmpcr2, TIM_CR2_OIS3, TIM_OCInitStruct->OCIdleState << 4U);
-
- /* Set the complementary output Idle state */
- MODIFY_REG(tmpcr2, TIM_CR2_OIS3N, TIM_OCInitStruct->OCNIdleState << 5U);
- }
-
- /* Write to TIMx CR2 */
- LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
-
- /* Write to TIMx CCMR2 */
- LL_TIM_WriteReg(TIMx, CCMR2, tmpccmr2);
-
- /* Set the Capture Compare Register value */
- LL_TIM_OC_SetCompareCH3(TIMx, TIM_OCInitStruct->CompareValue);
-
- /* Write to TIMx CCER */
- LL_TIM_WriteReg(TIMx, CCER, tmpccer);
-
- return SUCCESS;
-}
-
-/**
- * @brief Configure the TIMx output channel 4.
- * @param TIMx Timer Instance
- * @param TIM_OCInitStruct pointer to the the TIMx output channel 4 configuration data structure
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: TIMx registers are de-initialized
- * - ERROR: not applicable
- */
-static ErrorStatus OC4Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct)
-{
- uint32_t tmpccmr2 = 0U;
- uint32_t tmpccer = 0U;
- uint32_t tmpcr2 = 0U;
-
- /* Check the parameters */
- assert_param(IS_TIM_CC4_INSTANCE(TIMx));
- assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode));
- assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState));
- assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity));
- assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity));
- assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState));
-
- /* Disable the Channel 4: Reset the CC4E Bit */
- CLEAR_BIT(TIMx->CCER, TIM_CCER_CC4E);
-
- /* Get the TIMx CCER register value */
- tmpccer = LL_TIM_ReadReg(TIMx, CCER);
-
- /* Get the TIMx CR2 register value */
- tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
-
- /* Get the TIMx CCMR2 register value */
- tmpccmr2 = LL_TIM_ReadReg(TIMx, CCMR2);
-
- /* Reset Capture/Compare selection Bits */
- CLEAR_BIT(tmpccmr2, TIM_CCMR2_CC4S);
-
- /* Select the Output Compare Mode */
- MODIFY_REG(tmpccmr2, TIM_CCMR2_OC4M, TIM_OCInitStruct->OCMode << 8U);
-
- /* Set the Output Compare Polarity */
- MODIFY_REG(tmpccer, TIM_CCER_CC4P, TIM_OCInitStruct->OCPolarity << 12U);
-
- /* Set the Output State */
- MODIFY_REG(tmpccer, TIM_CCER_CC4E, TIM_OCInitStruct->OCState << 12U);
-
- if (IS_TIM_BREAK_INSTANCE(TIMx))
- {
- assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState));
- assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState));
-
- /* Set the Output Idle state */
- MODIFY_REG(tmpcr2, TIM_CR2_OIS4, TIM_OCInitStruct->OCIdleState << 6U);
- }
-
- /* Write to TIMx CR2 */
- LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
-
- /* Write to TIMx CCMR2 */
- LL_TIM_WriteReg(TIMx, CCMR2, tmpccmr2);
-
- /* Set the Capture Compare Register value */
- LL_TIM_OC_SetCompareCH4(TIMx, TIM_OCInitStruct->CompareValue);
-
- /* Write to TIMx CCER */
- LL_TIM_WriteReg(TIMx, CCER, tmpccer);
-
- return SUCCESS;
-}
-
-
-/**
- * @brief Configure the TIMx input channel 1.
- * @param TIMx Timer Instance
- * @param TIM_ICInitStruct pointer to the the TIMx input channel 1 configuration data structure
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: TIMx registers are de-initialized
- * - ERROR: not applicable
- */
-static ErrorStatus IC1Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
-{
- /* Check the parameters */
- assert_param(IS_TIM_CC1_INSTANCE(TIMx));
- assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity));
- assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput));
- assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler));
- assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter));
-
- /* Disable the Channel 1: Reset the CC1E Bit */
- TIMx->CCER &= (uint32_t)~TIM_CCER_CC1E;
-
- /* Select the Input and set the filter and the prescaler value */
- MODIFY_REG(TIMx->CCMR1,
- (TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC),
- (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 16U);
-
- /* Select the Polarity and set the CC1E Bit */
- MODIFY_REG(TIMx->CCER,
- (TIM_CCER_CC1P | TIM_CCER_CC1NP),
- (TIM_ICInitStruct->ICPolarity | TIM_CCER_CC1E));
-
- return SUCCESS;
-}
-
-/**
- * @brief Configure the TIMx input channel 2.
- * @param TIMx Timer Instance
- * @param TIM_ICInitStruct pointer to the the TIMx input channel 2 configuration data structure
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: TIMx registers are de-initialized
- * - ERROR: not applicable
- */
-static ErrorStatus IC2Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
-{
- /* Check the parameters */
- assert_param(IS_TIM_CC2_INSTANCE(TIMx));
- assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity));
- assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput));
- assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler));
- assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter));
-
- /* Disable the Channel 2: Reset the CC2E Bit */
- TIMx->CCER &= (uint32_t)~TIM_CCER_CC2E;
-
- /* Select the Input and set the filter and the prescaler value */
- MODIFY_REG(TIMx->CCMR1,
- (TIM_CCMR1_CC2S | TIM_CCMR1_IC2F | TIM_CCMR1_IC2PSC),
- (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 8U);
-
- /* Select the Polarity and set the CC2E Bit */
- MODIFY_REG(TIMx->CCER,
- (TIM_CCER_CC2P | TIM_CCER_CC2NP),
- ((TIM_ICInitStruct->ICPolarity << 4U) | TIM_CCER_CC2E));
-
- return SUCCESS;
-}
-
-/**
- * @brief Configure the TIMx input channel 3.
- * @param TIMx Timer Instance
- * @param TIM_ICInitStruct pointer to the the TIMx input channel 3 configuration data structure
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: TIMx registers are de-initialized
- * - ERROR: not applicable
- */
-static ErrorStatus IC3Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
-{
- /* Check the parameters */
- assert_param(IS_TIM_CC3_INSTANCE(TIMx));
- assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity));
- assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput));
- assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler));
- assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter));
-
- /* Disable the Channel 3: Reset the CC3E Bit */
- TIMx->CCER &= (uint32_t)~TIM_CCER_CC3E;
-
- /* Select the Input and set the filter and the prescaler value */
- MODIFY_REG(TIMx->CCMR2,
- (TIM_CCMR2_CC3S | TIM_CCMR2_IC3F | TIM_CCMR2_IC3PSC),
- (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 16U);
-
- /* Select the Polarity and set the CC3E Bit */
- MODIFY_REG(TIMx->CCER,
- (TIM_CCER_CC3P | TIM_CCER_CC3NP),
- ((TIM_ICInitStruct->ICPolarity << 8U) | TIM_CCER_CC3E));
-
- return SUCCESS;
-}
-
-/**
- * @brief Configure the TIMx input channel 4.
- * @param TIMx Timer Instance
- * @param TIM_ICInitStruct pointer to the the TIMx input channel 4 configuration data structure
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: TIMx registers are de-initialized
- * - ERROR: not applicable
- */
-static ErrorStatus IC4Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
-{
- /* Check the parameters */
- assert_param(IS_TIM_CC4_INSTANCE(TIMx));
- assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity));
- assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput));
- assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler));
- assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter));
-
- /* Disable the Channel 4: Reset the CC4E Bit */
- TIMx->CCER &= (uint32_t)~TIM_CCER_CC4E;
-
- /* Select the Input and set the filter and the prescaler value */
- MODIFY_REG(TIMx->CCMR2,
- (TIM_CCMR2_CC4S | TIM_CCMR2_IC4F | TIM_CCMR2_IC4PSC),
- (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 8U);
-
- /* Select the Polarity and set the CC4E Bit */
- MODIFY_REG(TIMx->CCER,
- TIM_CCER_CC4P,
- ((TIM_ICInitStruct->ICPolarity << 12U) | TIM_CCER_CC4E));
-
- return SUCCESS;
-}
-
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* TIM1 || TIM2 || TIM3 || TIM4 || TIM5 || TIM6 || TIM7 || TIM8 || TIM9 || TIM10 || TIM11 || TIM12 || TIM13 || TIM14 || TIM15 || TIM16 || TIM17 */
-
-/**
- * @}
- */
-
-#endif /* USE_FULL_LL_DRIVER */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usart.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usart.c
deleted file mode 100644
index 1fdded6..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usart.c
+++ /dev/null
@@ -1,449 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_usart.c
- * @author MCD Application Team
- * @brief USART LL module driver.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-#if defined(USE_FULL_LL_DRIVER)
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_usart.h"
-#include "stm32f1xx_ll_rcc.h"
-#include "stm32f1xx_ll_bus.h"
-#ifdef USE_FULL_ASSERT
-#include "stm32_assert.h"
-#else
-#define assert_param(expr) ((void)0U)
-#endif
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-#if defined (USART1) || defined (USART2) || defined (USART3) || defined (UART4) || defined (UART5)
-
-/** @addtogroup USART_LL
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/** @addtogroup USART_LL_Private_Constants
- * @{
- */
-
-/**
- * @}
- */
-
-
-/* Private macros ------------------------------------------------------------*/
-/** @addtogroup USART_LL_Private_Macros
- * @{
- */
-
-/* __BAUDRATE__ The maximum Baud Rate is derived from the maximum clock available
- * divided by the smallest oversampling used on the USART (i.e. 8) */
-#define IS_LL_USART_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) <= 10000000U)
-
-#define IS_LL_USART_DIRECTION(__VALUE__) (((__VALUE__) == LL_USART_DIRECTION_NONE) \
- || ((__VALUE__) == LL_USART_DIRECTION_RX) \
- || ((__VALUE__) == LL_USART_DIRECTION_TX) \
- || ((__VALUE__) == LL_USART_DIRECTION_TX_RX))
-
-#define IS_LL_USART_PARITY(__VALUE__) (((__VALUE__) == LL_USART_PARITY_NONE) \
- || ((__VALUE__) == LL_USART_PARITY_EVEN) \
- || ((__VALUE__) == LL_USART_PARITY_ODD))
-
-#define IS_LL_USART_DATAWIDTH(__VALUE__) (((__VALUE__) == LL_USART_DATAWIDTH_8B) \
- || ((__VALUE__) == LL_USART_DATAWIDTH_9B))
-
-#define IS_LL_USART_OVERSAMPLING(__VALUE__) (((__VALUE__) == LL_USART_OVERSAMPLING_16) \
- || ((__VALUE__) == LL_USART_OVERSAMPLING_8))
-
-#define IS_LL_USART_LASTBITCLKOUTPUT(__VALUE__) (((__VALUE__) == LL_USART_LASTCLKPULSE_NO_OUTPUT) \
- || ((__VALUE__) == LL_USART_LASTCLKPULSE_OUTPUT))
-
-#define IS_LL_USART_CLOCKPHASE(__VALUE__) (((__VALUE__) == LL_USART_PHASE_1EDGE) \
- || ((__VALUE__) == LL_USART_PHASE_2EDGE))
-
-#define IS_LL_USART_CLOCKPOLARITY(__VALUE__) (((__VALUE__) == LL_USART_POLARITY_LOW) \
- || ((__VALUE__) == LL_USART_POLARITY_HIGH))
-
-#define IS_LL_USART_CLOCKOUTPUT(__VALUE__) (((__VALUE__) == LL_USART_CLOCK_DISABLE) \
- || ((__VALUE__) == LL_USART_CLOCK_ENABLE))
-
-#define IS_LL_USART_STOPBITS(__VALUE__) (((__VALUE__) == LL_USART_STOPBITS_0_5) \
- || ((__VALUE__) == LL_USART_STOPBITS_1) \
- || ((__VALUE__) == LL_USART_STOPBITS_1_5) \
- || ((__VALUE__) == LL_USART_STOPBITS_2))
-
-#define IS_LL_USART_HWCONTROL(__VALUE__) (((__VALUE__) == LL_USART_HWCONTROL_NONE) \
- || ((__VALUE__) == LL_USART_HWCONTROL_RTS) \
- || ((__VALUE__) == LL_USART_HWCONTROL_CTS) \
- || ((__VALUE__) == LL_USART_HWCONTROL_RTS_CTS))
-
-/**
- * @}
- */
-
-/* Private function prototypes -----------------------------------------------*/
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup USART_LL_Exported_Functions
- * @{
- */
-
-/** @addtogroup USART_LL_EF_Init
- * @{
- */
-
-/**
- * @brief De-initialize USART registers (Registers restored to their default values).
- * @param USARTx USART Instance
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: USART registers are de-initialized
- * - ERROR: USART registers are not de-initialized
- */
-ErrorStatus LL_USART_DeInit(USART_TypeDef *USARTx)
-{
- ErrorStatus status = SUCCESS;
-
- /* Check the parameters */
- assert_param(IS_UART_INSTANCE(USARTx));
-
- if (USARTx == USART1)
- {
- /* Force reset of USART clock */
- LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_USART1);
-
- /* Release reset of USART clock */
- LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_USART1);
- }
- else if (USARTx == USART2)
- {
- /* Force reset of USART clock */
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_USART2);
-
- /* Release reset of USART clock */
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_USART2);
- }
-#if defined(USART3)
- else if (USARTx == USART3)
- {
- /* Force reset of USART clock */
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_USART3);
-
- /* Release reset of USART clock */
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_USART3);
- }
-#endif /* USART3 */
-#if defined(UART4)
- else if (USARTx == UART4)
- {
- /* Force reset of UART clock */
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_UART4);
-
- /* Release reset of UART clock */
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_UART4);
- }
-#endif /* UART4 */
-#if defined(UART5)
- else if (USARTx == UART5)
- {
- /* Force reset of UART clock */
- LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_UART5);
-
- /* Release reset of UART clock */
- LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_UART5);
- }
-#endif /* UART5 */
- else
- {
- status = ERROR;
- }
-
- return (status);
-}
-
-/**
- * @brief Initialize USART registers according to the specified
- * parameters in USART_InitStruct.
- * @note As some bits in USART configuration registers can only be written when the USART is disabled (USART_CR1_UE bit =0),
- * USART IP should be in disabled state prior calling this function. Otherwise, ERROR result will be returned.
- * @note Baud rate value stored in USART_InitStruct BaudRate field, should be valid (different from 0).
- * @param USARTx USART Instance
- * @param USART_InitStruct: pointer to a LL_USART_InitTypeDef structure
- * that contains the configuration information for the specified USART peripheral.
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: USART registers are initialized according to USART_InitStruct content
- * - ERROR: Problem occurred during USART Registers initialization
- */
-ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, LL_USART_InitTypeDef *USART_InitStruct)
-{
- ErrorStatus status = ERROR;
- uint32_t periphclk = LL_RCC_PERIPH_FREQUENCY_NO;
- LL_RCC_ClocksTypeDef rcc_clocks;
-
- /* Check the parameters */
- assert_param(IS_UART_INSTANCE(USARTx));
- assert_param(IS_LL_USART_BAUDRATE(USART_InitStruct->BaudRate));
- assert_param(IS_LL_USART_DATAWIDTH(USART_InitStruct->DataWidth));
- assert_param(IS_LL_USART_STOPBITS(USART_InitStruct->StopBits));
- assert_param(IS_LL_USART_PARITY(USART_InitStruct->Parity));
- assert_param(IS_LL_USART_DIRECTION(USART_InitStruct->TransferDirection));
- assert_param(IS_LL_USART_HWCONTROL(USART_InitStruct->HardwareFlowControl));
-#if defined(USART_CR1_OVER8)
- assert_param(IS_LL_USART_OVERSAMPLING(USART_InitStruct->OverSampling));
-#endif /* USART_OverSampling_Feature */
-
- /* USART needs to be in disabled state, in order to be able to configure some bits in
- CRx registers */
- if (LL_USART_IsEnabled(USARTx) == 0U)
- {
- /*---------------------------- USART CR1 Configuration -----------------------
- * Configure USARTx CR1 (USART Word Length, Parity, Mode and Oversampling bits) with parameters:
- * - DataWidth: USART_CR1_M bits according to USART_InitStruct->DataWidth value
- * - Parity: USART_CR1_PCE, USART_CR1_PS bits according to USART_InitStruct->Parity value
- * - TransferDirection: USART_CR1_TE, USART_CR1_RE bits according to USART_InitStruct->TransferDirection value
- * - Oversampling: USART_CR1_OVER8 bit according to USART_InitStruct->OverSampling value.
- */
-#if defined(USART_CR1_OVER8)
- MODIFY_REG(USARTx->CR1,
- (USART_CR1_M | USART_CR1_PCE | USART_CR1_PS |
- USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8),
- (USART_InitStruct->DataWidth | USART_InitStruct->Parity |
- USART_InitStruct->TransferDirection | USART_InitStruct->OverSampling));
-#else
- MODIFY_REG(USARTx->CR1,
- (USART_CR1_M | USART_CR1_PCE | USART_CR1_PS |
- USART_CR1_TE | USART_CR1_RE),
- (USART_InitStruct->DataWidth | USART_InitStruct->Parity |
- USART_InitStruct->TransferDirection));
-#endif /* USART_OverSampling_Feature */
-
- /*---------------------------- USART CR2 Configuration -----------------------
- * Configure USARTx CR2 (Stop bits) with parameters:
- * - Stop Bits: USART_CR2_STOP bits according to USART_InitStruct->StopBits value.
- * - CLKEN, CPOL, CPHA and LBCL bits are to be configured using LL_USART_ClockInit().
- */
- LL_USART_SetStopBitsLength(USARTx, USART_InitStruct->StopBits);
-
- /*---------------------------- USART CR3 Configuration -----------------------
- * Configure USARTx CR3 (Hardware Flow Control) with parameters:
- * - HardwareFlowControl: USART_CR3_RTSE, USART_CR3_CTSE bits according to USART_InitStruct->HardwareFlowControl value.
- */
- LL_USART_SetHWFlowCtrl(USARTx, USART_InitStruct->HardwareFlowControl);
-
- /*---------------------------- USART BRR Configuration -----------------------
- * Retrieve Clock frequency used for USART Peripheral
- */
- LL_RCC_GetSystemClocksFreq(&rcc_clocks);
- if (USARTx == USART1)
- {
- periphclk = rcc_clocks.PCLK2_Frequency;
- }
- else if (USARTx == USART2)
- {
- periphclk = rcc_clocks.PCLK1_Frequency;
- }
-#if defined(USART3)
- else if (USARTx == USART3)
- {
- periphclk = rcc_clocks.PCLK1_Frequency;
- }
-#endif /* USART3 */
-#if defined(UART4)
- else if (USARTx == UART4)
- {
- periphclk = rcc_clocks.PCLK1_Frequency;
- }
-#endif /* UART4 */
-#if defined(UART5)
- else if (USARTx == UART5)
- {
- periphclk = rcc_clocks.PCLK1_Frequency;
- }
-#endif /* UART5 */
- else
- {
- /* Nothing to do, as error code is already assigned to ERROR value */
- }
-
- /* Configure the USART Baud Rate :
- - valid baud rate value (different from 0) is required
- - Peripheral clock as returned by RCC service, should be valid (different from 0).
- */
- if ((periphclk != LL_RCC_PERIPH_FREQUENCY_NO)
- && (USART_InitStruct->BaudRate != 0U))
- {
- status = SUCCESS;
-#if defined(USART_CR1_OVER8)
- LL_USART_SetBaudRate(USARTx,
- periphclk,
- USART_InitStruct->OverSampling,
- USART_InitStruct->BaudRate);
-#else
- LL_USART_SetBaudRate(USARTx,
- periphclk,
- USART_InitStruct->BaudRate);
-#endif /* USART_OverSampling_Feature */
- }
- }
- /* Endif (=> USART not in Disabled state => return ERROR) */
-
- return (status);
-}
-
-/**
- * @brief Set each @ref LL_USART_InitTypeDef field to default value.
- * @param USART_InitStruct: pointer to a @ref LL_USART_InitTypeDef structure
- * whose fields will be set to default values.
- * @retval None
- */
-
-void LL_USART_StructInit(LL_USART_InitTypeDef *USART_InitStruct)
-{
- /* Set USART_InitStruct fields to default values */
- USART_InitStruct->BaudRate = 9600U;
- USART_InitStruct->DataWidth = LL_USART_DATAWIDTH_8B;
- USART_InitStruct->StopBits = LL_USART_STOPBITS_1;
- USART_InitStruct->Parity = LL_USART_PARITY_NONE ;
- USART_InitStruct->TransferDirection = LL_USART_DIRECTION_TX_RX;
- USART_InitStruct->HardwareFlowControl = LL_USART_HWCONTROL_NONE;
-#if defined(USART_CR1_OVER8)
- USART_InitStruct->OverSampling = LL_USART_OVERSAMPLING_16;
-#endif /* USART_OverSampling_Feature */
-}
-
-/**
- * @brief Initialize USART Clock related settings according to the
- * specified parameters in the USART_ClockInitStruct.
- * @note As some bits in USART configuration registers can only be written when the USART is disabled (USART_CR1_UE bit =0),
- * USART IP should be in disabled state prior calling this function. Otherwise, ERROR result will be returned.
- * @param USARTx USART Instance
- * @param USART_ClockInitStruct: pointer to a @ref LL_USART_ClockInitTypeDef structure
- * that contains the Clock configuration information for the specified USART peripheral.
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: USART registers related to Clock settings are initialized according to USART_ClockInitStruct content
- * - ERROR: Problem occurred during USART Registers initialization
- */
-ErrorStatus LL_USART_ClockInit(USART_TypeDef *USARTx, LL_USART_ClockInitTypeDef *USART_ClockInitStruct)
-{
- ErrorStatus status = SUCCESS;
-
- /* Check USART Instance and Clock signal output parameters */
- assert_param(IS_UART_INSTANCE(USARTx));
- assert_param(IS_LL_USART_CLOCKOUTPUT(USART_ClockInitStruct->ClockOutput));
-
- /* USART needs to be in disabled state, in order to be able to configure some bits in
- CRx registers */
- if (LL_USART_IsEnabled(USARTx) == 0U)
- {
- /*---------------------------- USART CR2 Configuration -----------------------*/
- /* If Clock signal has to be output */
- if (USART_ClockInitStruct->ClockOutput == LL_USART_CLOCK_DISABLE)
- {
- /* Deactivate Clock signal delivery :
- * - Disable Clock Output: USART_CR2_CLKEN cleared
- */
- LL_USART_DisableSCLKOutput(USARTx);
- }
- else
- {
- /* Ensure USART instance is USART capable */
- assert_param(IS_USART_INSTANCE(USARTx));
-
- /* Check clock related parameters */
- assert_param(IS_LL_USART_CLOCKPOLARITY(USART_ClockInitStruct->ClockPolarity));
- assert_param(IS_LL_USART_CLOCKPHASE(USART_ClockInitStruct->ClockPhase));
- assert_param(IS_LL_USART_LASTBITCLKOUTPUT(USART_ClockInitStruct->LastBitClockPulse));
-
- /*---------------------------- USART CR2 Configuration -----------------------
- * Configure USARTx CR2 (Clock signal related bits) with parameters:
- * - Enable Clock Output: USART_CR2_CLKEN set
- * - Clock Polarity: USART_CR2_CPOL bit according to USART_ClockInitStruct->ClockPolarity value
- * - Clock Phase: USART_CR2_CPHA bit according to USART_ClockInitStruct->ClockPhase value
- * - Last Bit Clock Pulse Output: USART_CR2_LBCL bit according to USART_ClockInitStruct->LastBitClockPulse value.
- */
- MODIFY_REG(USARTx->CR2,
- USART_CR2_CLKEN | USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_LBCL,
- USART_CR2_CLKEN | USART_ClockInitStruct->ClockPolarity |
- USART_ClockInitStruct->ClockPhase | USART_ClockInitStruct->LastBitClockPulse);
- }
- }
- /* Else (USART not in Disabled state => return ERROR */
- else
- {
- status = ERROR;
- }
-
- return (status);
-}
-
-/**
- * @brief Set each field of a @ref LL_USART_ClockInitTypeDef type structure to default value.
- * @param USART_ClockInitStruct: pointer to a @ref LL_USART_ClockInitTypeDef structure
- * whose fields will be set to default values.
- * @retval None
- */
-void LL_USART_ClockStructInit(LL_USART_ClockInitTypeDef *USART_ClockInitStruct)
-{
- /* Set LL_USART_ClockInitStruct fields with default values */
- USART_ClockInitStruct->ClockOutput = LL_USART_CLOCK_DISABLE;
- USART_ClockInitStruct->ClockPolarity = LL_USART_POLARITY_LOW; /* Not relevant when ClockOutput = LL_USART_CLOCK_DISABLE */
- USART_ClockInitStruct->ClockPhase = LL_USART_PHASE_1EDGE; /* Not relevant when ClockOutput = LL_USART_CLOCK_DISABLE */
- USART_ClockInitStruct->LastBitClockPulse = LL_USART_LASTCLKPULSE_NO_OUTPUT; /* Not relevant when ClockOutput = LL_USART_CLOCK_DISABLE */
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#endif /* USART1 || USART2 || USART3 || UART4 || UART5 */
-
-/**
- * @}
- */
-
-#endif /* USE_FULL_LL_DRIVER */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usb.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usb.c
deleted file mode 100644
index 1ee33c1..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usb.c
+++ /dev/null
@@ -1,2336 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_usb.c
- * @author MCD Application Team
- * @brief USB Low Layer HAL module driver.
- *
- * This file provides firmware functions to manage the following
- * functionalities of the USB Peripheral Controller:
- * + Initialization/de-initialization functions
- * + I/O operation functions
- * + Peripheral Control functions
- * + Peripheral State functions
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure.
-
- (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
-
- (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup USB_LL USB Low Layer
- * @brief Low layer module for USB_FS and USB_OTG_FS drivers
- * @{
- */
-
-#if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
-
-#if defined(STM32F102x6) || defined(STM32F102xB) || \
- defined(STM32F103x6) || defined(STM32F103xB) || \
- defined(STM32F103xE) || defined(STM32F103xG) || \
- defined(STM32F105xC) || defined(STM32F107xC)
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
-#if defined (USB_OTG_FS)
-/** @defgroup USB_LL_Private_Functions USB Low Layer Private Functions
- * @{
- */
-static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
-/**
- * @}
- */
-#endif /* USB_OTG_FS */
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup USB_LL_Exported_Functions USB Low Layer Exported Functions
- * @{
- */
-
-/** @defgroup USB_LL_Exported_Functions_Group1 Peripheral Control functions
- * @brief management functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral Control functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to control the PCD data
- transfers.
-
-@endverbatim
- * @{
- */
-
-/*==============================================================================
- USB OTG FS peripheral available on STM32F105xx and STM32F107xx devices
-==============================================================================*/
-#if defined (USB_OTG_FS)
-
-/**
- * @brief Initializes the USB Core
- * @param USBx: USB Instance
- * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
- * the configuration information for the specified USBx peripheral.
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(cfg);
-
- /* Select FS Embedded PHY */
- USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
-
- /* Reset after a PHY select and set Host mode */
- USB_CoreReset(USBx);
-
- /* Deactivate the power down*/
- USBx->GCCFG = USB_OTG_GCCFG_PWRDWN;
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_EnableGlobalInt
- * Enables the controller's Global Int in the AHB Config reg
- * @param USBx : Selected device
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
-{
- USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
- return HAL_OK;
-}
-
-/**
- * @brief USB_DisableGlobalInt
- * Disable the controller's Global Int in the AHB Config reg
- * @param USBx : Selected device
- * @retval HAL status
-*/
-HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
-{
- USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
- return HAL_OK;
-}
-
-/**
- * @brief USB_SetCurrentMode : Set functional mode
- * @param USBx : Selected device
- * @param mode : current core mode
- * This parameter can be one of the these values:
- * @arg USB_DEVICE_MODE: Peripheral mode mode
- * @arg USB_HOST_MODE: Host mode
- * @arg USB_DRD_MODE: Dual Role Device mode
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx , USB_ModeTypeDef mode)
-{
- USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
-
- if ( mode == USB_HOST_MODE)
- {
- USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
- }
- else if (mode == USB_DEVICE_MODE)
- {
- USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
- }
- HAL_Delay(50);
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_DevInit : Initializes the USB_OTG controller registers
- * for device mode
- * @param USBx : Selected device
- * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
- * the configuration information for the specified USBx peripheral.
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_DevInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
-{
- uint32_t index = 0;
-
- for (index = 0; index < 15 ; index++)
- {
- USBx->DIEPTXF[index] = 0;
- }
-
- /*Activate VBUS Sensing B */
- USBx->GCCFG |= USB_OTG_GCCFG_VBUSBSEN;
-
- /* Restart the Phy Clock */
- USBx_PCGCCTL = 0;
-
- /* Device mode configuration */
- USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80;
-
- /* Set Full speed phy */
- USB_SetDevSpeed (USBx , USB_OTG_SPEED_FULL);
-
- /* Flush the FIFOs */
- USB_FlushTxFifo(USBx , 0x10); /* all Tx FIFOs */
- USB_FlushRxFifo(USBx);
-
- /* Clear all pending Device Interrupts */
- USBx_DEVICE->DIEPMSK = 0;
- USBx_DEVICE->DOEPMSK = 0;
- USBx_DEVICE->DAINT = 0xFFFFFFFF;
- USBx_DEVICE->DAINTMSK = 0;
-
- for (index = 0; index < cfg.dev_endpoints; index++)
- {
- if ((USBx_INEP(index)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
- {
- USBx_INEP(index)->DIEPCTL = (USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK);
- }
- else
- {
- USBx_INEP(index)->DIEPCTL = 0;
- }
-
- USBx_INEP(index)->DIEPTSIZ = 0;
- USBx_INEP(index)->DIEPINT = 0xFF;
- }
-
- for (index = 0; index < cfg.dev_endpoints; index++)
- {
- if ((USBx_OUTEP(index)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
- {
- USBx_OUTEP(index)->DOEPCTL = (USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK);
- }
- else
- {
- USBx_OUTEP(index)->DOEPCTL = 0;
- }
-
- USBx_OUTEP(index)->DOEPTSIZ = 0;
- USBx_OUTEP(index)->DOEPINT = 0xFF;
- }
-
- USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
-
- /* Disable all interrupts. */
- USBx->GINTMSK = 0;
-
- /* Clear any pending interrupts */
- USBx->GINTSTS = 0xBFFFFFFF;
-
- /* Enable the common interrupts */
- USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
-
- /* Enable interrupts matching to the Device mode ONLY */
- USBx->GINTMSK |= (USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |\
- USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |\
- USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM|\
- USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
-
- if(cfg.Sof_enable)
- {
- USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
- }
-
- if (cfg.vbus_sensing_enable == ENABLE)
- {
- USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO
- * @param USBx : Selected device
- * @param num : FIFO number
- * This parameter can be a value from 1 to 15
- 15 means Flush all Tx FIFOs
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_FlushTxFifo (USB_OTG_GlobalTypeDef *USBx, uint32_t num )
-{
- uint32_t count = 0;
-
- USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH |(uint32_t)(num << 6));
-
- do
- {
- if (++count > 200000)
- {
- return HAL_TIMEOUT;
- }
- }
- while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_FlushRxFifo : Flush Rx FIFO
- * @param USBx : Selected device
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
-{
- uint32_t count = 0;
-
- USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
-
- do
- {
- if (++count > 200000)
- {
- return HAL_TIMEOUT;
- }
- }
- while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_SetDevSpeed :Initializes the DevSpd field of DCFG register
- * depending the PHY type and the enumeration speed of the device.
- * @param USBx : Selected device
- * @param speed : device speed
- * This parameter can be one of the these values:
- * @arg USB_OTG_SPEED_FULL: Full speed mode
- * @arg USB_OTG_SPEED_LOW: Low speed mode
- * @retval Hal status
- */
-HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx , uint8_t speed)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- USBx_DEVICE->DCFG |= speed;
- return HAL_OK;
-}
-
-/**
- * @brief USB_GetDevSpeed :Return the Dev Speed
- * @param USBx : Selected device
- * @retval speed : device speed
- * This parameter can be one of the these values:
- * @arg USB_OTG_SPEED_FULL: Full speed mode
- * @arg USB_OTG_SPEED_LOW: Low speed mode
- */
-uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx)
-{
- uint8_t speed = 0;
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- if (((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ)||
- ((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_48MHZ))
- {
- speed = USB_OTG_SPEED_FULL;
- }
- else if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ)
- {
- speed = USB_OTG_SPEED_LOW;
- }
-
- return speed;
-}
-
-/**
- * @brief Activate and configure an endpoint
- * @param USBx : Selected device
- * @param ep: pointer to endpoint structure
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- if (ep->is_in)
- {
- /* Assign a Tx FIFO */
- ep->tx_fifo_num = ep->num;
- }
- /* Set initial data PID. */
- if (ep->type == EP_TYPE_BULK )
- {
- ep->data_pid_start = 0;
- }
-
- if (ep->is_in == 1)
- {
- USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)));
-
- if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0)
- {
- USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\
- ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP));
- }
- }
- else
- {
- USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16);
-
- if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0)
- {
- USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\
- (USB_OTG_DIEPCTL_SD0PID_SEVNFRM)| (USB_OTG_DOEPCTL_USBAEP));
- }
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief De-activate and de-initialize an endpoint
- * @param USBx : Selected device
- * @param ep: pointer to endpoint structure
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- /* Read DEPCTLn register */
- if (ep->is_in == 1)
- {
- USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))));
- USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))));
- USBx_INEP(ep->num)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
- }
- else
- {
- USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));
- USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));
- USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
- }
- return HAL_OK;
-}
-
-/**
- * @brief USB_EPStartXfer : setup and starts a transfer over an EP
- * @param USBx : Selected device
- * @param ep: pointer to endpoint structure
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep)
-{
- uint16_t pktcnt = 0;
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- /* IN endpoint */
- if (ep->is_in == 1)
- {
- /* Zero Length Packet? */
- if (ep->xfer_len == 0)
- {
- USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
- USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ;
- USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
- }
- else
- {
- /* Program the transfer size and packet count
- * as follows: xfersize = N * maxpacket +
- * short_packet pktcnt = N + (short_packet
- * exist ? 1 : 0)
- */
- USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
- USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
- USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (((ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket) << 19)) ;
- USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
-
- if (ep->type == EP_TYPE_ISOC)
- {
- USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
- USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1 << 29));
- }
- }
-
- if (ep->type != EP_TYPE_ISOC)
- {
- /* Enable the Tx FIFO Empty Interrupt for this EP */
- if (ep->xfer_len > 0)
- {
- USBx_DEVICE->DIEPEMPMSK |= 1 << ep->num;
- }
- }
-
- if (ep->type == EP_TYPE_ISOC)
- {
- if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0)
- {
- USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
- }
- else
- {
- USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
- }
- }
-
- /* EP enable, IN data in FIFO */
- USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
-
- if (ep->type == EP_TYPE_ISOC)
- {
- USB_WritePacket(USBx, ep->xfer_buff, ep->num, ep->xfer_len);
- }
- }
- else /* OUT endpoint */
- {
- /* Program the transfer size and packet count as follows:
- * pktcnt = N
- * xfersize = N * maxpacket
- */
- USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
- USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
-
- if (ep->xfer_len == 0)
- {
- USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
- USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19));
- }
- else
- {
- pktcnt = (ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket;
- USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (pktcnt << 19));
- USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt));
- }
-
- if (ep->type == EP_TYPE_ISOC)
- {
- if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0)
- {
- USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
- }
- else
- {
- USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
- }
- }
- /* EP enable */
- USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_EP0StartXfer : setup and starts a transfer over the EP 0
- * @param USBx : Selected device
- * @param ep: pointer to endpoint structure
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- /* IN endpoint */
- if (ep->is_in == 1)
- {
- /* Zero Length Packet? */
- if (ep->xfer_len == 0)
- {
- USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
- USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19));
- USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
- }
- else
- {
- /* Program the transfer size and packet count
- * as follows: xfersize = N * maxpacket +
- * short_packet pktcnt = N + (short_packet
- * exist ? 1 : 0)
- */
- USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
- USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
-
- if(ep->xfer_len > ep->maxpacket)
- {
- ep->xfer_len = ep->maxpacket;
- }
- USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19));
- USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
- }
-
- /* Enable the Tx FIFO Empty Interrupt for this EP */
- if (ep->xfer_len > 0)
- {
- USBx_DEVICE->DIEPEMPMSK |= 1 << (ep->num);
- }
-
- /* EP enable, IN data in FIFO */
- USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
- }
- else /* OUT endpoint */
- {
- /* Program the transfer size and packet count as follows:
- * pktcnt = N
- * xfersize = N * maxpacket
- */
- USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
- USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
-
- if (ep->xfer_len > 0)
- {
- ep->xfer_len = ep->maxpacket;
- }
-
- USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19));
- USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket));
-
- /* EP enable */
- USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
- * with the EP/channel
- * @param USBx : Selected device
- * @param src : pointer to source buffer
- * @param ch_ep_num : endpoint or host channel number
- * @param len : Number of bytes to write
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len)
-{
- uint32_t count32b = 0 , index = 0;
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- count32b = (len + 3) / 4;
- for (index = 0; index < count32b; index++, src += 4)
- {
- USBx_DFIFO(ch_ep_num) = *((__packed uint32_t *)src);
- }
- return HAL_OK;
-}
-
-/**
- * @brief USB_ReadPacket : read a packet from the Tx FIFO associated
- * with the EP/channel
- * @param USBx : Selected device
- * @param dest : destination pointer
- * @param len : Number of bytes to read
- * @retval pointer to destination buffer
- */
-void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
-{
- uint32_t index = 0;
- uint32_t count32b = (len + 3) / 4;
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- for ( index = 0; index < count32b; index++, dest += 4 )
- {
- *(__packed uint32_t *)dest = USBx_DFIFO(0);
-
- }
- return ((void *)dest);
-}
-
-/**
- * @brief USB_EPSetStall : set a stall condition over an EP
- * @param USBx : Selected device
- * @param ep: pointer to endpoint structure
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- if (ep->is_in == 1)
- {
- if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == 0)
- {
- USBx_INEP(ep->num)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
- }
- USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
- }
- else
- {
- if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == 0)
- {
- USBx_OUTEP(ep->num)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
- }
- USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
- }
- return HAL_OK;
-}
-
-/**
- * @brief USB_EPClearStall : Clear a stall condition over an EP
- * @param USBx : Selected device
- * @param ep: pointer to endpoint structure
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- if (ep->is_in == 1)
- {
- USBx_INEP(ep->num)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
- if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
- {
- USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
- }
- }
- else
- {
- USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
- if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
- {
- USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
- }
- }
- return HAL_OK;
-}
-
-/**
- * @brief USB_StopDevice : Stop the usb device mode
- * @param USBx : Selected device
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
-{
- uint32_t index = 0;
-
- /* Clear Pending interrupt */
- for (index = 0; index < 15 ; index++)
- {
- USBx_INEP(index)->DIEPINT = 0xFF;
- USBx_OUTEP(index)->DOEPINT = 0xFF;
- }
- USBx_DEVICE->DAINT = 0xFFFFFFFF;
-
- /* Clear interrupt masks */
- USBx_DEVICE->DIEPMSK = 0;
- USBx_DEVICE->DOEPMSK = 0;
- USBx_DEVICE->DAINTMSK = 0;
-
- /* Flush the FIFO */
- USB_FlushRxFifo(USBx);
- USB_FlushTxFifo(USBx , 0x10 );
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_SetDevAddress : Stop the usb device mode
- * @param USBx : Selected device
- * @param address : new device address to be assigned
- * This parameter can be a value from 0 to 255
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_SetDevAddress (USB_OTG_GlobalTypeDef *USBx, uint8_t address)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- UNUSED(address);
- USBx_DEVICE->DCFG &= ~ (USB_OTG_DCFG_DAD);
- USBx_DEVICE->DCFG |= (address << 4) & USB_OTG_DCFG_DAD;
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down
- * @param USBx : Selected device
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_DevConnect (USB_OTG_GlobalTypeDef *USBx)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS ;
- HAL_Delay(3);
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down
- * @param USBx : Selected device
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_DevDisconnect (USB_OTG_GlobalTypeDef *USBx)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
- HAL_Delay(3);
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_ReadInterrupts: return the global USB interrupt status
- * @param USBx : Selected device
- * @retval HAL status
- */
-uint32_t USB_ReadInterrupts (USB_OTG_GlobalTypeDef *USBx)
-{
- uint32_t tmpreg = 0;
-
- tmpreg = USBx->GINTSTS;
- tmpreg &= USBx->GINTMSK;
- return tmpreg;
-}
-
-/**
- * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
- * @param USBx : Selected device
- * @retval HAL status
- */
-uint32_t USB_ReadDevAllOutEpInterrupt (USB_OTG_GlobalTypeDef *USBx)
-{
- uint32_t tmpreg = 0;
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- tmpreg = USBx_DEVICE->DAINT;
- tmpreg &= USBx_DEVICE->DAINTMSK;
- return ((tmpreg & 0xffff0000) >> 16);
-}
-
-/**
- * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
- * @param USBx : Selected device
- * @retval HAL status
- */
-uint32_t USB_ReadDevAllInEpInterrupt (USB_OTG_GlobalTypeDef *USBx)
-{
- uint32_t tmpreg = 0;
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- tmpreg = USBx_DEVICE->DAINT;
- tmpreg &= USBx_DEVICE->DAINTMSK;
- return ((tmpreg & 0xFFFF));
-}
-
-/**
- * @brief Returns Device OUT EP Interrupt register
- * @param USBx : Selected device
- * @param epnum : endpoint number
- * This parameter can be a value from 0 to 15
- * @retval Device OUT EP Interrupt register
- */
-uint32_t USB_ReadDevOutEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- uint32_t tmpreg = 0;
- tmpreg = USBx_OUTEP(epnum)->DOEPINT;
- tmpreg &= USBx_DEVICE->DOEPMSK;
- return tmpreg;
-}
-
-/**
- * @brief Returns Device IN EP Interrupt register
- * @param USBx : Selected device
- * @param epnum : endpoint number
- * This parameter can be a value from 0 to 15
- * @retval Device IN EP Interrupt register
- */
-uint32_t USB_ReadDevInEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum)
-{
- uint32_t tmpreg = 0, msk = 0, emp = 0;
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- msk = USBx_DEVICE->DIEPMSK;
- emp = USBx_DEVICE->DIEPEMPMSK;
- msk |= ((emp >> epnum) & 0x1) << 7;
- tmpreg = USBx_INEP(epnum)->DIEPINT & msk;
- return tmpreg;
-}
-
-/**
- * @brief USB_ClearInterrupts: clear a USB interrupt
- * @param USBx : Selected device
- * @param interrupt : interrupt flag
- * @retval None
- */
-void USB_ClearInterrupts (USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
-{
- USBx->GINTSTS |= interrupt;
-}
-
-/**
- * @brief Returns USB core mode
- * @param USBx : Selected device
- * @retval return core mode : Host or Device
- * This parameter can be one of the these values:
- * 0 : Host
- * 1 : Device
- */
-uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- return ((USBx->GINTSTS ) & 0x1);
-}
-
-/**
- * @brief Activate EP0 for Setup transactions
- * @param USBx : Selected device
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_ActivateSetup (USB_OTG_GlobalTypeDef *USBx)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- /* Set the MPS of the IN EP based on the enumeration speed */
- USBx_INEP(0)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
-
- if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ)
- {
- USBx_INEP(0)->DIEPCTL |= 3;
- }
- USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
-
- return HAL_OK;
-}
-
-/**
- * @brief Prepare the EP0 to start the first control setup
- * @param USBx : Selected device
- * @param psetup : pointer to setup packet
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t *psetup)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- UNUSED(psetup);
- USBx_OUTEP(0)->DOEPTSIZ = 0;
- USBx_OUTEP(0)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19));
- USBx_OUTEP(0)->DOEPTSIZ |= (3 * 8);
- USBx_OUTEP(0)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_HostInit : Initializes the USB OTG controller registers
- * for Host mode
- * @param USBx : Selected device
- * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
- * the configuration information for the specified USBx peripheral.
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_HostInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
-{
- uint32_t index = 0;
-
- /* Restart the Phy Clock */
- USBx_PCGCCTL = 0;
-
- /* no VBUS sensing*/
- USBx->GCCFG &=~ (USB_OTG_GCCFG_VBUSASEN);
- USBx->GCCFG &=~ (USB_OTG_GCCFG_VBUSBSEN);
-
- /* Disable the FS/LS support mode only */
- if((cfg.speed == USB_OTG_SPEED_FULL)&&
- (USBx != USB_OTG_FS))
- {
- USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS;
- }
- else
- {
- USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
- }
-
- /* Make sure the FIFOs are flushed. */
- USB_FlushTxFifo(USBx, 0x10 ); /* all Tx FIFOs */
- USB_FlushRxFifo(USBx);
-
- /* Clear all pending HC Interrupts */
- for (index = 0; index < cfg.Host_channels; index++)
- {
- USBx_HC(index)->HCINT = 0xFFFFFFFF;
- USBx_HC(index)->HCINTMSK = 0;
- }
-
- /* Enable VBUS driving */
- USB_DriveVbus(USBx, 1);
-
- HAL_Delay(200);
-
- /* Disable all interrupts. */
- USBx->GINTMSK = 0;
-
- /* Clear any pending interrupts */
- USBx->GINTSTS = 0xFFFFFFFF;
-
- if(USBx == USB_OTG_FS)
- {
- /* set Rx FIFO size */
- USBx->GRXFSIZ = (uint32_t )0x80;
- USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x60 << 16)& USB_OTG_NPTXFD) | 0x80);
- USBx->HPTXFSIZ = (uint32_t )(((0x40 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0);
- }
-
- /* Enable the common interrupts */
- USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
-
- /* Enable interrupts matching to the Host mode ONLY */
- USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM |\
- USB_OTG_GINTMSK_SOFM |USB_OTG_GINTSTS_DISCINT|\
- USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
- * HCFG register on the PHY type and set the right frame interval
- * @param USBx : Selected device
- * @param freq : clock frequency
- * This parameter can be one of the these values:
- * HCFG_48_MHZ : Full Speed 48 MHz Clock
- * HCFG_6_MHZ : Low Speed 6 MHz Clock
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx , uint8_t freq)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
- USBx_HOST->HCFG |= (freq & USB_OTG_HCFG_FSLSPCS);
-
- if (freq == HCFG_48_MHZ)
- {
- USBx_HOST->HFIR = (uint32_t)48000;
- }
- else if (freq == HCFG_6_MHZ)
- {
- USBx_HOST->HFIR = (uint32_t)6000;
- }
- return HAL_OK;
-}
-
-/**
-* @brief USB_OTG_ResetPort : Reset Host Port
- * @param USBx : Selected device
- * @retval HAL status
- * @note : (1)The application must wait at least 10 ms
- * before clearing the reset bit.
- */
-HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx)
-{
- __IO uint32_t hprt0 = 0;
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- hprt0 = USBx_HPRT0;
-
- hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
- USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
-
- USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
- HAL_Delay (10); /* See Note #1 */
- USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
- return HAL_OK;
-}
-
-/**
- * @brief USB_DriveVbus : activate or de-activate vbus
- * @param state : VBUS state
- * This parameter can be one of the these values:
- * 0 : VBUS Active
- * 1 : VBUS Inactive
- * @retval HAL status
-*/
-HAL_StatusTypeDef USB_DriveVbus (USB_OTG_GlobalTypeDef *USBx, uint8_t state)
-{
- __IO uint32_t hprt0 = 0;
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- hprt0 = USBx_HPRT0;
- hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
- USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
-
- if (((hprt0 & USB_OTG_HPRT_PPWR) == 0 ) && (state == 1 ))
- {
- USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
- }
- if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0 ))
- {
- USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
- }
- return HAL_OK;
-}
-
-/**
- * @brief Return Host Core speed
- * @param USBx : Selected device
- * @retval speed : Host speed
- * This parameter can be one of the these values:
- * @arg USB_OTG_SPEED_FULL: Full speed mode
- * @arg USB_OTG_SPEED_LOW: Low speed mode
- */
-uint32_t USB_GetHostSpeed (USB_OTG_GlobalTypeDef *USBx)
-{
- __IO uint32_t hprt0 = 0;
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- hprt0 = USBx_HPRT0;
- return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
-}
-
-/**
- * @brief Return Host Current Frame number
- * @param USBx : Selected device
- * @retval current frame number
-*/
-uint32_t USB_GetCurrentFrame (USB_OTG_GlobalTypeDef *USBx)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
-}
-
-/**
- * @brief Initialize a host channel
- * @param USBx : Selected device
- * @param ch_num : Channel number
- * This parameter can be a value from 1 to 15
- * @param epnum : Endpoint number
- * This parameter can be a value from 1 to 15
- * @param dev_address : Current device address
- * This parameter can be a value from 0 to 255
- * @param speed : Current device speed
- * This parameter can be one of the these values:
- * @arg USB_OTG_SPEED_FULL: Full speed mode
- * @arg USB_OTG_SPEED_LOW: Low speed mode
- * @param ep_type : Endpoint Type
- * This parameter can be one of the these values:
- * @arg EP_TYPE_CTRL: Control type
- * @arg EP_TYPE_ISOC: Isochronous type
- * @arg EP_TYPE_BULK: Bulk type
- * @arg EP_TYPE_INTR: Interrupt type
- * @param mps : Max Packet Size
- * This parameter can be a value from 0 to32K
- * @retval HAL state
- */
-HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx,
- uint8_t ch_num,
- uint8_t epnum,
- uint8_t dev_address,
- uint8_t speed,
- uint8_t ep_type,
- uint16_t mps)
-{
- /* Clear old interrupt conditions for this host channel. */
- USBx_HC(ch_num)->HCINT = 0xFFFFFFFF;
-
- /* Enable channel interrupts required for this transfer. */
- switch (ep_type)
- {
- case EP_TYPE_CTRL:
- case EP_TYPE_BULK:
- USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
- USB_OTG_HCINTMSK_STALLM |\
- USB_OTG_HCINTMSK_TXERRM |\
- USB_OTG_HCINTMSK_DTERRM |\
- USB_OTG_HCINTMSK_AHBERR |\
- USB_OTG_HCINTMSK_NAKM ;
-
- if (epnum & 0x80)
- {
- USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
- }
- break;
-
- case EP_TYPE_INTR:
- USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
- USB_OTG_HCINTMSK_STALLM |\
- USB_OTG_HCINTMSK_TXERRM |\
- USB_OTG_HCINTMSK_DTERRM |\
- USB_OTG_HCINTMSK_NAKM |\
- USB_OTG_HCINTMSK_AHBERR |\
- USB_OTG_HCINTMSK_FRMORM ;
-
- if (epnum & 0x80)
- {
- USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
- }
-
- break;
-
- case EP_TYPE_ISOC:
- USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
- USB_OTG_HCINTMSK_ACKM |\
- USB_OTG_HCINTMSK_AHBERR |\
- USB_OTG_HCINTMSK_FRMORM ;
-
- if (epnum & 0x80)
- {
- USBx_HC(ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
- }
- break;
- }
-
- /* Enable the top level host channel interrupt. */
- USBx_HOST->HAINTMSK |= (1 << ch_num);
-
- /* Make sure host channel interrupts are enabled. */
- USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
-
- /* Program the HCCHAR register */
- USBx_HC(ch_num)->HCCHAR = (((dev_address << 22) & USB_OTG_HCCHAR_DAD) |\
- (((epnum & 0x7F)<< 11) & USB_OTG_HCCHAR_EPNUM)|\
- ((((epnum & 0x80) == 0x80)<< 15) & USB_OTG_HCCHAR_EPDIR)|\
- (((speed == HPRT0_PRTSPD_LOW_SPEED)<< 17) & USB_OTG_HCCHAR_LSDEV)|\
- ((ep_type << 18) & USB_OTG_HCCHAR_EPTYP)|\
- (mps & USB_OTG_HCCHAR_MPSIZ));
-
- if (ep_type == EP_TYPE_INTR)
- {
- USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM ;
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Start a transfer over a host channel
- * @param USBx : Selected device
- * @param hc : pointer to host channel structure
- * @retval HAL state
- */
-#if defined (__CC_ARM) /*!< ARM Compiler */
-#pragma O0
-#elif defined (__GNUC__) /*!< GNU Compiler */
-#pragma GCC optimize ("O0")
-#endif /* __CC_ARM */
-HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc)
-{
- uint8_t is_oddframe = 0;
- uint16_t len_words = 0;
- uint16_t num_packets = 0;
- uint16_t max_hc_pkt_count = 256;
- uint32_t tmpreg = 0;
-
- /* Compute the expected number of packets associated to the transfer */
- if (hc->xfer_len > 0)
- {
- num_packets = (hc->xfer_len + hc->max_packet - 1) / hc->max_packet;
-
- if (num_packets > max_hc_pkt_count)
- {
- num_packets = max_hc_pkt_count;
- hc->xfer_len = num_packets * hc->max_packet;
- }
- }
- else
- {
- num_packets = 1;
- }
- if (hc->ep_is_in)
- {
- hc->xfer_len = num_packets * hc->max_packet;
- }
-
- /* Initialize the HCTSIZn register */
- USBx_HC(hc->ch_num)->HCTSIZ = (((hc->xfer_len) & USB_OTG_HCTSIZ_XFRSIZ)) |\
- ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |\
- (((hc->data_pid) << 29) & USB_OTG_HCTSIZ_DPID);
-
- is_oddframe = (USBx_HOST->HFNUM & 0x01) ? 0 : 1;
- USBx_HC(hc->ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
- USBx_HC(hc->ch_num)->HCCHAR |= (is_oddframe << 29);
-
- /* Set host channel enable */
- tmpreg = USBx_HC(hc->ch_num)->HCCHAR;
- tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
- tmpreg |= USB_OTG_HCCHAR_CHENA;
- USBx_HC(hc->ch_num)->HCCHAR = tmpreg;
-
- if((hc->ep_is_in == 0) && (hc->xfer_len > 0))
- {
- switch(hc->ep_type)
- {
- /* Non periodic transfer */
- case EP_TYPE_CTRL:
- case EP_TYPE_BULK:
- len_words = (hc->xfer_len + 3) / 4;
-
- /* check if there is enough space in FIFO space */
- if(len_words > (USBx->HNPTXSTS & 0xFFFF))
- {
- /* need to process data in nptxfempty interrupt */
- USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
- }
- break;
-
- /* Periodic transfer */
- case EP_TYPE_INTR:
- case EP_TYPE_ISOC:
- len_words = (hc->xfer_len + 3) / 4;
- /* check if there is enough space in FIFO space */
- if(len_words > (USBx_HOST->HPTXSTS & 0xFFFF)) /* split the transfer */
- {
- /* need to process data in ptxfempty interrupt */
- USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
- }
- break;
-
- default:
- break;
- }
-
- /* Write packet into the Tx FIFO. */
- USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, hc->xfer_len);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Read all host channel interrupts status
- * @param USBx : Selected device
- * @retval HAL state
- */
-uint32_t USB_HC_ReadInterrupt (USB_OTG_GlobalTypeDef *USBx)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- return ((USBx_HOST->HAINT) & 0xFFFF);
-}
-
-/**
- * @brief Halt a host channel
- * @param USBx : Selected device
- * @param hc_num : Host Channel number
- * This parameter can be a value from 1 to 15
- * @retval HAL state
- */
-HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx , uint8_t hc_num)
-{
- uint32_t count = 0;
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- /* Check for space in the request queue to issue the halt. */
- if (((((USBx_HC(hc_num)->HCCHAR) & USB_OTG_HCCHAR_EPTYP) >> 18) == HCCHAR_CTRL) ||
- (((((USBx_HC(hc_num)->HCCHAR) & USB_OTG_HCCHAR_EPTYP) >> 18) == HCCHAR_BULK)))
- {
- USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
-
- if ((USBx->HNPTXSTS & 0xFFFF) == 0)
- {
- USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
- USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
- USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
- do
- {
- if (++count > 1000)
- {
- break;
- }
- }
- while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
- }
- else
- {
- USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
- }
- }
- else
- {
- USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
-
- if ((USBx_HOST->HPTXSTS & 0xFFFF) == 0)
- {
- USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
- USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
- USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
- do
- {
- if (++count > 1000)
- {
- break;
- }
- }
- while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
- }
- else
- {
- USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
- }
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Initiate Do Ping protocol
- * @param USBx : Selected device
- * @param hc_num : Host Channel number
- * This parameter can be a value from 1 to 15
- * @retval HAL state
- */
-HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx , uint8_t ch_num)
-{
- uint8_t num_packets = 1;
- uint32_t tmpreg = 0;
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
-
- USBx_HC(ch_num)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |\
- USB_OTG_HCTSIZ_DOPING;
-
- /* Set host channel enable */
- tmpreg = USBx_HC(ch_num)->HCCHAR;
- tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
- tmpreg |= USB_OTG_HCCHAR_CHENA;
- USBx_HC(ch_num)->HCCHAR = tmpreg;
-
- return HAL_OK;
-}
-
-/**
- * @brief Stop Host Core
- * @param USBx : Selected device
- * @retval HAL state
- */
-HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
-{
- uint8_t index;
- uint32_t count = 0;
- uint32_t value = 0;
-
- USB_DisableGlobalInt(USBx);
-
- /* Flush FIFO */
- USB_FlushTxFifo(USBx, 0x10);
- USB_FlushRxFifo(USBx);
-
- /* Flush out any leftover queued requests. */
- for (index = 0; index <= 15; index++)
- {
- value = USBx_HC(index)->HCCHAR;
- value |= USB_OTG_HCCHAR_CHDIS;
- value &= ~USB_OTG_HCCHAR_CHENA;
- value &= ~USB_OTG_HCCHAR_EPDIR;
- USBx_HC(index)->HCCHAR = value;
- }
-
- /* Halt all channels to put them into a known state. */
- for (index = 0; index <= 15; index++)
- {
- value = USBx_HC(index)->HCCHAR ;
- value |= USB_OTG_HCCHAR_CHDIS;
- value |= USB_OTG_HCCHAR_CHENA;
- value &= ~USB_OTG_HCCHAR_EPDIR;
- USBx_HC(index)->HCCHAR = value;
-
- do
- {
- if (++count > 1000)
- {
- break;
- }
- }
- while ((USBx_HC(index)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
- }
-
- /* Clear any pending Host interrupts */
- USBx_HOST->HAINT = 0xFFFFFFFF;
- USBx->GINTSTS = 0xFFFFFFFF;
- USB_EnableGlobalInt(USBx);
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_ActivateRemoteWakeup : active remote wakeup signalling
- * @param USBx : Selected device
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
- {
- /* active Remote wakeup signalling */
- USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
- }
- return HAL_OK;
-}
-
-/**
- * @brief USB_DeActivateRemoteWakeup : de-active remote wakeup signalling
- * @param USBx : Selected device
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- /* active Remote wakeup signalling */
- USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
- return HAL_OK;
-}
-
-#endif /* USB_OTG_FS */
-
-/*==============================================================================
- USB Device FS peripheral available on STM32F102xx and STM32F103xx devices
-==============================================================================*/
-#if defined (USB)
-/**
- * @brief Initializes the USB Core
- * @param USBx: USB Instance
- * @param cfg : pointer to a USB_CfgTypeDef structure that contains
- * the configuration information for the specified USBx peripheral.
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- UNUSED(cfg);
- /* NOTE : - This function is not required by USB Device FS peripheral, it is used
- only by USB OTG FS peripheral.
- - This function is added to ensure compatibility across platforms.
- */
- return HAL_OK;
-}
-
-/**
- * @brief USB_EnableGlobalInt
- * Enables the controller's Global Int in the AHB Config reg
- * @param USBx : Selected device
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx)
-{
- uint32_t winterruptmask = 0;
-
- /* Set winterruptmask variable */
- winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \
- | USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_RESETM;
-
- /* Set interrupt mask */
- USBx->CNTR |= winterruptmask;
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_DisableGlobalInt
- * Disable the controller's Global Int in the AHB Config reg
- * @param USBx : Selected device
- * @retval HAL status
-*/
-HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx)
-{
- uint32_t winterruptmask = 0;
-
- /* Set winterruptmask variable */
- winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \
- | USB_CNTR_ESOFM | USB_CNTR_RESETM;
-
- /* Clear interrupt mask */
- USBx->CNTR &= ~winterruptmask;
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_SetCurrentMode : Set functional mode
- * @param USBx : Selected device
- * @param mode : current core mode
- * This parameter can be one of the these values:
- * @arg USB_DEVICE_MODE: Peripheral mode mode
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx , USB_ModeTypeDef mode)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- UNUSED(mode);
- /* NOTE : - This function is not required by USB Device FS peripheral, it is used
- only by USB OTG FS peripheral.
- - This function is added to ensure compatibility across platforms.
- */
- return HAL_OK;
-}
-
-/**
- * @brief USB_DevInit : Initializes the USB controller registers
- * for device mode
- * @param USBx : Selected device
- * @param cfg : pointer to a USB_CfgTypeDef structure that contains
- * the configuration information for the specified USBx peripheral.
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_DevInit (USB_TypeDef *USBx, USB_CfgTypeDef cfg)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(cfg);
-
- /* Init Device */
- /*CNTR_FRES = 1*/
- USBx->CNTR = USB_CNTR_FRES;
-
- /*CNTR_FRES = 0*/
- USBx->CNTR = 0;
-
- /*Clear pending interrupts*/
- USBx->ISTR = 0;
-
- /*Set Btable Address*/
- USBx->BTABLE = BTABLE_ADDRESS;
-
- /* Enable USB Device Interrupt mask */
- USB_EnableGlobalInt(USBx);
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_FlushTxFifo : Flush a Tx FIFO
- * @param USBx : Selected device
- * @param num : FIFO number
- * This parameter can be a value from 1 to 15
- 15 means Flush all Tx FIFOs
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_FlushTxFifo (USB_TypeDef *USBx, uint32_t num)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- UNUSED(num);
- /* NOTE : - This function is not required by USB Device FS peripheral, it is used
- only by USB OTG FS peripheral.
- - This function is added to ensure compatibility across platforms.
- */
- return HAL_OK;
-}
-
-/**
- * @brief USB_FlushRxFifo : Flush Rx FIFO
- * @param USBx : Selected device
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_FlushRxFifo(USB_TypeDef *USBx)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- /* NOTE : - This function is not required by USB Device FS peripheral, it is used
- only by USB OTG FS peripheral.
- - This function is added to ensure compatibility across platforms.
- */
- return HAL_OK;
-}
-
-/**
- * @brief Activate and configure an endpoint
- * @param USBx : Selected device
- * @param ep: pointer to endpoint structure
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
-{
- /* initialize Endpoint */
- switch (ep->type)
- {
- case EP_TYPE_CTRL:
- PCD_SET_EPTYPE(USBx, ep->num, USB_EP_CONTROL);
- break;
- case EP_TYPE_BULK:
- PCD_SET_EPTYPE(USBx, ep->num, USB_EP_BULK);
- break;
- case EP_TYPE_INTR:
- PCD_SET_EPTYPE(USBx, ep->num, USB_EP_INTERRUPT);
- break;
- case EP_TYPE_ISOC:
- PCD_SET_EPTYPE(USBx, ep->num, USB_EP_ISOCHRONOUS);
- break;
- default:
- break;
- }
-
- PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num);
-
- if (ep->doublebuffer == 0)
- {
- if (ep->is_in)
- {
- /*Set the endpoint Transmit buffer address */
- PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress);
- PCD_CLEAR_TX_DTOG(USBx, ep->num);
- /* Configure NAK status for the Endpoint*/
- PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
- }
- else
- {
- /*Set the endpoint Receive buffer address */
- PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress);
- /*Set the endpoint Receive buffer counter*/
- PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket);
- PCD_CLEAR_RX_DTOG(USBx, ep->num);
- /* Configure VALID status for the Endpoint*/
- PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
- }
- }
- /*Double Buffer*/
- else
- {
- /*Set the endpoint as double buffered*/
- PCD_SET_EP_DBUF(USBx, ep->num);
- /*Set buffer address for double buffered mode*/
- PCD_SET_EP_DBUF_ADDR(USBx, ep->num,ep->pmaaddr0, ep->pmaaddr1);
-
- if (ep->is_in==0)
- {
- /* Clear the data toggle bits for the endpoint IN/OUT*/
- PCD_CLEAR_RX_DTOG(USBx, ep->num);
- PCD_CLEAR_TX_DTOG(USBx, ep->num);
-
- /* Reset value of the data toggle bits for the endpoint out*/
- PCD_TX_DTOG(USBx, ep->num);
-
- PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
- PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
- }
- else
- {
- /* Clear the data toggle bits for the endpoint IN/OUT*/
- PCD_CLEAR_RX_DTOG(USBx, ep->num);
- PCD_CLEAR_TX_DTOG(USBx, ep->num);
- PCD_RX_DTOG(USBx, ep->num);
- /* Configure DISABLE status for the Endpoint*/
- PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
- PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
- }
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief De-activate and de-initialize an endpoint
- * @param USBx : Selected device
- * @param ep: pointer to endpoint structure
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
-{
- if (ep->doublebuffer == 0)
- {
- if (ep->is_in)
- {
- PCD_CLEAR_TX_DTOG(USBx, ep->num);
- /* Configure DISABLE status for the Endpoint*/
- PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
- }
- else
- {
- PCD_CLEAR_RX_DTOG(USBx, ep->num);
- /* Configure DISABLE status for the Endpoint*/
- PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
- }
- }
- /*Double Buffer*/
- else
- {
- if (ep->is_in==0)
- {
- /* Clear the data toggle bits for the endpoint IN/OUT*/
- PCD_CLEAR_RX_DTOG(USBx, ep->num);
- PCD_CLEAR_TX_DTOG(USBx, ep->num);
-
- /* Reset value of the data toggle bits for the endpoint out*/
- PCD_TX_DTOG(USBx, ep->num);
-
- PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
- PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
- }
- else
- {
- /* Clear the data toggle bits for the endpoint IN/OUT*/
- PCD_CLEAR_RX_DTOG(USBx, ep->num);
- PCD_CLEAR_TX_DTOG(USBx, ep->num);
- PCD_RX_DTOG(USBx, ep->num);
- /* Configure DISABLE status for the Endpoint*/
- PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
- PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
- }
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_EPStartXfer : setup and starts a transfer over an EP
- * @param USBx : Selected device
- * @param ep: pointer to endpoint structure
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx , USB_EPTypeDef *ep)
-{
- uint16_t pmabuffer = 0;
- uint32_t len = ep->xfer_len;
-
- /* IN endpoint */
- if (ep->is_in == 1)
- {
- /*Multi packet transfer*/
- if (ep->xfer_len > ep->maxpacket)
- {
- len=ep->maxpacket;
- ep->xfer_len-=len;
- }
- else
- {
- len=ep->xfer_len;
- ep->xfer_len =0;
- }
-
- /* configure and validate Tx endpoint */
- if (ep->doublebuffer == 0)
- {
- USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, len);
- PCD_SET_EP_TX_CNT(USBx, ep->num, len);
- }
- else
- {
- /* Write the data to the USB endpoint */
- if (PCD_GET_ENDPOINT(USBx, ep->num)& USB_EP_DTOG_TX)
- {
- /* Set the Double buffer counter for pmabuffer1 */
- PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
- pmabuffer = ep->pmaaddr1;
- }
- else
- {
- /* Set the Double buffer counter for pmabuffer0 */
- PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
- pmabuffer = ep->pmaaddr0;
- }
- USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, len);
- PCD_FreeUserBuffer(USBx, ep->num, ep->is_in);
- }
-
- PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
- }
- else /* OUT endpoint */
- {
- /* Multi packet transfer*/
- if (ep->xfer_len > ep->maxpacket)
- {
- len=ep->maxpacket;
- ep->xfer_len-=len;
- }
- else
- {
- len=ep->xfer_len;
- ep->xfer_len =0;
- }
-
- /* configure and validate Rx endpoint */
- if (ep->doublebuffer == 0)
- {
- /*Set RX buffer count*/
- PCD_SET_EP_RX_CNT(USBx, ep->num, len);
- }
- else
- {
- /*Set the Double buffer counter*/
- PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len);
- }
-
- PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
- * with the EP/channel
- * @param USBx : Selected device
- * @param src : pointer to source buffer
- * @param ch_ep_num : endpoint or host channel number
- * @param len : Number of bytes to write
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_WritePacket(USB_TypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- UNUSED(src);
- UNUSED(ch_ep_num);
- UNUSED(len);
- /* NOTE : - This function is not required by USB Device FS peripheral, it is used
- only by USB OTG FS peripheral.
- - This function is added to ensure compatibility across platforms.
- */
- return HAL_OK;
-}
-
-/**
- * @brief USB_ReadPacket : read a packet from the Tx FIFO associated
- * with the EP/channel
- * @param USBx : Selected device
- * @param dest : destination pointer
- * @param len : Number of bytes to read
- * @retval pointer to destination buffer
- */
-void *USB_ReadPacket(USB_TypeDef *USBx, uint8_t *dest, uint16_t len)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- UNUSED(dest);
- UNUSED(len);
- /* NOTE : - This function is not required by USB Device FS peripheral, it is used
- only by USB OTG FS peripheral.
- - This function is added to ensure compatibility across platforms.
- */
- return ((void *)NULL);
-}
-
-/**
- * @brief USB_EPSetStall : set a stall condition over an EP
- * @param USBx : Selected device
- * @param ep: pointer to endpoint structure
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx , USB_EPTypeDef *ep)
-{
- if (ep->num == 0)
- {
- /* This macro sets STALL status for RX & TX*/
- PCD_SET_EP_TXRX_STATUS(USBx, ep->num, USB_EP_RX_STALL, USB_EP_TX_STALL);
- }
- else
- {
- if (ep->is_in)
- {
- PCD_SET_EP_TX_STATUS(USBx, ep->num , USB_EP_TX_STALL);
- }
- else
- {
- PCD_SET_EP_RX_STATUS(USBx, ep->num , USB_EP_RX_STALL);
- }
- }
- return HAL_OK;
-}
-
-/**
- * @brief USB_EPClearStall : Clear a stall condition over an EP
- * @param USBx : Selected device
- * @param ep: pointer to endpoint structure
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
-{
- if (ep->is_in)
- {
- PCD_CLEAR_TX_DTOG(USBx, ep->num);
- PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
- }
- else
- {
- PCD_CLEAR_RX_DTOG(USBx, ep->num);
- PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
- }
- return HAL_OK;
-}
-
-/**
- * @brief USB_StopDevice : Stop the usb device mode
- * @param USBx : Selected device
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
-{
- /* disable all interrupts and force USB reset */
- USBx->CNTR = USB_CNTR_FRES;
-
- /* clear interrupt status register */
- USBx->ISTR = 0;
-
- /* switch-off device */
- USBx->CNTR = (USB_CNTR_FRES | USB_CNTR_PDWN);
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_SetDevAddress : Stop the usb device mode
- * @param USBx : Selected device
- * @param address : new device address to be assigned
- * This parameter can be a value from 0 to 255
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_SetDevAddress (USB_TypeDef *USBx, uint8_t address)
-{
- if(address == 0)
- {
- /* set device address and enable function */
- USBx->DADDR = USB_DADDR_EF;
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down
- * @param USBx : Selected device
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_DevConnect (USB_TypeDef *USBx)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- /* NOTE : - This function is not required by USB Device FS peripheral, it is used
- only by USB OTG FS peripheral.
- - This function is added to ensure compatibility across platforms.
- */
- return HAL_OK;
-}
-
-/**
- * @brief USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down
- * @param USBx : Selected device
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_DevDisconnect (USB_TypeDef *USBx)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- /* NOTE : - This function is not required by USB Device FS peripheral, it is used
- only by USB OTG FS peripheral.
- - This function is added to ensure compatibility across platforms.
- */
- return HAL_OK;
-}
-
-/**
- * @brief USB_ReadInterrupts: return the global USB interrupt status
- * @param USBx : Selected device
- * @retval HAL status
- */
-uint32_t USB_ReadInterrupts (USB_TypeDef *USBx)
-{
- uint32_t tmpreg = 0;
-
- tmpreg = USBx->ISTR;
- return tmpreg;
-}
-
-/**
- * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
- * @param USBx : Selected device
- * @retval HAL status
- */
-uint32_t USB_ReadDevAllOutEpInterrupt (USB_TypeDef *USBx)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- /* NOTE : - This function is not required by USB Device FS peripheral, it is used
- only by USB OTG FS peripheral.
- - This function is added to ensure compatibility across platforms.
- */
- return (0);
-}
-
-/**
- * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
- * @param USBx : Selected device
- * @retval HAL status
- */
-uint32_t USB_ReadDevAllInEpInterrupt (USB_TypeDef *USBx)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- /* NOTE : - This function is not required by USB Device FS peripheral, it is used
- only by USB OTG FS peripheral.
- - This function is added to ensure compatibility across platforms.
- */
- return (0);
-}
-
-/**
- * @brief Returns Device OUT EP Interrupt register
- * @param USBx : Selected device
- * @param epnum : endpoint number
- * This parameter can be a value from 0 to 15
- * @retval Device OUT EP Interrupt register
- */
-uint32_t USB_ReadDevOutEPInterrupt (USB_TypeDef *USBx , uint8_t epnum)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- UNUSED(epnum);
- /* NOTE : - This function is not required by USB Device FS peripheral, it is used
- only by USB OTG FS peripheral.
- - This function is added to ensure compatibility across platforms.
- */
- return (0);
-}
-
-/**
- * @brief Returns Device IN EP Interrupt register
- * @param USBx : Selected device
- * @param epnum : endpoint number
- * This parameter can be a value from 0 to 15
- * @retval Device IN EP Interrupt register
- */
-uint32_t USB_ReadDevInEPInterrupt (USB_TypeDef *USBx , uint8_t epnum)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- UNUSED(epnum);
- /* NOTE : - This function is not required by USB Device FS peripheral, it is used
- only by USB OTG FS peripheral.
- - This function is added to ensure compatibility across platforms.
- */
- return (0);
-}
-
-/**
- * @brief USB_ClearInterrupts: clear a USB interrupt
- * @param USBx : Selected device
- * @param interrupt : interrupt flag
- * @retval None
- */
-void USB_ClearInterrupts (USB_TypeDef *USBx, uint32_t interrupt)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- UNUSED(interrupt);
- /* NOTE : - This function is not required by USB Device FS peripheral, it is used
- only by USB OTG FS peripheral.
- - This function is added to ensure compatibility across platforms.
- */
-}
-
-/**
- * @brief Prepare the EP0 to start the first control setup
- * @param USBx : Selected device
- * @param psetup : pointer to setup packet
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_EP0_OutStart(USB_TypeDef *USBx, uint8_t *psetup)
-{
- /* Prevent unused argument(s) compilation warning */
- UNUSED(USBx);
- UNUSED(psetup);
- /* NOTE : - This function is not required by USB Device FS peripheral, it is used
- only by USB OTG FS peripheral.
- - This function is added to ensure compatibility across platforms.
- */
- return HAL_OK;
-}
-
-/**
- * @brief USB_ActivateRemoteWakeup : active remote wakeup signalling
- * @param USBx : Selected device
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
-{
- USBx->CNTR |= USB_CNTR_RESUME;
-
- return HAL_OK;
-}
-
-/**
- * @brief USB_DeActivateRemoteWakeup : de-active remote wakeup signalling
- * @param USBx : Selected device
- * @retval HAL status
- */
-HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
-{
- USBx->CNTR &= ~(USB_CNTR_RESUME);
- return HAL_OK;
-}
-
-/**
- * @brief Copy a buffer from user memory area to packet memory area (PMA)
- * @param USBx : pointer to USB register.
- * @param pbUsrBuf : pointer to user memory area.
- * @param wPMABufAddr : address into PMA.
- * @param wNBytes : number of bytes to be copied.
- * @retval None
- */
-void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
-{
- uint32_t nbytes = (wNBytes + 1) >> 1; /* nbytes = (wNBytes + 1) / 2 */
- uint32_t index = 0, temp1 = 0, temp2 = 0;
- uint16_t *pdwVal = NULL;
-
- pdwVal = (uint16_t *)(wPMABufAddr * 2 + (uint32_t)USBx + 0x400);
- for (index = nbytes; index != 0; index--)
- {
- temp1 = (uint16_t) * pbUsrBuf;
- pbUsrBuf++;
- temp2 = temp1 | (uint16_t) * pbUsrBuf << 8;
- *pdwVal++ = temp2;
- pdwVal++;
- pbUsrBuf++;
- }
-}
-
-/**
- * @brief Copy a buffer from user memory area to packet memory area (PMA)
- * @param USBx : pointer to USB register.
-* @param pbUsrBuf : pointer to user memory area.
- * @param wPMABufAddr : address into PMA.
- * @param wNBytes : number of bytes to be copied.
- * @retval None
- */
-void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
-{
- uint32_t nbytes = (wNBytes + 1) >> 1;/* /2*/
- uint32_t index = 0;
- uint32_t *pdwVal = NULL;
-
- pdwVal = (uint32_t *)(wPMABufAddr * 2 + (uint32_t)USBx + 0x400);
- for (index = nbytes; index != 0; index--)
- {
- *(uint16_t*)pbUsrBuf++ = *pdwVal++;
- pbUsrBuf++;
- }
-}
-
-#endif /* USB */
-
-/**
- * @}
- */
-/**
- * @}
- */
-
-#if defined (USB_OTG_FS)
-/** @addtogroup USB_LL_Private_Functions
- * @{
- */
-/**
- * @brief Reset the USB Core (needed after USB clock settings change)
- * @param USBx : Selected device
- * @retval HAL status
- */
-static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
-{
- uint32_t count = 0;
-
- /* Wait for AHB master IDLE state. */
- do
- {
- if (++count > 200000)
- {
- return HAL_TIMEOUT;
- }
- }
- while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0);
-
- /* Core Soft Reset */
- count = 0;
- USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
-
- do
- {
- if (++count > 200000)
- {
- return HAL_TIMEOUT;
- }
- }
- while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
-
- return HAL_OK;
-}
-/**
- * @}
- */
-#endif /* USB_OTG_FS */
-
-#endif /* STM32F102x6 || STM32F102xB || */
- /* STM32F103x6 || STM32F103xB || */
- /* STM32F103xE || STM32F103xG || */
- /* STM32F105xC || STM32F107xC */
-
-#endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_utils.c b/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_utils.c
deleted file mode 100644
index e5de6cf..0000000
--- a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_utils.c
+++ /dev/null
@@ -1,621 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_ll_utils.c
- * @author MCD Application Team
- * @brief UTILS LL module driver.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_rcc.h"
-#include "stm32f1xx_ll_utils.h"
-#include "stm32f1xx_ll_system.h"
-#ifdef USE_FULL_ASSERT
-#include "stm32_assert.h"
-#else
-#define assert_param(expr) ((void)0U)
-#endif
-
-/** @addtogroup STM32F1xx_LL_Driver
- * @{
- */
-
-/** @addtogroup UTILS_LL
- * @{
- */
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/** @addtogroup UTILS_LL_Private_Constants
- * @{
- */
-
-/* Defines used for PLL range */
-#define UTILS_PLL_OUTPUT_MAX RCC_MAX_FREQUENCY /*!< Frequency max for PLL output, in Hz */
-
-/* Defines used for HSE range */
-#define UTILS_HSE_FREQUENCY_MIN RCC_HSE_MIN /*!< Frequency min for HSE frequency, in Hz */
-#define UTILS_HSE_FREQUENCY_MAX RCC_HSE_MAX /*!< Frequency max for HSE frequency, in Hz */
-
-/* Defines used for FLASH latency according to HCLK Frequency */
-#if defined(FLASH_ACR_LATENCY)
-#define UTILS_LATENCY1_FREQ 24000000U /*!< SYSCLK frequency to set FLASH latency 1 */
-#define UTILS_LATENCY2_FREQ 48000000U /*!< SYSCLK frequency to set FLASH latency 2 */
-#else
- /*!< No Latency Configuration in this device */
-#endif
-/**
- * @}
- */
-/* Private macros ------------------------------------------------------------*/
-/** @addtogroup UTILS_LL_Private_Macros
- * @{
- */
-#define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1) \
- || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2) \
- || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4) \
- || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8) \
- || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16) \
- || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64) \
- || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
- || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
- || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
-
-#define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
- || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
- || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
- || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
- || ((__VALUE__) == LL_RCC_APB1_DIV_16))
-
-#define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
- || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
- || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
- || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
- || ((__VALUE__) == LL_RCC_APB2_DIV_16))
-
-#if defined(RCC_CFGR_PLLMULL6_5)
-#define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_4) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_5) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_6) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_7) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_8) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_9) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_6_5))
-#else
-#define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_2) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_3) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_4) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_5) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_6) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_7) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_8) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_9) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_10) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_11) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_12) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_13) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_14) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_15) \
- || ((__VALUE__) == LL_RCC_PLL_MUL_16))
-#endif /* RCC_CFGR_PLLMULL6_5 */
-
-#if defined(RCC_CFGR2_PREDIV1)
-#define IS_LL_UTILS_PREDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PREDIV_DIV_1) || ((__VALUE__) == LL_RCC_PREDIV_DIV_2) || \
- ((__VALUE__) == LL_RCC_PREDIV_DIV_3) || ((__VALUE__) == LL_RCC_PREDIV_DIV_4) || \
- ((__VALUE__) == LL_RCC_PREDIV_DIV_5) || ((__VALUE__) == LL_RCC_PREDIV_DIV_6) || \
- ((__VALUE__) == LL_RCC_PREDIV_DIV_7) || ((__VALUE__) == LL_RCC_PREDIV_DIV_8) || \
- ((__VALUE__) == LL_RCC_PREDIV_DIV_9) || ((__VALUE__) == LL_RCC_PREDIV_DIV_10) || \
- ((__VALUE__) == LL_RCC_PREDIV_DIV_11) || ((__VALUE__) == LL_RCC_PREDIV_DIV_12) || \
- ((__VALUE__) == LL_RCC_PREDIV_DIV_13) || ((__VALUE__) == LL_RCC_PREDIV_DIV_14) || \
- ((__VALUE__) == LL_RCC_PREDIV_DIV_15) || ((__VALUE__) == LL_RCC_PREDIV_DIV_16))
-#else
-#define IS_LL_UTILS_PREDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PREDIV_DIV_1) || ((__VALUE__) == LL_RCC_PREDIV_DIV_2))
-#endif /*RCC_PREDIV1_DIV_2_16_SUPPORT*/
-
-#define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((__VALUE__) <= UTILS_PLL_OUTPUT_MAX)
-
-
-#define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
- || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
-
-#define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
-/**
- * @}
- */
-/* Private function prototypes -----------------------------------------------*/
-/** @defgroup UTILS_LL_Private_Functions UTILS Private functions
- * @{
- */
-static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
- LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
-#if defined(FLASH_ACR_LATENCY)
-static ErrorStatus UTILS_SetFlashLatency(uint32_t Frequency);
-#endif /* FLASH_ACR_LATENCY */
-static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
-static ErrorStatus UTILS_PLL_IsBusy(void);
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup UTILS_LL_Exported_Functions
- * @{
- */
-
-/** @addtogroup UTILS_LL_EF_DELAY
- * @{
- */
-
-/**
- * @brief This function configures the Cortex-M SysTick source to have 1ms time base.
- * @note When a RTOS is used, it is recommended to avoid changing the Systick
- * configuration by calling this function, for a delay use rather osDelay RTOS service.
- * @param HCLKFrequency HCLK frequency in Hz
- * @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
- * @retval None
- */
-void LL_Init1msTick(uint32_t HCLKFrequency)
-{
- /* Use frequency provided in argument */
- LL_InitTick(HCLKFrequency, 1000U);
-}
-
-/**
- * @brief This function provides accurate delay (in milliseconds) based
- * on SysTick counter flag
- * @note When a RTOS is used, it is recommended to avoid using blocking delay
- * and use rather osDelay service.
- * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
- * will configure Systick to 1ms
- * @param Delay specifies the delay time length, in milliseconds.
- * @retval None
- */
-void LL_mDelay(uint32_t Delay)
-{
- __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
- /* Add this code to indicate that local variable is not used */
- ((void)tmp);
-
- /* Add a period to guaranty minimum wait */
- if (Delay < LL_MAX_DELAY)
- {
- Delay++;
- }
-
- while (Delay)
- {
- if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
- {
- Delay--;
- }
- }
-}
-
-/**
- * @}
- */
-
-/** @addtogroup UTILS_EF_SYSTEM
- * @brief System Configuration functions
- *
- @verbatim
- ===============================================================================
- ##### System Configuration functions #####
- ===============================================================================
- [..]
- System, AHB and APB buses clocks configuration
-
- (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is RCC_MAX_FREQUENCY Hz.
- @endverbatim
- @internal
- Depending on the SYSCLK frequency, the flash latency should be adapted accordingly:
- (++) +-----------------------------------------------+
- (++) | Latency | SYSCLK clock frequency (MHz) |
- (++) |---------------|-------------------------------|
- (++) |0WS(1CPU cycle)| 0 < SYSCLK <= 24 |
- (++) |---------------|-------------------------------|
- (++) |1WS(2CPU cycle)| 24 < SYSCLK <= 48 |
- (++) |---------------|-------------------------------|
- (++) |2WS(3CPU cycle)| 48 < SYSCLK <= 72 |
- (++) +-----------------------------------------------+
- @endinternal
- * @{
- */
-
-/**
- * @brief This function sets directly SystemCoreClock CMSIS variable.
- * @note Variable can be calculated also through SystemCoreClockUpdate function.
- * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
- * @retval None
- */
-void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
-{
- /* HCLK clock frequency */
- SystemCoreClock = HCLKFrequency;
-}
-
-/**
- * @brief This function configures system clock with HSI as clock source of the PLL
- * @note The application need to ensure that PLL is disabled.
- * @note Function is based on the following formula:
- * - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
- * - PREDIV: Set to 2 for few devices
- * - PLLMUL: The application software must set correctly the PLL multiplication factor to
- * not exceed 72MHz
- * @note FLASH latency can be modified through this function.
- * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
- * the configuration information for the PLL.
- * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
- * the configuration information for the BUS prescalers.
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: Max frequency configuration done
- * - ERROR: Max frequency configuration not done
- */
-ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
- LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
-{
- ErrorStatus status = SUCCESS;
- uint32_t pllfreq = 0U;
-
- /* Check if one of the PLL is enabled */
- if (UTILS_PLL_IsBusy() == SUCCESS)
- {
-#if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
- /* Check PREDIV value */
- assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
-#else
- /* Force PREDIV value to 2 */
- UTILS_PLLInitStruct->Prediv = LL_RCC_PREDIV_DIV_2;
-#endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
- /* Calculate the new PLL output frequency */
- pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
-
- /* Enable HSI if not enabled */
- if (LL_RCC_HSI_IsReady() != 1U)
- {
- LL_RCC_HSI_Enable();
- while (LL_RCC_HSI_IsReady() != 1U)
- {
- /* Wait for HSI ready */
- }
- }
-
- /* Configure PLL */
- LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, UTILS_PLLInitStruct->PLLMul);
-
- /* Enable PLL and switch system clock to PLL */
- status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
- }
- else
- {
- /* Current PLL configuration cannot be modified */
- status = ERROR;
- }
-
- return status;
-}
-
-/**
- * @brief This function configures system clock with HSE as clock source of the PLL
- * @note The application need to ensure that PLL is disabled.
- * @note Function is based on the following formula:
- * - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
- * - PREDIV: Set to 2 for few devices
- * - PLLMUL: The application software must set correctly the PLL multiplication factor to
- * not exceed @ref UTILS_PLL_OUTPUT_MAX
- * @note FLASH latency can be modified through this function.
- * @param HSEFrequency Value between Min_Data = RCC_HSE_MIN and Max_Data = RCC_HSE_MAX
- * @param HSEBypass This parameter can be one of the following values:
- * @arg @ref LL_UTILS_HSEBYPASS_ON
- * @arg @ref LL_UTILS_HSEBYPASS_OFF
- * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
- * the configuration information for the PLL.
- * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
- * the configuration information for the BUS prescalers.
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: Max frequency configuration done
- * - ERROR: Max frequency configuration not done
- */
-ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
- LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
-{
- ErrorStatus status = SUCCESS;
- uint32_t pllfreq = 0U;
-
- /* Check the parameters */
- assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
- assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
-
- /* Check if one of the PLL is enabled */
- if (UTILS_PLL_IsBusy() == SUCCESS)
- {
- assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->Prediv));
-
- /* Calculate the new PLL output frequency */
- pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
-
- /* Enable HSE if not enabled */
- if (LL_RCC_HSE_IsReady() != 1U)
- {
- /* Check if need to enable HSE bypass feature or not */
- if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
- {
- LL_RCC_HSE_EnableBypass();
- }
- else
- {
- LL_RCC_HSE_DisableBypass();
- }
-
- /* Enable HSE */
- LL_RCC_HSE_Enable();
- while (LL_RCC_HSE_IsReady() != 1U)
- {
- /* Wait for HSE ready */
- }
- }
-
- /* Configure PLL */
- LL_RCC_PLL_ConfigDomain_SYS((RCC_CFGR_PLLSRC | UTILS_PLLInitStruct->Prediv), UTILS_PLLInitStruct->PLLMul);
-
- /* Enable PLL and switch system clock to PLL */
- status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
- }
- else
- {
- /* Current PLL configuration cannot be modified */
- status = ERROR;
- }
-
- return status;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup UTILS_LL_Private_Functions
- * @{
- */
-/**
- * @brief Update number of Flash wait states in line with new frequency and current
- voltage range.
- * @param Frequency SYSCLK frequency
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: Latency has been modified
- * - ERROR: Latency cannot be modified
- */
-#if defined(FLASH_ACR_LATENCY)
-static ErrorStatus UTILS_SetFlashLatency(uint32_t Frequency)
-{
- ErrorStatus status = SUCCESS;
-
- uint32_t latency = LL_FLASH_LATENCY_0; /* default value 0WS */
-
- /* Frequency cannot be equal to 0 */
- if (Frequency == 0U)
- {
- status = ERROR;
- }
- else
- {
- if (Frequency > UTILS_LATENCY2_FREQ)
- {
- /* 48 < SYSCLK <= 72 => 2WS (3 CPU cycles) */
- latency = LL_FLASH_LATENCY_2;
- }
- else
- {
- if (Frequency > UTILS_LATENCY1_FREQ)
- {
- /* 24 < SYSCLK <= 48 => 1WS (2 CPU cycles) */
- latency = LL_FLASH_LATENCY_1;
- }
- /* else SYSCLK < 24MHz default LL_FLASH_LATENCY_0 0WS */
- }
-
- LL_FLASH_SetLatency(latency);
-
- /* Check that the new number of wait states is taken into account to access the Flash
- memory by reading the FLASH_ACR register */
- if (LL_FLASH_GetLatency() != latency)
- {
- status = ERROR;
- }
- }
- return status;
-}
-#endif /* FLASH_ACR_LATENCY */
-
-/**
- * @brief Function to check that PLL can be modified
- * @param PLL_InputFrequency PLL input frequency (in Hz)
- * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
- * the configuration information for the PLL.
- * @retval PLL output frequency (in Hz)
- */
-static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
-{
- uint32_t pllfreq = 0U;
-
- /* Check the parameters */
- assert_param(IS_LL_UTILS_PLLMUL_VALUE(UTILS_PLLInitStruct->PLLMul));
-
- /* Check different PLL parameters according to RM */
-#if defined (RCC_CFGR2_PREDIV1)
- pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / (UTILS_PLLInitStruct->Prediv + 1U), UTILS_PLLInitStruct->PLLMul);
-#elif defined(RCC_CFGR2_PREDIV1SRC)
- pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
-#else
- pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / ((UTILS_PLLInitStruct->Prediv >> RCC_CFGR_PLLXTPRE_Pos) + 1U), UTILS_PLLInitStruct->PLLMul);
-#endif /*RCC_CFGR2_PREDIV1SRC*/
- assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
-
- return pllfreq;
-}
-
-/**
- * @brief Function to check that PLL can be modified
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: PLL modification can be done
- * - ERROR: PLL is busy
- */
-static ErrorStatus UTILS_PLL_IsBusy(void)
-{
- ErrorStatus status = SUCCESS;
-
- /* Check if PLL is busy*/
- if (LL_RCC_PLL_IsReady() != 0U)
- {
- /* PLL configuration cannot be modified */
- status = ERROR;
- }
-#if defined(RCC_PLL2_SUPPORT)
- /* Check if PLL2 is busy*/
- if (LL_RCC_PLL2_IsReady() != 0U)
- {
- /* PLL2 configuration cannot be modified */
- status = ERROR;
- }
-#endif /* RCC_PLL2_SUPPORT */
-
-#if defined(RCC_PLLI2S_SUPPORT)
- /* Check if PLLI2S is busy*/
- if (LL_RCC_PLLI2S_IsReady() != 0U)
- {
- /* PLLI2S configuration cannot be modified */
- status = ERROR;
- }
-#endif /* RCC_PLLI2S_SUPPORT */
-
- return status;
-}
-
-/**
- * @brief Function to enable PLL and switch system clock to PLL
- * @param SYSCLK_Frequency SYSCLK frequency
- * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
- * the configuration information for the BUS prescalers.
- * @retval An ErrorStatus enumeration value:
- * - SUCCESS: No problem to switch system to PLL
- * - ERROR: Problem to switch system to PLL
- */
-static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
-{
- ErrorStatus status = SUCCESS;
-#if defined(FLASH_ACR_LATENCY)
- uint32_t sysclk_frequency_current = 0U;
-#endif /* FLASH_ACR_LATENCY */
-
- assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
- assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
- assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
-
-#if defined(FLASH_ACR_LATENCY)
- /* Calculate current SYSCLK frequency */
- sysclk_frequency_current = (SystemCoreClock << AHBPrescTable[LL_RCC_GetAHBPrescaler() >> RCC_CFGR_HPRE_Pos]);
-#endif /* FLASH_ACR_LATENCY */
-
- /* Increasing the number of wait states because of higher CPU frequency */
-#if defined (FLASH_ACR_LATENCY)
- if (sysclk_frequency_current < SYSCLK_Frequency)
- {
- /* Set FLASH latency to highest latency */
- status = UTILS_SetFlashLatency(SYSCLK_Frequency);
- }
-#endif /* FLASH_ACR_LATENCY */
-
- /* Update system clock configuration */
- if (status == SUCCESS)
- {
-#if defined(RCC_PLL2_SUPPORT)
- /* Enable PLL2 */
- LL_RCC_PLL2_Enable();
- while (LL_RCC_PLL2_IsReady() != 1U)
- {
- /* Wait for PLL2 ready */
- }
-
-#endif /* RCC_PLL2_SUPPORT */
- /* Enable PLL */
- LL_RCC_PLL_Enable();
- while (LL_RCC_PLL_IsReady() != 1U)
- {
- /* Wait for PLL ready */
- }
-
- /* Sysclk activation on the main PLL */
- LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
- LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
- while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
- {
- /* Wait for system clock switch to PLL */
- }
-
- /* Set APB1 & APB2 prescaler*/
- LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
- LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
- }
-
- /* Decreasing the number of wait states because of lower CPU frequency */
-#if defined (FLASH_ACR_LATENCY)
- if (sysclk_frequency_current > SYSCLK_Frequency)
- {
- /* Set FLASH latency to lowest latency */
- status = UTILS_SetFlashLatency(SYSCLK_Frequency);
- }
-#endif /* FLASH_ACR_LATENCY */
-
- /* Update SystemCoreClock variable */
- if (status == SUCCESS)
- {
- LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider));
- }
-
- return status;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Inc/main.h b/assets/templates/blackpill/Inc/main.h
deleted file mode 100644
index 1ce83b2..0000000
--- a/assets/templates/blackpill/Inc/main.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* USER CODE BEGIN Header */
-/**
- ******************************************************************************
- * @file : main.h
- * @brief : Header for main.c file.
- * This file contains the common defines of the application.
- ******************************************************************************
- ** This notice applies to any and all portions of this file
- * that are not between comment pairs USER CODE BEGIN and
- * USER CODE END. Other portions of this file, whether
- * inserted by the user or by software development tools
- * are owned by their respective copyright owners.
- *
- * COPYRIGHT(c) 2019 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-/* USER CODE END Header */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __MAIN_H
-#define __MAIN_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_ll_rcc.h"
-#include "stm32f1xx_ll_bus.h"
-#include "stm32f1xx_ll_system.h"
-#include "stm32f1xx_ll_exti.h"
-#include "stm32f1xx_ll_cortex.h"
-#include "stm32f1xx_ll_utils.h"
-#include "stm32f1xx_ll_pwr.h"
-#include "stm32f1xx_ll_dma.h"
-#include "stm32f1xx_ll_usart.h"
-#include "stm32f1xx.h"
-#include "stm32f1xx_ll_gpio.h"
-
-#if defined(USE_FULL_ASSERT)
-#include "stm32_assert.h"
-#endif /* USE_FULL_ASSERT */
-
-/* Private includes ----------------------------------------------------------*/
-/* USER CODE BEGIN Includes */
-
-/* USER CODE END Includes */
-
-/* Exported types ------------------------------------------------------------*/
-/* USER CODE BEGIN ET */
-
-/* USER CODE END ET */
-
-/* Exported constants --------------------------------------------------------*/
-/* USER CODE BEGIN EC */
-
-/* USER CODE END EC */
-
-/* Exported macro ------------------------------------------------------------*/
-/* USER CODE BEGIN EM */
-
-/* USER CODE END EM */
-
-/* Exported functions prototypes ---------------------------------------------*/
-void Error_Handler(void);
-
-/* USER CODE BEGIN EFP */
-
-/* USER CODE END EFP */
-
-/* Private defines -----------------------------------------------------------*/
-#ifndef NVIC_PRIORITYGROUP_0
-#define NVIC_PRIORITYGROUP_0 ((uint32_t)0x00000007) /*!< 0 bit for pre-emption priority,
- 4 bits for subpriority */
-#define NVIC_PRIORITYGROUP_1 ((uint32_t)0x00000006) /*!< 1 bit for pre-emption priority,
- 3 bits for subpriority */
-#define NVIC_PRIORITYGROUP_2 ((uint32_t)0x00000005) /*!< 2 bits for pre-emption priority,
- 2 bits for subpriority */
-#define NVIC_PRIORITYGROUP_3 ((uint32_t)0x00000004) /*!< 3 bits for pre-emption priority,
- 1 bit for subpriority */
-#define NVIC_PRIORITYGROUP_4 ((uint32_t)0x00000003) /*!< 4 bits for pre-emption priority,
- 0 bit for subpriority */
-#endif
-/* USER CODE BEGIN Private defines */
-
-/* USER CODE END Private defines */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __MAIN_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Inc/stm32_assert.h b/assets/templates/blackpill/Inc/stm32_assert.h
deleted file mode 100644
index 3cbee3c..0000000
--- a/assets/templates/blackpill/Inc/stm32_assert.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32_assert.h
- * @brief STM32 assert file.
- ******************************************************************************
- ** This notice applies to any and all portions of this file
- * that are not between comment pairs USER CODE BEGIN and
- * USER CODE END. Other portions of this file, whether
- * inserted by the user or by software development tools
- * are owned by their respective copyright owners.
- *
- * COPYRIGHT(c) 2019 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32_ASSERT_H
-#define __STM32_ASSERT_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Exported types ------------------------------------------------------------*/
-/* Exported constants --------------------------------------------------------*/
-/* Includes ------------------------------------------------------------------*/
-/* 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)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
-/* Exported functions ------------------------------------------------------- */
- void assert_failed(uint8_t* file, uint32_t line);
-#else
- #define assert_param(expr) ((void)0U)
-#endif /* USE_FULL_ASSERT */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32_ASSERT_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Inc/stm32f1xx_it.h b/assets/templates/blackpill/Inc/stm32f1xx_it.h
deleted file mode 100644
index d773f36..0000000
--- a/assets/templates/blackpill/Inc/stm32f1xx_it.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* USER CODE BEGIN Header */
-/**
- ******************************************************************************
- * @file stm32f1xx_it.h
- * @brief This file contains the headers of the interrupt handlers.
- ******************************************************************************
- *
- * COPYRIGHT(c) 2019 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-/* USER CODE END Header */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F1xx_IT_H
-#define __STM32F1xx_IT_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Private includes ----------------------------------------------------------*/
-/* USER CODE BEGIN Includes */
-
-/* USER CODE END Includes */
-
-#include "stm32f1xx.h"
-#include "stm32f1xx_ll_system.h"
-#include "stm32f1xx_ll_gpio.h"
-#include "stm32f1xx_ll_exti.h"
-/* Exported types ------------------------------------------------------------*/
-/* USER CODE BEGIN ET */
-
-/* USER CODE END ET */
-
-/* Exported constants --------------------------------------------------------*/
-/* USER CODE BEGIN EC */
-
-/* USER CODE END EC */
-
-/* Exported macro ------------------------------------------------------------*/
-/* USER CODE BEGIN EM */
-
-/* USER CODE END EM */
-
-/* Exported functions prototypes ---------------------------------------------*/
-void NMI_Handler(void);
-void HardFault_Handler(void);
-void MemManage_Handler(void);
-void BusFault_Handler(void);
-void UsageFault_Handler(void);
-void SVC_Handler(void);
-void DebugMon_Handler(void);
-void PendSV_Handler(void);
-void SysTick_Handler(void);
-/* USER CODE BEGIN EFP */
-
-/* USER CODE END EFP */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F1xx_IT_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Makefile b/assets/templates/blackpill/Makefile
deleted file mode 100644
index 6c3a406..0000000
--- a/assets/templates/blackpill/Makefile
+++ /dev/null
@@ -1,188 +0,0 @@
-##########################################################################################################################
-# File automatically-generated by tool: [projectgenerator] version: [3.0.0] date: [Wed Jul 03 10:04:07 CEST 2019]
-##########################################################################################################################
-
-# ------------------------------------------------
-# Generic Makefile (based on gcc)
-#
-# ChangeLog :
-# 2017-02-10 - Several enhancements + project update mode
-# 2015-07-22 - first version
-# ------------------------------------------------
-
-######################################
-# target
-######################################
-TARGET = blackpill
-
-
-######################################
-# building variables
-######################################
-# debug build?
-DEBUG = 1
-# optimization
-OPT = -Og
-
-
-#######################################
-# paths
-#######################################
-# Build path
-BUILD_DIR = build
-
-######################################
-# source
-######################################
-# C sources
-C_SOURCES = \
-Src/main.c \
-Src/stm32f1xx_it.c \
-Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rcc.c \
-Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_utils.c \
-Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_exti.c \
-Src/system_stm32f1xx.c \
-Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_gpio.c \
-Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_pwr.c \
-Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usart.c \
-Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_dma.c
-
-# ASM sources
-ASM_SOURCES = \
-startup_stm32f103xb.s
-
-
-#######################################
-# binaries
-#######################################
-PREFIX = arm-none-eabi-
-# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx)
-# either it can be added to the PATH environment variable.
-ifdef GCC_PATH
-CC = $(GCC_PATH)/$(PREFIX)gcc
-AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp
-CP = $(GCC_PATH)/$(PREFIX)objcopy
-SZ = $(GCC_PATH)/$(PREFIX)size
-else
-CC = $(PREFIX)gcc
-AS = $(PREFIX)gcc -x assembler-with-cpp
-CP = $(PREFIX)objcopy
-SZ = $(PREFIX)size
-endif
-HEX = $(CP) -O ihex
-BIN = $(CP) -O binary -S
-
-#######################################
-# CFLAGS
-#######################################
-# cpu
-CPU = -mcpu=cortex-m3
-
-# fpu
-# NONE for Cortex-M0/M0+/M3
-
-# float-abi
-
-
-# mcu
-MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)
-
-# macros for gcc
-# AS defines
-AS_DEFS =
-
-# C defines
-C_DEFS = \
--DUSE_FULL_LL_DRIVER \
--DSTM32F103xB \
--DHSE_VALUE=8000000 \
--DHSE_STARTUP_TIMEOUT=100 \
--DLSE_STARTUP_TIMEOUT=5000 \
--DLSE_VALUE=32768 \
--DHSI_VALUE=8000000 \
--DLSI_VALUE=40000 \
--DVDD_VALUE=3300 \
--DPREFETCH_ENABLE=1
-
-
-# AS includes
-AS_INCLUDES =
-
-# C includes
-C_INCLUDES = \
--IInc \
--IDrivers/STM32F1xx_HAL_Driver/Inc \
--IDrivers/CMSIS/Device/ST/STM32F1xx/Include \
--IDrivers/CMSIS/Include
-
-
-# compile gcc flags
-ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
-
-CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
-
-ifeq ($(DEBUG), 1)
-CFLAGS += -g -gdwarf-2
-endif
-
-
-# Generate dependency information
-CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
-
-
-#######################################
-# LDFLAGS
-#######################################
-# link script
-LDSCRIPT = STM32F103C8Tx_FLASH.ld
-
-# libraries
-LIBS = -lc -lm -lnosys
-LIBDIR =
-LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections
-
-# default action: build all
-all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin
-
-
-#######################################
-# build the application
-#######################################
-# list of objects
-OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
-vpath %.c $(sort $(dir $(C_SOURCES)))
-# list of ASM program objects
-OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
-vpath %.s $(sort $(dir $(ASM_SOURCES)))
-
-$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
- $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
-
-$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
- $(AS) -c $(CFLAGS) $< -o $@
-
-$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
- $(CC) $(OBJECTS) $(LDFLAGS) -o $@
- $(SZ) $@
-
-$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
- $(HEX) $< $@
-
-$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
- $(BIN) $< $@
-
-$(BUILD_DIR):
- mkdir $@
-
-#######################################
-# clean up
-#######################################
-clean:
- -rm -fR $(BUILD_DIR)
-
-#######################################
-# dependencies
-#######################################
--include $(wildcard $(BUILD_DIR)/*.d)
-
-# *** EOF ***
diff --git a/assets/templates/blackpill/STM32F103C8Tx_FLASH.ld b/assets/templates/blackpill/STM32F103C8Tx_FLASH.ld
deleted file mode 100644
index 38d06c5..0000000
--- a/assets/templates/blackpill/STM32F103C8Tx_FLASH.ld
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
-*****************************************************************************
-**
-
-** File : LinkerScript.ld
-**
-** Abstract : Linker script for STM32F103C8Tx Device with
-** 64KByte FLASH, 20KByte RAM
-**
-** Set heap size, stack size and stack location according
-** to application requirements.
-**
-** Set memory bank area and size if external memory is used.
-**
-** Target : STMicroelectronics STM32
-**
-**
-** Distribution: The file is distributed as is, without any warranty
-** of any kind.
-**
-** (c)Copyright Ac6.
-** You may use this file as-is or modify it according to the needs of your
-** project. Distribution of this file (unmodified or modified) is not
-** permitted. Ac6 permit registered System Workbench for MCU users the
-** rights to distribute the assembled, compiled & linked contents of this
-** file as part of an application binary file, provided that it is built
-** using the System Workbench for MCU toolchain.
-**
-*****************************************************************************
-*/
-
-/* Entry Point */
-ENTRY(Reset_Handler)
-
-/* Highest address of the user mode stack */
-_estack = 0x20005000; /* end of RAM */
-/* Generate a link error if heap and stack don't fit into RAM */
-_Min_Heap_Size = 0x200; /* required amount of heap */
-_Min_Stack_Size = 0x400; /* required amount of stack */
-
-/* Specify the memory areas */
-MEMORY
-{
-RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
-FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K
-}
-
-/* Define output sections */
-SECTIONS
-{
- /* The startup code goes first into FLASH */
- .isr_vector :
- {
- . = ALIGN(4);
- KEEP(*(.isr_vector)) /* Startup code */
- . = ALIGN(4);
- } >FLASH
-
- /* The program code and other data goes into FLASH */
- .text :
- {
- . = ALIGN(4);
- *(.text) /* .text sections (code) */
- *(.text*) /* .text* sections (code) */
- *(.glue_7) /* glue arm to thumb code */
- *(.glue_7t) /* glue thumb to arm code */
- *(.eh_frame)
-
- KEEP (*(.init))
- KEEP (*(.fini))
-
- . = ALIGN(4);
- _etext = .; /* define a global symbols at end of code */
- } >FLASH
-
- /* Constant data goes into FLASH */
- .rodata :
- {
- . = ALIGN(4);
- *(.rodata) /* .rodata sections (constants, strings, etc.) */
- *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
- . = ALIGN(4);
- } >FLASH
-
- .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
- .ARM : {
- __exidx_start = .;
- *(.ARM.exidx*)
- __exidx_end = .;
- } >FLASH
-
- .preinit_array :
- {
- PROVIDE_HIDDEN (__preinit_array_start = .);
- KEEP (*(.preinit_array*))
- PROVIDE_HIDDEN (__preinit_array_end = .);
- } >FLASH
- .init_array :
- {
- PROVIDE_HIDDEN (__init_array_start = .);
- KEEP (*(SORT(.init_array.*)))
- KEEP (*(.init_array*))
- PROVIDE_HIDDEN (__init_array_end = .);
- } >FLASH
- .fini_array :
- {
- PROVIDE_HIDDEN (__fini_array_start = .);
- KEEP (*(SORT(.fini_array.*)))
- KEEP (*(.fini_array*))
- PROVIDE_HIDDEN (__fini_array_end = .);
- } >FLASH
-
- /* used by the startup to initialize data */
- _sidata = LOADADDR(.data);
-
- /* Initialized data sections goes into RAM, load LMA copy after code */
- .data :
- {
- . = ALIGN(4);
- _sdata = .; /* create a global symbol at data start */
- *(.data) /* .data sections */
- *(.data*) /* .data* sections */
-
- . = ALIGN(4);
- _edata = .; /* define a global symbol at data end */
- } >RAM AT> FLASH
-
-
- /* Uninitialized data section */
- . = ALIGN(4);
- .bss :
- {
- /* This is used by the startup in order to initialize the .bss secion */
- _sbss = .; /* define a global symbol at bss start */
- __bss_start__ = _sbss;
- *(.bss)
- *(.bss*)
- *(COMMON)
-
- . = ALIGN(4);
- _ebss = .; /* define a global symbol at bss end */
- __bss_end__ = _ebss;
- } >RAM
-
- /* User_heap_stack section, used to check that there is enough RAM left */
- ._user_heap_stack :
- {
- . = ALIGN(8);
- PROVIDE ( end = . );
- PROVIDE ( _end = . );
- . = . + _Min_Heap_Size;
- . = . + _Min_Stack_Size;
- . = ALIGN(8);
- } >RAM
-
-
-
- /* Remove information from the standard libraries */
- /DISCARD/ :
- {
- libc.a ( * )
- libm.a ( * )
- libgcc.a ( * )
- }
-
- .ARM.attributes 0 : { *(.ARM.attributes) }
-}
-
-
diff --git a/assets/templates/blackpill/Src/aes.c b/assets/templates/blackpill/Src/aes.c
deleted file mode 100644
index 560624c..0000000
--- a/assets/templates/blackpill/Src/aes.c
+++ /dev/null
@@ -1,2209 +0,0 @@
-/*
- * FIPS-197 compliant AES implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
-/*
- * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
- *
- * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
- * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
- */
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_AES_C)
-
-#include
-
-#include "aes.h"
-#include "platform.h"
-#include "platform_util.h"
-#if defined(MBEDTLS_PADLOCK_C)
-#include "mbedtls/padlock.h"
-#endif
-#if defined(MBEDTLS_AESNI_C)
-#include "mbedtls/aesni.h"
-#endif
-
-#if defined(MBEDTLS_SELF_TEST)
-#if defined(MBEDTLS_PLATFORM_C)
-#include "platform.h"
-#else
-#include
-#define mbedtls_printf printf
-#endif /* MBEDTLS_PLATFORM_C */
-#endif /* MBEDTLS_SELF_TEST */
-
-#if !defined(MBEDTLS_AES_ALT)
-
-/* Parameter validation macros based on platform_util.h */
-#define AES_VALIDATE_RET( cond ) \
- MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA )
-#define AES_VALIDATE( cond ) \
- MBEDTLS_INTERNAL_VALIDATE( cond )
-
-/*
- * 32-bit integer manipulation macros (little endian)
- */
-#ifndef GET_UINT32_LE
-#define GET_UINT32_LE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] ) \
- | ( (uint32_t) (b)[(i) + 1] << 8 ) \
- | ( (uint32_t) (b)[(i) + 2] << 16 ) \
- | ( (uint32_t) (b)[(i) + 3] << 24 ); \
-}
-#endif
-
-#ifndef PUT_UINT32_LE
-#define PUT_UINT32_LE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
- (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
- (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
- (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
-}
-#endif
-
-#if defined(MBEDTLS_PADLOCK_C) && \
- ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) )
-static int aes_padlock_ace = -1;
-#endif
-
-#if defined(MBEDTLS_AES_ROM_TABLES)
-/*
- * Forward S-box
- */
-static const unsigned char FSb[256] =
-{
- 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
- 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
- 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
- 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
- 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
- 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
- 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
- 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
- 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
- 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
- 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
- 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
- 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
- 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
- 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
- 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
- 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
- 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
- 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
- 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
- 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
- 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
- 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
- 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
- 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
- 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
- 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
- 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
- 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
- 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
- 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
- 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
-};
-
-/*
- * Forward tables
- */
-#define FT \
-\
- V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \
- V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \
- V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \
- V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \
- V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \
- V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \
- V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \
- V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \
- V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \
- V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \
- V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \
- V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \
- V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \
- V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \
- V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \
- V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \
- V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \
- V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \
- V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \
- V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \
- V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \
- V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \
- V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \
- V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \
- V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \
- V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \
- V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \
- V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \
- V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \
- V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \
- V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \
- V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \
- V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \
- V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \
- V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \
- V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \
- V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \
- V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \
- V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \
- V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \
- V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \
- V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \
- V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \
- V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \
- V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \
- V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \
- V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \
- V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \
- V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \
- V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \
- V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \
- V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \
- V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \
- V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \
- V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \
- V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \
- V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \
- V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \
- V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \
- V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \
- V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \
- V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \
- V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \
- V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
-
-#define V(a,b,c,d) 0x##a##b##c##d
-static const uint32_t FT0[256] = { FT };
-#undef V
-
-#if !defined(MBEDTLS_AES_FEWER_TABLES)
-
-#define V(a,b,c,d) 0x##b##c##d##a
-static const uint32_t FT1[256] = { FT };
-#undef V
-
-#define V(a,b,c,d) 0x##c##d##a##b
-static const uint32_t FT2[256] = { FT };
-#undef V
-
-#define V(a,b,c,d) 0x##d##a##b##c
-static const uint32_t FT3[256] = { FT };
-#undef V
-
-#endif /* !MBEDTLS_AES_FEWER_TABLES */
-
-#undef FT
-
-/*
- * Reverse S-box
- */
-static const unsigned char RSb[256] =
-{
- 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
- 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
- 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
- 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
- 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
- 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
- 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
- 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
- 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
- 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
- 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
- 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
- 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
- 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
- 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
- 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
- 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
- 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
- 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
- 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
- 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
- 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
- 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
- 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
- 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
- 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
- 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
- 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
- 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
- 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
- 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
- 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
-};
-
-/*
- * Reverse tables
- */
-#define RT \
-\
- V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \
- V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \
- V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \
- V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \
- V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \
- V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \
- V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \
- V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \
- V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \
- V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \
- V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \
- V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \
- V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \
- V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \
- V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \
- V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \
- V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \
- V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \
- V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \
- V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \
- V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \
- V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \
- V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \
- V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \
- V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \
- V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \
- V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \
- V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \
- V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \
- V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \
- V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \
- V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \
- V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \
- V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \
- V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \
- V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \
- V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \
- V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \
- V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \
- V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \
- V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \
- V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \
- V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \
- V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \
- V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \
- V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \
- V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \
- V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \
- V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \
- V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \
- V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \
- V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \
- V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \
- V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \
- V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \
- V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \
- V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \
- V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \
- V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \
- V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \
- V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \
- V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \
- V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \
- V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0)
-
-#define V(a,b,c,d) 0x##a##b##c##d
-static const uint32_t RT0[256] = { RT };
-#undef V
-
-#if !defined(MBEDTLS_AES_FEWER_TABLES)
-
-#define V(a,b,c,d) 0x##b##c##d##a
-static const uint32_t RT1[256] = { RT };
-#undef V
-
-#define V(a,b,c,d) 0x##c##d##a##b
-static const uint32_t RT2[256] = { RT };
-#undef V
-
-#define V(a,b,c,d) 0x##d##a##b##c
-static const uint32_t RT3[256] = { RT };
-#undef V
-
-#endif /* !MBEDTLS_AES_FEWER_TABLES */
-
-#undef RT
-
-/*
- * Round constants
- */
-static const uint32_t RCON[10] =
-{
- 0x00000001, 0x00000002, 0x00000004, 0x00000008,
- 0x00000010, 0x00000020, 0x00000040, 0x00000080,
- 0x0000001B, 0x00000036
-};
-
-#else /* MBEDTLS_AES_ROM_TABLES */
-
-/*
- * Forward S-box & tables
- */
-static unsigned char FSb[256];
-static uint32_t FT0[256];
-#if !defined(MBEDTLS_AES_FEWER_TABLES)
-static uint32_t FT1[256];
-static uint32_t FT2[256];
-static uint32_t FT3[256];
-#endif /* !MBEDTLS_AES_FEWER_TABLES */
-
-/*
- * Reverse S-box & tables
- */
-static unsigned char RSb[256];
-static uint32_t RT0[256];
-#if !defined(MBEDTLS_AES_FEWER_TABLES)
-static uint32_t RT1[256];
-static uint32_t RT2[256];
-static uint32_t RT3[256];
-#endif /* !MBEDTLS_AES_FEWER_TABLES */
-
-/*
- * Round constants
- */
-static uint32_t RCON[10];
-
-/*
- * Tables generation code
- */
-#define ROTL8(x) ( ( (x) << 8 ) & 0xFFFFFFFF ) | ( (x) >> 24 )
-#define XTIME(x) ( ( (x) << 1 ) ^ ( ( (x) & 0x80 ) ? 0x1B : 0x00 ) )
-#define MUL(x,y) ( ( (x) && (y) ) ? pow[(log[(x)]+log[(y)]) % 255] : 0 )
-
-static int aes_init_done = 0;
-
-static void aes_gen_tables( void )
-{
- int i, x, y, z;
- int pow[256];
- int log[256];
-
- /*
- * compute pow and log tables over GF(2^8)
- */
- for( i = 0, x = 1; i < 256; i++ )
- {
- pow[i] = x;
- log[x] = i;
- x = ( x ^ XTIME( x ) ) & 0xFF;
- }
-
- /*
- * calculate the round constants
- */
- for( i = 0, x = 1; i < 10; i++ )
- {
- RCON[i] = (uint32_t) x;
- x = XTIME( x ) & 0xFF;
- }
-
- /*
- * generate the forward and reverse S-boxes
- */
- FSb[0x00] = 0x63;
- RSb[0x63] = 0x00;
-
- for( i = 1; i < 256; i++ )
- {
- x = pow[255 - log[i]];
-
- y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
- x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
- x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
- x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
- x ^= y ^ 0x63;
-
- FSb[i] = (unsigned char) x;
- RSb[x] = (unsigned char) i;
- }
-
- /*
- * generate the forward and reverse tables
- */
- for( i = 0; i < 256; i++ )
- {
- x = FSb[i];
- y = XTIME( x ) & 0xFF;
- z = ( y ^ x ) & 0xFF;
-
- FT0[i] = ( (uint32_t) y ) ^
- ( (uint32_t) x << 8 ) ^
- ( (uint32_t) x << 16 ) ^
- ( (uint32_t) z << 24 );
-
-#if !defined(MBEDTLS_AES_FEWER_TABLES)
- FT1[i] = ROTL8( FT0[i] );
- FT2[i] = ROTL8( FT1[i] );
- FT3[i] = ROTL8( FT2[i] );
-#endif /* !MBEDTLS_AES_FEWER_TABLES */
-
- x = RSb[i];
-
- RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^
- ( (uint32_t) MUL( 0x09, x ) << 8 ) ^
- ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
- ( (uint32_t) MUL( 0x0B, x ) << 24 );
-
-#if !defined(MBEDTLS_AES_FEWER_TABLES)
- RT1[i] = ROTL8( RT0[i] );
- RT2[i] = ROTL8( RT1[i] );
- RT3[i] = ROTL8( RT2[i] );
-#endif /* !MBEDTLS_AES_FEWER_TABLES */
- }
-}
-
-#undef ROTL8
-
-#endif /* MBEDTLS_AES_ROM_TABLES */
-
-#if defined(MBEDTLS_AES_FEWER_TABLES)
-
-#define ROTL8(x) ( (uint32_t)( ( x ) << 8 ) + (uint32_t)( ( x ) >> 24 ) )
-#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) )
-#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >> 8 ) )
-
-#define AES_RT0(idx) RT0[idx]
-#define AES_RT1(idx) ROTL8( RT0[idx] )
-#define AES_RT2(idx) ROTL16( RT0[idx] )
-#define AES_RT3(idx) ROTL24( RT0[idx] )
-
-#define AES_FT0(idx) FT0[idx]
-#define AES_FT1(idx) ROTL8( FT0[idx] )
-#define AES_FT2(idx) ROTL16( FT0[idx] )
-#define AES_FT3(idx) ROTL24( FT0[idx] )
-
-#else /* MBEDTLS_AES_FEWER_TABLES */
-
-#define AES_RT0(idx) RT0[idx]
-#define AES_RT1(idx) RT1[idx]
-#define AES_RT2(idx) RT2[idx]
-#define AES_RT3(idx) RT3[idx]
-
-#define AES_FT0(idx) FT0[idx]
-#define AES_FT1(idx) FT1[idx]
-#define AES_FT2(idx) FT2[idx]
-#define AES_FT3(idx) FT3[idx]
-
-#endif /* MBEDTLS_AES_FEWER_TABLES */
-
-void mbedtls_aes_init( mbedtls_aes_context *ctx )
-{
- AES_VALIDATE( ctx != NULL );
-
- memset( ctx, 0, sizeof( mbedtls_aes_context ) );
-}
-
-void mbedtls_aes_free( mbedtls_aes_context *ctx )
-{
- if( ctx == NULL )
- return;
-
- mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) );
-}
-
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
-void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
-{
- AES_VALIDATE( ctx != NULL );
-
- mbedtls_aes_init( &ctx->crypt );
- mbedtls_aes_init( &ctx->tweak );
-}
-
-void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
-{
- if( ctx == NULL )
- return;
-
- mbedtls_aes_free( &ctx->crypt );
- mbedtls_aes_free( &ctx->tweak );
-}
-#endif /* MBEDTLS_CIPHER_MODE_XTS */
-
-/*
- * AES key schedule (encryption)
- */
-#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
-int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
- unsigned int keybits )
-{
- unsigned int i;
- uint32_t *RK;
-
- AES_VALIDATE_RET( ctx != NULL );
- AES_VALIDATE_RET( key != NULL );
-
- switch( keybits )
- {
- case 128: ctx->nr = 10; break;
- case 192: ctx->nr = 12; break;
- case 256: ctx->nr = 14; break;
- default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
- }
-
-#if !defined(MBEDTLS_AES_ROM_TABLES)
- if( aes_init_done == 0 )
- {
- aes_gen_tables();
- aes_init_done = 1;
- }
-#endif
-
-#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
- if( aes_padlock_ace == -1 )
- aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
-
- if( aes_padlock_ace )
- ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
- else
-#endif
- ctx->rk = RK = ctx->buf;
-
-#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
- if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
- return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) );
-#endif
-
- for( i = 0; i < ( keybits >> 5 ); i++ )
- {
- GET_UINT32_LE( RK[i], key, i << 2 );
- }
-
- switch( ctx->nr )
- {
- case 10:
-
- for( i = 0; i < 10; i++, RK += 4 )
- {
- RK[4] = RK[0] ^ RCON[i] ^
- ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 );
-
- RK[5] = RK[1] ^ RK[4];
- RK[6] = RK[2] ^ RK[5];
- RK[7] = RK[3] ^ RK[6];
- }
- break;
-
- case 12:
-
- for( i = 0; i < 8; i++, RK += 6 )
- {
- RK[6] = RK[0] ^ RCON[i] ^
- ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 );
-
- RK[7] = RK[1] ^ RK[6];
- RK[8] = RK[2] ^ RK[7];
- RK[9] = RK[3] ^ RK[8];
- RK[10] = RK[4] ^ RK[9];
- RK[11] = RK[5] ^ RK[10];
- }
- break;
-
- case 14:
-
- for( i = 0; i < 7; i++, RK += 8 )
- {
- RK[8] = RK[0] ^ RCON[i] ^
- ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 );
-
- RK[9] = RK[1] ^ RK[8];
- RK[10] = RK[2] ^ RK[9];
- RK[11] = RK[3] ^ RK[10];
-
- RK[12] = RK[4] ^
- ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
-
- RK[13] = RK[5] ^ RK[12];
- RK[14] = RK[6] ^ RK[13];
- RK[15] = RK[7] ^ RK[14];
- }
- break;
- }
-
- return( 0 );
-}
-#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
-
-/*
- * AES key schedule (decryption)
- */
-#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
-int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
- unsigned int keybits )
-{
- int i, j, ret;
- mbedtls_aes_context cty;
- uint32_t *RK;
- uint32_t *SK;
-
- AES_VALIDATE_RET( ctx != NULL );
- AES_VALIDATE_RET( key != NULL );
-
- mbedtls_aes_init( &cty );
-
-#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
- if( aes_padlock_ace == -1 )
- aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
-
- if( aes_padlock_ace )
- ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
- else
-#endif
- ctx->rk = RK = ctx->buf;
-
- /* Also checks keybits */
- if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 )
- goto exit;
-
- ctx->nr = cty.nr;
-
-#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
- if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
- {
- mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk,
- (const unsigned char *) cty.rk, ctx->nr );
- goto exit;
- }
-#endif
-
- SK = cty.rk + cty.nr * 4;
-
- *RK++ = *SK++;
- *RK++ = *SK++;
- *RK++ = *SK++;
- *RK++ = *SK++;
-
- for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
- {
- for( j = 0; j < 4; j++, SK++ )
- {
- *RK++ = AES_RT0( FSb[ ( *SK ) & 0xFF ] ) ^
- AES_RT1( FSb[ ( *SK >> 8 ) & 0xFF ] ) ^
- AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^
- AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] );
- }
- }
-
- *RK++ = *SK++;
- *RK++ = *SK++;
- *RK++ = *SK++;
- *RK++ = *SK++;
-
-exit:
- mbedtls_aes_free( &cty );
-
- return( ret );
-}
-
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
-static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
- unsigned int keybits,
- const unsigned char **key1,
- unsigned int *key1bits,
- const unsigned char **key2,
- unsigned int *key2bits )
-{
- const unsigned int half_keybits = keybits / 2;
- const unsigned int half_keybytes = half_keybits / 8;
-
- switch( keybits )
- {
- case 256: break;
- case 512: break;
- default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
- }
-
- *key1bits = half_keybits;
- *key2bits = half_keybits;
- *key1 = &key[0];
- *key2 = &key[half_keybytes];
-
- return 0;
-}
-
-int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
- const unsigned char *key,
- unsigned int keybits)
-{
- int ret;
- const unsigned char *key1, *key2;
- unsigned int key1bits, key2bits;
-
- AES_VALIDATE_RET( ctx != NULL );
- AES_VALIDATE_RET( key != NULL );
-
- ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
- &key2, &key2bits );
- if( ret != 0 )
- return( ret );
-
- /* Set the tweak key. Always set tweak key for the encryption mode. */
- ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
- if( ret != 0 )
- return( ret );
-
- /* Set crypt key for encryption. */
- return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits );
-}
-
-int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
- const unsigned char *key,
- unsigned int keybits)
-{
- int ret;
- const unsigned char *key1, *key2;
- unsigned int key1bits, key2bits;
-
- AES_VALIDATE_RET( ctx != NULL );
- AES_VALIDATE_RET( key != NULL );
-
- ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
- &key2, &key2bits );
- if( ret != 0 )
- return( ret );
-
- /* Set the tweak key. Always set tweak key for encryption. */
- ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
- if( ret != 0 )
- return( ret );
-
- /* Set crypt key for decryption. */
- return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits );
-}
-#endif /* MBEDTLS_CIPHER_MODE_XTS */
-
-#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
-
-#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
- do \
- { \
- (X0) = *RK++ ^ AES_FT0( ( (Y0) ) & 0xFF ) ^ \
- AES_FT1( ( (Y1) >> 8 ) & 0xFF ) ^ \
- AES_FT2( ( (Y2) >> 16 ) & 0xFF ) ^ \
- AES_FT3( ( (Y3) >> 24 ) & 0xFF ); \
- \
- (X1) = *RK++ ^ AES_FT0( ( (Y1) ) & 0xFF ) ^ \
- AES_FT1( ( (Y2) >> 8 ) & 0xFF ) ^ \
- AES_FT2( ( (Y3) >> 16 ) & 0xFF ) ^ \
- AES_FT3( ( (Y0) >> 24 ) & 0xFF ); \
- \
- (X2) = *RK++ ^ AES_FT0( ( (Y2) ) & 0xFF ) ^ \
- AES_FT1( ( (Y3) >> 8 ) & 0xFF ) ^ \
- AES_FT2( ( (Y0) >> 16 ) & 0xFF ) ^ \
- AES_FT3( ( (Y1) >> 24 ) & 0xFF ); \
- \
- (X3) = *RK++ ^ AES_FT0( ( (Y3) ) & 0xFF ) ^ \
- AES_FT1( ( (Y0) >> 8 ) & 0xFF ) ^ \
- AES_FT2( ( (Y1) >> 16 ) & 0xFF ) ^ \
- AES_FT3( ( (Y2) >> 24 ) & 0xFF ); \
- } while( 0 )
-
-#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
- do \
- { \
- (X0) = *RK++ ^ AES_RT0( ( (Y0) ) & 0xFF ) ^ \
- AES_RT1( ( (Y3) >> 8 ) & 0xFF ) ^ \
- AES_RT2( ( (Y2) >> 16 ) & 0xFF ) ^ \
- AES_RT3( ( (Y1) >> 24 ) & 0xFF ); \
- \
- (X1) = *RK++ ^ AES_RT0( ( (Y1) ) & 0xFF ) ^ \
- AES_RT1( ( (Y0) >> 8 ) & 0xFF ) ^ \
- AES_RT2( ( (Y3) >> 16 ) & 0xFF ) ^ \
- AES_RT3( ( (Y2) >> 24 ) & 0xFF ); \
- \
- (X2) = *RK++ ^ AES_RT0( ( (Y2) ) & 0xFF ) ^ \
- AES_RT1( ( (Y1) >> 8 ) & 0xFF ) ^ \
- AES_RT2( ( (Y0) >> 16 ) & 0xFF ) ^ \
- AES_RT3( ( (Y3) >> 24 ) & 0xFF ); \
- \
- (X3) = *RK++ ^ AES_RT0( ( (Y3) ) & 0xFF ) ^ \
- AES_RT1( ( (Y2) >> 8 ) & 0xFF ) ^ \
- AES_RT2( ( (Y1) >> 16 ) & 0xFF ) ^ \
- AES_RT3( ( (Y0) >> 24 ) & 0xFF ); \
- } while( 0 )
-
-/*
- * AES-ECB block encryption
- */
-#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
-int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
- const unsigned char input[16],
- unsigned char output[16] )
-{
- int i;
- uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
-
- RK = ctx->rk;
-
- GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++;
- GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++;
- GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++;
- GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
-
- for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
- {
- AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
- AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
- }
-
- AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
-
- X0 = *RK++ ^ \
- ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
-
- X1 = *RK++ ^ \
- ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
-
- X2 = *RK++ ^ \
- ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
-
- X3 = *RK++ ^ \
- ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
-
- PUT_UINT32_LE( X0, output, 0 );
- PUT_UINT32_LE( X1, output, 4 );
- PUT_UINT32_LE( X2, output, 8 );
- PUT_UINT32_LE( X3, output, 12 );
-
- return( 0 );
-}
-#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
-
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
- const unsigned char input[16],
- unsigned char output[16] )
-{
- mbedtls_internal_aes_encrypt( ctx, input, output );
-}
-#endif /* !MBEDTLS_DEPRECATED_REMOVED */
-
-/*
- * AES-ECB block decryption
- */
-#if !defined(MBEDTLS_AES_DECRYPT_ALT)
-int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
- const unsigned char input[16],
- unsigned char output[16] )
-{
- int i;
- uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
-
- RK = ctx->rk;
-
- GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++;
- GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++;
- GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++;
- GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
-
- for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
- {
- AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
- AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
- }
-
- AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
-
- X0 = *RK++ ^ \
- ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^
- ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
-
- X1 = *RK++ ^ \
- ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^
- ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
-
- X2 = *RK++ ^ \
- ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^
- ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
-
- X3 = *RK++ ^ \
- ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^
- ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
-
- PUT_UINT32_LE( X0, output, 0 );
- PUT_UINT32_LE( X1, output, 4 );
- PUT_UINT32_LE( X2, output, 8 );
- PUT_UINT32_LE( X3, output, 12 );
-
- return( 0 );
-}
-#endif /* !MBEDTLS_AES_DECRYPT_ALT */
-
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
- const unsigned char input[16],
- unsigned char output[16] )
-{
- mbedtls_internal_aes_decrypt( ctx, input, output );
-}
-#endif /* !MBEDTLS_DEPRECATED_REMOVED */
-
-/*
- * AES-ECB block encryption/decryption
- */
-int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
- int mode,
- const unsigned char input[16],
- unsigned char output[16] )
-{
- AES_VALIDATE_RET( ctx != NULL );
- AES_VALIDATE_RET( input != NULL );
- AES_VALIDATE_RET( output != NULL );
- AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
- mode == MBEDTLS_AES_DECRYPT );
-
-#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
- if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
- return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) );
-#endif
-
-#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
- if( aes_padlock_ace )
- {
- if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 )
- return( 0 );
-
- // If padlock data misaligned, we just fall back to
- // unaccelerated mode
- //
- }
-#endif
-
- if( mode == MBEDTLS_AES_ENCRYPT )
- return( mbedtls_internal_aes_encrypt( ctx, input, output ) );
- else
- return( mbedtls_internal_aes_decrypt( ctx, input, output ) );
-}
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-/*
- * AES-CBC buffer encryption/decryption
- */
-int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
- int mode,
- size_t length,
- unsigned char iv[16],
- const unsigned char *input,
- unsigned char *output )
-{
- int i;
- unsigned char temp[16];
-
- AES_VALIDATE_RET( ctx != NULL );
- AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
- mode == MBEDTLS_AES_DECRYPT );
- AES_VALIDATE_RET( iv != NULL );
- AES_VALIDATE_RET( input != NULL );
- AES_VALIDATE_RET( output != NULL );
-
- if( length % 16 )
- return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
-
-#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
- if( aes_padlock_ace )
- {
- if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
- return( 0 );
-
- // If padlock data misaligned, we just fall back to
- // unaccelerated mode
- //
- }
-#endif
-
- if( mode == MBEDTLS_AES_DECRYPT )
- {
- while( length > 0 )
- {
- memcpy( temp, input, 16 );
- mbedtls_aes_crypt_ecb( ctx, mode, input, output );
-
- for( i = 0; i < 16; i++ )
- output[i] = (unsigned char)( output[i] ^ iv[i] );
-
- memcpy( iv, temp, 16 );
-
- input += 16;
- output += 16;
- length -= 16;
- }
- }
- else
- {
- while( length > 0 )
- {
- for( i = 0; i < 16; i++ )
- output[i] = (unsigned char)( input[i] ^ iv[i] );
-
- mbedtls_aes_crypt_ecb( ctx, mode, output, output );
- memcpy( iv, output, 16 );
-
- input += 16;
- output += 16;
- length -= 16;
- }
- }
-
- return( 0 );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
-
-/* Endianess with 64 bits values */
-#ifndef GET_UINT64_LE
-#define GET_UINT64_LE(n,b,i) \
-{ \
- (n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \
- | ( (uint64_t) (b)[(i) + 6] << 48 ) \
- | ( (uint64_t) (b)[(i) + 5] << 40 ) \
- | ( (uint64_t) (b)[(i) + 4] << 32 ) \
- | ( (uint64_t) (b)[(i) + 3] << 24 ) \
- | ( (uint64_t) (b)[(i) + 2] << 16 ) \
- | ( (uint64_t) (b)[(i) + 1] << 8 ) \
- | ( (uint64_t) (b)[(i) ] ); \
-}
-#endif
-
-#ifndef PUT_UINT64_LE
-#define PUT_UINT64_LE(n,b,i) \
-{ \
- (b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \
- (b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \
- (b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \
- (b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) ] = (unsigned char) ( (n) ); \
-}
-#endif
-
-typedef unsigned char mbedtls_be128[16];
-
-/*
- * GF(2^128) multiplication function
- *
- * This function multiplies a field element by x in the polynomial field
- * representation. It uses 64-bit word operations to gain speed but compensates
- * for machine endianess and hence works correctly on both big and little
- * endian machines.
- */
-static void mbedtls_gf128mul_x_ble( unsigned char r[16],
- const unsigned char x[16] )
-{
- uint64_t a, b, ra, rb;
-
- GET_UINT64_LE( a, x, 0 );
- GET_UINT64_LE( b, x, 8 );
-
- ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
- rb = ( a >> 63 ) | ( b << 1 );
-
- PUT_UINT64_LE( ra, r, 0 );
- PUT_UINT64_LE( rb, r, 8 );
-}
-
-/*
- * AES-XTS buffer encryption/decryption
- */
-int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
- int mode,
- size_t length,
- const unsigned char data_unit[16],
- const unsigned char *input,
- unsigned char *output )
-{
- int ret;
- size_t blocks = length / 16;
- size_t leftover = length % 16;
- unsigned char tweak[16];
- unsigned char prev_tweak[16];
- unsigned char tmp[16];
-
- AES_VALIDATE_RET( ctx != NULL );
- AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
- mode == MBEDTLS_AES_DECRYPT );
- AES_VALIDATE_RET( data_unit != NULL );
- AES_VALIDATE_RET( input != NULL );
- AES_VALIDATE_RET( output != NULL );
-
- /* Data units must be at least 16 bytes long. */
- if( length < 16 )
- return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
-
- /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
- if( length > ( 1 << 20 ) * 16 )
- return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
-
- /* Compute the tweak. */
- ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
- data_unit, tweak );
- if( ret != 0 )
- return( ret );
-
- while( blocks-- )
- {
- size_t i;
-
- if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
- {
- /* We are on the last block in a decrypt operation that has
- * leftover bytes, so we need to use the next tweak for this block,
- * and this tweak for the lefover bytes. Save the current tweak for
- * the leftovers and then update the current tweak for use on this,
- * the last full block. */
- memcpy( prev_tweak, tweak, sizeof( tweak ) );
- mbedtls_gf128mul_x_ble( tweak, tweak );
- }
-
- for( i = 0; i < 16; i++ )
- tmp[i] = input[i] ^ tweak[i];
-
- ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
- if( ret != 0 )
- return( ret );
-
- for( i = 0; i < 16; i++ )
- output[i] = tmp[i] ^ tweak[i];
-
- /* Update the tweak for the next block. */
- mbedtls_gf128mul_x_ble( tweak, tweak );
-
- output += 16;
- input += 16;
- }
-
- if( leftover )
- {
- /* If we are on the leftover bytes in a decrypt operation, we need to
- * use the previous tweak for these bytes (as saved in prev_tweak). */
- unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
-
- /* We are now on the final part of the data unit, which doesn't divide
- * evenly by 16. It's time for ciphertext stealing. */
- size_t i;
- unsigned char *prev_output = output - 16;
-
- /* Copy ciphertext bytes from the previous block to our output for each
- * byte of cyphertext we won't steal. At the same time, copy the
- * remainder of the input for this final round (since the loop bounds
- * are the same). */
- for( i = 0; i < leftover; i++ )
- {
- output[i] = prev_output[i];
- tmp[i] = input[i] ^ t[i];
- }
-
- /* Copy ciphertext bytes from the previous block for input in this
- * round. */
- for( ; i < 16; i++ )
- tmp[i] = prev_output[i] ^ t[i];
-
- ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
- if( ret != 0 )
- return ret;
-
- /* Write the result back to the previous block, overriding the previous
- * output we copied. */
- for( i = 0; i < 16; i++ )
- prev_output[i] = tmp[i] ^ t[i];
- }
-
- return( 0 );
-}
-#endif /* MBEDTLS_CIPHER_MODE_XTS */
-
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
-/*
- * AES-CFB128 buffer encryption/decryption
- */
-int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
- int mode,
- size_t length,
- size_t *iv_off,
- unsigned char iv[16],
- const unsigned char *input,
- unsigned char *output )
-{
- int c;
- size_t n;
-
- AES_VALIDATE_RET( ctx != NULL );
- AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
- mode == MBEDTLS_AES_DECRYPT );
- AES_VALIDATE_RET( iv_off != NULL );
- AES_VALIDATE_RET( iv != NULL );
- AES_VALIDATE_RET( input != NULL );
- AES_VALIDATE_RET( output != NULL );
-
- n = *iv_off;
-
- if( n > 15 )
- return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
-
- if( mode == MBEDTLS_AES_DECRYPT )
- {
- while( length-- )
- {
- if( n == 0 )
- mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
-
- c = *input++;
- *output++ = (unsigned char)( c ^ iv[n] );
- iv[n] = (unsigned char) c;
-
- n = ( n + 1 ) & 0x0F;
- }
- }
- else
- {
- while( length-- )
- {
- if( n == 0 )
- mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
-
- iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
-
- n = ( n + 1 ) & 0x0F;
- }
- }
-
- *iv_off = n;
-
- return( 0 );
-}
-
-/*
- * AES-CFB8 buffer encryption/decryption
- */
-int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
- int mode,
- size_t length,
- unsigned char iv[16],
- const unsigned char *input,
- unsigned char *output )
-{
- unsigned char c;
- unsigned char ov[17];
-
- AES_VALIDATE_RET( ctx != NULL );
- AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
- mode == MBEDTLS_AES_DECRYPT );
- AES_VALIDATE_RET( iv != NULL );
- AES_VALIDATE_RET( input != NULL );
- AES_VALIDATE_RET( output != NULL );
- while( length-- )
- {
- memcpy( ov, iv, 16 );
- mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
-
- if( mode == MBEDTLS_AES_DECRYPT )
- ov[16] = *input;
-
- c = *output++ = (unsigned char)( iv[0] ^ *input++ );
-
- if( mode == MBEDTLS_AES_ENCRYPT )
- ov[16] = c;
-
- memcpy( iv, ov + 1, 16 );
- }
-
- return( 0 );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
-/*
- * AES-OFB (Output Feedback Mode) buffer encryption/decryption
- */
-int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
- size_t length,
- size_t *iv_off,
- unsigned char iv[16],
- const unsigned char *input,
- unsigned char *output )
-{
- int ret = 0;
- size_t n;
-
- AES_VALIDATE_RET( ctx != NULL );
- AES_VALIDATE_RET( iv_off != NULL );
- AES_VALIDATE_RET( iv != NULL );
- AES_VALIDATE_RET( input != NULL );
- AES_VALIDATE_RET( output != NULL );
-
- n = *iv_off;
-
- if( n > 15 )
- return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
-
- while( length-- )
- {
- if( n == 0 )
- {
- ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
- if( ret != 0 )
- goto exit;
- }
- *output++ = *input++ ^ iv[n];
-
- n = ( n + 1 ) & 0x0F;
- }
-
- *iv_off = n;
-
-exit:
- return( ret );
-}
-#endif /* MBEDTLS_CIPHER_MODE_OFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
-/*
- * AES-CTR buffer encryption/decryption
- */
-int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
- size_t length,
- size_t *nc_off,
- unsigned char nonce_counter[16],
- unsigned char stream_block[16],
- const unsigned char *input,
- unsigned char *output )
-{
- int c, i;
- size_t n;
-
- AES_VALIDATE_RET( ctx != NULL );
- AES_VALIDATE_RET( nc_off != NULL );
- AES_VALIDATE_RET( nonce_counter != NULL );
- AES_VALIDATE_RET( stream_block != NULL );
- AES_VALIDATE_RET( input != NULL );
- AES_VALIDATE_RET( output != NULL );
-
- n = *nc_off;
-
- if ( n > 0x0F )
- return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
-
- while( length-- )
- {
- if( n == 0 ) {
- mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
-
- for( i = 16; i > 0; i-- )
- if( ++nonce_counter[i - 1] != 0 )
- break;
- }
- c = *input++;
- *output++ = (unsigned char)( c ^ stream_block[n] );
-
- n = ( n + 1 ) & 0x0F;
- }
-
- *nc_off = n;
-
- return( 0 );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CTR */
-
-#endif /* !MBEDTLS_AES_ALT */
-
-#if defined(MBEDTLS_SELF_TEST)
-/*
- * AES test vectors from:
- *
- * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
- */
-static const unsigned char aes_test_ecb_dec[3][16] =
-{
- { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
- 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
- { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
- 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
- { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
- 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
-};
-
-static const unsigned char aes_test_ecb_enc[3][16] =
-{
- { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
- 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
- { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
- 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
- { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
- 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
-};
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-static const unsigned char aes_test_cbc_dec[3][16] =
-{
- { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
- 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
- { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
- 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
- { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
- 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
-};
-
-static const unsigned char aes_test_cbc_enc[3][16] =
-{
- { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
- 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
- { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
- 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
- { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
- 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
-};
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
-/*
- * AES-CFB128 test vectors from:
- *
- * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
- */
-static const unsigned char aes_test_cfb128_key[3][32] =
-{
- { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
- 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
- { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
- 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
- 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
- { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
- 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
- 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
- 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
-};
-
-static const unsigned char aes_test_cfb128_iv[16] =
-{
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
-};
-
-static const unsigned char aes_test_cfb128_pt[64] =
-{
- 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
- 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
- 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
- 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
- 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
- 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
- 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
- 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
-};
-
-static const unsigned char aes_test_cfb128_ct[3][64] =
-{
- { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
- 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
- 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
- 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
- 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
- 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
- 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
- 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
- { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
- 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
- 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
- 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
- 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
- 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
- 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
- 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
- { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
- 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
- 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
- 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
- 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
- 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
- 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
- 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
-};
-#endif /* MBEDTLS_CIPHER_MODE_CFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
-/*
- * AES-OFB test vectors from:
- *
- * https://csrc.nist.gov/publications/detail/sp/800-38a/final
- */
-static const unsigned char aes_test_ofb_key[3][32] =
-{
- { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
- 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
- { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
- 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
- 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
- { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
- 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
- 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
- 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
-};
-
-static const unsigned char aes_test_ofb_iv[16] =
-{
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
-};
-
-static const unsigned char aes_test_ofb_pt[64] =
-{
- 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
- 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
- 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
- 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
- 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
- 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
- 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
- 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
-};
-
-static const unsigned char aes_test_ofb_ct[3][64] =
-{
- { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
- 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
- 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
- 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
- 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
- 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
- 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
- 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
- { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
- 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
- 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
- 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
- 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
- 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
- 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
- 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
- { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
- 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
- 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
- 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
- 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
- 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
- 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
- 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
-};
-#endif /* MBEDTLS_CIPHER_MODE_OFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
-/*
- * AES-CTR test vectors from:
- *
- * http://www.faqs.org/rfcs/rfc3686.html
- */
-
-static const unsigned char aes_test_ctr_key[3][16] =
-{
- { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
- 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
- { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
- 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
- { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
- 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
-};
-
-static const unsigned char aes_test_ctr_nonce_counter[3][16] =
-{
- { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
- { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
- 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
- { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
- 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
-};
-
-static const unsigned char aes_test_ctr_pt[3][48] =
-{
- { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
- 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
-
- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
-
- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
- 0x20, 0x21, 0x22, 0x23 }
-};
-
-static const unsigned char aes_test_ctr_ct[3][48] =
-{
- { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
- 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
- { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
- 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
- 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
- 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
- { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
- 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
- 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
- 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
- 0x25, 0xB2, 0x07, 0x2F }
-};
-
-static const int aes_test_ctr_len[3] =
- { 16, 32, 36 };
-#endif /* MBEDTLS_CIPHER_MODE_CTR */
-
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
-/*
- * AES-XTS test vectors from:
- *
- * IEEE P1619/D16 Annex B
- * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
- * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
- */
-static const unsigned char aes_test_xts_key[][32] =
-{
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
- { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
- 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
-};
-
-static const unsigned char aes_test_xts_pt32[][32] =
-{
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
- 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
- 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
- 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
- { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
- 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
- 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
- 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
-};
-
-static const unsigned char aes_test_xts_ct32[][32] =
-{
- { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
- 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
- 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
- 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
- { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
- 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
- 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
- 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
- { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
- 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
- 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
- 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
-};
-
-static const unsigned char aes_test_xts_data_unit[][16] =
-{
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
-};
-
-#endif /* MBEDTLS_CIPHER_MODE_XTS */
-
-/*
- * Checkup routine
- */
-int mbedtls_aes_self_test( int verbose )
-{
- int ret = 0, i, j, u, mode;
- unsigned int keybits;
- unsigned char key[32];
- unsigned char buf[64];
- const unsigned char *aes_tests;
-#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
- unsigned char iv[16];
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- unsigned char prv[16];
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
- defined(MBEDTLS_CIPHER_MODE_OFB)
- size_t offset;
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
- int len;
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- unsigned char nonce_counter[16];
- unsigned char stream_block[16];
-#endif
- mbedtls_aes_context ctx;
-
- memset( key, 0, 32 );
- mbedtls_aes_init( &ctx );
-
- /*
- * ECB mode
- */
- for( i = 0; i < 6; i++ )
- {
- u = i >> 1;
- keybits = 128 + u * 64;
- mode = i & 1;
-
- if( verbose != 0 )
- mbedtls_printf( " AES-ECB-%3d (%s): ", keybits,
- ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
-
- memset( buf, 0, 16 );
-
- if( mode == MBEDTLS_AES_DECRYPT )
- {
- ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
- aes_tests = aes_test_ecb_dec[u];
- }
- else
- {
- ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
- aes_tests = aes_test_ecb_enc[u];
- }
-
- /*
- * AES-192 is an optional feature that may be unavailable when
- * there is an alternative underlying implementation i.e. when
- * MBEDTLS_AES_ALT is defined.
- */
- if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
- {
- mbedtls_printf( "skipped\n" );
- continue;
- }
- else if( ret != 0 )
- {
- goto exit;
- }
-
- for( j = 0; j < 10000; j++ )
- {
- ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf );
- if( ret != 0 )
- goto exit;
- }
-
- if( memcmp( buf, aes_tests, 16 ) != 0 )
- {
- ret = 1;
- goto exit;
- }
-
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
-
- if( verbose != 0 )
- mbedtls_printf( "\n" );
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- /*
- * CBC mode
- */
- for( i = 0; i < 6; i++ )
- {
- u = i >> 1;
- keybits = 128 + u * 64;
- mode = i & 1;
-
- if( verbose != 0 )
- mbedtls_printf( " AES-CBC-%3d (%s): ", keybits,
- ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
-
- memset( iv , 0, 16 );
- memset( prv, 0, 16 );
- memset( buf, 0, 16 );
-
- if( mode == MBEDTLS_AES_DECRYPT )
- {
- ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
- aes_tests = aes_test_cbc_dec[u];
- }
- else
- {
- ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
- aes_tests = aes_test_cbc_enc[u];
- }
-
- /*
- * AES-192 is an optional feature that may be unavailable when
- * there is an alternative underlying implementation i.e. when
- * MBEDTLS_AES_ALT is defined.
- */
- if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
- {
- mbedtls_printf( "skipped\n" );
- continue;
- }
- else if( ret != 0 )
- {
- goto exit;
- }
-
- for( j = 0; j < 10000; j++ )
- {
- if( mode == MBEDTLS_AES_ENCRYPT )
- {
- unsigned char tmp[16];
-
- memcpy( tmp, prv, 16 );
- memcpy( prv, buf, 16 );
- memcpy( buf, tmp, 16 );
- }
-
- ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf );
- if( ret != 0 )
- goto exit;
-
- }
-
- if( memcmp( buf, aes_tests, 16 ) != 0 )
- {
- ret = 1;
- goto exit;
- }
-
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
-
- if( verbose != 0 )
- mbedtls_printf( "\n" );
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- /*
- * CFB128 mode
- */
- for( i = 0; i < 6; i++ )
- {
- u = i >> 1;
- keybits = 128 + u * 64;
- mode = i & 1;
-
- if( verbose != 0 )
- mbedtls_printf( " AES-CFB128-%3d (%s): ", keybits,
- ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
-
- memcpy( iv, aes_test_cfb128_iv, 16 );
- memcpy( key, aes_test_cfb128_key[u], keybits / 8 );
-
- offset = 0;
- ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
- /*
- * AES-192 is an optional feature that may be unavailable when
- * there is an alternative underlying implementation i.e. when
- * MBEDTLS_AES_ALT is defined.
- */
- if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
- {
- mbedtls_printf( "skipped\n" );
- continue;
- }
- else if( ret != 0 )
- {
- goto exit;
- }
-
- if( mode == MBEDTLS_AES_DECRYPT )
- {
- memcpy( buf, aes_test_cfb128_ct[u], 64 );
- aes_tests = aes_test_cfb128_pt;
- }
- else
- {
- memcpy( buf, aes_test_cfb128_pt, 64 );
- aes_tests = aes_test_cfb128_ct[u];
- }
-
- ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf );
- if( ret != 0 )
- goto exit;
-
- if( memcmp( buf, aes_tests, 64 ) != 0 )
- {
- ret = 1;
- goto exit;
- }
-
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
-
- if( verbose != 0 )
- mbedtls_printf( "\n" );
-#endif /* MBEDTLS_CIPHER_MODE_CFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- /*
- * OFB mode
- */
- for( i = 0; i < 6; i++ )
- {
- u = i >> 1;
- keybits = 128 + u * 64;
- mode = i & 1;
-
- if( verbose != 0 )
- mbedtls_printf( " AES-OFB-%3d (%s): ", keybits,
- ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
-
- memcpy( iv, aes_test_ofb_iv, 16 );
- memcpy( key, aes_test_ofb_key[u], keybits / 8 );
-
- offset = 0;
- ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
- /*
- * AES-192 is an optional feature that may be unavailable when
- * there is an alternative underlying implementation i.e. when
- * MBEDTLS_AES_ALT is defined.
- */
- if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
- {
- mbedtls_printf( "skipped\n" );
- continue;
- }
- else if( ret != 0 )
- {
- goto exit;
- }
-
- if( mode == MBEDTLS_AES_DECRYPT )
- {
- memcpy( buf, aes_test_ofb_ct[u], 64 );
- aes_tests = aes_test_ofb_pt;
- }
- else
- {
- memcpy( buf, aes_test_ofb_pt, 64 );
- aes_tests = aes_test_ofb_ct[u];
- }
-
- ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf );
- if( ret != 0 )
- goto exit;
-
- if( memcmp( buf, aes_tests, 64 ) != 0 )
- {
- ret = 1;
- goto exit;
- }
-
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
-
- if( verbose != 0 )
- mbedtls_printf( "\n" );
-#endif /* MBEDTLS_CIPHER_MODE_OFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- /*
- * CTR mode
- */
- for( i = 0; i < 6; i++ )
- {
- u = i >> 1;
- mode = i & 1;
-
- if( verbose != 0 )
- mbedtls_printf( " AES-CTR-128 (%s): ",
- ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
-
- memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 );
- memcpy( key, aes_test_ctr_key[u], 16 );
-
- offset = 0;
- if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 )
- goto exit;
-
- len = aes_test_ctr_len[u];
-
- if( mode == MBEDTLS_AES_DECRYPT )
- {
- memcpy( buf, aes_test_ctr_ct[u], len );
- aes_tests = aes_test_ctr_pt[u];
- }
- else
- {
- memcpy( buf, aes_test_ctr_pt[u], len );
- aes_tests = aes_test_ctr_ct[u];
- }
-
- ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter,
- stream_block, buf, buf );
- if( ret != 0 )
- goto exit;
-
- if( memcmp( buf, aes_tests, len ) != 0 )
- {
- ret = 1;
- goto exit;
- }
-
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
-
- if( verbose != 0 )
- mbedtls_printf( "\n" );
-#endif /* MBEDTLS_CIPHER_MODE_CTR */
-
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- {
- static const int num_tests =
- sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
- mbedtls_aes_xts_context ctx_xts;
-
- /*
- * XTS mode
- */
- mbedtls_aes_xts_init( &ctx_xts );
-
- for( i = 0; i < num_tests << 1; i++ )
- {
- const unsigned char *data_unit;
- u = i >> 1;
- mode = i & 1;
-
- if( verbose != 0 )
- mbedtls_printf( " AES-XTS-128 (%s): ",
- ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
-
- memset( key, 0, sizeof( key ) );
- memcpy( key, aes_test_xts_key[u], 32 );
- data_unit = aes_test_xts_data_unit[u];
-
- len = sizeof( *aes_test_xts_ct32 );
-
- if( mode == MBEDTLS_AES_DECRYPT )
- {
- ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 );
- if( ret != 0)
- goto exit;
- memcpy( buf, aes_test_xts_ct32[u], len );
- aes_tests = aes_test_xts_pt32[u];
- }
- else
- {
- ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 );
- if( ret != 0)
- goto exit;
- memcpy( buf, aes_test_xts_pt32[u], len );
- aes_tests = aes_test_xts_ct32[u];
- }
-
-
- ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit,
- buf, buf );
- if( ret != 0 )
- goto exit;
-
- if( memcmp( buf, aes_tests, len ) != 0 )
- {
- ret = 1;
- goto exit;
- }
-
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
-
- if( verbose != 0 )
- mbedtls_printf( "\n" );
-
- mbedtls_aes_xts_free( &ctx_xts );
- }
-#endif /* MBEDTLS_CIPHER_MODE_XTS */
-
- ret = 0;
-
-exit:
- if( ret != 0 && verbose != 0 )
- mbedtls_printf( "failed\n" );
-
- mbedtls_aes_free( &ctx );
-
- return( ret );
-}
-
-#endif /* MBEDTLS_SELF_TEST */
-
-#endif /* MBEDTLS_AES_C */
diff --git a/assets/templates/blackpill/Src/aes.h b/assets/templates/blackpill/Src/aes.h
deleted file mode 100644
index 94e7282..0000000
--- a/assets/templates/blackpill/Src/aes.h
+++ /dev/null
@@ -1,674 +0,0 @@
-/**
- * \file aes.h
- *
- * \brief This file contains AES definitions and functions.
- *
- * The Advanced Encryption Standard (AES) specifies a FIPS-approved
- * cryptographic algorithm that can be used to protect electronic
- * data.
- *
- * The AES algorithm is a symmetric block cipher that can
- * encrypt and decrypt information. For more information, see
- * FIPS Publication 197: Advanced Encryption Standard and
- * ISO/IEC 18033-2:2006: Information technology -- Security
- * techniques -- Encryption algorithms -- Part 2: Asymmetric
- * ciphers.
- *
- * The AES-XTS block mode is standardized by NIST SP 800-38E
- *
- * and described in detail by IEEE P1619
- * .
- */
-
-/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
- */
-
-#ifndef MBEDTLS_AES_H
-#define MBEDTLS_AES_H
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#include
-#include
-
-/* padlock.c and aesni.c rely on these values! */
-#define MBEDTLS_AES_ENCRYPT 1 /**< AES encryption. */
-#define MBEDTLS_AES_DECRYPT 0 /**< AES decryption. */
-
-/* Error codes in range 0x0020-0x0022 */
-#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
-#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
-
-/* Error codes in range 0x0021-0x0025 */
-#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021 /**< Invalid input data. */
-
-/* MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE is deprecated and should not be used. */
-#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE -0x0023 /**< Feature not available. For example, an unsupported AES key size. */
-
-/* MBEDTLS_ERR_AES_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_AES_HW_ACCEL_FAILED -0x0025 /**< AES hardware accelerator failed. */
-
-#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
- !defined(inline) && !defined(__cplusplus)
-#define inline __inline
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if !defined(MBEDTLS_AES_ALT)
-// Regular implementation
-//
-
-/**
- * \brief The AES context-type definition.
- */
-typedef struct mbedtls_aes_context
-{
- int nr; /*!< The number of rounds. */
- uint32_t *rk; /*!< AES round keys. */
- uint32_t buf[68]; /*!< Unaligned data buffer. This buffer can
- hold 32 extra Bytes, which can be used for
- one of the following purposes:
- - Alignment if VIA padlock is
- used.
- - Simplifying key expansion in the 256-bit
- case by generating an extra round key.
-
*/
-}
-mbedtls_aes_context;
-
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
-/**
- * \brief The AES XTS context-type definition.
- */
-typedef struct mbedtls_aes_xts_context
-{
- mbedtls_aes_context crypt; /*!< The AES context to use for AES block
- encryption or decryption. */
- mbedtls_aes_context tweak; /*!< The AES context used for tweak
- computation. */
-} mbedtls_aes_xts_context;
-#endif /* MBEDTLS_CIPHER_MODE_XTS */
-
-#else /* MBEDTLS_AES_ALT */
-#include "aes_alt.h"
-#endif /* MBEDTLS_AES_ALT */
-
-/**
- * \brief This function initializes the specified AES context.
- *
- * It must be the first API called before using
- * the context.
- *
- * \param ctx The AES context to initialize. This must not be \c NULL.
- */
-void mbedtls_aes_init( mbedtls_aes_context *ctx );
-
-/**
- * \brief This function releases and clears the specified AES context.
- *
- * \param ctx The AES context to clear.
- * If this is \c NULL, this function does nothing.
- * Otherwise, the context must have been at least initialized.
- */
-void mbedtls_aes_free( mbedtls_aes_context *ctx );
-
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
-/**
- * \brief This function initializes the specified AES XTS context.
- *
- * It must be the first API called before using
- * the context.
- *
- * \param ctx The AES XTS context to initialize. This must not be \c NULL.
- */
-void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx );
-
-/**
- * \brief This function releases and clears the specified AES XTS context.
- *
- * \param ctx The AES XTS context to clear.
- * If this is \c NULL, this function does nothing.
- * Otherwise, the context must have been at least initialized.
- */
-void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx );
-#endif /* MBEDTLS_CIPHER_MODE_XTS */
-
-/**
- * \brief This function sets the encryption key.
- *
- * \param ctx The AES context to which the key should be bound.
- * It must be initialized.
- * \param key The encryption key.
- * This must be a readable buffer of size \p keybits bits.
- * \param keybits The size of data passed in bits. Valid options are:
- * - 128 bits
- * - 192 bits
- * - 256 bits
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
- */
-int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
- unsigned int keybits );
-
-/**
- * \brief This function sets the decryption key.
- *
- * \param ctx The AES context to which the key should be bound.
- * It must be initialized.
- * \param key The decryption key.
- * This must be a readable buffer of size \p keybits bits.
- * \param keybits The size of data passed. Valid options are:
- * - 128 bits
- * - 192 bits
- * - 256 bits
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
- */
-int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
- unsigned int keybits );
-
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
-/**
- * \brief This function prepares an XTS context for encryption and
- * sets the encryption key.
- *
- * \param ctx The AES XTS context to which the key should be bound.
- * It must be initialized.
- * \param key The encryption key. This is comprised of the XTS key1
- * concatenated with the XTS key2.
- * This must be a readable buffer of size \p keybits bits.
- * \param keybits The size of \p key passed in bits. Valid options are:
- * - 256 bits (each of key1 and key2 is a 128-bit key)
- * - 512 bits (each of key1 and key2 is a 256-bit key)
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
- */
-int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
- const unsigned char *key,
- unsigned int keybits );
-
-/**
- * \brief This function prepares an XTS context for decryption and
- * sets the decryption key.
- *
- * \param ctx The AES XTS context to which the key should be bound.
- * It must be initialized.
- * \param key The decryption key. This is comprised of the XTS key1
- * concatenated with the XTS key2.
- * This must be a readable buffer of size \p keybits bits.
- * \param keybits The size of \p key passed in bits. Valid options are:
- * - 256 bits (each of key1 and key2 is a 128-bit key)
- * - 512 bits (each of key1 and key2 is a 256-bit key)
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
- */
-int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
- const unsigned char *key,
- unsigned int keybits );
-#endif /* MBEDTLS_CIPHER_MODE_XTS */
-
-/**
- * \brief This function performs an AES single-block encryption or
- * decryption operation.
- *
- * It performs the operation defined in the \p mode parameter
- * (encrypt or decrypt), on the input data buffer defined in
- * the \p input parameter.
- *
- * mbedtls_aes_init(), and either mbedtls_aes_setkey_enc() or
- * mbedtls_aes_setkey_dec() must be called before the first
- * call to this API with the same context.
- *
- * \param ctx The AES context to use for encryption or decryption.
- * It must be initialized and bound to a key.
- * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
- * #MBEDTLS_AES_DECRYPT.
- * \param input The buffer holding the input data.
- * It must be readable and at least \c 16 Bytes long.
- * \param output The buffer where the output data will be written.
- * It must be writeable and at least \c 16 Bytes long.
-
- * \return \c 0 on success.
- */
-int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
- int mode,
- const unsigned char input[16],
- unsigned char output[16] );
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-/**
- * \brief This function performs an AES-CBC encryption or decryption operation
- * on full blocks.
- *
- * It performs the operation defined in the \p mode
- * parameter (encrypt/decrypt), on the input data buffer defined in
- * the \p input parameter.
- *
- * It can be called as many times as needed, until all the input
- * data is processed. mbedtls_aes_init(), and either
- * mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called
- * before the first call to this API with the same context.
- *
- * \note This function operates on full blocks, that is, the input size
- * must be a multiple of the AES block size of \c 16 Bytes.
- *
- * \note Upon exit, the content of the IV is updated so that you can
- * call the same function again on the next
- * block(s) of data and get the same result as if it was
- * encrypted in one call. This allows a "streaming" usage.
- * If you need to retain the contents of the IV, you should
- * either save it manually or use the cipher module instead.
- *
- *
- * \param ctx The AES context to use for encryption or decryption.
- * It must be initialized and bound to a key.
- * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
- * #MBEDTLS_AES_DECRYPT.
- * \param length The length of the input data in Bytes. This must be a
- * multiple of the block size (\c 16 Bytes).
- * \param iv Initialization vector (updated after use).
- * It must be a readable and writeable buffer of \c 16 Bytes.
- * \param input The buffer holding the input data.
- * It must be readable and of size \p length Bytes.
- * \param output The buffer holding the output data.
- * It must be writeable and of size \p length Bytes.
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
- * on failure.
- */
-int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
- int mode,
- size_t length,
- unsigned char iv[16],
- const unsigned char *input,
- unsigned char *output );
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
-/**
- * \brief This function performs an AES-XTS encryption or decryption
- * operation for an entire XTS data unit.
- *
- * AES-XTS encrypts or decrypts blocks based on their location as
- * defined by a data unit number. The data unit number must be
- * provided by \p data_unit.
- *
- * NIST SP 800-38E limits the maximum size of a data unit to 2^20
- * AES blocks. If the data unit is larger than this, this function
- * returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH.
- *
- * \param ctx The AES XTS context to use for AES XTS operations.
- * It must be initialized and bound to a key.
- * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
- * #MBEDTLS_AES_DECRYPT.
- * \param length The length of a data unit in Bytes. This can be any
- * length between 16 bytes and 2^24 bytes inclusive
- * (between 1 and 2^20 block cipher blocks).
- * \param data_unit The address of the data unit encoded as an array of 16
- * bytes in little-endian format. For disk encryption, this
- * is typically the index of the block device sector that
- * contains the data.
- * \param input The buffer holding the input data (which is an entire
- * data unit). This function reads \p length Bytes from \p
- * input.
- * \param output The buffer holding the output data (which is an entire
- * data unit). This function writes \p length Bytes to \p
- * output.
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is
- * smaller than an AES block in size (16 Bytes) or if \p
- * length is larger than 2^20 blocks (16 MiB).
- */
-int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
- int mode,
- size_t length,
- const unsigned char data_unit[16],
- const unsigned char *input,
- unsigned char *output );
-#endif /* MBEDTLS_CIPHER_MODE_XTS */
-
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
-/**
- * \brief This function performs an AES-CFB128 encryption or decryption
- * operation.
- *
- * It performs the operation defined in the \p mode
- * parameter (encrypt or decrypt), on the input data buffer
- * defined in the \p input parameter.
- *
- * For CFB, you must set up the context with mbedtls_aes_setkey_enc(),
- * regardless of whether you are performing an encryption or decryption
- * operation, that is, regardless of the \p mode parameter. This is
- * because CFB mode uses the same key schedule for encryption and
- * decryption.
- *
- * \note Upon exit, the content of the IV is updated so that you can
- * call the same function again on the next
- * block(s) of data and get the same result as if it was
- * encrypted in one call. This allows a "streaming" usage.
- * If you need to retain the contents of the
- * IV, you must either save it manually or use the cipher
- * module instead.
- *
- *
- * \param ctx The AES context to use for encryption or decryption.
- * It must be initialized and bound to a key.
- * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
- * #MBEDTLS_AES_DECRYPT.
- * \param length The length of the input data in Bytes.
- * \param iv_off The offset in IV (updated after use).
- * It must point to a valid \c size_t.
- * \param iv The initialization vector (updated after use).
- * It must be a readable and writeable buffer of \c 16 Bytes.
- * \param input The buffer holding the input data.
- * It must be readable and of size \p length Bytes.
- * \param output The buffer holding the output data.
- * It must be writeable and of size \p length Bytes.
- *
- * \return \c 0 on success.
- */
-int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
- int mode,
- size_t length,
- size_t *iv_off,
- unsigned char iv[16],
- const unsigned char *input,
- unsigned char *output );
-
-/**
- * \brief This function performs an AES-CFB8 encryption or decryption
- * operation.
- *
- * It performs the operation defined in the \p mode
- * parameter (encrypt/decrypt), on the input data buffer defined
- * in the \p input parameter.
- *
- * Due to the nature of CFB, you must use the same key schedule for
- * both encryption and decryption operations. Therefore, you must
- * use the context initialized with mbedtls_aes_setkey_enc() for
- * both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT.
- *
- * \note Upon exit, the content of the IV is updated so that you can
- * call the same function again on the next
- * block(s) of data and get the same result as if it was
- * encrypted in one call. This allows a "streaming" usage.
- * If you need to retain the contents of the
- * IV, you should either save it manually or use the cipher
- * module instead.
- *
- *
- * \param ctx The AES context to use for encryption or decryption.
- * It must be initialized and bound to a key.
- * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
- * #MBEDTLS_AES_DECRYPT
- * \param length The length of the input data.
- * \param iv The initialization vector (updated after use).
- * It must be a readable and writeable buffer of \c 16 Bytes.
- * \param input The buffer holding the input data.
- * It must be readable and of size \p length Bytes.
- * \param output The buffer holding the output data.
- * It must be writeable and of size \p length Bytes.
- *
- * \return \c 0 on success.
- */
-int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
- int mode,
- size_t length,
- unsigned char iv[16],
- const unsigned char *input,
- unsigned char *output );
-#endif /*MBEDTLS_CIPHER_MODE_CFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
-/**
- * \brief This function performs an AES-OFB (Output Feedback Mode)
- * encryption or decryption operation.
- *
- * For OFB, you must set up the context with
- * mbedtls_aes_setkey_enc(), regardless of whether you are
- * performing an encryption or decryption operation. This is
- * because OFB mode uses the same key schedule for encryption and
- * decryption.
- *
- * The OFB operation is identical for encryption or decryption,
- * therefore no operation mode needs to be specified.
- *
- * \note Upon exit, the content of iv, the Initialisation Vector, is
- * updated so that you can call the same function again on the next
- * block(s) of data and get the same result as if it was encrypted
- * in one call. This allows a "streaming" usage, by initialising
- * iv_off to 0 before the first call, and preserving its value
- * between calls.
- *
- * For non-streaming use, the iv should be initialised on each call
- * to a unique value, and iv_off set to 0 on each call.
- *
- * If you need to retain the contents of the initialisation vector,
- * you must either save it manually or use the cipher module
- * instead.
- *
- * \warning For the OFB mode, the initialisation vector must be unique
- * every encryption operation. Reuse of an initialisation vector
- * will compromise security.
- *
- * \param ctx The AES context to use for encryption or decryption.
- * It must be initialized and bound to a key.
- * \param length The length of the input data.
- * \param iv_off The offset in IV (updated after use).
- * It must point to a valid \c size_t.
- * \param iv The initialization vector (updated after use).
- * It must be a readable and writeable buffer of \c 16 Bytes.
- * \param input The buffer holding the input data.
- * It must be readable and of size \p length Bytes.
- * \param output The buffer holding the output data.
- * It must be writeable and of size \p length Bytes.
- *
- * \return \c 0 on success.
- */
-int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
- size_t length,
- size_t *iv_off,
- unsigned char iv[16],
- const unsigned char *input,
- unsigned char *output );
-
-#endif /* MBEDTLS_CIPHER_MODE_OFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
-/**
- * \brief This function performs an AES-CTR encryption or decryption
- * operation.
- *
- * This function performs the operation defined in the \p mode
- * parameter (encrypt/decrypt), on the input data buffer
- * defined in the \p input parameter.
- *
- * Due to the nature of CTR, you must use the same key schedule
- * for both encryption and decryption operations. Therefore, you
- * must use the context initialized with mbedtls_aes_setkey_enc()
- * for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT.
- *
- * \warning You must never reuse a nonce value with the same key. Doing so
- * would void the encryption for the two messages encrypted with
- * the same nonce and key.
- *
- * There are two common strategies for managing nonces with CTR:
- *
- * 1. You can handle everything as a single message processed over
- * successive calls to this function. In that case, you want to
- * set \p nonce_counter and \p nc_off to 0 for the first call, and
- * then preserve the values of \p nonce_counter, \p nc_off and \p
- * stream_block across calls to this function as they will be
- * updated by this function.
- *
- * With this strategy, you must not encrypt more than 2**128
- * blocks of data with the same key.
- *
- * 2. You can encrypt separate messages by dividing the \p
- * nonce_counter buffer in two areas: the first one used for a
- * per-message nonce, handled by yourself, and the second one
- * updated by this function internally.
- *
- * For example, you might reserve the first 12 bytes for the
- * per-message nonce, and the last 4 bytes for internal use. In that
- * case, before calling this function on a new message you need to
- * set the first 12 bytes of \p nonce_counter to your chosen nonce
- * value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
- * stream_block to be ignored). That way, you can encrypt at most
- * 2**96 messages of up to 2**32 blocks each with the same key.
- *
- * The per-message nonce (or information sufficient to reconstruct
- * it) needs to be communicated with the ciphertext and must be unique.
- * The recommended way to ensure uniqueness is to use a message
- * counter. An alternative is to generate random nonces, but this
- * limits the number of messages that can be securely encrypted:
- * for example, with 96-bit random nonces, you should not encrypt
- * more than 2**32 messages with the same key.
- *
- * Note that for both stategies, sizes are measured in blocks and
- * that an AES block is 16 bytes.
- *
- * \warning Upon return, \p stream_block contains sensitive data. Its
- * content must not be written to insecure storage and should be
- * securely discarded as soon as it's no longer needed.
- *
- * \param ctx The AES context to use for encryption or decryption.
- * It must be initialized and bound to a key.
- * \param length The length of the input data.
- * \param nc_off The offset in the current \p stream_block, for
- * resuming within the current cipher stream. The
- * offset pointer should be 0 at the start of a stream.
- * It must point to a valid \c size_t.
- * \param nonce_counter The 128-bit nonce and counter.
- * It must be a readable-writeable buffer of \c 16 Bytes.
- * \param stream_block The saved stream block for resuming. This is
- * overwritten by the function.
- * It must be a readable-writeable buffer of \c 16 Bytes.
- * \param input The buffer holding the input data.
- * It must be readable and of size \p length Bytes.
- * \param output The buffer holding the output data.
- * It must be writeable and of size \p length Bytes.
- *
- * \return \c 0 on success.
- */
-int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
- size_t length,
- size_t *nc_off,
- unsigned char nonce_counter[16],
- unsigned char stream_block[16],
- const unsigned char *input,
- unsigned char *output );
-#endif /* MBEDTLS_CIPHER_MODE_CTR */
-
-/**
- * \brief Internal AES block encryption function. This is only
- * exposed to allow overriding it using
- * \c MBEDTLS_AES_ENCRYPT_ALT.
- *
- * \param ctx The AES context to use for encryption.
- * \param input The plaintext block.
- * \param output The output (ciphertext) block.
- *
- * \return \c 0 on success.
- */
-int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
- const unsigned char input[16],
- unsigned char output[16] );
-
-/**
- * \brief Internal AES block decryption function. This is only
- * exposed to allow overriding it using see
- * \c MBEDTLS_AES_DECRYPT_ALT.
- *
- * \param ctx The AES context to use for decryption.
- * \param input The ciphertext block.
- * \param output The output (plaintext) block.
- *
- * \return \c 0 on success.
- */
-int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
- const unsigned char input[16],
- unsigned char output[16] );
-
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-#if defined(MBEDTLS_DEPRECATED_WARNING)
-#define MBEDTLS_DEPRECATED __attribute__((deprecated))
-#else
-#define MBEDTLS_DEPRECATED
-#endif
-/**
- * \brief Deprecated internal AES block encryption function
- * without return value.
- *
- * \deprecated Superseded by mbedtls_internal_aes_encrypt()
- *
- * \param ctx The AES context to use for encryption.
- * \param input Plaintext block.
- * \param output Output (ciphertext) block.
- */
-MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
- const unsigned char input[16],
- unsigned char output[16] );
-
-/**
- * \brief Deprecated internal AES block decryption function
- * without return value.
- *
- * \deprecated Superseded by mbedtls_internal_aes_decrypt()
- *
- * \param ctx The AES context to use for decryption.
- * \param input Ciphertext block.
- * \param output Output (plaintext) block.
- */
-MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
- const unsigned char input[16],
- unsigned char output[16] );
-
-#undef MBEDTLS_DEPRECATED
-#endif /* !MBEDTLS_DEPRECATED_REMOVED */
-
-
-#if defined(MBEDTLS_SELF_TEST)
-/**
- * \brief Checkup routine.
- *
- * \return \c 0 on success.
- * \return \c 1 on failure.
- */
-int mbedtls_aes_self_test( int verbose );
-
-#endif /* MBEDTLS_SELF_TEST */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* aes.h */
diff --git a/assets/templates/blackpill/Src/cipher.c b/assets/templates/blackpill/Src/cipher.c
deleted file mode 100644
index 0a46dae..0000000
--- a/assets/templates/blackpill/Src/cipher.c
+++ /dev/null
@@ -1,1540 +0,0 @@
-/**
- * \file cipher.c
- *
- * \brief Generic cipher wrapper for mbed TLS
- *
- * \author Adriaan de Jong
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_CIPHER_C)
-
-#include "cipher.h"
-#include "cipher_internal.h"
-#include "platform_util.h"
-
-#include
-#include
-
-#if defined(MBEDTLS_CHACHAPOLY_C)
-#include "mbedtls/chachapoly.h"
-#endif
-
-#if defined(MBEDTLS_GCM_C)
-#include "gcm.h"
-#endif
-
-#if defined(MBEDTLS_CCM_C)
-#include "mbedtls/ccm.h"
-#endif
-
-#if defined(MBEDTLS_CHACHA20_C)
-#include "mbedtls/chacha20.h"
-#endif
-
-#if defined(MBEDTLS_CMAC_C)
-#include "mbedtls/cmac.h"
-#endif
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-#include "psa/crypto.h"
-#include "mbedtls/psa_util.h"
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-#if defined(MBEDTLS_NIST_KW_C)
-#include "mbedtls/nist_kw.h"
-#endif
-
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#define mbedtls_calloc calloc
-#define mbedtls_free free
-#endif
-
-#define CIPHER_VALIDATE_RET( cond ) \
- MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA )
-#define CIPHER_VALIDATE( cond ) \
- MBEDTLS_INTERNAL_VALIDATE( cond )
-
-#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
-/* Compare the contents of two buffers in constant time.
- * Returns 0 if the contents are bitwise identical, otherwise returns
- * a non-zero value.
- * This is currently only used by GCM and ChaCha20+Poly1305.
- */
-static int mbedtls_constant_time_memcmp( const void *v1, const void *v2,
- size_t len )
-{
- const unsigned char *p1 = (const unsigned char*) v1;
- const unsigned char *p2 = (const unsigned char*) v2;
- size_t i;
- unsigned char diff;
-
- for( diff = 0, i = 0; i < len; i++ )
- diff |= p1[i] ^ p2[i];
-
- return( (int)diff );
-}
-#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
-
-static int supported_init = 0;
-
-const int *mbedtls_cipher_list( void )
-{
- const mbedtls_cipher_definition_t *def;
- int *type;
-
- if( ! supported_init )
- {
- def = mbedtls_cipher_definitions;
- type = mbedtls_cipher_supported;
-
- while( def->type != 0 )
- *type++ = (*def++).type;
-
- *type = 0;
-
- supported_init = 1;
- }
-
- return( mbedtls_cipher_supported );
-}
-
-const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type(
- const mbedtls_cipher_type_t cipher_type )
-{
- const mbedtls_cipher_definition_t *def;
-
- for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
- if( def->type == cipher_type )
- return( def->info );
-
- return( NULL );
-}
-
-const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string(
- const char *cipher_name )
-{
- const mbedtls_cipher_definition_t *def;
-
- if( NULL == cipher_name )
- return( NULL );
-
- for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
- if( ! strcmp( def->info->name, cipher_name ) )
- return( def->info );
-
- return( NULL );
-}
-
-const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values(
- const mbedtls_cipher_id_t cipher_id,
- int key_bitlen,
- const mbedtls_cipher_mode_t mode )
-{
- const mbedtls_cipher_definition_t *def;
-
- for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
- if( def->info->base->cipher == cipher_id &&
- def->info->key_bitlen == (unsigned) key_bitlen &&
- def->info->mode == mode )
- return( def->info );
-
- return( NULL );
-}
-
-void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx )
-{
- CIPHER_VALIDATE( ctx != NULL );
- memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
-}
-
-void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
-{
- if( ctx == NULL )
- return;
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if( ctx->psa_enabled == 1 )
- {
- if( ctx->cipher_ctx != NULL )
- {
- mbedtls_cipher_context_psa * const cipher_psa =
- (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
-
- if( cipher_psa->slot_state == MBEDTLS_CIPHER_PSA_KEY_OWNED )
- {
- /* xxx_free() doesn't allow to return failures. */
- (void) psa_destroy_key( cipher_psa->slot );
- }
-
- mbedtls_platform_zeroize( cipher_psa, sizeof( *cipher_psa ) );
- mbedtls_free( cipher_psa );
- }
-
- mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
- return;
- }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-#if defined(MBEDTLS_CMAC_C)
- if( ctx->cmac_ctx )
- {
- mbedtls_platform_zeroize( ctx->cmac_ctx,
- sizeof( mbedtls_cmac_context_t ) );
- mbedtls_free( ctx->cmac_ctx );
- }
-#endif
-
- if( ctx->cipher_ctx )
- ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx );
-
- mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
-}
-
-int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
- const mbedtls_cipher_info_t *cipher_info )
-{
- CIPHER_VALIDATE_RET( ctx != NULL );
- if( cipher_info == NULL )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
-
- if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) )
- return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
-
- ctx->cipher_info = cipher_info;
-
-#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
- /*
- * Ignore possible errors caused by a cipher mode that doesn't use padding
- */
-#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
- (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 );
-#else
- (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE );
-#endif
-#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
-
- return( 0 );
-}
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx,
- const mbedtls_cipher_info_t *cipher_info,
- size_t taglen )
-{
- psa_algorithm_t alg;
- mbedtls_cipher_context_psa *cipher_psa;
-
- if( NULL == cipher_info || NULL == ctx )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- /* Check that the underlying cipher mode and cipher type are
- * supported by the underlying PSA Crypto implementation. */
- alg = mbedtls_psa_translate_cipher_mode( cipher_info->mode, taglen );
- if( alg == 0 )
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
- if( mbedtls_psa_translate_cipher_type( cipher_info->type ) == 0 )
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
-
- memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
-
- cipher_psa = mbedtls_calloc( 1, sizeof(mbedtls_cipher_context_psa ) );
- if( cipher_psa == NULL )
- return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
- cipher_psa->alg = alg;
- ctx->cipher_ctx = cipher_psa;
- ctx->cipher_info = cipher_info;
- ctx->psa_enabled = 1;
- return( 0 );
-}
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
- const unsigned char *key,
- int key_bitlen,
- const mbedtls_operation_t operation )
-{
- CIPHER_VALIDATE_RET( ctx != NULL );
- CIPHER_VALIDATE_RET( key != NULL );
- CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT ||
- operation == MBEDTLS_DECRYPT );
- if( ctx->cipher_info == NULL )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if( ctx->psa_enabled == 1 )
- {
- mbedtls_cipher_context_psa * const cipher_psa =
- (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
-
- size_t const key_bytelen = ( (size_t) key_bitlen + 7 ) / 8;
-
- psa_status_t status;
- psa_key_type_t key_type;
- psa_key_usage_t key_usage;
- psa_key_policy_t key_policy;
-
- /* PSA Crypto API only accepts byte-aligned keys. */
- if( key_bitlen % 8 != 0 )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- /* Don't allow keys to be set multiple times. */
- if( cipher_psa->slot_state != MBEDTLS_CIPHER_PSA_KEY_UNSET )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- key_type = mbedtls_psa_translate_cipher_type(
- ctx->cipher_info->type );
- if( key_type == 0 )
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
-
- /* Allocate a key slot to use. */
- status = psa_allocate_key( &cipher_psa->slot );
- if( status != PSA_SUCCESS )
- return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
-
- /* Indicate that we own the key slot and need to
- * destroy it in mbedtls_cipher_free(). */
- cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED;
-
- /* From that point on, the responsibility for destroying the
- * key slot is on mbedtls_cipher_free(). This includes the case
- * where the policy setup or key import below fail, as
- * mbedtls_cipher_free() needs to be called in any case. */
-
- /* Setup policy for the new key slot. */
- key_policy = psa_key_policy_init();
-
- /* Mbed TLS' cipher layer doesn't enforce the mode of operation
- * (encrypt vs. decrypt): it is possible to setup a key for encryption
- * and use it for AEAD decryption. Until tests relying on this
- * are changed, allow any usage in PSA. */
- /* key_usage = mbedtls_psa_translate_cipher_operation( operation ); */
- key_usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
- psa_key_policy_set_usage( &key_policy, key_usage, cipher_psa->alg );
- status = psa_set_key_policy( cipher_psa->slot, &key_policy );
- if( status != PSA_SUCCESS )
- return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
-
- /* Populate new key slot. */
- status = psa_import_key( cipher_psa->slot,
- key_type, key, key_bytelen );
- if( status != PSA_SUCCESS )
- return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
-
- ctx->key_bitlen = key_bitlen;
- ctx->operation = operation;
- return( 0 );
- }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
- if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 &&
- (int) ctx->cipher_info->key_bitlen != key_bitlen )
- {
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
-
- ctx->key_bitlen = key_bitlen;
- ctx->operation = operation;
-
- /*
- * For OFB, CFB and CTR mode always use the encryption key schedule
- */
- if( MBEDTLS_ENCRYPT == operation ||
- MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
- MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
- MBEDTLS_MODE_CTR == ctx->cipher_info->mode )
- {
- return( ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
- ctx->key_bitlen ) );
- }
-
- if( MBEDTLS_DECRYPT == operation )
- return( ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
- ctx->key_bitlen ) );
-
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-}
-
-int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
- const unsigned char *iv,
- size_t iv_len )
-{
- size_t actual_iv_size;
-
- CIPHER_VALIDATE_RET( ctx != NULL );
- CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
- if( ctx->cipher_info == NULL )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if( ctx->psa_enabled == 1 )
- {
- /* While PSA Crypto has an API for multipart
- * operations, we currently don't make it
- * accessible through the cipher layer. */
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
- }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
- /* avoid buffer overflow in ctx->iv */
- if( iv_len > MBEDTLS_MAX_IV_LENGTH )
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
-
- if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 )
- actual_iv_size = iv_len;
- else
- {
- actual_iv_size = ctx->cipher_info->iv_size;
-
- /* avoid reading past the end of input buffer */
- if( actual_iv_size > iv_len )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
-
-#if defined(MBEDTLS_CHACHA20_C)
- if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
- {
- if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx,
- iv,
- 0U ) ) /* Initial counter value */
- {
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
- }
-#endif
-
- if ( actual_iv_size != 0 )
- {
- memcpy( ctx->iv, iv, actual_iv_size );
- ctx->iv_size = actual_iv_size;
- }
-
- return( 0 );
-}
-
-int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
-{
- CIPHER_VALIDATE_RET( ctx != NULL );
- if( ctx->cipher_info == NULL )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if( ctx->psa_enabled == 1 )
- {
- /* We don't support resetting PSA-based
- * cipher contexts, yet. */
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
- }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
- ctx->unprocessed_len = 0;
-
- return( 0 );
-}
-
-#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
-int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
- const unsigned char *ad, size_t ad_len )
-{
- CIPHER_VALIDATE_RET( ctx != NULL );
- CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
- if( ctx->cipher_info == NULL )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if( ctx->psa_enabled == 1 )
- {
- /* While PSA Crypto has an API for multipart
- * operations, we currently don't make it
- * accessible through the cipher layer. */
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
- }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-#if defined(MBEDTLS_GCM_C)
- if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
- {
- return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
- ctx->iv, ctx->iv_size, ad, ad_len ) );
- }
-#endif
-
-#if defined(MBEDTLS_CHACHAPOLY_C)
- if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
- {
- int result;
- mbedtls_chachapoly_mode_t mode;
-
- mode = ( ctx->operation == MBEDTLS_ENCRYPT )
- ? MBEDTLS_CHACHAPOLY_ENCRYPT
- : MBEDTLS_CHACHAPOLY_DECRYPT;
-
- result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
- ctx->iv,
- mode );
- if ( result != 0 )
- return( result );
-
- return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
- ad, ad_len ) );
- }
-#endif
-
- return( 0 );
-}
-#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
-
-int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
- size_t ilen, unsigned char *output, size_t *olen )
-{
- int ret;
- size_t block_size;
-
- CIPHER_VALIDATE_RET( ctx != NULL );
- CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
- CIPHER_VALIDATE_RET( output != NULL );
- CIPHER_VALIDATE_RET( olen != NULL );
- if( ctx->cipher_info == NULL )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if( ctx->psa_enabled == 1 )
- {
- /* While PSA Crypto has an API for multipart
- * operations, we currently don't make it
- * accessible through the cipher layer. */
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
- }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
- *olen = 0;
- block_size = mbedtls_cipher_get_block_size( ctx );
-
- if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB )
- {
- if( ilen != block_size )
- return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
-
- *olen = ilen;
-
- if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx,
- ctx->operation, input, output ) ) )
- {
- return( ret );
- }
-
- return( 0 );
- }
-
-#if defined(MBEDTLS_GCM_C)
- if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM )
- {
- *olen = ilen;
- return( mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
- output ) );
- }
-#endif
-
-#if defined(MBEDTLS_CHACHAPOLY_C)
- if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 )
- {
- *olen = ilen;
- return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
- ilen, input, output ) );
- }
-#endif
-
- if ( 0 == block_size )
- {
- return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
- }
-
- if( input == output &&
- ( ctx->unprocessed_len != 0 || ilen % block_size ) )
- {
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC )
- {
- size_t copy_len = 0;
-
- /*
- * If there is not enough data for a full block, cache it.
- */
- if( ( ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding &&
- ilen <= block_size - ctx->unprocessed_len ) ||
- ( ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding &&
- ilen < block_size - ctx->unprocessed_len ) ||
- ( ctx->operation == MBEDTLS_ENCRYPT &&
- ilen < block_size - ctx->unprocessed_len ) )
- {
- memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
- ilen );
-
- ctx->unprocessed_len += ilen;
- return( 0 );
- }
-
- /*
- * Process cached data first
- */
- if( 0 != ctx->unprocessed_len )
- {
- copy_len = block_size - ctx->unprocessed_len;
-
- memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
- copy_len );
-
- if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
- ctx->operation, block_size, ctx->iv,
- ctx->unprocessed_data, output ) ) )
- {
- return( ret );
- }
-
- *olen += block_size;
- output += block_size;
- ctx->unprocessed_len = 0;
-
- input += copy_len;
- ilen -= copy_len;
- }
-
- /*
- * Cache final, incomplete block
- */
- if( 0 != ilen )
- {
- if( 0 == block_size )
- {
- return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
- }
-
- /* Encryption: only cache partial blocks
- * Decryption w/ padding: always keep at least one whole block
- * Decryption w/o padding: only cache partial blocks
- */
- copy_len = ilen % block_size;
- if( copy_len == 0 &&
- ctx->operation == MBEDTLS_DECRYPT &&
- NULL != ctx->add_padding)
- {
- copy_len = block_size;
- }
-
- memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
- copy_len );
-
- ctx->unprocessed_len += copy_len;
- ilen -= copy_len;
- }
-
- /*
- * Process remaining full blocks
- */
- if( ilen )
- {
- if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
- ctx->operation, ilen, ctx->iv, input, output ) ) )
- {
- return( ret );
- }
-
- *olen += ilen;
- }
-
- return( 0 );
- }
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB )
- {
- if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx,
- ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv,
- input, output ) ) )
- {
- return( ret );
- }
-
- *olen = ilen;
-
- return( 0 );
- }
-#endif /* MBEDTLS_CIPHER_MODE_CFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB )
- {
- if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx,
- ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) )
- {
- return( ret );
- }
-
- *olen = ilen;
-
- return( 0 );
- }
-#endif /* MBEDTLS_CIPHER_MODE_OFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR )
- {
- if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx,
- ilen, &ctx->unprocessed_len, ctx->iv,
- ctx->unprocessed_data, input, output ) ) )
- {
- return( ret );
- }
-
- *olen = ilen;
-
- return( 0 );
- }
-#endif /* MBEDTLS_CIPHER_MODE_CTR */
-
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS )
- {
- if( ctx->unprocessed_len > 0 ) {
- /* We can only process an entire data unit at a time. */
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
- }
-
- ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx,
- ctx->operation, ilen, ctx->iv, input, output );
- if( ret != 0 )
- {
- return( ret );
- }
-
- *olen = ilen;
-
- return( 0 );
- }
-#endif /* MBEDTLS_CIPHER_MODE_XTS */
-
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM )
- {
- if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx,
- ilen, input, output ) ) )
- {
- return( ret );
- }
-
- *olen = ilen;
-
- return( 0 );
- }
-#endif /* MBEDTLS_CIPHER_MODE_STREAM */
-
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
-}
-
-#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
-#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
-/*
- * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len
- */
-static void add_pkcs_padding( unsigned char *output, size_t output_len,
- size_t data_len )
-{
- size_t padding_len = output_len - data_len;
- unsigned char i;
-
- for( i = 0; i < padding_len; i++ )
- output[data_len + i] = (unsigned char) padding_len;
-}
-
-static int get_pkcs_padding( unsigned char *input, size_t input_len,
- size_t *data_len )
-{
- size_t i, pad_idx;
- unsigned char padding_len, bad = 0;
-
- if( NULL == input || NULL == data_len )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- padding_len = input[input_len - 1];
- *data_len = input_len - padding_len;
-
- /* Avoid logical || since it results in a branch */
- bad |= padding_len > input_len;
- bad |= padding_len == 0;
-
- /* The number of bytes checked must be independent of padding_len,
- * so pick input_len, which is usually 8 or 16 (one block) */
- pad_idx = input_len - padding_len;
- for( i = 0; i < input_len; i++ )
- bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx );
-
- return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
-}
-#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
-
-#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
-/*
- * One and zeros padding: fill with 80 00 ... 00
- */
-static void add_one_and_zeros_padding( unsigned char *output,
- size_t output_len, size_t data_len )
-{
- size_t padding_len = output_len - data_len;
- unsigned char i = 0;
-
- output[data_len] = 0x80;
- for( i = 1; i < padding_len; i++ )
- output[data_len + i] = 0x00;
-}
-
-static int get_one_and_zeros_padding( unsigned char *input, size_t input_len,
- size_t *data_len )
-{
- size_t i;
- unsigned char done = 0, prev_done, bad;
-
- if( NULL == input || NULL == data_len )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- bad = 0x80;
- *data_len = 0;
- for( i = input_len; i > 0; i-- )
- {
- prev_done = done;
- done |= ( input[i - 1] != 0 );
- *data_len |= ( i - 1 ) * ( done != prev_done );
- bad ^= input[i - 1] * ( done != prev_done );
- }
-
- return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
-
-}
-#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
-
-#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
-/*
- * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length
- */
-static void add_zeros_and_len_padding( unsigned char *output,
- size_t output_len, size_t data_len )
-{
- size_t padding_len = output_len - data_len;
- unsigned char i = 0;
-
- for( i = 1; i < padding_len; i++ )
- output[data_len + i - 1] = 0x00;
- output[output_len - 1] = (unsigned char) padding_len;
-}
-
-static int get_zeros_and_len_padding( unsigned char *input, size_t input_len,
- size_t *data_len )
-{
- size_t i, pad_idx;
- unsigned char padding_len, bad = 0;
-
- if( NULL == input || NULL == data_len )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- padding_len = input[input_len - 1];
- *data_len = input_len - padding_len;
-
- /* Avoid logical || since it results in a branch */
- bad |= padding_len > input_len;
- bad |= padding_len == 0;
-
- /* The number of bytes checked must be independent of padding_len */
- pad_idx = input_len - padding_len;
- for( i = 0; i < input_len - 1; i++ )
- bad |= input[i] * ( i >= pad_idx );
-
- return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
-}
-#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
-
-#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
-/*
- * Zero padding: fill with 00 ... 00
- */
-static void add_zeros_padding( unsigned char *output,
- size_t output_len, size_t data_len )
-{
- size_t i;
-
- for( i = data_len; i < output_len; i++ )
- output[i] = 0x00;
-}
-
-static int get_zeros_padding( unsigned char *input, size_t input_len,
- size_t *data_len )
-{
- size_t i;
- unsigned char done = 0, prev_done;
-
- if( NULL == input || NULL == data_len )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- *data_len = 0;
- for( i = input_len; i > 0; i-- )
- {
- prev_done = done;
- done |= ( input[i-1] != 0 );
- *data_len |= i * ( done != prev_done );
- }
-
- return( 0 );
-}
-#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
-
-/*
- * No padding: don't pad :)
- *
- * There is no add_padding function (check for NULL in mbedtls_cipher_finish)
- * but a trivial get_padding function
- */
-static int get_no_padding( unsigned char *input, size_t input_len,
- size_t *data_len )
-{
- if( NULL == input || NULL == data_len )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- *data_len = input_len;
-
- return( 0 );
-}
-#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
-
-int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
- unsigned char *output, size_t *olen )
-{
- CIPHER_VALIDATE_RET( ctx != NULL );
- CIPHER_VALIDATE_RET( output != NULL );
- CIPHER_VALIDATE_RET( olen != NULL );
- if( ctx->cipher_info == NULL )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if( ctx->psa_enabled == 1 )
- {
- /* While PSA Crypto has an API for multipart
- * operations, we currently don't make it
- * accessible through the cipher layer. */
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
- }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
- *olen = 0;
-
- if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
- MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
- MBEDTLS_MODE_CTR == ctx->cipher_info->mode ||
- MBEDTLS_MODE_GCM == ctx->cipher_info->mode ||
- MBEDTLS_MODE_XTS == ctx->cipher_info->mode ||
- MBEDTLS_MODE_STREAM == ctx->cipher_info->mode )
- {
- return( 0 );
- }
-
- if ( ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) ||
- ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) )
- {
- return( 0 );
- }
-
- if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode )
- {
- if( ctx->unprocessed_len != 0 )
- return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
-
- return( 0 );
- }
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode )
- {
- int ret = 0;
-
- if( MBEDTLS_ENCRYPT == ctx->operation )
- {
- /* check for 'no padding' mode */
- if( NULL == ctx->add_padding )
- {
- if( 0 != ctx->unprocessed_len )
- return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
-
- return( 0 );
- }
-
- ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ),
- ctx->unprocessed_len );
- }
- else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len )
- {
- /*
- * For decrypt operations, expect a full block,
- * or an empty block if no padding
- */
- if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len )
- return( 0 );
-
- return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
- }
-
- /* cipher block */
- if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
- ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv,
- ctx->unprocessed_data, output ) ) )
- {
- return( ret );
- }
-
- /* Set output size for decryption */
- if( MBEDTLS_DECRYPT == ctx->operation )
- return( ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
- olen ) );
-
- /* Set output size for encryption */
- *olen = mbedtls_cipher_get_block_size( ctx );
- return( 0 );
- }
-#else
- ((void) output);
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
-}
-
-#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
-int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
- mbedtls_cipher_padding_t mode )
-{
- CIPHER_VALIDATE_RET( ctx != NULL );
-
- if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
- {
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if( ctx->psa_enabled == 1 )
- {
- /* While PSA Crypto knows about CBC padding
- * schemes, we currently don't make them
- * accessible through the cipher layer. */
- if( mode != MBEDTLS_PADDING_NONE )
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
-
- return( 0 );
- }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
- switch( mode )
- {
-#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
- case MBEDTLS_PADDING_PKCS7:
- ctx->add_padding = add_pkcs_padding;
- ctx->get_padding = get_pkcs_padding;
- break;
-#endif
-#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
- case MBEDTLS_PADDING_ONE_AND_ZEROS:
- ctx->add_padding = add_one_and_zeros_padding;
- ctx->get_padding = get_one_and_zeros_padding;
- break;
-#endif
-#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
- case MBEDTLS_PADDING_ZEROS_AND_LEN:
- ctx->add_padding = add_zeros_and_len_padding;
- ctx->get_padding = get_zeros_and_len_padding;
- break;
-#endif
-#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
- case MBEDTLS_PADDING_ZEROS:
- ctx->add_padding = add_zeros_padding;
- ctx->get_padding = get_zeros_padding;
- break;
-#endif
- case MBEDTLS_PADDING_NONE:
- ctx->add_padding = NULL;
- ctx->get_padding = get_no_padding;
- break;
-
- default:
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
- }
-
- return( 0 );
-}
-#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
-
-#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
-int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
- unsigned char *tag, size_t tag_len )
-{
- CIPHER_VALIDATE_RET( ctx != NULL );
- CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
- if( ctx->cipher_info == NULL )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- if( MBEDTLS_ENCRYPT != ctx->operation )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if( ctx->psa_enabled == 1 )
- {
- /* While PSA Crypto has an API for multipart
- * operations, we currently don't make it
- * accessible through the cipher layer. */
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
-
- return( 0 );
- }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-#if defined(MBEDTLS_GCM_C)
- if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
- return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
- tag, tag_len ) );
-#endif
-
-#if defined(MBEDTLS_CHACHAPOLY_C)
- if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
- {
- /* Don't allow truncated MAC for Poly1305 */
- if ( tag_len != 16U )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- return( mbedtls_chachapoly_finish(
- (mbedtls_chachapoly_context*) ctx->cipher_ctx, tag ) );
- }
-#endif
-
- return( 0 );
-}
-
-int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
- const unsigned char *tag, size_t tag_len )
-{
- unsigned char check_tag[16];
- int ret;
-
- CIPHER_VALIDATE_RET( ctx != NULL );
- CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
- if( ctx->cipher_info == NULL )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- if( MBEDTLS_DECRYPT != ctx->operation )
- {
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if( ctx->psa_enabled == 1 )
- {
- /* While PSA Crypto has an API for multipart
- * operations, we currently don't make it
- * accessible through the cipher layer. */
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
- }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-#if defined(MBEDTLS_GCM_C)
- if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
- {
- if( tag_len > sizeof( check_tag ) )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- if( 0 != ( ret = mbedtls_gcm_finish(
- (mbedtls_gcm_context *) ctx->cipher_ctx,
- check_tag, tag_len ) ) )
- {
- return( ret );
- }
-
- /* Check the tag in "constant-time" */
- if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
- return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
-
- return( 0 );
- }
-#endif /* MBEDTLS_GCM_C */
-
-#if defined(MBEDTLS_CHACHAPOLY_C)
- if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
- {
- /* Don't allow truncated MAC for Poly1305 */
- if ( tag_len != sizeof( check_tag ) )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- ret = mbedtls_chachapoly_finish(
- (mbedtls_chachapoly_context*) ctx->cipher_ctx, check_tag );
- if ( ret != 0 )
- {
- return( ret );
- }
-
- /* Check the tag in "constant-time" */
- if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
- return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
-
- return( 0 );
- }
-#endif /* MBEDTLS_CHACHAPOLY_C */
-
- return( 0 );
-}
-#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
-
-/*
- * Packet-oriented wrapper for non-AEAD modes
- */
-int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
- const unsigned char *iv, size_t iv_len,
- const unsigned char *input, size_t ilen,
- unsigned char *output, size_t *olen )
-{
- int ret;
- size_t finish_olen;
-
- CIPHER_VALIDATE_RET( ctx != NULL );
- CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
- CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
- CIPHER_VALIDATE_RET( output != NULL );
- CIPHER_VALIDATE_RET( olen != NULL );
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if( ctx->psa_enabled == 1 )
- {
- /* As in the non-PSA case, we don't check that
- * a key has been set. If not, the key slot will
- * still be in its default state of 0, which is
- * guaranteed to be invalid, hence the PSA-call
- * below will gracefully fail. */
- mbedtls_cipher_context_psa * const cipher_psa =
- (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
-
- psa_status_t status;
- psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT;
- size_t part_len;
-
- if( ctx->operation == MBEDTLS_DECRYPT )
- {
- status = psa_cipher_decrypt_setup( &cipher_op,
- cipher_psa->slot,
- cipher_psa->alg );
- }
- else if( ctx->operation == MBEDTLS_ENCRYPT )
- {
- status = psa_cipher_encrypt_setup( &cipher_op,
- cipher_psa->slot,
- cipher_psa->alg );
- }
- else
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- /* In the following, we can immediately return on an error,
- * because the PSA Crypto API guarantees that cipher operations
- * are terminated by unsuccessful calls to psa_cipher_update(),
- * and by any call to psa_cipher_finish(). */
- if( status != PSA_SUCCESS )
- return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
-
- status = psa_cipher_set_iv( &cipher_op, iv, iv_len );
- if( status != PSA_SUCCESS )
- return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
-
- status = psa_cipher_update( &cipher_op,
- input, ilen,
- output, ilen, olen );
- if( status != PSA_SUCCESS )
- return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
-
- status = psa_cipher_finish( &cipher_op,
- output + *olen, ilen - *olen,
- &part_len );
- if( status != PSA_SUCCESS )
- return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
-
- *olen += part_len;
- return( 0 );
- }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
- if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
- return( ret );
-
- if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 )
- return( ret );
-
- if( ( ret = mbedtls_cipher_update( ctx, input, ilen,
- output, olen ) ) != 0 )
- return( ret );
-
- if( ( ret = mbedtls_cipher_finish( ctx, output + *olen,
- &finish_olen ) ) != 0 )
- return( ret );
-
- *olen += finish_olen;
-
- return( 0 );
-}
-
-#if defined(MBEDTLS_CIPHER_MODE_AEAD)
-/*
- * Packet-oriented encryption for AEAD modes
- */
-int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
- const unsigned char *iv, size_t iv_len,
- const unsigned char *ad, size_t ad_len,
- const unsigned char *input, size_t ilen,
- unsigned char *output, size_t *olen,
- unsigned char *tag, size_t tag_len )
-{
- CIPHER_VALIDATE_RET( ctx != NULL );
- CIPHER_VALIDATE_RET( iv != NULL );
- CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
- CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
- CIPHER_VALIDATE_RET( output != NULL );
- CIPHER_VALIDATE_RET( olen != NULL );
- CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if( ctx->psa_enabled == 1 )
- {
- /* As in the non-PSA case, we don't check that
- * a key has been set. If not, the key slot will
- * still be in its default state of 0, which is
- * guaranteed to be invalid, hence the PSA-call
- * below will gracefully fail. */
- mbedtls_cipher_context_psa * const cipher_psa =
- (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
-
- psa_status_t status;
-
- /* PSA Crypto API always writes the authentication tag
- * at the end of the encrypted message. */
- if( tag != output + ilen )
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
-
- status = psa_aead_encrypt( cipher_psa->slot,
- cipher_psa->alg,
- iv, iv_len,
- ad, ad_len,
- input, ilen,
- output, ilen + tag_len, olen );
- if( status != PSA_SUCCESS )
- return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
-
- *olen -= tag_len;
- return( 0 );
- }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-#if defined(MBEDTLS_GCM_C)
- if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
- {
- *olen = ilen;
- return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT,
- ilen, iv, iv_len, ad, ad_len,
- input, output, tag_len, tag ) );
- }
-#endif /* MBEDTLS_GCM_C */
-#if defined(MBEDTLS_CCM_C)
- if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
- {
- *olen = ilen;
- return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen,
- iv, iv_len, ad, ad_len, input, output,
- tag, tag_len ) );
- }
-#endif /* MBEDTLS_CCM_C */
-#if defined(MBEDTLS_CHACHAPOLY_C)
- if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
- {
- /* ChachaPoly has fixed length nonce and MAC (tag) */
- if ( ( iv_len != ctx->cipher_info->iv_size ) ||
- ( tag_len != 16U ) )
- {
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
-
- *olen = ilen;
- return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx,
- ilen, iv, ad, ad_len, input, output, tag ) );
- }
-#endif /* MBEDTLS_CHACHAPOLY_C */
-#if defined(MBEDTLS_NIST_KW_C)
- if( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
- MBEDTLS_MODE_KWP == ctx->cipher_info->mode )
- {
- mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
- MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
-
- /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */
- if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
- {
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
-
- return( mbedtls_nist_kw_wrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) );
- }
-#endif /* MBEDTLS_NIST_KW_C */
-
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
-}
-
-/*
- * Packet-oriented decryption for AEAD modes
- */
-int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
- const unsigned char *iv, size_t iv_len,
- const unsigned char *ad, size_t ad_len,
- const unsigned char *input, size_t ilen,
- unsigned char *output, size_t *olen,
- const unsigned char *tag, size_t tag_len )
-{
- CIPHER_VALIDATE_RET( ctx != NULL );
- CIPHER_VALIDATE_RET( iv != NULL );
- CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
- CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
- CIPHER_VALIDATE_RET( output != NULL );
- CIPHER_VALIDATE_RET( olen != NULL );
- CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- if( ctx->psa_enabled == 1 )
- {
- /* As in the non-PSA case, we don't check that
- * a key has been set. If not, the key slot will
- * still be in its default state of 0, which is
- * guaranteed to be invalid, hence the PSA-call
- * below will gracefully fail. */
- mbedtls_cipher_context_psa * const cipher_psa =
- (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
-
- psa_status_t status;
-
- /* PSA Crypto API always writes the authentication tag
- * at the end of the encrypted message. */
- if( tag != input + ilen )
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
-
- status = psa_aead_decrypt( cipher_psa->slot,
- cipher_psa->alg,
- iv, iv_len,
- ad, ad_len,
- input, ilen + tag_len,
- output, ilen, olen );
- if( status == PSA_ERROR_INVALID_SIGNATURE )
- return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
- else if( status != PSA_SUCCESS )
- return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
-
- return( 0 );
- }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-#if defined(MBEDTLS_GCM_C)
- if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
- {
- int ret;
-
- *olen = ilen;
- ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen,
- iv, iv_len, ad, ad_len,
- tag, tag_len, input, output );
-
- if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED )
- ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
-
- return( ret );
- }
-#endif /* MBEDTLS_GCM_C */
-#if defined(MBEDTLS_CCM_C)
- if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
- {
- int ret;
-
- *olen = ilen;
- ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen,
- iv, iv_len, ad, ad_len,
- input, output, tag, tag_len );
-
- if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED )
- ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
-
- return( ret );
- }
-#endif /* MBEDTLS_CCM_C */
-#if defined(MBEDTLS_CHACHAPOLY_C)
- if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
- {
- int ret;
-
- /* ChachaPoly has fixed length nonce and MAC (tag) */
- if ( ( iv_len != ctx->cipher_info->iv_size ) ||
- ( tag_len != 16U ) )
- {
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
-
- *olen = ilen;
- ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen,
- iv, ad, ad_len, tag, input, output );
-
- if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED )
- ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
-
- return( ret );
- }
-#endif /* MBEDTLS_CHACHAPOLY_C */
-#if defined(MBEDTLS_NIST_KW_C)
- if( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
- MBEDTLS_MODE_KWP == ctx->cipher_info->mode )
- {
- mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
- MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
-
- /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */
- if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
- {
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
-
- return( mbedtls_nist_kw_unwrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) );
- }
-#endif /* MBEDTLS_NIST_KW_C */
-
- return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
-}
-#endif /* MBEDTLS_CIPHER_MODE_AEAD */
-
-#endif /* MBEDTLS_CIPHER_C */
diff --git a/assets/templates/blackpill/Src/cipher.h b/assets/templates/blackpill/Src/cipher.h
deleted file mode 100644
index ea00703..0000000
--- a/assets/templates/blackpill/Src/cipher.h
+++ /dev/null
@@ -1,926 +0,0 @@
-/**
- * \file cipher.h
- *
- * \brief This file contains an abstraction interface for use with the cipher
- * primitives provided by the library. It provides a common interface to all of
- * the available cipher operations.
- *
- * \author Adriaan de Jong
- */
-/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
- */
-
-#ifndef MBEDTLS_CIPHER_H
-#define MBEDTLS_CIPHER_H
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#include
-#include "platform_util.h"
-
-#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
-#define MBEDTLS_CIPHER_MODE_AEAD
-#endif
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-#define MBEDTLS_CIPHER_MODE_WITH_PADDING
-#endif
-
-#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \
- defined(MBEDTLS_CHACHA20_C)
-#define MBEDTLS_CIPHER_MODE_STREAM
-#endif
-
-#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
- !defined(inline) && !defined(__cplusplus)
-#define inline __inline
-#endif
-
-#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */
-#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters. */
-#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */
-#define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */
-#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */
-#define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */
-#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 /**< The context is invalid. For example, because it was freed. */
-
-/* MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED -0x6400 /**< Cipher hardware accelerator failed. */
-
-#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length. */
-#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length. */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief Supported cipher types.
- *
- * \warning RC4 and DES are considered weak ciphers and their use
- * constitutes a security risk. Arm recommends considering stronger
- * ciphers instead.
- */
-typedef enum {
- MBEDTLS_CIPHER_ID_NONE = 0, /**< Placeholder to mark the end of cipher ID lists. */
- MBEDTLS_CIPHER_ID_NULL, /**< The identity cipher, treated as a stream cipher. */
- MBEDTLS_CIPHER_ID_AES, /**< The AES cipher. */
- MBEDTLS_CIPHER_ID_DES, /**< The DES cipher. */
- MBEDTLS_CIPHER_ID_3DES, /**< The Triple DES cipher. */
- MBEDTLS_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */
- MBEDTLS_CIPHER_ID_BLOWFISH, /**< The Blowfish cipher. */
- MBEDTLS_CIPHER_ID_ARC4, /**< The RC4 cipher. */
- MBEDTLS_CIPHER_ID_ARIA, /**< The Aria cipher. */
- MBEDTLS_CIPHER_ID_CHACHA20, /**< The ChaCha20 cipher. */
-} mbedtls_cipher_id_t;
-
-/**
- * \brief Supported {cipher type, cipher mode} pairs.
- *
- * \warning RC4 and DES are considered weak ciphers and their use
- * constitutes a security risk. Arm recommends considering stronger
- * ciphers instead.
- */
-typedef enum {
- MBEDTLS_CIPHER_NONE = 0, /**< Placeholder to mark the end of cipher-pair lists. */
- MBEDTLS_CIPHER_NULL, /**< The identity stream cipher. */
- MBEDTLS_CIPHER_AES_128_ECB, /**< AES cipher with 128-bit ECB mode. */
- MBEDTLS_CIPHER_AES_192_ECB, /**< AES cipher with 192-bit ECB mode. */
- MBEDTLS_CIPHER_AES_256_ECB, /**< AES cipher with 256-bit ECB mode. */
- MBEDTLS_CIPHER_AES_128_CBC, /**< AES cipher with 128-bit CBC mode. */
- MBEDTLS_CIPHER_AES_192_CBC, /**< AES cipher with 192-bit CBC mode. */
- MBEDTLS_CIPHER_AES_256_CBC, /**< AES cipher with 256-bit CBC mode. */
- MBEDTLS_CIPHER_AES_128_CFB128, /**< AES cipher with 128-bit CFB128 mode. */
- MBEDTLS_CIPHER_AES_192_CFB128, /**< AES cipher with 192-bit CFB128 mode. */
- MBEDTLS_CIPHER_AES_256_CFB128, /**< AES cipher with 256-bit CFB128 mode. */
- MBEDTLS_CIPHER_AES_128_CTR, /**< AES cipher with 128-bit CTR mode. */
- MBEDTLS_CIPHER_AES_192_CTR, /**< AES cipher with 192-bit CTR mode. */
- MBEDTLS_CIPHER_AES_256_CTR, /**< AES cipher with 256-bit CTR mode. */
- MBEDTLS_CIPHER_AES_128_GCM, /**< AES cipher with 128-bit GCM mode. */
- MBEDTLS_CIPHER_AES_192_GCM, /**< AES cipher with 192-bit GCM mode. */
- MBEDTLS_CIPHER_AES_256_GCM, /**< AES cipher with 256-bit GCM mode. */
- MBEDTLS_CIPHER_CAMELLIA_128_ECB, /**< Camellia cipher with 128-bit ECB mode. */
- MBEDTLS_CIPHER_CAMELLIA_192_ECB, /**< Camellia cipher with 192-bit ECB mode. */
- MBEDTLS_CIPHER_CAMELLIA_256_ECB, /**< Camellia cipher with 256-bit ECB mode. */
- MBEDTLS_CIPHER_CAMELLIA_128_CBC, /**< Camellia cipher with 128-bit CBC mode. */
- MBEDTLS_CIPHER_CAMELLIA_192_CBC, /**< Camellia cipher with 192-bit CBC mode. */
- MBEDTLS_CIPHER_CAMELLIA_256_CBC, /**< Camellia cipher with 256-bit CBC mode. */
- MBEDTLS_CIPHER_CAMELLIA_128_CFB128, /**< Camellia cipher with 128-bit CFB128 mode. */
- MBEDTLS_CIPHER_CAMELLIA_192_CFB128, /**< Camellia cipher with 192-bit CFB128 mode. */
- MBEDTLS_CIPHER_CAMELLIA_256_CFB128, /**< Camellia cipher with 256-bit CFB128 mode. */
- MBEDTLS_CIPHER_CAMELLIA_128_CTR, /**< Camellia cipher with 128-bit CTR mode. */
- MBEDTLS_CIPHER_CAMELLIA_192_CTR, /**< Camellia cipher with 192-bit CTR mode. */
- MBEDTLS_CIPHER_CAMELLIA_256_CTR, /**< Camellia cipher with 256-bit CTR mode. */
- MBEDTLS_CIPHER_CAMELLIA_128_GCM, /**< Camellia cipher with 128-bit GCM mode. */
- MBEDTLS_CIPHER_CAMELLIA_192_GCM, /**< Camellia cipher with 192-bit GCM mode. */
- MBEDTLS_CIPHER_CAMELLIA_256_GCM, /**< Camellia cipher with 256-bit GCM mode. */
- MBEDTLS_CIPHER_DES_ECB, /**< DES cipher with ECB mode. */
- MBEDTLS_CIPHER_DES_CBC, /**< DES cipher with CBC mode. */
- MBEDTLS_CIPHER_DES_EDE_ECB, /**< DES cipher with EDE ECB mode. */
- MBEDTLS_CIPHER_DES_EDE_CBC, /**< DES cipher with EDE CBC mode. */
- MBEDTLS_CIPHER_DES_EDE3_ECB, /**< DES cipher with EDE3 ECB mode. */
- MBEDTLS_CIPHER_DES_EDE3_CBC, /**< DES cipher with EDE3 CBC mode. */
- MBEDTLS_CIPHER_BLOWFISH_ECB, /**< Blowfish cipher with ECB mode. */
- MBEDTLS_CIPHER_BLOWFISH_CBC, /**< Blowfish cipher with CBC mode. */
- MBEDTLS_CIPHER_BLOWFISH_CFB64, /**< Blowfish cipher with CFB64 mode. */
- MBEDTLS_CIPHER_BLOWFISH_CTR, /**< Blowfish cipher with CTR mode. */
- MBEDTLS_CIPHER_ARC4_128, /**< RC4 cipher with 128-bit mode. */
- MBEDTLS_CIPHER_AES_128_CCM, /**< AES cipher with 128-bit CCM mode. */
- MBEDTLS_CIPHER_AES_192_CCM, /**< AES cipher with 192-bit CCM mode. */
- MBEDTLS_CIPHER_AES_256_CCM, /**< AES cipher with 256-bit CCM mode. */
- MBEDTLS_CIPHER_CAMELLIA_128_CCM, /**< Camellia cipher with 128-bit CCM mode. */
- MBEDTLS_CIPHER_CAMELLIA_192_CCM, /**< Camellia cipher with 192-bit CCM mode. */
- MBEDTLS_CIPHER_CAMELLIA_256_CCM, /**< Camellia cipher with 256-bit CCM mode. */
- MBEDTLS_CIPHER_ARIA_128_ECB, /**< Aria cipher with 128-bit key and ECB mode. */
- MBEDTLS_CIPHER_ARIA_192_ECB, /**< Aria cipher with 192-bit key and ECB mode. */
- MBEDTLS_CIPHER_ARIA_256_ECB, /**< Aria cipher with 256-bit key and ECB mode. */
- MBEDTLS_CIPHER_ARIA_128_CBC, /**< Aria cipher with 128-bit key and CBC mode. */
- MBEDTLS_CIPHER_ARIA_192_CBC, /**< Aria cipher with 192-bit key and CBC mode. */
- MBEDTLS_CIPHER_ARIA_256_CBC, /**< Aria cipher with 256-bit key and CBC mode. */
- MBEDTLS_CIPHER_ARIA_128_CFB128, /**< Aria cipher with 128-bit key and CFB-128 mode. */
- MBEDTLS_CIPHER_ARIA_192_CFB128, /**< Aria cipher with 192-bit key and CFB-128 mode. */
- MBEDTLS_CIPHER_ARIA_256_CFB128, /**< Aria cipher with 256-bit key and CFB-128 mode. */
- MBEDTLS_CIPHER_ARIA_128_CTR, /**< Aria cipher with 128-bit key and CTR mode. */
- MBEDTLS_CIPHER_ARIA_192_CTR, /**< Aria cipher with 192-bit key and CTR mode. */
- MBEDTLS_CIPHER_ARIA_256_CTR, /**< Aria cipher with 256-bit key and CTR mode. */
- MBEDTLS_CIPHER_ARIA_128_GCM, /**< Aria cipher with 128-bit key and GCM mode. */
- MBEDTLS_CIPHER_ARIA_192_GCM, /**< Aria cipher with 192-bit key and GCM mode. */
- MBEDTLS_CIPHER_ARIA_256_GCM, /**< Aria cipher with 256-bit key and GCM mode. */
- MBEDTLS_CIPHER_ARIA_128_CCM, /**< Aria cipher with 128-bit key and CCM mode. */
- MBEDTLS_CIPHER_ARIA_192_CCM, /**< Aria cipher with 192-bit key and CCM mode. */
- MBEDTLS_CIPHER_ARIA_256_CCM, /**< Aria cipher with 256-bit key and CCM mode. */
- MBEDTLS_CIPHER_AES_128_OFB, /**< AES 128-bit cipher in OFB mode. */
- MBEDTLS_CIPHER_AES_192_OFB, /**< AES 192-bit cipher in OFB mode. */
- MBEDTLS_CIPHER_AES_256_OFB, /**< AES 256-bit cipher in OFB mode. */
- MBEDTLS_CIPHER_AES_128_XTS, /**< AES 128-bit cipher in XTS block mode. */
- MBEDTLS_CIPHER_AES_256_XTS, /**< AES 256-bit cipher in XTS block mode. */
- MBEDTLS_CIPHER_CHACHA20, /**< ChaCha20 stream cipher. */
- MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< ChaCha20-Poly1305 AEAD cipher. */
- MBEDTLS_CIPHER_AES_128_KW, /**< AES cipher with 128-bit NIST KW mode. */
- MBEDTLS_CIPHER_AES_192_KW, /**< AES cipher with 192-bit NIST KW mode. */
- MBEDTLS_CIPHER_AES_256_KW, /**< AES cipher with 256-bit NIST KW mode. */
- MBEDTLS_CIPHER_AES_128_KWP, /**< AES cipher with 128-bit NIST KWP mode. */
- MBEDTLS_CIPHER_AES_192_KWP, /**< AES cipher with 192-bit NIST KWP mode. */
- MBEDTLS_CIPHER_AES_256_KWP, /**< AES cipher with 256-bit NIST KWP mode. */
-} mbedtls_cipher_type_t;
-
-/** Supported cipher modes. */
-typedef enum {
- MBEDTLS_MODE_NONE = 0, /**< None. */
- MBEDTLS_MODE_ECB, /**< The ECB cipher mode. */
- MBEDTLS_MODE_CBC, /**< The CBC cipher mode. */
- MBEDTLS_MODE_CFB, /**< The CFB cipher mode. */
- MBEDTLS_MODE_OFB, /**< The OFB cipher mode. */
- MBEDTLS_MODE_CTR, /**< The CTR cipher mode. */
- MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */
- MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */
- MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */
- MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */
- MBEDTLS_MODE_CHACHAPOLY, /**< The ChaCha-Poly cipher mode. */
- MBEDTLS_MODE_KW, /**< The SP800-38F KW mode */
- MBEDTLS_MODE_KWP, /**< The SP800-38F KWP mode */
-} mbedtls_cipher_mode_t;
-
-/** Supported cipher padding types. */
-typedef enum {
- MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default). */
- MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding. */
- MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding. */
- MBEDTLS_PADDING_ZEROS, /**< Zero padding (not reversible). */
- MBEDTLS_PADDING_NONE, /**< Never pad (full blocks only). */
-} mbedtls_cipher_padding_t;
-
-/** Type of operation. */
-typedef enum {
- MBEDTLS_OPERATION_NONE = -1,
- MBEDTLS_DECRYPT = 0,
- MBEDTLS_ENCRYPT,
-} mbedtls_operation_t;
-
-enum {
- /** Undefined key length. */
- MBEDTLS_KEY_LENGTH_NONE = 0,
- /** Key length, in bits (including parity), for DES keys. */
- MBEDTLS_KEY_LENGTH_DES = 64,
- /** Key length in bits, including parity, for DES in two-key EDE. */
- MBEDTLS_KEY_LENGTH_DES_EDE = 128,
- /** Key length in bits, including parity, for DES in three-key EDE. */
- MBEDTLS_KEY_LENGTH_DES_EDE3 = 192,
-};
-
-/** Maximum length of any IV, in Bytes. */
-#define MBEDTLS_MAX_IV_LENGTH 16
-/** Maximum block size of any cipher, in Bytes. */
-#define MBEDTLS_MAX_BLOCK_LENGTH 16
-
-/**
- * Base cipher information (opaque struct).
- */
-typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t;
-
-/**
- * CMAC context (opaque struct).
- */
-typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t;
-
-/**
- * Cipher information. Allows calling cipher functions
- * in a generic way.
- */
-typedef struct mbedtls_cipher_info_t
-{
- /** Full cipher identifier. For example,
- * MBEDTLS_CIPHER_AES_256_CBC.
- */
- mbedtls_cipher_type_t type;
-
- /** The cipher mode. For example, MBEDTLS_MODE_CBC. */
- mbedtls_cipher_mode_t mode;
-
- /** The cipher key length, in bits. This is the
- * default length for variable sized ciphers.
- * Includes parity bits for ciphers like DES.
- */
- unsigned int key_bitlen;
-
- /** Name of the cipher. */
- const char * name;
-
- /** IV or nonce size, in Bytes.
- * For ciphers that accept variable IV sizes,
- * this is the recommended size.
- */
- unsigned int iv_size;
-
- /** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and
- * MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the
- * cipher supports variable IV or variable key sizes, respectively.
- */
- int flags;
-
- /** The block size, in Bytes. */
- unsigned int block_size;
-
- /** Struct for base cipher information and functions. */
- const mbedtls_cipher_base_t *base;
-
-} mbedtls_cipher_info_t;
-
-/**
- * Generic cipher context.
- */
-typedef struct mbedtls_cipher_context_t
-{
- /** Information about the associated cipher. */
- const mbedtls_cipher_info_t *cipher_info;
-
- /** Key length to use. */
- int key_bitlen;
-
- /** Operation that the key of the context has been
- * initialized for.
- */
- mbedtls_operation_t operation;
-
-#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
- /** Padding functions to use, if relevant for
- * the specific cipher mode.
- */
- void (*add_padding)( unsigned char *output, size_t olen, size_t data_len );
- int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len );
-#endif
-
- /** Buffer for input that has not been processed yet. */
- unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH];
-
- /** Number of Bytes that have not been processed yet. */
- size_t unprocessed_len;
-
- /** Current IV or NONCE_COUNTER for CTR-mode, data unit (or sector) number
- * for XTS-mode. */
- unsigned char iv[MBEDTLS_MAX_IV_LENGTH];
-
- /** IV size in Bytes, for ciphers with variable-length IVs. */
- size_t iv_size;
-
- /** The cipher-specific context. */
- void *cipher_ctx;
-
-#if defined(MBEDTLS_CMAC_C)
- /** CMAC-specific context. */
- mbedtls_cmac_context_t *cmac_ctx;
-#endif
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
- /** Indicates whether the cipher operations should be performed
- * by Mbed TLS' own crypto library or an external implementation
- * of the PSA Crypto API.
- * This is unset if the cipher context was established through
- * mbedtls_cipher_setup(), and set if it was established through
- * mbedtls_cipher_setup_psa().
- */
- unsigned char psa_enabled;
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-} mbedtls_cipher_context_t;
-
-/**
- * \brief This function retrieves the list of ciphers supported
- * by the generic cipher module.
- *
- * For any cipher identifier in the returned list, you can
- * obtain the corresponding generic cipher information structure
- * via mbedtls_cipher_info_from_type(), which can then be used
- * to prepare a cipher context via mbedtls_cipher_setup().
- *
- *
- * \return A statically-allocated array of cipher identifiers
- * of type cipher_type_t. The last entry is zero.
- */
-const int *mbedtls_cipher_list( void );
-
-/**
- * \brief This function retrieves the cipher-information
- * structure associated with the given cipher name.
- *
- * \param cipher_name Name of the cipher to search for. This must not be
- * \c NULL.
- *
- * \return The cipher information structure associated with the
- * given \p cipher_name.
- * \return \c NULL if the associated cipher information is not found.
- */
-const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name );
-
-/**
- * \brief This function retrieves the cipher-information
- * structure associated with the given cipher type.
- *
- * \param cipher_type Type of the cipher to search for.
- *
- * \return The cipher information structure associated with the
- * given \p cipher_type.
- * \return \c NULL if the associated cipher information is not found.
- */
-const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type );
-
-/**
- * \brief This function retrieves the cipher-information
- * structure associated with the given cipher ID,
- * key size and mode.
- *
- * \param cipher_id The ID of the cipher to search for. For example,
- * #MBEDTLS_CIPHER_ID_AES.
- * \param key_bitlen The length of the key in bits.
- * \param mode The cipher mode. For example, #MBEDTLS_MODE_CBC.
- *
- * \return The cipher information structure associated with the
- * given \p cipher_id.
- * \return \c NULL if the associated cipher information is not found.
- */
-const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
- int key_bitlen,
- const mbedtls_cipher_mode_t mode );
-
-/**
- * \brief This function initializes a \p cipher_context as NONE.
- *
- * \param ctx The context to be initialized. This must not be \c NULL.
- */
-void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
-
-/**
- * \brief This function frees and clears the cipher-specific
- * context of \p ctx. Freeing \p ctx itself remains the
- * responsibility of the caller.
- *
- * \param ctx The context to be freed. If this is \c NULL, the
- * function has no effect, otherwise this must point to an
- * initialized context.
- */
-void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx );
-
-
-/**
- * \brief This function initializes a cipher context for
- * use with the given cipher primitive.
- *
- * \param ctx The context to initialize. This must be initialized.
- * \param cipher_info The cipher to use.
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
- * parameter-verification failure.
- * \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
- * cipher-specific context fails.
- *
- * \internal Currently, the function also clears the structure.
- * In future versions, the caller will be required to call
- * mbedtls_cipher_init() on the structure first.
- */
-int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
- const mbedtls_cipher_info_t *cipher_info );
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-/**
- * \brief This function initializes a cipher context for
- * PSA-based use with the given cipher primitive.
- *
- * \note See #MBEDTLS_USE_PSA_CRYPTO for information on PSA.
- *
- * \param ctx The context to initialize. May not be \c NULL.
- * \param cipher_info The cipher to use.
- * \param taglen For AEAD ciphers, the length in bytes of the
- * authentication tag to use. Subsequent uses of
- * mbedtls_cipher_auth_encrypt() or
- * mbedtls_cipher_auth_decrypt() must provide
- * the same tag length.
- * For non-AEAD ciphers, the value must be \c 0.
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
- * parameter-verification failure.
- * \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
- * cipher-specific context fails.
- */
-int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx,
- const mbedtls_cipher_info_t *cipher_info,
- size_t taglen );
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-/**
- * \brief This function returns the block size of the given cipher.
- *
- * \param ctx The context of the cipher. This must be initialized.
- *
- * \return The block size of the underlying cipher.
- * \return \c 0 if \p ctx has not been initialized.
- */
-static inline unsigned int mbedtls_cipher_get_block_size(
- const mbedtls_cipher_context_t *ctx )
-{
- MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
- if( ctx->cipher_info == NULL )
- return 0;
-
- return ctx->cipher_info->block_size;
-}
-
-/**
- * \brief This function returns the mode of operation for
- * the cipher. For example, MBEDTLS_MODE_CBC.
- *
- * \param ctx The context of the cipher. This must be initialized.
- *
- * \return The mode of operation.
- * \return #MBEDTLS_MODE_NONE if \p ctx has not been initialized.
- */
-static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode(
- const mbedtls_cipher_context_t *ctx )
-{
- MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, MBEDTLS_MODE_NONE );
- if( ctx->cipher_info == NULL )
- return MBEDTLS_MODE_NONE;
-
- return ctx->cipher_info->mode;
-}
-
-/**
- * \brief This function returns the size of the IV or nonce
- * of the cipher, in Bytes.
- *
- * \param ctx The context of the cipher. This must be initialized.
- *
- * \return The recommended IV size if no IV has been set.
- * \return \c 0 for ciphers not using an IV or a nonce.
- * \return The actual size if an IV has been set.
- */
-static inline int mbedtls_cipher_get_iv_size(
- const mbedtls_cipher_context_t *ctx )
-{
- MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
- if( ctx->cipher_info == NULL )
- return 0;
-
- if( ctx->iv_size != 0 )
- return (int) ctx->iv_size;
-
- return (int) ctx->cipher_info->iv_size;
-}
-
-/**
- * \brief This function returns the type of the given cipher.
- *
- * \param ctx The context of the cipher. This must be initialized.
- *
- * \return The type of the cipher.
- * \return #MBEDTLS_CIPHER_NONE if \p ctx has not been initialized.
- */
-static inline mbedtls_cipher_type_t mbedtls_cipher_get_type(
- const mbedtls_cipher_context_t *ctx )
-{
- MBEDTLS_INTERNAL_VALIDATE_RET(
- ctx != NULL, MBEDTLS_CIPHER_NONE );
- if( ctx->cipher_info == NULL )
- return MBEDTLS_CIPHER_NONE;
-
- return ctx->cipher_info->type;
-}
-
-/**
- * \brief This function returns the name of the given cipher
- * as a string.
- *
- * \param ctx The context of the cipher. This must be initialized.
- *
- * \return The name of the cipher.
- * \return NULL if \p ctx has not been not initialized.
- */
-static inline const char *mbedtls_cipher_get_name(
- const mbedtls_cipher_context_t *ctx )
-{
- MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
- if( ctx->cipher_info == NULL )
- return 0;
-
- return ctx->cipher_info->name;
-}
-
-/**
- * \brief This function returns the key length of the cipher.
- *
- * \param ctx The context of the cipher. This must be initialized.
- *
- * \return The key length of the cipher in bits.
- * \return #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been
- * initialized.
- */
-static inline int mbedtls_cipher_get_key_bitlen(
- const mbedtls_cipher_context_t *ctx )
-{
- MBEDTLS_INTERNAL_VALIDATE_RET(
- ctx != NULL, MBEDTLS_KEY_LENGTH_NONE );
- if( ctx->cipher_info == NULL )
- return MBEDTLS_KEY_LENGTH_NONE;
-
- return (int) ctx->cipher_info->key_bitlen;
-}
-
-/**
- * \brief This function returns the operation of the given cipher.
- *
- * \param ctx The context of the cipher. This must be initialized.
- *
- * \return The type of operation: #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
- * \return #MBEDTLS_OPERATION_NONE if \p ctx has not been initialized.
- */
-static inline mbedtls_operation_t mbedtls_cipher_get_operation(
- const mbedtls_cipher_context_t *ctx )
-{
- MBEDTLS_INTERNAL_VALIDATE_RET(
- ctx != NULL, MBEDTLS_OPERATION_NONE );
- if( ctx->cipher_info == NULL )
- return MBEDTLS_OPERATION_NONE;
-
- return ctx->operation;
-}
-
-/**
- * \brief This function sets the key to use with the given context.
- *
- * \param ctx The generic cipher context. This must be initialized and
- * bound to a cipher information structure.
- * \param key The key to use. This must be a readable buffer of at
- * least \p key_bitlen Bits.
- * \param key_bitlen The key length to use, in Bits.
- * \param operation The operation that the key will be used for:
- * #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
- * parameter-verification failure.
- * \return A cipher-specific error code on failure.
- */
-int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
- const unsigned char *key,
- int key_bitlen,
- const mbedtls_operation_t operation );
-
-#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
-/**
- * \brief This function sets the padding mode, for cipher modes
- * that use padding.
- *
- * The default passing mode is PKCS7 padding.
- *
- * \param ctx The generic cipher context. This must be initialized and
- * bound to a cipher information structure.
- * \param mode The padding mode.
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
- * if the selected padding mode is not supported.
- * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode
- * does not support padding.
- */
-int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
- mbedtls_cipher_padding_t mode );
-#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
-
-/**
- * \brief This function sets the initialization vector (IV)
- * or nonce.
- *
- * \note Some ciphers do not use IVs nor nonce. For these
- * ciphers, this function has no effect.
- *
- * \param ctx The generic cipher context. This must be initialized and
- * bound to a cipher information structure.
- * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. This
- * must be a readable buffer of at least \p iv_len Bytes.
- * \param iv_len The IV length for ciphers with variable-size IV.
- * This parameter is discarded by ciphers with fixed-size IV.
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
- * parameter-verification failure.
- */
-int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
- const unsigned char *iv,
- size_t iv_len );
-
-/**
- * \brief This function resets the cipher state.
- *
- * \param ctx The generic cipher context. This must be initialized.
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
- * parameter-verification failure.
- */
-int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx );
-
-#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
-/**
- * \brief This function adds additional data for AEAD ciphers.
- * Currently supported with GCM and ChaCha20+Poly1305.
- * This must be called exactly once, after
- * mbedtls_cipher_reset().
- *
- * \param ctx The generic cipher context. This must be initialized.
- * \param ad The additional data to use. This must be a readable
- * buffer of at least \p ad_len Bytes.
- * \param ad_len The length of \p ad in Bytes.
- *
- * \return \c 0 on success.
- * \return A specific error code on failure.
- */
-int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
- const unsigned char *ad, size_t ad_len );
-#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
-
-/**
- * \brief The generic cipher update function. It encrypts or
- * decrypts using the given cipher context. Writes as
- * many block-sized blocks of data as possible to output.
- * Any data that cannot be written immediately is either
- * added to the next block, or flushed when
- * mbedtls_cipher_finish() is called.
- * Exception: For MBEDTLS_MODE_ECB, expects a single block
- * in size. For example, 16 Bytes for AES.
- *
- * \note If the underlying cipher is used in GCM mode, all calls
- * to this function, except for the last one before
- * mbedtls_cipher_finish(), must have \p ilen as a
- * multiple of the block size of the cipher.
- *
- * \param ctx The generic cipher context. This must be initialized and
- * bound to a key.
- * \param input The buffer holding the input data. This must be a
- * readable buffer of at least \p ilen Bytes.
- * \param ilen The length of the input data.
- * \param output The buffer for the output data. This must be able to
- * hold at least `ilen + block_size`. This must not be the
- * same buffer as \p input.
- * \param olen The length of the output data, to be updated with the
- * actual number of Bytes written. This must not be
- * \c NULL.
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
- * parameter-verification failure.
- * \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an
- * unsupported mode for a cipher.
- * \return A cipher-specific error code on failure.
- */
-int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx,
- const unsigned char *input,
- size_t ilen, unsigned char *output,
- size_t *olen );
-
-/**
- * \brief The generic cipher finalization function. If data still
- * needs to be flushed from an incomplete block, the data
- * contained in it is padded to the size of
- * the last block, and written to the \p output buffer.
- *
- * \param ctx The generic cipher context. This must be initialized and
- * bound to a key.
- * \param output The buffer to write data to. This needs to be a writable
- * buffer of at least \p block_size Bytes.
- * \param olen The length of the data written to the \p output buffer.
- * This may not be \c NULL.
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
- * parameter-verification failure.
- * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
- * expecting a full block but not receiving one.
- * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
- * while decrypting.
- * \return A cipher-specific error code on failure.
- */
-int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
- unsigned char *output, size_t *olen );
-
-#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
-/**
- * \brief This function writes a tag for AEAD ciphers.
- * Currently supported with GCM and ChaCha20+Poly1305.
- * This must be called after mbedtls_cipher_finish().
- *
- * \param ctx The generic cipher context. This must be initialized,
- * bound to a key, and have just completed a cipher
- * operation through mbedtls_cipher_finish() the tag for
- * which should be written.
- * \param tag The buffer to write the tag to. This must be a writable
- * buffer of at least \p tag_len Bytes.
- * \param tag_len The length of the tag to write.
- *
- * \return \c 0 on success.
- * \return A specific error code on failure.
- */
-int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
- unsigned char *tag, size_t tag_len );
-
-/**
- * \brief This function checks the tag for AEAD ciphers.
- * Currently supported with GCM and ChaCha20+Poly1305.
- * This must be called after mbedtls_cipher_finish().
- *
- * \param ctx The generic cipher context. This must be initialized.
- * \param tag The buffer holding the tag. This must be a readable
- * buffer of at least \p tag_len Bytes.
- * \param tag_len The length of the tag to check.
- *
- * \return \c 0 on success.
- * \return A specific error code on failure.
- */
-int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
- const unsigned char *tag, size_t tag_len );
-#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
-
-/**
- * \brief The generic all-in-one encryption/decryption function,
- * for all ciphers except AEAD constructs.
- *
- * \param ctx The generic cipher context. This must be initialized.
- * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
- * This must be a readable buffer of at least \p iv_len
- * Bytes.
- * \param iv_len The IV length for ciphers with variable-size IV.
- * This parameter is discarded by ciphers with fixed-size
- * IV.
- * \param input The buffer holding the input data. This must be a
- * readable buffer of at least \p ilen Bytes.
- * \param ilen The length of the input data in Bytes.
- * \param output The buffer for the output data. This must be able to
- * hold at least `ilen + block_size`. This must not be the
- * same buffer as \p input.
- * \param olen The length of the output data, to be updated with the
- * actual number of Bytes written. This must not be
- * \c NULL.
- *
- * \note Some ciphers do not use IVs nor nonce. For these
- * ciphers, use \p iv = NULL and \p iv_len = 0.
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
- * parameter-verification failure.
- * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
- * expecting a full block but not receiving one.
- * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
- * while decrypting.
- * \return A cipher-specific error code on failure.
- */
-int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
- const unsigned char *iv, size_t iv_len,
- const unsigned char *input, size_t ilen,
- unsigned char *output, size_t *olen );
-
-#if defined(MBEDTLS_CIPHER_MODE_AEAD)
-/**
- * \brief The generic autenticated encryption (AEAD) function.
- *
- * \param ctx The generic cipher context. This must be initialized and
- * bound to a key.
- * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
- * This must be a readable buffer of at least \p iv_len
- * Bytes.
- * \param iv_len The IV length for ciphers with variable-size IV.
- * This parameter is discarded by ciphers with fixed-size IV.
- * \param ad The additional data to authenticate. This must be a
- * readable buffer of at least \p ad_len Bytes.
- * \param ad_len The length of \p ad.
- * \param input The buffer holding the input data. This must be a
- * readable buffer of at least \p ilen Bytes.
- * \param ilen The length of the input data.
- * \param output The buffer for the output data. This must be able to
- * hold at least \p ilen Bytes.
- * \param olen The length of the output data, to be updated with the
- * actual number of Bytes written. This must not be
- * \c NULL.
- * \param tag The buffer for the authentication tag. This must be a
- * writable buffer of at least \p tag_len Bytes.
- * \param tag_len The desired length of the authentication tag.
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
- * parameter-verification failure.
- * \return A cipher-specific error code on failure.
- */
-int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
- const unsigned char *iv, size_t iv_len,
- const unsigned char *ad, size_t ad_len,
- const unsigned char *input, size_t ilen,
- unsigned char *output, size_t *olen,
- unsigned char *tag, size_t tag_len );
-
-/**
- * \brief The generic autenticated decryption (AEAD) function.
- *
- * \note If the data is not authentic, then the output buffer
- * is zeroed out to prevent the unauthentic plaintext being
- * used, making this interface safer.
- *
- * \param ctx The generic cipher context. This must be initialized and
- * and bound to a key.
- * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
- * This must be a readable buffer of at least \p iv_len
- * Bytes.
- * \param iv_len The IV length for ciphers with variable-size IV.
- * This parameter is discarded by ciphers with fixed-size IV.
- * \param ad The additional data to be authenticated. This must be a
- * readable buffer of at least \p ad_len Bytes.
- * \param ad_len The length of \p ad.
- * \param input The buffer holding the input data. This must be a
- * readable buffer of at least \p ilen Bytes.
- * \param ilen The length of the input data.
- * \param output The buffer for the output data.
- * This must be able to hold at least \p ilen Bytes.
- * \param olen The length of the output data, to be updated with the
- * actual number of Bytes written. This must not be
- * \c NULL.
- * \param tag The buffer holding the authentication tag. This must be
- * a readable buffer of at least \p tag_len Bytes.
- * \param tag_len The length of the authentication tag.
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
- * parameter-verification failure.
- * \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic.
- * \return A cipher-specific error code on failure.
- */
-int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
- const unsigned char *iv, size_t iv_len,
- const unsigned char *ad, size_t ad_len,
- const unsigned char *input, size_t ilen,
- unsigned char *output, size_t *olen,
- const unsigned char *tag, size_t tag_len );
-#endif /* MBEDTLS_CIPHER_MODE_AEAD */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* MBEDTLS_CIPHER_H */
diff --git a/assets/templates/blackpill/Src/cipher_internal.h b/assets/templates/blackpill/Src/cipher_internal.h
deleted file mode 100644
index d711339..0000000
--- a/assets/templates/blackpill/Src/cipher_internal.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- * \file cipher_internal.h
- *
- * \brief Cipher wrappers.
- *
- * \author Adriaan de Jong
- */
-/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
-#ifndef MBEDTLS_CIPHER_WRAP_H
-#define MBEDTLS_CIPHER_WRAP_H
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#include "cipher.h"
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-#include "psa/crypto.h"
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Base cipher information. The non-mode specific functions and values.
- */
-struct mbedtls_cipher_base_t
-{
- /** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */
- mbedtls_cipher_id_t cipher;
-
- /** Encrypt using ECB */
- int (*ecb_func)( void *ctx, mbedtls_operation_t mode,
- const unsigned char *input, unsigned char *output );
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- /** Encrypt using CBC */
- int (*cbc_func)( void *ctx, mbedtls_operation_t mode, size_t length,
- unsigned char *iv, const unsigned char *input,
- unsigned char *output );
-#endif
-
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- /** Encrypt using CFB (Full length) */
- int (*cfb_func)( void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off,
- unsigned char *iv, const unsigned char *input,
- unsigned char *output );
-#endif
-
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- /** Encrypt using OFB (Full length) */
- int (*ofb_func)( void *ctx, size_t length, size_t *iv_off,
- unsigned char *iv,
- const unsigned char *input,
- unsigned char *output );
-#endif
-
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- /** Encrypt using CTR */
- int (*ctr_func)( void *ctx, size_t length, size_t *nc_off,
- unsigned char *nonce_counter, unsigned char *stream_block,
- const unsigned char *input, unsigned char *output );
-#endif
-
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- /** Encrypt or decrypt using XTS. */
- int (*xts_func)( void *ctx, mbedtls_operation_t mode, size_t length,
- const unsigned char data_unit[16],
- const unsigned char *input, unsigned char *output );
-#endif
-
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- /** Encrypt using STREAM */
- int (*stream_func)( void *ctx, size_t length,
- const unsigned char *input, unsigned char *output );
-#endif
-
- /** Set key for encryption purposes */
- int (*setkey_enc_func)( void *ctx, const unsigned char *key,
- unsigned int key_bitlen );
-
- /** Set key for decryption purposes */
- int (*setkey_dec_func)( void *ctx, const unsigned char *key,
- unsigned int key_bitlen);
-
- /** Allocate a new context */
- void * (*ctx_alloc_func)( void );
-
- /** Free the given context */
- void (*ctx_free_func)( void *ctx );
-
-};
-
-typedef struct
-{
- mbedtls_cipher_type_t type;
- const mbedtls_cipher_info_t *info;
-} mbedtls_cipher_definition_t;
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-typedef enum
-{
- MBEDTLS_CIPHER_PSA_KEY_UNSET = 0,
- MBEDTLS_CIPHER_PSA_KEY_OWNED, /* Used for PSA-based cipher contexts which */
- /* use raw key material internally imported */
- /* into a allocated key slot, and which */
- /* hence need to destroy that key slot */
- /* when they are no longer needed. */
- MBEDTLS_CIPHER_PSA_KEY_NOT_OWNED, /* Used for PSA-based cipher contexts */
- /* which use a key from a key slot */
- /* provided by the user, and which */
- /* hence should not be destroyed when */
- /* the context is no longer needed. */
-} mbedtls_cipher_psa_key_ownership;
-
-typedef struct
-{
- psa_algorithm_t alg;
- psa_key_handle_t slot;
- mbedtls_cipher_psa_key_ownership slot_state;
-} mbedtls_cipher_context_psa;
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
-
-extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[];
-
-extern int mbedtls_cipher_supported[];
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* MBEDTLS_CIPHER_WRAP_H */
diff --git a/assets/templates/blackpill/Src/cipher_wrap.c b/assets/templates/blackpill/Src/cipher_wrap.c
deleted file mode 100644
index fcbc92d..0000000
--- a/assets/templates/blackpill/Src/cipher_wrap.c
+++ /dev/null
@@ -1,2411 +0,0 @@
-/**
- * \file cipher_wrap.c
- *
- * \brief Generic cipher wrapper for mbed TLS
- *
- * \author Adriaan de Jong
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_CIPHER_C)
-
-#include "cipher_internal.h"
-
-#if defined(MBEDTLS_CHACHAPOLY_C)
-#include "mbedtls/chachapoly.h"
-#endif
-
-#if defined(MBEDTLS_AES_C)
-#include "aes.h"
-#endif
-
-#if defined(MBEDTLS_ARC4_C)
-#include "mbedtls/arc4.h"
-#endif
-
-#if defined(MBEDTLS_CAMELLIA_C)
-#include "mbedtls/camellia.h"
-#endif
-
-#if defined(MBEDTLS_ARIA_C)
-#include "mbedtls/aria.h"
-#endif
-
-#if defined(MBEDTLS_DES_C)
-#include "mbedtls/des.h"
-#endif
-
-#if defined(MBEDTLS_BLOWFISH_C)
-#include "mbedtls/blowfish.h"
-#endif
-
-#if defined(MBEDTLS_CHACHA20_C)
-#include "mbedtls/chacha20.h"
-#endif
-
-#if defined(MBEDTLS_GCM_C)
-#include "gcm.h"
-#endif
-
-#if defined(MBEDTLS_CCM_C)
-#include "mbedtls/ccm.h"
-#endif
-
-#if defined(MBEDTLS_NIST_KW_C)
-#include "mbedtls/nist_kw.h"
-#endif
-
-#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
-#include
-#endif
-
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include
-#define mbedtls_calloc calloc
-#define mbedtls_free free
-#endif
-
-#if defined(MBEDTLS_GCM_C)
-/* shared by all GCM ciphers */
-static void *gcm_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_gcm_context ) );
-
- if( ctx != NULL )
- mbedtls_gcm_init( (mbedtls_gcm_context *) ctx );
-
- return( ctx );
-}
-
-static void gcm_ctx_free( void *ctx )
-{
- mbedtls_gcm_free( ctx );
- mbedtls_free( ctx );
-}
-#endif /* MBEDTLS_GCM_C */
-
-#if defined(MBEDTLS_CCM_C)
-/* shared by all CCM ciphers */
-static void *ccm_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ccm_context ) );
-
- if( ctx != NULL )
- mbedtls_ccm_init( (mbedtls_ccm_context *) ctx );
-
- return( ctx );
-}
-
-static void ccm_ctx_free( void *ctx )
-{
- mbedtls_ccm_free( ctx );
- mbedtls_free( ctx );
-}
-#endif /* MBEDTLS_CCM_C */
-
-#if defined(MBEDTLS_AES_C)
-
-static int aes_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
- const unsigned char *input, unsigned char *output )
-{
- return mbedtls_aes_crypt_ecb( (mbedtls_aes_context *) ctx, operation, input, output );
-}
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-static int aes_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length,
- unsigned char *iv, const unsigned char *input, unsigned char *output )
-{
- return mbedtls_aes_crypt_cbc( (mbedtls_aes_context *) ctx, operation, length, iv, input,
- output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
-static int aes_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation,
- size_t length, size_t *iv_off, unsigned char *iv,
- const unsigned char *input, unsigned char *output )
-{
- return mbedtls_aes_crypt_cfb128( (mbedtls_aes_context *) ctx, operation, length, iv_off, iv,
- input, output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
-static int aes_crypt_ofb_wrap( void *ctx, size_t length, size_t *iv_off,
- unsigned char *iv, const unsigned char *input, unsigned char *output )
-{
- return mbedtls_aes_crypt_ofb( (mbedtls_aes_context *) ctx, length, iv_off,
- iv, input, output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_OFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
-static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
- unsigned char *nonce_counter, unsigned char *stream_block,
- const unsigned char *input, unsigned char *output )
-{
- return mbedtls_aes_crypt_ctr( (mbedtls_aes_context *) ctx, length, nc_off, nonce_counter,
- stream_block, input, output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CTR */
-
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
-static int aes_crypt_xts_wrap( void *ctx, mbedtls_operation_t operation,
- size_t length,
- const unsigned char data_unit[16],
- const unsigned char *input,
- unsigned char *output )
-{
- mbedtls_aes_xts_context *xts_ctx = ctx;
- int mode;
-
- switch( operation )
- {
- case MBEDTLS_ENCRYPT:
- mode = MBEDTLS_AES_ENCRYPT;
- break;
- case MBEDTLS_DECRYPT:
- mode = MBEDTLS_AES_DECRYPT;
- break;
- default:
- return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
- }
-
- return mbedtls_aes_crypt_xts( xts_ctx, mode, length,
- data_unit, input, output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_XTS */
-
-static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- return mbedtls_aes_setkey_dec( (mbedtls_aes_context *) ctx, key, key_bitlen );
-}
-
-static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- return mbedtls_aes_setkey_enc( (mbedtls_aes_context *) ctx, key, key_bitlen );
-}
-
-static void * aes_ctx_alloc( void )
-{
- mbedtls_aes_context *aes = mbedtls_calloc( 1, sizeof( mbedtls_aes_context ) );
-
- if( aes == NULL )
- return( NULL );
-
- mbedtls_aes_init( aes );
-
- return( aes );
-}
-
-static void aes_ctx_free( void *ctx )
-{
- mbedtls_aes_free( (mbedtls_aes_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static const mbedtls_cipher_base_t aes_info = {
- MBEDTLS_CIPHER_ID_AES,
- aes_crypt_ecb_wrap,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- aes_crypt_cbc_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- aes_crypt_cfb128_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- aes_crypt_ofb_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- aes_crypt_ctr_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
-#endif
- aes_setkey_enc_wrap,
- aes_setkey_dec_wrap,
- aes_ctx_alloc,
- aes_ctx_free
-};
-
-static const mbedtls_cipher_info_t aes_128_ecb_info = {
- MBEDTLS_CIPHER_AES_128_ECB,
- MBEDTLS_MODE_ECB,
- 128,
- "AES-128-ECB",
- 0,
- 0,
- 16,
- &aes_info
-};
-
-static const mbedtls_cipher_info_t aes_192_ecb_info = {
- MBEDTLS_CIPHER_AES_192_ECB,
- MBEDTLS_MODE_ECB,
- 192,
- "AES-192-ECB",
- 0,
- 0,
- 16,
- &aes_info
-};
-
-static const mbedtls_cipher_info_t aes_256_ecb_info = {
- MBEDTLS_CIPHER_AES_256_ECB,
- MBEDTLS_MODE_ECB,
- 256,
- "AES-256-ECB",
- 0,
- 0,
- 16,
- &aes_info
-};
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-static const mbedtls_cipher_info_t aes_128_cbc_info = {
- MBEDTLS_CIPHER_AES_128_CBC,
- MBEDTLS_MODE_CBC,
- 128,
- "AES-128-CBC",
- 16,
- 0,
- 16,
- &aes_info
-};
-
-static const mbedtls_cipher_info_t aes_192_cbc_info = {
- MBEDTLS_CIPHER_AES_192_CBC,
- MBEDTLS_MODE_CBC,
- 192,
- "AES-192-CBC",
- 16,
- 0,
- 16,
- &aes_info
-};
-
-static const mbedtls_cipher_info_t aes_256_cbc_info = {
- MBEDTLS_CIPHER_AES_256_CBC,
- MBEDTLS_MODE_CBC,
- 256,
- "AES-256-CBC",
- 16,
- 0,
- 16,
- &aes_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
-static const mbedtls_cipher_info_t aes_128_cfb128_info = {
- MBEDTLS_CIPHER_AES_128_CFB128,
- MBEDTLS_MODE_CFB,
- 128,
- "AES-128-CFB128",
- 16,
- 0,
- 16,
- &aes_info
-};
-
-static const mbedtls_cipher_info_t aes_192_cfb128_info = {
- MBEDTLS_CIPHER_AES_192_CFB128,
- MBEDTLS_MODE_CFB,
- 192,
- "AES-192-CFB128",
- 16,
- 0,
- 16,
- &aes_info
-};
-
-static const mbedtls_cipher_info_t aes_256_cfb128_info = {
- MBEDTLS_CIPHER_AES_256_CFB128,
- MBEDTLS_MODE_CFB,
- 256,
- "AES-256-CFB128",
- 16,
- 0,
- 16,
- &aes_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_CFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
-static const mbedtls_cipher_info_t aes_128_ofb_info = {
- MBEDTLS_CIPHER_AES_128_OFB,
- MBEDTLS_MODE_OFB,
- 128,
- "AES-128-OFB",
- 16,
- 0,
- 16,
- &aes_info
-};
-
-static const mbedtls_cipher_info_t aes_192_ofb_info = {
- MBEDTLS_CIPHER_AES_192_OFB,
- MBEDTLS_MODE_OFB,
- 192,
- "AES-192-OFB",
- 16,
- 0,
- 16,
- &aes_info
-};
-
-static const mbedtls_cipher_info_t aes_256_ofb_info = {
- MBEDTLS_CIPHER_AES_256_OFB,
- MBEDTLS_MODE_OFB,
- 256,
- "AES-256-OFB",
- 16,
- 0,
- 16,
- &aes_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_OFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
-static const mbedtls_cipher_info_t aes_128_ctr_info = {
- MBEDTLS_CIPHER_AES_128_CTR,
- MBEDTLS_MODE_CTR,
- 128,
- "AES-128-CTR",
- 16,
- 0,
- 16,
- &aes_info
-};
-
-static const mbedtls_cipher_info_t aes_192_ctr_info = {
- MBEDTLS_CIPHER_AES_192_CTR,
- MBEDTLS_MODE_CTR,
- 192,
- "AES-192-CTR",
- 16,
- 0,
- 16,
- &aes_info
-};
-
-static const mbedtls_cipher_info_t aes_256_ctr_info = {
- MBEDTLS_CIPHER_AES_256_CTR,
- MBEDTLS_MODE_CTR,
- 256,
- "AES-256-CTR",
- 16,
- 0,
- 16,
- &aes_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_CTR */
-
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
-static int xts_aes_setkey_enc_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- mbedtls_aes_xts_context *xts_ctx = ctx;
- return( mbedtls_aes_xts_setkey_enc( xts_ctx, key, key_bitlen ) );
-}
-
-static int xts_aes_setkey_dec_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- mbedtls_aes_xts_context *xts_ctx = ctx;
- return( mbedtls_aes_xts_setkey_dec( xts_ctx, key, key_bitlen ) );
-}
-
-static void *xts_aes_ctx_alloc( void )
-{
- mbedtls_aes_xts_context *xts_ctx = mbedtls_calloc( 1, sizeof( *xts_ctx ) );
-
- if( xts_ctx != NULL )
- mbedtls_aes_xts_init( xts_ctx );
-
- return( xts_ctx );
-}
-
-static void xts_aes_ctx_free( void *ctx )
-{
- mbedtls_aes_xts_context *xts_ctx = ctx;
-
- if( xts_ctx == NULL )
- return;
-
- mbedtls_aes_xts_free( xts_ctx );
- mbedtls_free( xts_ctx );
-}
-
-static const mbedtls_cipher_base_t xts_aes_info = {
- MBEDTLS_CIPHER_ID_AES,
- NULL,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- aes_crypt_xts_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
-#endif
- xts_aes_setkey_enc_wrap,
- xts_aes_setkey_dec_wrap,
- xts_aes_ctx_alloc,
- xts_aes_ctx_free
-};
-
-static const mbedtls_cipher_info_t aes_128_xts_info = {
- MBEDTLS_CIPHER_AES_128_XTS,
- MBEDTLS_MODE_XTS,
- 256,
- "AES-128-XTS",
- 16,
- 0,
- 16,
- &xts_aes_info
-};
-
-static const mbedtls_cipher_info_t aes_256_xts_info = {
- MBEDTLS_CIPHER_AES_256_XTS,
- MBEDTLS_MODE_XTS,
- 512,
- "AES-256-XTS",
- 16,
- 0,
- 16,
- &xts_aes_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_XTS */
-
-#if defined(MBEDTLS_GCM_C)
-static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_AES,
- key, key_bitlen );
-}
-
-static const mbedtls_cipher_base_t gcm_aes_info = {
- MBEDTLS_CIPHER_ID_AES,
- NULL,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
-#endif
- gcm_aes_setkey_wrap,
- gcm_aes_setkey_wrap,
- gcm_ctx_alloc,
- gcm_ctx_free,
-};
-
-static const mbedtls_cipher_info_t aes_128_gcm_info = {
- MBEDTLS_CIPHER_AES_128_GCM,
- MBEDTLS_MODE_GCM,
- 128,
- "AES-128-GCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &gcm_aes_info
-};
-
-static const mbedtls_cipher_info_t aes_192_gcm_info = {
- MBEDTLS_CIPHER_AES_192_GCM,
- MBEDTLS_MODE_GCM,
- 192,
- "AES-192-GCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &gcm_aes_info
-};
-
-static const mbedtls_cipher_info_t aes_256_gcm_info = {
- MBEDTLS_CIPHER_AES_256_GCM,
- MBEDTLS_MODE_GCM,
- 256,
- "AES-256-GCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &gcm_aes_info
-};
-#endif /* MBEDTLS_GCM_C */
-
-#if defined(MBEDTLS_CCM_C)
-static int ccm_aes_setkey_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_AES,
- key, key_bitlen );
-}
-
-static const mbedtls_cipher_base_t ccm_aes_info = {
- MBEDTLS_CIPHER_ID_AES,
- NULL,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
-#endif
- ccm_aes_setkey_wrap,
- ccm_aes_setkey_wrap,
- ccm_ctx_alloc,
- ccm_ctx_free,
-};
-
-static const mbedtls_cipher_info_t aes_128_ccm_info = {
- MBEDTLS_CIPHER_AES_128_CCM,
- MBEDTLS_MODE_CCM,
- 128,
- "AES-128-CCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &ccm_aes_info
-};
-
-static const mbedtls_cipher_info_t aes_192_ccm_info = {
- MBEDTLS_CIPHER_AES_192_CCM,
- MBEDTLS_MODE_CCM,
- 192,
- "AES-192-CCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &ccm_aes_info
-};
-
-static const mbedtls_cipher_info_t aes_256_ccm_info = {
- MBEDTLS_CIPHER_AES_256_CCM,
- MBEDTLS_MODE_CCM,
- 256,
- "AES-256-CCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &ccm_aes_info
-};
-#endif /* MBEDTLS_CCM_C */
-
-#endif /* MBEDTLS_AES_C */
-
-#if defined(MBEDTLS_CAMELLIA_C)
-
-static int camellia_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
- const unsigned char *input, unsigned char *output )
-{
- return mbedtls_camellia_crypt_ecb( (mbedtls_camellia_context *) ctx, operation, input,
- output );
-}
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-static int camellia_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation,
- size_t length, unsigned char *iv,
- const unsigned char *input, unsigned char *output )
-{
- return mbedtls_camellia_crypt_cbc( (mbedtls_camellia_context *) ctx, operation, length, iv,
- input, output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
-static int camellia_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation,
- size_t length, size_t *iv_off, unsigned char *iv,
- const unsigned char *input, unsigned char *output )
-{
- return mbedtls_camellia_crypt_cfb128( (mbedtls_camellia_context *) ctx, operation, length,
- iv_off, iv, input, output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
-static int camellia_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
- unsigned char *nonce_counter, unsigned char *stream_block,
- const unsigned char *input, unsigned char *output )
-{
- return mbedtls_camellia_crypt_ctr( (mbedtls_camellia_context *) ctx, length, nc_off,
- nonce_counter, stream_block, input, output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CTR */
-
-static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- return mbedtls_camellia_setkey_dec( (mbedtls_camellia_context *) ctx, key, key_bitlen );
-}
-
-static int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- return mbedtls_camellia_setkey_enc( (mbedtls_camellia_context *) ctx, key, key_bitlen );
-}
-
-static void * camellia_ctx_alloc( void )
-{
- mbedtls_camellia_context *ctx;
- ctx = mbedtls_calloc( 1, sizeof( mbedtls_camellia_context ) );
-
- if( ctx == NULL )
- return( NULL );
-
- mbedtls_camellia_init( ctx );
-
- return( ctx );
-}
-
-static void camellia_ctx_free( void *ctx )
-{
- mbedtls_camellia_free( (mbedtls_camellia_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static const mbedtls_cipher_base_t camellia_info = {
- MBEDTLS_CIPHER_ID_CAMELLIA,
- camellia_crypt_ecb_wrap,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- camellia_crypt_cbc_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- camellia_crypt_cfb128_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- camellia_crypt_ctr_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
-#endif
- camellia_setkey_enc_wrap,
- camellia_setkey_dec_wrap,
- camellia_ctx_alloc,
- camellia_ctx_free
-};
-
-static const mbedtls_cipher_info_t camellia_128_ecb_info = {
- MBEDTLS_CIPHER_CAMELLIA_128_ECB,
- MBEDTLS_MODE_ECB,
- 128,
- "CAMELLIA-128-ECB",
- 16,
- 0,
- 16,
- &camellia_info
-};
-
-static const mbedtls_cipher_info_t camellia_192_ecb_info = {
- MBEDTLS_CIPHER_CAMELLIA_192_ECB,
- MBEDTLS_MODE_ECB,
- 192,
- "CAMELLIA-192-ECB",
- 16,
- 0,
- 16,
- &camellia_info
-};
-
-static const mbedtls_cipher_info_t camellia_256_ecb_info = {
- MBEDTLS_CIPHER_CAMELLIA_256_ECB,
- MBEDTLS_MODE_ECB,
- 256,
- "CAMELLIA-256-ECB",
- 16,
- 0,
- 16,
- &camellia_info
-};
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-static const mbedtls_cipher_info_t camellia_128_cbc_info = {
- MBEDTLS_CIPHER_CAMELLIA_128_CBC,
- MBEDTLS_MODE_CBC,
- 128,
- "CAMELLIA-128-CBC",
- 16,
- 0,
- 16,
- &camellia_info
-};
-
-static const mbedtls_cipher_info_t camellia_192_cbc_info = {
- MBEDTLS_CIPHER_CAMELLIA_192_CBC,
- MBEDTLS_MODE_CBC,
- 192,
- "CAMELLIA-192-CBC",
- 16,
- 0,
- 16,
- &camellia_info
-};
-
-static const mbedtls_cipher_info_t camellia_256_cbc_info = {
- MBEDTLS_CIPHER_CAMELLIA_256_CBC,
- MBEDTLS_MODE_CBC,
- 256,
- "CAMELLIA-256-CBC",
- 16,
- 0,
- 16,
- &camellia_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
-static const mbedtls_cipher_info_t camellia_128_cfb128_info = {
- MBEDTLS_CIPHER_CAMELLIA_128_CFB128,
- MBEDTLS_MODE_CFB,
- 128,
- "CAMELLIA-128-CFB128",
- 16,
- 0,
- 16,
- &camellia_info
-};
-
-static const mbedtls_cipher_info_t camellia_192_cfb128_info = {
- MBEDTLS_CIPHER_CAMELLIA_192_CFB128,
- MBEDTLS_MODE_CFB,
- 192,
- "CAMELLIA-192-CFB128",
- 16,
- 0,
- 16,
- &camellia_info
-};
-
-static const mbedtls_cipher_info_t camellia_256_cfb128_info = {
- MBEDTLS_CIPHER_CAMELLIA_256_CFB128,
- MBEDTLS_MODE_CFB,
- 256,
- "CAMELLIA-256-CFB128",
- 16,
- 0,
- 16,
- &camellia_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_CFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
-static const mbedtls_cipher_info_t camellia_128_ctr_info = {
- MBEDTLS_CIPHER_CAMELLIA_128_CTR,
- MBEDTLS_MODE_CTR,
- 128,
- "CAMELLIA-128-CTR",
- 16,
- 0,
- 16,
- &camellia_info
-};
-
-static const mbedtls_cipher_info_t camellia_192_ctr_info = {
- MBEDTLS_CIPHER_CAMELLIA_192_CTR,
- MBEDTLS_MODE_CTR,
- 192,
- "CAMELLIA-192-CTR",
- 16,
- 0,
- 16,
- &camellia_info
-};
-
-static const mbedtls_cipher_info_t camellia_256_ctr_info = {
- MBEDTLS_CIPHER_CAMELLIA_256_CTR,
- MBEDTLS_MODE_CTR,
- 256,
- "CAMELLIA-256-CTR",
- 16,
- 0,
- 16,
- &camellia_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_CTR */
-
-#if defined(MBEDTLS_GCM_C)
-static int gcm_camellia_setkey_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA,
- key, key_bitlen );
-}
-
-static const mbedtls_cipher_base_t gcm_camellia_info = {
- MBEDTLS_CIPHER_ID_CAMELLIA,
- NULL,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
-#endif
- gcm_camellia_setkey_wrap,
- gcm_camellia_setkey_wrap,
- gcm_ctx_alloc,
- gcm_ctx_free,
-};
-
-static const mbedtls_cipher_info_t camellia_128_gcm_info = {
- MBEDTLS_CIPHER_CAMELLIA_128_GCM,
- MBEDTLS_MODE_GCM,
- 128,
- "CAMELLIA-128-GCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &gcm_camellia_info
-};
-
-static const mbedtls_cipher_info_t camellia_192_gcm_info = {
- MBEDTLS_CIPHER_CAMELLIA_192_GCM,
- MBEDTLS_MODE_GCM,
- 192,
- "CAMELLIA-192-GCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &gcm_camellia_info
-};
-
-static const mbedtls_cipher_info_t camellia_256_gcm_info = {
- MBEDTLS_CIPHER_CAMELLIA_256_GCM,
- MBEDTLS_MODE_GCM,
- 256,
- "CAMELLIA-256-GCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &gcm_camellia_info
-};
-#endif /* MBEDTLS_GCM_C */
-
-#if defined(MBEDTLS_CCM_C)
-static int ccm_camellia_setkey_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA,
- key, key_bitlen );
-}
-
-static const mbedtls_cipher_base_t ccm_camellia_info = {
- MBEDTLS_CIPHER_ID_CAMELLIA,
- NULL,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
-#endif
- ccm_camellia_setkey_wrap,
- ccm_camellia_setkey_wrap,
- ccm_ctx_alloc,
- ccm_ctx_free,
-};
-
-static const mbedtls_cipher_info_t camellia_128_ccm_info = {
- MBEDTLS_CIPHER_CAMELLIA_128_CCM,
- MBEDTLS_MODE_CCM,
- 128,
- "CAMELLIA-128-CCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &ccm_camellia_info
-};
-
-static const mbedtls_cipher_info_t camellia_192_ccm_info = {
- MBEDTLS_CIPHER_CAMELLIA_192_CCM,
- MBEDTLS_MODE_CCM,
- 192,
- "CAMELLIA-192-CCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &ccm_camellia_info
-};
-
-static const mbedtls_cipher_info_t camellia_256_ccm_info = {
- MBEDTLS_CIPHER_CAMELLIA_256_CCM,
- MBEDTLS_MODE_CCM,
- 256,
- "CAMELLIA-256-CCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &ccm_camellia_info
-};
-#endif /* MBEDTLS_CCM_C */
-
-#endif /* MBEDTLS_CAMELLIA_C */
-
-#if defined(MBEDTLS_ARIA_C)
-
-static int aria_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
- const unsigned char *input, unsigned char *output )
-{
- (void) operation;
- return mbedtls_aria_crypt_ecb( (mbedtls_aria_context *) ctx, input,
- output );
-}
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-static int aria_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation,
- size_t length, unsigned char *iv,
- const unsigned char *input, unsigned char *output )
-{
- return mbedtls_aria_crypt_cbc( (mbedtls_aria_context *) ctx, operation, length, iv,
- input, output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
-static int aria_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation,
- size_t length, size_t *iv_off, unsigned char *iv,
- const unsigned char *input, unsigned char *output )
-{
- return mbedtls_aria_crypt_cfb128( (mbedtls_aria_context *) ctx, operation, length,
- iv_off, iv, input, output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
-static int aria_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
- unsigned char *nonce_counter, unsigned char *stream_block,
- const unsigned char *input, unsigned char *output )
-{
- return mbedtls_aria_crypt_ctr( (mbedtls_aria_context *) ctx, length, nc_off,
- nonce_counter, stream_block, input, output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CTR */
-
-static int aria_setkey_dec_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- return mbedtls_aria_setkey_dec( (mbedtls_aria_context *) ctx, key, key_bitlen );
-}
-
-static int aria_setkey_enc_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- return mbedtls_aria_setkey_enc( (mbedtls_aria_context *) ctx, key, key_bitlen );
-}
-
-static void * aria_ctx_alloc( void )
-{
- mbedtls_aria_context *ctx;
- ctx = mbedtls_calloc( 1, sizeof( mbedtls_aria_context ) );
-
- if( ctx == NULL )
- return( NULL );
-
- mbedtls_aria_init( ctx );
-
- return( ctx );
-}
-
-static void aria_ctx_free( void *ctx )
-{
- mbedtls_aria_free( (mbedtls_aria_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static const mbedtls_cipher_base_t aria_info = {
- MBEDTLS_CIPHER_ID_ARIA,
- aria_crypt_ecb_wrap,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- aria_crypt_cbc_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- aria_crypt_cfb128_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- aria_crypt_ctr_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
-#endif
- aria_setkey_enc_wrap,
- aria_setkey_dec_wrap,
- aria_ctx_alloc,
- aria_ctx_free
-};
-
-static const mbedtls_cipher_info_t aria_128_ecb_info = {
- MBEDTLS_CIPHER_ARIA_128_ECB,
- MBEDTLS_MODE_ECB,
- 128,
- "ARIA-128-ECB",
- 16,
- 0,
- 16,
- &aria_info
-};
-
-static const mbedtls_cipher_info_t aria_192_ecb_info = {
- MBEDTLS_CIPHER_ARIA_192_ECB,
- MBEDTLS_MODE_ECB,
- 192,
- "ARIA-192-ECB",
- 16,
- 0,
- 16,
- &aria_info
-};
-
-static const mbedtls_cipher_info_t aria_256_ecb_info = {
- MBEDTLS_CIPHER_ARIA_256_ECB,
- MBEDTLS_MODE_ECB,
- 256,
- "ARIA-256-ECB",
- 16,
- 0,
- 16,
- &aria_info
-};
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-static const mbedtls_cipher_info_t aria_128_cbc_info = {
- MBEDTLS_CIPHER_ARIA_128_CBC,
- MBEDTLS_MODE_CBC,
- 128,
- "ARIA-128-CBC",
- 16,
- 0,
- 16,
- &aria_info
-};
-
-static const mbedtls_cipher_info_t aria_192_cbc_info = {
- MBEDTLS_CIPHER_ARIA_192_CBC,
- MBEDTLS_MODE_CBC,
- 192,
- "ARIA-192-CBC",
- 16,
- 0,
- 16,
- &aria_info
-};
-
-static const mbedtls_cipher_info_t aria_256_cbc_info = {
- MBEDTLS_CIPHER_ARIA_256_CBC,
- MBEDTLS_MODE_CBC,
- 256,
- "ARIA-256-CBC",
- 16,
- 0,
- 16,
- &aria_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
-static const mbedtls_cipher_info_t aria_128_cfb128_info = {
- MBEDTLS_CIPHER_ARIA_128_CFB128,
- MBEDTLS_MODE_CFB,
- 128,
- "ARIA-128-CFB128",
- 16,
- 0,
- 16,
- &aria_info
-};
-
-static const mbedtls_cipher_info_t aria_192_cfb128_info = {
- MBEDTLS_CIPHER_ARIA_192_CFB128,
- MBEDTLS_MODE_CFB,
- 192,
- "ARIA-192-CFB128",
- 16,
- 0,
- 16,
- &aria_info
-};
-
-static const mbedtls_cipher_info_t aria_256_cfb128_info = {
- MBEDTLS_CIPHER_ARIA_256_CFB128,
- MBEDTLS_MODE_CFB,
- 256,
- "ARIA-256-CFB128",
- 16,
- 0,
- 16,
- &aria_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_CFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
-static const mbedtls_cipher_info_t aria_128_ctr_info = {
- MBEDTLS_CIPHER_ARIA_128_CTR,
- MBEDTLS_MODE_CTR,
- 128,
- "ARIA-128-CTR",
- 16,
- 0,
- 16,
- &aria_info
-};
-
-static const mbedtls_cipher_info_t aria_192_ctr_info = {
- MBEDTLS_CIPHER_ARIA_192_CTR,
- MBEDTLS_MODE_CTR,
- 192,
- "ARIA-192-CTR",
- 16,
- 0,
- 16,
- &aria_info
-};
-
-static const mbedtls_cipher_info_t aria_256_ctr_info = {
- MBEDTLS_CIPHER_ARIA_256_CTR,
- MBEDTLS_MODE_CTR,
- 256,
- "ARIA-256-CTR",
- 16,
- 0,
- 16,
- &aria_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_CTR */
-
-#if defined(MBEDTLS_GCM_C)
-static int gcm_aria_setkey_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA,
- key, key_bitlen );
-}
-
-static const mbedtls_cipher_base_t gcm_aria_info = {
- MBEDTLS_CIPHER_ID_ARIA,
- NULL,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
-#endif
- gcm_aria_setkey_wrap,
- gcm_aria_setkey_wrap,
- gcm_ctx_alloc,
- gcm_ctx_free,
-};
-
-static const mbedtls_cipher_info_t aria_128_gcm_info = {
- MBEDTLS_CIPHER_ARIA_128_GCM,
- MBEDTLS_MODE_GCM,
- 128,
- "ARIA-128-GCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &gcm_aria_info
-};
-
-static const mbedtls_cipher_info_t aria_192_gcm_info = {
- MBEDTLS_CIPHER_ARIA_192_GCM,
- MBEDTLS_MODE_GCM,
- 192,
- "ARIA-192-GCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &gcm_aria_info
-};
-
-static const mbedtls_cipher_info_t aria_256_gcm_info = {
- MBEDTLS_CIPHER_ARIA_256_GCM,
- MBEDTLS_MODE_GCM,
- 256,
- "ARIA-256-GCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &gcm_aria_info
-};
-#endif /* MBEDTLS_GCM_C */
-
-#if defined(MBEDTLS_CCM_C)
-static int ccm_aria_setkey_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA,
- key, key_bitlen );
-}
-
-static const mbedtls_cipher_base_t ccm_aria_info = {
- MBEDTLS_CIPHER_ID_ARIA,
- NULL,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
-#endif
- ccm_aria_setkey_wrap,
- ccm_aria_setkey_wrap,
- ccm_ctx_alloc,
- ccm_ctx_free,
-};
-
-static const mbedtls_cipher_info_t aria_128_ccm_info = {
- MBEDTLS_CIPHER_ARIA_128_CCM,
- MBEDTLS_MODE_CCM,
- 128,
- "ARIA-128-CCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &ccm_aria_info
-};
-
-static const mbedtls_cipher_info_t aria_192_ccm_info = {
- MBEDTLS_CIPHER_ARIA_192_CCM,
- MBEDTLS_MODE_CCM,
- 192,
- "ARIA-192-CCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &ccm_aria_info
-};
-
-static const mbedtls_cipher_info_t aria_256_ccm_info = {
- MBEDTLS_CIPHER_ARIA_256_CCM,
- MBEDTLS_MODE_CCM,
- 256,
- "ARIA-256-CCM",
- 12,
- MBEDTLS_CIPHER_VARIABLE_IV_LEN,
- 16,
- &ccm_aria_info
-};
-#endif /* MBEDTLS_CCM_C */
-
-#endif /* MBEDTLS_ARIA_C */
-
-#if defined(MBEDTLS_DES_C)
-
-static int des_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
- const unsigned char *input, unsigned char *output )
-{
- ((void) operation);
- return mbedtls_des_crypt_ecb( (mbedtls_des_context *) ctx, input, output );
-}
-
-static int des3_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
- const unsigned char *input, unsigned char *output )
-{
- ((void) operation);
- return mbedtls_des3_crypt_ecb( (mbedtls_des3_context *) ctx, input, output );
-}
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-static int des_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length,
- unsigned char *iv, const unsigned char *input, unsigned char *output )
-{
- return mbedtls_des_crypt_cbc( (mbedtls_des_context *) ctx, operation, length, iv, input,
- output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-static int des3_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length,
- unsigned char *iv, const unsigned char *input, unsigned char *output )
-{
- return mbedtls_des3_crypt_cbc( (mbedtls_des3_context *) ctx, operation, length, iv, input,
- output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-static int des_setkey_dec_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- ((void) key_bitlen);
-
- return mbedtls_des_setkey_dec( (mbedtls_des_context *) ctx, key );
-}
-
-static int des_setkey_enc_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- ((void) key_bitlen);
-
- return mbedtls_des_setkey_enc( (mbedtls_des_context *) ctx, key );
-}
-
-static int des3_set2key_dec_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- ((void) key_bitlen);
-
- return mbedtls_des3_set2key_dec( (mbedtls_des3_context *) ctx, key );
-}
-
-static int des3_set2key_enc_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- ((void) key_bitlen);
-
- return mbedtls_des3_set2key_enc( (mbedtls_des3_context *) ctx, key );
-}
-
-static int des3_set3key_dec_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- ((void) key_bitlen);
-
- return mbedtls_des3_set3key_dec( (mbedtls_des3_context *) ctx, key );
-}
-
-static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- ((void) key_bitlen);
-
- return mbedtls_des3_set3key_enc( (mbedtls_des3_context *) ctx, key );
-}
-
-static void * des_ctx_alloc( void )
-{
- mbedtls_des_context *des = mbedtls_calloc( 1, sizeof( mbedtls_des_context ) );
-
- if( des == NULL )
- return( NULL );
-
- mbedtls_des_init( des );
-
- return( des );
-}
-
-static void des_ctx_free( void *ctx )
-{
- mbedtls_des_free( (mbedtls_des_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void * des3_ctx_alloc( void )
-{
- mbedtls_des3_context *des3;
- des3 = mbedtls_calloc( 1, sizeof( mbedtls_des3_context ) );
-
- if( des3 == NULL )
- return( NULL );
-
- mbedtls_des3_init( des3 );
-
- return( des3 );
-}
-
-static void des3_ctx_free( void *ctx )
-{
- mbedtls_des3_free( (mbedtls_des3_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static const mbedtls_cipher_base_t des_info = {
- MBEDTLS_CIPHER_ID_DES,
- des_crypt_ecb_wrap,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- des_crypt_cbc_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
-#endif
- des_setkey_enc_wrap,
- des_setkey_dec_wrap,
- des_ctx_alloc,
- des_ctx_free
-};
-
-static const mbedtls_cipher_info_t des_ecb_info = {
- MBEDTLS_CIPHER_DES_ECB,
- MBEDTLS_MODE_ECB,
- MBEDTLS_KEY_LENGTH_DES,
- "DES-ECB",
- 8,
- 0,
- 8,
- &des_info
-};
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-static const mbedtls_cipher_info_t des_cbc_info = {
- MBEDTLS_CIPHER_DES_CBC,
- MBEDTLS_MODE_CBC,
- MBEDTLS_KEY_LENGTH_DES,
- "DES-CBC",
- 8,
- 0,
- 8,
- &des_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-static const mbedtls_cipher_base_t des_ede_info = {
- MBEDTLS_CIPHER_ID_DES,
- des3_crypt_ecb_wrap,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- des3_crypt_cbc_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
-#endif
- des3_set2key_enc_wrap,
- des3_set2key_dec_wrap,
- des3_ctx_alloc,
- des3_ctx_free
-};
-
-static const mbedtls_cipher_info_t des_ede_ecb_info = {
- MBEDTLS_CIPHER_DES_EDE_ECB,
- MBEDTLS_MODE_ECB,
- MBEDTLS_KEY_LENGTH_DES_EDE,
- "DES-EDE-ECB",
- 8,
- 0,
- 8,
- &des_ede_info
-};
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-static const mbedtls_cipher_info_t des_ede_cbc_info = {
- MBEDTLS_CIPHER_DES_EDE_CBC,
- MBEDTLS_MODE_CBC,
- MBEDTLS_KEY_LENGTH_DES_EDE,
- "DES-EDE-CBC",
- 8,
- 0,
- 8,
- &des_ede_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-static const mbedtls_cipher_base_t des_ede3_info = {
- MBEDTLS_CIPHER_ID_3DES,
- des3_crypt_ecb_wrap,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- des3_crypt_cbc_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
-#endif
- des3_set3key_enc_wrap,
- des3_set3key_dec_wrap,
- des3_ctx_alloc,
- des3_ctx_free
-};
-
-static const mbedtls_cipher_info_t des_ede3_ecb_info = {
- MBEDTLS_CIPHER_DES_EDE3_ECB,
- MBEDTLS_MODE_ECB,
- MBEDTLS_KEY_LENGTH_DES_EDE3,
- "DES-EDE3-ECB",
- 8,
- 0,
- 8,
- &des_ede3_info
-};
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-static const mbedtls_cipher_info_t des_ede3_cbc_info = {
- MBEDTLS_CIPHER_DES_EDE3_CBC,
- MBEDTLS_MODE_CBC,
- MBEDTLS_KEY_LENGTH_DES_EDE3,
- "DES-EDE3-CBC",
- 8,
- 0,
- 8,
- &des_ede3_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-#endif /* MBEDTLS_DES_C */
-
-#if defined(MBEDTLS_BLOWFISH_C)
-
-static int blowfish_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
- const unsigned char *input, unsigned char *output )
-{
- return mbedtls_blowfish_crypt_ecb( (mbedtls_blowfish_context *) ctx, operation, input,
- output );
-}
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-static int blowfish_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation,
- size_t length, unsigned char *iv, const unsigned char *input,
- unsigned char *output )
-{
- return mbedtls_blowfish_crypt_cbc( (mbedtls_blowfish_context *) ctx, operation, length, iv,
- input, output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
-static int blowfish_crypt_cfb64_wrap( void *ctx, mbedtls_operation_t operation,
- size_t length, size_t *iv_off, unsigned char *iv,
- const unsigned char *input, unsigned char *output )
-{
- return mbedtls_blowfish_crypt_cfb64( (mbedtls_blowfish_context *) ctx, operation, length,
- iv_off, iv, input, output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
-static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
- unsigned char *nonce_counter, unsigned char *stream_block,
- const unsigned char *input, unsigned char *output )
-{
- return mbedtls_blowfish_crypt_ctr( (mbedtls_blowfish_context *) ctx, length, nc_off,
- nonce_counter, stream_block, input, output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CTR */
-
-static int blowfish_setkey_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- return mbedtls_blowfish_setkey( (mbedtls_blowfish_context *) ctx, key, key_bitlen );
-}
-
-static void * blowfish_ctx_alloc( void )
-{
- mbedtls_blowfish_context *ctx;
- ctx = mbedtls_calloc( 1, sizeof( mbedtls_blowfish_context ) );
-
- if( ctx == NULL )
- return( NULL );
-
- mbedtls_blowfish_init( ctx );
-
- return( ctx );
-}
-
-static void blowfish_ctx_free( void *ctx )
-{
- mbedtls_blowfish_free( (mbedtls_blowfish_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static const mbedtls_cipher_base_t blowfish_info = {
- MBEDTLS_CIPHER_ID_BLOWFISH,
- blowfish_crypt_ecb_wrap,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- blowfish_crypt_cbc_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- blowfish_crypt_cfb64_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- blowfish_crypt_ctr_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
-#endif
- blowfish_setkey_wrap,
- blowfish_setkey_wrap,
- blowfish_ctx_alloc,
- blowfish_ctx_free
-};
-
-static const mbedtls_cipher_info_t blowfish_ecb_info = {
- MBEDTLS_CIPHER_BLOWFISH_ECB,
- MBEDTLS_MODE_ECB,
- 128,
- "BLOWFISH-ECB",
- 8,
- MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
- 8,
- &blowfish_info
-};
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-static const mbedtls_cipher_info_t blowfish_cbc_info = {
- MBEDTLS_CIPHER_BLOWFISH_CBC,
- MBEDTLS_MODE_CBC,
- 128,
- "BLOWFISH-CBC",
- 8,
- MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
- 8,
- &blowfish_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
-static const mbedtls_cipher_info_t blowfish_cfb64_info = {
- MBEDTLS_CIPHER_BLOWFISH_CFB64,
- MBEDTLS_MODE_CFB,
- 128,
- "BLOWFISH-CFB64",
- 8,
- MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
- 8,
- &blowfish_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_CFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
-static const mbedtls_cipher_info_t blowfish_ctr_info = {
- MBEDTLS_CIPHER_BLOWFISH_CTR,
- MBEDTLS_MODE_CTR,
- 128,
- "BLOWFISH-CTR",
- 8,
- MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
- 8,
- &blowfish_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_CTR */
-#endif /* MBEDTLS_BLOWFISH_C */
-
-#if defined(MBEDTLS_ARC4_C)
-static int arc4_crypt_stream_wrap( void *ctx, size_t length,
- const unsigned char *input,
- unsigned char *output )
-{
- return( mbedtls_arc4_crypt( (mbedtls_arc4_context *) ctx, length, input, output ) );
-}
-
-static int arc4_setkey_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- /* we get key_bitlen in bits, arc4 expects it in bytes */
- if( key_bitlen % 8 != 0 )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- mbedtls_arc4_setup( (mbedtls_arc4_context *) ctx, key, key_bitlen / 8 );
- return( 0 );
-}
-
-static void * arc4_ctx_alloc( void )
-{
- mbedtls_arc4_context *ctx;
- ctx = mbedtls_calloc( 1, sizeof( mbedtls_arc4_context ) );
-
- if( ctx == NULL )
- return( NULL );
-
- mbedtls_arc4_init( ctx );
-
- return( ctx );
-}
-
-static void arc4_ctx_free( void *ctx )
-{
- mbedtls_arc4_free( (mbedtls_arc4_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static const mbedtls_cipher_base_t arc4_base_info = {
- MBEDTLS_CIPHER_ID_ARC4,
- NULL,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- arc4_crypt_stream_wrap,
-#endif
- arc4_setkey_wrap,
- arc4_setkey_wrap,
- arc4_ctx_alloc,
- arc4_ctx_free
-};
-
-static const mbedtls_cipher_info_t arc4_128_info = {
- MBEDTLS_CIPHER_ARC4_128,
- MBEDTLS_MODE_STREAM,
- 128,
- "ARC4-128",
- 0,
- 0,
- 1,
- &arc4_base_info
-};
-#endif /* MBEDTLS_ARC4_C */
-
-#if defined(MBEDTLS_CHACHA20_C)
-
-static int chacha20_setkey_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- if( key_bitlen != 256U )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- if ( 0 != mbedtls_chacha20_setkey( (mbedtls_chacha20_context*)ctx, key ) )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- return( 0 );
-}
-
-static int chacha20_stream_wrap( void *ctx, size_t length,
- const unsigned char *input,
- unsigned char *output )
-{
- int ret;
-
- ret = mbedtls_chacha20_update( ctx, length, input, output );
- if( ret == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- return( ret );
-}
-
-static void * chacha20_ctx_alloc( void )
-{
- mbedtls_chacha20_context *ctx;
- ctx = mbedtls_calloc( 1, sizeof( mbedtls_chacha20_context ) );
-
- if( ctx == NULL )
- return( NULL );
-
- mbedtls_chacha20_init( ctx );
-
- return( ctx );
-}
-
-static void chacha20_ctx_free( void *ctx )
-{
- mbedtls_chacha20_free( (mbedtls_chacha20_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static const mbedtls_cipher_base_t chacha20_base_info = {
- MBEDTLS_CIPHER_ID_CHACHA20,
- NULL,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- chacha20_stream_wrap,
-#endif
- chacha20_setkey_wrap,
- chacha20_setkey_wrap,
- chacha20_ctx_alloc,
- chacha20_ctx_free
-};
-static const mbedtls_cipher_info_t chacha20_info = {
- MBEDTLS_CIPHER_CHACHA20,
- MBEDTLS_MODE_STREAM,
- 256,
- "CHACHA20",
- 12,
- 0,
- 1,
- &chacha20_base_info
-};
-#endif /* MBEDTLS_CHACHA20_C */
-
-#if defined(MBEDTLS_CHACHAPOLY_C)
-
-static int chachapoly_setkey_wrap( void *ctx,
- const unsigned char *key,
- unsigned int key_bitlen )
-{
- if( key_bitlen != 256U )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- if ( 0 != mbedtls_chachapoly_setkey( (mbedtls_chachapoly_context*)ctx, key ) )
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
- return( 0 );
-}
-
-static void * chachapoly_ctx_alloc( void )
-{
- mbedtls_chachapoly_context *ctx;
- ctx = mbedtls_calloc( 1, sizeof( mbedtls_chachapoly_context ) );
-
- if( ctx == NULL )
- return( NULL );
-
- mbedtls_chachapoly_init( ctx );
-
- return( ctx );
-}
-
-static void chachapoly_ctx_free( void *ctx )
-{
- mbedtls_chachapoly_free( (mbedtls_chachapoly_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static const mbedtls_cipher_base_t chachapoly_base_info = {
- MBEDTLS_CIPHER_ID_CHACHA20,
- NULL,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
-#endif
- chachapoly_setkey_wrap,
- chachapoly_setkey_wrap,
- chachapoly_ctx_alloc,
- chachapoly_ctx_free
-};
-static const mbedtls_cipher_info_t chachapoly_info = {
- MBEDTLS_CIPHER_CHACHA20_POLY1305,
- MBEDTLS_MODE_CHACHAPOLY,
- 256,
- "CHACHA20-POLY1305",
- 12,
- 0,
- 1,
- &chachapoly_base_info
-};
-#endif /* MBEDTLS_CHACHAPOLY_C */
-
-#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
-static int null_crypt_stream( void *ctx, size_t length,
- const unsigned char *input,
- unsigned char *output )
-{
- ((void) ctx);
- memmove( output, input, length );
- return( 0 );
-}
-
-static int null_setkey( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- ((void) ctx);
- ((void) key);
- ((void) key_bitlen);
-
- return( 0 );
-}
-
-static void * null_ctx_alloc( void )
-{
- return( (void *) 1 );
-}
-
-static void null_ctx_free( void *ctx )
-{
- ((void) ctx);
-}
-
-static const mbedtls_cipher_base_t null_base_info = {
- MBEDTLS_CIPHER_ID_NULL,
- NULL,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- null_crypt_stream,
-#endif
- null_setkey,
- null_setkey,
- null_ctx_alloc,
- null_ctx_free
-};
-
-static const mbedtls_cipher_info_t null_cipher_info = {
- MBEDTLS_CIPHER_NULL,
- MBEDTLS_MODE_STREAM,
- 0,
- "NULL",
- 0,
- 0,
- 1,
- &null_base_info
-};
-#endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */
-
-#if defined(MBEDTLS_NIST_KW_C)
-static void *kw_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_nist_kw_context ) );
-
- if( ctx != NULL )
- mbedtls_nist_kw_init( (mbedtls_nist_kw_context *) ctx );
-
- return( ctx );
-}
-
-static void kw_ctx_free( void *ctx )
-{
- mbedtls_nist_kw_free( ctx );
- mbedtls_free( ctx );
-}
-
-static int kw_aes_setkey_wrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- return mbedtls_nist_kw_setkey( (mbedtls_nist_kw_context *) ctx,
- MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 1 );
-}
-
-static int kw_aes_setkey_unwrap( void *ctx, const unsigned char *key,
- unsigned int key_bitlen )
-{
- return mbedtls_nist_kw_setkey( (mbedtls_nist_kw_context *) ctx,
- MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 0 );
-}
-
-static const mbedtls_cipher_base_t kw_aes_info = {
- MBEDTLS_CIPHER_ID_AES,
- NULL,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
- NULL,
-#endif
- kw_aes_setkey_wrap,
- kw_aes_setkey_unwrap,
- kw_ctx_alloc,
- kw_ctx_free,
-};
-
-static const mbedtls_cipher_info_t aes_128_nist_kw_info = {
- MBEDTLS_CIPHER_AES_128_KW,
- MBEDTLS_MODE_KW,
- 128,
- "AES-128-KW",
- 0,
- 0,
- 16,
- &kw_aes_info
-};
-
-static const mbedtls_cipher_info_t aes_192_nist_kw_info = {
- MBEDTLS_CIPHER_AES_192_KW,
- MBEDTLS_MODE_KW,
- 192,
- "AES-192-KW",
- 0,
- 0,
- 16,
- &kw_aes_info
-};
-
-static const mbedtls_cipher_info_t aes_256_nist_kw_info = {
- MBEDTLS_CIPHER_AES_256_KW,
- MBEDTLS_MODE_KW,
- 256,
- "AES-256-KW",
- 0,
- 0,
- 16,
- &kw_aes_info
-};
-
-static const mbedtls_cipher_info_t aes_128_nist_kwp_info = {
- MBEDTLS_CIPHER_AES_128_KWP,
- MBEDTLS_MODE_KWP,
- 128,
- "AES-128-KWP",
- 0,
- 0,
- 16,
- &kw_aes_info
-};
-
-static const mbedtls_cipher_info_t aes_192_nist_kwp_info = {
- MBEDTLS_CIPHER_AES_192_KWP,
- MBEDTLS_MODE_KWP,
- 192,
- "AES-192-KWP",
- 0,
- 0,
- 16,
- &kw_aes_info
-};
-
-static const mbedtls_cipher_info_t aes_256_nist_kwp_info = {
- MBEDTLS_CIPHER_AES_256_KWP,
- MBEDTLS_MODE_KWP,
- 256,
- "AES-256-KWP",
- 0,
- 0,
- 16,
- &kw_aes_info
-};
-#endif /* MBEDTLS_NIST_KW_C */
-
-const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] =
-{
-#if defined(MBEDTLS_AES_C)
- { MBEDTLS_CIPHER_AES_128_ECB, &aes_128_ecb_info },
- { MBEDTLS_CIPHER_AES_192_ECB, &aes_192_ecb_info },
- { MBEDTLS_CIPHER_AES_256_ECB, &aes_256_ecb_info },
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_CIPHER_AES_128_CBC, &aes_128_cbc_info },
- { MBEDTLS_CIPHER_AES_192_CBC, &aes_192_cbc_info },
- { MBEDTLS_CIPHER_AES_256_CBC, &aes_256_cbc_info },
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- { MBEDTLS_CIPHER_AES_128_CFB128, &aes_128_cfb128_info },
- { MBEDTLS_CIPHER_AES_192_CFB128, &aes_192_cfb128_info },
- { MBEDTLS_CIPHER_AES_256_CFB128, &aes_256_cfb128_info },
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
- { MBEDTLS_CIPHER_AES_128_OFB, &aes_128_ofb_info },
- { MBEDTLS_CIPHER_AES_192_OFB, &aes_192_ofb_info },
- { MBEDTLS_CIPHER_AES_256_OFB, &aes_256_ofb_info },
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- { MBEDTLS_CIPHER_AES_128_CTR, &aes_128_ctr_info },
- { MBEDTLS_CIPHER_AES_192_CTR, &aes_192_ctr_info },
- { MBEDTLS_CIPHER_AES_256_CTR, &aes_256_ctr_info },
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
- { MBEDTLS_CIPHER_AES_128_XTS, &aes_128_xts_info },
- { MBEDTLS_CIPHER_AES_256_XTS, &aes_256_xts_info },
-#endif
-#if defined(MBEDTLS_GCM_C)
- { MBEDTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info },
- { MBEDTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info },
- { MBEDTLS_CIPHER_AES_256_GCM, &aes_256_gcm_info },
-#endif
-#if defined(MBEDTLS_CCM_C)
- { MBEDTLS_CIPHER_AES_128_CCM, &aes_128_ccm_info },
- { MBEDTLS_CIPHER_AES_192_CCM, &aes_192_ccm_info },
- { MBEDTLS_CIPHER_AES_256_CCM, &aes_256_ccm_info },
-#endif
-#endif /* MBEDTLS_AES_C */
-
-#if defined(MBEDTLS_ARC4_C)
- { MBEDTLS_CIPHER_ARC4_128, &arc4_128_info },
-#endif
-
-#if defined(MBEDTLS_BLOWFISH_C)
- { MBEDTLS_CIPHER_BLOWFISH_ECB, &blowfish_ecb_info },
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_CIPHER_BLOWFISH_CBC, &blowfish_cbc_info },
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- { MBEDTLS_CIPHER_BLOWFISH_CFB64, &blowfish_cfb64_info },
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- { MBEDTLS_CIPHER_BLOWFISH_CTR, &blowfish_ctr_info },
-#endif
-#endif /* MBEDTLS_BLOWFISH_C */
-
-#if defined(MBEDTLS_CAMELLIA_C)
- { MBEDTLS_CIPHER_CAMELLIA_128_ECB, &camellia_128_ecb_info },
- { MBEDTLS_CIPHER_CAMELLIA_192_ECB, &camellia_192_ecb_info },
- { MBEDTLS_CIPHER_CAMELLIA_256_ECB, &camellia_256_ecb_info },
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_CIPHER_CAMELLIA_128_CBC, &camellia_128_cbc_info },
- { MBEDTLS_CIPHER_CAMELLIA_192_CBC, &camellia_192_cbc_info },
- { MBEDTLS_CIPHER_CAMELLIA_256_CBC, &camellia_256_cbc_info },
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- { MBEDTLS_CIPHER_CAMELLIA_128_CFB128, &camellia_128_cfb128_info },
- { MBEDTLS_CIPHER_CAMELLIA_192_CFB128, &camellia_192_cfb128_info },
- { MBEDTLS_CIPHER_CAMELLIA_256_CFB128, &camellia_256_cfb128_info },
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- { MBEDTLS_CIPHER_CAMELLIA_128_CTR, &camellia_128_ctr_info },
- { MBEDTLS_CIPHER_CAMELLIA_192_CTR, &camellia_192_ctr_info },
- { MBEDTLS_CIPHER_CAMELLIA_256_CTR, &camellia_256_ctr_info },
-#endif
-#if defined(MBEDTLS_GCM_C)
- { MBEDTLS_CIPHER_CAMELLIA_128_GCM, &camellia_128_gcm_info },
- { MBEDTLS_CIPHER_CAMELLIA_192_GCM, &camellia_192_gcm_info },
- { MBEDTLS_CIPHER_CAMELLIA_256_GCM, &camellia_256_gcm_info },
-#endif
-#if defined(MBEDTLS_CCM_C)
- { MBEDTLS_CIPHER_CAMELLIA_128_CCM, &camellia_128_ccm_info },
- { MBEDTLS_CIPHER_CAMELLIA_192_CCM, &camellia_192_ccm_info },
- { MBEDTLS_CIPHER_CAMELLIA_256_CCM, &camellia_256_ccm_info },
-#endif
-#endif /* MBEDTLS_CAMELLIA_C */
-
-#if defined(MBEDTLS_ARIA_C)
- { MBEDTLS_CIPHER_ARIA_128_ECB, &aria_128_ecb_info },
- { MBEDTLS_CIPHER_ARIA_192_ECB, &aria_192_ecb_info },
- { MBEDTLS_CIPHER_ARIA_256_ECB, &aria_256_ecb_info },
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_CIPHER_ARIA_128_CBC, &aria_128_cbc_info },
- { MBEDTLS_CIPHER_ARIA_192_CBC, &aria_192_cbc_info },
- { MBEDTLS_CIPHER_ARIA_256_CBC, &aria_256_cbc_info },
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
- { MBEDTLS_CIPHER_ARIA_128_CFB128, &aria_128_cfb128_info },
- { MBEDTLS_CIPHER_ARIA_192_CFB128, &aria_192_cfb128_info },
- { MBEDTLS_CIPHER_ARIA_256_CFB128, &aria_256_cfb128_info },
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
- { MBEDTLS_CIPHER_ARIA_128_CTR, &aria_128_ctr_info },
- { MBEDTLS_CIPHER_ARIA_192_CTR, &aria_192_ctr_info },
- { MBEDTLS_CIPHER_ARIA_256_CTR, &aria_256_ctr_info },
-#endif
-#if defined(MBEDTLS_GCM_C)
- { MBEDTLS_CIPHER_ARIA_128_GCM, &aria_128_gcm_info },
- { MBEDTLS_CIPHER_ARIA_192_GCM, &aria_192_gcm_info },
- { MBEDTLS_CIPHER_ARIA_256_GCM, &aria_256_gcm_info },
-#endif
-#if defined(MBEDTLS_CCM_C)
- { MBEDTLS_CIPHER_ARIA_128_CCM, &aria_128_ccm_info },
- { MBEDTLS_CIPHER_ARIA_192_CCM, &aria_192_ccm_info },
- { MBEDTLS_CIPHER_ARIA_256_CCM, &aria_256_ccm_info },
-#endif
-#endif /* MBEDTLS_ARIA_C */
-
-#if defined(MBEDTLS_DES_C)
- { MBEDTLS_CIPHER_DES_ECB, &des_ecb_info },
- { MBEDTLS_CIPHER_DES_EDE_ECB, &des_ede_ecb_info },
- { MBEDTLS_CIPHER_DES_EDE3_ECB, &des_ede3_ecb_info },
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
- { MBEDTLS_CIPHER_DES_CBC, &des_cbc_info },
- { MBEDTLS_CIPHER_DES_EDE_CBC, &des_ede_cbc_info },
- { MBEDTLS_CIPHER_DES_EDE3_CBC, &des_ede3_cbc_info },
-#endif
-#endif /* MBEDTLS_DES_C */
-
-#if defined(MBEDTLS_CHACHA20_C)
- { MBEDTLS_CIPHER_CHACHA20, &chacha20_info },
-#endif
-
-#if defined(MBEDTLS_CHACHAPOLY_C)
- { MBEDTLS_CIPHER_CHACHA20_POLY1305, &chachapoly_info },
-#endif
-
-#if defined(MBEDTLS_NIST_KW_C)
- { MBEDTLS_CIPHER_AES_128_KW, &aes_128_nist_kw_info },
- { MBEDTLS_CIPHER_AES_192_KW, &aes_192_nist_kw_info },
- { MBEDTLS_CIPHER_AES_256_KW, &aes_256_nist_kw_info },
- { MBEDTLS_CIPHER_AES_128_KWP, &aes_128_nist_kwp_info },
- { MBEDTLS_CIPHER_AES_192_KWP, &aes_192_nist_kwp_info },
- { MBEDTLS_CIPHER_AES_256_KWP, &aes_256_nist_kwp_info },
-#endif
-
-#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
- { MBEDTLS_CIPHER_NULL, &null_cipher_info },
-#endif /* MBEDTLS_CIPHER_NULL_CIPHER */
-
- { MBEDTLS_CIPHER_NONE, NULL }
-};
-
-#define NUM_CIPHERS ( sizeof(mbedtls_cipher_definitions) / \
- sizeof(mbedtls_cipher_definitions[0]) )
-int mbedtls_cipher_supported[NUM_CIPHERS];
-
-#endif /* MBEDTLS_CIPHER_C */
diff --git a/assets/templates/blackpill/Src/config.h b/assets/templates/blackpill/Src/config.h
deleted file mode 100644
index 953afea..0000000
--- a/assets/templates/blackpill/Src/config.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-#define MBEDTLS_GCM_C
-#define MBEDTLS_CIPHER_C
-#define MBEDTLS_AES_C
-#define MBEDTLS_SELF_TEST
diff --git a/assets/templates/blackpill/Src/gcm.c b/assets/templates/blackpill/Src/gcm.c
deleted file mode 100644
index d3af74c..0000000
--- a/assets/templates/blackpill/Src/gcm.c
+++ /dev/null
@@ -1,1020 +0,0 @@
-/*
- * NIST SP800-38D compliant GCM implementation
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
-
-/*
- * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
- *
- * See also:
- * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
- *
- * We use the algorithm described as Shoup's method with 4-bit tables in
- * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
- */
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_GCM_C)
-
-#include "gcm.h"
-#include "platform_util.h"
-
-#include
-
-#if defined(MBEDTLS_AESNI_C)
-#include "mbedtls/aesni.h"
-#endif
-
-#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
-#include "aes.h"
-#include "platform.h"
-#if !defined(MBEDTLS_PLATFORM_C)
-#include
-#define mbedtls_printf printf
-#endif /* MBEDTLS_PLATFORM_C */
-#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
-
-#if !defined(MBEDTLS_GCM_ALT)
-
-/* Parameter validation macros */
-#define GCM_VALIDATE_RET( cond ) \
- MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
-#define GCM_VALIDATE( cond ) \
- MBEDTLS_INTERNAL_VALIDATE( cond )
-
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
-}
-#endif
-
-/*
- * Initialize a context
- */
-void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
-{
- GCM_VALIDATE( ctx != NULL );
- memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
-}
-
-/*
- * Precompute small multiples of H, that is set
- * HH[i] || HL[i] = H times i,
- * where i is seen as a field element as in [MGV], ie high-order bits
- * correspond to low powers of P. The result is stored in the same way, that
- * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
- * corresponds to P^127.
- */
-static int gcm_gen_table( mbedtls_gcm_context *ctx )
-{
- int ret, i, j;
- uint64_t hi, lo;
- uint64_t vl, vh;
- unsigned char h[16];
- size_t olen = 0;
-
- memset( h, 0, 16 );
- if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
- return( ret );
-
- /* pack h as two 64-bits ints, big-endian */
- GET_UINT32_BE( hi, h, 0 );
- GET_UINT32_BE( lo, h, 4 );
- vh = (uint64_t) hi << 32 | lo;
-
- GET_UINT32_BE( hi, h, 8 );
- GET_UINT32_BE( lo, h, 12 );
- vl = (uint64_t) hi << 32 | lo;
-
- /* 8 = 1000 corresponds to 1 in GF(2^128) */
- ctx->HL[8] = vl;
- ctx->HH[8] = vh;
-
-#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
- /* With CLMUL support, we need only h, not the rest of the table */
- if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
- return( 0 );
-#endif
-
- /* 0 corresponds to 0 in GF(2^128) */
- ctx->HH[0] = 0;
- ctx->HL[0] = 0;
-
- for( i = 4; i > 0; i >>= 1 )
- {
- uint32_t T = ( vl & 1 ) * 0xe1000000U;
- vl = ( vh << 63 ) | ( vl >> 1 );
- vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
-
- ctx->HL[i] = vl;
- ctx->HH[i] = vh;
- }
-
- for( i = 2; i <= 8; i *= 2 )
- {
- uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
- vh = *HiH;
- vl = *HiL;
- for( j = 1; j < i; j++ )
- {
- HiH[j] = vh ^ ctx->HH[j];
- HiL[j] = vl ^ ctx->HL[j];
- }
- }
-
- return( 0 );
-}
-
-int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
- mbedtls_cipher_id_t cipher,
- const unsigned char *key,
- unsigned int keybits )
-{
- int ret;
- const mbedtls_cipher_info_t *cipher_info;
-
- GCM_VALIDATE_RET( ctx != NULL );
- GCM_VALIDATE_RET( key != NULL );
- GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
-
- cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
- MBEDTLS_MODE_ECB );
- if( cipher_info == NULL )
- return( MBEDTLS_ERR_GCM_BAD_INPUT );
-
- if( cipher_info->block_size != 16 )
- return( MBEDTLS_ERR_GCM_BAD_INPUT );
-
- mbedtls_cipher_free( &ctx->cipher_ctx );
-
- if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
- return( ret );
-
- if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
- MBEDTLS_ENCRYPT ) ) != 0 )
- {
- return( ret );
- }
-
- if( ( ret = gcm_gen_table( ctx ) ) != 0 )
- return( ret );
-
- return( 0 );
-}
-
-/*
- * Shoup's method for multiplication use this table with
- * last4[x] = x times P^128
- * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
- */
-static const uint64_t last4[16] =
-{
- 0x0000, 0x1c20, 0x3840, 0x2460,
- 0x7080, 0x6ca0, 0x48c0, 0x54e0,
- 0xe100, 0xfd20, 0xd940, 0xc560,
- 0x9180, 0x8da0, 0xa9c0, 0xb5e0
-};
-
-/*
- * Sets output to x times H using the precomputed tables.
- * x and output are seen as elements of GF(2^128) as in [MGV].
- */
-static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
- unsigned char output[16] )
-{
- int i = 0;
- unsigned char lo, hi, rem;
- uint64_t zh, zl;
-
-#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
- if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
- unsigned char h[16];
-
- PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
- PUT_UINT32_BE( ctx->HH[8], h, 4 );
- PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
- PUT_UINT32_BE( ctx->HL[8], h, 12 );
-
- mbedtls_aesni_gcm_mult( output, x, h );
- return;
- }
-#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
-
- lo = x[15] & 0xf;
-
- zh = ctx->HH[lo];
- zl = ctx->HL[lo];
-
- for( i = 15; i >= 0; i-- )
- {
- lo = x[i] & 0xf;
- hi = x[i] >> 4;
-
- if( i != 15 )
- {
- rem = (unsigned char) zl & 0xf;
- zl = ( zh << 60 ) | ( zl >> 4 );
- zh = ( zh >> 4 );
- zh ^= (uint64_t) last4[rem] << 48;
- zh ^= ctx->HH[lo];
- zl ^= ctx->HL[lo];
-
- }
-
- rem = (unsigned char) zl & 0xf;
- zl = ( zh << 60 ) | ( zl >> 4 );
- zh = ( zh >> 4 );
- zh ^= (uint64_t) last4[rem] << 48;
- zh ^= ctx->HH[hi];
- zl ^= ctx->HL[hi];
- }
-
- PUT_UINT32_BE( zh >> 32, output, 0 );
- PUT_UINT32_BE( zh, output, 4 );
- PUT_UINT32_BE( zl >> 32, output, 8 );
- PUT_UINT32_BE( zl, output, 12 );
-}
-
-int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
- int mode,
- const unsigned char *iv,
- size_t iv_len,
- const unsigned char *add,
- size_t add_len )
-{
- int ret;
- unsigned char work_buf[16];
- size_t i;
- const unsigned char *p;
- size_t use_len, olen = 0;
-
- GCM_VALIDATE_RET( ctx != NULL );
- GCM_VALIDATE_RET( iv != NULL );
- GCM_VALIDATE_RET( add_len == 0 || add != NULL );
-
- /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
- /* IV is not allowed to be zero length */
- if( iv_len == 0 ||
- ( (uint64_t) iv_len ) >> 61 != 0 ||
- ( (uint64_t) add_len ) >> 61 != 0 )
- {
- return( MBEDTLS_ERR_GCM_BAD_INPUT );
- }
-
- memset( ctx->y, 0x00, sizeof(ctx->y) );
- memset( ctx->buf, 0x00, sizeof(ctx->buf) );
-
- ctx->mode = mode;
- ctx->len = 0;
- ctx->add_len = 0;
-
- if( iv_len == 12 )
- {
- memcpy( ctx->y, iv, iv_len );
- ctx->y[15] = 1;
- }
- else
- {
- memset( work_buf, 0x00, 16 );
- PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
-
- p = iv;
- while( iv_len > 0 )
- {
- use_len = ( iv_len < 16 ) ? iv_len : 16;
-
- for( i = 0; i < use_len; i++ )
- ctx->y[i] ^= p[i];
-
- gcm_mult( ctx, ctx->y, ctx->y );
-
- iv_len -= use_len;
- p += use_len;
- }
-
- for( i = 0; i < 16; i++ )
- ctx->y[i] ^= work_buf[i];
-
- gcm_mult( ctx, ctx->y, ctx->y );
- }
-
- if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
- ctx->base_ectr, &olen ) ) != 0 )
- {
- return( ret );
- }
-
- ctx->add_len = add_len;
- p = add;
- while( add_len > 0 )
- {
- use_len = ( add_len < 16 ) ? add_len : 16;
-
- for( i = 0; i < use_len; i++ )
- ctx->buf[i] ^= p[i];
-
- gcm_mult( ctx, ctx->buf, ctx->buf );
-
- add_len -= use_len;
- p += use_len;
- }
-
- return( 0 );
-}
-
-int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
- size_t length,
- const unsigned char *input,
- unsigned char *output )
-{
- int ret;
- unsigned char ectr[16];
- size_t i;
- const unsigned char *p;
- unsigned char *out_p = output;
- size_t use_len, olen = 0;
-
- GCM_VALIDATE_RET( ctx != NULL );
- GCM_VALIDATE_RET( length == 0 || input != NULL );
- GCM_VALIDATE_RET( length == 0 || output != NULL );
-
- if( output > input && (size_t) ( output - input ) < length )
- return( MBEDTLS_ERR_GCM_BAD_INPUT );
-
- /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
- * Also check for possible overflow */
- if( ctx->len + length < ctx->len ||
- (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
- {
- return( MBEDTLS_ERR_GCM_BAD_INPUT );
- }
-
- ctx->len += length;
-
- p = input;
- while( length > 0 )
- {
- use_len = ( length < 16 ) ? length : 16;
-
- for( i = 16; i > 12; i-- )
- if( ++ctx->y[i - 1] != 0 )
- break;
-
- if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
- &olen ) ) != 0 )
- {
- return( ret );
- }
-
- for( i = 0; i < use_len; i++ )
- {
- if( ctx->mode == MBEDTLS_GCM_DECRYPT )
- ctx->buf[i] ^= p[i];
- out_p[i] = ectr[i] ^ p[i];
- if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
- ctx->buf[i] ^= out_p[i];
- }
-
- gcm_mult( ctx, ctx->buf, ctx->buf );
-
- length -= use_len;
- p += use_len;
- out_p += use_len;
- }
-
- return( 0 );
-}
-
-int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
- unsigned char *tag,
- size_t tag_len )
-{
- unsigned char work_buf[16];
- size_t i;
- uint64_t orig_len;
- uint64_t orig_add_len;
-
- GCM_VALIDATE_RET( ctx != NULL );
- GCM_VALIDATE_RET( tag != NULL );
-
- orig_len = ctx->len * 8;
- orig_add_len = ctx->add_len * 8;
-
- if( tag_len > 16 || tag_len < 4 )
- return( MBEDTLS_ERR_GCM_BAD_INPUT );
-
- memcpy( tag, ctx->base_ectr, tag_len );
-
- if( orig_len || orig_add_len )
- {
- memset( work_buf, 0x00, 16 );
-
- PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
- PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
- PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
- PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
-
- for( i = 0; i < 16; i++ )
- ctx->buf[i] ^= work_buf[i];
-
- gcm_mult( ctx, ctx->buf, ctx->buf );
-
- for( i = 0; i < tag_len; i++ )
- tag[i] ^= ctx->buf[i];
- }
-
- return( 0 );
-}
-
-int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
- int mode,
- size_t length,
- const unsigned char *iv,
- size_t iv_len,
- const unsigned char *add,
- size_t add_len,
- const unsigned char *input,
- unsigned char *output,
- size_t tag_len,
- unsigned char *tag )
-{
- int ret;
-
- GCM_VALIDATE_RET( ctx != NULL );
- GCM_VALIDATE_RET( iv != NULL );
- GCM_VALIDATE_RET( add_len == 0 || add != NULL );
- GCM_VALIDATE_RET( length == 0 || input != NULL );
- GCM_VALIDATE_RET( length == 0 || output != NULL );
- GCM_VALIDATE_RET( tag != NULL );
-
- if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
- return( ret );
-
- if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
- return( ret );
-
- if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
- return( ret );
-
- return( 0 );
-}
-
-int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
- size_t length,
- const unsigned char *iv,
- size_t iv_len,
- const unsigned char *add,
- size_t add_len,
- const unsigned char *tag,
- size_t tag_len,
- const unsigned char *input,
- unsigned char *output )
-{
- int ret;
- unsigned char check_tag[16];
- size_t i;
- int diff;
-
- GCM_VALIDATE_RET( ctx != NULL );
- GCM_VALIDATE_RET( iv != NULL );
- GCM_VALIDATE_RET( add_len == 0 || add != NULL );
- GCM_VALIDATE_RET( tag != NULL );
- GCM_VALIDATE_RET( length == 0 || input != NULL );
- GCM_VALIDATE_RET( length == 0 || output != NULL );
-
- if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
- iv, iv_len, add, add_len,
- input, output, tag_len, check_tag ) ) != 0 )
- {
- return( ret );
- }
-
- /* Check tag in "constant-time" */
- for( diff = 0, i = 0; i < tag_len; i++ )
- diff |= tag[i] ^ check_tag[i];
-
- if( diff != 0 )
- {
- mbedtls_platform_zeroize( output, length );
- return( MBEDTLS_ERR_GCM_AUTH_FAILED );
- }
-
- return( 0 );
-}
-
-void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
-{
- if( ctx == NULL )
- return;
- mbedtls_cipher_free( &ctx->cipher_ctx );
- mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
-}
-
-#endif /* !MBEDTLS_GCM_ALT */
-
-#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
-/*
- * AES-GCM test vectors from:
- *
- * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
- */
-#define MAX_TESTS 6
-
-static const int key_index_test_data[MAX_TESTS] =
- { 0, 0, 1, 1, 1, 1 };
-
-static const unsigned char key_test_data[MAX_TESTS][32] =
-{
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
- 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
- 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
- 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
-};
-
-static const size_t iv_len_test_data[MAX_TESTS] =
- { 12, 12, 12, 12, 8, 60 };
-
-static const int iv_index_test_data[MAX_TESTS] =
- { 0, 0, 1, 1, 1, 2 };
-
-static const unsigned char iv_test_data[MAX_TESTS][64] =
-{
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00 },
- { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
- 0xde, 0xca, 0xf8, 0x88 },
- { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
- 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
- 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
- 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
- 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
- 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
- 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
- 0xa6, 0x37, 0xb3, 0x9b },
-};
-
-static const size_t add_len_test_data[MAX_TESTS] =
- { 0, 0, 0, 20, 20, 20 };
-
-static const int add_index_test_data[MAX_TESTS] =
- { 0, 0, 0, 1, 1, 1 };
-
-static const unsigned char additional_test_data[MAX_TESTS][64] =
-{
- { 0x00 },
- { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
- 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
- 0xab, 0xad, 0xda, 0xd2 },
-};
-
-static const size_t pt_len_test_data[MAX_TESTS] =
- { 0, 16, 64, 60, 60, 60 };
-
-static const int pt_index_test_data[MAX_TESTS] =
- { 0, 0, 1, 1, 1, 1 };
-
-static const unsigned char pt_test_data[MAX_TESTS][64] =
-{
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
- 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
- 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
- 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
- 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
- 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
- 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
- 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
-};
-
-static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
-{
- { 0x00 },
- { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
- 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
- { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
- 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
- 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
- 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
- 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
- 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
- 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
- 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
- { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
- 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
- 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
- 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
- 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
- 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
- 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
- 0x3d, 0x58, 0xe0, 0x91 },
- { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
- 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
- 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
- 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
- 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
- 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
- 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
- 0xc2, 0x3f, 0x45, 0x98 },
- { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
- 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
- 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
- 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
- 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
- 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
- 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
- 0x4c, 0x34, 0xae, 0xe5 },
- { 0x00 },
- { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
- 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
- { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
- 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
- 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
- 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
- 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
- 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
- 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
- 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
- { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
- 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
- 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
- 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
- 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
- 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
- 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
- 0xcc, 0xda, 0x27, 0x10 },
- { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
- 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
- 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
- 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
- 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
- 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
- 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
- 0xa0, 0xf0, 0x62, 0xf7 },
- { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
- 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
- 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
- 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
- 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
- 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
- 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
- 0xe9, 0xb7, 0x37, 0x3b },
- { 0x00 },
- { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
- 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
- { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
- 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
- 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
- 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
- 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
- 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
- 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
- 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
- { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
- 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
- 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
- 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
- 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
- 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
- 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
- 0xbc, 0xc9, 0xf6, 0x62 },
- { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
- 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
- 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
- 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
- 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
- 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
- 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
- 0xf4, 0x7c, 0x9b, 0x1f },
- { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
- 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
- 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
- 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
- 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
- 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
- 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
- 0x44, 0xae, 0x7e, 0x3f },
-};
-
-static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
-{
- { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
- 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
- { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
- 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
- { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
- 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
- { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
- 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
- { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
- 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
- { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
- 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
- { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
- 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
- { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
- 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
- { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
- 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
- { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
- 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
- { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
- 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
- { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
- 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
- { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
- 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
- { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
- 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
- { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
- 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
- { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
- 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
- { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
- 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
- { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
- 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
-};
-
-int mbedtls_gcm_self_test( int verbose )
-{
- mbedtls_gcm_context ctx;
- unsigned char buf[64];
- unsigned char tag_buf[16];
- int i, j, ret;
- mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
-
- for( j = 0; j < 3; j++ )
- {
- int key_len = 128 + 64 * j;
-
- for( i = 0; i < MAX_TESTS; i++ )
- {
- mbedtls_gcm_init( &ctx );
-
- if( verbose != 0 )
- mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
- key_len, i, "enc" );
-
- ret = mbedtls_gcm_setkey( &ctx, cipher,
- key_test_data[key_index_test_data[i]],
- key_len );
- /*
- * AES-192 is an optional feature that may be unavailable when
- * there is an alternative underlying implementation i.e. when
- * MBEDTLS_AES_ALT is defined.
- */
- if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
- {
- mbedtls_printf( "skipped\n" );
- break;
- }
- else if( ret != 0 )
- {
- goto exit;
- }
-
- ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
- pt_len_test_data[i],
- iv_test_data[iv_index_test_data[i]],
- iv_len_test_data[i],
- additional_test_data[add_index_test_data[i]],
- add_len_test_data[i],
- pt_test_data[pt_index_test_data[i]],
- buf, 16, tag_buf );
- if( ret != 0 )
- goto exit;
-
- if ( memcmp( buf, ct_test_data[j * 6 + i],
- pt_len_test_data[i] ) != 0 ||
- memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
- {
- ret = 1;
- goto exit;
- }
-
- mbedtls_gcm_free( &ctx );
-
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
-
- mbedtls_gcm_init( &ctx );
-
- if( verbose != 0 )
- mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
- key_len, i, "dec" );
-
- ret = mbedtls_gcm_setkey( &ctx, cipher,
- key_test_data[key_index_test_data[i]],
- key_len );
- if( ret != 0 )
- goto exit;
-
- ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
- pt_len_test_data[i],
- iv_test_data[iv_index_test_data[i]],
- iv_len_test_data[i],
- additional_test_data[add_index_test_data[i]],
- add_len_test_data[i],
- ct_test_data[j * 6 + i], buf, 16, tag_buf );
-
- if( ret != 0 )
- goto exit;
-
- if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
- pt_len_test_data[i] ) != 0 ||
- memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
- {
- ret = 1;
- goto exit;
- }
-
- mbedtls_gcm_free( &ctx );
-
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
-
- mbedtls_gcm_init( &ctx );
-
- if( verbose != 0 )
- mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
- key_len, i, "enc" );
-
- ret = mbedtls_gcm_setkey( &ctx, cipher,
- key_test_data[key_index_test_data[i]],
- key_len );
- if( ret != 0 )
- goto exit;
-
- ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
- iv_test_data[iv_index_test_data[i]],
- iv_len_test_data[i],
- additional_test_data[add_index_test_data[i]],
- add_len_test_data[i] );
- if( ret != 0 )
- goto exit;
-
- if( pt_len_test_data[i] > 32 )
- {
- size_t rest_len = pt_len_test_data[i] - 32;
- ret = mbedtls_gcm_update( &ctx, 32,
- pt_test_data[pt_index_test_data[i]],
- buf );
- if( ret != 0 )
- goto exit;
-
- ret = mbedtls_gcm_update( &ctx, rest_len,
- pt_test_data[pt_index_test_data[i]] + 32,
- buf + 32 );
- if( ret != 0 )
- goto exit;
- }
- else
- {
- ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
- pt_test_data[pt_index_test_data[i]],
- buf );
- if( ret != 0 )
- goto exit;
- }
-
- ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
- if( ret != 0 )
- goto exit;
-
- if( memcmp( buf, ct_test_data[j * 6 + i],
- pt_len_test_data[i] ) != 0 ||
- memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
- {
- ret = 1;
- goto exit;
- }
-
- mbedtls_gcm_free( &ctx );
-
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
-
- mbedtls_gcm_init( &ctx );
-
- if( verbose != 0 )
- mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
- key_len, i, "dec" );
-
- ret = mbedtls_gcm_setkey( &ctx, cipher,
- key_test_data[key_index_test_data[i]],
- key_len );
- if( ret != 0 )
- goto exit;
-
- ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
- iv_test_data[iv_index_test_data[i]],
- iv_len_test_data[i],
- additional_test_data[add_index_test_data[i]],
- add_len_test_data[i] );
- if( ret != 0 )
- goto exit;
-
- if( pt_len_test_data[i] > 32 )
- {
- size_t rest_len = pt_len_test_data[i] - 32;
- ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i],
- buf );
- if( ret != 0 )
- goto exit;
-
- ret = mbedtls_gcm_update( &ctx, rest_len,
- ct_test_data[j * 6 + i] + 32,
- buf + 32 );
- if( ret != 0 )
- goto exit;
- }
- else
- {
- ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
- ct_test_data[j * 6 + i],
- buf );
- if( ret != 0 )
- goto exit;
- }
-
- ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
- if( ret != 0 )
- goto exit;
-
- if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
- pt_len_test_data[i] ) != 0 ||
- memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
- {
- ret = 1;
- goto exit;
- }
-
- mbedtls_gcm_free( &ctx );
-
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
- }
- }
-
- if( verbose != 0 )
- mbedtls_printf( "\n" );
-
- ret = 0;
-
-exit:
- if( ret != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
- mbedtls_gcm_free( &ctx );
- }
-
- return( ret );
-}
-
-#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
-
-#endif /* MBEDTLS_GCM_C */
diff --git a/assets/templates/blackpill/Src/gcm.h b/assets/templates/blackpill/Src/gcm.h
deleted file mode 100644
index fd130ab..0000000
--- a/assets/templates/blackpill/Src/gcm.h
+++ /dev/null
@@ -1,326 +0,0 @@
-/**
- * \file gcm.h
- *
- * \brief This file contains GCM definitions and functions.
- *
- * The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined
- * in D. McGrew, J. Viega, The Galois/Counter Mode of Operation
- * (GCM), Natl. Inst. Stand. Technol.
- *
- * For more information on GCM, see NIST SP 800-38D: Recommendation for
- * Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC.
- *
- */
-/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
- */
-
-#ifndef MBEDTLS_GCM_H
-#define MBEDTLS_GCM_H
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#include "cipher.h"
-
-#include
-
-#define MBEDTLS_GCM_ENCRYPT 1
-#define MBEDTLS_GCM_DECRYPT 0
-
-#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */
-
-/* MBEDTLS_ERR_GCM_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_GCM_HW_ACCEL_FAILED -0x0013 /**< GCM hardware accelerator failed. */
-
-#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if !defined(MBEDTLS_GCM_ALT)
-
-/**
- * \brief The GCM context structure.
- */
-typedef struct mbedtls_gcm_context
-{
- mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */
- uint64_t HL[16]; /*!< Precalculated HTable low. */
- uint64_t HH[16]; /*!< Precalculated HTable high. */
- uint64_t len; /*!< The total length of the encrypted data. */
- uint64_t add_len; /*!< The total length of the additional data. */
- unsigned char base_ectr[16]; /*!< The first ECTR for tag. */
- unsigned char y[16]; /*!< The Y working value. */
- unsigned char buf[16]; /*!< The buf working value. */
- int mode; /*!< The operation to perform:
- #MBEDTLS_GCM_ENCRYPT or
- #MBEDTLS_GCM_DECRYPT. */
-}
-mbedtls_gcm_context;
-
-#else /* !MBEDTLS_GCM_ALT */
-#include "gcm_alt.h"
-#endif /* !MBEDTLS_GCM_ALT */
-
-/**
- * \brief This function initializes the specified GCM context,
- * to make references valid, and prepares the context
- * for mbedtls_gcm_setkey() or mbedtls_gcm_free().
- *
- * The function does not bind the GCM context to a particular
- * cipher, nor set the key. For this purpose, use
- * mbedtls_gcm_setkey().
- *
- * \param ctx The GCM context to initialize. This must not be \c NULL.
- */
-void mbedtls_gcm_init( mbedtls_gcm_context *ctx );
-
-/**
- * \brief This function associates a GCM context with a
- * cipher algorithm and a key.
- *
- * \param ctx The GCM context. This must be initialized.
- * \param cipher The 128-bit block cipher to use.
- * \param key The encryption key. This must be a readable buffer of at
- * least \p keybits bits.
- * \param keybits The key size in bits. Valid options are:
- * - 128 bits
- * - 192 bits
- * - 256 bits
- *
- * \return \c 0 on success.
- * \return A cipher-specific error code on failure.
- */
-int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
- mbedtls_cipher_id_t cipher,
- const unsigned char *key,
- unsigned int keybits );
-
-/**
- * \brief This function performs GCM encryption or decryption of a buffer.
- *
- * \note For encryption, the output buffer can be the same as the
- * input buffer. For decryption, the output buffer cannot be
- * the same as input buffer. If the buffers overlap, the output
- * buffer must trail at least 8 Bytes behind the input buffer.
- *
- * \warning When this function performs a decryption, it outputs the
- * authentication tag and does not verify that the data is
- * authentic. You should use this function to perform encryption
- * only. For decryption, use mbedtls_gcm_auth_decrypt() instead.
- *
- * \param ctx The GCM context to use for encryption or decryption. This
- * must be initialized.
- * \param mode The operation to perform:
- * - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption.
- * The ciphertext is written to \p output and the
- * authentication tag is written to \p tag.
- * - #MBEDTLS_GCM_DECRYPT to perform decryption.
- * The plaintext is written to \p output and the
- * authentication tag is written to \p tag.
- * Note that this mode is not recommended, because it does
- * not verify the authenticity of the data. For this reason,
- * you should use mbedtls_gcm_auth_decrypt() instead of
- * calling this function in decryption mode.
- * \param length The length of the input data, which is equal to the length
- * of the output data.
- * \param iv The initialization vector. This must be a readable buffer of
- * at least \p iv_len Bytes.
- * \param iv_len The length of the IV.
- * \param add The buffer holding the additional data. This must be of at
- * least that size in Bytes.
- * \param add_len The length of the additional data.
- * \param input The buffer holding the input data. If \p length is greater
- * than zero, this must be a readable buffer of at least that
- * size in Bytes.
- * \param output The buffer for holding the output data. If \p length is greater
- * than zero, this must be a writable buffer of at least that
- * size in Bytes.
- * \param tag_len The length of the tag to generate.
- * \param tag The buffer for holding the tag. This must be a readable
- * buffer of at least \p tag_len Bytes.
- *
- * \return \c 0 if the encryption or decryption was performed
- * successfully. Note that in #MBEDTLS_GCM_DECRYPT mode,
- * this does not indicate that the data is authentic.
- * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are
- * not valid or a cipher-specific error code if the encryption
- * or decryption failed.
- */
-int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
- int mode,
- size_t length,
- const unsigned char *iv,
- size_t iv_len,
- const unsigned char *add,
- size_t add_len,
- const unsigned char *input,
- unsigned char *output,
- size_t tag_len,
- unsigned char *tag );
-
-/**
- * \brief This function performs a GCM authenticated decryption of a
- * buffer.
- *
- * \note For decryption, the output buffer cannot be the same as
- * input buffer. If the buffers overlap, the output buffer
- * must trail at least 8 Bytes behind the input buffer.
- *
- * \param ctx The GCM context. This must be initialized.
- * \param length The length of the ciphertext to decrypt, which is also
- * the length of the decrypted plaintext.
- * \param iv The initialization vector. This must be a readable buffer
- * of at least \p iv_len Bytes.
- * \param iv_len The length of the IV.
- * \param add The buffer holding the additional data. This must be of at
- * least that size in Bytes.
- * \param add_len The length of the additional data.
- * \param tag The buffer holding the tag to verify. This must be a
- * readable buffer of at least \p tag_len Bytes.
- * \param tag_len The length of the tag to verify.
- * \param input The buffer holding the ciphertext. If \p length is greater
- * than zero, this must be a readable buffer of at least that
- * size.
- * \param output The buffer for holding the decrypted plaintext. If \p length
- * is greater than zero, this must be a writable buffer of at
- * least that size.
- *
- * \return \c 0 if successful and authenticated.
- * \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match.
- * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are
- * not valid or a cipher-specific error code if the decryption
- * failed.
- */
-int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
- size_t length,
- const unsigned char *iv,
- size_t iv_len,
- const unsigned char *add,
- size_t add_len,
- const unsigned char *tag,
- size_t tag_len,
- const unsigned char *input,
- unsigned char *output );
-
-/**
- * \brief This function starts a GCM encryption or decryption
- * operation.
- *
- * \param ctx The GCM context. This must be initialized.
- * \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or
- * #MBEDTLS_GCM_DECRYPT.
- * \param iv The initialization vector. This must be a readable buffer of
- * at least \p iv_len Bytes.
- * \param iv_len The length of the IV.
- * \param add The buffer holding the additional data, or \c NULL
- * if \p add_len is \c 0.
- * \param add_len The length of the additional data. If \c 0,
- * \p add may be \c NULL.
- *
- * \return \c 0 on success.
- */
-int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
- int mode,
- const unsigned char *iv,
- size_t iv_len,
- const unsigned char *add,
- size_t add_len );
-
-/**
- * \brief This function feeds an input buffer into an ongoing GCM
- * encryption or decryption operation.
- *
- * ` The function expects input to be a multiple of 16
- * Bytes. Only the last call before calling
- * mbedtls_gcm_finish() can be less than 16 Bytes.
- *
- * \note For decryption, the output buffer cannot be the same as
- * input buffer. If the buffers overlap, the output buffer
- * must trail at least 8 Bytes behind the input buffer.
- *
- * \param ctx The GCM context. This must be initialized.
- * \param length The length of the input data. This must be a multiple of
- * 16 except in the last call before mbedtls_gcm_finish().
- * \param input The buffer holding the input data. If \p length is greater
- * than zero, this must be a readable buffer of at least that
- * size in Bytes.
- * \param output The buffer for holding the output data. If \p length is
- * greater than zero, this must be a writable buffer of at
- * least that size in Bytes.
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
- */
-int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
- size_t length,
- const unsigned char *input,
- unsigned char *output );
-
-/**
- * \brief This function finishes the GCM operation and generates
- * the authentication tag.
- *
- * It wraps up the GCM stream, and generates the
- * tag. The tag can have a maximum length of 16 Bytes.
- *
- * \param ctx The GCM context. This must be initialized.
- * \param tag The buffer for holding the tag. This must be a readable
- * buffer of at least \p tag_len Bytes.
- * \param tag_len The length of the tag to generate. This must be at least
- * four.
- *
- * \return \c 0 on success.
- * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
- */
-int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
- unsigned char *tag,
- size_t tag_len );
-
-/**
- * \brief This function clears a GCM context and the underlying
- * cipher sub-context.
- *
- * \param ctx The GCM context to clear. If this is \c NULL, the call has
- * no effect. Otherwise, this must be initialized.
- */
-void mbedtls_gcm_free( mbedtls_gcm_context *ctx );
-
-#if defined(MBEDTLS_SELF_TEST)
-
-/**
- * \brief The GCM checkup routine.
- *
- * \return \c 0 on success.
- * \return \c 1 on failure.
- */
-int mbedtls_gcm_self_test( int verbose );
-
-#endif /* MBEDTLS_SELF_TEST */
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* gcm.h */
diff --git a/assets/templates/blackpill/Src/main.c b/assets/templates/blackpill/Src/main.c
deleted file mode 100644
index 47b5494..0000000
--- a/assets/templates/blackpill/Src/main.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/* USER CODE BEGIN Header */
-/**
- ******************************************************************************
- * @file : main.c
- * @brief : Main program body
- ******************************************************************************
- ** This notice applies to any and all portions of this file
- * that are not between comment pairs USER CODE BEGIN and
- * USER CODE END. Other portions of this file, whether
- * inserted by the user or by software development tools
- * are owned by their respective copyright owners.
- *
- * COPYRIGHT(c) 2019 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-/* USER CODE END Header */
-
-/* Includes ------------------------------------------------------------------*/
-#include "main.h"
-
-/* Private includes ----------------------------------------------------------*/
-/* USER CODE BEGIN Includes */
-
-/* USER CODE END Includes */
-
-/* Private typedef -----------------------------------------------------------*/
-/* USER CODE BEGIN PTD */
-
-/* USER CODE END PTD */
-
-/* Private define ------------------------------------------------------------*/
-/* USER CODE BEGIN PD */
-
-/* USER CODE END PD */
-
-/* Private macro -------------------------------------------------------------*/
-/* USER CODE BEGIN PM */
-
-/* USER CODE END PM */
-
-/* Private variables ---------------------------------------------------------*/
-
-/* USER CODE BEGIN PV */
-
-/* USER CODE END PV */
-
-/* Private function prototypes -----------------------------------------------*/
-void SystemClock_Config(void);
-static void MX_GPIO_Init(void);
-static void MX_USART1_UART_Init(void);
-/* USER CODE BEGIN PFP */
-
-/* USER CODE END PFP */
-
-/* Private user code ---------------------------------------------------------*/
-/* USER CODE BEGIN 0 */
-
-/* USER CODE END 0 */
-
-/**
- * @brief The application entry point.
- * @retval int
- */
-int main(void)
-{
- /* USER CODE BEGIN 1 */
-
- /* USER CODE END 1 */
-
- /* MCU Configuration--------------------------------------------------------*/
-
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
-
-
- LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_AFIO);
- LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
-
- NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
-
- /* System interrupt init*/
-
- /**NOJTAG: JTAG-DP Disabled and SW-DP Enabled
- */
- LL_GPIO_AF_Remap_SWJ_NOJTAG();
-
- /* USER CODE BEGIN Init */
-
- /* USER CODE END Init */
-
- /* Configure the system clock */
- SystemClock_Config();
-
- /* USER CODE BEGIN SysInit */
-
- /* USER CODE END SysInit */
-
- /* Initialize all configured peripherals */
- MX_GPIO_Init();
- MX_USART1_UART_Init();
- /* USER CODE BEGIN 2 */
-
- /* USER CODE END 2 */
-
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- uint8_t trm = 0xFF;
- uint8_t rcv;
-
- while (1)
- {
- /* USER CODE END WHILE */
- while (!LL_USART_IsActiveFlag_TXE(USART1));
- LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_12);
- LL_USART_TransmitData8(USART1, trm);
- LL_mDelay(100);
- while (LL_USART_IsActiveFlag_RXNE(USART1));
- LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_12);
- rcv = LL_USART_ReceiveData8(USART1);
- LL_mDelay(100);
- /* USER CODE BEGIN 3 */
- }
- /* USER CODE END 3 */
-}
-
-/**
- * @brief System Clock Configuration
- * @retval None
- */
-void SystemClock_Config(void)
-{
- LL_FLASH_SetLatency(LL_FLASH_LATENCY_1);
-
- if(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_1)
- {
- Error_Handler();
- }
- LL_RCC_HSI_SetCalibTrimming(16);
- LL_RCC_HSI_Enable();
-
- /* Wait till HSI is ready */
- while(LL_RCC_HSI_IsReady() != 1)
- {
-
- }
- LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, LL_RCC_PLL_MUL_12);
- LL_RCC_PLL_Enable();
-
- /* Wait till PLL is ready */
- while(LL_RCC_PLL_IsReady() != 1)
- {
-
- }
- LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
- LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
- LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
- LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
-
- /* Wait till System clock is ready */
- while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
- {
-
- }
- LL_Init1msTick(48000000);
- LL_SYSTICK_SetClkSource(LL_SYSTICK_CLKSOURCE_HCLK);
- LL_SetSystemCoreClock(48000000);
-}
-
-/**
- * @brief USART1 Initialization Function
- * @param None
- * @retval None
- */
-static void MX_USART1_UART_Init(void)
-{
-
- /* USER CODE BEGIN USART1_Init 0 */
-
- /* USER CODE END USART1_Init 0 */
-
- LL_USART_InitTypeDef USART_InitStruct = {0};
-
- LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
-
- /* Peripheral clock enable */
- LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);
-
- LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA);
- /**USART1 GPIO Configuration
- PA9 ------> USART1_TX
- PA10 ------> USART1_RX
- */
- GPIO_InitStruct.Pin = LL_GPIO_PIN_9;
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
- LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-
- GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
- GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;
- LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-
- /* USER CODE BEGIN USART1_Init 1 */
-
- /* USER CODE END USART1_Init 1 */
- USART_InitStruct.BaudRate = 115200;
- USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
- USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
- USART_InitStruct.Parity = LL_USART_PARITY_NONE;
- USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
- USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
- LL_USART_Init(USART1, &USART_InitStruct);
- LL_USART_ConfigAsyncMode(USART1);
- LL_USART_Enable(USART1);
- /* USER CODE BEGIN USART1_Init 2 */
-
- /* USER CODE END USART1_Init 2 */
-
-}
-
-/**
- * @brief GPIO Initialization Function
- * @param None
- * @retval None
- */
-static void MX_GPIO_Init(void)
-{
- LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
-
- /* GPIO Ports Clock Enable */
- LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOC);
- LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOD);
- LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA);
- LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB);
-
- /**/
- LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_12);
-
- /**/
- GPIO_InitStruct.Pin = LL_GPIO_PIN_13|LL_GPIO_PIN_14|LL_GPIO_PIN_15;
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
- LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
-
- /**/
- GPIO_InitStruct.Pin = LL_GPIO_PIN_0|LL_GPIO_PIN_1;
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
- LL_GPIO_Init(GPIOD, &GPIO_InitStruct);
-
- /**/
- GPIO_InitStruct.Pin = LL_GPIO_PIN_0|LL_GPIO_PIN_1|LL_GPIO_PIN_2|LL_GPIO_PIN_3
- |LL_GPIO_PIN_4|LL_GPIO_PIN_5|LL_GPIO_PIN_6|LL_GPIO_PIN_7
- |LL_GPIO_PIN_8|LL_GPIO_PIN_11|LL_GPIO_PIN_12|LL_GPIO_PIN_15;
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
- LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-
- /**/
- GPIO_InitStruct.Pin = LL_GPIO_PIN_0|LL_GPIO_PIN_1|LL_GPIO_PIN_2|LL_GPIO_PIN_10
- |LL_GPIO_PIN_11|LL_GPIO_PIN_13|LL_GPIO_PIN_14|LL_GPIO_PIN_15
- |LL_GPIO_PIN_3|LL_GPIO_PIN_4|LL_GPIO_PIN_5|LL_GPIO_PIN_6
- |LL_GPIO_PIN_7|LL_GPIO_PIN_8|LL_GPIO_PIN_9;
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
- LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
-
- /**/
- GPIO_InitStruct.Pin = LL_GPIO_PIN_12;
- GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
- LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
-
- /**/
- LL_GPIO_AF_EnableRemap_PD01();
-
-}
-
-/* USER CODE BEGIN 4 */
-
-/* USER CODE END 4 */
-
-/**
- * @brief This function is executed in case of error occurrence.
- * @retval None
- */
-void Error_Handler(void)
-{
- /* USER CODE BEGIN Error_Handler_Debug */
- /* User can add his own implementation to report the HAL error return state */
-
- /* USER CODE END Error_Handler_Debug */
-}
-
-#ifdef USE_FULL_ASSERT
-/**
- * @brief Reports the name of the source file and the source line number
- * where the assert_param error has occurred.
- * @param file: pointer to the source file name
- * @param line: assert_param error line source number
- * @retval None
- */
-void assert_failed(uint8_t *file, uint32_t line)
-{
- /* USER CODE BEGIN 6 */
- /* User can add his own implementation to report the file name and line number,
- tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
- /* USER CODE END 6 */
-}
-#endif /* USE_FULL_ASSERT */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Src/mygcmmain.c b/assets/templates/blackpill/Src/mygcmmain.c
deleted file mode 100644
index b292efc..0000000
--- a/assets/templates/blackpill/Src/mygcmmain.c
+++ /dev/null
@@ -1,54 +0,0 @@
-#include "gcm.h"
-#include "platform_util.h"
-#include
-
-static void single_encryption(void) {
- mbedtls_gcm_context ctx;
- unsigned char buf[64];
- unsigned char tag_buf[16];
- int ret;
- mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
- // 32 bytes.. that's 256 bits
- const unsigned char key[32] = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
- 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
- 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
- 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 };
- unsigned char plaintext[64] = { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
- 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
- 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
- 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
- 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
- 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
- 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
- 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 };
- unsigned char expected_ciphertext[64] = { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
- 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
- 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
- 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
- 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
- 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
- 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
- 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85};
- const unsigned char initial_value[12] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
- 0xde, 0xca, 0xf8, 0x88 };
- const unsigned char additional[] = {};
-
- mbedtls_gcm_init( &ctx );
- // 128 bits, not bytes!
- ret = mbedtls_gcm_setkey( &ctx, cipher, key, 128 );
-
- ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, 64, initial_value, 12, additional, 0, plaintext, buf, 16, tag_buf);
- mbedtls_gcm_free( &ctx );
- if (memcmp(buf, expected_ciphertext, 64) == 0) {
- printf("Local test workerino!\n");
- } else {
- printf("Local test failed -.-\n");
- }
-
-}
-
-int main(void) {
- mbedtls_gcm_self_test(1);
- single_encryption();
- return 0;
-}
diff --git a/assets/templates/blackpill/Src/platform.c b/assets/templates/blackpill/Src/platform.c
deleted file mode 100644
index 8792873..0000000
--- a/assets/templates/blackpill/Src/platform.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * Platform abstraction layer
- *
- * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_PLATFORM_C)
-
-#include "platform.h"
-#include "platform_util.h"
-
-/* The compile time configuration of memory allocation via the macros
- * MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO takes precedence over the runtime
- * configuration via mbedtls_platform_set_calloc_free(). So, omit everything
- * related to the latter if MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO are defined. */
-#if defined(MBEDTLS_PLATFORM_MEMORY) && \
- !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && \
- defined(MBEDTLS_PLATFORM_FREE_MACRO) )
-
-#if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
-static void *platform_calloc_uninit( size_t n, size_t size )
-{
- ((void) n);
- ((void) size);
- return( NULL );
-}
-
-#define MBEDTLS_PLATFORM_STD_CALLOC platform_calloc_uninit
-#endif /* !MBEDTLS_PLATFORM_STD_CALLOC */
-
-#if !defined(MBEDTLS_PLATFORM_STD_FREE)
-static void platform_free_uninit( void *ptr )
-{
- ((void) ptr);
-}
-
-#define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit
-#endif /* !MBEDTLS_PLATFORM_STD_FREE */
-
-static void * (*mbedtls_calloc_func)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC;
-static void (*mbedtls_free_func)( void * ) = MBEDTLS_PLATFORM_STD_FREE;
-
-void * mbedtls_calloc( size_t nmemb, size_t size )
-{
- return (*mbedtls_calloc_func)( nmemb, size );
-}
-
-void mbedtls_free( void * ptr )
-{
- (*mbedtls_free_func)( ptr );
-}
-
-int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
- void (*free_func)( void * ) )
-{
- mbedtls_calloc_func = calloc_func;
- mbedtls_free_func = free_func;
- return( 0 );
-}
-#endif /* MBEDTLS_PLATFORM_MEMORY &&
- !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&
- defined(MBEDTLS_PLATFORM_FREE_MACRO) ) */
-
-#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
-#include
-int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... )
-{
- int ret;
- va_list argp;
-
- va_start( argp, fmt );
- ret = mbedtls_vsnprintf( s, n, fmt, argp );
- va_end( argp );
-
- return( ret );
-}
-#endif
-
-#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
-#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
-/*
- * Make dummy function to prevent NULL pointer dereferences
- */
-static int platform_snprintf_uninit( char * s, size_t n,
- const char * format, ... )
-{
- ((void) s);
- ((void) n);
- ((void) format);
- return( 0 );
-}
-
-#define MBEDTLS_PLATFORM_STD_SNPRINTF platform_snprintf_uninit
-#endif /* !MBEDTLS_PLATFORM_STD_SNPRINTF */
-
-int (*mbedtls_snprintf)( char * s, size_t n,
- const char * format,
- ... ) = MBEDTLS_PLATFORM_STD_SNPRINTF;
-
-int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
- const char * format,
- ... ) )
-{
- mbedtls_snprintf = snprintf_func;
- return( 0 );
-}
-#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
-
-#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
-#include
-int mbedtls_platform_win32_vsnprintf( char *s, size_t n, const char *fmt, va_list arg )
-{
- int ret;
-
- /* Avoid calling the invalid parameter handler by checking ourselves */
- if( s == NULL || n == 0 || fmt == NULL )
- return( -1 );
-
-#if defined(_TRUNCATE)
- ret = vsnprintf_s( s, n, _TRUNCATE, fmt, arg );
-#else
- ret = vsnprintf( s, n, fmt, arg );
- if( ret < 0 || (size_t) ret == n )
- {
- s[n-1] = '\0';
- ret = -1;
- }
-#endif
-
- return( ret );
-}
-#endif
-
-#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT)
-#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF)
-/*
- * Make dummy function to prevent NULL pointer dereferences
- */
-static int platform_vsnprintf_uninit( char * s, size_t n,
- const char * format, va_list arg )
-{
- ((void) s);
- ((void) n);
- ((void) format);
- ((void) arg);
- return( -1 );
-}
-
-#define MBEDTLS_PLATFORM_STD_VSNPRINTF platform_vsnprintf_uninit
-#endif /* !MBEDTLS_PLATFORM_STD_VSNPRINTF */
-
-int (*mbedtls_vsnprintf)( char * s, size_t n,
- const char * format,
- va_list arg ) = MBEDTLS_PLATFORM_STD_VSNPRINTF;
-
-int mbedtls_platform_set_vsnprintf( int (*vsnprintf_func)( char * s, size_t n,
- const char * format,
- va_list arg ) )
-{
- mbedtls_vsnprintf = vsnprintf_func;
- return( 0 );
-}
-#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
-
-#if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
-#if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
-/*
- * Make dummy function to prevent NULL pointer dereferences
- */
-static int platform_printf_uninit( const char *format, ... )
-{
- ((void) format);
- return( 0 );
-}
-
-#define MBEDTLS_PLATFORM_STD_PRINTF platform_printf_uninit
-#endif /* !MBEDTLS_PLATFORM_STD_PRINTF */
-
-int (*mbedtls_printf)( const char *, ... ) = MBEDTLS_PLATFORM_STD_PRINTF;
-
-int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) )
-{
- mbedtls_printf = printf_func;
- return( 0 );
-}
-#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */
-
-#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
-#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF)
-/*
- * Make dummy function to prevent NULL pointer dereferences
- */
-static int platform_fprintf_uninit( FILE *stream, const char *format, ... )
-{
- ((void) stream);
- ((void) format);
- return( 0 );
-}
-
-#define MBEDTLS_PLATFORM_STD_FPRINTF platform_fprintf_uninit
-#endif /* !MBEDTLS_PLATFORM_STD_FPRINTF */
-
-int (*mbedtls_fprintf)( FILE *, const char *, ... ) =
- MBEDTLS_PLATFORM_STD_FPRINTF;
-
-int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *, const char *, ... ) )
-{
- mbedtls_fprintf = fprintf_func;
- return( 0 );
-}
-#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */
-
-#if defined(MBEDTLS_PLATFORM_EXIT_ALT)
-#if !defined(MBEDTLS_PLATFORM_STD_EXIT)
-/*
- * Make dummy function to prevent NULL pointer dereferences
- */
-static void platform_exit_uninit( int status )
-{
- ((void) status);
-}
-
-#define MBEDTLS_PLATFORM_STD_EXIT platform_exit_uninit
-#endif /* !MBEDTLS_PLATFORM_STD_EXIT */
-
-void (*mbedtls_exit)( int status ) = MBEDTLS_PLATFORM_STD_EXIT;
-
-int mbedtls_platform_set_exit( void (*exit_func)( int status ) )
-{
- mbedtls_exit = exit_func;
- return( 0 );
-}
-#endif /* MBEDTLS_PLATFORM_EXIT_ALT */
-
-#if defined(MBEDTLS_HAVE_TIME)
-
-#if defined(MBEDTLS_PLATFORM_TIME_ALT)
-#if !defined(MBEDTLS_PLATFORM_STD_TIME)
-/*
- * Make dummy function to prevent NULL pointer dereferences
- */
-static mbedtls_time_t platform_time_uninit( mbedtls_time_t* timer )
-{
- ((void) timer);
- return( 0 );
-}
-
-#define MBEDTLS_PLATFORM_STD_TIME platform_time_uninit
-#endif /* !MBEDTLS_PLATFORM_STD_TIME */
-
-mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* timer ) = MBEDTLS_PLATFORM_STD_TIME;
-
-int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* timer ) )
-{
- mbedtls_time = time_func;
- return( 0 );
-}
-#endif /* MBEDTLS_PLATFORM_TIME_ALT */
-
-#endif /* MBEDTLS_HAVE_TIME */
-
-#if defined(MBEDTLS_ENTROPY_NV_SEED)
-#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
-/* Default implementations for the platform independent seed functions use
- * standard libc file functions to read from and write to a pre-defined filename
- */
-int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len )
-{
- FILE *file;
- size_t n;
-
- if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL )
- return( -1 );
-
- if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len )
- {
- fclose( file );
- mbedtls_platform_zeroize( buf, buf_len );
- return( -1 );
- }
-
- fclose( file );
- return( (int)n );
-}
-
-int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len )
-{
- FILE *file;
- size_t n;
-
- if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL )
- return -1;
-
- if( ( n = fwrite( buf, 1, buf_len, file ) ) != buf_len )
- {
- fclose( file );
- return -1;
- }
-
- fclose( file );
- return( (int)n );
-}
-#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
-
-#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
-#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ)
-/*
- * Make dummy function to prevent NULL pointer dereferences
- */
-static int platform_nv_seed_read_uninit( unsigned char *buf, size_t buf_len )
-{
- ((void) buf);
- ((void) buf_len);
- return( -1 );
-}
-
-#define MBEDTLS_PLATFORM_STD_NV_SEED_READ platform_nv_seed_read_uninit
-#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_READ */
-
-#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE)
-/*
- * Make dummy function to prevent NULL pointer dereferences
- */
-static int platform_nv_seed_write_uninit( unsigned char *buf, size_t buf_len )
-{
- ((void) buf);
- ((void) buf_len);
- return( -1 );
-}
-
-#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE platform_nv_seed_write_uninit
-#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_WRITE */
-
-int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) =
- MBEDTLS_PLATFORM_STD_NV_SEED_READ;
-int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) =
- MBEDTLS_PLATFORM_STD_NV_SEED_WRITE;
-
-int mbedtls_platform_set_nv_seed(
- int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ),
- int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) )
-{
- mbedtls_nv_seed_read = nv_seed_read_func;
- mbedtls_nv_seed_write = nv_seed_write_func;
- return( 0 );
-}
-#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
-#endif /* MBEDTLS_ENTROPY_NV_SEED */
-
-#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT)
-/*
- * Placeholder platform setup that does nothing by default
- */
-int mbedtls_platform_setup( mbedtls_platform_context *ctx )
-{
- (void)ctx;
-
- return( 0 );
-}
-
-/*
- * Placeholder platform teardown that does nothing by default
- */
-void mbedtls_platform_teardown( mbedtls_platform_context *ctx )
-{
- (void)ctx;
-}
-#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
-
-#endif /* MBEDTLS_PLATFORM_C */
diff --git a/assets/templates/blackpill/Src/platform.h b/assets/templates/blackpill/Src/platform.h
deleted file mode 100644
index 363d6b3..0000000
--- a/assets/templates/blackpill/Src/platform.h
+++ /dev/null
@@ -1,419 +0,0 @@
-/**
- * \file platform.h
- *
- * \brief This file contains the definitions and functions of the
- * Mbed TLS platform abstraction layer.
- *
- * The platform abstraction layer removes the need for the library
- * to directly link to standard C library functions or operating
- * system services, making the library easier to port and embed.
- * Application developers and users of the library can provide their own
- * implementations of these functions, or implementations specific to
- * their platform, which can be statically linked to the library or
- * dynamically configured at runtime.
- */
-/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
- */
-#ifndef MBEDTLS_PLATFORM_H
-#define MBEDTLS_PLATFORM_H
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_HAVE_TIME)
-#include "platform_time.h"
-#endif
-
-#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED -0x0070 /**< Hardware accelerator failed */
-#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED -0x0072 /**< The requested feature is not supported by the platform */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \name SECTION: Module settings
- *
- * The configuration options you can set for this module are in this section.
- * Either change them in config.h or define them on the compiler command line.
- * \{
- */
-
-/* The older Microsoft Windows common runtime provides non-conforming
- * implementations of some standard library functions, including snprintf
- * and vsnprintf. This affects MSVC and MinGW builds.
- */
-#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900)
-#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF
-#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF
-#endif
-
-#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
-#include
-#include
-#include
-#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
-#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
-#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use. */
-#else
-#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< The default \c snprintf function to use. */
-#endif
-#endif
-#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF)
-#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
-#define MBEDTLS_PLATFORM_STD_VSNPRINTF mbedtls_platform_win32_vsnprintf /**< The default \c vsnprintf function to use. */
-#else
-#define MBEDTLS_PLATFORM_STD_VSNPRINTF vsnprintf /**< The default \c vsnprintf function to use. */
-#endif
-#endif
-#if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
-#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< The default \c printf function to use. */
-#endif
-#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF)
-#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< The default \c fprintf function to use. */
-#endif
-#if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
-#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< The default \c calloc function to use. */
-#endif
-#if !defined(MBEDTLS_PLATFORM_STD_FREE)
-#define MBEDTLS_PLATFORM_STD_FREE free /**< The default \c free function to use. */
-#endif
-#if !defined(MBEDTLS_PLATFORM_STD_EXIT)
-#define MBEDTLS_PLATFORM_STD_EXIT exit /**< The default \c exit function to use. */
-#endif
-#if !defined(MBEDTLS_PLATFORM_STD_TIME)
-#define MBEDTLS_PLATFORM_STD_TIME time /**< The default \c time function to use. */
-#endif
-#if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS)
-#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS /**< The default exit value to use. */
-#endif
-#if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE)
-#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE /**< The default exit value to use. */
-#endif
-#if defined(MBEDTLS_FS_IO)
-#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ)
-#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read
-#endif
-#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE)
-#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write
-#endif
-#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE)
-#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile"
-#endif
-#endif /* MBEDTLS_FS_IO */
-#else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
-#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR)
-#include MBEDTLS_PLATFORM_STD_MEM_HDR
-#endif
-#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
-
-
-/* \} name SECTION: Module settings */
-
-/*
- * The function pointers for calloc and free.
- */
-#if defined(MBEDTLS_PLATFORM_MEMORY)
-#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \
- defined(MBEDTLS_PLATFORM_CALLOC_MACRO)
-#define mbedtls_free MBEDTLS_PLATFORM_FREE_MACRO
-#define mbedtls_calloc MBEDTLS_PLATFORM_CALLOC_MACRO
-#else
-/* For size_t */
-#include
-extern void *mbedtls_calloc( size_t n, size_t size );
-extern void mbedtls_free( void *ptr );
-
-/**
- * \brief This function dynamically sets the memory-management
- * functions used by the library, during runtime.
- *
- * \param calloc_func The \c calloc function implementation.
- * \param free_func The \c free function implementation.
- *
- * \return \c 0.
- */
-int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
- void (*free_func)( void * ) );
-#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */
-#else /* !MBEDTLS_PLATFORM_MEMORY */
-#define mbedtls_free free
-#define mbedtls_calloc calloc
-#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */
-
-/*
- * The function pointers for fprintf
- */
-#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
-/* We need FILE * */
-#include
-extern int (*mbedtls_fprintf)( FILE *stream, const char *format, ... );
-
-/**
- * \brief This function dynamically configures the fprintf
- * function that is called when the
- * mbedtls_fprintf() function is invoked by the library.
- *
- * \param fprintf_func The \c fprintf function implementation.
- *
- * \return \c 0.
- */
-int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *,
- ... ) );
-#else
-#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO)
-#define mbedtls_fprintf MBEDTLS_PLATFORM_FPRINTF_MACRO
-#else
-#define mbedtls_fprintf fprintf
-#endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */
-#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */
-
-/*
- * The function pointers for printf
- */
-#if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
-extern int (*mbedtls_printf)( const char *format, ... );
-
-/**
- * \brief This function dynamically configures the snprintf
- * function that is called when the mbedtls_snprintf()
- * function is invoked by the library.
- *
- * \param printf_func The \c printf function implementation.
- *
- * \return \c 0 on success.
- */
-int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) );
-#else /* !MBEDTLS_PLATFORM_PRINTF_ALT */
-#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO)
-#define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO
-#else
-#define mbedtls_printf printf
-#endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */
-#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */
-
-/*
- * The function pointers for snprintf
- *
- * The snprintf implementation should conform to C99:
- * - it *must* always correctly zero-terminate the buffer
- * (except when n == 0, then it must leave the buffer untouched)
- * - however it is acceptable to return -1 instead of the required length when
- * the destination buffer is too short.
- */
-#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
-/* For Windows (inc. MSYS2), we provide our own fixed implementation */
-int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... );
-#endif
-
-#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
-extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... );
-
-/**
- * \brief This function allows configuring a custom
- * \c snprintf function pointer.
- *
- * \param snprintf_func The \c snprintf function implementation.
- *
- * \return \c 0 on success.
- */
-int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
- const char * format, ... ) );
-#else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
-#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
-#define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO
-#else
-#define mbedtls_snprintf MBEDTLS_PLATFORM_STD_SNPRINTF
-#endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */
-#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
-
-/*
- * The function pointers for vsnprintf
- *
- * The vsnprintf implementation should conform to C99:
- * - it *must* always correctly zero-terminate the buffer
- * (except when n == 0, then it must leave the buffer untouched)
- * - however it is acceptable to return -1 instead of the required length when
- * the destination buffer is too short.
- */
-#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
-#include
-/* For Older Windows (inc. MSYS2), we provide our own fixed implementation */
-int mbedtls_platform_win32_vsnprintf( char *s, size_t n, const char *fmt, va_list arg );
-#endif
-
-#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT)
-#include
-extern int (*mbedtls_vsnprintf)( char * s, size_t n, const char * format, va_list arg );
-
-/**
- * \brief Set your own snprintf function pointer
- *
- * \param vsnprintf_func The \c vsnprintf function implementation
- *
- * \return \c 0
- */
-int mbedtls_platform_set_vsnprintf( int (*vsnprintf_func)( char * s, size_t n,
- const char * format, va_list arg ) );
-#else /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
-#if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
-#define mbedtls_vsnprintf MBEDTLS_PLATFORM_VSNPRINTF_MACRO
-#else
-#define mbedtls_vsnprintf vsnprintf
-#endif /* MBEDTLS_PLATFORM_VSNPRINTF_MACRO */
-#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
-
-/*
- * The function pointers for exit
- */
-#if defined(MBEDTLS_PLATFORM_EXIT_ALT)
-extern void (*mbedtls_exit)( int status );
-
-/**
- * \brief This function dynamically configures the exit
- * function that is called when the mbedtls_exit()
- * function is invoked by the library.
- *
- * \param exit_func The \c exit function implementation.
- *
- * \return \c 0 on success.
- */
-int mbedtls_platform_set_exit( void (*exit_func)( int status ) );
-#else
-#if defined(MBEDTLS_PLATFORM_EXIT_MACRO)
-#define mbedtls_exit MBEDTLS_PLATFORM_EXIT_MACRO
-#else
-#define mbedtls_exit exit
-#endif /* MBEDTLS_PLATFORM_EXIT_MACRO */
-#endif /* MBEDTLS_PLATFORM_EXIT_ALT */
-
-/*
- * The default exit values
- */
-#if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS)
-#define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS
-#else
-#define MBEDTLS_EXIT_SUCCESS 0
-#endif
-#if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE)
-#define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE
-#else
-#define MBEDTLS_EXIT_FAILURE 1
-#endif
-
-/*
- * The function pointers for reading from and writing a seed file to
- * Non-Volatile storage (NV) in a platform-independent way
- *
- * Only enabled when the NV seed entropy source is enabled
- */
-#if defined(MBEDTLS_ENTROPY_NV_SEED)
-#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
-/* Internal standard platform definitions */
-int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len );
-int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len );
-#endif
-
-#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
-extern int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len );
-extern int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len );
-
-/**
- * \brief This function allows configuring custom seed file writing and
- * reading functions.
- *
- * \param nv_seed_read_func The seed reading function implementation.
- * \param nv_seed_write_func The seed writing function implementation.
- *
- * \return \c 0 on success.
- */
-int mbedtls_platform_set_nv_seed(
- int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ),
- int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len )
- );
-#else
-#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \
- defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO)
-#define mbedtls_nv_seed_read MBEDTLS_PLATFORM_NV_SEED_READ_MACRO
-#define mbedtls_nv_seed_write MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO
-#else
-#define mbedtls_nv_seed_read mbedtls_platform_std_nv_seed_read
-#define mbedtls_nv_seed_write mbedtls_platform_std_nv_seed_write
-#endif
-#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
-#endif /* MBEDTLS_ENTROPY_NV_SEED */
-
-#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT)
-
-/**
- * \brief The platform context structure.
- *
- * \note This structure may be used to assist platform-specific
- * setup or teardown operations.
- */
-typedef struct mbedtls_platform_context
-{
- char dummy; /**< A placeholder member, as empty structs are not portable. */
-}
-mbedtls_platform_context;
-
-#else
-#include "platform_alt.h"
-#endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
-
-/**
- * \brief This function performs any platform-specific initialization
- * operations.
- *
- * \note This function should be called before any other library functions.
- *
- * Its implementation is platform-specific, and unless
- * platform-specific code is provided, it does nothing.
- *
- * \note The usage and necessity of this function is dependent on the platform.
- *
- * \param ctx The platform context.
- *
- * \return \c 0 on success.
- */
-int mbedtls_platform_setup( mbedtls_platform_context *ctx );
-/**
- * \brief This function performs any platform teardown operations.
- *
- * \note This function should be called after every other Mbed TLS module
- * has been correctly freed using the appropriate free function.
- *
- * Its implementation is platform-specific, and unless
- * platform-specific code is provided, it does nothing.
- *
- * \note The usage and necessity of this function is dependent on the platform.
- *
- * \param ctx The platform context.
- *
- */
-void mbedtls_platform_teardown( mbedtls_platform_context *ctx );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* platform.h */
diff --git a/assets/templates/blackpill/Src/platform_time.h b/assets/templates/blackpill/Src/platform_time.h
deleted file mode 100644
index 2ed36f5..0000000
--- a/assets/templates/blackpill/Src/platform_time.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * \file platform_time.h
- *
- * \brief mbed TLS Platform time abstraction
- */
-/*
- * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
-#ifndef MBEDTLS_PLATFORM_TIME_H
-#define MBEDTLS_PLATFORM_TIME_H
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \name SECTION: Module settings
- *
- * The configuration options you can set for this module are in this section.
- * Either change them in config.h or define them on the compiler command line.
- * \{
- */
-
-/*
- * The time_t datatype
- */
-#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO)
-typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t;
-#else
-/* For time_t */
-#include
-typedef time_t mbedtls_time_t;
-#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */
-
-/*
- * The function pointers for time
- */
-#if defined(MBEDTLS_PLATFORM_TIME_ALT)
-extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time );
-
-/**
- * \brief Set your own time function pointer
- *
- * \param time_func the time function implementation
- *
- * \return 0
- */
-int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) );
-#else
-#if defined(MBEDTLS_PLATFORM_TIME_MACRO)
-#define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO
-#else
-#define mbedtls_time time
-#endif /* MBEDTLS_PLATFORM_TIME_MACRO */
-#endif /* MBEDTLS_PLATFORM_TIME_ALT */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* platform_time.h */
diff --git a/assets/templates/blackpill/Src/platform_util.c b/assets/templates/blackpill/Src/platform_util.c
deleted file mode 100644
index 04a64b3..0000000
--- a/assets/templates/blackpill/Src/platform_util.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Common and shared functions used by multiple modules in the Mbed TLS
- * library.
- *
- * Copyright (C) 2018, Arm Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
- */
-
-/*
- * Ensure gmtime_r is available even with -std=c99; must be defined before
- * config.h, which pulls in glibc's features.h. Harmless on other platforms.
- */
-#if !defined(_POSIX_C_SOURCE)
-#define _POSIX_C_SOURCE 200112L
-#endif
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#include "platform_util.h"
-#include "platform.h"
-#include "threading.h"
-
-#include
-#include
-
-#if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT)
-/*
- * This implementation should never be optimized out by the compiler
- *
- * This implementation for mbedtls_platform_zeroize() was inspired from Colin
- * Percival's blog article at:
- *
- * http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html
- *
- * It uses a volatile function pointer to the standard memset(). Because the
- * pointer is volatile the compiler expects it to change at
- * any time and will not optimize out the call that could potentially perform
- * other operations on the input buffer instead of just setting it to 0.
- * Nevertheless, as pointed out by davidtgoldblatt on Hacker News
- * (refer to http://www.daemonology.net/blog/2014-09-05-erratum.html for
- * details), optimizations of the following form are still possible:
- *
- * if( memset_func != memset )
- * memset_func( buf, 0, len );
- *
- * Note that it is extremely difficult to guarantee that
- * mbedtls_platform_zeroize() will not be optimized out by aggressive compilers
- * in a portable way. For this reason, Mbed TLS also provides the configuration
- * option MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure
- * mbedtls_platform_zeroize() to use a suitable implementation for their
- * platform and needs.
- */
-static void * (* const volatile memset_func)( void *, int, size_t ) = memset;
-
-void mbedtls_platform_zeroize( void *buf, size_t len )
-{
- memset_func( buf, 0, len );
-}
-#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */
-
-#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
-#include
-#if !defined(_WIN32) && (defined(unix) || \
- defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \
- defined(__MACH__)))
-#include
-#endif /* !_WIN32 && (unix || __unix || __unix__ ||
- * (__APPLE__ && __MACH__)) */
-
-#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
- ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
- _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) )
-/*
- * This is a convenience shorthand macro to avoid checking the long
- * preprocessor conditions above. Ideally, we could expose this macro in
- * platform_util.h and simply use it in platform_util.c, threading.c and
- * threading.h. However, this macro is not part of the Mbed TLS public API, so
- * we keep it private by only defining it in this file
- */
-#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) )
-#define PLATFORM_UTIL_USE_GMTIME
-#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */
-
-#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
- ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
- _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */
-
-struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
- struct tm *tm_buf )
-{
-#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
- return( ( gmtime_s( tm_buf, tt ) == 0 ) ? tm_buf : NULL );
-#elif !defined(PLATFORM_UTIL_USE_GMTIME)
- return( gmtime_r( tt, tm_buf ) );
-#else
- struct tm *lt;
-
-#if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 )
- return( NULL );
-#endif /* MBEDTLS_THREADING_C */
-
- lt = gmtime( tt );
-
- if( lt != NULL )
- {
- memcpy( tm_buf, lt, sizeof( struct tm ) );
- }
-
-#if defined(MBEDTLS_THREADING_C)
- if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 )
- return( NULL );
-#endif /* MBEDTLS_THREADING_C */
-
- return( ( lt == NULL ) ? NULL : tm_buf );
-#endif /* _WIN32 && !EFIX64 && !EFI32 */
-}
-#endif /* MBEDTLS_HAVE_TIME_DATE && MBEDTLS_PLATFORM_GMTIME_R_ALT */
diff --git a/assets/templates/blackpill/Src/platform_util.h b/assets/templates/blackpill/Src/platform_util.h
deleted file mode 100644
index 09d0965..0000000
--- a/assets/templates/blackpill/Src/platform_util.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/**
- * \file platform_util.h
- *
- * \brief Common and shared functions used by multiple modules in the Mbed TLS
- * library.
- */
-/*
- * Copyright (C) 2018, Arm Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
- */
-#ifndef MBEDTLS_PLATFORM_UTIL_H
-#define MBEDTLS_PLATFORM_UTIL_H
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#include
-#if defined(MBEDTLS_HAVE_TIME_DATE)
-#include "platform_time.h"
-#include
-#endif /* MBEDTLS_HAVE_TIME_DATE */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined(MBEDTLS_CHECK_PARAMS)
-
-#if defined(MBEDTLS_CHECK_PARAMS_ASSERT)
-/* Allow the user to define MBEDTLS_PARAM_FAILED to something like assert
- * (which is what our config.h suggests). */
-#include
-#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */
-
-#if defined(MBEDTLS_PARAM_FAILED)
-/** An alternative definition of MBEDTLS_PARAM_FAILED has been set in config.h.
- *
- * This flag can be used to check whether it is safe to assume that
- * MBEDTLS_PARAM_FAILED() will expand to a call to mbedtls_param_failed().
- */
-#define MBEDTLS_PARAM_FAILED_ALT
-
-#elif defined(MBEDTLS_CHECK_PARAMS_ASSERT)
-#define MBEDTLS_PARAM_FAILED( cond ) assert( cond )
-#define MBEDTLS_PARAM_FAILED_ALT
-
-#else /* MBEDTLS_PARAM_FAILED */
-#define MBEDTLS_PARAM_FAILED( cond ) \
- mbedtls_param_failed( #cond, __FILE__, __LINE__ )
-
-/**
- * \brief User supplied callback function for parameter validation failure.
- * See #MBEDTLS_CHECK_PARAMS for context.
- *
- * This function will be called unless an alternative treatement
- * is defined through the #MBEDTLS_PARAM_FAILED macro.
- *
- * This function can return, and the operation will be aborted, or
- * alternatively, through use of setjmp()/longjmp() can resume
- * execution in the application code.
- *
- * \param failure_condition The assertion that didn't hold.
- * \param file The file where the assertion failed.
- * \param line The line in the file where the assertion failed.
- */
-void mbedtls_param_failed( const char *failure_condition,
- const char *file,
- int line );
-#endif /* MBEDTLS_PARAM_FAILED */
-
-/* Internal macro meant to be called only from within the library. */
-#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) \
- do { \
- if( !(cond) ) \
- { \
- MBEDTLS_PARAM_FAILED( cond ); \
- return( ret ); \
- } \
- } while( 0 )
-
-/* Internal macro meant to be called only from within the library. */
-#define MBEDTLS_INTERNAL_VALIDATE( cond ) \
- do { \
- if( !(cond) ) \
- { \
- MBEDTLS_PARAM_FAILED( cond ); \
- return; \
- } \
- } while( 0 )
-
-#else /* MBEDTLS_CHECK_PARAMS */
-
-/* Internal macros meant to be called only from within the library. */
-#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) do { } while( 0 )
-#define MBEDTLS_INTERNAL_VALIDATE( cond ) do { } while( 0 )
-
-#endif /* MBEDTLS_CHECK_PARAMS */
-
-/* Internal helper macros for deprecating API constants. */
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-#if defined(MBEDTLS_DEPRECATED_WARNING)
-/* Deliberately don't (yet) export MBEDTLS_DEPRECATED here
- * to avoid conflict with other headers which define and use
- * it, too. We might want to move all these definitions here at
- * some point for uniformity. */
-#define MBEDTLS_DEPRECATED __attribute__((deprecated))
-MBEDTLS_DEPRECATED typedef char const * mbedtls_deprecated_string_constant_t;
-#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) \
- ( (mbedtls_deprecated_string_constant_t) ( VAL ) )
-MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t;
-#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) \
- ( (mbedtls_deprecated_numeric_constant_t) ( VAL ) )
-#undef MBEDTLS_DEPRECATED
-#else /* MBEDTLS_DEPRECATED_WARNING */
-#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) VAL
-#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) VAL
-#endif /* MBEDTLS_DEPRECATED_WARNING */
-#endif /* MBEDTLS_DEPRECATED_REMOVED */
-
-/**
- * \brief Securely zeroize a buffer
- *
- * The function is meant to wipe the data contained in a buffer so
- * that it can no longer be recovered even if the program memory
- * is later compromised. Call this function on sensitive data
- * stored on the stack before returning from a function, and on
- * sensitive data stored on the heap before freeing the heap
- * object.
- *
- * It is extremely difficult to guarantee that calls to
- * mbedtls_platform_zeroize() are not removed by aggressive
- * compiler optimizations in a portable way. For this reason, Mbed
- * TLS provides the configuration option
- * MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure
- * mbedtls_platform_zeroize() to use a suitable implementation for
- * their platform and needs
- *
- * \param buf Buffer to be zeroized
- * \param len Length of the buffer in bytes
- *
- */
-void mbedtls_platform_zeroize( void *buf, size_t len );
-
-#if defined(MBEDTLS_HAVE_TIME_DATE)
-/**
- * \brief Platform-specific implementation of gmtime_r()
- *
- * The function is a thread-safe abstraction that behaves
- * similarly to the gmtime_r() function from Unix/POSIX.
- *
- * Mbed TLS will try to identify the underlying platform and
- * make use of an appropriate underlying implementation (e.g.
- * gmtime_r() for POSIX and gmtime_s() for Windows). If this is
- * not possible, then gmtime() will be used. In this case, calls
- * from the library to gmtime() will be guarded by the mutex
- * mbedtls_threading_gmtime_mutex if MBEDTLS_THREADING_C is
- * enabled. It is recommended that calls from outside the library
- * are also guarded by this mutex.
- *
- * If MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, then Mbed TLS will
- * unconditionally use the alternative implementation for
- * mbedtls_platform_gmtime_r() supplied by the user at compile time.
- *
- * \param tt Pointer to an object containing time (in seconds) since the
- * epoch to be converted
- * \param tm_buf Pointer to an object where the results will be stored
- *
- * \return Pointer to an object of type struct tm on success, otherwise
- * NULL
- */
-struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
- struct tm *tm_buf );
-#endif /* MBEDTLS_HAVE_TIME_DATE */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* MBEDTLS_PLATFORM_UTIL_H */
diff --git a/assets/templates/blackpill/Src/stm32f1xx_it.c b/assets/templates/blackpill/Src/stm32f1xx_it.c
deleted file mode 100644
index 5d3e7fa..0000000
--- a/assets/templates/blackpill/Src/stm32f1xx_it.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/* USER CODE BEGIN Header */
-/**
- ******************************************************************************
- * @file stm32f1xx_it.c
- * @brief Interrupt Service Routines.
- ******************************************************************************
- *
- * COPYRIGHT(c) 2019 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-/* USER CODE END Header */
-
-/* Includes ------------------------------------------------------------------*/
-#include "main.h"
-#include "stm32f1xx_it.h"
-/* Private includes ----------------------------------------------------------*/
-/* USER CODE BEGIN Includes */
-/* USER CODE END Includes */
-
-/* Private typedef -----------------------------------------------------------*/
-/* USER CODE BEGIN TD */
-
-/* USER CODE END TD */
-
-/* Private define ------------------------------------------------------------*/
-/* USER CODE BEGIN PD */
-
-/* USER CODE END PD */
-
-/* Private macro -------------------------------------------------------------*/
-/* USER CODE BEGIN PM */
-
-/* USER CODE END PM */
-
-/* Private variables ---------------------------------------------------------*/
-/* USER CODE BEGIN PV */
-
-/* USER CODE END PV */
-
-/* Private function prototypes -----------------------------------------------*/
-/* USER CODE BEGIN PFP */
-
-/* USER CODE END PFP */
-
-/* Private user code ---------------------------------------------------------*/
-/* USER CODE BEGIN 0 */
-
-/* USER CODE END 0 */
-
-/* External variables --------------------------------------------------------*/
-/* USER CODE BEGIN EV */
-
-/* USER CODE END EV */
-
-/******************************************************************************/
-/* Cortex-M3 Processor Interruption and Exception Handlers */
-/******************************************************************************/
-/**
- * @brief This function handles Non maskable interrupt.
- */
-void NMI_Handler(void)
-{
- /* USER CODE BEGIN NonMaskableInt_IRQn 0 */
-
- /* USER CODE END NonMaskableInt_IRQn 0 */
- /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
-
- /* USER CODE END NonMaskableInt_IRQn 1 */
-}
-
-/**
- * @brief This function handles Hard fault interrupt.
- */
-void HardFault_Handler(void)
-{
- /* USER CODE BEGIN HardFault_IRQn 0 */
-
- /* USER CODE END HardFault_IRQn 0 */
- while (1)
- {
- /* USER CODE BEGIN W1_HardFault_IRQn 0 */
- /* USER CODE END W1_HardFault_IRQn 0 */
- }
-}
-
-/**
- * @brief This function handles Memory management fault.
- */
-void MemManage_Handler(void)
-{
- /* USER CODE BEGIN MemoryManagement_IRQn 0 */
-
- /* USER CODE END MemoryManagement_IRQn 0 */
- while (1)
- {
- /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
- /* USER CODE END W1_MemoryManagement_IRQn 0 */
- }
-}
-
-/**
- * @brief This function handles Prefetch fault, memory access fault.
- */
-void BusFault_Handler(void)
-{
- /* USER CODE BEGIN BusFault_IRQn 0 */
-
- /* USER CODE END BusFault_IRQn 0 */
- while (1)
- {
- /* USER CODE BEGIN W1_BusFault_IRQn 0 */
- /* USER CODE END W1_BusFault_IRQn 0 */
- }
-}
-
-/**
- * @brief This function handles Undefined instruction or illegal state.
- */
-void UsageFault_Handler(void)
-{
- /* USER CODE BEGIN UsageFault_IRQn 0 */
-
- /* USER CODE END UsageFault_IRQn 0 */
- while (1)
- {
- /* USER CODE BEGIN W1_UsageFault_IRQn 0 */
- /* USER CODE END W1_UsageFault_IRQn 0 */
- }
-}
-
-/**
- * @brief This function handles System service call via SWI instruction.
- */
-void SVC_Handler(void)
-{
- /* USER CODE BEGIN SVCall_IRQn 0 */
-
- /* USER CODE END SVCall_IRQn 0 */
- /* USER CODE BEGIN SVCall_IRQn 1 */
-
- /* USER CODE END SVCall_IRQn 1 */
-}
-
-/**
- * @brief This function handles Debug monitor.
- */
-void DebugMon_Handler(void)
-{
- /* USER CODE BEGIN DebugMonitor_IRQn 0 */
-
- /* USER CODE END DebugMonitor_IRQn 0 */
- /* USER CODE BEGIN DebugMonitor_IRQn 1 */
-
- /* USER CODE END DebugMonitor_IRQn 1 */
-}
-
-/**
- * @brief This function handles Pendable request for system service.
- */
-void PendSV_Handler(void)
-{
- /* USER CODE BEGIN PendSV_IRQn 0 */
-
- /* USER CODE END PendSV_IRQn 0 */
- /* USER CODE BEGIN PendSV_IRQn 1 */
-
- /* USER CODE END PendSV_IRQn 1 */
-}
-
-/**
- * @brief This function handles System tick timer.
- */
-void SysTick_Handler(void)
-{
- /* USER CODE BEGIN SysTick_IRQn 0 */
-
- /* USER CODE END SysTick_IRQn 0 */
-
- /* USER CODE BEGIN SysTick_IRQn 1 */
-
- /* USER CODE END SysTick_IRQn 1 */
-}
-
-/******************************************************************************/
-/* STM32F1xx Peripheral Interrupt Handlers */
-/* Add here the Interrupt Handlers for the used peripherals. */
-/* For the available peripheral interrupt handler names, */
-/* please refer to the startup file (startup_stm32f1xx.s). */
-/******************************************************************************/
-
-/* USER CODE BEGIN 1 */
-
-/* USER CODE END 1 */
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Src/system_stm32f1xx.c b/assets/templates/blackpill/Src/system_stm32f1xx.c
deleted file mode 100644
index 789b551..0000000
--- a/assets/templates/blackpill/Src/system_stm32f1xx.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/**
- ******************************************************************************
- * @file system_stm32f1xx.c
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @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_stm32f1xx_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_stm32f1xx_xx.s" file, to
- * configure the system clock before to branch to main program.
- *
- * 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depending on
- * the product used), refer to "HSE_VALUE".
- * 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
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
-/** @addtogroup CMSIS
- * @{
- */
-
-/** @addtogroup stm32f1xx_system
- * @{
- */
-
-/** @addtogroup STM32F1xx_System_Private_Includes
- * @{
- */
-
-#include "stm32f1xx.h"
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F1xx_System_Private_TypesDefinitions
- * @{
- */
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F1xx_System_Private_Defines
- * @{
- */
-
-#if !defined (HSE_VALUE)
- #define HSE_VALUE 8000000U /*!< Default value of the External oscillator in Hz.
- This value can be provided and adapted by the user application. */
-#endif /* HSE_VALUE */
-
-#if !defined (HSI_VALUE)
- #define HSI_VALUE 8000000U /*!< Default value of the Internal oscillator in Hz.
- This value can be provided and adapted by the user application. */
-#endif /* HSI_VALUE */
-
-/*!< Uncomment the following line if you need to use external SRAM */
-#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
-/* #define DATA_IN_ExtSRAM */
-#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
-
-/*!< Uncomment the following line if you need to relocate your vector Table in
- Internal SRAM. */
-/* #define VECT_TAB_SRAM */
-#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
- This value must be a multiple of 0x200. */
-
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F1xx_System_Private_Macros
- * @{
- */
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F1xx_System_Private_Variables
- * @{
- */
-
-/*******************************************************************************
-* Clock Definitions
-*******************************************************************************/
-#if defined(STM32F100xB) ||defined(STM32F100xE)
- uint32_t SystemCoreClock = 24000000U; /*!< System Clock Frequency (Core Clock) */
-#else /*!< HSI Selected as System Clock source */
- uint32_t SystemCoreClock = 72000000U; /*!< System Clock Frequency (Core Clock) */
-#endif
-
-const uint8_t AHBPrescTable[16U] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
-const uint8_t APBPrescTable[8U] = {0, 0, 0, 0, 1, 2, 3, 4};
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F1xx_System_Private_FunctionPrototypes
- * @{
- */
-
-#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
-#ifdef DATA_IN_ExtSRAM
- static void SystemInit_ExtMemCtl(void);
-#endif /* DATA_IN_ExtSRAM */
-#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
-
-/**
- * @}
- */
-
-/** @addtogroup STM32F1xx_System_Private_Functions
- * @{
- */
-
-/**
- * @brief Setup the microcontroller system
- * Initialize the Embedded Flash Interface, the PLL and update the
- * SystemCoreClock variable.
- * @note This function should be used only after reset.
- * @param None
- * @retval None
- */
-void SystemInit (void)
-{
- /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
- /* Set HSION bit */
- RCC->CR |= 0x00000001U;
-
- /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
-#if !defined(STM32F105xC) && !defined(STM32F107xC)
- RCC->CFGR &= 0xF8FF0000U;
-#else
- RCC->CFGR &= 0xF0FF0000U;
-#endif /* STM32F105xC */
-
- /* Reset HSEON, CSSON and PLLON bits */
- RCC->CR &= 0xFEF6FFFFU;
-
- /* Reset HSEBYP bit */
- RCC->CR &= 0xFFFBFFFFU;
-
- /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
- RCC->CFGR &= 0xFF80FFFFU;
-
-#if defined(STM32F105xC) || defined(STM32F107xC)
- /* Reset PLL2ON and PLL3ON bits */
- RCC->CR &= 0xEBFFFFFFU;
-
- /* Disable all interrupts and clear pending bits */
- RCC->CIR = 0x00FF0000U;
-
- /* Reset CFGR2 register */
- RCC->CFGR2 = 0x00000000U;
-#elif defined(STM32F100xB) || defined(STM32F100xE)
- /* Disable all interrupts and clear pending bits */
- RCC->CIR = 0x009F0000U;
-
- /* Reset CFGR2 register */
- RCC->CFGR2 = 0x00000000U;
-#else
- /* Disable all interrupts and clear pending bits */
- RCC->CIR = 0x009F0000U;
-#endif /* STM32F105xC */
-
-#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
- #ifdef DATA_IN_ExtSRAM
- SystemInit_ExtMemCtl();
- #endif /* DATA_IN_ExtSRAM */
-#endif
-
-#ifdef VECT_TAB_SRAM
- SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
-#else
- SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
-#endif
-}
-
-/**
- * @brief Update SystemCoreClock variable according to Clock Register Values.
- * The SystemCoreClock variable contains the core clock (HCLK), it can
- * be used by the user application to setup the SysTick timer or configure
- * other parameters.
- *
- * @note Each time the core clock (HCLK) changes, this function must be called
- * to update SystemCoreClock variable value. Otherwise, any configuration
- * based on this variable will be incorrect.
- *
- * @note - The system frequency computed by this function is not the real
- * frequency in the chip. It is calculated based on the predefined
- * constant and the selected clock source:
- *
- * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
- *
- * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
- *
- * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
- * or HSI_VALUE(*) multiplied by the PLL factors.
- *
- * (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
- * 8 MHz) but the real value may vary depending on the variations
- * in voltage and temperature.
- *
- * (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
- * 8 MHz or 25 MHz, depending on the product used), user has to ensure
- * that HSE_VALUE is same as the real frequency of the crystal used.
- * Otherwise, this function may have wrong result.
- *
- * - The result of this function could be not correct when using fractional
- * value for HSE crystal.
- * @param None
- * @retval None
- */
-void SystemCoreClockUpdate (void)
-{
- uint32_t tmp = 0U, pllmull = 0U, pllsource = 0U;
-
-#if defined(STM32F105xC) || defined(STM32F107xC)
- uint32_t prediv1source = 0U, prediv1factor = 0U, prediv2factor = 0U, pll2mull = 0U;
-#endif /* STM32F105xC */
-
-#if defined(STM32F100xB) || defined(STM32F100xE)
- uint32_t prediv1factor = 0U;
-#endif /* STM32F100xB or STM32F100xE */
-
- /* Get SYSCLK source -------------------------------------------------------*/
- tmp = RCC->CFGR & RCC_CFGR_SWS;
-
- switch (tmp)
- {
- case 0x00U: /* HSI used as system clock */
- SystemCoreClock = HSI_VALUE;
- break;
- case 0x04U: /* HSE used as system clock */
- SystemCoreClock = HSE_VALUE;
- break;
- case 0x08U: /* PLL used as system clock */
-
- /* Get PLL clock source and multiplication factor ----------------------*/
- pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
- pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
-
-#if !defined(STM32F105xC) && !defined(STM32F107xC)
- pllmull = ( pllmull >> 18U) + 2U;
-
- if (pllsource == 0x00U)
- {
- /* HSI oscillator clock divided by 2 selected as PLL clock entry */
- SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
- }
- else
- {
- #if defined(STM32F100xB) || defined(STM32F100xE)
- prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
- /* HSE oscillator clock selected as PREDIV1 clock entry */
- SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
- #else
- /* HSE selected as PLL clock entry */
- if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
- {/* HSE oscillator clock divided by 2 */
- SystemCoreClock = (HSE_VALUE >> 1U) * pllmull;
- }
- else
- {
- SystemCoreClock = HSE_VALUE * pllmull;
- }
- #endif
- }
-#else
- pllmull = pllmull >> 18U;
-
- if (pllmull != 0x0DU)
- {
- pllmull += 2U;
- }
- else
- { /* PLL multiplication factor = PLL input clock * 6.5 */
- pllmull = 13U / 2U;
- }
-
- if (pllsource == 0x00U)
- {
- /* HSI oscillator clock divided by 2 selected as PLL clock entry */
- SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
- }
- else
- {/* PREDIV1 selected as PLL clock entry */
-
- /* Get PREDIV1 clock source and division factor */
- prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
- prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
-
- if (prediv1source == 0U)
- {
- /* HSE oscillator clock selected as PREDIV1 clock entry */
- SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
- }
- else
- {/* PLL2 clock selected as PREDIV1 clock entry */
-
- /* Get PREDIV2 division factor and PLL2 multiplication factor */
- prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4U) + 1U;
- pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8U) + 2U;
- SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
- }
- }
-#endif /* STM32F105xC */
- break;
-
- default:
- SystemCoreClock = HSI_VALUE;
- break;
- }
-
- /* Compute HCLK clock frequency ----------------*/
- /* Get HCLK prescaler */
- tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
- /* HCLK clock frequency */
- SystemCoreClock >>= tmp;
-}
-
-#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
-/**
- * @brief Setup the external memory controller. Called in startup_stm32f1xx.s
- * before jump to __main
- * @param None
- * @retval None
- */
-#ifdef DATA_IN_ExtSRAM
-/**
- * @brief Setup the external memory controller.
- * Called in startup_stm32f1xx_xx.s/.c before jump to main.
- * This function configures the external SRAM mounted on STM3210E-EVAL
- * board (STM32 High density devices). This SRAM will be used as program
- * data memory (including heap and stack).
- * @param None
- * @retval None
- */
-void SystemInit_ExtMemCtl(void)
-{
- __IO uint32_t tmpreg;
- /*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
- required, then adjust the Register Addresses */
-
- /* Enable FSMC clock */
- RCC->AHBENR = 0x00000114U;
-
- /* Delay after an RCC peripheral clock enabling */
- tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN);
-
- /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
- RCC->APB2ENR = 0x000001E0U;
-
- /* Delay after an RCC peripheral clock enabling */
- tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);
-
- (void)(tmpreg);
-
-/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/
-/*---------------- SRAM Address lines configuration -------------------------*/
-/*---------------- NOE and NWE configuration --------------------------------*/
-/*---------------- NE3 configuration ----------------------------------------*/
-/*---------------- NBL0, NBL1 configuration ---------------------------------*/
-
- GPIOD->CRL = 0x44BB44BBU;
- GPIOD->CRH = 0xBBBBBBBBU;
-
- GPIOE->CRL = 0xB44444BBU;
- GPIOE->CRH = 0xBBBBBBBBU;
-
- GPIOF->CRL = 0x44BBBBBBU;
- GPIOF->CRH = 0xBBBB4444U;
-
- GPIOG->CRL = 0x44BBBBBBU;
- GPIOG->CRH = 0x444B4B44U;
-
-/*---------------- FSMC Configuration ---------------------------------------*/
-/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/
-
- FSMC_Bank1->BTCR[4U] = 0x00001091U;
- FSMC_Bank1->BTCR[5U] = 0x00110212U;
-}
-#endif /* DATA_IN_ExtSRAM */
-#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Src/threading.c b/assets/templates/blackpill/Src/threading.c
deleted file mode 100644
index 7c90c7c..0000000
--- a/assets/templates/blackpill/Src/threading.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Threading abstraction layer
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
-
-/*
- * Ensure gmtime_r is available even with -std=c99; must be defined before
- * config.h, which pulls in glibc's features.h. Harmless on other platforms.
- */
-#if !defined(_POSIX_C_SOURCE)
-#define _POSIX_C_SOURCE 200112L
-#endif
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_THREADING_C)
-
-#include "mbedtls/threading.h"
-
-#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
-
-#if !defined(_WIN32) && (defined(unix) || \
- defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \
- defined(__MACH__)))
-#include
-#endif /* !_WIN32 && (unix || __unix || __unix__ ||
- * (__APPLE__ && __MACH__)) */
-
-#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
- ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
- _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) )
-/*
- * This is a convenience shorthand macro to avoid checking the long
- * preprocessor conditions above. Ideally, we could expose this macro in
- * platform_util.h and simply use it in platform_util.c, threading.c and
- * threading.h. However, this macro is not part of the Mbed TLS public API, so
- * we keep it private by only defining it in this file
- */
-
-#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) )
-#define THREADING_USE_GMTIME
-#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */
-
-#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
- ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
- _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */
-
-#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */
-
-#if defined(MBEDTLS_THREADING_PTHREAD)
-static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex )
-{
- if( mutex == NULL )
- return;
-
- mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0;
-}
-
-static void threading_mutex_free_pthread( mbedtls_threading_mutex_t *mutex )
-{
- if( mutex == NULL || !mutex->is_valid )
- return;
-
- (void) pthread_mutex_destroy( &mutex->mutex );
- mutex->is_valid = 0;
-}
-
-static int threading_mutex_lock_pthread( mbedtls_threading_mutex_t *mutex )
-{
- if( mutex == NULL || ! mutex->is_valid )
- return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA );
-
- if( pthread_mutex_lock( &mutex->mutex ) != 0 )
- return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
-
- return( 0 );
-}
-
-static int threading_mutex_unlock_pthread( mbedtls_threading_mutex_t *mutex )
-{
- if( mutex == NULL || ! mutex->is_valid )
- return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA );
-
- if( pthread_mutex_unlock( &mutex->mutex ) != 0 )
- return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
-
- return( 0 );
-}
-
-void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_init_pthread;
-void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_free_pthread;
-int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_lock_pthread;
-int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_unlock_pthread;
-
-/*
- * With phtreads we can statically initialize mutexes
- */
-#define MUTEX_INIT = { PTHREAD_MUTEX_INITIALIZER, 1 }
-
-#endif /* MBEDTLS_THREADING_PTHREAD */
-
-#if defined(MBEDTLS_THREADING_ALT)
-static int threading_mutex_fail( mbedtls_threading_mutex_t *mutex )
-{
- ((void) mutex );
- return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA );
-}
-static void threading_mutex_dummy( mbedtls_threading_mutex_t *mutex )
-{
- ((void) mutex );
- return;
-}
-
-void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy;
-void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy;
-int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail;
-int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail;
-
-/*
- * Set functions pointers and initialize global mutexes
- */
-void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ),
- void (*mutex_free)( mbedtls_threading_mutex_t * ),
- int (*mutex_lock)( mbedtls_threading_mutex_t * ),
- int (*mutex_unlock)( mbedtls_threading_mutex_t * ) )
-{
- mbedtls_mutex_init = mutex_init;
- mbedtls_mutex_free = mutex_free;
- mbedtls_mutex_lock = mutex_lock;
- mbedtls_mutex_unlock = mutex_unlock;
-
-#if defined(MBEDTLS_FS_IO)
- mbedtls_mutex_init( &mbedtls_threading_readdir_mutex );
-#endif
-#if defined(THREADING_USE_GMTIME)
- mbedtls_mutex_init( &mbedtls_threading_gmtime_mutex );
-#endif
-}
-
-/*
- * Free global mutexes
- */
-void mbedtls_threading_free_alt( void )
-{
-#if defined(MBEDTLS_FS_IO)
- mbedtls_mutex_free( &mbedtls_threading_readdir_mutex );
-#endif
-#if defined(THREADING_USE_GMTIME)
- mbedtls_mutex_free( &mbedtls_threading_gmtime_mutex );
-#endif
-}
-#endif /* MBEDTLS_THREADING_ALT */
-
-/*
- * Define global mutexes
- */
-#ifndef MUTEX_INIT
-#define MUTEX_INIT
-#endif
-#if defined(MBEDTLS_FS_IO)
-mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex MUTEX_INIT;
-#endif
-#if defined(THREADING_USE_GMTIME)
-mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT;
-#endif
-
-#endif /* MBEDTLS_THREADING_C */
diff --git a/assets/templates/blackpill/Src/threading.h b/assets/templates/blackpill/Src/threading.h
deleted file mode 100644
index 92e6e6b..0000000
--- a/assets/templates/blackpill/Src/threading.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/**
- * \file threading.h
- *
- * \brief Threading abstraction layer
- */
-/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
-#ifndef MBEDTLS_THREADING_H
-#define MBEDTLS_THREADING_H
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#include
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE is deprecated and should not be
- * used. */
-#define MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE -0x001A /**< The selected feature is not available. */
-
-#define MBEDTLS_ERR_THREADING_BAD_INPUT_DATA -0x001C /**< Bad input parameters to function. */
-#define MBEDTLS_ERR_THREADING_MUTEX_ERROR -0x001E /**< Locking / unlocking / free failed with error code. */
-
-#if defined(MBEDTLS_THREADING_PTHREAD)
-#include
-typedef struct mbedtls_threading_mutex_t
-{
- pthread_mutex_t mutex;
- char is_valid;
-} mbedtls_threading_mutex_t;
-#endif
-
-#if defined(MBEDTLS_THREADING_ALT)
-/* You should define the mbedtls_threading_mutex_t type in your header */
-#include "threading_alt.h"
-
-/**
- * \brief Set your alternate threading implementation function
- * pointers and initialize global mutexes. If used, this
- * function must be called once in the main thread before any
- * other mbed TLS function is called, and
- * mbedtls_threading_free_alt() must be called once in the main
- * thread after all other mbed TLS functions.
- *
- * \note mutex_init() and mutex_free() don't return a status code.
- * If mutex_init() fails, it should leave its argument (the
- * mutex) in a state such that mutex_lock() will fail when
- * called with this argument.
- *
- * \param mutex_init the init function implementation
- * \param mutex_free the free function implementation
- * \param mutex_lock the lock function implementation
- * \param mutex_unlock the unlock function implementation
- */
-void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ),
- void (*mutex_free)( mbedtls_threading_mutex_t * ),
- int (*mutex_lock)( mbedtls_threading_mutex_t * ),
- int (*mutex_unlock)( mbedtls_threading_mutex_t * ) );
-
-/**
- * \brief Free global mutexes.
- */
-void mbedtls_threading_free_alt( void );
-#endif /* MBEDTLS_THREADING_ALT */
-
-#if defined(MBEDTLS_THREADING_C)
-/*
- * The function pointers for mutex_init, mutex_free, mutex_ and mutex_unlock
- *
- * All these functions are expected to work or the result will be undefined.
- */
-extern void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t *mutex );
-extern void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t *mutex );
-extern int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t *mutex );
-extern int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t *mutex );
-
-/*
- * Global mutexes
- */
-#if defined(MBEDTLS_FS_IO)
-extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex;
-#endif
-
-#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
-/* This mutex may or may not be used in the default definition of
- * mbedtls_platform_gmtime_r(), but in order to determine that,
- * we need to check POSIX features, hence modify _POSIX_C_SOURCE.
- * With the current approach, this declaration is orphaned, lacking
- * an accompanying definition, in case mbedtls_platform_gmtime_r()
- * doesn't need it, but that's not a problem. */
-extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex;
-#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */
-
-#endif /* MBEDTLS_THREADING_C */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* threading.h */
diff --git a/assets/templates/blackpill/blackpill.ioc b/assets/templates/blackpill/blackpill.ioc
deleted file mode 100644
index f56e6a5..0000000
--- a/assets/templates/blackpill/blackpill.ioc
+++ /dev/null
@@ -1,103 +0,0 @@
-#MicroXplorer Configuration settings - do not modify
-File.Version=6
-KeepUserPlacement=false
-Mcu.Family=STM32F1
-Mcu.IP0=NVIC
-Mcu.IP1=RCC
-Mcu.IP2=SYS
-Mcu.IP3=USART1
-Mcu.IPNb=4
-Mcu.Name=STM32F103C(8-B)Tx
-Mcu.Package=LQFP48
-Mcu.Pin0=PB12
-Mcu.Pin1=PA9
-Mcu.Pin2=PA10
-Mcu.Pin3=PA13
-Mcu.Pin4=PA14
-Mcu.Pin5=VP_SYS_VS_Systick
-Mcu.PinsNb=6
-Mcu.ThirdPartyNb=0
-Mcu.UserConstants=
-Mcu.UserName=STM32F103C8Tx
-MxCube.Version=5.0.1
-MxDb.Version=DB.5.0.1
-NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false
-NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false
-NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false
-NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false
-NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false
-NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false
-NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
-NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false
-NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false
-NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false
-PA10.Mode=Asynchronous
-PA10.Signal=USART1_RX
-PA13.Mode=Serial_Wire
-PA13.Signal=SYS_JTMS-SWDIO
-PA14.Mode=Serial_Wire
-PA14.Signal=SYS_JTCK-SWCLK
-PA9.Mode=Asynchronous
-PA9.Signal=USART1_TX
-PB12.Locked=true
-PB12.Signal=GPIO_Output
-PCC.Checker=false
-PCC.Line=STM32F103
-PCC.MCU=STM32F103C(8-B)Tx
-PCC.PartNumber=STM32F103C8Tx
-PCC.Seq0=0
-PCC.Series=STM32F1
-PCC.Temperature=25
-PCC.Vdd=3.3
-PinOutPanel.RotationAngle=0
-ProjectManager.AskForMigrate=true
-ProjectManager.BackupPrevious=false
-ProjectManager.CompilerOptimize=6
-ProjectManager.ComputerToolchain=false
-ProjectManager.CoupleFile=false
-ProjectManager.CustomerFirmwarePackage=
-ProjectManager.DefaultFWLocation=true
-ProjectManager.DeletePrevious=true
-ProjectManager.DeviceId=STM32F103C8Tx
-ProjectManager.FirmwarePackage=STM32Cube FW_F1 V1.7.0
-ProjectManager.FreePins=true
-ProjectManager.HalAssertFull=false
-ProjectManager.HeapSize=0x200
-ProjectManager.KeepUserCode=false
-ProjectManager.LastFirmware=true
-ProjectManager.LibraryCopy=0
-ProjectManager.MainLocation=Src
-ProjectManager.NoMain=false
-ProjectManager.PreviousToolchain=
-ProjectManager.ProjectBuild=false
-ProjectManager.ProjectFileName=blackpill.ioc
-ProjectManager.ProjectName=blackpill
-ProjectManager.StackSize=0x400
-ProjectManager.TargetToolchain=Makefile
-ProjectManager.ToolChainLocation=
-ProjectManager.UnderRoot=false
-ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-LL-true,2-SystemClock_Config-RCC-false-LL-false,3-MX_USART1_UART_Init-USART1-false-LL-true
-RCC.ADCFreqValue=24000000
-RCC.AHBFreq_Value=48000000
-RCC.APB1CLKDivider=RCC_HCLK_DIV2
-RCC.APB1Freq_Value=24000000
-RCC.APB1TimFreq_Value=48000000
-RCC.APB2Freq_Value=48000000
-RCC.APB2TimFreq_Value=48000000
-RCC.FCLKCortexFreq_Value=48000000
-RCC.FamilyName=M
-RCC.HCLKFreq_Value=48000000
-RCC.IPParameters=ADCFreqValue,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,MCOFreq_Value,PLLCLKFreq_Value,PLLMCOFreq_Value,PLLMUL,SYSCLKFreq_VALUE,SYSCLKSource,TimSysFreq_Value,USBFreq_Value
-RCC.MCOFreq_Value=48000000
-RCC.PLLCLKFreq_Value=48000000
-RCC.PLLMCOFreq_Value=24000000
-RCC.PLLMUL=RCC_PLL_MUL12
-RCC.SYSCLKFreq_VALUE=48000000
-RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
-RCC.TimSysFreq_Value=48000000
-RCC.USBFreq_Value=48000000
-USART1.IPParameters=VirtualMode
-USART1.VirtualMode=VM_ASYNC
-VP_SYS_VS_Systick.Mode=SysTick
-VP_SYS_VS_Systick.Signal=SYS_VS_Systick
-board=custom
diff --git a/assets/templates/blackpill/startup_stm32f103xb.s b/assets/templates/blackpill/startup_stm32f103xb.s
deleted file mode 100644
index 1bdd524..0000000
--- a/assets/templates/blackpill/startup_stm32f103xb.s
+++ /dev/null
@@ -1,379 +0,0 @@
-/**
- *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
- * @file startup_stm32f103xb.s
- * @author MCD Application Team
- * @version V4.2.0
- * @date 31-March-2017
- * @brief STM32F103xB Devices vector table for Atollic toolchain.
- * This module performs:
- * - Set the initial SP
- * - Set the initial PC == Reset_Handler,
- * - Set the vector table entries with the exceptions ISR address
- * - Configure the clock system
- * - Branches to main in the C library (which eventually
- * calls main()).
- * After Reset the Cortex-M3 processor is in Thread mode,
- * priority is Privileged, and the Stack is set to Main.
- ******************************************************************************
- *
- * © COPYRIGHT(c) 2017 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
- *
- ******************************************************************************
- */
-
- .syntax unified
- .cpu cortex-m3
- .fpu softvfp
- .thumb
-
-.global g_pfnVectors
-.global Default_Handler
-
-/* start address for the initialization values of the .data section.
-defined in linker script */
-.word _sidata
-/* start address for the .data section. defined in linker script */
-.word _sdata
-/* end address for the .data section. defined in linker script */
-.word _edata
-/* start address for the .bss section. defined in linker script */
-.word _sbss
-/* end address for the .bss section. defined in linker script */
-.word _ebss
-
-.equ BootRAM, 0xF108F85F
-/**
- * @brief This is the code that gets called when the processor first
- * starts execution following a reset event. Only the absolutely
- * necessary set is performed, after which the application
- * supplied main() routine is called.
- * @param None
- * @retval : None
-*/
-
- .section .text.Reset_Handler
- .weak Reset_Handler
- .type Reset_Handler, %function
-Reset_Handler:
-
-/* Copy the data segment initializers from flash to SRAM */
- movs r1, #0
- b LoopCopyDataInit
-
-CopyDataInit:
- ldr r3, =_sidata
- ldr r3, [r3, r1]
- str r3, [r0, r1]
- adds r1, r1, #4
-
-LoopCopyDataInit:
- ldr r0, =_sdata
- ldr r3, =_edata
- adds r2, r0, r1
- cmp r2, r3
- bcc CopyDataInit
- ldr r2, =_sbss
- b LoopFillZerobss
-/* Zero fill the bss segment. */
-FillZerobss:
- movs r3, #0
- str r3, [r2], #4
-
-LoopFillZerobss:
- ldr r3, = _ebss
- cmp r2, r3
- bcc FillZerobss
-
-/* Call the clock system intitialization function.*/
- bl SystemInit
-/* Call static constructors */
- bl __libc_init_array
-/* Call the application's entry point.*/
- bl main
- bx lr
-.size Reset_Handler, .-Reset_Handler
-
-/**
- * @brief This is the code that gets called when the processor receives an
- * unexpected interrupt. This simply enters an infinite loop, preserving
- * the system state for examination by a debugger.
- *
- * @param None
- * @retval : None
-*/
- .section .text.Default_Handler,"ax",%progbits
-Default_Handler:
-Infinite_Loop:
- b Infinite_Loop
- .size Default_Handler, .-Default_Handler
-/******************************************************************************
-*
-* The minimal vector table for a Cortex M3. Note that the proper constructs
-* must be placed on this to ensure that it ends up at physical address
-* 0x0000.0000.
-*
-******************************************************************************/
- .section .isr_vector,"a",%progbits
- .type g_pfnVectors, %object
- .size g_pfnVectors, .-g_pfnVectors
-
-
-g_pfnVectors:
-
- .word _estack
- .word Reset_Handler
- .word NMI_Handler
- .word HardFault_Handler
- .word MemManage_Handler
- .word BusFault_Handler
- .word UsageFault_Handler
- .word 0
- .word 0
- .word 0
- .word 0
- .word SVC_Handler
- .word DebugMon_Handler
- .word 0
- .word PendSV_Handler
- .word SysTick_Handler
- .word WWDG_IRQHandler
- .word PVD_IRQHandler
- .word TAMPER_IRQHandler
- .word RTC_IRQHandler
- .word FLASH_IRQHandler
- .word RCC_IRQHandler
- .word EXTI0_IRQHandler
- .word EXTI1_IRQHandler
- .word EXTI2_IRQHandler
- .word EXTI3_IRQHandler
- .word EXTI4_IRQHandler
- .word DMA1_Channel1_IRQHandler
- .word DMA1_Channel2_IRQHandler
- .word DMA1_Channel3_IRQHandler
- .word DMA1_Channel4_IRQHandler
- .word DMA1_Channel5_IRQHandler
- .word DMA1_Channel6_IRQHandler
- .word DMA1_Channel7_IRQHandler
- .word ADC1_2_IRQHandler
- .word USB_HP_CAN1_TX_IRQHandler
- .word USB_LP_CAN1_RX0_IRQHandler
- .word CAN1_RX1_IRQHandler
- .word CAN1_SCE_IRQHandler
- .word EXTI9_5_IRQHandler
- .word TIM1_BRK_IRQHandler
- .word TIM1_UP_IRQHandler
- .word TIM1_TRG_COM_IRQHandler
- .word TIM1_CC_IRQHandler
- .word TIM2_IRQHandler
- .word TIM3_IRQHandler
- .word TIM4_IRQHandler
- .word I2C1_EV_IRQHandler
- .word I2C1_ER_IRQHandler
- .word I2C2_EV_IRQHandler
- .word I2C2_ER_IRQHandler
- .word SPI1_IRQHandler
- .word SPI2_IRQHandler
- .word USART1_IRQHandler
- .word USART2_IRQHandler
- .word USART3_IRQHandler
- .word EXTI15_10_IRQHandler
- .word RTC_Alarm_IRQHandler
- .word USBWakeUp_IRQHandler
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word 0
- .word BootRAM /* @0x108. This is for boot in RAM mode for
- STM32F10x Medium Density devices. */
-
-/*******************************************************************************
-*
-* Provide weak aliases for each Exception handler to the Default_Handler.
-* As they are weak aliases, any function with the same name will override
-* this definition.
-*
-*******************************************************************************/
-
- .weak NMI_Handler
- .thumb_set NMI_Handler,Default_Handler
-
- .weak HardFault_Handler
- .thumb_set HardFault_Handler,Default_Handler
-
- .weak MemManage_Handler
- .thumb_set MemManage_Handler,Default_Handler
-
- .weak BusFault_Handler
- .thumb_set BusFault_Handler,Default_Handler
-
- .weak UsageFault_Handler
- .thumb_set UsageFault_Handler,Default_Handler
-
- .weak SVC_Handler
- .thumb_set SVC_Handler,Default_Handler
-
- .weak DebugMon_Handler
- .thumb_set DebugMon_Handler,Default_Handler
-
- .weak PendSV_Handler
- .thumb_set PendSV_Handler,Default_Handler
-
- .weak SysTick_Handler
- .thumb_set SysTick_Handler,Default_Handler
-
- .weak WWDG_IRQHandler
- .thumb_set WWDG_IRQHandler,Default_Handler
-
- .weak PVD_IRQHandler
- .thumb_set PVD_IRQHandler,Default_Handler
-
- .weak TAMPER_IRQHandler
- .thumb_set TAMPER_IRQHandler,Default_Handler
-
- .weak RTC_IRQHandler
- .thumb_set RTC_IRQHandler,Default_Handler
-
- .weak FLASH_IRQHandler
- .thumb_set FLASH_IRQHandler,Default_Handler
-
- .weak RCC_IRQHandler
- .thumb_set RCC_IRQHandler,Default_Handler
-
- .weak EXTI0_IRQHandler
- .thumb_set EXTI0_IRQHandler,Default_Handler
-
- .weak EXTI1_IRQHandler
- .thumb_set EXTI1_IRQHandler,Default_Handler
-
- .weak EXTI2_IRQHandler
- .thumb_set EXTI2_IRQHandler,Default_Handler
-
- .weak EXTI3_IRQHandler
- .thumb_set EXTI3_IRQHandler,Default_Handler
-
- .weak EXTI4_IRQHandler
- .thumb_set EXTI4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel1_IRQHandler
- .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
-
- .weak DMA1_Channel2_IRQHandler
- .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
-
- .weak DMA1_Channel3_IRQHandler
- .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
-
- .weak DMA1_Channel4_IRQHandler
- .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
-
- .weak DMA1_Channel5_IRQHandler
- .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
-
- .weak DMA1_Channel6_IRQHandler
- .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
-
- .weak DMA1_Channel7_IRQHandler
- .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
-
- .weak ADC1_2_IRQHandler
- .thumb_set ADC1_2_IRQHandler,Default_Handler
-
- .weak USB_HP_CAN1_TX_IRQHandler
- .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
-
- .weak USB_LP_CAN1_RX0_IRQHandler
- .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
-
- .weak CAN1_RX1_IRQHandler
- .thumb_set CAN1_RX1_IRQHandler,Default_Handler
-
- .weak CAN1_SCE_IRQHandler
- .thumb_set CAN1_SCE_IRQHandler,Default_Handler
-
- .weak EXTI9_5_IRQHandler
- .thumb_set EXTI9_5_IRQHandler,Default_Handler
-
- .weak TIM1_BRK_IRQHandler
- .thumb_set TIM1_BRK_IRQHandler,Default_Handler
-
- .weak TIM1_UP_IRQHandler
- .thumb_set TIM1_UP_IRQHandler,Default_Handler
-
- .weak TIM1_TRG_COM_IRQHandler
- .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
-
- .weak TIM1_CC_IRQHandler
- .thumb_set TIM1_CC_IRQHandler,Default_Handler
-
- .weak TIM2_IRQHandler
- .thumb_set TIM2_IRQHandler,Default_Handler
-
- .weak TIM3_IRQHandler
- .thumb_set TIM3_IRQHandler,Default_Handler
-
- .weak TIM4_IRQHandler
- .thumb_set TIM4_IRQHandler,Default_Handler
-
- .weak I2C1_EV_IRQHandler
- .thumb_set I2C1_EV_IRQHandler,Default_Handler
-
- .weak I2C1_ER_IRQHandler
- .thumb_set I2C1_ER_IRQHandler,Default_Handler
-
- .weak I2C2_EV_IRQHandler
- .thumb_set I2C2_EV_IRQHandler,Default_Handler
-
- .weak I2C2_ER_IRQHandler
- .thumb_set I2C2_ER_IRQHandler,Default_Handler
-
- .weak SPI1_IRQHandler
- .thumb_set SPI1_IRQHandler,Default_Handler
-
- .weak SPI2_IRQHandler
- .thumb_set SPI2_IRQHandler,Default_Handler
-
- .weak USART1_IRQHandler
- .thumb_set USART1_IRQHandler,Default_Handler
-
- .weak USART2_IRQHandler
- .thumb_set USART2_IRQHandler,Default_Handler
-
- .weak USART3_IRQHandler
- .thumb_set USART3_IRQHandler,Default_Handler
-
- .weak EXTI15_10_IRQHandler
- .thumb_set EXTI15_10_IRQHandler,Default_Handler
-
- .weak RTC_Alarm_IRQHandler
- .thumb_set RTC_Alarm_IRQHandler,Default_Handler
-
- .weak USBWakeUp_IRQHandler
- .thumb_set USBWakeUp_IRQHandler,Default_Handler
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
diff --git a/get_algos.py b/get_algos.py
index 84c4ecd..d30b604 100755
--- a/get_algos.py
+++ b/get_algos.py
@@ -6,7 +6,7 @@ import shutil
import random
import subprocess
-def bench(algo_dir):
+def bench(algo_dir, template_dir="templates/linux"):
print(algo_dir)
build_dir = None
while build_dir is None:
@@ -17,34 +17,46 @@ def bench(algo_dir):
shutil.copytree(algo_dir, build_dir)
- assets_dir = "assets"
-
- hs = os.path.join(assets_dir, "crypto_aead.h")
- h = os.path.join(build_dir, "crypto_aead.h")
- shutil.copy(hs, h)
-
- ms = os.path.join(assets_dir, "main.c")
- m = os.path.join(build_dir, "main.c")
- shutil.copy(ms, m)
-
c = os.path.join(build_dir, "genkat_aead.c")
if os.path.exists(c):
os.remove(c)
+ hfiles = []
+ cfiles = []
+ for r, d, f in os.walk(build_dir):
+ for file in f:
+ if file.endswith(".c"):
+ cfiles.append(file)
+ elif file.endswith(".h"):
+ hfiles.append(file)
+
+ for f in os.listdir(template_dir):
+ dst = os.path.join(build_dir, f)
+ src = os.path.join(template_dir, f)
+ if os.path.isfile(src) or os.path.islink(src):
+ shutil.copy2(src, dst)
+ elif os.path.isdir(src):
+ shutil.copytree(src, dst)
+ else:
+ raise Exception("I don't know what %s is" % src)
+
wd = os.getcwd()
try:
- os.chdir(build_dir)
+ env = os.environ
- cfiles = []
- for r, d, f in os.walk("."):
- for file in f:
- if file.endswith(".c"):
- cfiles.append(file)
-
- pargs = ['gcc']
- pargs.extend(cfiles)
- pargs.extend(["-o", "test"])
- p = subprocess.Popen(pargs)
+ env['SRC_FILES'] = ' '.join(cfiles)
+ env['HDR_FILES'] = ' '.join(hfiles)
+
+ os.chdir(build_dir)
+ if os.path.isfile('./configure'):
+ p = subprocess.Popen(["./configure"], env=env)
+ compout, comperr = p.communicate()
+ print(compout)
+ print("---")
+ print(comperr)
+
+ pargs = ['make']
+ p = subprocess.Popen(pargs, env=env)
compout, comperr = p.communicate()
print(compout)
print("---")
@@ -54,12 +66,16 @@ def bench(algo_dir):
os.chdir(wd)
# shutil.rmtree(build_dir)
- #exit(0) # stop immediately for now
+ exit(0) # stop immediately for now
-def main(*argv):
+def main(argv):
submissions_dir = "all-lwc-submission-files"
+ template_dir = "templates/linux"
+ if len(argv) > 1:
+ template_dir = argv[1]
+ print("Using template %s" % template_dir)
subs = os.listdir(submissions_dir)
files = set()
@@ -72,7 +88,7 @@ def main(*argv):
if file == "encrypt.c":
f = os.path.join(r, file)
d = os.path.split(f)[0]
- bench(d)
+ bench(d, template_dir)
assert os.path.isdir(d)
files.add(d)
print()
diff --git a/assets/templates/blackpill/.mxproject b/templates/blackpill/.mxproject
similarity index 100%
rename from assets/templates/blackpill/.mxproject
rename to templates/blackpill/.mxproject
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_class_marks_example/ARM/arm_class_marks_example_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_class_marks_example/ARM/arm_class_marks_example_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_class_marks_example/ARM/arm_class_marks_example_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_class_marks_example/ARM/arm_class_marks_example_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_class_marks_example/GCC/arm_class_marks_example_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_class_marks_example/GCC/arm_class_marks_example_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_class_marks_example/GCC/arm_class_marks_example_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_class_marks_example/GCC/arm_class_marks_example_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/ARM/arm_convolution_example_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/ARM/arm_convolution_example_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/ARM/arm_convolution_example_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/ARM/arm_convolution_example_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/ARM/math_helper.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/ARM/math_helper.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/ARM/math_helper.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/ARM/math_helper.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/ARM/math_helper.h b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/ARM/math_helper.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/ARM/math_helper.h
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/ARM/math_helper.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/GCC/arm_convolution_example_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/GCC/arm_convolution_example_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/GCC/arm_convolution_example_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/GCC/arm_convolution_example_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/GCC/math_helper.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/GCC/math_helper.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/GCC/math_helper.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/GCC/math_helper.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/GCC/math_helper.h b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/GCC/math_helper.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/GCC/math_helper.h
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_convolution_example/GCC/math_helper.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_dotproduct_example/ARM/arm_dotproduct_example_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_dotproduct_example/ARM/arm_dotproduct_example_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_dotproduct_example/ARM/arm_dotproduct_example_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_dotproduct_example/ARM/arm_dotproduct_example_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_dotproduct_example/GCC/arm_dotproduct_example_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_dotproduct_example/GCC/arm_dotproduct_example_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_dotproduct_example/GCC/arm_dotproduct_example_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_dotproduct_example/GCC/arm_dotproduct_example_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fft_bin_example/ARM/arm_fft_bin_data.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fft_bin_example/ARM/arm_fft_bin_data.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fft_bin_example/ARM/arm_fft_bin_data.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fft_bin_example/ARM/arm_fft_bin_data.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fft_bin_example/ARM/arm_fft_bin_example_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fft_bin_example/ARM/arm_fft_bin_example_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fft_bin_example/ARM/arm_fft_bin_example_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fft_bin_example/ARM/arm_fft_bin_example_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fft_bin_example/GCC/arm_fft_bin_data.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fft_bin_example/GCC/arm_fft_bin_data.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fft_bin_example/GCC/arm_fft_bin_data.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fft_bin_example/GCC/arm_fft_bin_data.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fft_bin_example/GCC/arm_fft_bin_example_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fft_bin_example/GCC/arm_fft_bin_example_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fft_bin_example/GCC/arm_fft_bin_example_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fft_bin_example/GCC/arm_fft_bin_example_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fir_example/ARM/arm_fir_data.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fir_example/ARM/arm_fir_data.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fir_example/ARM/arm_fir_data.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fir_example/ARM/arm_fir_data.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fir_example/ARM/arm_fir_example_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fir_example/ARM/arm_fir_example_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fir_example/ARM/arm_fir_example_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fir_example/ARM/arm_fir_example_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fir_example/ARM/math_helper.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fir_example/ARM/math_helper.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fir_example/ARM/math_helper.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fir_example/ARM/math_helper.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fir_example/ARM/math_helper.h b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fir_example/ARM/math_helper.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fir_example/ARM/math_helper.h
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_fir_example/ARM/math_helper.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_graphic_equalizer_example/ARM/arm_graphic_equalizer_data.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_graphic_equalizer_example/ARM/arm_graphic_equalizer_data.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_graphic_equalizer_example/ARM/arm_graphic_equalizer_data.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_graphic_equalizer_example/ARM/arm_graphic_equalizer_data.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_graphic_equalizer_example/ARM/arm_graphic_equalizer_example_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_graphic_equalizer_example/ARM/arm_graphic_equalizer_example_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_graphic_equalizer_example/ARM/arm_graphic_equalizer_example_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_graphic_equalizer_example/ARM/arm_graphic_equalizer_example_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_graphic_equalizer_example/ARM/math_helper.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_graphic_equalizer_example/ARM/math_helper.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_graphic_equalizer_example/ARM/math_helper.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_graphic_equalizer_example/ARM/math_helper.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_graphic_equalizer_example/ARM/math_helper.h b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_graphic_equalizer_example/ARM/math_helper.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_graphic_equalizer_example/ARM/math_helper.h
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_graphic_equalizer_example/ARM/math_helper.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_linear_interp_example/ARM/arm_linear_interp_data.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_linear_interp_example/ARM/arm_linear_interp_data.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_linear_interp_example/ARM/arm_linear_interp_data.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_linear_interp_example/ARM/arm_linear_interp_data.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_linear_interp_example/ARM/arm_linear_interp_example_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_linear_interp_example/ARM/arm_linear_interp_example_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_linear_interp_example/ARM/arm_linear_interp_example_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_linear_interp_example/ARM/arm_linear_interp_example_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_linear_interp_example/ARM/math_helper.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_linear_interp_example/ARM/math_helper.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_linear_interp_example/ARM/math_helper.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_linear_interp_example/ARM/math_helper.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_linear_interp_example/ARM/math_helper.h b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_linear_interp_example/ARM/math_helper.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_linear_interp_example/ARM/math_helper.h
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_linear_interp_example/ARM/math_helper.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_matrix_example/ARM/arm_matrix_example_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_matrix_example/ARM/arm_matrix_example_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_matrix_example/ARM/arm_matrix_example_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_matrix_example/ARM/arm_matrix_example_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_matrix_example/ARM/math_helper.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_matrix_example/ARM/math_helper.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_matrix_example/ARM/math_helper.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_matrix_example/ARM/math_helper.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_matrix_example/ARM/math_helper.h b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_matrix_example/ARM/math_helper.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_matrix_example/ARM/math_helper.h
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_matrix_example/ARM/math_helper.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_signal_converge_example/ARM/arm_signal_converge_data.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_signal_converge_example/ARM/arm_signal_converge_data.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_signal_converge_example/ARM/arm_signal_converge_data.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_signal_converge_example/ARM/arm_signal_converge_data.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_signal_converge_example/ARM/arm_signal_converge_example_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_signal_converge_example/ARM/arm_signal_converge_example_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_signal_converge_example/ARM/arm_signal_converge_example_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_signal_converge_example/ARM/arm_signal_converge_example_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_signal_converge_example/ARM/math_helper.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_signal_converge_example/ARM/math_helper.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_signal_converge_example/ARM/math_helper.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_signal_converge_example/ARM/math_helper.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_signal_converge_example/ARM/math_helper.h b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_signal_converge_example/ARM/math_helper.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_signal_converge_example/ARM/math_helper.h
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_signal_converge_example/ARM/math_helper.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_sin_cos_example/ARM/arm_sin_cos_example_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_sin_cos_example/ARM/arm_sin_cos_example_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_sin_cos_example/ARM/arm_sin_cos_example_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_sin_cos_example/ARM/arm_sin_cos_example_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_variance_example/ARM/arm_variance_example_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_variance_example/ARM/arm_variance_example_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_variance_example/ARM/arm_variance_example_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Examples/arm_variance_example/ARM/arm_variance_example_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_abs_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_abs_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_abs_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_abs_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_abs_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_abs_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_abs_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_abs_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_abs_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_abs_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_abs_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_abs_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_abs_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_abs_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_abs_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_abs_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_add_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_add_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_add_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_add_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_add_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_add_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_add_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_add_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_add_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_add_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_add_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_add_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_add_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_add_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_add_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_add_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_mult_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_mult_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_mult_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_mult_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_mult_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_mult_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_mult_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_mult_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_mult_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_mult_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_mult_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_mult_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_mult_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_mult_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_mult_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_mult_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_negate_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_negate_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_negate_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_negate_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_negate_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_negate_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_negate_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_negate_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_negate_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_negate_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_negate_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_negate_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_negate_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_negate_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_negate_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_negate_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_offset_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_offset_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_offset_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_offset_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_offset_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_offset_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_offset_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_offset_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_offset_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_offset_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_offset_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_offset_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_offset_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_offset_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_offset_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_offset_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_scale_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_scale_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_scale_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_scale_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_scale_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_scale_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_scale_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_scale_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_scale_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_scale_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_scale_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_scale_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_scale_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_scale_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_scale_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_scale_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_shift_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_shift_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_shift_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_shift_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_shift_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_shift_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_shift_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_shift_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_shift_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_shift_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_shift_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_shift_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_sub_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_sub_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_sub_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_sub_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_sub_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_sub_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_sub_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_sub_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_sub_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_sub_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_sub_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_sub_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_sub_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_sub_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_sub_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/BasicMathFunctions/arm_sub_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/CommonTables/arm_common_tables.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/CommonTables/arm_common_tables.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/CommonTables/arm_common_tables.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/CommonTables/arm_common_tables.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/CommonTables/arm_const_structs.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/CommonTables/arm_const_structs.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/CommonTables/arm_const_structs.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/CommonTables/arm_const_structs.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_conj_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_conj_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_conj_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_conj_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_conj_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_conj_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_conj_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_conj_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_conj_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_conj_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_conj_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_conj_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_dot_prod_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_dot_prod_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_dot_prod_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_dot_prod_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_dot_prod_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_dot_prod_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_dot_prod_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_dot_prod_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_dot_prod_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_dot_prod_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_dot_prod_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_dot_prod_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_squared_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_squared_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_squared_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_squared_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_squared_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_squared_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_squared_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_squared_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_squared_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_squared_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_squared_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_squared_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_real_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_real_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_real_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_real_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_real_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_real_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_real_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_real_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_real_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_real_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_real_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_real_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_init_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_init_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_init_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_init_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_init_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_init_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_init_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_init_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_init_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_init_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_init_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_init_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_reset_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_reset_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_reset_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_reset_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_reset_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_reset_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_reset_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_reset_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_reset_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_reset_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_reset_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_pid_reset_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_sin_cos_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_sin_cos_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_sin_cos_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_sin_cos_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_sin_cos_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_sin_cos_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_sin_cos_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/ControllerFunctions/arm_sin_cos_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_cos_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_cos_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_cos_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_cos_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_cos_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_cos_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_cos_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_cos_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_cos_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_cos_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_cos_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_cos_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sin_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sin_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sin_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sin_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sin_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sin_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sin_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sin_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sin_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sin_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sin_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sin_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sqrt_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sqrt_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sqrt_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sqrt_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sqrt_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sqrt_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sqrt_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sqrt_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_32x64_init_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_32x64_init_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_32x64_init_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_32x64_init_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_32x64_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_32x64_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_32x64_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_32x64_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_fast_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_fast_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_fast_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_fast_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_fast_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_fast_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_fast_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_fast_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_init_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_init_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_init_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_init_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_init_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_init_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_init_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_init_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_init_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_init_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_init_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_init_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_f64.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_f64.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_f64.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_f64.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_init_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_init_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_init_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_init_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_init_f64.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_init_f64.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_init_f64.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_init_f64.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_stereo_df2T_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_stereo_df2T_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_stereo_df2T_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_stereo_df2T_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_stereo_df2T_init_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_stereo_df2T_init_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_stereo_df2T_init_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_stereo_df2T_init_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_fast_opt_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_fast_opt_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_fast_opt_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_fast_opt_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_fast_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_fast_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_fast_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_fast_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_fast_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_fast_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_fast_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_fast_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_opt_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_opt_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_opt_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_opt_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_opt_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_opt_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_opt_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_opt_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_fast_opt_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_fast_opt_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_fast_opt_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_fast_opt_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_fast_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_fast_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_fast_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_fast_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_fast_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_fast_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_fast_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_fast_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_opt_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_opt_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_opt_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_opt_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_opt_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_opt_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_opt_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_opt_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_conv_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_fast_opt_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_fast_opt_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_fast_opt_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_fast_opt_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_fast_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_fast_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_fast_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_fast_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_fast_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_fast_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_fast_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_fast_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_opt_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_opt_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_opt_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_opt_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_opt_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_opt_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_opt_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_opt_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_correlate_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_fast_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_fast_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_fast_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_fast_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_fast_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_fast_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_fast_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_fast_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_init_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_init_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_init_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_init_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_init_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_init_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_init_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_init_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_init_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_init_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_init_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_init_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_fast_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_fast_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_fast_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_fast_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_fast_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_fast_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_fast_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_fast_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_init_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_init_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_init_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_init_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_init_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_init_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_init_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_init_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_init_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_init_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_init_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_init_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_init_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_init_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_init_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_init_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_init_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_init_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_init_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_init_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_init_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_init_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_init_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_init_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_init_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_init_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_init_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_init_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_init_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_init_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_init_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_init_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_init_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_init_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_init_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_init_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_init_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_init_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_init_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_init_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_q7.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_q7.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_q7.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_init_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_init_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_init_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_init_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_init_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_init_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_init_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_init_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_init_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_init_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_init_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_init_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_init_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_init_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_init_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_init_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_init_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_init_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_init_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_init_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_init_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_init_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_init_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_init_q31.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_init_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_init_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_init_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_init_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_init_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_init_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_init_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_init_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_init_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_init_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_init_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_init_q31.c
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_q15.c
new file mode 100644
index 0000000..007db31
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_q15.c
@@ -0,0 +1,440 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_lms_norm_q15.c
+*
+* Description: Q15 NLMS filter.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupFilters
+ */
+
+/**
+ * @addtogroup LMS_NORM
+ * @{
+ */
+
+/**
+* @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.
+*
+* Scaling and Overflow Behavior:
+* \par
+* The function is implemented using a 64-bit internal accumulator.
+* Both coefficients 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.
+*
+* \par
+* In this filter, filter coefficients are updated for each sample and the updation of filter cofficients are saturted.
+*
+ */
+
+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)
+{
+ q15_t *pState = S->pState; /* State pointer */
+ q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
+ q15_t *pStateCurnt; /* Points to the current sample of the state */
+ q15_t *px, *pb; /* Temporary pointers for state and coefficient buffers */
+ q15_t mu = S->mu; /* Adaptive factor */
+ uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */
+ uint32_t tapCnt, blkCnt; /* Loop counters */
+ q31_t energy; /* Energy of the input */
+ q63_t acc; /* Accumulator */
+ q15_t e = 0, d = 0; /* error, reference data sample */
+ q15_t w = 0, in; /* weight factor and state */
+ q15_t x0; /* temporary variable to hold input sample */
+ //uint32_t shift = (uint32_t) S->postShift + 1u; /* Shift to be applied to the output */
+ q15_t errorXmu, oneByEnergy; /* Temporary variables to store error and mu product and reciprocal of energy */
+ q15_t postShift; /* Post shift to be applied to weight after reciprocal calculation */
+ q31_t coef; /* Teporary variable for coefficient */
+ q31_t acc_l, acc_h;
+ int32_t lShift = (15 - (int32_t) S->postShift); /* Post shift */
+ int32_t uShift = (32 - lShift);
+
+ energy = S->energy;
+ x0 = S->x0;
+
+ /* S->pState points to buffer which contains previous frame (numTaps - 1) samples */
+ /* pStateCurnt points to the location where the new input data should be written */
+ pStateCurnt = &(S->pState[(numTaps - 1u)]);
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ while(blkCnt > 0u)
+ {
+ /* Copy the new input sample into the state buffer */
+ *pStateCurnt++ = *pSrc;
+
+ /* Initialize pState pointer */
+ px = pState;
+
+ /* Initialize coeff pointer */
+ pb = (pCoeffs);
+
+ /* Read the sample from input buffer */
+ in = *pSrc++;
+
+ /* Update the energy calculation */
+ energy -= (((q31_t) x0 * (x0)) >> 15);
+ energy += (((q31_t) in * (in)) >> 15);
+
+ /* Set the accumulator to zero */
+ acc = 0;
+
+ /* Loop unrolling. Process 4 taps at a time. */
+ tapCnt = numTaps >> 2;
+
+ while(tapCnt > 0u)
+ {
+
+ /* Perform the multiply-accumulate */
+#ifndef UNALIGNED_SUPPORT_DISABLE
+
+ acc = __SMLALD(*__SIMD32(px)++, (*__SIMD32(pb)++), acc);
+ acc = __SMLALD(*__SIMD32(px)++, (*__SIMD32(pb)++), acc);
+
+#else
+
+ acc += (((q31_t) * px++ * (*pb++)));
+ acc += (((q31_t) * px++ * (*pb++)));
+ acc += (((q31_t) * px++ * (*pb++)));
+ acc += (((q31_t) * px++ * (*pb++)));
+
+#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* If the filter length is not a multiple of 4, compute the remaining filter taps */
+ tapCnt = numTaps % 0x4u;
+
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+ acc += (((q31_t) * px++ * (*pb++)));
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* Calc lower part of acc */
+ acc_l = acc & 0xffffffff;
+
+ /* Calc upper part of acc */
+ acc_h = (acc >> 32) & 0xffffffff;
+
+ /* Apply shift for lower part of acc and upper part of acc */
+ acc = (uint32_t) acc_l >> lShift | acc_h << uShift;
+
+ /* Converting the result to 1.15 format and saturate the output */
+ acc = __SSAT(acc, 16u);
+
+ /* Store the result from accumulator into the destination buffer. */
+ *pOut++ = (q15_t) acc;
+
+ /* Compute and store error */
+ d = *pRef++;
+ e = d - (q15_t) acc;
+ *pErr++ = e;
+
+ /* Calculation of 1/energy */
+ postShift = arm_recip_q15((q15_t) energy + DELTA_Q15,
+ &oneByEnergy, S->recipTable);
+
+ /* Calculation of e * mu value */
+ errorXmu = (q15_t) (((q31_t) e * mu) >> 15);
+
+ /* Calculation of (e * mu) * (1/energy) value */
+ acc = (((q31_t) errorXmu * oneByEnergy) >> (15 - postShift));
+
+ /* Weighting factor for the normalized version */
+ w = (q15_t) __SSAT((q31_t) acc, 16);
+
+ /* Initialize pState pointer */
+ px = pState;
+
+ /* Initialize coeff pointer */
+ pb = (pCoeffs);
+
+ /* Loop unrolling. Process 4 taps at a time. */
+ tapCnt = numTaps >> 2;
+
+ /* Update filter coefficients */
+ while(tapCnt > 0u)
+ {
+ coef = *pb + (((q31_t) w * (*px++)) >> 15);
+ *pb++ = (q15_t) __SSAT((coef), 16);
+ coef = *pb + (((q31_t) w * (*px++)) >> 15);
+ *pb++ = (q15_t) __SSAT((coef), 16);
+ coef = *pb + (((q31_t) w * (*px++)) >> 15);
+ *pb++ = (q15_t) __SSAT((coef), 16);
+ coef = *pb + (((q31_t) w * (*px++)) >> 15);
+ *pb++ = (q15_t) __SSAT((coef), 16);
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* If the filter length is not a multiple of 4, compute the remaining filter taps */
+ tapCnt = numTaps % 0x4u;
+
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+ coef = *pb + (((q31_t) w * (*px++)) >> 15);
+ *pb++ = (q15_t) __SSAT((coef), 16);
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* Read the sample from state buffer */
+ x0 = *pState;
+
+ /* Advance state pointer by 1 for the next sample */
+ pState = pState + 1u;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Save energy and x0 values for the next frame */
+ S->energy = (q15_t) energy;
+ S->x0 = x0;
+
+ /* Processing is complete. Now copy the last numTaps - 1 samples to the
+ satrt of the state buffer. This prepares the state buffer for the
+ next function call. */
+
+ /* Points to the start of the pState buffer */
+ pStateCurnt = S->pState;
+
+ /* Calculation of count for copying integer writes */
+ tapCnt = (numTaps - 1u) >> 2;
+
+ while(tapCnt > 0u)
+ {
+
+#ifndef UNALIGNED_SUPPORT_DISABLE
+
+ *__SIMD32(pStateCurnt)++ = *__SIMD32(pState)++;
+ *__SIMD32(pStateCurnt)++ = *__SIMD32(pState)++;
+
+#else
+
+ *pStateCurnt++ = *pState++;
+ *pStateCurnt++ = *pState++;
+ *pStateCurnt++ = *pState++;
+ *pStateCurnt++ = *pState++;
+
+#endif
+
+ tapCnt--;
+
+ }
+
+ /* Calculation of count for remaining q15_t data */
+ tapCnt = (numTaps - 1u) % 0x4u;
+
+ /* copy data */
+ while(tapCnt > 0u)
+ {
+ *pStateCurnt++ = *pState++;
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ while(blkCnt > 0u)
+ {
+ /* Copy the new input sample into the state buffer */
+ *pStateCurnt++ = *pSrc;
+
+ /* Initialize pState pointer */
+ px = pState;
+
+ /* Initialize pCoeffs pointer */
+ pb = pCoeffs;
+
+ /* Read the sample from input buffer */
+ in = *pSrc++;
+
+ /* Update the energy calculation */
+ energy -= (((q31_t) x0 * (x0)) >> 15);
+ energy += (((q31_t) in * (in)) >> 15);
+
+ /* Set the accumulator to zero */
+ acc = 0;
+
+ /* Loop over numTaps number of values */
+ tapCnt = numTaps;
+
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+ acc += (((q31_t) * px++ * (*pb++)));
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* Calc lower part of acc */
+ acc_l = acc & 0xffffffff;
+
+ /* Calc upper part of acc */
+ acc_h = (acc >> 32) & 0xffffffff;
+
+ /* Apply shift for lower part of acc and upper part of acc */
+ acc = (uint32_t) acc_l >> lShift | acc_h << uShift;
+
+ /* Converting the result to 1.15 format and saturate the output */
+ acc = __SSAT(acc, 16u);
+
+ /* Converting the result to 1.15 format */
+ //acc = __SSAT((acc >> (16u - shift)), 16u);
+
+ /* Store the result from accumulator into the destination buffer. */
+ *pOut++ = (q15_t) acc;
+
+ /* Compute and store error */
+ d = *pRef++;
+ e = d - (q15_t) acc;
+ *pErr++ = e;
+
+ /* Calculation of 1/energy */
+ postShift = arm_recip_q15((q15_t) energy + DELTA_Q15,
+ &oneByEnergy, S->recipTable);
+
+ /* Calculation of e * mu value */
+ errorXmu = (q15_t) (((q31_t) e * mu) >> 15);
+
+ /* Calculation of (e * mu) * (1/energy) value */
+ acc = (((q31_t) errorXmu * oneByEnergy) >> (15 - postShift));
+
+ /* Weighting factor for the normalized version */
+ w = (q15_t) __SSAT((q31_t) acc, 16);
+
+ /* Initialize pState pointer */
+ px = pState;
+
+ /* Initialize coeff pointer */
+ pb = (pCoeffs);
+
+ /* Loop over numTaps number of values */
+ tapCnt = numTaps;
+
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+ coef = *pb + (((q31_t) w * (*px++)) >> 15);
+ *pb++ = (q15_t) __SSAT((coef), 16);
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* Read the sample from state buffer */
+ x0 = *pState;
+
+ /* Advance state pointer by 1 for the next sample */
+ pState = pState + 1u;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Save energy and x0 values for the next frame */
+ S->energy = (q15_t) energy;
+ S->x0 = x0;
+
+ /* Processing is complete. Now copy the last numTaps - 1 samples to the
+ satrt of the state buffer. This prepares the state buffer for the
+ next function call. */
+
+ /* Points to the start of the pState buffer */
+ pStateCurnt = S->pState;
+
+ /* copy (numTaps - 1u) data */
+ tapCnt = (numTaps - 1u);
+
+ /* copy data */
+ while(tapCnt > 0u)
+ {
+ *pStateCurnt++ = *pState++;
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+}
+
+
+/**
+ * @} end of LMS_NORM group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_q31.c
new file mode 100644
index 0000000..20701fa
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_q31.c
@@ -0,0 +1,431 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_lms_norm_q31.c
+*
+* Description: Processing function for the Q31 NLMS filter.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupFilters
+ */
+
+/**
+ * @addtogroup LMS_NORM
+ * @{
+ */
+
+/**
+* @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.
+*
+* 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
+* log2(numTaps) bits. The reference signal should not be scaled down.
+* After all multiply-accumulates are performed, the 2.62 accumulator is shifted
+* and saturated to 1.31 format to yield the final result.
+* The output signal and error signal are in 1.31 format.
+*
+* \par
+* In this filter, filter coefficients are updated for each sample and the
+* updation of filter cofficients are saturted.
+*
+*/
+
+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)
+{
+ q31_t *pState = S->pState; /* State pointer */
+ q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
+ q31_t *pStateCurnt; /* Points to the current sample of the state */
+ q31_t *px, *pb; /* Temporary pointers for state and coefficient buffers */
+ q31_t mu = S->mu; /* Adaptive factor */
+ uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */
+ uint32_t tapCnt, blkCnt; /* Loop counters */
+ q63_t energy; /* Energy of the input */
+ q63_t acc; /* Accumulator */
+ q31_t e = 0, d = 0; /* error, reference data sample */
+ q31_t w = 0, in; /* weight factor and state */
+ q31_t x0; /* temporary variable to hold input sample */
+// uint32_t shift = 32u - ((uint32_t) S->postShift + 1u); /* Shift to be applied to the output */
+ q31_t errorXmu, oneByEnergy; /* Temporary variables to store error and mu product and reciprocal of energy */
+ q31_t postShift; /* Post shift to be applied to weight after reciprocal calculation */
+ q31_t coef; /* Temporary variable for coef */
+ q31_t acc_l, acc_h; /* temporary input */
+ uint32_t uShift = ((uint32_t) S->postShift + 1u);
+ uint32_t lShift = 32u - uShift; /* Shift to be applied to the output */
+
+ energy = S->energy;
+ x0 = S->x0;
+
+ /* S->pState points to buffer which contains previous frame (numTaps - 1) samples */
+ /* pStateCurnt points to the location where the new input data should be written */
+ pStateCurnt = &(S->pState[(numTaps - 1u)]);
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ while(blkCnt > 0u)
+ {
+
+ /* Copy the new input sample into the state buffer */
+ *pStateCurnt++ = *pSrc;
+
+ /* Initialize pState pointer */
+ px = pState;
+
+ /* Initialize coeff pointer */
+ pb = (pCoeffs);
+
+ /* Read the sample from input buffer */
+ in = *pSrc++;
+
+ /* Update the energy calculation */
+ energy = (q31_t) ((((q63_t) energy << 32) -
+ (((q63_t) x0 * x0) << 1)) >> 32);
+ energy = (q31_t) (((((q63_t) in * in) << 1) + (energy << 32)) >> 32);
+
+ /* Set the accumulator to zero */
+ acc = 0;
+
+ /* Loop unrolling. Process 4 taps at a time. */
+ tapCnt = numTaps >> 2;
+
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+ acc += ((q63_t) (*px++)) * (*pb++);
+ acc += ((q63_t) (*px++)) * (*pb++);
+ acc += ((q63_t) (*px++)) * (*pb++);
+ acc += ((q63_t) (*px++)) * (*pb++);
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* If the filter length is not a multiple of 4, compute the remaining filter taps */
+ tapCnt = numTaps % 0x4u;
+
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+ acc += ((q63_t) (*px++)) * (*pb++);
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* Converting the result to 1.31 format */
+ /* Calc lower part of acc */
+ acc_l = acc & 0xffffffff;
+
+ /* Calc upper part of acc */
+ acc_h = (acc >> 32) & 0xffffffff;
+
+ acc = (uint32_t) acc_l >> lShift | acc_h << uShift;
+
+ /* Store the result from accumulator into the destination buffer. */
+ *pOut++ = (q31_t) acc;
+
+ /* Compute and store error */
+ d = *pRef++;
+ e = d - (q31_t) acc;
+ *pErr++ = e;
+
+ /* Calculates the reciprocal of energy */
+ postShift = arm_recip_q31(energy + DELTA_Q31,
+ &oneByEnergy, &S->recipTable[0]);
+
+ /* Calculation of product of (e * mu) */
+ errorXmu = (q31_t) (((q63_t) e * mu) >> 31);
+
+ /* Weighting factor for the normalized version */
+ w = clip_q63_to_q31(((q63_t) errorXmu * oneByEnergy) >> (31 - postShift));
+
+ /* Initialize pState pointer */
+ px = pState;
+
+ /* Initialize coeff pointer */
+ pb = (pCoeffs);
+
+ /* Loop unrolling. Process 4 taps at a time. */
+ tapCnt = numTaps >> 2;
+
+ /* Update filter coefficients */
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+
+ /* coef is in 2.30 format */
+ coef = (q31_t) (((q63_t) w * (*px++)) >> (32));
+ /* get coef in 1.31 format by left shifting */
+ *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
+ /* update coefficient buffer to next coefficient */
+ pb++;
+
+ coef = (q31_t) (((q63_t) w * (*px++)) >> (32));
+ *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
+ pb++;
+
+ coef = (q31_t) (((q63_t) w * (*px++)) >> (32));
+ *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
+ pb++;
+
+ coef = (q31_t) (((q63_t) w * (*px++)) >> (32));
+ *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
+ pb++;
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* If the filter length is not a multiple of 4, compute the remaining filter taps */
+ tapCnt = numTaps % 0x4u;
+
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+ coef = (q31_t) (((q63_t) w * (*px++)) >> (32));
+ *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
+ pb++;
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* Read the sample from state buffer */
+ x0 = *pState;
+
+ /* Advance state pointer by 1 for the next sample */
+ pState = pState + 1;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Save energy and x0 values for the next frame */
+ S->energy = (q31_t) energy;
+ S->x0 = x0;
+
+ /* Processing is complete. Now copy the last numTaps - 1 samples to the
+ satrt of the state buffer. This prepares the state buffer for the
+ next function call. */
+
+ /* Points to the start of the pState buffer */
+ pStateCurnt = S->pState;
+
+ /* Loop unrolling for (numTaps - 1u) samples copy */
+ tapCnt = (numTaps - 1u) >> 2u;
+
+ /* copy data */
+ while(tapCnt > 0u)
+ {
+ *pStateCurnt++ = *pState++;
+ *pStateCurnt++ = *pState++;
+ *pStateCurnt++ = *pState++;
+ *pStateCurnt++ = *pState++;
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* Calculate remaining number of copies */
+ tapCnt = (numTaps - 1u) % 0x4u;
+
+ /* Copy the remaining q31_t data */
+ while(tapCnt > 0u)
+ {
+ *pStateCurnt++ = *pState++;
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ while(blkCnt > 0u)
+ {
+
+ /* Copy the new input sample into the state buffer */
+ *pStateCurnt++ = *pSrc;
+
+ /* Initialize pState pointer */
+ px = pState;
+
+ /* Initialize pCoeffs pointer */
+ pb = pCoeffs;
+
+ /* Read the sample from input buffer */
+ in = *pSrc++;
+
+ /* Update the energy calculation */
+ energy =
+ (q31_t) ((((q63_t) energy << 32) - (((q63_t) x0 * x0) << 1)) >> 32);
+ energy = (q31_t) (((((q63_t) in * in) << 1) + (energy << 32)) >> 32);
+
+ /* Set the accumulator to zero */
+ acc = 0;
+
+ /* Loop over numTaps number of values */
+ tapCnt = numTaps;
+
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+ acc += ((q63_t) (*px++)) * (*pb++);
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* Converting the result to 1.31 format */
+ /* Converting the result to 1.31 format */
+ /* Calc lower part of acc */
+ acc_l = acc & 0xffffffff;
+
+ /* Calc upper part of acc */
+ acc_h = (acc >> 32) & 0xffffffff;
+
+ acc = (uint32_t) acc_l >> lShift | acc_h << uShift;
+
+
+ //acc = (q31_t) (acc >> shift);
+
+ /* Store the result from accumulator into the destination buffer. */
+ *pOut++ = (q31_t) acc;
+
+ /* Compute and store error */
+ d = *pRef++;
+ e = d - (q31_t) acc;
+ *pErr++ = e;
+
+ /* Calculates the reciprocal of energy */
+ postShift =
+ arm_recip_q31(energy + DELTA_Q31, &oneByEnergy, &S->recipTable[0]);
+
+ /* Calculation of product of (e * mu) */
+ errorXmu = (q31_t) (((q63_t) e * mu) >> 31);
+
+ /* Weighting factor for the normalized version */
+ w = clip_q63_to_q31(((q63_t) errorXmu * oneByEnergy) >> (31 - postShift));
+
+ /* Initialize pState pointer */
+ px = pState;
+
+ /* Initialize coeff pointer */
+ pb = (pCoeffs);
+
+ /* Loop over numTaps number of values */
+ tapCnt = numTaps;
+
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+ /* coef is in 2.30 format */
+ coef = (q31_t) (((q63_t) w * (*px++)) >> (32));
+ /* get coef in 1.31 format by left shifting */
+ *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
+ /* update coefficient buffer to next coefficient */
+ pb++;
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* Read the sample from state buffer */
+ x0 = *pState;
+
+ /* Advance state pointer by 1 for the next sample */
+ pState = pState + 1;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Save energy and x0 values for the next frame */
+ S->energy = (q31_t) energy;
+ S->x0 = x0;
+
+ /* Processing is complete. Now copy the last numTaps - 1 samples to the
+ start of the state buffer. This prepares the state buffer for the
+ next function call. */
+
+ /* Points to the start of the pState buffer */
+ pStateCurnt = S->pState;
+
+ /* Loop for (numTaps - 1u) samples copy */
+ tapCnt = (numTaps - 1u);
+
+ /* Copy the remaining q31_t data */
+ while(tapCnt > 0u)
+ {
+ *pStateCurnt++ = *pState++;
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+}
+
+/**
+ * @} end of LMS_NORM group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_q15.c
new file mode 100644
index 0000000..2f1b991
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_q15.c
@@ -0,0 +1,380 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_lms_q15.c
+*
+* Description: Processing function for the Q15 LMS filter.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+/**
+ * @ingroup groupFilters
+ */
+
+/**
+ * @addtogroup LMS
+ * @{
+ */
+
+ /**
+ * @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.
+ *
+ * \par Scaling and Overflow Behavior:
+ * The function is implemented using a 64-bit internal accumulator.
+ * Both coefficients 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.
+ *
+ * \par
+ * In this filter, filter coefficients are updated for each sample and the updation of filter cofficients are saturted.
+ *
+ */
+
+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)
+{
+ q15_t *pState = S->pState; /* State pointer */
+ uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */
+ q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
+ q15_t *pStateCurnt; /* Points to the current sample of the state */
+ q15_t mu = S->mu; /* Adaptive factor */
+ q15_t *px; /* Temporary pointer for state */
+ q15_t *pb; /* Temporary pointer for coefficient buffer */
+ uint32_t tapCnt, blkCnt; /* Loop counters */
+ q63_t acc; /* Accumulator */
+ q15_t e = 0; /* error of data sample */
+ q15_t alpha; /* Intermediate constant for taps update */
+ q31_t coef; /* Teporary variable for coefficient */
+ q31_t acc_l, acc_h;
+ int32_t lShift = (15 - (int32_t) S->postShift); /* Post shift */
+ int32_t uShift = (32 - lShift);
+
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+
+ /* S->pState points to buffer which contains previous frame (numTaps - 1) samples */
+ /* pStateCurnt points to the location where the new input data should be written */
+ pStateCurnt = &(S->pState[(numTaps - 1u)]);
+
+ /* Initializing blkCnt with blockSize */
+ blkCnt = blockSize;
+
+ while(blkCnt > 0u)
+ {
+ /* Copy the new input sample into the state buffer */
+ *pStateCurnt++ = *pSrc++;
+
+ /* Initialize state pointer */
+ px = pState;
+
+ /* Initialize coefficient pointer */
+ pb = pCoeffs;
+
+ /* Set the accumulator to zero */
+ acc = 0;
+
+ /* Loop unrolling. Process 4 taps at a time. */
+ tapCnt = numTaps >> 2u;
+
+ while(tapCnt > 0u)
+ {
+ /* acc += b[N] * x[n-N] + b[N-1] * x[n-N-1] */
+ /* Perform the multiply-accumulate */
+#ifndef UNALIGNED_SUPPORT_DISABLE
+
+ acc = __SMLALD(*__SIMD32(px)++, (*__SIMD32(pb)++), acc);
+ acc = __SMLALD(*__SIMD32(px)++, (*__SIMD32(pb)++), acc);
+
+#else
+
+ acc += (q63_t) (((q31_t) (*px++) * (*pb++)));
+ acc += (q63_t) (((q31_t) (*px++) * (*pb++)));
+ acc += (q63_t) (((q31_t) (*px++) * (*pb++)));
+ acc += (q63_t) (((q31_t) (*px++) * (*pb++)));
+
+
+#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* If the filter length is not a multiple of 4, compute the remaining filter taps */
+ tapCnt = numTaps % 0x4u;
+
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+ acc += (q63_t) (((q31_t) (*px++) * (*pb++)));
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* Calc lower part of acc */
+ acc_l = acc & 0xffffffff;
+
+ /* Calc upper part of acc */
+ acc_h = (acc >> 32) & 0xffffffff;
+
+ /* Apply shift for lower part of acc and upper part of acc */
+ acc = (uint32_t) acc_l >> lShift | acc_h << uShift;
+
+ /* Converting the result to 1.15 format and saturate the output */
+ acc = __SSAT(acc, 16);
+
+ /* Store the result from accumulator into the destination buffer. */
+ *pOut++ = (q15_t) acc;
+
+ /* Compute and store error */
+ e = *pRef++ - (q15_t) acc;
+
+ *pErr++ = (q15_t) e;
+
+ /* Compute alpha i.e. intermediate constant for taps update */
+ alpha = (q15_t) (((q31_t) e * (mu)) >> 15);
+
+ /* Initialize state pointer */
+ /* Advance state pointer by 1 for the next sample */
+ px = pState++;
+
+ /* Initialize coefficient pointer */
+ pb = pCoeffs;
+
+ /* Loop unrolling. Process 4 taps at a time. */
+ tapCnt = numTaps >> 2u;
+
+ /* Update filter coefficients */
+ while(tapCnt > 0u)
+ {
+ coef = (q31_t) * pb + (((q31_t) alpha * (*px++)) >> 15);
+ *pb++ = (q15_t) __SSAT((coef), 16);
+ coef = (q31_t) * pb + (((q31_t) alpha * (*px++)) >> 15);
+ *pb++ = (q15_t) __SSAT((coef), 16);
+ coef = (q31_t) * pb + (((q31_t) alpha * (*px++)) >> 15);
+ *pb++ = (q15_t) __SSAT((coef), 16);
+ coef = (q31_t) * pb + (((q31_t) alpha * (*px++)) >> 15);
+ *pb++ = (q15_t) __SSAT((coef), 16);
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* If the filter length is not a multiple of 4, compute the remaining filter taps */
+ tapCnt = numTaps % 0x4u;
+
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+ coef = (q31_t) * pb + (((q31_t) alpha * (*px++)) >> 15);
+ *pb++ = (q15_t) __SSAT((coef), 16);
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* Decrement the loop counter */
+ blkCnt--;
+
+ }
+
+ /* Processing is complete. Now copy the last numTaps - 1 samples to the
+ satrt of the state buffer. This prepares the state buffer for the
+ next function call. */
+
+ /* Points to the start of the pState buffer */
+ pStateCurnt = S->pState;
+
+ /* Calculation of count for copying integer writes */
+ tapCnt = (numTaps - 1u) >> 2;
+
+ while(tapCnt > 0u)
+ {
+
+#ifndef UNALIGNED_SUPPORT_DISABLE
+
+ *__SIMD32(pStateCurnt)++ = *__SIMD32(pState)++;
+ *__SIMD32(pStateCurnt)++ = *__SIMD32(pState)++;
+#else
+ *pStateCurnt++ = *pState++;
+ *pStateCurnt++ = *pState++;
+ *pStateCurnt++ = *pState++;
+ *pStateCurnt++ = *pState++;
+#endif
+
+ tapCnt--;
+
+ }
+
+ /* Calculation of count for remaining q15_t data */
+ tapCnt = (numTaps - 1u) % 0x4u;
+
+ /* copy data */
+ while(tapCnt > 0u)
+ {
+ *pStateCurnt++ = *pState++;
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* S->pState points to buffer which contains previous frame (numTaps - 1) samples */
+ /* pStateCurnt points to the location where the new input data should be written */
+ pStateCurnt = &(S->pState[(numTaps - 1u)]);
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+ while(blkCnt > 0u)
+ {
+ /* Copy the new input sample into the state buffer */
+ *pStateCurnt++ = *pSrc++;
+
+ /* Initialize pState pointer */
+ px = pState;
+
+ /* Initialize pCoeffs pointer */
+ pb = pCoeffs;
+
+ /* Set the accumulator to zero */
+ acc = 0;
+
+ /* Loop over numTaps number of values */
+ tapCnt = numTaps;
+
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+ acc += (q63_t) ((q31_t) (*px++) * (*pb++));
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* Calc lower part of acc */
+ acc_l = acc & 0xffffffff;
+
+ /* Calc upper part of acc */
+ acc_h = (acc >> 32) & 0xffffffff;
+
+ /* Apply shift for lower part of acc and upper part of acc */
+ acc = (uint32_t) acc_l >> lShift | acc_h << uShift;
+
+ /* Converting the result to 1.15 format and saturate the output */
+ acc = __SSAT(acc, 16);
+
+ /* Store the result from accumulator into the destination buffer. */
+ *pOut++ = (q15_t) acc;
+
+ /* Compute and store error */
+ e = *pRef++ - (q15_t) acc;
+
+ *pErr++ = (q15_t) e;
+
+ /* Compute alpha i.e. intermediate constant for taps update */
+ alpha = (q15_t) (((q31_t) e * (mu)) >> 15);
+
+ /* Initialize pState pointer */
+ /* Advance state pointer by 1 for the next sample */
+ px = pState++;
+
+ /* Initialize pCoeffs pointer */
+ pb = pCoeffs;
+
+ /* Loop over numTaps number of values */
+ tapCnt = numTaps;
+
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+ coef = (q31_t) * pb + (((q31_t) alpha * (*px++)) >> 15);
+ *pb++ = (q15_t) __SSAT((coef), 16);
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* Decrement the loop counter */
+ blkCnt--;
+
+ }
+
+ /* Processing is complete. Now copy the last numTaps - 1 samples to the
+ start of the state buffer. This prepares the state buffer for the
+ next function call. */
+
+ /* Points to the start of the pState buffer */
+ pStateCurnt = S->pState;
+
+ /* Copy (numTaps - 1u) samples */
+ tapCnt = (numTaps - 1u);
+
+ /* Copy the data */
+ while(tapCnt > 0u)
+ {
+ *pStateCurnt++ = *pState++;
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+}
+
+/**
+ * @} end of LMS group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_q31.c
new file mode 100644
index 0000000..838e912
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_lms_q31.c
@@ -0,0 +1,369 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_lms_q31.c
+*
+* Description: Processing function for the Q31 LMS filter.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+/**
+ * @ingroup groupFilters
+ */
+
+/**
+ * @addtogroup LMS
+ * @{
+ */
+
+ /**
+ * @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.
+ *
+ * \par Scaling and Overflow Behavior:
+ * 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 clips.
+ * In order to avoid overflows completely the input signal must be scaled down by
+ * log2(numTaps) bits.
+ * The reference signal should not be scaled down.
+ * After all multiply-accumulates are performed, the 2.62 accumulator is shifted
+ * and saturated to 1.31 format to yield the final result.
+ * The output signal and error signal are in 1.31 format.
+ *
+ * \par
+ * In this filter, filter coefficients are updated for each sample and the updation of filter cofficients are saturted.
+ */
+
+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)
+{
+ q31_t *pState = S->pState; /* State pointer */
+ uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */
+ q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
+ q31_t *pStateCurnt; /* Points to the current sample of the state */
+ q31_t mu = S->mu; /* Adaptive factor */
+ q31_t *px; /* Temporary pointer for state */
+ q31_t *pb; /* Temporary pointer for coefficient buffer */
+ uint32_t tapCnt, blkCnt; /* Loop counters */
+ q63_t acc; /* Accumulator */
+ q31_t e = 0; /* error of data sample */
+ q31_t alpha; /* Intermediate constant for taps update */
+ q31_t coef; /* Temporary variable for coef */
+ q31_t acc_l, acc_h; /* temporary input */
+ uint32_t uShift = ((uint32_t) S->postShift + 1u);
+ uint32_t lShift = 32u - uShift; /* Shift to be applied to the output */
+
+ /* S->pState points to buffer which contains previous frame (numTaps - 1) samples */
+ /* pStateCurnt points to the location where the new input data should be written */
+ pStateCurnt = &(S->pState[(numTaps - 1u)]);
+
+ /* Initializing blkCnt with blockSize */
+ blkCnt = blockSize;
+
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ while(blkCnt > 0u)
+ {
+ /* Copy the new input sample into the state buffer */
+ *pStateCurnt++ = *pSrc++;
+
+ /* Initialize state pointer */
+ px = pState;
+
+ /* Initialize coefficient pointer */
+ pb = pCoeffs;
+
+ /* Set the accumulator to zero */
+ acc = 0;
+
+ /* Loop unrolling. Process 4 taps at a time. */
+ tapCnt = numTaps >> 2;
+
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+ /* acc += b[N] * x[n-N] */
+ acc += ((q63_t) (*px++)) * (*pb++);
+
+ /* acc += b[N-1] * x[n-N-1] */
+ acc += ((q63_t) (*px++)) * (*pb++);
+
+ /* acc += b[N-2] * x[n-N-2] */
+ acc += ((q63_t) (*px++)) * (*pb++);
+
+ /* acc += b[N-3] * x[n-N-3] */
+ acc += ((q63_t) (*px++)) * (*pb++);
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* If the filter length is not a multiple of 4, compute the remaining filter taps */
+ tapCnt = numTaps % 0x4u;
+
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+ acc += ((q63_t) (*px++)) * (*pb++);
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* Converting the result to 1.31 format */
+ /* Calc lower part of acc */
+ acc_l = acc & 0xffffffff;
+
+ /* Calc upper part of acc */
+ acc_h = (acc >> 32) & 0xffffffff;
+
+ acc = (uint32_t) acc_l >> lShift | acc_h << uShift;
+
+ /* Store the result from accumulator into the destination buffer. */
+ *pOut++ = (q31_t) acc;
+
+ /* Compute and store error */
+ e = *pRef++ - (q31_t) acc;
+
+ *pErr++ = (q31_t) e;
+
+ /* Compute alpha i.e. intermediate constant for taps update */
+ alpha = (q31_t) (((q63_t) e * mu) >> 31);
+
+ /* Initialize state pointer */
+ /* Advance state pointer by 1 for the next sample */
+ px = pState++;
+
+ /* Initialize coefficient pointer */
+ pb = pCoeffs;
+
+ /* Loop unrolling. Process 4 taps at a time. */
+ tapCnt = numTaps >> 2;
+
+ /* Update filter coefficients */
+ while(tapCnt > 0u)
+ {
+ /* coef is in 2.30 format */
+ coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32));
+ /* get coef in 1.31 format by left shifting */
+ *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
+ /* update coefficient buffer to next coefficient */
+ pb++;
+
+ coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32));
+ *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
+ pb++;
+
+ coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32));
+ *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
+ pb++;
+
+ coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32));
+ *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
+ pb++;
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* If the filter length is not a multiple of 4, compute the remaining filter taps */
+ tapCnt = numTaps % 0x4u;
+
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+ coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32));
+ *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
+ pb++;
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Processing is complete. Now copy the last numTaps - 1 samples to the
+ satrt of the state buffer. This prepares the state buffer for the
+ next function call. */
+
+ /* Points to the start of the pState buffer */
+ pStateCurnt = S->pState;
+
+ /* Loop unrolling for (numTaps - 1u) samples copy */
+ tapCnt = (numTaps - 1u) >> 2u;
+
+ /* copy data */
+ while(tapCnt > 0u)
+ {
+ *pStateCurnt++ = *pState++;
+ *pStateCurnt++ = *pState++;
+ *pStateCurnt++ = *pState++;
+ *pStateCurnt++ = *pState++;
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* Calculate remaining number of copies */
+ tapCnt = (numTaps - 1u) % 0x4u;
+
+ /* Copy the remaining q31_t data */
+ while(tapCnt > 0u)
+ {
+ *pStateCurnt++ = *pState++;
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ while(blkCnt > 0u)
+ {
+ /* Copy the new input sample into the state buffer */
+ *pStateCurnt++ = *pSrc++;
+
+ /* Initialize pState pointer */
+ px = pState;
+
+ /* Initialize pCoeffs pointer */
+ pb = pCoeffs;
+
+ /* Set the accumulator to zero */
+ acc = 0;
+
+ /* Loop over numTaps number of values */
+ tapCnt = numTaps;
+
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+ acc += ((q63_t) (*px++)) * (*pb++);
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* Converting the result to 1.31 format */
+ /* Store the result from accumulator into the destination buffer. */
+ /* Calc lower part of acc */
+ acc_l = acc & 0xffffffff;
+
+ /* Calc upper part of acc */
+ acc_h = (acc >> 32) & 0xffffffff;
+
+ acc = (uint32_t) acc_l >> lShift | acc_h << uShift;
+
+ *pOut++ = (q31_t) acc;
+
+ /* Compute and store error */
+ e = *pRef++ - (q31_t) acc;
+
+ *pErr++ = (q31_t) e;
+
+ /* Weighting factor for the LMS version */
+ alpha = (q31_t) (((q63_t) e * mu) >> 31);
+
+ /* Initialize pState pointer */
+ /* Advance state pointer by 1 for the next sample */
+ px = pState++;
+
+ /* Initialize pCoeffs pointer */
+ pb = pCoeffs;
+
+ /* Loop over numTaps number of values */
+ tapCnt = numTaps;
+
+ while(tapCnt > 0u)
+ {
+ /* Perform the multiply-accumulate */
+ coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32));
+ *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1u));
+ pb++;
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Processing is complete. Now copy the last numTaps - 1 samples to the
+ start of the state buffer. This prepares the state buffer for the
+ next function call. */
+
+ /* Points to the start of the pState buffer */
+ pStateCurnt = S->pState;
+
+ /* Copy (numTaps - 1u) samples */
+ tapCnt = (numTaps - 1u);
+
+ /* Copy the data */
+ while(tapCnt > 0u)
+ {
+ *pStateCurnt++ = *pState++;
+
+ /* Decrement the loop counter */
+ tapCnt--;
+ }
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+}
+
+/**
+ * @} end of LMS group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_add_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_add_f32.c
new file mode 100644
index 0000000..e418492
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_add_f32.c
@@ -0,0 +1,208 @@
+/* ----------------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_add_f32.c
+*
+* Description: Floating-point matrix addition
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @defgroup MatrixAdd Matrix Addition
+ *
+ * Adds two matrices.
+ * \image html MatrixAddition.gif "Addition of two 3 x 3 matrices"
+ *
+ * The functions check to make sure that
+ * pSrcA
, pSrcB
, and pDst
have the same
+ * number of rows and columns.
+ */
+
+/**
+ * @addtogroup MatrixAdd
+ * @{
+ */
+
+
+/**
+ * @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)
+{
+ float32_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
+ float32_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
+ float32_t *pOut = pDst->pData; /* output data matrix pointer */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ float32_t inA1, inA2, inB1, inB2, out1, out2; /* temporary variables */
+
+#endif // #ifndef ARM_MATH_CM0_FAMILY
+
+ uint32_t numSamples; /* total number of elements in the matrix */
+ uint32_t blkCnt; /* loop counters */
+ arm_status status; /* status of matrix addition */
+
+#ifdef ARM_MATH_MATRIX_CHECK
+ /* Check for matrix mismatch condition */
+ if((pSrcA->numRows != pSrcB->numRows) ||
+ (pSrcA->numCols != pSrcB->numCols) ||
+ (pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif
+ {
+
+ /* Total number of samples in the input matrix */
+ numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols;
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Loop unrolling */
+ blkCnt = numSamples >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) + B(m,n) */
+ /* Add and then store the results in the destination buffer. */
+ /* Read values from source A */
+ inA1 = pIn1[0];
+
+ /* Read values from source B */
+ inB1 = pIn2[0];
+
+ /* Read values from source A */
+ inA2 = pIn1[1];
+
+ /* out = sourceA + sourceB */
+ out1 = inA1 + inB1;
+
+ /* Read values from source B */
+ inB2 = pIn2[1];
+
+ /* Read values from source A */
+ inA1 = pIn1[2];
+
+ /* out = sourceA + sourceB */
+ out2 = inA2 + inB2;
+
+ /* Read values from source B */
+ inB1 = pIn2[2];
+
+ /* Store result in destination */
+ pOut[0] = out1;
+ pOut[1] = out2;
+
+ /* Read values from source A */
+ inA2 = pIn1[3];
+
+ /* Read values from source B */
+ inB2 = pIn2[3];
+
+ /* out = sourceA + sourceB */
+ out1 = inA1 + inB1;
+
+ /* out = sourceA + sourceB */
+ out2 = inA2 + inB2;
+
+ /* Store result in destination */
+ pOut[2] = out1;
+
+ /* Store result in destination */
+ pOut[3] = out2;
+
+
+ /* update pointers to process next sampels */
+ pIn1 += 4u;
+ pIn2 += 4u;
+ pOut += 4u;
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the numSamples is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = numSamples % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Initialize blkCnt with number of samples */
+ blkCnt = numSamples;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) + B(m,n) */
+ /* Add and then store the results in the destination buffer. */
+ *pOut++ = (*pIn1++) + (*pIn2++);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+
+ }
+
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixAdd group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_add_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_add_q15.c
new file mode 100644
index 0000000..45d1837
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_add_q15.c
@@ -0,0 +1,163 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_add_q15.c
+*
+* Description: Q15 matrix addition
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @addtogroup MatrixAdd
+ * @{
+ */
+
+/**
+ * @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.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function uses saturating arithmetic.
+ * Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
+ */
+
+arm_status arm_mat_add_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst)
+{
+ q15_t *pInA = pSrcA->pData; /* input data matrix pointer A */
+ q15_t *pInB = pSrcB->pData; /* input data matrix pointer B */
+ q15_t *pOut = pDst->pData; /* output data matrix pointer */
+ uint16_t numSamples; /* total number of elements in the matrix */
+ uint32_t blkCnt; /* loop counters */
+ arm_status status; /* status of matrix addition */
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+
+ /* Check for matrix mismatch condition */
+ if((pSrcA->numRows != pSrcB->numRows) ||
+ (pSrcA->numCols != pSrcB->numCols) ||
+ (pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+
+ {
+ /* Total number of samples in the input matrix */
+ numSamples = (uint16_t) (pSrcA->numRows * pSrcA->numCols);
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /* Loop unrolling */
+ blkCnt = (uint32_t) numSamples >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) + B(m,n) */
+ /* Add, Saturate and then store the results in the destination buffer. */
+ *__SIMD32(pOut)++ = __QADD16(*__SIMD32(pInA)++, *__SIMD32(pInB)++);
+ *__SIMD32(pOut)++ = __QADD16(*__SIMD32(pInA)++, *__SIMD32(pInB)++);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = (uint32_t) numSamples % 0x4u;
+
+ /* q15 pointers of input and output are initialized */
+
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) + B(m,n) */
+ /* Add, Saturate and then store the results in the destination buffer. */
+ *pOut++ = (q15_t) __QADD16(*pInA++, *pInB++);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Initialize blkCnt with number of samples */
+ blkCnt = (uint32_t) numSamples;
+
+
+ /* q15 pointers of input and output are initialized */
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) + B(m,n) */
+ /* Add, Saturate and then store the results in the destination buffer. */
+ *pOut++ = (q15_t) __SSAT(((q31_t) * pInA++ + *pInB++), 16);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ /* set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixAdd group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_add_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_add_q31.c
new file mode 100644
index 0000000..b6ccddb
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_add_q31.c
@@ -0,0 +1,207 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_add_q31.c
+*
+* Description: Q31 matrix addition
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @addtogroup MatrixAdd
+ * @{
+ */
+
+/**
+ * @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.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function uses saturating arithmetic.
+ * Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] will be saturated.
+ */
+
+arm_status arm_mat_add_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst)
+{
+ q31_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
+ q31_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
+ q31_t *pOut = pDst->pData; /* output data matrix pointer */
+ q31_t inA1, inB1; /* temporary variables */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ q31_t inA2, inB2; /* temporary variables */
+ q31_t out1, out2; /* temporary variables */
+
+#endif // #ifndef ARM_MATH_CM0_FAMILY
+
+ uint32_t numSamples; /* total number of elements in the matrix */
+ uint32_t blkCnt; /* loop counters */
+ arm_status status; /* status of matrix addition */
+
+#ifdef ARM_MATH_MATRIX_CHECK
+ /* Check for matrix mismatch condition */
+ if((pSrcA->numRows != pSrcB->numRows) ||
+ (pSrcA->numCols != pSrcB->numCols) ||
+ (pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif
+ {
+ /* Total number of samples in the input matrix */
+ numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols;
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /* Loop Unrolling */
+ blkCnt = numSamples >> 2u;
+
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) + B(m,n) */
+ /* Add, saturate and then store the results in the destination buffer. */
+ /* Read values from source A */
+ inA1 = pIn1[0];
+
+ /* Read values from source B */
+ inB1 = pIn2[0];
+
+ /* Read values from source A */
+ inA2 = pIn1[1];
+
+ /* Add and saturate */
+ out1 = __QADD(inA1, inB1);
+
+ /* Read values from source B */
+ inB2 = pIn2[1];
+
+ /* Read values from source A */
+ inA1 = pIn1[2];
+
+ /* Add and saturate */
+ out2 = __QADD(inA2, inB2);
+
+ /* Read values from source B */
+ inB1 = pIn2[2];
+
+ /* Store result in destination */
+ pOut[0] = out1;
+ pOut[1] = out2;
+
+ /* Read values from source A */
+ inA2 = pIn1[3];
+
+ /* Read values from source B */
+ inB2 = pIn2[3];
+
+ /* Add and saturate */
+ out1 = __QADD(inA1, inB1);
+ out2 = __QADD(inA2, inB2);
+
+ /* Store result in destination */
+ pOut[2] = out1;
+ pOut[3] = out2;
+
+ /* update pointers to process next sampels */
+ pIn1 += 4u;
+ pIn2 += 4u;
+ pOut += 4u;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the numSamples is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = numSamples % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Initialize blkCnt with number of samples */
+ blkCnt = numSamples;
+
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) + B(m,n) */
+ /* Add, saturate and then store the results in the destination buffer. */
+ inA1 = *pIn1++;
+ inB1 = *pIn2++;
+
+ inA1 = __QADD(inA1, inB1);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+
+ *pOut++ = inA1;
+
+ }
+
+ /* set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixAdd group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_f32.c
new file mode 100644
index 0000000..d9d3388
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_f32.c
@@ -0,0 +1,283 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_cmplx_mult_f32.c
+*
+* Description: Floating-point matrix multiplication.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @defgroup CmplxMatrixMult Complex Matrix Multiplication
+ *
+ * Complex Matrix multiplication is only defined if the number of columns of the
+ * first matrix equals the number of rows of the second matrix.
+ * Multiplying an M x N
matrix with an N x P
matrix results
+ * in an M x P
matrix.
+ * When matrix size checking is enabled, the functions check: (1) that the inner dimensions of
+ * pSrcA
and pSrcB
are equal; and (2) that the size of the output
+ * matrix equals the outer dimensions of pSrcA
and pSrcB
.
+ */
+
+
+/**
+ * @addtogroup CmplxMatrixMult
+ * @{
+ */
+
+/**
+ * @brief Floating-point Complex matrix multiplication.
+ * @param[in] *pSrcA points to the first input complex matrix structure
+ * @param[in] *pSrcB points to the second input complex matrix structure
+ * @param[out] *pDst points to output complex 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_cmplx_mult_f32(
+ const arm_matrix_instance_f32 * pSrcA,
+ const arm_matrix_instance_f32 * pSrcB,
+ arm_matrix_instance_f32 * pDst)
+{
+ float32_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
+ float32_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
+ float32_t *pInA = pSrcA->pData; /* input data matrix pointer A */
+ float32_t *pOut = pDst->pData; /* output data matrix pointer */
+ float32_t *px; /* Temporary output data matrix pointer */
+ uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
+ uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
+ uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
+ float32_t sumReal1, sumImag1; /* accumulator */
+ float32_t a0, b0, c0, d0;
+ float32_t a1, b1, c1, d1;
+ float32_t sumReal2, sumImag2; /* accumulator */
+
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ uint16_t col, i = 0u, j, row = numRowsA, colCnt; /* loop counters */
+ arm_status status; /* status of matrix multiplication */
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+
+ /* Check for matrix mismatch condition */
+ if((pSrcA->numCols != pSrcB->numRows) ||
+ (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
+ {
+
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+
+ {
+ /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
+ /* row loop */
+ do
+ {
+ /* Output pointer is set to starting address of the row being processed */
+ px = pOut + 2 * i;
+
+ /* For every row wise process, the column loop counter is to be initiated */
+ col = numColsB;
+
+ /* For every row wise process, the pIn2 pointer is set
+ ** to the starting address of the pSrcB data */
+ pIn2 = pSrcB->pData;
+
+ j = 0u;
+
+ /* column loop */
+ do
+ {
+ /* Set the variable sum, that acts as accumulator, to zero */
+ sumReal1 = 0.0f;
+ sumImag1 = 0.0f;
+
+ sumReal2 = 0.0f;
+ sumImag2 = 0.0f;
+
+ /* Initiate the pointer pIn1 to point to the starting address of the column being processed */
+ pIn1 = pInA;
+
+ /* Apply loop unrolling and compute 4 MACs simultaneously. */
+ colCnt = numColsA >> 2;
+
+ /* matrix multiplication */
+ while(colCnt > 0u)
+ {
+
+ /* Reading real part of complex matrix A */
+ a0 = *pIn1;
+
+ /* Reading real part of complex matrix B */
+ c0 = *pIn2;
+
+ /* Reading imaginary part of complex matrix A */
+ b0 = *(pIn1 + 1u);
+
+ /* Reading imaginary part of complex matrix B */
+ d0 = *(pIn2 + 1u);
+
+ sumReal1 += a0 * c0;
+ sumImag1 += b0 * c0;
+
+ pIn1 += 2u;
+ pIn2 += 2 * numColsB;
+
+ sumReal2 -= b0 * d0;
+ sumImag2 += a0 * d0;
+
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+
+ a1 = *pIn1;
+ c1 = *pIn2;
+
+ b1 = *(pIn1 + 1u);
+ d1 = *(pIn2 + 1u);
+
+ sumReal1 += a1 * c1;
+ sumImag1 += b1 * c1;
+
+ pIn1 += 2u;
+ pIn2 += 2 * numColsB;
+
+ sumReal2 -= b1 * d1;
+ sumImag2 += a1 * d1;
+
+ a0 = *pIn1;
+ c0 = *pIn2;
+
+ b0 = *(pIn1 + 1u);
+ d0 = *(pIn2 + 1u);
+
+ sumReal1 += a0 * c0;
+ sumImag1 += b0 * c0;
+
+ pIn1 += 2u;
+ pIn2 += 2 * numColsB;
+
+ sumReal2 -= b0 * d0;
+ sumImag2 += a0 * d0;
+
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+
+ a1 = *pIn1;
+ c1 = *pIn2;
+
+ b1 = *(pIn1 + 1u);
+ d1 = *(pIn2 + 1u);
+
+ sumReal1 += a1 * c1;
+ sumImag1 += b1 * c1;
+
+ pIn1 += 2u;
+ pIn2 += 2 * numColsB;
+
+ sumReal2 -= b1 * d1;
+ sumImag2 += a1 * d1;
+
+ /* Decrement the loop count */
+ colCnt--;
+ }
+
+ /* If the columns of pSrcA is not a multiple of 4, compute any remaining MACs here.
+ ** No loop unrolling is used. */
+ colCnt = numColsA % 0x4u;
+
+ while(colCnt > 0u)
+ {
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+ a1 = *pIn1;
+ c1 = *pIn2;
+
+ b1 = *(pIn1 + 1u);
+ d1 = *(pIn2 + 1u);
+
+ sumReal1 += a1 * c1;
+ sumImag1 += b1 * c1;
+
+ pIn1 += 2u;
+ pIn2 += 2 * numColsB;
+
+ sumReal2 -= b1 * d1;
+ sumImag2 += a1 * d1;
+
+ /* Decrement the loop counter */
+ colCnt--;
+ }
+
+ sumReal1 += sumReal2;
+ sumImag1 += sumImag2;
+
+ /* Store the result in the destination buffer */
+ *px++ = sumReal1;
+ *px++ = sumImag1;
+
+ /* Update the pointer pIn2 to point to the starting address of the next column */
+ j++;
+ pIn2 = pSrcB->pData + 2u * j;
+
+ /* Decrement the column loop counter */
+ col--;
+
+ } while(col > 0u);
+
+ /* Update the pointer pInA to point to the starting address of the next row */
+ i = i + numColsB;
+ pInA = pInA + 2 * numColsA;
+
+ /* Decrement the row loop counter */
+ row--;
+
+ } while(row > 0u);
+
+ /* Set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixMult group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_q15.c
new file mode 100644
index 0000000..46122ab
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_q15.c
@@ -0,0 +1,424 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_cmplx_mat_mult_q15.c
+*
+* Description: Q15 complex matrix multiplication.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @addtogroup CmplxMatrixMult
+ * @{
+ */
+
+
+/**
+ * @brief Q15 Complex matrix multiplication
+ * @param[in] *pSrcA points to the first input complex matrix structure
+ * @param[in] *pSrcB points to the second input complex matrix structure
+ * @param[out] *pDst points to output complex matrix structure
+ * @param[in] *pScratch 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.
+ *
+ * \par Conditions for optimum performance
+ * Input, output and state buffers should be aligned by 32-bit
+ *
+ * \par Restrictions
+ * If the silicon does not support unaligned memory access enable the macro UNALIGNED_SUPPORT_DISABLE
+ * In this case input, output, scratch buffers should be aligned by 32-bit
+ *
+ * @details
+ * Scaling and Overflow Behavior:
+ *
+ * \par
+ * The function is implemented using a 64-bit internal accumulator. The inputs to the
+ * multiplications are 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. This approach
+ * provides 33 guard bits and there is no risk of overflow. The 34.30 result is then
+ * truncated to 34.15 format by discarding the low 15 bits and then saturated to
+ * 1.15 format.
+ *
+ * \par
+ * Refer to arm_mat_mult_fast_q15()
for a faster but less precise version of this function.
+ *
+ */
+
+
+
+
+arm_status arm_mat_cmplx_mult_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst,
+ q15_t * pScratch)
+{
+ /* accumulator */
+ q15_t *pSrcBT = pScratch; /* input data matrix pointer for transpose */
+ q15_t *pInA = pSrcA->pData; /* input data matrix pointer A of Q15 type */
+ q15_t *pInB = pSrcB->pData; /* input data matrix pointer B of Q15 type */
+ q15_t *px; /* Temporary output data matrix pointer */
+ uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
+ uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
+ uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
+ uint16_t numRowsB = pSrcB->numRows; /* number of rows of input matrix A */
+ uint16_t col, i = 0u, row = numRowsB, colCnt; /* loop counters */
+ arm_status status; /* status of matrix multiplication */
+ q63_t sumReal, sumImag;
+
+#ifdef UNALIGNED_SUPPORT_DISABLE
+ q15_t in; /* Temporary variable to hold the input value */
+ q15_t a, b, c, d;
+#else
+ q31_t in; /* Temporary variable to hold the input value */
+ q31_t prod1, prod2;
+ q31_t pSourceA, pSourceB;
+#endif
+
+#ifdef ARM_MATH_MATRIX_CHECK
+ /* Check for matrix mismatch condition */
+ if((pSrcA->numCols != pSrcB->numRows) ||
+ (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif
+ {
+ /* Matrix transpose */
+ do
+ {
+ /* Apply loop unrolling and exchange the columns with row elements */
+ col = numColsB >> 2;
+
+ /* The pointer px is set to starting address of the column being processed */
+ px = pSrcBT + i;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(col > 0u)
+ {
+#ifdef UNALIGNED_SUPPORT_DISABLE
+ /* Read two elements from the row */
+ in = *pInB++;
+ *px = in;
+ in = *pInB++;
+ px[1] = in;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB * 2;
+
+ /* Read two elements from the row */
+ in = *pInB++;
+ *px = in;
+ in = *pInB++;
+ px[1] = in;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB * 2;
+
+ /* Read two elements from the row */
+ in = *pInB++;
+ *px = in;
+ in = *pInB++;
+ px[1] = in;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB * 2;
+
+ /* Read two elements from the row */
+ in = *pInB++;
+ *px = in;
+ in = *pInB++;
+ px[1] = in;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB * 2;
+
+ /* Decrement the column loop counter */
+ col--;
+ }
+
+ /* If the columns of pSrcB is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ col = numColsB % 0x4u;
+
+ while(col > 0u)
+ {
+ /* Read two elements from the row */
+ in = *pInB++;
+ *px = in;
+ in = *pInB++;
+ px[1] = in;
+#else
+
+ /* Read two elements from the row */
+ in = *__SIMD32(pInB)++;
+
+ *__SIMD32(px) = in;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB * 2;
+
+
+ /* Read two elements from the row */
+ in = *__SIMD32(pInB)++;
+
+ *__SIMD32(px) = in;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB * 2;
+
+ /* Read two elements from the row */
+ in = *__SIMD32(pInB)++;
+
+ *__SIMD32(px) = in;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB * 2;
+
+ /* Read two elements from the row */
+ in = *__SIMD32(pInB)++;
+
+ *__SIMD32(px) = in;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB * 2;
+
+ /* Decrement the column loop counter */
+ col--;
+ }
+
+ /* If the columns of pSrcB is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ col = numColsB % 0x4u;
+
+ while(col > 0u)
+ {
+ /* Read two elements from the row */
+ in = *__SIMD32(pInB)++;
+
+ *__SIMD32(px) = in;
+#endif
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB * 2;
+
+ /* Decrement the column loop counter */
+ col--;
+ }
+
+ i = i + 2u;
+
+ /* Decrement the row loop counter */
+ row--;
+
+ } while(row > 0u);
+
+ /* Reset the variables for the usage in the following multiplication process */
+ row = numRowsA;
+ i = 0u;
+ px = pDst->pData;
+
+ /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
+ /* row loop */
+ do
+ {
+ /* For every row wise process, the column loop counter is to be initiated */
+ col = numColsB;
+
+ /* For every row wise process, the pIn2 pointer is set
+ ** to the starting address of the transposed pSrcB data */
+ pInB = pSrcBT;
+
+ /* column loop */
+ do
+ {
+ /* Set the variable sum, that acts as accumulator, to zero */
+ sumReal = 0;
+ sumImag = 0;
+
+ /* Apply loop unrolling and compute 2 MACs simultaneously. */
+ colCnt = numColsA >> 1;
+
+ /* Initiate the pointer pIn1 to point to the starting address of the column being processed */
+ pInA = pSrcA->pData + i * 2;
+
+
+ /* matrix multiplication */
+ while(colCnt > 0u)
+ {
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+
+#ifdef UNALIGNED_SUPPORT_DISABLE
+
+ /* read real and imag values from pSrcA buffer */
+ a = *pInA;
+ b = *(pInA + 1u);
+ /* read real and imag values from pSrcB buffer */
+ c = *pInB;
+ d = *(pInB + 1u);
+
+ /* Multiply and Accumlates */
+ sumReal += (q31_t) a *c;
+ sumImag += (q31_t) a *d;
+ sumReal -= (q31_t) b *d;
+ sumImag += (q31_t) b *c;
+
+ /* read next real and imag values from pSrcA buffer */
+ a = *(pInA + 2u);
+ b = *(pInA + 3u);
+ /* read next real and imag values from pSrcB buffer */
+ c = *(pInB + 2u);
+ d = *(pInB + 3u);
+
+ /* update pointer */
+ pInA += 4u;
+
+ /* Multiply and Accumlates */
+ sumReal += (q31_t) a *c;
+ sumImag += (q31_t) a *d;
+ sumReal -= (q31_t) b *d;
+ sumImag += (q31_t) b *c;
+ /* update pointer */
+ pInB += 4u;
+#else
+ /* read real and imag values from pSrcA and pSrcB buffer */
+ pSourceA = *__SIMD32(pInA)++;
+ pSourceB = *__SIMD32(pInB)++;
+
+ /* Multiply and Accumlates */
+#ifdef ARM_MATH_BIG_ENDIAN
+ prod1 = -__SMUSD(pSourceA, pSourceB);
+#else
+ prod1 = __SMUSD(pSourceA, pSourceB);
+#endif
+ prod2 = __SMUADX(pSourceA, pSourceB);
+ sumReal += (q63_t) prod1;
+ sumImag += (q63_t) prod2;
+
+ /* read real and imag values from pSrcA and pSrcB buffer */
+ pSourceA = *__SIMD32(pInA)++;
+ pSourceB = *__SIMD32(pInB)++;
+
+ /* Multiply and Accumlates */
+#ifdef ARM_MATH_BIG_ENDIAN
+ prod1 = -__SMUSD(pSourceA, pSourceB);
+#else
+ prod1 = __SMUSD(pSourceA, pSourceB);
+#endif
+ prod2 = __SMUADX(pSourceA, pSourceB);
+ sumReal += (q63_t) prod1;
+ sumImag += (q63_t) prod2;
+
+#endif /* #ifdef UNALIGNED_SUPPORT_DISABLE */
+
+ /* Decrement the loop counter */
+ colCnt--;
+ }
+
+ /* process odd column samples */
+ if((numColsA & 0x1u) > 0u)
+ {
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+
+#ifdef UNALIGNED_SUPPORT_DISABLE
+
+ /* read real and imag values from pSrcA and pSrcB buffer */
+ a = *pInA++;
+ b = *pInA++;
+ c = *pInB++;
+ d = *pInB++;
+
+ /* Multiply and Accumlates */
+ sumReal += (q31_t) a *c;
+ sumImag += (q31_t) a *d;
+ sumReal -= (q31_t) b *d;
+ sumImag += (q31_t) b *c;
+
+#else
+ /* read real and imag values from pSrcA and pSrcB buffer */
+ pSourceA = *__SIMD32(pInA)++;
+ pSourceB = *__SIMD32(pInB)++;
+
+ /* Multiply and Accumlates */
+#ifdef ARM_MATH_BIG_ENDIAN
+ prod1 = -__SMUSD(pSourceA, pSourceB);
+#else
+ prod1 = __SMUSD(pSourceA, pSourceB);
+#endif
+ prod2 = __SMUADX(pSourceA, pSourceB);
+ sumReal += (q63_t) prod1;
+ sumImag += (q63_t) prod2;
+
+#endif /* #ifdef UNALIGNED_SUPPORT_DISABLE */
+
+ }
+
+ /* Saturate and store the result in the destination buffer */
+
+ *px++ = (q15_t) (__SSAT(sumReal >> 15, 16));
+ *px++ = (q15_t) (__SSAT(sumImag >> 15, 16));
+
+ /* Decrement the column loop counter */
+ col--;
+
+ } while(col > 0u);
+
+ i = i + numColsA;
+
+ /* Decrement the row loop counter */
+ row--;
+
+ } while(row > 0u);
+
+ /* set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixMult group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_q31.c
new file mode 100644
index 0000000..4053554
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_q31.c
@@ -0,0 +1,293 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_cmplx_mult_q31.c
+*
+* Description: Floating-point matrix multiplication.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @addtogroup CmplxMatrixMult
+ * @{
+ */
+
+/**
+ * @brief Q31 Complex matrix multiplication
+ * @param[in] *pSrcA points to the first input complex matrix structure
+ * @param[in] *pSrcB points to the second input complex matrix structure
+ * @param[out] *pDst points to output complex matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ *
+ * @details
+ * 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. There is no saturation
+ * on intermediate additions. Thus, if the accumulator overflows it wraps around and
+ * distorts the result. The input signals should be scaled down to avoid intermediate
+ * overflows. The input is thus scaled down by log2(numColsA) bits
+ * to avoid overflows, as a total of numColsA additions are performed internally.
+ * The 2.62 accumulator is right shifted by 31 bits and saturated to 1.31 format to yield the final result.
+ *
+ *
+ */
+
+arm_status arm_mat_cmplx_mult_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst)
+{
+ q31_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
+ q31_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
+ q31_t *pInA = pSrcA->pData; /* input data matrix pointer A */
+ q31_t *pOut = pDst->pData; /* output data matrix pointer */
+ q31_t *px; /* Temporary output data matrix pointer */
+ uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
+ uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
+ uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
+ q63_t sumReal1, sumImag1; /* accumulator */
+ q31_t a0, b0, c0, d0;
+ q31_t a1, b1, c1, d1;
+
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ uint16_t col, i = 0u, j, row = numRowsA, colCnt; /* loop counters */
+ arm_status status; /* status of matrix multiplication */
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+
+ /* Check for matrix mismatch condition */
+ if((pSrcA->numCols != pSrcB->numRows) ||
+ (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
+ {
+
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+
+ {
+ /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
+ /* row loop */
+ do
+ {
+ /* Output pointer is set to starting address of the row being processed */
+ px = pOut + 2 * i;
+
+ /* For every row wise process, the column loop counter is to be initiated */
+ col = numColsB;
+
+ /* For every row wise process, the pIn2 pointer is set
+ ** to the starting address of the pSrcB data */
+ pIn2 = pSrcB->pData;
+
+ j = 0u;
+
+ /* column loop */
+ do
+ {
+ /* Set the variable sum, that acts as accumulator, to zero */
+ sumReal1 = 0.0;
+ sumImag1 = 0.0;
+
+ /* Initiate the pointer pIn1 to point to the starting address of the column being processed */
+ pIn1 = pInA;
+
+ /* Apply loop unrolling and compute 4 MACs simultaneously. */
+ colCnt = numColsA >> 2;
+
+ /* matrix multiplication */
+ while(colCnt > 0u)
+ {
+
+ /* Reading real part of complex matrix A */
+ a0 = *pIn1;
+
+ /* Reading real part of complex matrix B */
+ c0 = *pIn2;
+
+ /* Reading imaginary part of complex matrix A */
+ b0 = *(pIn1 + 1u);
+
+ /* Reading imaginary part of complex matrix B */
+ d0 = *(pIn2 + 1u);
+
+ /* Multiply and Accumlates */
+ sumReal1 += (q63_t) a0 *c0;
+ sumImag1 += (q63_t) b0 *c0;
+
+ /* update pointers */
+ pIn1 += 2u;
+ pIn2 += 2 * numColsB;
+
+ /* Multiply and Accumlates */
+ sumReal1 -= (q63_t) b0 *d0;
+ sumImag1 += (q63_t) a0 *d0;
+
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+
+ /* read real and imag values from pSrcA and pSrcB buffer */
+ a1 = *pIn1;
+ c1 = *pIn2;
+ b1 = *(pIn1 + 1u);
+ d1 = *(pIn2 + 1u);
+
+ /* Multiply and Accumlates */
+ sumReal1 += (q63_t) a1 *c1;
+ sumImag1 += (q63_t) b1 *c1;
+
+ /* update pointers */
+ pIn1 += 2u;
+ pIn2 += 2 * numColsB;
+
+ /* Multiply and Accumlates */
+ sumReal1 -= (q63_t) b1 *d1;
+ sumImag1 += (q63_t) a1 *d1;
+
+ a0 = *pIn1;
+ c0 = *pIn2;
+
+ b0 = *(pIn1 + 1u);
+ d0 = *(pIn2 + 1u);
+
+ /* Multiply and Accumlates */
+ sumReal1 += (q63_t) a0 *c0;
+ sumImag1 += (q63_t) b0 *c0;
+
+ /* update pointers */
+ pIn1 += 2u;
+ pIn2 += 2 * numColsB;
+
+ /* Multiply and Accumlates */
+ sumReal1 -= (q63_t) b0 *d0;
+ sumImag1 += (q63_t) a0 *d0;
+
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+
+ a1 = *pIn1;
+ c1 = *pIn2;
+
+ b1 = *(pIn1 + 1u);
+ d1 = *(pIn2 + 1u);
+
+ /* Multiply and Accumlates */
+ sumReal1 += (q63_t) a1 *c1;
+ sumImag1 += (q63_t) b1 *c1;
+
+ /* update pointers */
+ pIn1 += 2u;
+ pIn2 += 2 * numColsB;
+
+ /* Multiply and Accumlates */
+ sumReal1 -= (q63_t) b1 *d1;
+ sumImag1 += (q63_t) a1 *d1;
+
+ /* Decrement the loop count */
+ colCnt--;
+ }
+
+ /* If the columns of pSrcA is not a multiple of 4, compute any remaining MACs here.
+ ** No loop unrolling is used. */
+ colCnt = numColsA % 0x4u;
+
+ while(colCnt > 0u)
+ {
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+ a1 = *pIn1;
+ c1 = *pIn2;
+
+ b1 = *(pIn1 + 1u);
+ d1 = *(pIn2 + 1u);
+
+ /* Multiply and Accumlates */
+ sumReal1 += (q63_t) a1 *c1;
+ sumImag1 += (q63_t) b1 *c1;
+
+ /* update pointers */
+ pIn1 += 2u;
+ pIn2 += 2 * numColsB;
+
+ /* Multiply and Accumlates */
+ sumReal1 -= (q63_t) b1 *d1;
+ sumImag1 += (q63_t) a1 *d1;
+
+ /* Decrement the loop counter */
+ colCnt--;
+ }
+
+ /* Store the result in the destination buffer */
+ *px++ = (q31_t) clip_q63_to_q31(sumReal1 >> 31);
+ *px++ = (q31_t) clip_q63_to_q31(sumImag1 >> 31);
+
+ /* Update the pointer pIn2 to point to the starting address of the next column */
+ j++;
+ pIn2 = pSrcB->pData + 2u * j;
+
+ /* Decrement the column loop counter */
+ col--;
+
+ } while(col > 0u);
+
+ /* Update the pointer pInA to point to the starting address of the next row */
+ i = i + numColsB;
+ pInA = pInA + 2 * numColsA;
+
+ /* Decrement the row loop counter */
+ row--;
+
+ } while(row > 0u);
+
+ /* Set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixMult group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_init_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_init_f32.c
new file mode 100644
index 0000000..2a670b3
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_init_f32.c
@@ -0,0 +1,88 @@
+/* ----------------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_init_f32.c
+*
+* Description: Floating-point matrix initialization.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @defgroup MatrixInit Matrix Initialization
+ *
+ * Initializes the underlying matrix data structure.
+ * The functions set the numRows
,
+ * numCols
, and pData
fields
+ * of the matrix data structure.
+ */
+
+/**
+ * @addtogroup MatrixInit
+ * @{
+ */
+
+/**
+ * @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)
+{
+ /* Assign Number of Rows */
+ S->numRows = nRows;
+
+ /* Assign Number of Columns */
+ S->numCols = nColumns;
+
+ /* Assign Data pointer */
+ S->pData = pData;
+}
+
+/**
+ * @} end of MatrixInit group
+ */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_init_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_init_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_init_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_init_q15.c
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_init_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_init_q31.c
new file mode 100644
index 0000000..3fefda4
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_init_q31.c
@@ -0,0 +1,84 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_init_q31.c
+*
+* Description: Q31 matrix initialization.
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @defgroup MatrixInit Matrix Initialization
+ *
+ */
+
+/**
+ * @addtogroup MatrixInit
+ * @{
+ */
+
+ /**
+ * @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)
+{
+ /* Assign Number of Rows */
+ S->numRows = nRows;
+
+ /* Assign Number of Columns */
+ S->numCols = nColumns;
+
+ /* Assign Data pointer */
+ S->pData = pData;
+}
+
+/**
+ * @} end of MatrixInit group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_inverse_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_inverse_f32.c
new file mode 100644
index 0000000..f6fb9da
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_inverse_f32.c
@@ -0,0 +1,703 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_inverse_f32.c
+*
+* Description: Floating-point matrix inverse.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @defgroup MatrixInv Matrix Inverse
+ *
+ * Computes the inverse of a matrix.
+ *
+ * The inverse is defined only if the input matrix is square and non-singular (the determinant
+ * is non-zero). The function checks that the input and output matrices are square and of the
+ * same size.
+ *
+ * Matrix inversion is numerically sensitive and the CMSIS DSP library only supports matrix
+ * inversion of floating-point matrices.
+ *
+ * \par Algorithm
+ * The Gauss-Jordan method is used to find the inverse.
+ * The algorithm performs a sequence of elementary row-operations until it
+ * reduces the input matrix to an identity matrix. Applying the same sequence
+ * of elementary row-operations to an identity matrix yields the inverse matrix.
+ * If the input matrix is singular, then the algorithm terminates and returns error status
+ * ARM_MATH_SINGULAR
.
+ * \image html MatrixInverse.gif "Matrix Inverse of a 3 x 3 matrix using Gauss-Jordan Method"
+ */
+
+/**
+ * @addtogroup MatrixInv
+ * @{
+ */
+
+/**
+ * @brief Floating-point matrix inverse.
+ * @param[in] *pSrc points to input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns
+ * ARM_MATH_SIZE_MISMATCH
if the input matrix is not square or if the size
+ * of the output matrix does not match the size of the input matrix.
+ * If the input matrix is found to be singular (non-invertible), then the function returns
+ * ARM_MATH_SINGULAR
. Otherwise, the function returns ARM_MATH_SUCCESS
.
+ */
+
+arm_status arm_mat_inverse_f32(
+ const arm_matrix_instance_f32 * pSrc,
+ arm_matrix_instance_f32 * pDst)
+{
+ float32_t *pIn = pSrc->pData; /* input data matrix pointer */
+ float32_t *pOut = pDst->pData; /* output data matrix pointer */
+ float32_t *pInT1, *pInT2; /* Temporary input data matrix pointer */
+ float32_t *pOutT1, *pOutT2; /* Temporary output data matrix pointer */
+ float32_t *pPivotRowIn, *pPRT_in, *pPivotRowDst, *pPRT_pDst; /* Temporary input and output data matrix pointer */
+ uint32_t numRows = pSrc->numRows; /* Number of rows in the matrix */
+ uint32_t numCols = pSrc->numCols; /* Number of Cols in the matrix */
+
+#ifndef ARM_MATH_CM0_FAMILY
+ float32_t maxC; /* maximum value in the column */
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ float32_t Xchg, in = 0.0f, in1; /* Temporary input values */
+ uint32_t i, rowCnt, flag = 0u, j, loopCnt, k, l; /* loop counters */
+ arm_status status; /* status of matrix inverse */
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+
+ /* Check for matrix mismatch condition */
+ if((pSrc->numRows != pSrc->numCols) || (pDst->numRows != pDst->numCols)
+ || (pSrc->numRows != pDst->numRows))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+
+ {
+
+ /*--------------------------------------------------------------------------------------------------------------
+ * Matrix Inverse can be solved using elementary row operations.
+ *
+ * Gauss-Jordan Method:
+ *
+ * 1. First combine the identity matrix and the input matrix separated by a bar to form an
+ * augmented matrix as follows:
+ * _ _ _ _
+ * | a11 a12 | 1 0 | | X11 X12 |
+ * | | | = | |
+ * |_ a21 a22 | 0 1 _| |_ X21 X21 _|
+ *
+ * 2. In our implementation, pDst Matrix is used as identity matrix.
+ *
+ * 3. Begin with the first row. Let i = 1.
+ *
+ * 4. Check to see if the pivot for column i is the greatest of the column.
+ * The pivot is the element of the main diagonal that is on the current row.
+ * For instance, if working with row i, then the pivot element is aii.
+ * If the pivot is not the most significant of the columns, exchange that row with a row
+ * below it that does contain the most significant value in column i. If the most
+ * significant value of the column is zero, then an inverse to that matrix does not exist.
+ * The most significant value of the column is the absolute maximum.
+ *
+ * 5. Divide every element of row i by the pivot.
+ *
+ * 6. For every row below and row i, replace that row with the sum of that row and
+ * a multiple of row i so that each new element in column i below row i is zero.
+ *
+ * 7. Move to the next row and column and repeat steps 2 through 5 until you have zeros
+ * for every element below and above the main diagonal.
+ *
+ * 8. Now an identical matrix is formed to the left of the bar(input matrix, pSrc).
+ * Therefore, the matrix to the right of the bar is our solution(pDst matrix, pDst).
+ *----------------------------------------------------------------------------------------------------------------*/
+
+ /* Working pointer for destination matrix */
+ pOutT1 = pOut;
+
+ /* Loop over the number of rows */
+ rowCnt = numRows;
+
+ /* Making the destination matrix as identity matrix */
+ while(rowCnt > 0u)
+ {
+ /* Writing all zeroes in lower triangle of the destination matrix */
+ j = numRows - rowCnt;
+ while(j > 0u)
+ {
+ *pOutT1++ = 0.0f;
+ j--;
+ }
+
+ /* Writing all ones in the diagonal of the destination matrix */
+ *pOutT1++ = 1.0f;
+
+ /* Writing all zeroes in upper triangle of the destination matrix */
+ j = rowCnt - 1u;
+ while(j > 0u)
+ {
+ *pOutT1++ = 0.0f;
+ j--;
+ }
+
+ /* Decrement the loop counter */
+ rowCnt--;
+ }
+
+ /* Loop over the number of columns of the input matrix.
+ All the elements in each column are processed by the row operations */
+ loopCnt = numCols;
+
+ /* Index modifier to navigate through the columns */
+ l = 0u;
+
+ while(loopCnt > 0u)
+ {
+ /* Check if the pivot element is zero..
+ * If it is zero then interchange the row with non zero row below.
+ * If there is no non zero element to replace in the rows below,
+ * then the matrix is Singular. */
+
+ /* Working pointer for the input matrix that points
+ * to the pivot element of the particular row */
+ pInT1 = pIn + (l * numCols);
+
+ /* Working pointer for the destination matrix that points
+ * to the pivot element of the particular row */
+ pOutT1 = pOut + (l * numCols);
+
+ /* Temporary variable to hold the pivot value */
+ in = *pInT1;
+
+ /* Grab the most significant value from column l */
+ maxC = 0;
+ for (i = l; i < numRows; i++)
+ {
+ maxC = *pInT1 > 0 ? (*pInT1 > maxC ? *pInT1 : maxC) : (-*pInT1 > maxC ? -*pInT1 : maxC);
+ pInT1 += numCols;
+ }
+
+ /* Update the status if the matrix is singular */
+ if(maxC == 0.0f)
+ {
+ return ARM_MATH_SINGULAR;
+ }
+
+ /* Restore pInT1 */
+ pInT1 = pIn;
+
+ /* Destination pointer modifier */
+ k = 1u;
+
+ /* Check if the pivot element is the most significant of the column */
+ if( (in > 0.0f ? in : -in) != maxC)
+ {
+ /* Loop over the number rows present below */
+ i = numRows - (l + 1u);
+
+ while(i > 0u)
+ {
+ /* Update the input and destination pointers */
+ pInT2 = pInT1 + (numCols * l);
+ pOutT2 = pOutT1 + (numCols * k);
+
+ /* Look for the most significant element to
+ * replace in the rows below */
+ if((*pInT2 > 0.0f ? *pInT2: -*pInT2) == maxC)
+ {
+ /* Loop over number of columns
+ * to the right of the pilot element */
+ j = numCols - l;
+
+ while(j > 0u)
+ {
+ /* Exchange the row elements of the input matrix */
+ Xchg = *pInT2;
+ *pInT2++ = *pInT1;
+ *pInT1++ = Xchg;
+
+ /* Decrement the loop counter */
+ j--;
+ }
+
+ /* Loop over number of columns of the destination matrix */
+ j = numCols;
+
+ while(j > 0u)
+ {
+ /* Exchange the row elements of the destination matrix */
+ Xchg = *pOutT2;
+ *pOutT2++ = *pOutT1;
+ *pOutT1++ = Xchg;
+
+ /* Decrement the loop counter */
+ j--;
+ }
+
+ /* Flag to indicate whether exchange is done or not */
+ flag = 1u;
+
+ /* Break after exchange is done */
+ break;
+ }
+
+ /* Update the destination pointer modifier */
+ k++;
+
+ /* Decrement the loop counter */
+ i--;
+ }
+ }
+
+ /* Update the status if the matrix is singular */
+ if((flag != 1u) && (in == 0.0f))
+ {
+ return ARM_MATH_SINGULAR;
+ }
+
+ /* Points to the pivot row of input and destination matrices */
+ pPivotRowIn = pIn + (l * numCols);
+ pPivotRowDst = pOut + (l * numCols);
+
+ /* Temporary pointers to the pivot row pointers */
+ pInT1 = pPivotRowIn;
+ pInT2 = pPivotRowDst;
+
+ /* Pivot element of the row */
+ in = *pPivotRowIn;
+
+ /* Loop over number of columns
+ * to the right of the pilot element */
+ j = (numCols - l);
+
+ while(j > 0u)
+ {
+ /* Divide each element of the row of the input matrix
+ * by the pivot element */
+ in1 = *pInT1;
+ *pInT1++ = in1 / in;
+
+ /* Decrement the loop counter */
+ j--;
+ }
+
+ /* Loop over number of columns of the destination matrix */
+ j = numCols;
+
+ while(j > 0u)
+ {
+ /* Divide each element of the row of the destination matrix
+ * by the pivot element */
+ in1 = *pInT2;
+ *pInT2++ = in1 / in;
+
+ /* Decrement the loop counter */
+ j--;
+ }
+
+ /* Replace the rows with the sum of that row and a multiple of row i
+ * so that each new element in column i above row i is zero.*/
+
+ /* Temporary pointers for input and destination matrices */
+ pInT1 = pIn;
+ pInT2 = pOut;
+
+ /* index used to check for pivot element */
+ i = 0u;
+
+ /* Loop over number of rows */
+ /* to be replaced by the sum of that row and a multiple of row i */
+ k = numRows;
+
+ while(k > 0u)
+ {
+ /* Check for the pivot element */
+ if(i == l)
+ {
+ /* If the processing element is the pivot element,
+ only the columns to the right are to be processed */
+ pInT1 += numCols - l;
+
+ pInT2 += numCols;
+ }
+ else
+ {
+ /* Element of the reference row */
+ in = *pInT1;
+
+ /* Working pointers for input and destination pivot rows */
+ pPRT_in = pPivotRowIn;
+ pPRT_pDst = pPivotRowDst;
+
+ /* Loop over the number of columns to the right of the pivot element,
+ to replace the elements in the input matrix */
+ j = (numCols - l);
+
+ while(j > 0u)
+ {
+ /* Replace the element by the sum of that row
+ and a multiple of the reference row */
+ in1 = *pInT1;
+ *pInT1++ = in1 - (in * *pPRT_in++);
+
+ /* Decrement the loop counter */
+ j--;
+ }
+
+ /* Loop over the number of columns to
+ replace the elements in the destination matrix */
+ j = numCols;
+
+ while(j > 0u)
+ {
+ /* Replace the element by the sum of that row
+ and a multiple of the reference row */
+ in1 = *pInT2;
+ *pInT2++ = in1 - (in * *pPRT_pDst++);
+
+ /* Decrement the loop counter */
+ j--;
+ }
+
+ }
+
+ /* Increment the temporary input pointer */
+ pInT1 = pInT1 + l;
+
+ /* Decrement the loop counter */
+ k--;
+
+ /* Increment the pivot index */
+ i++;
+ }
+
+ /* Increment the input pointer */
+ pIn++;
+
+ /* Decrement the loop counter */
+ loopCnt--;
+
+ /* Increment the index modifier */
+ l++;
+ }
+
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ float32_t Xchg, in = 0.0f; /* Temporary input values */
+ uint32_t i, rowCnt, flag = 0u, j, loopCnt, k, l; /* loop counters */
+ arm_status status; /* status of matrix inverse */
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+ /* Check for matrix mismatch condition */
+ if((pSrc->numRows != pSrc->numCols) || (pDst->numRows != pDst->numCols)
+ || (pSrc->numRows != pDst->numRows))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+ {
+
+ /*--------------------------------------------------------------------------------------------------------------
+ * Matrix Inverse can be solved using elementary row operations.
+ *
+ * Gauss-Jordan Method:
+ *
+ * 1. First combine the identity matrix and the input matrix separated by a bar to form an
+ * augmented matrix as follows:
+ * _ _ _ _ _ _ _ _
+ * | | a11 a12 | | | 1 0 | | | X11 X12 |
+ * | | | | | | | = | |
+ * |_ |_ a21 a22 _| | |_0 1 _| _| |_ X21 X21 _|
+ *
+ * 2. In our implementation, pDst Matrix is used as identity matrix.
+ *
+ * 3. Begin with the first row. Let i = 1.
+ *
+ * 4. Check to see if the pivot for row i is zero.
+ * The pivot is the element of the main diagonal that is on the current row.
+ * For instance, if working with row i, then the pivot element is aii.
+ * If the pivot is zero, exchange that row with a row below it that does not
+ * contain a zero in column i. If this is not possible, then an inverse
+ * to that matrix does not exist.
+ *
+ * 5. Divide every element of row i by the pivot.
+ *
+ * 6. For every row below and row i, replace that row with the sum of that row and
+ * a multiple of row i so that each new element in column i below row i is zero.
+ *
+ * 7. Move to the next row and column and repeat steps 2 through 5 until you have zeros
+ * for every element below and above the main diagonal.
+ *
+ * 8. Now an identical matrix is formed to the left of the bar(input matrix, src).
+ * Therefore, the matrix to the right of the bar is our solution(dst matrix, dst).
+ *----------------------------------------------------------------------------------------------------------------*/
+
+ /* Working pointer for destination matrix */
+ pOutT1 = pOut;
+
+ /* Loop over the number of rows */
+ rowCnt = numRows;
+
+ /* Making the destination matrix as identity matrix */
+ while(rowCnt > 0u)
+ {
+ /* Writing all zeroes in lower triangle of the destination matrix */
+ j = numRows - rowCnt;
+ while(j > 0u)
+ {
+ *pOutT1++ = 0.0f;
+ j--;
+ }
+
+ /* Writing all ones in the diagonal of the destination matrix */
+ *pOutT1++ = 1.0f;
+
+ /* Writing all zeroes in upper triangle of the destination matrix */
+ j = rowCnt - 1u;
+ while(j > 0u)
+ {
+ *pOutT1++ = 0.0f;
+ j--;
+ }
+
+ /* Decrement the loop counter */
+ rowCnt--;
+ }
+
+ /* Loop over the number of columns of the input matrix.
+ All the elements in each column are processed by the row operations */
+ loopCnt = numCols;
+
+ /* Index modifier to navigate through the columns */
+ l = 0u;
+ //for(loopCnt = 0u; loopCnt < numCols; loopCnt++)
+ while(loopCnt > 0u)
+ {
+ /* Check if the pivot element is zero..
+ * If it is zero then interchange the row with non zero row below.
+ * If there is no non zero element to replace in the rows below,
+ * then the matrix is Singular. */
+
+ /* Working pointer for the input matrix that points
+ * to the pivot element of the particular row */
+ pInT1 = pIn + (l * numCols);
+
+ /* Working pointer for the destination matrix that points
+ * to the pivot element of the particular row */
+ pOutT1 = pOut + (l * numCols);
+
+ /* Temporary variable to hold the pivot value */
+ in = *pInT1;
+
+ /* Destination pointer modifier */
+ k = 1u;
+
+ /* Check if the pivot element is zero */
+ if(*pInT1 == 0.0f)
+ {
+ /* Loop over the number rows present below */
+ for (i = (l + 1u); i < numRows; i++)
+ {
+ /* Update the input and destination pointers */
+ pInT2 = pInT1 + (numCols * l);
+ pOutT2 = pOutT1 + (numCols * k);
+
+ /* Check if there is a non zero pivot element to
+ * replace in the rows below */
+ if(*pInT2 != 0.0f)
+ {
+ /* Loop over number of columns
+ * to the right of the pilot element */
+ for (j = 0u; j < (numCols - l); j++)
+ {
+ /* Exchange the row elements of the input matrix */
+ Xchg = *pInT2;
+ *pInT2++ = *pInT1;
+ *pInT1++ = Xchg;
+ }
+
+ for (j = 0u; j < numCols; j++)
+ {
+ Xchg = *pOutT2;
+ *pOutT2++ = *pOutT1;
+ *pOutT1++ = Xchg;
+ }
+
+ /* Flag to indicate whether exchange is done or not */
+ flag = 1u;
+
+ /* Break after exchange is done */
+ break;
+ }
+
+ /* Update the destination pointer modifier */
+ k++;
+ }
+ }
+
+ /* Update the status if the matrix is singular */
+ if((flag != 1u) && (in == 0.0f))
+ {
+ return ARM_MATH_SINGULAR;
+ }
+
+ /* Points to the pivot row of input and destination matrices */
+ pPivotRowIn = pIn + (l * numCols);
+ pPivotRowDst = pOut + (l * numCols);
+
+ /* Temporary pointers to the pivot row pointers */
+ pInT1 = pPivotRowIn;
+ pOutT1 = pPivotRowDst;
+
+ /* Pivot element of the row */
+ in = *(pIn + (l * numCols));
+
+ /* Loop over number of columns
+ * to the right of the pilot element */
+ for (j = 0u; j < (numCols - l); j++)
+ {
+ /* Divide each element of the row of the input matrix
+ * by the pivot element */
+ *pInT1 = *pInT1 / in;
+ pInT1++;
+ }
+ for (j = 0u; j < numCols; j++)
+ {
+ /* Divide each element of the row of the destination matrix
+ * by the pivot element */
+ *pOutT1 = *pOutT1 / in;
+ pOutT1++;
+ }
+
+ /* Replace the rows with the sum of that row and a multiple of row i
+ * so that each new element in column i above row i is zero.*/
+
+ /* Temporary pointers for input and destination matrices */
+ pInT1 = pIn;
+ pOutT1 = pOut;
+
+ for (i = 0u; i < numRows; i++)
+ {
+ /* Check for the pivot element */
+ if(i == l)
+ {
+ /* If the processing element is the pivot element,
+ only the columns to the right are to be processed */
+ pInT1 += numCols - l;
+ pOutT1 += numCols;
+ }
+ else
+ {
+ /* Element of the reference row */
+ in = *pInT1;
+
+ /* Working pointers for input and destination pivot rows */
+ pPRT_in = pPivotRowIn;
+ pPRT_pDst = pPivotRowDst;
+
+ /* Loop over the number of columns to the right of the pivot element,
+ to replace the elements in the input matrix */
+ for (j = 0u; j < (numCols - l); j++)
+ {
+ /* Replace the element by the sum of that row
+ and a multiple of the reference row */
+ *pInT1 = *pInT1 - (in * *pPRT_in++);
+ pInT1++;
+ }
+ /* Loop over the number of columns to
+ replace the elements in the destination matrix */
+ for (j = 0u; j < numCols; j++)
+ {
+ /* Replace the element by the sum of that row
+ and a multiple of the reference row */
+ *pOutT1 = *pOutT1 - (in * *pPRT_pDst++);
+ pOutT1++;
+ }
+
+ }
+ /* Increment the temporary input pointer */
+ pInT1 = pInT1 + l;
+ }
+ /* Increment the input pointer */
+ pIn++;
+
+ /* Decrement the loop counter */
+ loopCnt--;
+ /* Increment the index modifier */
+ l++;
+ }
+
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ /* Set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+
+ if((flag != 1u) && (in == 0.0f))
+ {
+ pIn = pSrc->pData;
+ for (i = 0; i < numRows * numCols; i++)
+ {
+ if (pIn[i] != 0.0f)
+ break;
+ }
+
+ if (i == numRows * numCols)
+ status = ARM_MATH_SINGULAR;
+ }
+ }
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixInv group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_inverse_f64.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_inverse_f64.c
new file mode 100644
index 0000000..5fe42d4
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_inverse_f64.c
@@ -0,0 +1,703 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_inverse_f64.c
+*
+* Description: Floating-point matrix inverse.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @defgroup MatrixInv Matrix Inverse
+ *
+ * Computes the inverse of a matrix.
+ *
+ * The inverse is defined only if the input matrix is square and non-singular (the determinant
+ * is non-zero). The function checks that the input and output matrices are square and of the
+ * same size.
+ *
+ * Matrix inversion is numerically sensitive and the CMSIS DSP library only supports matrix
+ * inversion of floating-point matrices.
+ *
+ * \par Algorithm
+ * The Gauss-Jordan method is used to find the inverse.
+ * The algorithm performs a sequence of elementary row-operations until it
+ * reduces the input matrix to an identity matrix. Applying the same sequence
+ * of elementary row-operations to an identity matrix yields the inverse matrix.
+ * If the input matrix is singular, then the algorithm terminates and returns error status
+ * ARM_MATH_SINGULAR
.
+ * \image html MatrixInverse.gif "Matrix Inverse of a 3 x 3 matrix using Gauss-Jordan Method"
+ */
+
+/**
+ * @addtogroup MatrixInv
+ * @{
+ */
+
+/**
+ * @brief Floating-point matrix inverse.
+ * @param[in] *pSrc points to input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns
+ * ARM_MATH_SIZE_MISMATCH
if the input matrix is not square or if the size
+ * of the output matrix does not match the size of the input matrix.
+ * If the input matrix is found to be singular (non-invertible), then the function returns
+ * ARM_MATH_SINGULAR
. Otherwise, the function returns ARM_MATH_SUCCESS
.
+ */
+
+arm_status arm_mat_inverse_f64(
+ const arm_matrix_instance_f64 * pSrc,
+ arm_matrix_instance_f64 * pDst)
+{
+ float64_t *pIn = pSrc->pData; /* input data matrix pointer */
+ float64_t *pOut = pDst->pData; /* output data matrix pointer */
+ float64_t *pInT1, *pInT2; /* Temporary input data matrix pointer */
+ float64_t *pOutT1, *pOutT2; /* Temporary output data matrix pointer */
+ float64_t *pPivotRowIn, *pPRT_in, *pPivotRowDst, *pPRT_pDst; /* Temporary input and output data matrix pointer */
+ uint32_t numRows = pSrc->numRows; /* Number of rows in the matrix */
+ uint32_t numCols = pSrc->numCols; /* Number of Cols in the matrix */
+
+#ifndef ARM_MATH_CM0_FAMILY
+ float64_t maxC; /* maximum value in the column */
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ float64_t Xchg, in = 0.0f, in1; /* Temporary input values */
+ uint32_t i, rowCnt, flag = 0u, j, loopCnt, k, l; /* loop counters */
+ arm_status status; /* status of matrix inverse */
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+
+ /* Check for matrix mismatch condition */
+ if((pSrc->numRows != pSrc->numCols) || (pDst->numRows != pDst->numCols)
+ || (pSrc->numRows != pDst->numRows))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+
+ {
+
+ /*--------------------------------------------------------------------------------------------------------------
+ * Matrix Inverse can be solved using elementary row operations.
+ *
+ * Gauss-Jordan Method:
+ *
+ * 1. First combine the identity matrix and the input matrix separated by a bar to form an
+ * augmented matrix as follows:
+ * _ _ _ _
+ * | a11 a12 | 1 0 | | X11 X12 |
+ * | | | = | |
+ * |_ a21 a22 | 0 1 _| |_ X21 X21 _|
+ *
+ * 2. In our implementation, pDst Matrix is used as identity matrix.
+ *
+ * 3. Begin with the first row. Let i = 1.
+ *
+ * 4. Check to see if the pivot for column i is the greatest of the column.
+ * The pivot is the element of the main diagonal that is on the current row.
+ * For instance, if working with row i, then the pivot element is aii.
+ * If the pivot is not the most significant of the columns, exchange that row with a row
+ * below it that does contain the most significant value in column i. If the most
+ * significant value of the column is zero, then an inverse to that matrix does not exist.
+ * The most significant value of the column is the absolute maximum.
+ *
+ * 5. Divide every element of row i by the pivot.
+ *
+ * 6. For every row below and row i, replace that row with the sum of that row and
+ * a multiple of row i so that each new element in column i below row i is zero.
+ *
+ * 7. Move to the next row and column and repeat steps 2 through 5 until you have zeros
+ * for every element below and above the main diagonal.
+ *
+ * 8. Now an identical matrix is formed to the left of the bar(input matrix, pSrc).
+ * Therefore, the matrix to the right of the bar is our solution(pDst matrix, pDst).
+ *----------------------------------------------------------------------------------------------------------------*/
+
+ /* Working pointer for destination matrix */
+ pOutT1 = pOut;
+
+ /* Loop over the number of rows */
+ rowCnt = numRows;
+
+ /* Making the destination matrix as identity matrix */
+ while(rowCnt > 0u)
+ {
+ /* Writing all zeroes in lower triangle of the destination matrix */
+ j = numRows - rowCnt;
+ while(j > 0u)
+ {
+ *pOutT1++ = 0.0f;
+ j--;
+ }
+
+ /* Writing all ones in the diagonal of the destination matrix */
+ *pOutT1++ = 1.0f;
+
+ /* Writing all zeroes in upper triangle of the destination matrix */
+ j = rowCnt - 1u;
+ while(j > 0u)
+ {
+ *pOutT1++ = 0.0f;
+ j--;
+ }
+
+ /* Decrement the loop counter */
+ rowCnt--;
+ }
+
+ /* Loop over the number of columns of the input matrix.
+ All the elements in each column are processed by the row operations */
+ loopCnt = numCols;
+
+ /* Index modifier to navigate through the columns */
+ l = 0u;
+
+ while(loopCnt > 0u)
+ {
+ /* Check if the pivot element is zero..
+ * If it is zero then interchange the row with non zero row below.
+ * If there is no non zero element to replace in the rows below,
+ * then the matrix is Singular. */
+
+ /* Working pointer for the input matrix that points
+ * to the pivot element of the particular row */
+ pInT1 = pIn + (l * numCols);
+
+ /* Working pointer for the destination matrix that points
+ * to the pivot element of the particular row */
+ pOutT1 = pOut + (l * numCols);
+
+ /* Temporary variable to hold the pivot value */
+ in = *pInT1;
+
+ /* Grab the most significant value from column l */
+ maxC = 0;
+ for (i = l; i < numRows; i++)
+ {
+ maxC = *pInT1 > 0 ? (*pInT1 > maxC ? *pInT1 : maxC) : (-*pInT1 > maxC ? -*pInT1 : maxC);
+ pInT1 += numCols;
+ }
+
+ /* Update the status if the matrix is singular */
+ if(maxC == 0.0f)
+ {
+ return ARM_MATH_SINGULAR;
+ }
+
+ /* Restore pInT1 */
+ pInT1 = pIn;
+
+ /* Destination pointer modifier */
+ k = 1u;
+
+ /* Check if the pivot element is the most significant of the column */
+ if( (in > 0.0f ? in : -in) != maxC)
+ {
+ /* Loop over the number rows present below */
+ i = numRows - (l + 1u);
+
+ while(i > 0u)
+ {
+ /* Update the input and destination pointers */
+ pInT2 = pInT1 + (numCols * l);
+ pOutT2 = pOutT1 + (numCols * k);
+
+ /* Look for the most significant element to
+ * replace in the rows below */
+ if((*pInT2 > 0.0f ? *pInT2: -*pInT2) == maxC)
+ {
+ /* Loop over number of columns
+ * to the right of the pilot element */
+ j = numCols - l;
+
+ while(j > 0u)
+ {
+ /* Exchange the row elements of the input matrix */
+ Xchg = *pInT2;
+ *pInT2++ = *pInT1;
+ *pInT1++ = Xchg;
+
+ /* Decrement the loop counter */
+ j--;
+ }
+
+ /* Loop over number of columns of the destination matrix */
+ j = numCols;
+
+ while(j > 0u)
+ {
+ /* Exchange the row elements of the destination matrix */
+ Xchg = *pOutT2;
+ *pOutT2++ = *pOutT1;
+ *pOutT1++ = Xchg;
+
+ /* Decrement the loop counter */
+ j--;
+ }
+
+ /* Flag to indicate whether exchange is done or not */
+ flag = 1u;
+
+ /* Break after exchange is done */
+ break;
+ }
+
+ /* Update the destination pointer modifier */
+ k++;
+
+ /* Decrement the loop counter */
+ i--;
+ }
+ }
+
+ /* Update the status if the matrix is singular */
+ if((flag != 1u) && (in == 0.0f))
+ {
+ return ARM_MATH_SINGULAR;
+ }
+
+ /* Points to the pivot row of input and destination matrices */
+ pPivotRowIn = pIn + (l * numCols);
+ pPivotRowDst = pOut + (l * numCols);
+
+ /* Temporary pointers to the pivot row pointers */
+ pInT1 = pPivotRowIn;
+ pInT2 = pPivotRowDst;
+
+ /* Pivot element of the row */
+ in = *pPivotRowIn;
+
+ /* Loop over number of columns
+ * to the right of the pilot element */
+ j = (numCols - l);
+
+ while(j > 0u)
+ {
+ /* Divide each element of the row of the input matrix
+ * by the pivot element */
+ in1 = *pInT1;
+ *pInT1++ = in1 / in;
+
+ /* Decrement the loop counter */
+ j--;
+ }
+
+ /* Loop over number of columns of the destination matrix */
+ j = numCols;
+
+ while(j > 0u)
+ {
+ /* Divide each element of the row of the destination matrix
+ * by the pivot element */
+ in1 = *pInT2;
+ *pInT2++ = in1 / in;
+
+ /* Decrement the loop counter */
+ j--;
+ }
+
+ /* Replace the rows with the sum of that row and a multiple of row i
+ * so that each new element in column i above row i is zero.*/
+
+ /* Temporary pointers for input and destination matrices */
+ pInT1 = pIn;
+ pInT2 = pOut;
+
+ /* index used to check for pivot element */
+ i = 0u;
+
+ /* Loop over number of rows */
+ /* to be replaced by the sum of that row and a multiple of row i */
+ k = numRows;
+
+ while(k > 0u)
+ {
+ /* Check for the pivot element */
+ if(i == l)
+ {
+ /* If the processing element is the pivot element,
+ only the columns to the right are to be processed */
+ pInT1 += numCols - l;
+
+ pInT2 += numCols;
+ }
+ else
+ {
+ /* Element of the reference row */
+ in = *pInT1;
+
+ /* Working pointers for input and destination pivot rows */
+ pPRT_in = pPivotRowIn;
+ pPRT_pDst = pPivotRowDst;
+
+ /* Loop over the number of columns to the right of the pivot element,
+ to replace the elements in the input matrix */
+ j = (numCols - l);
+
+ while(j > 0u)
+ {
+ /* Replace the element by the sum of that row
+ and a multiple of the reference row */
+ in1 = *pInT1;
+ *pInT1++ = in1 - (in * *pPRT_in++);
+
+ /* Decrement the loop counter */
+ j--;
+ }
+
+ /* Loop over the number of columns to
+ replace the elements in the destination matrix */
+ j = numCols;
+
+ while(j > 0u)
+ {
+ /* Replace the element by the sum of that row
+ and a multiple of the reference row */
+ in1 = *pInT2;
+ *pInT2++ = in1 - (in * *pPRT_pDst++);
+
+ /* Decrement the loop counter */
+ j--;
+ }
+
+ }
+
+ /* Increment the temporary input pointer */
+ pInT1 = pInT1 + l;
+
+ /* Decrement the loop counter */
+ k--;
+
+ /* Increment the pivot index */
+ i++;
+ }
+
+ /* Increment the input pointer */
+ pIn++;
+
+ /* Decrement the loop counter */
+ loopCnt--;
+
+ /* Increment the index modifier */
+ l++;
+ }
+
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ float64_t Xchg, in = 0.0f; /* Temporary input values */
+ uint32_t i, rowCnt, flag = 0u, j, loopCnt, k, l; /* loop counters */
+ arm_status status; /* status of matrix inverse */
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+ /* Check for matrix mismatch condition */
+ if((pSrc->numRows != pSrc->numCols) || (pDst->numRows != pDst->numCols)
+ || (pSrc->numRows != pDst->numRows))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+ {
+
+ /*--------------------------------------------------------------------------------------------------------------
+ * Matrix Inverse can be solved using elementary row operations.
+ *
+ * Gauss-Jordan Method:
+ *
+ * 1. First combine the identity matrix and the input matrix separated by a bar to form an
+ * augmented matrix as follows:
+ * _ _ _ _ _ _ _ _
+ * | | a11 a12 | | | 1 0 | | | X11 X12 |
+ * | | | | | | | = | |
+ * |_ |_ a21 a22 _| | |_0 1 _| _| |_ X21 X21 _|
+ *
+ * 2. In our implementation, pDst Matrix is used as identity matrix.
+ *
+ * 3. Begin with the first row. Let i = 1.
+ *
+ * 4. Check to see if the pivot for row i is zero.
+ * The pivot is the element of the main diagonal that is on the current row.
+ * For instance, if working with row i, then the pivot element is aii.
+ * If the pivot is zero, exchange that row with a row below it that does not
+ * contain a zero in column i. If this is not possible, then an inverse
+ * to that matrix does not exist.
+ *
+ * 5. Divide every element of row i by the pivot.
+ *
+ * 6. For every row below and row i, replace that row with the sum of that row and
+ * a multiple of row i so that each new element in column i below row i is zero.
+ *
+ * 7. Move to the next row and column and repeat steps 2 through 5 until you have zeros
+ * for every element below and above the main diagonal.
+ *
+ * 8. Now an identical matrix is formed to the left of the bar(input matrix, src).
+ * Therefore, the matrix to the right of the bar is our solution(dst matrix, dst).
+ *----------------------------------------------------------------------------------------------------------------*/
+
+ /* Working pointer for destination matrix */
+ pOutT1 = pOut;
+
+ /* Loop over the number of rows */
+ rowCnt = numRows;
+
+ /* Making the destination matrix as identity matrix */
+ while(rowCnt > 0u)
+ {
+ /* Writing all zeroes in lower triangle of the destination matrix */
+ j = numRows - rowCnt;
+ while(j > 0u)
+ {
+ *pOutT1++ = 0.0f;
+ j--;
+ }
+
+ /* Writing all ones in the diagonal of the destination matrix */
+ *pOutT1++ = 1.0f;
+
+ /* Writing all zeroes in upper triangle of the destination matrix */
+ j = rowCnt - 1u;
+ while(j > 0u)
+ {
+ *pOutT1++ = 0.0f;
+ j--;
+ }
+
+ /* Decrement the loop counter */
+ rowCnt--;
+ }
+
+ /* Loop over the number of columns of the input matrix.
+ All the elements in each column are processed by the row operations */
+ loopCnt = numCols;
+
+ /* Index modifier to navigate through the columns */
+ l = 0u;
+ //for(loopCnt = 0u; loopCnt < numCols; loopCnt++)
+ while(loopCnt > 0u)
+ {
+ /* Check if the pivot element is zero..
+ * If it is zero then interchange the row with non zero row below.
+ * If there is no non zero element to replace in the rows below,
+ * then the matrix is Singular. */
+
+ /* Working pointer for the input matrix that points
+ * to the pivot element of the particular row */
+ pInT1 = pIn + (l * numCols);
+
+ /* Working pointer for the destination matrix that points
+ * to the pivot element of the particular row */
+ pOutT1 = pOut + (l * numCols);
+
+ /* Temporary variable to hold the pivot value */
+ in = *pInT1;
+
+ /* Destination pointer modifier */
+ k = 1u;
+
+ /* Check if the pivot element is zero */
+ if(*pInT1 == 0.0f)
+ {
+ /* Loop over the number rows present below */
+ for (i = (l + 1u); i < numRows; i++)
+ {
+ /* Update the input and destination pointers */
+ pInT2 = pInT1 + (numCols * l);
+ pOutT2 = pOutT1 + (numCols * k);
+
+ /* Check if there is a non zero pivot element to
+ * replace in the rows below */
+ if(*pInT2 != 0.0f)
+ {
+ /* Loop over number of columns
+ * to the right of the pilot element */
+ for (j = 0u; j < (numCols - l); j++)
+ {
+ /* Exchange the row elements of the input matrix */
+ Xchg = *pInT2;
+ *pInT2++ = *pInT1;
+ *pInT1++ = Xchg;
+ }
+
+ for (j = 0u; j < numCols; j++)
+ {
+ Xchg = *pOutT2;
+ *pOutT2++ = *pOutT1;
+ *pOutT1++ = Xchg;
+ }
+
+ /* Flag to indicate whether exchange is done or not */
+ flag = 1u;
+
+ /* Break after exchange is done */
+ break;
+ }
+
+ /* Update the destination pointer modifier */
+ k++;
+ }
+ }
+
+ /* Update the status if the matrix is singular */
+ if((flag != 1u) && (in == 0.0f))
+ {
+ return ARM_MATH_SINGULAR;
+ }
+
+ /* Points to the pivot row of input and destination matrices */
+ pPivotRowIn = pIn + (l * numCols);
+ pPivotRowDst = pOut + (l * numCols);
+
+ /* Temporary pointers to the pivot row pointers */
+ pInT1 = pPivotRowIn;
+ pOutT1 = pPivotRowDst;
+
+ /* Pivot element of the row */
+ in = *(pIn + (l * numCols));
+
+ /* Loop over number of columns
+ * to the right of the pilot element */
+ for (j = 0u; j < (numCols - l); j++)
+ {
+ /* Divide each element of the row of the input matrix
+ * by the pivot element */
+ *pInT1 = *pInT1 / in;
+ pInT1++;
+ }
+ for (j = 0u; j < numCols; j++)
+ {
+ /* Divide each element of the row of the destination matrix
+ * by the pivot element */
+ *pOutT1 = *pOutT1 / in;
+ pOutT1++;
+ }
+
+ /* Replace the rows with the sum of that row and a multiple of row i
+ * so that each new element in column i above row i is zero.*/
+
+ /* Temporary pointers for input and destination matrices */
+ pInT1 = pIn;
+ pOutT1 = pOut;
+
+ for (i = 0u; i < numRows; i++)
+ {
+ /* Check for the pivot element */
+ if(i == l)
+ {
+ /* If the processing element is the pivot element,
+ only the columns to the right are to be processed */
+ pInT1 += numCols - l;
+ pOutT1 += numCols;
+ }
+ else
+ {
+ /* Element of the reference row */
+ in = *pInT1;
+
+ /* Working pointers for input and destination pivot rows */
+ pPRT_in = pPivotRowIn;
+ pPRT_pDst = pPivotRowDst;
+
+ /* Loop over the number of columns to the right of the pivot element,
+ to replace the elements in the input matrix */
+ for (j = 0u; j < (numCols - l); j++)
+ {
+ /* Replace the element by the sum of that row
+ and a multiple of the reference row */
+ *pInT1 = *pInT1 - (in * *pPRT_in++);
+ pInT1++;
+ }
+ /* Loop over the number of columns to
+ replace the elements in the destination matrix */
+ for (j = 0u; j < numCols; j++)
+ {
+ /* Replace the element by the sum of that row
+ and a multiple of the reference row */
+ *pOutT1 = *pOutT1 - (in * *pPRT_pDst++);
+ pOutT1++;
+ }
+
+ }
+ /* Increment the temporary input pointer */
+ pInT1 = pInT1 + l;
+ }
+ /* Increment the input pointer */
+ pIn++;
+
+ /* Decrement the loop counter */
+ loopCnt--;
+ /* Increment the index modifier */
+ l++;
+ }
+
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ /* Set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+
+ if((flag != 1u) && (in == 0.0f))
+ {
+ pIn = pSrc->pData;
+ for (i = 0; i < numRows * numCols; i++)
+ {
+ if (pIn[i] != 0.0f)
+ break;
+ }
+
+ if (i == numRows * numCols)
+ status = ARM_MATH_SINGULAR;
+ }
+ }
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixInv group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_f32.c
new file mode 100644
index 0000000..2a63d66
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_f32.c
@@ -0,0 +1,286 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_mult_f32.c
+*
+* Description: Floating-point matrix multiplication.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @defgroup MatrixMult Matrix Multiplication
+ *
+ * Multiplies two matrices.
+ *
+ * \image html MatrixMultiplication.gif "Multiplication of two 3 x 3 matrices"
+
+ * Matrix multiplication is only defined if the number of columns of the
+ * first matrix equals the number of rows of the second matrix.
+ * Multiplying an M x N
matrix with an N x P
matrix results
+ * in an M x P
matrix.
+ * When matrix size checking is enabled, the functions check: (1) that the inner dimensions of
+ * pSrcA
and pSrcB
are equal; and (2) that the size of the output
+ * matrix equals the outer dimensions of pSrcA
and pSrcB
.
+ */
+
+
+/**
+ * @addtogroup MatrixMult
+ * @{
+ */
+
+/**
+ * @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)
+{
+ float32_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
+ float32_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
+ float32_t *pInA = pSrcA->pData; /* input data matrix pointer A */
+ float32_t *pOut = pDst->pData; /* output data matrix pointer */
+ float32_t *px; /* Temporary output data matrix pointer */
+ float32_t sum; /* Accumulator */
+ uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
+ uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
+ uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ float32_t in1, in2, in3, in4;
+ uint16_t col, i = 0u, j, row = numRowsA, colCnt; /* loop counters */
+ arm_status status; /* status of matrix multiplication */
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+
+ /* Check for matrix mismatch condition */
+ if((pSrcA->numCols != pSrcB->numRows) ||
+ (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
+ {
+
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+
+ {
+ /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
+ /* row loop */
+ do
+ {
+ /* Output pointer is set to starting address of the row being processed */
+ px = pOut + i;
+
+ /* For every row wise process, the column loop counter is to be initiated */
+ col = numColsB;
+
+ /* For every row wise process, the pIn2 pointer is set
+ ** to the starting address of the pSrcB data */
+ pIn2 = pSrcB->pData;
+
+ j = 0u;
+
+ /* column loop */
+ do
+ {
+ /* Set the variable sum, that acts as accumulator, to zero */
+ sum = 0.0f;
+
+ /* Initiate the pointer pIn1 to point to the starting address of the column being processed */
+ pIn1 = pInA;
+
+ /* Apply loop unrolling and compute 4 MACs simultaneously. */
+ colCnt = numColsA >> 2u;
+
+ /* matrix multiplication */
+ while(colCnt > 0u)
+ {
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+ in3 = *pIn2;
+ pIn2 += numColsB;
+ in1 = pIn1[0];
+ in2 = pIn1[1];
+ sum += in1 * in3;
+ in4 = *pIn2;
+ pIn2 += numColsB;
+ sum += in2 * in4;
+
+ in3 = *pIn2;
+ pIn2 += numColsB;
+ in1 = pIn1[2];
+ in2 = pIn1[3];
+ sum += in1 * in3;
+ in4 = *pIn2;
+ pIn2 += numColsB;
+ sum += in2 * in4;
+ pIn1 += 4u;
+
+ /* Decrement the loop count */
+ colCnt--;
+ }
+
+ /* If the columns of pSrcA is not a multiple of 4, compute any remaining MACs here.
+ ** No loop unrolling is used. */
+ colCnt = numColsA % 0x4u;
+
+ while(colCnt > 0u)
+ {
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+ sum += *pIn1++ * (*pIn2);
+ pIn2 += numColsB;
+
+ /* Decrement the loop counter */
+ colCnt--;
+ }
+
+ /* Store the result in the destination buffer */
+ *px++ = sum;
+
+ /* Update the pointer pIn2 to point to the starting address of the next column */
+ j++;
+ pIn2 = pSrcB->pData + j;
+
+ /* Decrement the column loop counter */
+ col--;
+
+ } while(col > 0u);
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ float32_t *pInB = pSrcB->pData; /* input data matrix pointer B */
+ uint16_t col, i = 0u, row = numRowsA, colCnt; /* loop counters */
+ arm_status status; /* status of matrix multiplication */
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+ /* Check for matrix mismatch condition */
+ if((pSrcA->numCols != pSrcB->numRows) ||
+ (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
+ {
+
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+
+ {
+ /* The following loop performs the dot-product of each row in pInA with each column in pInB */
+ /* row loop */
+ do
+ {
+ /* Output pointer is set to starting address of the row being processed */
+ px = pOut + i;
+
+ /* For every row wise process, the column loop counter is to be initiated */
+ col = numColsB;
+
+ /* For every row wise process, the pIn2 pointer is set
+ ** to the starting address of the pSrcB data */
+ pIn2 = pSrcB->pData;
+
+ /* column loop */
+ do
+ {
+ /* Set the variable sum, that acts as accumulator, to zero */
+ sum = 0.0f;
+
+ /* Initialize the pointer pIn1 to point to the starting address of the row being processed */
+ pIn1 = pInA;
+
+ /* Matrix A columns number of MAC operations are to be performed */
+ colCnt = numColsA;
+
+ while(colCnt > 0u)
+ {
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+ sum += *pIn1++ * (*pIn2);
+ pIn2 += numColsB;
+
+ /* Decrement the loop counter */
+ colCnt--;
+ }
+
+ /* Store the result in the destination buffer */
+ *px++ = sum;
+
+ /* Decrement the column loop counter */
+ col--;
+
+ /* Update the pointer pIn2 to point to the starting address of the next column */
+ pIn2 = pInB + (numColsB - col);
+
+ } while(col > 0u);
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ /* Update the pointer pInA to point to the starting address of the next row */
+ i = i + numColsB;
+ pInA = pInA + numColsA;
+
+ /* Decrement the row loop counter */
+ row--;
+
+ } while(row > 0u);
+ /* Set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixMult group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_fast_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_fast_q15.c
new file mode 100644
index 0000000..b3c7aa0
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_fast_q15.c
@@ -0,0 +1,369 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_mult_fast_q15.c
+*
+* Description: Q15 matrix multiplication (fast variant)
+*
+* Target Processor: Cortex-M4/Cortex-M3
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @addtogroup MatrixMult
+ * @{
+ */
+
+
+/**
+ * @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.
+ *
+ * @details
+ * Scaling and Overflow Behavior:
+ *
+ * \par
+ * The difference between the function arm_mat_mult_q15() and this fast variant is that
+ * the fast variant use a 32-bit rather than a 64-bit accumulator.
+ * The result of each 1.15 x 1.15 multiplication is truncated to
+ * 2.30 format. These intermediate results are accumulated in a 32-bit register in 2.30
+ * format. Finally, the accumulator is saturated and converted to a 1.15 result.
+ *
+ * \par
+ * The fast version has the same overflow behavior as the standard version but provides
+ * less precision since it discards the low 16 bits of each multiplication result.
+ * In order to avoid overflows completely the input signals must be scaled down.
+ * Scale down one of the input matrices by log2(numColsA) bits to
+ * avoid overflows, as a total of numColsA additions are computed internally for each
+ * output element.
+ *
+ * \par
+ * See arm_mat_mult_q15()
for a slower implementation of this function
+ * which uses 64-bit accumulation to provide higher precision.
+ */
+
+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)
+{
+ q31_t sum; /* accumulator */
+ q15_t *pSrcBT = pState; /* input data matrix pointer for transpose */
+ q15_t *pInA = pSrcA->pData; /* input data matrix pointer A of Q15 type */
+ q15_t *pInB = pSrcB->pData; /* input data matrix pointer B of Q15 type */
+ q15_t *px; /* Temporary output data matrix pointer */
+ uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
+ uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
+ uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
+ uint16_t numRowsB = pSrcB->numRows; /* number of rows of input matrix A */
+ uint16_t col, i = 0u, row = numRowsB, colCnt; /* loop counters */
+ arm_status status; /* status of matrix multiplication */
+
+#ifndef UNALIGNED_SUPPORT_DISABLE
+
+ q31_t in; /* Temporary variable to hold the input value */
+ q31_t inA1, inA2, inB1, inB2;
+
+#else
+
+ q15_t in; /* Temporary variable to hold the input value */
+ q15_t inA1, inA2, inB1, inB2;
+
+#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
+
+#ifdef ARM_MATH_MATRIX_CHECK
+ /* Check for matrix mismatch condition */
+ if((pSrcA->numCols != pSrcB->numRows) ||
+ (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif
+ {
+ /* Matrix transpose */
+ do
+ {
+ /* Apply loop unrolling and exchange the columns with row elements */
+ col = numColsB >> 2;
+
+ /* The pointer px is set to starting address of the column being processed */
+ px = pSrcBT + i;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(col > 0u)
+ {
+#ifndef UNALIGNED_SUPPORT_DISABLE
+ /* Read two elements from the row */
+ in = *__SIMD32(pInB)++;
+
+ /* Unpack and store one element in the destination */
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ *px = (q15_t) in;
+
+#else
+
+ *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
+
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB;
+
+ /* Unpack and store the second element in the destination */
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
+
+#else
+
+ *px = (q15_t) in;
+
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB;
+
+ /* Read two elements from the row */
+ in = *__SIMD32(pInB)++;
+
+ /* Unpack and store one element in the destination */
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ *px = (q15_t) in;
+
+#else
+
+ *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
+
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB;
+
+ /* Unpack and store the second element in the destination */
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
+
+#else
+
+ *px = (q15_t) in;
+
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+
+#else
+
+ /* Read one element from the row */
+ in = *pInB++;
+
+ /* Store one element in the destination */
+ *px = in;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB;
+
+ /* Read one element from the row */
+ in = *pInB++;
+
+ /* Store one element in the destination */
+ *px = in;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB;
+
+ /* Read one element from the row */
+ in = *pInB++;
+
+ /* Store one element in the destination */
+ *px = in;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB;
+
+ /* Read one element from the row */
+ in = *pInB++;
+
+ /* Store one element in the destination */
+ *px = in;
+
+#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB;
+
+ /* Decrement the column loop counter */
+ col--;
+ }
+
+ /* If the columns of pSrcB is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ col = numColsB % 0x4u;
+
+ while(col > 0u)
+ {
+ /* Read and store the input element in the destination */
+ *px = *pInB++;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB;
+
+ /* Decrement the column loop counter */
+ col--;
+ }
+
+ i++;
+
+ /* Decrement the row loop counter */
+ row--;
+
+ } while(row > 0u);
+
+ /* Reset the variables for the usage in the following multiplication process */
+ row = numRowsA;
+ i = 0u;
+ px = pDst->pData;
+
+ /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
+ /* row loop */
+ do
+ {
+ /* For every row wise process, the column loop counter is to be initiated */
+ col = numColsB;
+
+ /* For every row wise process, the pIn2 pointer is set
+ ** to the starting address of the transposed pSrcB data */
+ pInB = pSrcBT;
+
+ /* column loop */
+ do
+ {
+ /* Set the variable sum, that acts as accumulator, to zero */
+ sum = 0;
+
+ /* Apply loop unrolling and compute 2 MACs simultaneously. */
+ colCnt = numColsA >> 2;
+
+ /* Initiate the pointer pIn1 to point to the starting address of the column being processed */
+ pInA = pSrcA->pData + i;
+
+ /* matrix multiplication */
+ while(colCnt > 0u)
+ {
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+#ifndef UNALIGNED_SUPPORT_DISABLE
+
+ inA1 = *__SIMD32(pInA)++;
+ inB1 = *__SIMD32(pInB)++;
+ inA2 = *__SIMD32(pInA)++;
+ inB2 = *__SIMD32(pInB)++;
+
+ sum = __SMLAD(inA1, inB1, sum);
+ sum = __SMLAD(inA2, inB2, sum);
+
+#else
+
+ inA1 = *pInA++;
+ inB1 = *pInB++;
+ inA2 = *pInA++;
+ sum += inA1 * inB1;
+ inB2 = *pInB++;
+
+ inA1 = *pInA++;
+ inB1 = *pInB++;
+ sum += inA2 * inB2;
+ inA2 = *pInA++;
+ inB2 = *pInB++;
+
+ sum += inA1 * inB1;
+ sum += inA2 * inB2;
+
+#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
+
+ /* Decrement the loop counter */
+ colCnt--;
+ }
+
+ /* process odd column samples */
+ colCnt = numColsA % 0x4u;
+
+ while(colCnt > 0u)
+ {
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+ sum += (q31_t) (*pInA++) * (*pInB++);
+
+ colCnt--;
+ }
+
+ /* Saturate and store the result in the destination buffer */
+ *px = (q15_t) (sum >> 15);
+ px++;
+
+ /* Decrement the column loop counter */
+ col--;
+
+ } while(col > 0u);
+
+ i = i + numColsA;
+
+ /* Decrement the row loop counter */
+ row--;
+
+ } while(row > 0u);
+
+ /* set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixMult group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_fast_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_fast_q31.c
new file mode 100644
index 0000000..c11958f
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_fast_q31.c
@@ -0,0 +1,226 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_mult_fast_q31.c
+*
+* Description: Q31 matrix multiplication (fast variant).
+*
+* Target Processor: Cortex-M4/Cortex-M3
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @addtogroup MatrixMult
+ * @{
+ */
+
+/**
+ * @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.
+ *
+ * @details
+ * Scaling and Overflow Behavior:
+ *
+ * \par
+ * The difference between the function arm_mat_mult_q31() and this fast variant is that
+ * the fast variant use a 32-bit rather than a 64-bit accumulator.
+ * The result of each 1.31 x 1.31 multiplication is truncated to
+ * 2.30 format. These intermediate results are accumulated in a 32-bit register in 2.30
+ * format. Finally, the accumulator is saturated and converted to a 1.31 result.
+ *
+ * \par
+ * The fast version has the same overflow behavior as the standard version but provides
+ * less precision since it discards the low 32 bits of each multiplication result.
+ * In order to avoid overflows completely the input signals must be scaled down.
+ * Scale down one of the input matrices by log2(numColsA) bits to
+ * avoid overflows, as a total of numColsA additions are computed internally for each
+ * output element.
+ *
+ * \par
+ * See arm_mat_mult_q31()
for a slower implementation of this function
+ * which uses 64-bit accumulation to provide higher precision.
+ */
+
+arm_status arm_mat_mult_fast_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst)
+{
+ q31_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
+ q31_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
+ q31_t *pInA = pSrcA->pData; /* input data matrix pointer A */
+// q31_t *pSrcB = pSrcB->pData; /* input data matrix pointer B */
+ q31_t *pOut = pDst->pData; /* output data matrix pointer */
+ q31_t *px; /* Temporary output data matrix pointer */
+ q31_t sum; /* Accumulator */
+ uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
+ uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
+ uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
+ uint16_t col, i = 0u, j, row = numRowsA, colCnt; /* loop counters */
+ arm_status status; /* status of matrix multiplication */
+ q31_t inA1, inA2, inA3, inA4, inB1, inB2, inB3, inB4;
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+
+ /* Check for matrix mismatch condition */
+ if((pSrcA->numCols != pSrcB->numRows) ||
+ (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+
+ {
+ /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
+ /* row loop */
+ do
+ {
+ /* Output pointer is set to starting address of the row being processed */
+ px = pOut + i;
+
+ /* For every row wise process, the column loop counter is to be initiated */
+ col = numColsB;
+
+ /* For every row wise process, the pIn2 pointer is set
+ ** to the starting address of the pSrcB data */
+ pIn2 = pSrcB->pData;
+
+ j = 0u;
+
+ /* column loop */
+ do
+ {
+ /* Set the variable sum, that acts as accumulator, to zero */
+ sum = 0;
+
+ /* Initiate the pointer pIn1 to point to the starting address of pInA */
+ pIn1 = pInA;
+
+ /* Apply loop unrolling and compute 4 MACs simultaneously. */
+ colCnt = numColsA >> 2;
+
+
+ /* matrix multiplication */
+ while(colCnt > 0u)
+ {
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+ /* Perform the multiply-accumulates */
+ inB1 = *pIn2;
+ pIn2 += numColsB;
+
+ inA1 = pIn1[0];
+ inA2 = pIn1[1];
+
+ inB2 = *pIn2;
+ pIn2 += numColsB;
+
+ inB3 = *pIn2;
+ pIn2 += numColsB;
+
+ sum = (q31_t) ((((q63_t) sum << 32) + ((q63_t) inA1 * inB1)) >> 32);
+ sum = (q31_t) ((((q63_t) sum << 32) + ((q63_t) inA2 * inB2)) >> 32);
+
+ inA3 = pIn1[2];
+ inA4 = pIn1[3];
+
+ inB4 = *pIn2;
+ pIn2 += numColsB;
+
+ sum = (q31_t) ((((q63_t) sum << 32) + ((q63_t) inA3 * inB3)) >> 32);
+ sum = (q31_t) ((((q63_t) sum << 32) + ((q63_t) inA4 * inB4)) >> 32);
+
+ pIn1 += 4u;
+
+ /* Decrement the loop counter */
+ colCnt--;
+ }
+
+ /* If the columns of pSrcA is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ colCnt = numColsA % 0x4u;
+
+ while(colCnt > 0u)
+ {
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+ /* Perform the multiply-accumulates */
+ sum = (q31_t) ((((q63_t) sum << 32) +
+ ((q63_t) * pIn1++ * (*pIn2))) >> 32);
+ pIn2 += numColsB;
+
+ /* Decrement the loop counter */
+ colCnt--;
+ }
+
+ /* Convert the result from 2.30 to 1.31 format and store in destination buffer */
+ *px++ = sum << 1;
+
+ /* Update the pointer pIn2 to point to the starting address of the next column */
+ j++;
+ pIn2 = pSrcB->pData + j;
+
+ /* Decrement the column loop counter */
+ col--;
+
+ } while(col > 0u);
+
+ /* Update the pointer pInA to point to the starting address of the next row */
+ i = i + numColsB;
+ pInA = pInA + numColsA;
+
+ /* Decrement the row loop counter */
+ row--;
+
+ } while(row > 0u);
+
+ /* set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixMult group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_q15.c
new file mode 100644
index 0000000..702ee83
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_q15.c
@@ -0,0 +1,469 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_mult_q15.c
+*
+* Description: Q15 matrix multiplication.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @addtogroup MatrixMult
+ * @{
+ */
+
+
+/**
+ * @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
+ * @param[in] *pState points to the array for storing intermediate results (Unused)
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ *
+ * @details
+ * Scaling and Overflow Behavior:
+ *
+ * \par
+ * The function is implemented using a 64-bit internal accumulator. The inputs to the
+ * multiplications are 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. This approach
+ * provides 33 guard bits and there is no risk of overflow. The 34.30 result is then
+ * truncated to 34.15 format by discarding the low 15 bits and then saturated to
+ * 1.15 format.
+ *
+ * \par
+ * Refer to arm_mat_mult_fast_q15()
for a faster but less precise version of this function for Cortex-M3 and Cortex-M4.
+ *
+ */
+
+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 CMSIS_UNUSED)
+{
+ q63_t sum; /* accumulator */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ q15_t *pSrcBT = pState; /* input data matrix pointer for transpose */
+ q15_t *pInA = pSrcA->pData; /* input data matrix pointer A of Q15 type */
+ q15_t *pInB = pSrcB->pData; /* input data matrix pointer B of Q15 type */
+ q15_t *px; /* Temporary output data matrix pointer */
+ uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
+ uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
+ uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
+ uint16_t numRowsB = pSrcB->numRows; /* number of rows of input matrix A */
+ uint16_t col, i = 0u, row = numRowsB, colCnt; /* loop counters */
+ arm_status status; /* status of matrix multiplication */
+
+#ifndef UNALIGNED_SUPPORT_DISABLE
+
+ q31_t in; /* Temporary variable to hold the input value */
+ q31_t pSourceA1, pSourceB1, pSourceA2, pSourceB2;
+
+#else
+
+ q15_t in; /* Temporary variable to hold the input value */
+ q15_t inA1, inB1, inA2, inB2;
+
+#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
+
+#ifdef ARM_MATH_MATRIX_CHECK
+ /* Check for matrix mismatch condition */
+ if((pSrcA->numCols != pSrcB->numRows) ||
+ (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+ {
+ /* Matrix transpose */
+ do
+ {
+ /* Apply loop unrolling and exchange the columns with row elements */
+ col = numColsB >> 2;
+
+ /* The pointer px is set to starting address of the column being processed */
+ px = pSrcBT + i;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(col > 0u)
+ {
+#ifndef UNALIGNED_SUPPORT_DISABLE
+
+ /* Read two elements from the row */
+ in = *__SIMD32(pInB)++;
+
+ /* Unpack and store one element in the destination */
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ *px = (q15_t) in;
+
+#else
+
+ *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
+
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB;
+
+ /* Unpack and store the second element in the destination */
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
+
+#else
+
+ *px = (q15_t) in;
+
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB;
+
+ /* Read two elements from the row */
+ in = *__SIMD32(pInB)++;
+
+ /* Unpack and store one element in the destination */
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ *px = (q15_t) in;
+
+#else
+
+ *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
+
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB;
+
+ /* Unpack and store the second element in the destination */
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
+
+#else
+
+ *px = (q15_t) in;
+
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB;
+
+#else
+
+ /* Read one element from the row */
+ in = *pInB++;
+
+ /* Store one element in the destination */
+ *px = in;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB;
+
+ /* Read one element from the row */
+ in = *pInB++;
+
+ /* Store one element in the destination */
+ *px = in;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB;
+
+ /* Read one element from the row */
+ in = *pInB++;
+
+ /* Store one element in the destination */
+ *px = in;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB;
+
+ /* Read one element from the row */
+ in = *pInB++;
+
+ /* Store one element in the destination */
+ *px = in;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB;
+
+#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
+
+ /* Decrement the column loop counter */
+ col--;
+ }
+
+ /* If the columns of pSrcB is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ col = numColsB % 0x4u;
+
+ while(col > 0u)
+ {
+ /* Read and store the input element in the destination */
+ *px = *pInB++;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += numRowsB;
+
+ /* Decrement the column loop counter */
+ col--;
+ }
+
+ i++;
+
+ /* Decrement the row loop counter */
+ row--;
+
+ } while(row > 0u);
+
+ /* Reset the variables for the usage in the following multiplication process */
+ row = numRowsA;
+ i = 0u;
+ px = pDst->pData;
+
+ /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
+ /* row loop */
+ do
+ {
+ /* For every row wise process, the column loop counter is to be initiated */
+ col = numColsB;
+
+ /* For every row wise process, the pIn2 pointer is set
+ ** to the starting address of the transposed pSrcB data */
+ pInB = pSrcBT;
+
+ /* column loop */
+ do
+ {
+ /* Set the variable sum, that acts as accumulator, to zero */
+ sum = 0;
+
+ /* Apply loop unrolling and compute 2 MACs simultaneously. */
+ colCnt = numColsA >> 2;
+
+ /* Initiate the pointer pIn1 to point to the starting address of the column being processed */
+ pInA = pSrcA->pData + i;
+
+
+ /* matrix multiplication */
+ while(colCnt > 0u)
+ {
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+#ifndef UNALIGNED_SUPPORT_DISABLE
+
+ /* read real and imag values from pSrcA and pSrcB buffer */
+ pSourceA1 = *__SIMD32(pInA)++;
+ pSourceB1 = *__SIMD32(pInB)++;
+
+ pSourceA2 = *__SIMD32(pInA)++;
+ pSourceB2 = *__SIMD32(pInB)++;
+
+ /* Multiply and Accumlates */
+ sum = __SMLALD(pSourceA1, pSourceB1, sum);
+ sum = __SMLALD(pSourceA2, pSourceB2, sum);
+
+#else
+ /* read real and imag values from pSrcA and pSrcB buffer */
+ inA1 = *pInA++;
+ inB1 = *pInB++;
+ inA2 = *pInA++;
+ /* Multiply and Accumlates */
+ sum += inA1 * inB1;
+ inB2 = *pInB++;
+
+ inA1 = *pInA++;
+ inB1 = *pInB++;
+ /* Multiply and Accumlates */
+ sum += inA2 * inB2;
+ inA2 = *pInA++;
+ inB2 = *pInB++;
+
+ /* Multiply and Accumlates */
+ sum += inA1 * inB1;
+ sum += inA2 * inB2;
+
+#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
+
+ /* Decrement the loop counter */
+ colCnt--;
+ }
+
+ /* process remaining column samples */
+ colCnt = numColsA & 3u;
+
+ while(colCnt > 0u)
+ {
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+ sum += *pInA++ * *pInB++;
+
+ /* Decrement the loop counter */
+ colCnt--;
+ }
+
+ /* Saturate and store the result in the destination buffer */
+ *px = (q15_t) (__SSAT((sum >> 15), 16));
+ px++;
+
+ /* Decrement the column loop counter */
+ col--;
+
+ } while(col > 0u);
+
+ i = i + numColsA;
+
+ /* Decrement the row loop counter */
+ row--;
+
+ } while(row > 0u);
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ q15_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
+ q15_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
+ q15_t *pInA = pSrcA->pData; /* input data matrix pointer A of Q15 type */
+ q15_t *pInB = pSrcB->pData; /* input data matrix pointer B of Q15 type */
+ q15_t *pOut = pDst->pData; /* output data matrix pointer */
+ q15_t *px; /* Temporary output data matrix pointer */
+ uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
+ uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
+ uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
+ uint16_t col, i = 0u, row = numRowsA, colCnt; /* loop counters */
+ arm_status status; /* status of matrix multiplication */
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+ /* Check for matrix mismatch condition */
+ if((pSrcA->numCols != pSrcB->numRows) ||
+ (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+
+ {
+ /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
+ /* row loop */
+ do
+ {
+ /* Output pointer is set to starting address of the row being processed */
+ px = pOut + i;
+
+ /* For every row wise process, the column loop counter is to be initiated */
+ col = numColsB;
+
+ /* For every row wise process, the pIn2 pointer is set
+ ** to the starting address of the pSrcB data */
+ pIn2 = pSrcB->pData;
+
+ /* column loop */
+ do
+ {
+ /* Set the variable sum, that acts as accumulator, to zero */
+ sum = 0;
+
+ /* Initiate the pointer pIn1 to point to the starting address of pSrcA */
+ pIn1 = pInA;
+
+ /* Matrix A columns number of MAC operations are to be performed */
+ colCnt = numColsA;
+
+ /* matrix multiplication */
+ while(colCnt > 0u)
+ {
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+ /* Perform the multiply-accumulates */
+ sum += (q31_t) * pIn1++ * *pIn2;
+ pIn2 += numColsB;
+
+ /* Decrement the loop counter */
+ colCnt--;
+ }
+
+ /* Convert the result from 34.30 to 1.15 format and store the saturated value in destination buffer */
+ /* Saturate and store the result in the destination buffer */
+ *px++ = (q15_t) __SSAT((sum >> 15), 16);
+
+ /* Decrement the column loop counter */
+ col--;
+
+ /* Update the pointer pIn2 to point to the starting address of the next column */
+ pIn2 = pInB + (numColsB - col);
+
+ } while(col > 0u);
+
+ /* Update the pointer pSrcA to point to the starting address of the next row */
+ i = i + numColsB;
+ pInA = pInA + numColsA;
+
+ /* Decrement the row loop counter */
+ row--;
+
+ } while(row > 0u);
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+ /* set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixMult group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_q31.c
new file mode 100644
index 0000000..5d22522
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_q31.c
@@ -0,0 +1,294 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_mult_q31.c
+*
+* Description: Q31 matrix multiplication.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @addtogroup MatrixMult
+ * @{
+ */
+
+/**
+ * @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.
+ *
+ * @details
+ * 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. There is no saturation
+ * on intermediate additions. Thus, if the accumulator overflows it wraps around and
+ * distorts the result. The input signals should be scaled down to avoid intermediate
+ * overflows. The input is thus scaled down by log2(numColsA) bits
+ * to avoid overflows, as a total of numColsA additions are performed internally.
+ * The 2.62 accumulator is right shifted by 31 bits and saturated to 1.31 format to yield the final result.
+ *
+ * \par
+ * See arm_mat_mult_fast_q31()
for a faster but less precise implementation of this function for Cortex-M3 and Cortex-M4.
+ *
+ */
+
+arm_status arm_mat_mult_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst)
+{
+ q31_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
+ q31_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
+ q31_t *pInA = pSrcA->pData; /* input data matrix pointer A */
+ q31_t *pOut = pDst->pData; /* output data matrix pointer */
+ q31_t *px; /* Temporary output data matrix pointer */
+ q63_t sum; /* Accumulator */
+ uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
+ uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
+ uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ uint16_t col, i = 0u, j, row = numRowsA, colCnt; /* loop counters */
+ arm_status status; /* status of matrix multiplication */
+ q31_t a0, a1, a2, a3, b0, b1, b2, b3;
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+
+ /* Check for matrix mismatch condition */
+ if((pSrcA->numCols != pSrcB->numRows) ||
+ (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+
+ {
+ /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
+ /* row loop */
+ do
+ {
+ /* Output pointer is set to starting address of the row being processed */
+ px = pOut + i;
+
+ /* For every row wise process, the column loop counter is to be initiated */
+ col = numColsB;
+
+ /* For every row wise process, the pIn2 pointer is set
+ ** to the starting address of the pSrcB data */
+ pIn2 = pSrcB->pData;
+
+ j = 0u;
+
+ /* column loop */
+ do
+ {
+ /* Set the variable sum, that acts as accumulator, to zero */
+ sum = 0;
+
+ /* Initiate the pointer pIn1 to point to the starting address of pInA */
+ pIn1 = pInA;
+
+ /* Apply loop unrolling and compute 4 MACs simultaneously. */
+ colCnt = numColsA >> 2;
+
+
+ /* matrix multiplication */
+ while(colCnt > 0u)
+ {
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+ /* Perform the multiply-accumulates */
+ b0 = *pIn2;
+ pIn2 += numColsB;
+
+ a0 = *pIn1++;
+ a1 = *pIn1++;
+
+ b1 = *pIn2;
+ pIn2 += numColsB;
+ b2 = *pIn2;
+ pIn2 += numColsB;
+
+ sum += (q63_t) a0 *b0;
+ sum += (q63_t) a1 *b1;
+
+ a2 = *pIn1++;
+ a3 = *pIn1++;
+
+ b3 = *pIn2;
+ pIn2 += numColsB;
+
+ sum += (q63_t) a2 *b2;
+ sum += (q63_t) a3 *b3;
+
+ /* Decrement the loop counter */
+ colCnt--;
+ }
+
+ /* If the columns of pSrcA is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ colCnt = numColsA % 0x4u;
+
+ while(colCnt > 0u)
+ {
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+ /* Perform the multiply-accumulates */
+ sum += (q63_t) * pIn1++ * *pIn2;
+ pIn2 += numColsB;
+
+ /* Decrement the loop counter */
+ colCnt--;
+ }
+
+ /* Convert the result from 2.62 to 1.31 format and store in destination buffer */
+ *px++ = (q31_t) (sum >> 31);
+
+ /* Update the pointer pIn2 to point to the starting address of the next column */
+ j++;
+ pIn2 = (pSrcB->pData) + j;
+
+ /* Decrement the column loop counter */
+ col--;
+
+ } while(col > 0u);
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ q31_t *pInB = pSrcB->pData; /* input data matrix pointer B */
+ uint16_t col, i = 0u, row = numRowsA, colCnt; /* loop counters */
+ arm_status status; /* status of matrix multiplication */
+
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+ /* Check for matrix mismatch condition */
+ if((pSrcA->numCols != pSrcB->numRows) ||
+ (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+
+ {
+ /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
+ /* row loop */
+ do
+ {
+ /* Output pointer is set to starting address of the row being processed */
+ px = pOut + i;
+
+ /* For every row wise process, the column loop counter is to be initiated */
+ col = numColsB;
+
+ /* For every row wise process, the pIn2 pointer is set
+ ** to the starting address of the pSrcB data */
+ pIn2 = pSrcB->pData;
+
+ /* column loop */
+ do
+ {
+ /* Set the variable sum, that acts as accumulator, to zero */
+ sum = 0;
+
+ /* Initiate the pointer pIn1 to point to the starting address of pInA */
+ pIn1 = pInA;
+
+ /* Matrix A columns number of MAC operations are to be performed */
+ colCnt = numColsA;
+
+ /* matrix multiplication */
+ while(colCnt > 0u)
+ {
+ /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
+ /* Perform the multiply-accumulates */
+ sum += (q63_t) * pIn1++ * *pIn2;
+ pIn2 += numColsB;
+
+ /* Decrement the loop counter */
+ colCnt--;
+ }
+
+ /* Convert the result from 2.62 to 1.31 format and store in destination buffer */
+ *px++ = (q31_t) clip_q63_to_q31(sum >> 31);
+
+ /* Decrement the column loop counter */
+ col--;
+
+ /* Update the pointer pIn2 to point to the starting address of the next column */
+ pIn2 = pInB + (numColsB - col);
+
+ } while(col > 0u);
+
+#endif
+
+ /* Update the pointer pInA to point to the starting address of the next row */
+ i = i + numColsB;
+ pInA = pInA + numColsA;
+
+ /* Decrement the row loop counter */
+ row--;
+
+ } while(row > 0u);
+
+ /* set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixMult group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_f32.c
new file mode 100644
index 0000000..37defa3
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_f32.c
@@ -0,0 +1,181 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_scale_f32.c
+*
+* Description: Multiplies a floating-point matrix by a scalar.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @defgroup MatrixScale Matrix Scale
+ *
+ * Multiplies a matrix by a scalar. This is accomplished by multiplying each element in the
+ * matrix by the scalar. For example:
+ * \image html MatrixScale.gif "Matrix Scaling of a 3 x 3 matrix"
+ *
+ * The function checks to make sure that the input and output matrices are of the same size.
+ *
+ * In the fixed-point Q15 and Q31 functions, scale
is represented by
+ * a fractional multiplication scaleFract
and an arithmetic shift shift
.
+ * The shift allows the gain of the scaling operation to exceed 1.0.
+ * The overall scale factor applied to the fixed-point data is
+ *
+ * scale = scaleFract * 2^shift.
+ *
+ */
+
+/**
+ * @addtogroup MatrixScale
+ * @{
+ */
+
+/**
+ * @brief Floating-point matrix scaling.
+ * @param[in] *pSrc points to input matrix structure
+ * @param[in] scale scale factor to be applied
+ * @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_f32(
+ const arm_matrix_instance_f32 * pSrc,
+ float32_t scale,
+ arm_matrix_instance_f32 * pDst)
+{
+ float32_t *pIn = pSrc->pData; /* input data matrix pointer */
+ float32_t *pOut = pDst->pData; /* output data matrix pointer */
+ uint32_t numSamples; /* total number of elements in the matrix */
+ uint32_t blkCnt; /* loop counters */
+ arm_status status; /* status of matrix scaling */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ float32_t in1, in2, in3, in4; /* temporary variables */
+ float32_t out1, out2, out3, out4; /* temporary variables */
+
+#endif // #ifndef ARM_MATH_CM0_FAMILY
+
+#ifdef ARM_MATH_MATRIX_CHECK
+ /* Check for matrix mismatch condition */
+ if((pSrc->numRows != pDst->numRows) || (pSrc->numCols != pDst->numCols))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+ {
+ /* Total number of samples in the input matrix */
+ numSamples = (uint32_t) pSrc->numRows * pSrc->numCols;
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /* Loop Unrolling */
+ blkCnt = numSamples >> 2;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) * scale */
+ /* Scaling and results are stored in the destination buffer. */
+ in1 = pIn[0];
+ in2 = pIn[1];
+ in3 = pIn[2];
+ in4 = pIn[3];
+
+ out1 = in1 * scale;
+ out2 = in2 * scale;
+ out3 = in3 * scale;
+ out4 = in4 * scale;
+
+
+ pOut[0] = out1;
+ pOut[1] = out2;
+ pOut[2] = out3;
+ pOut[3] = out4;
+
+ /* update pointers to process next sampels */
+ pIn += 4u;
+ pOut += 4u;
+
+ /* Decrement the numSamples loop counter */
+ blkCnt--;
+ }
+
+ /* If the numSamples is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = numSamples % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Initialize blkCnt with number of samples */
+ blkCnt = numSamples;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) * scale */
+ /* The results are stored in the destination buffer. */
+ *pOut++ = (*pIn++) * scale;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixScale group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_q15.c
new file mode 100644
index 0000000..5b1af16
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_q15.c
@@ -0,0 +1,183 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_scale_q15.c
+*
+* Description: Multiplies a Q15 matrix by a scalar.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @addtogroup MatrixScale
+ * @{
+ */
+
+/**
+ * @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 structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH
or ARM_MATH_SUCCESS
based on the outcome of size checking.
+ *
+ * @details
+ * Scaling and Overflow Behavior:
+ * \par
+ * The input data *pSrc
and scaleFract
are in 1.15 format.
+ * These are multiplied to yield a 2.30 intermediate result and this is shifted with saturation to 1.15 format.
+ */
+
+arm_status arm_mat_scale_q15(
+ const arm_matrix_instance_q15 * pSrc,
+ q15_t scaleFract,
+ int32_t shift,
+ arm_matrix_instance_q15 * pDst)
+{
+ q15_t *pIn = pSrc->pData; /* input data matrix pointer */
+ q15_t *pOut = pDst->pData; /* output data matrix pointer */
+ uint32_t numSamples; /* total number of elements in the matrix */
+ int32_t totShift = 15 - shift; /* total shift to apply after scaling */
+ uint32_t blkCnt; /* loop counters */
+ arm_status status; /* status of matrix scaling */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ q15_t in1, in2, in3, in4;
+ q31_t out1, out2, out3, out4;
+ q31_t inA1, inA2;
+
+#endif // #ifndef ARM_MATH_CM0_FAMILY
+
+#ifdef ARM_MATH_MATRIX_CHECK
+ /* Check for matrix mismatch */
+ if((pSrc->numRows != pDst->numRows) || (pSrc->numCols != pDst->numCols))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif // #ifdef ARM_MATH_MATRIX_CHECK
+ {
+ /* Total number of samples in the input matrix */
+ numSamples = (uint32_t) pSrc->numRows * pSrc->numCols;
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ /* Loop Unrolling */
+ blkCnt = numSamples >> 2;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) * k */
+ /* Scale, saturate and then store the results in the destination buffer. */
+ /* Reading 2 inputs from memory */
+ inA1 = _SIMD32_OFFSET(pIn);
+ inA2 = _SIMD32_OFFSET(pIn + 2);
+
+ /* C = A * scale */
+ /* Scale the inputs and then store the 2 results in the destination buffer
+ * in single cycle by packing the outputs */
+ out1 = (q31_t) ((q15_t) (inA1 >> 16) * scaleFract);
+ out2 = (q31_t) ((q15_t) inA1 * scaleFract);
+ out3 = (q31_t) ((q15_t) (inA2 >> 16) * scaleFract);
+ out4 = (q31_t) ((q15_t) inA2 * scaleFract);
+
+ out1 = out1 >> totShift;
+ inA1 = _SIMD32_OFFSET(pIn + 4);
+ out2 = out2 >> totShift;
+ inA2 = _SIMD32_OFFSET(pIn + 6);
+ out3 = out3 >> totShift;
+ out4 = out4 >> totShift;
+
+ in1 = (q15_t) (__SSAT(out1, 16));
+ in2 = (q15_t) (__SSAT(out2, 16));
+ in3 = (q15_t) (__SSAT(out3, 16));
+ in4 = (q15_t) (__SSAT(out4, 16));
+
+ _SIMD32_OFFSET(pOut) = __PKHBT(in2, in1, 16);
+ _SIMD32_OFFSET(pOut + 2) = __PKHBT(in4, in3, 16);
+
+ /* update pointers to process next sampels */
+ pIn += 4u;
+ pOut += 4u;
+
+
+ /* Decrement the numSamples loop counter */
+ blkCnt--;
+ }
+
+ /* If the numSamples is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = numSamples % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Initialize blkCnt with number of samples */
+ blkCnt = numSamples;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) * k */
+ /* Scale, saturate and then store the results in the destination buffer. */
+ *pOut++ =
+ (q15_t) (__SSAT(((q31_t) (*pIn++) * scaleFract) >> totShift, 16));
+
+ /* Decrement the numSamples loop counter */
+ blkCnt--;
+ }
+ /* Set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixScale group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_q31.c
new file mode 100644
index 0000000..5c88e41
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_q31.c
@@ -0,0 +1,202 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_scale_q31.c
+*
+* Description: Multiplies a Q31 matrix by a scalar.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @addtogroup MatrixScale
+ * @{
+ */
+
+/**
+ * @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.
+ *
+ * @details
+ * Scaling and Overflow Behavior:
+ * \par
+ * The input data *pSrc
and scaleFract
are in 1.31 format.
+ * These are multiplied to yield a 2.62 intermediate result and this is shifted with saturation to 1.31 format.
+ */
+
+arm_status arm_mat_scale_q31(
+ const arm_matrix_instance_q31 * pSrc,
+ q31_t scaleFract,
+ int32_t shift,
+ arm_matrix_instance_q31 * pDst)
+{
+ q31_t *pIn = pSrc->pData; /* input data matrix pointer */
+ q31_t *pOut = pDst->pData; /* output data matrix pointer */
+ uint32_t numSamples; /* total number of elements in the matrix */
+ int32_t totShift = shift + 1; /* shift to apply after scaling */
+ uint32_t blkCnt; /* loop counters */
+ arm_status status; /* status of matrix scaling */
+ q31_t in1, in2, out1; /* temporary variabels */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ q31_t in3, in4, out2, out3, out4; /* temporary variables */
+
+#endif // #ifndef ARM_MAT_CM0
+
+#ifdef ARM_MATH_MATRIX_CHECK
+ /* Check for matrix mismatch */
+ if((pSrc->numRows != pDst->numRows) || (pSrc->numCols != pDst->numCols))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif // #ifdef ARM_MATH_MATRIX_CHECK
+ {
+ /* Total number of samples in the input matrix */
+ numSamples = (uint32_t) pSrc->numRows * pSrc->numCols;
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /* Loop Unrolling */
+ blkCnt = numSamples >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) * k */
+ /* Read values from input */
+ in1 = *pIn;
+ in2 = *(pIn + 1);
+ in3 = *(pIn + 2);
+ in4 = *(pIn + 3);
+
+ /* multiply input with scaler value */
+ in1 = ((q63_t) in1 * scaleFract) >> 32;
+ in2 = ((q63_t) in2 * scaleFract) >> 32;
+ in3 = ((q63_t) in3 * scaleFract) >> 32;
+ in4 = ((q63_t) in4 * scaleFract) >> 32;
+
+ /* apply shifting */
+ out1 = in1 << totShift;
+ out2 = in2 << totShift;
+
+ /* saturate the results. */
+ if(in1 != (out1 >> totShift))
+ out1 = 0x7FFFFFFF ^ (in1 >> 31);
+
+ if(in2 != (out2 >> totShift))
+ out2 = 0x7FFFFFFF ^ (in2 >> 31);
+
+ out3 = in3 << totShift;
+ out4 = in4 << totShift;
+
+ *pOut = out1;
+ *(pOut + 1) = out2;
+
+ if(in3 != (out3 >> totShift))
+ out3 = 0x7FFFFFFF ^ (in3 >> 31);
+
+ if(in4 != (out4 >> totShift))
+ out4 = 0x7FFFFFFF ^ (in4 >> 31);
+
+
+ *(pOut + 2) = out3;
+ *(pOut + 3) = out4;
+
+ /* update pointers to process next sampels */
+ pIn += 4u;
+ pOut += 4u;
+
+
+ /* Decrement the numSamples loop counter */
+ blkCnt--;
+ }
+
+ /* If the numSamples is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = numSamples % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Initialize blkCnt with number of samples */
+ blkCnt = numSamples;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) * k */
+ /* Scale, saturate and then store the results in the destination buffer. */
+ in1 = *pIn++;
+
+ in2 = ((q63_t) in1 * scaleFract) >> 32;
+
+ out1 = in2 << totShift;
+
+ if(in2 != (out1 >> totShift))
+ out1 = 0x7FFFFFFF ^ (in2 >> 31);
+
+ *pOut++ = out1;
+
+ /* Decrement the numSamples loop counter */
+ blkCnt--;
+ }
+
+ /* Set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixScale group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_f32.c
new file mode 100644
index 0000000..f07bbe0
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_f32.c
@@ -0,0 +1,209 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_sub_f32.c
+*
+* Description: Floating-point matrix subtraction.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @defgroup MatrixSub Matrix Subtraction
+ *
+ * Subtract two matrices.
+ * \image html MatrixSubtraction.gif "Subraction of two 3 x 3 matrices"
+ *
+ * The functions check to make sure that
+ * pSrcA
, pSrcB
, and pDst
have the same
+ * number of rows and columns.
+ */
+
+/**
+ * @addtogroup MatrixSub
+ * @{
+ */
+
+/**
+ * @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)
+{
+ float32_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
+ float32_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
+ float32_t *pOut = pDst->pData; /* output data matrix pointer */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ float32_t inA1, inA2, inB1, inB2, out1, out2; /* temporary variables */
+
+#endif // #ifndef ARM_MATH_CM0_FAMILY
+
+ uint32_t numSamples; /* total number of elements in the matrix */
+ uint32_t blkCnt; /* loop counters */
+ arm_status status; /* status of matrix subtraction */
+
+#ifdef ARM_MATH_MATRIX_CHECK
+ /* Check for matrix mismatch condition */
+ if((pSrcA->numRows != pSrcB->numRows) ||
+ (pSrcA->numCols != pSrcB->numCols) ||
+ (pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+ {
+ /* Total number of samples in the input matrix */
+ numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols;
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /* Loop Unrolling */
+ blkCnt = numSamples >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) - B(m,n) */
+ /* Subtract and then store the results in the destination buffer. */
+ /* Read values from source A */
+ inA1 = pIn1[0];
+
+ /* Read values from source B */
+ inB1 = pIn2[0];
+
+ /* Read values from source A */
+ inA2 = pIn1[1];
+
+ /* out = sourceA - sourceB */
+ out1 = inA1 - inB1;
+
+ /* Read values from source B */
+ inB2 = pIn2[1];
+
+ /* Read values from source A */
+ inA1 = pIn1[2];
+
+ /* out = sourceA - sourceB */
+ out2 = inA2 - inB2;
+
+ /* Read values from source B */
+ inB1 = pIn2[2];
+
+ /* Store result in destination */
+ pOut[0] = out1;
+ pOut[1] = out2;
+
+ /* Read values from source A */
+ inA2 = pIn1[3];
+
+ /* Read values from source B */
+ inB2 = pIn2[3];
+
+ /* out = sourceA - sourceB */
+ out1 = inA1 - inB1;
+
+
+ /* out = sourceA - sourceB */
+ out2 = inA2 - inB2;
+
+ /* Store result in destination */
+ pOut[2] = out1;
+
+ /* Store result in destination */
+ pOut[3] = out2;
+
+
+ /* update pointers to process next sampels */
+ pIn1 += 4u;
+ pIn2 += 4u;
+ pOut += 4u;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the numSamples is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = numSamples % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Initialize blkCnt with number of samples */
+ blkCnt = numSamples;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) - B(m,n) */
+ /* Subtract and then store the results in the destination buffer. */
+ *pOut++ = (*pIn1++) - (*pIn2++);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixSub group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_q15.c
new file mode 100644
index 0000000..fd7b29c
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_q15.c
@@ -0,0 +1,160 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_sub_q15.c
+*
+* Description: Q15 Matrix subtraction
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @addtogroup MatrixSub
+ * @{
+ */
+
+/**
+ * @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.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function uses saturating arithmetic.
+ * Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
+ */
+
+arm_status arm_mat_sub_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst)
+{
+ q15_t *pInA = pSrcA->pData; /* input data matrix pointer A */
+ q15_t *pInB = pSrcB->pData; /* input data matrix pointer B */
+ q15_t *pOut = pDst->pData; /* output data matrix pointer */
+ uint32_t numSamples; /* total number of elements in the matrix */
+ uint32_t blkCnt; /* loop counters */
+ arm_status status; /* status of matrix subtraction */
+
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+
+ /* Check for matrix mismatch condition */
+ if((pSrcA->numRows != pSrcB->numRows) ||
+ (pSrcA->numCols != pSrcB->numCols) ||
+ (pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+
+ {
+ /* Total number of samples in the input matrix */
+ numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols;
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /* Apply loop unrolling */
+ blkCnt = numSamples >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) - B(m,n) */
+ /* Subtract, Saturate and then store the results in the destination buffer. */
+ *__SIMD32(pOut)++ = __QSUB16(*__SIMD32(pInA)++, *__SIMD32(pInB)++);
+ *__SIMD32(pOut)++ = __QSUB16(*__SIMD32(pInA)++, *__SIMD32(pInB)++);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = numSamples % 0x4u;
+
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) - B(m,n) */
+ /* Subtract and then store the results in the destination buffer. */
+ *pOut++ = (q15_t) __QSUB16(*pInA++, *pInB++);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Initialize blkCnt with number of samples */
+ blkCnt = numSamples;
+
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) - B(m,n) */
+ /* Subtract and then store the results in the destination buffer. */
+ *pOut++ = (q15_t) __SSAT(((q31_t) * pInA++ - *pInB++), 16);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ /* Set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixSub group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_q31.c
new file mode 100644
index 0000000..d2f2f98
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_q31.c
@@ -0,0 +1,208 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_sub_q31.c
+*
+* Description: Q31 matrix subtraction
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @addtogroup MatrixSub
+ * @{
+ */
+
+/**
+ * @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.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function uses saturating arithmetic.
+ * Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] will be saturated.
+ */
+
+
+arm_status arm_mat_sub_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst)
+{
+ q31_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
+ q31_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
+ q31_t *pOut = pDst->pData; /* output data matrix pointer */
+ q31_t inA1, inB1; /* temporary variables */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ q31_t inA2, inB2; /* temporary variables */
+ q31_t out1, out2; /* temporary variables */
+
+#endif // #ifndef ARM_MATH_CM0_FAMILY
+
+ uint32_t numSamples; /* total number of elements in the matrix */
+ uint32_t blkCnt; /* loop counters */
+ arm_status status; /* status of matrix subtraction */
+
+
+#ifdef ARM_MATH_MATRIX_CHECK
+ /* Check for matrix mismatch condition */
+ if((pSrcA->numRows != pSrcB->numRows) ||
+ (pSrcA->numCols != pSrcB->numCols) ||
+ (pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif
+ {
+ /* Total number of samples in the input matrix */
+ numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols;
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /* Loop Unrolling */
+ blkCnt = numSamples >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) - B(m,n) */
+ /* Subtract, saturate and then store the results in the destination buffer. */
+ /* Read values from source A */
+ inA1 = pIn1[0];
+
+ /* Read values from source B */
+ inB1 = pIn2[0];
+
+ /* Read values from source A */
+ inA2 = pIn1[1];
+
+ /* Subtract and saturate */
+ out1 = __QSUB(inA1, inB1);
+
+ /* Read values from source B */
+ inB2 = pIn2[1];
+
+ /* Read values from source A */
+ inA1 = pIn1[2];
+
+ /* Subtract and saturate */
+ out2 = __QSUB(inA2, inB2);
+
+ /* Read values from source B */
+ inB1 = pIn2[2];
+
+ /* Store result in destination */
+ pOut[0] = out1;
+ pOut[1] = out2;
+
+ /* Read values from source A */
+ inA2 = pIn1[3];
+
+ /* Read values from source B */
+ inB2 = pIn2[3];
+
+ /* Subtract and saturate */
+ out1 = __QSUB(inA1, inB1);
+
+ /* Subtract and saturate */
+ out2 = __QSUB(inA2, inB2);
+
+ /* Store result in destination */
+ pOut[2] = out1;
+ pOut[3] = out2;
+
+ /* update pointers to process next samples */
+ pIn1 += 4u;
+ pIn2 += 4u;
+ pOut += 4u;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the numSamples is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = numSamples % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Initialize blkCnt with number of samples */
+ blkCnt = numSamples;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C(m,n) = A(m,n) - B(m,n) */
+ /* Subtract, saturate and then store the results in the destination buffer. */
+ inA1 = *pIn1++;
+ inB1 = *pIn2++;
+
+ inA1 = __QSUB(inA1, inB1);
+
+ *pOut++ = inA1;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixSub group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_f32.c
new file mode 100644
index 0000000..84c08ec
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_f32.c
@@ -0,0 +1,218 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_trans_f32.c
+*
+* Description: Floating-point matrix transpose.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 MatrixTrans Matrix Transpose
+ *
+ * Tranposes a matrix.
+ * Transposing an M x N
matrix flips it around the center diagonal and results in an N x M
matrix.
+ * \image html MatrixTranspose.gif "Transpose of a 3 x 3 matrix"
+ */
+
+#include "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @addtogroup MatrixTrans
+ * @{
+ */
+
+/**
+ * @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)
+{
+ float32_t *pIn = pSrc->pData; /* input data matrix pointer */
+ float32_t *pOut = pDst->pData; /* output data matrix pointer */
+ float32_t *px; /* Temporary output data matrix pointer */
+ uint16_t nRows = pSrc->numRows; /* number of rows */
+ uint16_t nColumns = pSrc->numCols; /* number of columns */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ uint16_t blkCnt, i = 0u, row = nRows; /* loop counters */
+ arm_status status; /* status of matrix transpose */
+
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+
+ /* Check for matrix mismatch condition */
+ if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+
+ {
+ /* Matrix transpose by exchanging the rows with columns */
+ /* row loop */
+ do
+ {
+ /* Loop Unrolling */
+ blkCnt = nColumns >> 2;
+
+ /* The pointer px is set to starting address of the column being processed */
+ px = pOut + i;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u) /* column loop */
+ {
+ /* Read and store the input element in the destination */
+ *px = *pIn++;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += nRows;
+
+ /* Read and store the input element in the destination */
+ *px = *pIn++;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += nRows;
+
+ /* Read and store the input element in the destination */
+ *px = *pIn++;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += nRows;
+
+ /* Read and store the input element in the destination */
+ *px = *pIn++;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += nRows;
+
+ /* Decrement the column loop counter */
+ blkCnt--;
+ }
+
+ /* Perform matrix transpose for last 3 samples here. */
+ blkCnt = nColumns % 0x4u;
+
+ while(blkCnt > 0u)
+ {
+ /* Read and store the input element in the destination */
+ *px = *pIn++;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += nRows;
+
+ /* Decrement the column loop counter */
+ blkCnt--;
+ }
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ uint16_t col, i = 0u, row = nRows; /* loop counters */
+ arm_status status; /* status of matrix transpose */
+
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+ /* Check for matrix mismatch condition */
+ if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+
+ {
+ /* Matrix transpose by exchanging the rows with columns */
+ /* row loop */
+ do
+ {
+ /* The pointer px is set to starting address of the column being processed */
+ px = pOut + i;
+
+ /* Initialize column loop counter */
+ col = nColumns;
+
+ while(col > 0u)
+ {
+ /* Read and store the input element in the destination */
+ *px = *pIn++;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += nRows;
+
+ /* Decrement the column loop counter */
+ col--;
+ }
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ i++;
+
+ /* Decrement the row loop counter */
+ row--;
+
+ } while(row > 0u); /* row loop end */
+
+ /* Set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixTrans group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_q15.c
new file mode 100644
index 0000000..4e0fb82
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_q15.c
@@ -0,0 +1,284 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_trans_q15.c
+*
+* Description: Q15 matrix transpose.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @addtogroup MatrixTrans
+ * @{
+ */
+
+/*
+ * @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)
+{
+ q15_t *pSrcA = pSrc->pData; /* input data matrix pointer */
+ q15_t *pOut = pDst->pData; /* output data matrix pointer */
+ uint16_t nRows = pSrc->numRows; /* number of nRows */
+ uint16_t nColumns = pSrc->numCols; /* number of nColumns */
+ uint16_t col, row = nRows, i = 0u; /* row and column loop counters */
+ arm_status status; /* status of matrix transpose */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+#ifndef UNALIGNED_SUPPORT_DISABLE
+
+ q31_t in; /* variable to hold temporary output */
+
+#else
+
+ q15_t in;
+
+#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+
+ /* Check for matrix mismatch condition */
+ if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+
+ {
+ /* Matrix transpose by exchanging the rows with columns */
+ /* row loop */
+ do
+ {
+
+ /* Apply loop unrolling and exchange the columns with row elements */
+ col = nColumns >> 2u;
+
+ /* The pointer pOut is set to starting address of the column being processed */
+ pOut = pDst->pData + i;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(col > 0u)
+ {
+#ifndef UNALIGNED_SUPPORT_DISABLE
+
+ /* Read two elements from the row */
+ in = *__SIMD32(pSrcA)++;
+
+ /* Unpack and store one element in the destination */
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ *pOut = (q15_t) in;
+
+#else
+
+ *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
+
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+
+ /* Update the pointer pOut to point to the next row of the transposed matrix */
+ pOut += nRows;
+
+ /* Unpack and store the second element in the destination */
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
+
+#else
+
+ *pOut = (q15_t) in;
+
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+
+ /* Update the pointer pOut to point to the next row of the transposed matrix */
+ pOut += nRows;
+
+ /* Read two elements from the row */
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ in = *__SIMD32(pSrcA)++;
+
+#else
+
+ in = *__SIMD32(pSrcA)++;
+
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+
+ /* Unpack and store one element in the destination */
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ *pOut = (q15_t) in;
+
+#else
+
+ *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
+
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+
+ /* Update the pointer pOut to point to the next row of the transposed matrix */
+ pOut += nRows;
+
+ /* Unpack and store the second element in the destination */
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
+
+#else
+
+ *pOut = (q15_t) in;
+
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+
+#else
+ /* Read one element from the row */
+ in = *pSrcA++;
+
+ /* Store one element in the destination */
+ *pOut = in;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ pOut += nRows;
+
+ /* Read one element from the row */
+ in = *pSrcA++;
+
+ /* Store one element in the destination */
+ *pOut = in;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ pOut += nRows;
+
+ /* Read one element from the row */
+ in = *pSrcA++;
+
+ /* Store one element in the destination */
+ *pOut = in;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ pOut += nRows;
+
+ /* Read one element from the row */
+ in = *pSrcA++;
+
+ /* Store one element in the destination */
+ *pOut = in;
+
+#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
+
+ /* Update the pointer pOut to point to the next row of the transposed matrix */
+ pOut += nRows;
+
+ /* Decrement the column loop counter */
+ col--;
+ }
+
+ /* Perform matrix transpose for last 3 samples here. */
+ col = nColumns % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+ /* Check for matrix mismatch condition */
+ if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+
+ {
+ /* Matrix transpose by exchanging the rows with columns */
+ /* row loop */
+ do
+ {
+ /* The pointer pOut is set to starting address of the column being processed */
+ pOut = pDst->pData + i;
+
+ /* Initialize column loop counter */
+ col = nColumns;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(col > 0u)
+ {
+ /* Read and store the input element in the destination */
+ *pOut = *pSrcA++;
+
+ /* Update the pointer pOut to point to the next row of the transposed matrix */
+ pOut += nRows;
+
+ /* Decrement the column loop counter */
+ col--;
+ }
+
+ i++;
+
+ /* Decrement the row loop counter */
+ row--;
+
+ } while(row > 0u);
+
+ /* set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixTrans group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_q31.c
new file mode 100644
index 0000000..ec92582
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_q31.c
@@ -0,0 +1,210 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mat_trans_q31.c
+*
+* Description: Q31 matrix transpose.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupMatrix
+ */
+
+/**
+ * @addtogroup MatrixTrans
+ * @{
+ */
+
+/*
+ * @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)
+{
+ q31_t *pIn = pSrc->pData; /* input data matrix pointer */
+ q31_t *pOut = pDst->pData; /* output data matrix pointer */
+ q31_t *px; /* Temporary output data matrix pointer */
+ uint16_t nRows = pSrc->numRows; /* number of nRows */
+ uint16_t nColumns = pSrc->numCols; /* number of nColumns */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ uint16_t blkCnt, i = 0u, row = nRows; /* loop counters */
+ arm_status status; /* status of matrix transpose */
+
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+
+ /* Check for matrix mismatch condition */
+ if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+
+ {
+ /* Matrix transpose by exchanging the rows with columns */
+ /* row loop */
+ do
+ {
+ /* Apply loop unrolling and exchange the columns with row elements */
+ blkCnt = nColumns >> 2u;
+
+ /* The pointer px is set to starting address of the column being processed */
+ px = pOut + i;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* Read and store the input element in the destination */
+ *px = *pIn++;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += nRows;
+
+ /* Read and store the input element in the destination */
+ *px = *pIn++;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += nRows;
+
+ /* Read and store the input element in the destination */
+ *px = *pIn++;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += nRows;
+
+ /* Read and store the input element in the destination */
+ *px = *pIn++;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += nRows;
+
+ /* Decrement the column loop counter */
+ blkCnt--;
+ }
+
+ /* Perform matrix transpose for last 3 samples here. */
+ blkCnt = nColumns % 0x4u;
+
+ while(blkCnt > 0u)
+ {
+ /* Read and store the input element in the destination */
+ *px = *pIn++;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += nRows;
+
+ /* Decrement the column loop counter */
+ blkCnt--;
+ }
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ uint16_t col, i = 0u, row = nRows; /* loop counters */
+ arm_status status; /* status of matrix transpose */
+
+
+#ifdef ARM_MATH_MATRIX_CHECK
+
+ /* Check for matrix mismatch condition */
+ if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows))
+ {
+ /* Set status as ARM_MATH_SIZE_MISMATCH */
+ status = ARM_MATH_SIZE_MISMATCH;
+ }
+ else
+#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
+
+ {
+ /* Matrix transpose by exchanging the rows with columns */
+ /* row loop */
+ do
+ {
+ /* The pointer px is set to starting address of the column being processed */
+ px = pOut + i;
+
+ /* Initialize column loop counter */
+ col = nColumns;
+
+ while(col > 0u)
+ {
+ /* Read and store the input element in the destination */
+ *px = *pIn++;
+
+ /* Update the pointer px to point to the next row of the transposed matrix */
+ px += nRows;
+
+ /* Decrement the column loop counter */
+ col--;
+ }
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ i++;
+
+ /* Decrement the row loop counter */
+ row--;
+
+ }
+ while(row > 0u); /* row loop end */
+
+ /* set status as ARM_MATH_SUCCESS */
+ status = ARM_MATH_SUCCESS;
+ }
+
+ /* Return to application */
+ return (status);
+}
+
+/**
+ * @} end of MatrixTrans group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_f32.c
new file mode 100644
index 0000000..2326646
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_f32.c
@@ -0,0 +1,186 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_max_f32.c
+*
+* Description: Maximum value of a floating-point vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @defgroup Max Maximum
+ *
+ * Computes the maximum value of an array of data.
+ * The function returns both the maximum value and its position within the array.
+ * There are separate functions for floating-point, Q31, Q15, and Q7 data types.
+ */
+
+/**
+ * @addtogroup Max
+ * @{
+ */
+
+
+/**
+ * @brief Maximum value of a floating-point vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult maximum value returned here
+ * @param[out] *pIndex index of maximum value returned here
+ * @return none.
+ */
+
+void arm_max_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult,
+ uint32_t * pIndex)
+{
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ float32_t maxVal1, maxVal2, out; /* Temporary variables to store the output value. */
+ uint32_t blkCnt, outIndex, count; /* loop counter */
+
+ /* Initialise the count value. */
+ count = 0u;
+ /* Initialise the index value to zero. */
+ outIndex = 0u;
+ /* Load first input value that act as reference value for comparision */
+ out = *pSrc++;
+
+ /* Loop unrolling */
+ blkCnt = (blockSize - 1u) >> 2u;
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ while(blkCnt > 0u)
+ {
+ /* Initialize maxVal to the next consecutive values one by one */
+ maxVal1 = *pSrc++;
+
+ maxVal2 = *pSrc++;
+
+ /* compare for the maximum value */
+ if(out < maxVal1)
+ {
+ /* Update the maximum value and its index */
+ out = maxVal1;
+ outIndex = count + 1u;
+ }
+
+ maxVal1 = *pSrc++;
+
+ /* compare for the maximum value */
+ if(out < maxVal2)
+ {
+ /* Update the maximum value and its index */
+ out = maxVal2;
+ outIndex = count + 2u;
+ }
+
+ maxVal2 = *pSrc++;
+
+ /* compare for the maximum value */
+ if(out < maxVal1)
+ {
+ /* Update the maximum value and its index */
+ out = maxVal1;
+ outIndex = count + 3u;
+ }
+
+ /* compare for the maximum value */
+ if(out < maxVal2)
+ {
+ /* Update the maximum value and its index */
+ out = maxVal2;
+ outIndex = count + 4u;
+ }
+
+ count += 4u;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* if (blockSize - 1u) is not multiple of 4 */
+ blkCnt = (blockSize - 1u) % 4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+ float32_t maxVal1, out; /* Temporary variables to store the output value. */
+ uint32_t blkCnt, outIndex; /* loop counter */
+
+ /* Initialise the index value to zero. */
+ outIndex = 0u;
+ /* Load first input value that act as reference value for comparision */
+ out = *pSrc++;
+
+ blkCnt = (blockSize - 1u);
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* Initialize maxVal to the next consecutive values one by one */
+ maxVal1 = *pSrc++;
+
+ /* compare for the maximum value */
+ if(out < maxVal1)
+ {
+ /* Update the maximum value and it's index */
+ out = maxVal1;
+ outIndex = blockSize - blkCnt;
+ }
+
+
+ /* Decrement the loop counter */
+ blkCnt--;
+
+ }
+
+ /* Store the maximum value and it's index into destination pointers */
+ *pResult = out;
+ *pIndex = outIndex;
+}
+
+/**
+ * @} end of Max group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_q15.c
new file mode 100644
index 0000000..20375c2
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_q15.c
@@ -0,0 +1,176 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_max_q15.c
+*
+* Description: Maximum value of a Q15 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @addtogroup Max
+ * @{
+ */
+
+
+/**
+ * @brief Maximum value of a Q15 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult maximum value returned here
+ * @param[out] *pIndex index of maximum value returned here
+ * @return none.
+ */
+
+void arm_max_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult,
+ uint32_t * pIndex)
+{
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ q15_t maxVal1, maxVal2, out; /* Temporary variables to store the output value. */
+ uint32_t blkCnt, outIndex, count; /* loop counter */
+
+ /* Initialise the count value. */
+ count = 0u;
+ /* Initialise the index value to zero. */
+ outIndex = 0u;
+ /* Load first input value that act as reference value for comparision */
+ out = *pSrc++;
+
+ /* Loop unrolling */
+ blkCnt = (blockSize - 1u) >> 2u;
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ while(blkCnt > 0u)
+ {
+ /* Initialize maxVal to the next consecutive values one by one */
+ maxVal1 = *pSrc++;
+
+ maxVal2 = *pSrc++;
+
+ /* compare for the maximum value */
+ if(out < maxVal1)
+ {
+ /* Update the maximum value and its index */
+ out = maxVal1;
+ outIndex = count + 1u;
+ }
+
+ maxVal1 = *pSrc++;
+
+ /* compare for the maximum value */
+ if(out < maxVal2)
+ {
+ /* Update the maximum value and its index */
+ out = maxVal2;
+ outIndex = count + 2u;
+ }
+
+ maxVal2 = *pSrc++;
+
+ /* compare for the maximum value */
+ if(out < maxVal1)
+ {
+ /* Update the maximum value and its index */
+ out = maxVal1;
+ outIndex = count + 3u;
+ }
+
+ /* compare for the maximum value */
+ if(out < maxVal2)
+ {
+ /* Update the maximum value and its index */
+ out = maxVal2;
+ outIndex = count + 4u;
+ }
+
+ count += 4u;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* if (blockSize - 1u) is not multiple of 4 */
+ blkCnt = (blockSize - 1u) % 4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+ q15_t maxVal1, out; /* Temporary variables to store the output value. */
+ uint32_t blkCnt, outIndex; /* loop counter */
+
+ blkCnt = (blockSize - 1u);
+
+ /* Initialise the index value to zero. */
+ outIndex = 0u;
+ /* Load first input value that act as reference value for comparision */
+ out = *pSrc++;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* Initialize maxVal to the next consecutive values one by one */
+ maxVal1 = *pSrc++;
+
+ /* compare for the maximum value */
+ if(out < maxVal1)
+ {
+ /* Update the maximum value and it's index */
+ out = maxVal1;
+ outIndex = blockSize - blkCnt;
+ }
+ /* Decrement the loop counter */
+ blkCnt--;
+
+ }
+
+ /* Store the maximum value and its index into destination pointers */
+ *pResult = out;
+ *pIndex = outIndex;
+}
+
+/**
+ * @} end of Max group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_q31.c
new file mode 100644
index 0000000..c687e79
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_q31.c
@@ -0,0 +1,177 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_max_q31.c
+*
+* Description: Maximum value of a Q31 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @addtogroup Max
+ * @{
+ */
+
+
+/**
+ * @brief Maximum value of a Q31 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult maximum value returned here
+ * @param[out] *pIndex index of maximum value returned here
+ * @return none.
+ */
+
+void arm_max_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult,
+ uint32_t * pIndex)
+{
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ q31_t maxVal1, maxVal2, out; /* Temporary variables to store the output value. */
+ uint32_t blkCnt, outIndex, count; /* loop counter */
+
+ /* Initialise the count value. */
+ count = 0u;
+ /* Initialise the index value to zero. */
+ outIndex = 0u;
+ /* Load first input value that act as reference value for comparision */
+ out = *pSrc++;
+
+ /* Loop unrolling */
+ blkCnt = (blockSize - 1u) >> 2u;
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ while(blkCnt > 0u)
+ {
+ /* Initialize maxVal to the next consecutive values one by one */
+ maxVal1 = *pSrc++;
+
+ maxVal2 = *pSrc++;
+
+ /* compare for the maximum value */
+ if(out < maxVal1)
+ {
+ /* Update the maximum value and its index */
+ out = maxVal1;
+ outIndex = count + 1u;
+ }
+
+ maxVal1 = *pSrc++;
+
+ /* compare for the maximum value */
+ if(out < maxVal2)
+ {
+ /* Update the maximum value and its index */
+ out = maxVal2;
+ outIndex = count + 2u;
+ }
+
+ maxVal2 = *pSrc++;
+
+ /* compare for the maximum value */
+ if(out < maxVal1)
+ {
+ /* Update the maximum value and its index */
+ out = maxVal1;
+ outIndex = count + 3u;
+ }
+
+ /* compare for the maximum value */
+ if(out < maxVal2)
+ {
+ /* Update the maximum value and its index */
+ out = maxVal2;
+ outIndex = count + 4u;
+ }
+
+ count += 4u;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* if (blockSize - 1u) is not multiple of 4 */
+ blkCnt = (blockSize - 1u) % 4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+ q31_t maxVal1, out; /* Temporary variables to store the output value. */
+ uint32_t blkCnt, outIndex; /* loop counter */
+
+ /* Initialise the index value to zero. */
+ outIndex = 0u;
+ /* Load first input value that act as reference value for comparision */
+ out = *pSrc++;
+
+ blkCnt = (blockSize - 1u);
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* Initialize maxVal to the next consecutive values one by one */
+ maxVal1 = *pSrc++;
+
+ /* compare for the maximum value */
+ if(out < maxVal1)
+ {
+ /* Update the maximum value and it's index */
+ out = maxVal1;
+ outIndex = blockSize - blkCnt;
+ }
+
+ /* Decrement the loop counter */
+ blkCnt--;
+
+ }
+
+ /* Store the maximum value and its index into destination pointers */
+ *pResult = out;
+ *pIndex = outIndex;
+}
+
+/**
+ * @} end of Max group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_q7.c
new file mode 100644
index 0000000..0e0cc2d
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_q7.c
@@ -0,0 +1,177 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_max_q7.c
+*
+* Description: Maximum value of a Q7 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @addtogroup Max
+ * @{
+ */
+
+
+/**
+ * @brief Maximum value of a Q7 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult maximum value returned here
+ * @param[out] *pIndex index of maximum value returned here
+ * @return none.
+ */
+
+void arm_max_q7(
+ q7_t * pSrc,
+ uint32_t blockSize,
+ q7_t * pResult,
+ uint32_t * pIndex)
+{
+#ifndef ARM_MATH_CM0_FAMILY
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ q7_t maxVal1, maxVal2, out; /* Temporary variables to store the output value. */
+ uint32_t blkCnt, outIndex, count; /* loop counter */
+
+ /* Initialise the count value. */
+ count = 0u;
+ /* Initialise the index value to zero. */
+ outIndex = 0u;
+ /* Load first input value that act as reference value for comparision */
+ out = *pSrc++;
+
+ /* Loop unrolling */
+ blkCnt = (blockSize - 1u) >> 2u;
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ while(blkCnt > 0u)
+ {
+ /* Initialize maxVal to the next consecutive values one by one */
+ maxVal1 = *pSrc++;
+
+ maxVal2 = *pSrc++;
+
+ /* compare for the maximum value */
+ if(out < maxVal1)
+ {
+ /* Update the maximum value and its index */
+ out = maxVal1;
+ outIndex = count + 1u;
+ }
+
+ maxVal1 = *pSrc++;
+
+ /* compare for the maximum value */
+ if(out < maxVal2)
+ {
+ /* Update the maximum value and its index */
+ out = maxVal2;
+ outIndex = count + 2u;
+ }
+
+ maxVal2 = *pSrc++;
+
+ /* compare for the maximum value */
+ if(out < maxVal1)
+ {
+ /* Update the maximum value and its index */
+ out = maxVal1;
+ outIndex = count + 3u;
+ }
+
+ /* compare for the maximum value */
+ if(out < maxVal2)
+ {
+ /* Update the maximum value and its index */
+ out = maxVal2;
+ outIndex = count + 4u;
+ }
+
+ count += 4u;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* if (blockSize - 1u) is not multiple of 4 */
+ blkCnt = (blockSize - 1u) % 4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+ q7_t maxVal1, out; /* Temporary variables to store the output value. */
+ uint32_t blkCnt, outIndex; /* loop counter */
+
+ /* Initialise the index value to zero. */
+ outIndex = 0u;
+ /* Load first input value that act as reference value for comparision */
+ out = *pSrc++;
+
+ blkCnt = (blockSize - 1u);
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* Initialize maxVal to the next consecutive values one by one */
+ maxVal1 = *pSrc++;
+
+ /* compare for the maximum value */
+ if(out < maxVal1)
+ {
+ /* Update the maximum value and it's index */
+ out = maxVal1;
+ outIndex = blockSize - blkCnt;
+ }
+ /* Decrement the loop counter */
+ blkCnt--;
+
+ }
+
+ /* Store the maximum value and its index into destination pointers */
+ *pResult = out;
+ *pIndex = outIndex;
+
+}
+
+/**
+ * @} end of Max group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_f32.c
new file mode 100644
index 0000000..bc054b2
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_f32.c
@@ -0,0 +1,139 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mean_f32.c
+*
+* Description: Mean value of a floating-point vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @defgroup mean Mean
+ *
+ * Calculates the mean of the input vector. Mean is defined as the average of the elements in the vector.
+ * The underlying algorithm is used:
+ *
+ *
+ * Result = (pSrc[0] + pSrc[1] + pSrc[2] + ... + pSrc[blockSize-1]) / blockSize;
+ *
+ *
+ * There are separate functions for floating-point, Q31, Q15, and Q7 data types.
+ */
+
+/**
+ * @addtogroup mean
+ * @{
+ */
+
+
+/**
+ * @brief Mean value of a floating-point vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult mean value returned here
+ * @return none.
+ */
+
+
+void arm_mean_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult)
+{
+ float32_t sum = 0.0f; /* Temporary result storage */
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ float32_t in1, in2, in3, in4;
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
+ in1 = *pSrc++;
+ in2 = *pSrc++;
+ in3 = *pSrc++;
+ in4 = *pSrc++;
+
+ sum += in1;
+ sum += in2;
+ sum += in3;
+ sum += in4;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
+ sum += *pSrc++;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */
+ /* Store the result to the destination */
+ *pResult = sum / (float32_t) blockSize;
+}
+
+/**
+ * @} end of mean group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_q15.c
new file mode 100644
index 0000000..ff5d64b
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_q15.c
@@ -0,0 +1,133 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mean_q15.c
+*
+* Description: Mean value of a Q15 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @addtogroup mean
+ * @{
+ */
+
+/**
+ * @brief Mean value of a Q15 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult mean value returned here
+ * @return none.
+ *
+ * @details
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using a 32-bit internal accumulator.
+ * The input is represented in 1.15 format and is accumulated in a 32-bit
+ * accumulator in 17.15 format.
+ * There is no risk of internal overflow with this approach, and the
+ * full precision of intermediate result is preserved.
+ * Finally, the accumulator is saturated and truncated to yield a result of 1.15 format.
+ *
+ */
+
+
+void arm_mean_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult)
+{
+ q31_t sum = 0; /* Temporary result storage */
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ q31_t in;
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
+ in = *__SIMD32(pSrc)++;
+ sum += ((in << 16) >> 16);
+ sum += (in >> 16);
+ in = *__SIMD32(pSrc)++;
+ sum += ((in << 16) >> 16);
+ sum += (in >> 16);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
+ sum += *pSrc++;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */
+ /* Store the result to the destination */
+ *pResult = (q15_t) (sum / (q31_t)blockSize);
+}
+
+/**
+ * @} end of mean group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_q31.c
new file mode 100644
index 0000000..afd62b3
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_q31.c
@@ -0,0 +1,136 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mean_q31.c
+*
+* Description: Mean value of a Q31 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @addtogroup mean
+ * @{
+ */
+
+/**
+ * @brief Mean value of a Q31 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult mean value returned here
+ * @return none.
+ *
+ * @details
+ * Scaling and Overflow Behavior:
+ *\par
+ * The function is implemented using a 64-bit internal accumulator.
+ * The input is represented in 1.31 format and is accumulated in a 64-bit
+ * accumulator in 33.31 format.
+ * There is no risk of internal overflow with this approach, and the
+ * full precision of intermediate result is preserved.
+ * Finally, the accumulator is truncated to yield a result of 1.31 format.
+ *
+ */
+
+
+void arm_mean_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult)
+{
+ q63_t sum = 0; /* Temporary result storage */
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ q31_t in1, in2, in3, in4;
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
+ in1 = *pSrc++;
+ in2 = *pSrc++;
+ in3 = *pSrc++;
+ in4 = *pSrc++;
+
+ sum += in1;
+ sum += in2;
+ sum += in3;
+ sum += in4;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
+ sum += *pSrc++;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */
+ /* Store the result to the destination */
+ *pResult = (q31_t) (sum / (int32_t) blockSize);
+}
+
+/**
+ * @} end of mean group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_q7.c
new file mode 100644
index 0000000..522e3d4
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_q7.c
@@ -0,0 +1,133 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_mean_q7.c
+*
+* Description: Mean value of a Q7 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @addtogroup mean
+ * @{
+ */
+
+/**
+ * @brief Mean value of a Q7 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult mean value returned here
+ * @return none.
+ *
+ * @details
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using a 32-bit internal accumulator.
+ * The input is represented in 1.7 format and is accumulated in a 32-bit
+ * accumulator in 25.7 format.
+ * There is no risk of internal overflow with this approach, and the
+ * full precision of intermediate result is preserved.
+ * Finally, the accumulator is truncated to yield a result of 1.7 format.
+ *
+ */
+
+
+void arm_mean_q7(
+ q7_t * pSrc,
+ uint32_t blockSize,
+ q7_t * pResult)
+{
+ q31_t sum = 0; /* Temporary result storage */
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ q31_t in;
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
+ in = *__SIMD32(pSrc)++;
+
+ sum += ((in << 24) >> 24);
+ sum += ((in << 16) >> 24);
+ sum += ((in << 8) >> 24);
+ sum += (in >> 24);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
+ sum += *pSrc++;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */
+ /* Store the result to the destination */
+ *pResult = (q7_t) (sum / (int32_t) blockSize);
+}
+
+/**
+ * @} end of mean group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_f32.c
new file mode 100644
index 0000000..22f057a
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_f32.c
@@ -0,0 +1,183 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_min_f32.c
+*
+* Description: Minimum value of a floating-point vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @defgroup Min Minimum
+ *
+ * Computes the minimum value of an array of data.
+ * The function returns both the minimum value and its position within the array.
+ * There are separate functions for floating-point, Q31, Q15, and Q7 data types.
+ */
+
+/**
+ * @addtogroup Min
+ * @{
+ */
+
+
+/**
+ * @brief Minimum value of a floating-point vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult minimum value returned here
+ * @param[out] *pIndex index of minimum value returned here
+ * @return none.
+ *
+ */
+
+void arm_min_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult,
+ uint32_t * pIndex)
+{
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ float32_t minVal1, minVal2, out; /* Temporary variables to store the output value. */
+ uint32_t blkCnt, outIndex, count; /* loop counter */
+
+ /* Initialise the count value. */
+ count = 0u;
+ /* Initialise the index value to zero. */
+ outIndex = 0u;
+ /* Load first input value that act as reference value for comparision */
+ out = *pSrc++;
+
+ /* Loop unrolling */
+ blkCnt = (blockSize - 1u) >> 2u;
+
+ while(blkCnt > 0)
+ {
+ /* Initialize minVal to the next consecutive values one by one */
+ minVal1 = *pSrc++;
+ minVal2 = *pSrc++;
+
+ /* compare for the minimum value */
+ if(out > minVal1)
+ {
+ /* Update the minimum value and its index */
+ out = minVal1;
+ outIndex = count + 1u;
+ }
+
+ minVal1 = *pSrc++;
+
+ /* compare for the minimum value */
+ if(out > minVal2)
+ {
+ /* Update the minimum value and its index */
+ out = minVal2;
+ outIndex = count + 2u;
+ }
+
+ minVal2 = *pSrc++;
+
+ /* compare for the minimum value */
+ if(out > minVal1)
+ {
+ /* Update the minimum value and its index */
+ out = minVal1;
+ outIndex = count + 3u;
+ }
+
+ /* compare for the minimum value */
+ if(out > minVal2)
+ {
+ /* Update the minimum value and its index */
+ out = minVal2;
+ outIndex = count + 4u;
+ }
+
+ count += 4u;
+
+ blkCnt--;
+ }
+
+ /* if (blockSize - 1u ) is not multiple of 4 */
+ blkCnt = (blockSize - 1u) % 4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+ float32_t minVal1, out; /* Temporary variables to store the output value. */
+ uint32_t blkCnt, outIndex; /* loop counter */
+
+ /* Initialise the index value to zero. */
+ outIndex = 0u;
+ /* Load first input value that act as reference value for comparision */
+ out = *pSrc++;
+
+ blkCnt = (blockSize - 1u);
+
+#endif // #ifndef ARM_MATH_CM0_FAMILY
+
+ while(blkCnt > 0)
+ {
+ /* Initialize minVal to the next consecutive values one by one */
+ minVal1 = *pSrc++;
+
+ /* compare for the minimum value */
+ if(out > minVal1)
+ {
+ /* Update the minimum value and it's index */
+ out = minVal1;
+ outIndex = blockSize - blkCnt;
+ }
+
+ blkCnt--;
+
+ }
+
+ /* Store the minimum value and it's index into destination pointers */
+ *pResult = out;
+ *pIndex = outIndex;
+}
+
+/**
+ * @} end of Min group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_q15.c
new file mode 100644
index 0000000..05c13dd
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_q15.c
@@ -0,0 +1,177 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_min_q15.c
+*
+* Description: Minimum value of a Q15 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+
+/**
+ * @addtogroup Min
+ * @{
+ */
+
+
+/**
+ * @brief Minimum value of a Q15 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult minimum value returned here
+ * @param[out] *pIndex index of minimum value returned here
+ * @return none.
+ *
+ */
+
+void arm_min_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult,
+ uint32_t * pIndex)
+{
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ q15_t minVal1, minVal2, out; /* Temporary variables to store the output value. */
+ uint32_t blkCnt, outIndex, count; /* loop counter */
+
+ /* Initialise the count value. */
+ count = 0u;
+ /* Initialise the index value to zero. */
+ outIndex = 0u;
+ /* Load first input value that act as reference value for comparision */
+ out = *pSrc++;
+
+ /* Loop unrolling */
+ blkCnt = (blockSize - 1u) >> 2u;
+
+ while(blkCnt > 0)
+ {
+ /* Initialize minVal to the next consecutive values one by one */
+ minVal1 = *pSrc++;
+ minVal2 = *pSrc++;
+
+ /* compare for the minimum value */
+ if(out > minVal1)
+ {
+ /* Update the minimum value and its index */
+ out = minVal1;
+ outIndex = count + 1u;
+ }
+
+ minVal1 = *pSrc++;
+
+ /* compare for the minimum value */
+ if(out > minVal2)
+ {
+ /* Update the minimum value and its index */
+ out = minVal2;
+ outIndex = count + 2u;
+ }
+
+ minVal2 = *pSrc++;
+
+ /* compare for the minimum value */
+ if(out > minVal1)
+ {
+ /* Update the minimum value and its index */
+ out = minVal1;
+ outIndex = count + 3u;
+ }
+
+ /* compare for the minimum value */
+ if(out > minVal2)
+ {
+ /* Update the minimum value and its index */
+ out = minVal2;
+ outIndex = count + 4u;
+ }
+
+ count += 4u;
+
+ blkCnt--;
+ }
+
+ /* if (blockSize - 1u ) is not multiple of 4 */
+ blkCnt = (blockSize - 1u) % 4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+ q15_t minVal1, out; /* Temporary variables to store the output value. */
+ uint32_t blkCnt, outIndex; /* loop counter */
+
+ blkCnt = (blockSize - 1u);
+
+ /* Initialise the index value to zero. */
+ outIndex = 0u;
+ /* Load first input value that act as reference value for comparision */
+ out = *pSrc++;
+
+#endif // #ifndef ARM_MATH_CM0_FAMILY
+
+ while(blkCnt > 0)
+ {
+ /* Initialize minVal to the next consecutive values one by one */
+ minVal1 = *pSrc++;
+
+ /* compare for the minimum value */
+ if(out > minVal1)
+ {
+ /* Update the minimum value and it's index */
+ out = minVal1;
+ outIndex = blockSize - blkCnt;
+ }
+
+ blkCnt--;
+
+ }
+
+
+
+ /* Store the minimum value and its index into destination pointers */
+ *pResult = out;
+ *pIndex = outIndex;
+}
+
+/**
+ * @} end of Min group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_q31.c
new file mode 100644
index 0000000..97431db
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_q31.c
@@ -0,0 +1,176 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_min_q31.c
+*
+* Description: Minimum value of a Q31 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+
+/**
+ * @addtogroup Min
+ * @{
+ */
+
+
+/**
+ * @brief Minimum value of a Q31 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult minimum value returned here
+ * @param[out] *pIndex index of minimum value returned here
+ * @return none.
+ *
+ */
+
+void arm_min_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult,
+ uint32_t * pIndex)
+{
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ q31_t minVal1, minVal2, out; /* Temporary variables to store the output value. */
+ uint32_t blkCnt, outIndex, count; /* loop counter */
+
+ /* Initialise the count value. */
+ count = 0u;
+ /* Initialise the index value to zero. */
+ outIndex = 0u;
+ /* Load first input value that act as reference value for comparision */
+ out = *pSrc++;
+
+
+ /* Loop unrolling */
+ blkCnt = (blockSize - 1u) >> 2u;
+
+ while(blkCnt > 0)
+ {
+ /* Initialize minVal to the next consecutive values one by one */
+ minVal1 = *pSrc++;
+ minVal2 = *pSrc++;
+
+ /* compare for the minimum value */
+ if(out > minVal1)
+ {
+ /* Update the minimum value and its index */
+ out = minVal1;
+ outIndex = count + 1u;
+ }
+
+ minVal1 = *pSrc++;
+
+ /* compare for the minimum value */
+ if(out > minVal2)
+ {
+ /* Update the minimum value and its index */
+ out = minVal2;
+ outIndex = count + 2u;
+ }
+
+ minVal2 = *pSrc++;
+
+ /* compare for the minimum value */
+ if(out > minVal1)
+ {
+ /* Update the minimum value and its index */
+ out = minVal1;
+ outIndex = count + 3u;
+ }
+
+ /* compare for the minimum value */
+ if(out > minVal2)
+ {
+ /* Update the minimum value and its index */
+ out = minVal2;
+ outIndex = count + 4u;
+ }
+
+ count += 4u;
+
+ blkCnt--;
+ }
+
+ /* if (blockSize - 1u ) is not multiple of 4 */
+ blkCnt = (blockSize - 1u) % 4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+ q31_t minVal1, out; /* Temporary variables to store the output value. */
+ uint32_t blkCnt, outIndex; /* loop counter */
+
+ blkCnt = (blockSize - 1u);
+
+ /* Initialise the index value to zero. */
+ outIndex = 0u;
+ /* Load first input value that act as reference value for comparision */
+ out = *pSrc++;
+
+#endif // #ifndef ARM_MATH_CM0_FAMILY
+
+ while(blkCnt > 0)
+ {
+ /* Initialize minVal to the next consecutive values one by one */
+ minVal1 = *pSrc++;
+
+ /* compare for the minimum value */
+ if(out > minVal1)
+ {
+ /* Update the minimum value and it's index */
+ out = minVal1;
+ outIndex = blockSize - blkCnt;
+ }
+
+ blkCnt--;
+
+ }
+
+ /* Store the minimum value and its index into destination pointers */
+ *pResult = out;
+ *pIndex = outIndex;
+}
+
+/**
+ * @} end of Min group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_q7.c
new file mode 100644
index 0000000..b6d0950
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_q7.c
@@ -0,0 +1,178 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_min_q7.c
+*
+* Description: Minimum value of a Q7 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @addtogroup Min
+ * @{
+ */
+
+
+/**
+ * @brief Minimum value of a Q7 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult minimum value returned here
+ * @param[out] *pIndex index of minimum value returned here
+ * @return none.
+ *
+ */
+
+void arm_min_q7(
+ q7_t * pSrc,
+ uint32_t blockSize,
+ q7_t * pResult,
+ uint32_t * pIndex)
+{
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ q7_t minVal1, minVal2, out; /* Temporary variables to store the output value. */
+ uint32_t blkCnt, outIndex, count; /* loop counter */
+
+ /* Initialise the count value. */
+ count = 0u;
+ /* Initialise the index value to zero. */
+ outIndex = 0u;
+ /* Load first input value that act as reference value for comparision */
+ out = *pSrc++;
+
+ /* Loop unrolling */
+ blkCnt = (blockSize - 1u) >> 2u;
+
+ while(blkCnt > 0)
+ {
+ /* Initialize minVal to the next consecutive values one by one */
+ minVal1 = *pSrc++;
+ minVal2 = *pSrc++;
+
+ /* compare for the minimum value */
+ if(out > minVal1)
+ {
+ /* Update the minimum value and its index */
+ out = minVal1;
+ outIndex = count + 1u;
+ }
+
+ minVal1 = *pSrc++;
+
+ /* compare for the minimum value */
+ if(out > minVal2)
+ {
+ /* Update the minimum value and its index */
+ out = minVal2;
+ outIndex = count + 2u;
+ }
+
+ minVal2 = *pSrc++;
+
+ /* compare for the minimum value */
+ if(out > minVal1)
+ {
+ /* Update the minimum value and its index */
+ out = minVal1;
+ outIndex = count + 3u;
+ }
+
+ /* compare for the minimum value */
+ if(out > minVal2)
+ {
+ /* Update the minimum value and its index */
+ out = minVal2;
+ outIndex = count + 4u;
+ }
+
+ count += 4u;
+
+ blkCnt--;
+ }
+
+ /* if (blockSize - 1u ) is not multiple of 4 */
+ blkCnt = (blockSize - 1u) % 4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ q7_t minVal1, out; /* Temporary variables to store the output value. */
+ uint32_t blkCnt, outIndex; /* loop counter */
+
+ /* Initialise the index value to zero. */
+ outIndex = 0u;
+ /* Load first input value that act as reference value for comparision */
+ out = *pSrc++;
+
+ blkCnt = (blockSize - 1u);
+
+#endif // #ifndef ARM_MATH_CM0_FAMILY
+
+ while(blkCnt > 0)
+ {
+ /* Initialize minVal to the next consecutive values one by one */
+ minVal1 = *pSrc++;
+
+ /* compare for the minimum value */
+ if(out > minVal1)
+ {
+ /* Update the minimum value and it's index */
+ out = minVal1;
+ outIndex = blockSize - blkCnt;
+ }
+
+ blkCnt--;
+
+ }
+
+ /* Store the minimum value and its index into destination pointers */
+ *pResult = out;
+ *pIndex = outIndex;
+
+
+}
+
+/**
+ * @} end of Min group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_f32.c
new file mode 100644
index 0000000..831c5b0
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_f32.c
@@ -0,0 +1,143 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_power_f32.c
+*
+* Description: Sum of the squares of the elements of a floating-point vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @defgroup power Power
+ *
+ * Calculates the sum of the squares of the elements in the input vector.
+ * The underlying algorithm is used:
+ *
+ *
+ * Result = pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + pSrc[2] * pSrc[2] + ... + pSrc[blockSize-1] * pSrc[blockSize-1];
+ *
+ *
+ * There are separate functions for floating point, Q31, Q15, and Q7 data types.
+ */
+
+/**
+ * @addtogroup power
+ * @{
+ */
+
+
+/**
+ * @brief Sum of the squares of the elements of a floating-point vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult sum of the squares value returned here
+ * @return none.
+ *
+ */
+
+
+void arm_power_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult)
+{
+ float32_t sum = 0.0f; /* accumulator */
+ float32_t in; /* Temporary variable to store input value */
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
+ /* Compute Power and then store the result in a temporary variable, sum. */
+ in = *pSrc++;
+ sum += in * in;
+ in = *pSrc++;
+ sum += in * in;
+ in = *pSrc++;
+ sum += in * in;
+ in = *pSrc++;
+ sum += in * in;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+
+ while(blkCnt > 0u)
+ {
+ /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
+ /* compute power and then store the result in a temporary variable, sum. */
+ in = *pSrc++;
+ sum += in * in;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Store the result to the destination */
+ *pResult = sum;
+}
+
+/**
+ * @} end of power group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_q15.c
new file mode 100644
index 0000000..6e7034a
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_q15.c
@@ -0,0 +1,152 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_power_q15.c
+*
+* Description: Sum of the squares of the elements of a Q15 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @addtogroup power
+ * @{
+ */
+
+/**
+ * @brief Sum of the squares of the elements of a Q15 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult sum of the squares value returned here
+ * @return none.
+ *
+ * @details
+ * Scaling and Overflow Behavior:
+ *
+ * \par
+ * The function is implemented using a 64-bit internal accumulator.
+ * The input is represented in 1.15 format.
+ * Intermediate multiplication yields a 2.30 format, and this
+ * result is added without saturation to a 64-bit accumulator in 34.30 format.
+ * With 33 guard bits in the accumulator, there is no risk of overflow, and the
+ * full precision of the intermediate multiplication is preserved.
+ * Finally, the return result is in 34.30 format.
+ *
+ */
+
+void arm_power_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q63_t * pResult)
+{
+ q63_t sum = 0; /* Temporary result storage */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ q31_t in32; /* Temporary variable to store input value */
+ q15_t in16; /* Temporary variable to store input value */
+ uint32_t blkCnt; /* loop counter */
+
+
+ /* loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
+ /* Compute Power and then store the result in a temporary variable, sum. */
+ in32 = *__SIMD32(pSrc)++;
+ sum = __SMLALD(in32, in32, sum);
+ in32 = *__SIMD32(pSrc)++;
+ sum = __SMLALD(in32, in32, sum);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+ while(blkCnt > 0u)
+ {
+ /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
+ /* Compute Power and then store the result in a temporary variable, sum. */
+ in16 = *pSrc++;
+ sum = __SMLALD(in16, in16, sum);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ q15_t in; /* Temporary variable to store input value */
+ uint32_t blkCnt; /* loop counter */
+
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+ while(blkCnt > 0u)
+ {
+ /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
+ /* Compute Power and then store the result in a temporary variable, sum. */
+ in = *pSrc++;
+ sum += ((q31_t) in * in);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ /* Store the results in 34.30 format */
+ *pResult = sum;
+}
+
+/**
+ * @} end of power group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_q31.c
new file mode 100644
index 0000000..2f7976a
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_q31.c
@@ -0,0 +1,143 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_power_q31.c
+*
+* Description: Sum of the squares of the elements of a Q31 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @addtogroup power
+ * @{
+ */
+
+/**
+ * @brief Sum of the squares of the elements of a Q31 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult sum of the squares value returned here
+ * @return none.
+ *
+ * @details
+ * Scaling and Overflow Behavior:
+ *
+ * \par
+ * The function is implemented using a 64-bit internal accumulator.
+ * The input is represented in 1.31 format.
+ * Intermediate multiplication yields a 2.62 format, and this
+ * result is truncated to 2.48 format by discarding the lower 14 bits.
+ * The 2.48 result is then added without saturation to a 64-bit accumulator in 16.48 format.
+ * With 15 guard bits in the accumulator, there is no risk of overflow, and the
+ * full precision of the intermediate multiplication is preserved.
+ * Finally, the return result is in 16.48 format.
+ *
+ */
+
+void arm_power_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q63_t * pResult)
+{
+ q63_t sum = 0; /* Temporary result storage */
+ q31_t in;
+ uint32_t blkCnt; /* loop counter */
+
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
+ /* Compute Power then shift intermediate results by 14 bits to maintain 16.48 format and then store the result in a temporary variable sum, providing 15 guard bits. */
+ in = *pSrc++;
+ sum += ((q63_t) in * in) >> 14u;
+
+ in = *pSrc++;
+ sum += ((q63_t) in * in) >> 14u;
+
+ in = *pSrc++;
+ sum += ((q63_t) in * in) >> 14u;
+
+ in = *pSrc++;
+ sum += ((q63_t) in * in) >> 14u;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
+ /* Compute Power and then store the result in a temporary variable, sum. */
+ in = *pSrc++;
+ sum += ((q63_t) in * in) >> 14u;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Store the results in 16.48 format */
+ *pResult = sum;
+}
+
+/**
+ * @} end of power group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_q7.c
new file mode 100644
index 0000000..3e97f91
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_power_q7.c
@@ -0,0 +1,141 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_power_q7.c
+*
+* Description: Sum of the squares of the elements of a Q7 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @addtogroup power
+ * @{
+ */
+
+/**
+ * @brief Sum of the squares of the elements of a Q7 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult sum of the squares value returned here
+ * @return none.
+ *
+ * @details
+ * Scaling and Overflow Behavior:
+ *
+ * \par
+ * The function is implemented using a 32-bit internal accumulator.
+ * The input is represented in 1.7 format.
+ * Intermediate multiplication yields a 2.14 format, and this
+ * result is added without saturation to an accumulator in 18.14 format.
+ * With 17 guard bits in the accumulator, there is no risk of overflow, and the
+ * full precision of the intermediate multiplication is preserved.
+ * Finally, the return result is in 18.14 format.
+ *
+ */
+
+void arm_power_q7(
+ q7_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult)
+{
+ q31_t sum = 0; /* Temporary result storage */
+ q7_t in; /* Temporary variable to store input */
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ q31_t input1; /* Temporary variable to store packed input */
+ q31_t in1, in2; /* Temporary variables to store input */
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* Reading two inputs of pSrc vector and packing */
+ input1 = *__SIMD32(pSrc)++;
+
+ in1 = __SXTB16(__ROR(input1, 8));
+ in2 = __SXTB16(input1);
+
+ /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
+ /* calculate power and accumulate to accumulator */
+ sum = __SMLAD(in1, in1, sum);
+ sum = __SMLAD(in2, in2, sum);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
+ /* Compute Power and then store the result in a temporary variable, sum. */
+ in = *pSrc++;
+ sum += ((q15_t) in * in);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Store the result in 18.14 format */
+ *pResult = sum;
+}
+
+/**
+ * @} end of power group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_f32.c
new file mode 100644
index 0000000..466d17b
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_f32.c
@@ -0,0 +1,141 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_rms_f32.c
+*
+* Description: Root mean square value of an array of F32 type
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @defgroup RMS Root mean square (RMS)
+ *
+ *
+ * Calculates the Root Mean Sqaure of the elements in the input vector.
+ * The underlying algorithm is used:
+ *
+ *
+ * Result = sqrt(((pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] * pSrc[blockSize-1]) / blockSize));
+ *
+ *
+ * There are separate functions for floating point, Q31, and Q15 data types.
+ */
+
+/**
+ * @addtogroup RMS
+ * @{
+ */
+
+
+/**
+ * @brief Root Mean Square of the elements of a floating-point vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult rms value returned here
+ * @return none.
+ *
+ */
+
+void arm_rms_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult)
+{
+ float32_t sum = 0.0f; /* Accumulator */
+ float32_t in; /* Tempoprary variable to store input value */
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /* loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
+ /* Compute sum of the squares and then store the result in a temporary variable, sum */
+ in = *pSrc++;
+ sum += in * in;
+ in = *pSrc++;
+ sum += in * in;
+ in = *pSrc++;
+ sum += in * in;
+ in = *pSrc++;
+ sum += in * in;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
+ /* Compute sum of the squares and then store the results in a temporary variable, sum */
+ in = *pSrc++;
+ sum += in * in;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Compute Rms and store the result in the destination */
+ arm_sqrt_f32(sum / (float32_t) blockSize, pResult);
+}
+
+/**
+ * @} end of RMS group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_q15.c
new file mode 100644
index 0000000..74372be
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_q15.c
@@ -0,0 +1,153 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_rms_q15.c
+*
+* Description: Root Mean Square of the elements of a Q15 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @addtogroup RMS
+ * @{
+ */
+
+/**
+ * @brief Root Mean Square of the elements of a Q15 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult rms value returned here
+ * @return none.
+ *
+ * @details
+ * Scaling and Overflow Behavior:
+ *
+ * \par
+ * The function is implemented using a 64-bit internal accumulator.
+ * The input is represented in 1.15 format.
+ * Intermediate multiplication yields a 2.30 format, and this
+ * result is added without saturation to a 64-bit accumulator in 34.30 format.
+ * With 33 guard bits in the accumulator, there is no risk of overflow, and the
+ * full precision of the intermediate multiplication is preserved.
+ * Finally, the 34.30 result is truncated to 34.15 format by discarding the lower
+ * 15 bits, and then saturated to yield a result in 1.15 format.
+ *
+ */
+
+void arm_rms_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult)
+{
+ q63_t sum = 0; /* accumulator */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ q31_t in; /* temporary variable to store the input value */
+ q15_t in1; /* temporary variable to store the input value */
+ uint32_t blkCnt; /* loop counter */
+
+ /* loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute sum of the squares and then store the results in a temporary variable, sum */
+ in = *__SIMD32(pSrc)++;
+ sum = __SMLALD(in, in, sum);
+ in = *__SIMD32(pSrc)++;
+ sum = __SMLALD(in, in, sum);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute sum of the squares and then store the results in a temporary variable, sum */
+ in1 = *pSrc++;
+ sum = __SMLALD(in1, in1, sum);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Truncating and saturating the accumulator to 1.15 format */
+ /* Store the result in the destination */
+ arm_sqrt_q15(__SSAT((sum / (q63_t)blockSize) >> 15, 16), pResult);
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ q15_t in; /* temporary variable to store the input value */
+ uint32_t blkCnt; /* loop counter */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute sum of the squares and then store the results in a temporary variable, sum */
+ in = *pSrc++;
+ sum += ((q31_t) in * in);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Truncating and saturating the accumulator to 1.15 format */
+ /* Store the result in the destination */
+ arm_sqrt_q15(__SSAT((sum / (q63_t)blockSize) >> 15, 16), pResult);
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+}
+
+/**
+ * @} end of RMS group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_q31.c
new file mode 100644
index 0000000..7072e19
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_q31.c
@@ -0,0 +1,150 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_rms_q31.c
+*
+* Description: Root Mean Square of the elements of a Q31 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @addtogroup RMS
+ * @{
+ */
+
+
+/**
+ * @brief Root Mean Square of the elements of a Q31 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult rms value returned here
+ * @return none.
+ *
+ * @details
+ * Scaling and Overflow Behavior:
+ *
+ *\par
+ * The function is implemented using an internal 64-bit accumulator.
+ * The input is represented in 1.31 format, and intermediate multiplication
+ * yields a 2.62 format.
+ * The accumulator maintains full precision of the intermediate multiplication results,
+ * but provides only a single guard bit.
+ * There is no saturation on intermediate additions.
+ * If the accumulator overflows, it wraps around and distorts the result.
+ * In order to avoid overflows completely, the input signal must be scaled down by
+ * log2(blockSize) bits, as a total of blockSize additions are performed internally.
+ * Finally, the 2.62 accumulator is right shifted by 31 bits to yield a 1.31 format value.
+ *
+ */
+
+void arm_rms_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult)
+{
+ q63_t sum = 0; /* accumulator */
+ q31_t in; /* Temporary variable to store the input */
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ q31_t in1, in2, in3, in4; /* Temporary input variables */
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 8 outputs at a time.
+ ** a second loop below computes the remaining 1 to 7 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
+ /* Compute sum of the squares and then store the result in a temporary variable, sum */
+ /* read two samples from source buffer */
+ in1 = pSrc[0];
+ in2 = pSrc[1];
+
+ /* calculate power and accumulate to accumulator */
+ sum += (q63_t) in1 *in1;
+ sum += (q63_t) in2 *in2;
+
+ /* read two samples from source buffer */
+ in3 = pSrc[2];
+ in4 = pSrc[3];
+
+ /* calculate power and accumulate to accumulator */
+ sum += (q63_t) in3 *in3;
+ sum += (q63_t) in4 *in4;
+
+
+ /* update source buffer to process next samples */
+ pSrc += 4u;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 8, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
+ /* Compute sum of the squares and then store the results in a temporary variable, sum */
+ in = *pSrc++;
+ sum += (q63_t) in *in;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Convert data in 2.62 to 1.31 by 31 right shifts and saturate */
+ /* Compute Rms and store the result in the destination vector */
+ arm_sqrt_q31(clip_q63_to_q31((sum / (q63_t) blockSize) >> 31), pResult);
+}
+
+/**
+ * @} end of RMS group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_f32.c
new file mode 100644
index 0000000..2483ada
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_f32.c
@@ -0,0 +1,208 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_std_f32.c
+*
+* Description: Standard deviation of the elements of a floating-point vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @defgroup STD Standard deviation
+ *
+ * Calculates the standard deviation of the elements in the input vector.
+ * The underlying algorithm is used:
+ *
+ *
+ * Result = sqrt((sumOfSquares - sum2 / blockSize) / (blockSize - 1))
+ *
+ * where, sumOfSquares = pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] * pSrc[blockSize-1]
+ *
+ * sum = pSrc[0] + pSrc[1] + pSrc[2] + ... + pSrc[blockSize-1]
+ *
+ *
+ * There are separate functions for floating point, Q31, and Q15 data types.
+ */
+
+/**
+ * @addtogroup STD
+ * @{
+ */
+
+
+/**
+ * @brief Standard deviation of the elements of a floating-point vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult standard deviation value returned here
+ * @return none.
+ *
+ */
+
+
+void arm_std_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult)
+{
+ float32_t sum = 0.0f; /* Temporary result storage */
+ float32_t sumOfSquares = 0.0f; /* Sum of squares */
+ float32_t in; /* input value */
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ float32_t meanOfSquares, mean, squareOfMean;
+
+ if(blockSize == 1)
+ {
+ *pResult = 0;
+ return;
+ }
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute Sum of squares of the input samples
+ * and then store the result in a temporary variable, sum. */
+ in = *pSrc++;
+ sum += in;
+ sumOfSquares += in * in;
+ in = *pSrc++;
+ sum += in;
+ sumOfSquares += in * in;
+ in = *pSrc++;
+ sum += in;
+ sumOfSquares += in * in;
+ in = *pSrc++;
+ sum += in;
+ sumOfSquares += in * in;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute Sum of squares of the input samples
+ * and then store the result in a temporary variable, sum. */
+ in = *pSrc++;
+ sum += in;
+ sumOfSquares += in * in;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Compute Mean of squares of the input samples
+ * and then store the result in a temporary variable, meanOfSquares. */
+ meanOfSquares = sumOfSquares / ((float32_t) blockSize - 1.0f);
+
+ /* Compute mean of all input values */
+ mean = sum / (float32_t) blockSize;
+
+ /* Compute square of mean */
+ squareOfMean = (mean * mean) * (((float32_t) blockSize) /
+ ((float32_t) blockSize - 1.0f));
+
+ /* Compute standard deviation and then store the result to the destination */
+ arm_sqrt_f32((meanOfSquares - squareOfMean), pResult);
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ float32_t squareOfSum; /* Square of Sum */
+ float32_t var; /* Temporary varaince storage */
+
+ if(blockSize == 1)
+ {
+ *pResult = 0;
+ return;
+ }
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute Sum of squares of the input samples
+ * and then store the result in a temporary variable, sumOfSquares. */
+ in = *pSrc++;
+ sumOfSquares += in * in;
+
+ /* C = (A[0] + A[1] + ... + A[blockSize-1]) */
+ /* Compute Sum of the input samples
+ * and then store the result in a temporary variable, sum. */
+ sum += in;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Compute the square of sum */
+ squareOfSum = ((sum * sum) / (float32_t) blockSize);
+
+ /* Compute the variance */
+ var = ((sumOfSquares - squareOfSum) / (float32_t) (blockSize - 1.0f));
+
+ /* Compute standard deviation and then store the result to the destination */
+ arm_sqrt_f32(var, pResult);
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+}
+
+/**
+ * @} end of STD group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_q15.c
new file mode 100644
index 0000000..f113099
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_q15.c
@@ -0,0 +1,195 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_std_q15.c
+*
+* Description: Standard deviation of an array of Q15 type.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @addtogroup STD
+ * @{
+ */
+
+/**
+ * @brief Standard deviation of the elements of a Q15 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult standard deviation value returned here
+ * @return none.
+ *
+ * @details
+ * Scaling and Overflow Behavior:
+ *
+ * \par
+ * The function is implemented using a 64-bit internal accumulator.
+ * The input is represented in 1.15 format.
+ * Intermediate multiplication yields a 2.30 format, and this
+ * result is added without saturation to a 64-bit accumulator in 34.30 format.
+ * With 33 guard bits in the accumulator, there is no risk of overflow, and the
+ * full precision of the intermediate multiplication is preserved.
+ * Finally, the 34.30 result is truncated to 34.15 format by discarding the lower
+ * 15 bits, and then saturated to yield a result in 1.15 format.
+ */
+
+void arm_std_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult)
+{
+ q31_t sum = 0; /* Accumulator */
+ q31_t meanOfSquares, squareOfMean; /* square of mean and mean of square */
+ uint32_t blkCnt; /* loop counter */
+ q63_t sumOfSquares = 0; /* Accumulator */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ q31_t in; /* input value */
+ q15_t in1; /* input value */
+
+ if(blockSize == 1)
+ {
+ *pResult = 0;
+ return;
+ }
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute Sum of squares of the input samples
+ * and then store the result in a temporary variable, sum. */
+ in = *__SIMD32(pSrc)++;
+ sum += ((in << 16) >> 16);
+ sum += (in >> 16);
+ sumOfSquares = __SMLALD(in, in, sumOfSquares);
+ in = *__SIMD32(pSrc)++;
+ sum += ((in << 16) >> 16);
+ sum += (in >> 16);
+ sumOfSquares = __SMLALD(in, in, sumOfSquares);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute Sum of squares of the input samples
+ * and then store the result in a temporary variable, sum. */
+ in1 = *pSrc++;
+ sumOfSquares = __SMLALD(in1, in1, sumOfSquares);
+ sum += in1;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Compute Mean of squares of the input samples
+ * and then store the result in a temporary variable, meanOfSquares. */
+ meanOfSquares = (q31_t)(sumOfSquares / (q63_t)(blockSize - 1));
+
+ /* Compute square of mean */
+ squareOfMean = (q31_t) ((q63_t)sum * sum / (q63_t)(blockSize * (blockSize - 1)));
+
+ /* mean of the squares minus the square of the mean. */
+ /* Compute standard deviation and store the result to the destination */
+ arm_sqrt_q15(__SSAT((meanOfSquares - squareOfMean) >> 15, 16u), pResult);
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+ q15_t in; /* input value */
+
+ if(blockSize == 1)
+ {
+ *pResult = 0;
+ return;
+ }
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute Sum of squares of the input samples
+ * and then store the result in a temporary variable, sumOfSquares. */
+ in = *pSrc++;
+ sumOfSquares += (in * in);
+
+ /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
+ /* Compute sum of all input values and then store the result in a temporary variable, sum. */
+ sum += in;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Compute Mean of squares of the input samples
+ * and then store the result in a temporary variable, meanOfSquares. */
+ meanOfSquares = (q31_t)(sumOfSquares / (q63_t)(blockSize - 1));
+
+ /* Compute square of mean */
+ squareOfMean = (q31_t) ((q63_t)sum * sum / (q63_t)(blockSize * (blockSize - 1)));
+
+ /* mean of the squares minus the square of the mean. */
+ /* Compute standard deviation and store the result to the destination */
+ arm_sqrt_q15(__SSAT((meanOfSquares - squareOfMean) >> 15, 16u), pResult);
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+
+}
+
+/**
+ * @} end of STD group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_q31.c
new file mode 100644
index 0000000..f2518c5
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_q31.c
@@ -0,0 +1,186 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_std_q31.c
+*
+* Description: Standard deviation of an array of Q31 type.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @addtogroup STD
+ * @{
+ */
+
+
+/**
+ * @brief Standard deviation of the elements of a Q31 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult standard deviation value returned here
+ * @return none.
+ * @details
+ * Scaling and Overflow Behavior:
+ *
+ *\par
+ * The function is implemented using an internal 64-bit accumulator.
+ * The input is represented in 1.31 format, which is then downshifted by 8 bits
+ * which yields 1.23, and intermediate multiplication yields a 2.46 format.
+ * The accumulator maintains full precision of the intermediate multiplication results,
+ * but provides only a 16 guard bits.
+ * There is no saturation on intermediate additions.
+ * If the accumulator overflows it wraps around and distorts the result.
+ * In order to avoid overflows completely the input signal must be scaled down by
+ * log2(blockSize)-8 bits, as a total of blockSize additions are performed internally.
+ * After division, internal variables should be Q18.46
+ * Finally, the 18.46 accumulator is right shifted by 15 bits to yield a 1.31 format value.
+ *
+ */
+
+
+void arm_std_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult)
+{
+ q63_t sum = 0; /* Accumulator */
+ q63_t meanOfSquares, squareOfMean; /* square of mean and mean of square */
+ q31_t in; /* input value */
+ uint32_t blkCnt; /* loop counter */
+ q63_t sumOfSquares = 0; /* Accumulator */
+
+ if(blockSize == 1)
+ {
+ *pResult = 0;
+ return;
+ }
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute Sum of squares of the input samples
+ * and then store the result in a temporary variable, sum. */
+ in = *pSrc++ >> 8;
+ sum += in;
+ sumOfSquares += ((q63_t) (in) * (in));
+ in = *pSrc++ >> 8;
+ sum += in;
+ sumOfSquares += ((q63_t) (in) * (in));
+ in = *pSrc++ >> 8;
+ sum += in;
+ sumOfSquares += ((q63_t) (in) * (in));
+ in = *pSrc++ >> 8;
+ sum += in;
+ sumOfSquares += ((q63_t) (in) * (in));
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute Sum of squares of the input samples
+ * and then store the result in a temporary variable, sum. */
+ in = *pSrc++ >> 8;
+ sum += in;
+ sumOfSquares += ((q63_t) (in) * (in));
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Compute Mean of squares of the input samples
+ * and then store the result in a temporary variable, meanOfSquares. */
+ meanOfSquares = sumOfSquares / (q63_t)(blockSize - 1);
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute Sum of squares of the input samples
+ * and then store the result in a temporary variable, sumOfSquares. */
+ in = *pSrc++ >> 8;
+ sumOfSquares += ((q63_t) (in) * (in));
+
+ /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
+ /* Compute sum of all input values and then store the result in a temporary variable, sum. */
+ sum += in;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Compute Mean of squares of the input samples
+ * and then store the result in a temporary variable, meanOfSquares. */
+ meanOfSquares = sumOfSquares / (q63_t)(blockSize - 1);
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ /* Compute square of mean */
+ squareOfMean = sum * sum / (q63_t)(blockSize * (blockSize - 1u));
+
+ /* Compute standard deviation and then store the result to the destination */
+ arm_sqrt_q31((meanOfSquares - squareOfMean) >> 15, pResult);
+
+}
+
+/**
+ * @} end of STD group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_var_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_var_f32.c
new file mode 100644
index 0000000..aff478d
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_var_f32.c
@@ -0,0 +1,204 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_var_f32.c
+*
+* Description: Variance of the elements of a floating-point vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @defgroup variance Variance
+ *
+ * Calculates the variance of the elements in the input vector.
+ * The underlying algorithm is used:
+ *
+ *
+ * Result = (sumOfSquares - sum2 / blockSize) / (blockSize - 1)
+ *
+ * where, sumOfSquares = pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] * pSrc[blockSize-1]
+ *
+ * sum = pSrc[0] + pSrc[1] + pSrc[2] + ... + pSrc[blockSize-1]
+ *
+ *
+ * There are separate functions for floating point, Q31, and Q15 data types.
+ */
+
+/**
+ * @addtogroup variance
+ * @{
+ */
+
+
+/**
+ * @brief Variance of the elements of a floating-point vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult variance value returned here
+ * @return none.
+ *
+ */
+
+
+void arm_var_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult)
+{
+
+ float32_t sum = 0.0f; /* Temporary result storage */
+ float32_t sumOfSquares = 0.0f; /* Sum of squares */
+ float32_t in; /* input value */
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ float32_t meanOfSquares, mean, squareOfMean; /* Temporary variables */
+
+ if(blockSize == 1)
+ {
+ *pResult = 0;
+ return;
+ }
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute Sum of squares of the input samples
+ * and then store the result in a temporary variable, sum. */
+ in = *pSrc++;
+ sum += in;
+ sumOfSquares += in * in;
+ in = *pSrc++;
+ sum += in;
+ sumOfSquares += in * in;
+ in = *pSrc++;
+ sum += in;
+ sumOfSquares += in * in;
+ in = *pSrc++;
+ sum += in;
+ sumOfSquares += in * in;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute Sum of squares of the input samples
+ * and then store the result in a temporary variable, sum. */
+ in = *pSrc++;
+ sum += in;
+ sumOfSquares += in * in;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Compute Mean of squares of the input samples
+ * and then store the result in a temporary variable, meanOfSquares. */
+ meanOfSquares = sumOfSquares / ((float32_t) blockSize - 1.0f);
+
+ /* Compute mean of all input values */
+ mean = sum / (float32_t) blockSize;
+
+ /* Compute square of mean */
+ squareOfMean = (mean * mean) * (((float32_t) blockSize) /
+ ((float32_t) blockSize - 1.0f));
+
+ /* Compute variance and then store the result to the destination */
+ *pResult = meanOfSquares - squareOfMean;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+ float32_t squareOfSum; /* Square of Sum */
+
+ if(blockSize == 1)
+ {
+ *pResult = 0;
+ return;
+ }
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute Sum of squares of the input samples
+ * and then store the result in a temporary variable, sumOfSquares. */
+ in = *pSrc++;
+ sumOfSquares += in * in;
+
+ /* C = (A[0] + A[1] + ... + A[blockSize-1]) */
+ /* Compute Sum of the input samples
+ * and then store the result in a temporary variable, sum. */
+ sum += in;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Compute the square of sum */
+ squareOfSum = ((sum * sum) / (float32_t) blockSize);
+
+ /* Compute the variance */
+ *pResult = ((sumOfSquares - squareOfSum) / (float32_t) (blockSize - 1.0f));
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+}
+
+/**
+ * @} end of variance group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_var_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_var_q15.c
new file mode 100644
index 0000000..d304cfb
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_var_q15.c
@@ -0,0 +1,195 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_var_q15.c
+*
+* Description: Variance of an array of Q15 type.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @addtogroup variance
+ * @{
+ */
+
+/**
+ * @brief Variance of the elements of a Q15 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult variance value returned here
+ * @return none.
+ *
+ * @details
+ * Scaling and Overflow Behavior:
+ *
+ * \par
+ * The function is implemented using a 64-bit internal accumulator.
+ * The input is represented in 1.15 format.
+ * Intermediate multiplication yields a 2.30 format, and this
+ * result is added without saturation to a 64-bit accumulator in 34.30 format.
+ * With 33 guard bits in the accumulator, there is no risk of overflow, and the
+ * full precision of the intermediate multiplication is preserved.
+ * Finally, the 34.30 result is truncated to 34.15 format by discarding the lower
+ * 15 bits, and then saturated to yield a result in 1.15 format.
+ *
+ */
+
+
+void arm_var_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult)
+{
+
+ q31_t sum = 0; /* Accumulator */
+ q31_t meanOfSquares, squareOfMean; /* square of mean and mean of square */
+ uint32_t blkCnt; /* loop counter */
+ q63_t sumOfSquares = 0; /* Accumulator */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ q31_t in; /* input value */
+ q15_t in1; /* input value */
+
+ if(blockSize == 1)
+ {
+ *pResult = 0;
+ return;
+ }
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute Sum of squares of the input samples
+ * and then store the result in a temporary variable, sum. */
+ in = *__SIMD32(pSrc)++;
+ sum += ((in << 16) >> 16);
+ sum += (in >> 16);
+ sumOfSquares = __SMLALD(in, in, sumOfSquares);
+ in = *__SIMD32(pSrc)++;
+ sum += ((in << 16) >> 16);
+ sum += (in >> 16);
+ sumOfSquares = __SMLALD(in, in, sumOfSquares);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute Sum of squares of the input samples
+ * and then store the result in a temporary variable, sum. */
+ in1 = *pSrc++;
+ sumOfSquares = __SMLALD(in1, in1, sumOfSquares);
+ sum += in1;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Compute Mean of squares of the input samples
+ * and then store the result in a temporary variable, meanOfSquares. */
+ meanOfSquares = (q31_t) (sumOfSquares / (q63_t)(blockSize - 1));
+
+ /* Compute square of mean */
+ squareOfMean = (q31_t)((q63_t)sum * sum / (q63_t)(blockSize * (blockSize - 1)));
+
+ /* mean of the squares minus the square of the mean. */
+ *pResult = (meanOfSquares - squareOfMean) >> 15;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+ q15_t in; /* input value */
+
+ if(blockSize == 1)
+ {
+ *pResult = 0;
+ return;
+ }
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute Sum of squares of the input samples
+ * and then store the result in a temporary variable, sumOfSquares. */
+ in = *pSrc++;
+ sumOfSquares += (in * in);
+
+ /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
+ /* Compute sum of all input values and then store the result in a temporary variable, sum. */
+ sum += in;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Compute Mean of squares of the input samples
+ * and then store the result in a temporary variable, meanOfSquares. */
+ meanOfSquares = (q31_t) (sumOfSquares / (q63_t)(blockSize - 1));
+
+ /* Compute square of mean */
+ squareOfMean = (q31_t)((q63_t)sum * sum / (q63_t)(blockSize * (blockSize - 1)));
+
+ /* mean of the squares minus the square of the mean. */
+ *pResult = (meanOfSquares - squareOfMean) >> 15;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+}
+
+/**
+ * @} end of variance group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_var_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_var_q31.c
new file mode 100644
index 0000000..6bd0de8
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_var_q31.c
@@ -0,0 +1,187 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_var_q31.c
+*
+* Description: Variance of an array of Q31 type.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupStats
+ */
+
+/**
+ * @addtogroup variance
+ * @{
+ */
+
+/**
+ * @brief Variance of the elements of a Q31 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult variance value returned here
+ * @return none.
+ *
+ * @details
+ * Scaling and Overflow Behavior:
+ *
+ *\par
+ * The function is implemented using an internal 64-bit accumulator.
+ * The input is represented in 1.31 format, which is then downshifted by 8 bits
+ * which yields 1.23, and intermediate multiplication yields a 2.46 format.
+ * The accumulator maintains full precision of the intermediate multiplication results,
+ * but provides only a 16 guard bits.
+ * There is no saturation on intermediate additions.
+ * If the accumulator overflows it wraps around and distorts the result.
+ * In order to avoid overflows completely the input signal must be scaled down by
+ * log2(blockSize)-8 bits, as a total of blockSize additions are performed internally.
+ * After division, internal variables should be Q18.46
+ * Finally, the 18.46 accumulator is right shifted by 15 bits to yield a 1.31 format value.
+ *
+ */
+
+
+void arm_var_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult)
+{
+ q63_t sum = 0; /* Accumulator */
+ q63_t meanOfSquares, squareOfMean; /* square of mean and mean of square */
+ q31_t in; /* input value */
+ uint32_t blkCnt; /* loop counter */
+ q63_t sumOfSquares = 0; /* Accumulator */
+
+ if(blockSize == 1)
+ {
+ *pResult = 0;
+ return;
+ }
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute Sum of squares of the input samples
+ * and then store the result in a temporary variable, sum. */
+ in = *pSrc++ >> 8;
+ sum += in;
+ sumOfSquares += ((q63_t) (in) * (in));
+ in = *pSrc++ >> 8;
+ sum += in;
+ sumOfSquares += ((q63_t) (in) * (in));
+ in = *pSrc++ >> 8;
+ sum += in;
+ sumOfSquares += ((q63_t) (in) * (in));
+ in = *pSrc++ >> 8;
+ sum += in;
+ sumOfSquares += ((q63_t) (in) * (in));
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute Sum of squares of the input samples
+ * and then store the result in a temporary variable, sum. */
+ in = *pSrc++ >> 8;
+ sum += in;
+ sumOfSquares += ((q63_t) (in) * (in));
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Compute Mean of squares of the input samples
+ * and then store the result in a temporary variable, meanOfSquares. */
+ meanOfSquares = sumOfSquares / (q63_t)(blockSize - 1);
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+ while(blkCnt > 0u)
+ {
+ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
+ /* Compute Sum of squares of the input samples
+ * and then store the result in a temporary variable, sumOfSquares. */
+ in = *pSrc++ >> 8;
+ sumOfSquares += ((q63_t) (in) * (in));
+
+ /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
+ /* Compute sum of all input values and then store the result in a temporary variable, sum. */
+ sum += in;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* Compute Mean of squares of the input samples
+ * and then store the result in a temporary variable, meanOfSquares. */
+ meanOfSquares = sumOfSquares / (q63_t)(blockSize - 1);
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ /* Compute square of mean */
+ squareOfMean = sum * sum / (q63_t)(blockSize * (blockSize - 1u));
+
+
+ /* Compute standard deviation and then store the result to the destination */
+ *pResult = (meanOfSquares - squareOfMean) >> 15;
+
+}
+
+/**
+ * @} end of variance group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_f32.c
new file mode 100644
index 0000000..bdbdff5
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_f32.c
@@ -0,0 +1,135 @@
+/* ----------------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_copy_f32.c
+*
+* Description: Copies the elements of a floating-point vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @defgroup copy Vector Copy
+ *
+ * Copies sample by sample from source vector to destination vector.
+ *
+ *
+ * pDst[n] = pSrc[n]; 0 <= n < blockSize.
+ *
+ *
+ * There are separate functions for floating point, Q31, Q15, and Q7 data types.
+ */
+
+/**
+ * @addtogroup copy
+ * @{
+ */
+
+/**
+ * @brief Copies the elements of a floating-point vector.
+ * @param[in] *pSrc points to input vector
+ * @param[out] *pDst points to output vector
+ * @param[in] blockSize length of the input vector
+ * @return none.
+ *
+ */
+
+
+void arm_copy_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize)
+{
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ float32_t in1, in2, in3, in4;
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = A */
+ /* Copy and then store the results in the destination buffer */
+ in1 = *pSrc++;
+ in2 = *pSrc++;
+ in3 = *pSrc++;
+ in4 = *pSrc++;
+
+ *pDst++ = in1;
+ *pDst++ = in2;
+ *pDst++ = in3;
+ *pDst++ = in4;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = A */
+ /* Copy and then store the results in the destination buffer */
+ *pDst++ = *pSrc++;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+}
+
+/**
+ * @} end of BasicCopy group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_q15.c
new file mode 100644
index 0000000..2d152c0
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_q15.c
@@ -0,0 +1,114 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_copy_q15.c
+*
+* Description: Copies the elements of a Q15 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @addtogroup copy
+ * @{
+ */
+/**
+ * @brief Copies the elements of a Q15 vector.
+ * @param[in] *pSrc points to input vector
+ * @param[out] *pDst points to output vector
+ * @param[in] blockSize length of the input vector
+ * @return none.
+ *
+ */
+
+void arm_copy_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize)
+{
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = A */
+ /* Read two inputs */
+ *__SIMD32(pDst)++ = *__SIMD32(pSrc)++;
+ *__SIMD32(pDst)++ = *__SIMD32(pSrc)++;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = A */
+ /* Copy and then store the value in the destination buffer */
+ *pDst++ = *pSrc++;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+}
+
+/**
+ * @} end of BasicCopy group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_q31.c
new file mode 100644
index 0000000..7dec928
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_q31.c
@@ -0,0 +1,123 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_copy_q31.c
+*
+* Description: Copies the elements of a Q31 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @addtogroup copy
+ * @{
+ */
+
+/**
+ * @brief Copies the elements of a Q31 vector.
+ * @param[in] *pSrc points to input vector
+ * @param[out] *pDst points to output vector
+ * @param[in] blockSize length of the input vector
+ * @return none.
+ *
+ */
+
+void arm_copy_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize)
+{
+ uint32_t blkCnt; /* loop counter */
+
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ q31_t in1, in2, in3, in4;
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = A */
+ /* Copy and then store the values in the destination buffer */
+ in1 = *pSrc++;
+ in2 = *pSrc++;
+ in3 = *pSrc++;
+ in4 = *pSrc++;
+
+ *pDst++ = in1;
+ *pDst++ = in2;
+ *pDst++ = in3;
+ *pDst++ = in4;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = A */
+ /* Copy and then store the value in the destination buffer */
+ *pDst++ = *pSrc++;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+}
+
+/**
+ * @} end of BasicCopy group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_q7.c
new file mode 100644
index 0000000..69c42cb
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_copy_q7.c
@@ -0,0 +1,115 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_copy_q7.c
+*
+* Description: Copies the elements of a Q7 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @addtogroup copy
+ * @{
+ */
+
+/**
+ * @brief Copies the elements of a Q7 vector.
+ * @param[in] *pSrc points to input vector
+ * @param[out] *pDst points to output vector
+ * @param[in] blockSize length of the input vector
+ * @return none.
+ *
+ */
+
+void arm_copy_q7(
+ q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize)
+{
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = A */
+ /* Copy and then store the results in the destination buffer */
+ /* 4 samples are copied and stored at a time using SIMD */
+ *__SIMD32(pDst)++ = *__SIMD32(pSrc)++;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+
+ while(blkCnt > 0u)
+ {
+ /* C = A */
+ /* Copy and then store the results in the destination buffer */
+ *pDst++ = *pSrc++;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+}
+
+/**
+ * @} end of BasicCopy group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_f32.c
new file mode 100644
index 0000000..a284f88
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_f32.c
@@ -0,0 +1,134 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_fill_f32.c
+*
+* Description: Fills a constant value into a floating-point vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @defgroup Fill Vector Fill
+ *
+ * Fills the destination vector with a constant value.
+ *
+ *
+ * pDst[n] = value; 0 <= n < blockSize.
+ *
+ *
+ * There are separate functions for floating point, Q31, Q15, and Q7 data types.
+ */
+
+/**
+ * @addtogroup Fill
+ * @{
+ */
+
+/**
+ * @brief Fills a constant value into a floating-point vector.
+ * @param[in] value input value to be filled
+ * @param[out] *pDst points to output vector
+ * @param[in] blockSize length of the output vector
+ * @return none.
+ *
+ */
+
+
+void arm_fill_f32(
+ float32_t value,
+ float32_t * pDst,
+ uint32_t blockSize)
+{
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ float32_t in1 = value;
+ float32_t in2 = value;
+ float32_t in3 = value;
+ float32_t in4 = value;
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = value */
+ /* Fill the value in the destination buffer */
+ *pDst++ = in1;
+ *pDst++ = in2;
+ *pDst++ = in3;
+ *pDst++ = in4;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+
+ while(blkCnt > 0u)
+ {
+ /* C = value */
+ /* Fill the value in the destination buffer */
+ *pDst++ = value;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+}
+
+/**
+ * @} end of Fill group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_q15.c
new file mode 100644
index 0000000..817b127
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_q15.c
@@ -0,0 +1,120 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_fill_q15.c
+*
+* Description: Fills a constant value into a Q15 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @addtogroup Fill
+ * @{
+ */
+
+/**
+ * @brief Fills a constant value into a Q15 vector.
+ * @param[in] value input value to be filled
+ * @param[out] *pDst points to output vector
+ * @param[in] blockSize length of the output vector
+ * @return none.
+ *
+ */
+
+void arm_fill_q15(
+ q15_t value,
+ q15_t * pDst,
+ uint32_t blockSize)
+{
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ q31_t packedValue; /* value packed to 32 bits */
+
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* Packing two 16 bit values to 32 bit value in order to use SIMD */
+ packedValue = __PKHBT(value, value, 16u);
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = value */
+ /* Fill the value in the destination buffer */
+ *__SIMD32(pDst)++ = packedValue;
+ *__SIMD32(pDst)++ = packedValue;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = value */
+ /* Fill the value in the destination buffer */
+ *pDst++ = value;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+}
+
+/**
+ * @} end of Fill group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_q31.c
new file mode 100644
index 0000000..0b773c9
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_q31.c
@@ -0,0 +1,121 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_fill_q31.c
+*
+* Description: Fills a constant value into a Q31 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @addtogroup Fill
+ * @{
+ */
+
+/**
+ * @brief Fills a constant value into a Q31 vector.
+ * @param[in] value input value to be filled
+ * @param[out] *pDst points to output vector
+ * @param[in] blockSize length of the output vector
+ * @return none.
+ *
+ */
+
+void arm_fill_q31(
+ q31_t value,
+ q31_t * pDst,
+ uint32_t blockSize)
+{
+ uint32_t blkCnt; /* loop counter */
+
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ q31_t in1 = value;
+ q31_t in2 = value;
+ q31_t in3 = value;
+ q31_t in4 = value;
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = value */
+ /* Fill the value in the destination buffer */
+ *pDst++ = in1;
+ *pDst++ = in2;
+ *pDst++ = in3;
+ *pDst++ = in4;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = value */
+ /* Fill the value in the destination buffer */
+ *pDst++ = value;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+}
+
+/**
+ * @} end of Fill group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_q7.c
new file mode 100644
index 0000000..0dde606
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_fill_q7.c
@@ -0,0 +1,118 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_fill_q7.c
+*
+* Description: Fills a constant value into a Q7 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @addtogroup Fill
+ * @{
+ */
+
+/**
+ * @brief Fills a constant value into a Q7 vector.
+ * @param[in] value input value to be filled
+ * @param[out] *pDst points to output vector
+ * @param[in] blockSize length of the output vector
+ * @return none.
+ *
+ */
+
+void arm_fill_q7(
+ q7_t value,
+ q7_t * pDst,
+ uint32_t blockSize)
+{
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ q31_t packedValue; /* value packed to 32 bits */
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* Packing four 8 bit values to 32 bit value in order to use SIMD */
+ packedValue = __PACKq7(value, value, value, value);
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = value */
+ /* Fill the value in the destination buffer */
+ *__SIMD32(pDst)++ = packedValue;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = value */
+ /* Fill the value in the destination buffer */
+ *pDst++ = value;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+}
+
+/**
+ * @} end of Fill group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_float_to_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_float_to_q15.c
new file mode 100644
index 0000000..cdc53a5
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_float_to_q15.c
@@ -0,0 +1,204 @@
+/* ----------------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_float_to_q15.c
+*
+* Description: Converts the elements of the floating-point vector to Q15 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @addtogroup float_to_x
+ * @{
+ */
+
+/**
+ * @brief Converts the elements of the floating-point vector to Q15 vector.
+ * @param[in] *pSrc points to the floating-point input vector
+ * @param[out] *pDst points to the Q15 output vector
+ * @param[in] blockSize length of the input vector
+ * @return none.
+ *
+ * \par Description:
+ * \par
+ * The equation used for the conversion process is:
+ *
+ * pDst[n] = (q15_t)(pSrc[n] * 32768); 0 <= n < blockSize.
+ *
+ * \par Scaling and Overflow Behavior:
+ * \par
+ * The function uses saturating arithmetic.
+ * Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
+ * \note
+ * In order to apply rounding, the library should be rebuilt with the ROUNDING macro
+ * defined in the preprocessor section of project options.
+ *
+ */
+
+
+void arm_float_to_q15(
+ float32_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize)
+{
+ float32_t *pIn = pSrc; /* Src pointer */
+ uint32_t blkCnt; /* loop counter */
+
+#ifdef ARM_MATH_ROUNDING
+
+ float32_t in;
+
+#endif /* #ifdef ARM_MATH_ROUNDING */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+
+#ifdef ARM_MATH_ROUNDING
+ /* C = A * 32768 */
+ /* convert from float to q15 and then store the results in the destination buffer */
+ in = *pIn++;
+ in = (in * 32768.0f);
+ in += in > 0.0f ? 0.5f : -0.5f;
+ *pDst++ = (q15_t) (__SSAT((q31_t) (in), 16));
+
+ in = *pIn++;
+ in = (in * 32768.0f);
+ in += in > 0.0f ? 0.5f : -0.5f;
+ *pDst++ = (q15_t) (__SSAT((q31_t) (in), 16));
+
+ in = *pIn++;
+ in = (in * 32768.0f);
+ in += in > 0.0f ? 0.5f : -0.5f;
+ *pDst++ = (q15_t) (__SSAT((q31_t) (in), 16));
+
+ in = *pIn++;
+ in = (in * 32768.0f);
+ in += in > 0.0f ? 0.5f : -0.5f;
+ *pDst++ = (q15_t) (__SSAT((q31_t) (in), 16));
+
+#else
+
+ /* C = A * 32768 */
+ /* convert from float to q15 and then store the results in the destination buffer */
+ *pDst++ = (q15_t) __SSAT((q31_t) (*pIn++ * 32768.0f), 16);
+ *pDst++ = (q15_t) __SSAT((q31_t) (*pIn++ * 32768.0f), 16);
+ *pDst++ = (q15_t) __SSAT((q31_t) (*pIn++ * 32768.0f), 16);
+ *pDst++ = (q15_t) __SSAT((q31_t) (*pIn++ * 32768.0f), 16);
+
+#endif /* #ifdef ARM_MATH_ROUNDING */
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+ while(blkCnt > 0u)
+ {
+
+#ifdef ARM_MATH_ROUNDING
+ /* C = A * 32768 */
+ /* convert from float to q15 and then store the results in the destination buffer */
+ in = *pIn++;
+ in = (in * 32768.0f);
+ in += in > 0.0f ? 0.5f : -0.5f;
+ *pDst++ = (q15_t) (__SSAT((q31_t) (in), 16));
+
+#else
+
+ /* C = A * 32768 */
+ /* convert from float to q15 and then store the results in the destination buffer */
+ *pDst++ = (q15_t) __SSAT((q31_t) (*pIn++ * 32768.0f), 16);
+
+#endif /* #ifdef ARM_MATH_ROUNDING */
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+ while(blkCnt > 0u)
+ {
+
+#ifdef ARM_MATH_ROUNDING
+ /* C = A * 32768 */
+ /* convert from float to q15 and then store the results in the destination buffer */
+ in = *pIn++;
+ in = (in * 32768.0f);
+ in += in > 0 ? 0.5f : -0.5f;
+ *pDst++ = (q15_t) (__SSAT((q31_t) (in), 16));
+
+#else
+
+ /* C = A * 32768 */
+ /* convert from float to q15 and then store the results in the destination buffer */
+ *pDst++ = (q15_t) __SSAT((q31_t) (*pIn++ * 32768.0f), 16);
+
+#endif /* #ifdef ARM_MATH_ROUNDING */
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+}
+
+/**
+ * @} end of float_to_x group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_float_to_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_float_to_q31.c
new file mode 100644
index 0000000..a2bf3f5
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_float_to_q31.c
@@ -0,0 +1,211 @@
+/* ----------------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_float_to_q31.c
+*
+* Description: Converts the elements of the floating-point vector to Q31 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @defgroup float_to_x Convert 32-bit floating point value
+ */
+
+/**
+ * @addtogroup float_to_x
+ * @{
+ */
+
+/**
+ * @brief Converts the elements of the floating-point vector to Q31 vector.
+ * @param[in] *pSrc points to the floating-point input vector
+ * @param[out] *pDst points to the Q31 output vector
+ * @param[in] blockSize length of the input vector
+ * @return none.
+ *
+ *\par Description:
+ * \par
+ * The equation used for the conversion process is:
+ *
+ *
+ * pDst[n] = (q31_t)(pSrc[n] * 2147483648); 0 <= n < blockSize.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function uses saturating arithmetic.
+ * Results outside of the allowable Q31 range[0x80000000 0x7FFFFFFF] will be saturated.
+ *
+ * \note In order to apply rounding, the library should be rebuilt with the ROUNDING macro
+ * defined in the preprocessor section of project options.
+ */
+
+
+void arm_float_to_q31(
+ float32_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize)
+{
+ float32_t *pIn = pSrc; /* Src pointer */
+ uint32_t blkCnt; /* loop counter */
+
+#ifdef ARM_MATH_ROUNDING
+
+ float32_t in;
+
+#endif /* #ifdef ARM_MATH_ROUNDING */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+
+#ifdef ARM_MATH_ROUNDING
+
+ /* C = A * 32768 */
+ /* convert from float to Q31 and then store the results in the destination buffer */
+ in = *pIn++;
+ in = (in * 2147483648.0f);
+ in += in > 0.0f ? 0.5f : -0.5f;
+ *pDst++ = clip_q63_to_q31((q63_t) (in));
+
+ in = *pIn++;
+ in = (in * 2147483648.0f);
+ in += in > 0.0f ? 0.5f : -0.5f;
+ *pDst++ = clip_q63_to_q31((q63_t) (in));
+
+ in = *pIn++;
+ in = (in * 2147483648.0f);
+ in += in > 0.0f ? 0.5f : -0.5f;
+ *pDst++ = clip_q63_to_q31((q63_t) (in));
+
+ in = *pIn++;
+ in = (in * 2147483648.0f);
+ in += in > 0.0f ? 0.5f : -0.5f;
+ *pDst++ = clip_q63_to_q31((q63_t) (in));
+
+#else
+
+ /* C = A * 2147483648 */
+ /* convert from float to Q31 and then store the results in the destination buffer */
+ *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0f));
+ *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0f));
+ *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0f));
+ *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0f));
+
+#endif /* #ifdef ARM_MATH_ROUNDING */
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+ while(blkCnt > 0u)
+ {
+
+#ifdef ARM_MATH_ROUNDING
+
+ /* C = A * 2147483648 */
+ /* convert from float to Q31 and then store the results in the destination buffer */
+ in = *pIn++;
+ in = (in * 2147483648.0f);
+ in += in > 0.0f ? 0.5f : -0.5f;
+ *pDst++ = clip_q63_to_q31((q63_t) (in));
+
+#else
+
+ /* C = A * 2147483648 */
+ /* convert from float to Q31 and then store the results in the destination buffer */
+ *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0f));
+
+#endif /* #ifdef ARM_MATH_ROUNDING */
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+ while(blkCnt > 0u)
+ {
+
+#ifdef ARM_MATH_ROUNDING
+
+ /* C = A * 2147483648 */
+ /* convert from float to Q31 and then store the results in the destination buffer */
+ in = *pIn++;
+ in = (in * 2147483648.0f);
+ in += in > 0 ? 0.5f : -0.5f;
+ *pDst++ = clip_q63_to_q31((q63_t) (in));
+
+#else
+
+ /* C = A * 2147483648 */
+ /* convert from float to Q31 and then store the results in the destination buffer */
+ *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0f));
+
+#endif /* #ifdef ARM_MATH_ROUNDING */
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+}
+
+/**
+ * @} end of float_to_x group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_float_to_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_float_to_q7.c
new file mode 100644
index 0000000..0497e2b
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_float_to_q7.c
@@ -0,0 +1,203 @@
+/* ----------------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_float_to_q7.c
+*
+* Description: Converts the elements of the floating-point vector to Q7 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @addtogroup float_to_x
+ * @{
+ */
+
+/**
+ * @brief Converts the elements of the floating-point vector to Q7 vector.
+ * @param[in] *pSrc points to the floating-point input vector
+ * @param[out] *pDst points to the Q7 output vector
+ * @param[in] blockSize length of the input vector
+ * @return none.
+ *
+ *\par Description:
+ * \par
+ * The equation used for the conversion process is:
+ *
+ * pDst[n] = (q7_t)(pSrc[n] * 128); 0 <= n < blockSize.
+ *
+ * \par Scaling and Overflow Behavior:
+ * \par
+ * The function uses saturating arithmetic.
+ * Results outside of the allowable Q7 range [0x80 0x7F] will be saturated.
+ * \note
+ * In order to apply rounding, the library should be rebuilt with the ROUNDING macro
+ * defined in the preprocessor section of project options.
+ */
+
+
+void arm_float_to_q7(
+ float32_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize)
+{
+ float32_t *pIn = pSrc; /* Src pointer */
+ uint32_t blkCnt; /* loop counter */
+
+#ifdef ARM_MATH_ROUNDING
+
+ float32_t in;
+
+#endif /* #ifdef ARM_MATH_ROUNDING */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+
+#ifdef ARM_MATH_ROUNDING
+ /* C = A * 128 */
+ /* convert from float to q7 and then store the results in the destination buffer */
+ in = *pIn++;
+ in = (in * 128);
+ in += in > 0.0f ? 0.5f : -0.5f;
+ *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8));
+
+ in = *pIn++;
+ in = (in * 128);
+ in += in > 0.0f ? 0.5f : -0.5f;
+ *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8));
+
+ in = *pIn++;
+ in = (in * 128);
+ in += in > 0.0f ? 0.5f : -0.5f;
+ *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8));
+
+ in = *pIn++;
+ in = (in * 128);
+ in += in > 0.0f ? 0.5f : -0.5f;
+ *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8));
+
+#else
+
+ /* C = A * 128 */
+ /* convert from float to q7 and then store the results in the destination buffer */
+ *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8);
+ *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8);
+ *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8);
+ *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8);
+
+#endif /* #ifdef ARM_MATH_ROUNDING */
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+ while(blkCnt > 0u)
+ {
+
+#ifdef ARM_MATH_ROUNDING
+ /* C = A * 128 */
+ /* convert from float to q7 and then store the results in the destination buffer */
+ in = *pIn++;
+ in = (in * 128);
+ in += in > 0.0f ? 0.5f : -0.5f;
+ *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8));
+
+#else
+
+ /* C = A * 128 */
+ /* convert from float to q7 and then store the results in the destination buffer */
+ *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8);
+
+#endif /* #ifdef ARM_MATH_ROUNDING */
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+ while(blkCnt > 0u)
+ {
+#ifdef ARM_MATH_ROUNDING
+ /* C = A * 128 */
+ /* convert from float to q7 and then store the results in the destination buffer */
+ in = *pIn++;
+ in = (in * 128.0f);
+ in += in > 0 ? 0.5f : -0.5f;
+ *pDst++ = (q7_t) (__SSAT((q31_t) (in), 8));
+
+#else
+
+ /* C = A * 128 */
+ /* convert from float to q7 and then store the results in the destination buffer */
+ *pDst++ = (q7_t) __SSAT((q31_t) (*pIn++ * 128.0f), 8);
+
+#endif /* #ifdef ARM_MATH_ROUNDING */
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+}
+
+/**
+ * @} end of float_to_x group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q15_to_float.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q15_to_float.c
new file mode 100644
index 0000000..2e9624a
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q15_to_float.c
@@ -0,0 +1,134 @@
+/* ----------------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_q15_to_float.c
+*
+* Description: Converts the elements of the Q15 vector to floating-point vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @defgroup q15_to_x Convert 16-bit Integer value
+ */
+
+/**
+ * @addtogroup q15_to_x
+ * @{
+ */
+
+
+
+
+/**
+ * @brief Converts the elements of the Q15 vector to floating-point vector.
+ * @param[in] *pSrc points to the Q15 input vector
+ * @param[out] *pDst points to the floating-point output vector
+ * @param[in] blockSize length of the input vector
+ * @return none.
+ *
+ * \par Description:
+ *
+ * The equation used for the conversion process is:
+ *
+ *
+ * pDst[n] = (float32_t) pSrc[n] / 32768; 0 <= n < blockSize.
+ *
+ *
+ */
+
+
+void arm_q15_to_float(
+ q15_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize)
+{
+ q15_t *pIn = pSrc; /* Src pointer */
+ uint32_t blkCnt; /* loop counter */
+
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (float32_t) A / 32768 */
+ /* convert from q15 to float and then store the results in the destination buffer */
+ *pDst++ = ((float32_t) * pIn++ / 32768.0f);
+ *pDst++ = ((float32_t) * pIn++ / 32768.0f);
+ *pDst++ = ((float32_t) * pIn++ / 32768.0f);
+ *pDst++ = ((float32_t) * pIn++ / 32768.0f);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = (float32_t) A / 32768 */
+ /* convert from q15 to float and then store the results in the destination buffer */
+ *pDst++ = ((float32_t) * pIn++ / 32768.0f);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+}
+
+/**
+ * @} end of q15_to_x group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q15_to_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q15_to_q31.c
new file mode 100644
index 0000000..5a34279
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q15_to_q31.c
@@ -0,0 +1,156 @@
+/* ----------------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_q15_to_q31.c
+*
+* Description: Converts the elements of the Q15 vector to Q31 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @addtogroup q15_to_x
+ * @{
+ */
+
+/**
+ * @brief Converts the elements of the Q15 vector to Q31 vector.
+ * @param[in] *pSrc points to the Q15 input vector
+ * @param[out] *pDst points to the Q31 output vector
+ * @param[in] blockSize length of the input vector
+ * @return none.
+ *
+ * \par Description:
+ *
+ * The equation used for the conversion process is:
+ *
+ *
+ * pDst[n] = (q31_t) pSrc[n] << 16; 0 <= n < blockSize.
+ *
+ *
+ */
+
+
+void arm_q15_to_q31(
+ q15_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize)
+{
+ q15_t *pIn = pSrc; /* Src pointer */
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ q31_t in1, in2;
+ q31_t out1, out2, out3, out4;
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (q31_t)A << 16 */
+ /* convert from q15 to q31 and then store the results in the destination buffer */
+ in1 = *__SIMD32(pIn)++;
+ in2 = *__SIMD32(pIn)++;
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ /* extract lower 16 bits to 32 bit result */
+ out1 = in1 << 16u;
+ /* extract upper 16 bits to 32 bit result */
+ out2 = in1 & 0xFFFF0000;
+ /* extract lower 16 bits to 32 bit result */
+ out3 = in2 << 16u;
+ /* extract upper 16 bits to 32 bit result */
+ out4 = in2 & 0xFFFF0000;
+
+#else
+
+ /* extract upper 16 bits to 32 bit result */
+ out1 = in1 & 0xFFFF0000;
+ /* extract lower 16 bits to 32 bit result */
+ out2 = in1 << 16u;
+ /* extract upper 16 bits to 32 bit result */
+ out3 = in2 & 0xFFFF0000;
+ /* extract lower 16 bits to 32 bit result */
+ out4 = in2 << 16u;
+
+#endif // #ifndef ARM_MATH_BIG_ENDIAN
+
+ *pDst++ = out1;
+ *pDst++ = out2;
+ *pDst++ = out3;
+ *pDst++ = out4;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = (q31_t)A << 16 */
+ /* convert from q15 to q31 and then store the results in the destination buffer */
+ *pDst++ = (q31_t) * pIn++ << 16;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+}
+
+/**
+ * @} end of q15_to_x group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q15_to_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q15_to_q7.c
new file mode 100644
index 0000000..9b029a0
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q15_to_q7.c
@@ -0,0 +1,154 @@
+/* ----------------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_q15_to_q7.c
+*
+* Description: Converts the elements of the Q15 vector to Q7 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @addtogroup q15_to_x
+ * @{
+ */
+
+
+/**
+ * @brief Converts the elements of the Q15 vector to Q7 vector.
+ * @param[in] *pSrc points to the Q15 input vector
+ * @param[out] *pDst points to the Q7 output vector
+ * @param[in] blockSize length of the input vector
+ * @return none.
+ *
+ * \par Description:
+ *
+ * The equation used for the conversion process is:
+ *
+ *
+ * pDst[n] = (q7_t) pSrc[n] >> 8; 0 <= n < blockSize.
+ *
+ *
+ */
+
+
+void arm_q15_to_q7(
+ q15_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize)
+{
+ q15_t *pIn = pSrc; /* Src pointer */
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ q31_t in1, in2;
+ q31_t out1, out2;
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (q7_t) A >> 8 */
+ /* convert from q15 to q7 and then store the results in the destination buffer */
+ in1 = *__SIMD32(pIn)++;
+ in2 = *__SIMD32(pIn)++;
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ out1 = __PKHTB(in2, in1, 16);
+ out2 = __PKHBT(in2, in1, 16);
+
+#else
+
+ out1 = __PKHTB(in1, in2, 16);
+ out2 = __PKHBT(in1, in2, 16);
+
+#endif // #ifndef ARM_MATH_BIG_ENDIAN
+
+ /* rotate packed value by 24 */
+ out2 = ((uint32_t) out2 << 8) | ((uint32_t) out2 >> 24);
+
+ /* anding with 0xff00ff00 to get two 8 bit values */
+ out1 = out1 & 0xFF00FF00;
+ /* anding with 0x00ff00ff to get two 8 bit values */
+ out2 = out2 & 0x00FF00FF;
+
+ /* oring two values(contains two 8 bit values) to get four packed 8 bit values */
+ out1 = out1 | out2;
+
+ /* store 4 samples at a time to destiantion buffer */
+ *__SIMD32(pDst)++ = out1;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = (q7_t) A >> 8 */
+ /* convert from q15 to q7 and then store the results in the destination buffer */
+ *pDst++ = (q7_t) (*pIn++ >> 8);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+}
+
+/**
+ * @} end of q15_to_x group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q31_to_float.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q31_to_float.c
new file mode 100644
index 0000000..4ea5c26
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q31_to_float.c
@@ -0,0 +1,131 @@
+/* ----------------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_q31_to_float.c
+*
+* Description: Converts the elements of the Q31 vector to floating-point vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @defgroup q31_to_x Convert 32-bit Integer value
+ */
+
+/**
+ * @addtogroup q31_to_x
+ * @{
+ */
+
+/**
+ * @brief Converts the elements of the Q31 vector to floating-point vector.
+ * @param[in] *pSrc points to the Q31 input vector
+ * @param[out] *pDst points to the floating-point output vector
+ * @param[in] blockSize length of the input vector
+ * @return none.
+ *
+ * \par Description:
+ *
+ * The equation used for the conversion process is:
+ *
+ *
+ * pDst[n] = (float32_t) pSrc[n] / 2147483648; 0 <= n < blockSize.
+ *
+ *
+ */
+
+
+void arm_q31_to_float(
+ q31_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize)
+{
+ q31_t *pIn = pSrc; /* Src pointer */
+ uint32_t blkCnt; /* loop counter */
+
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (float32_t) A / 2147483648 */
+ /* convert from q31 to float and then store the results in the destination buffer */
+ *pDst++ = ((float32_t) * pIn++ / 2147483648.0f);
+ *pDst++ = ((float32_t) * pIn++ / 2147483648.0f);
+ *pDst++ = ((float32_t) * pIn++ / 2147483648.0f);
+ *pDst++ = ((float32_t) * pIn++ / 2147483648.0f);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = (float32_t) A / 2147483648 */
+ /* convert from q31 to float and then store the results in the destination buffer */
+ *pDst++ = ((float32_t) * pIn++ / 2147483648.0f);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+}
+
+/**
+ * @} end of q31_to_x group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q31_to_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q31_to_q15.c
new file mode 100644
index 0000000..053c6ba
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q31_to_q15.c
@@ -0,0 +1,145 @@
+/* ----------------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_q31_to_q15.c
+*
+* Description: Converts the elements of the Q31 vector to Q15 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @addtogroup q31_to_x
+ * @{
+ */
+
+/**
+ * @brief Converts the elements of the Q31 vector to Q15 vector.
+ * @param[in] *pSrc points to the Q31 input vector
+ * @param[out] *pDst points to the Q15 output vector
+ * @param[in] blockSize length of the input vector
+ * @return none.
+ *
+ * \par Description:
+ *
+ * The equation used for the conversion process is:
+ *
+ *
+ * pDst[n] = (q15_t) pSrc[n] >> 16; 0 <= n < blockSize.
+ *
+ *
+ */
+
+
+void arm_q31_to_q15(
+ q31_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize)
+{
+ q31_t *pIn = pSrc; /* Src pointer */
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ q31_t in1, in2, in3, in4;
+ q31_t out1, out2;
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (q15_t) A >> 16 */
+ /* convert from q31 to q15 and then store the results in the destination buffer */
+ in1 = *pIn++;
+ in2 = *pIn++;
+ in3 = *pIn++;
+ in4 = *pIn++;
+
+ /* pack two higher 16-bit values from two 32-bit values */
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ out1 = __PKHTB(in2, in1, 16);
+ out2 = __PKHTB(in4, in3, 16);
+
+#else
+
+ out1 = __PKHTB(in1, in2, 16);
+ out2 = __PKHTB(in3, in4, 16);
+
+#endif // #ifdef ARM_MATH_BIG_ENDIAN
+
+ *__SIMD32(pDst)++ = out1;
+ *__SIMD32(pDst)++ = out2;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = (q15_t) A >> 16 */
+ /* convert from q31 to q15 and then store the results in the destination buffer */
+ *pDst++ = (q15_t) (*pIn++ >> 16);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+}
+
+/**
+ * @} end of q31_to_x group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q31_to_q7.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q31_to_q7.c
new file mode 100644
index 0000000..26bfd32
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q31_to_q7.c
@@ -0,0 +1,136 @@
+/* ----------------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_q31_to_q7.c
+*
+* Description: Converts the elements of the Q31 vector to Q7 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @addtogroup q31_to_x
+ * @{
+ */
+
+/**
+ * @brief Converts the elements of the Q31 vector to Q7 vector.
+ * @param[in] *pSrc points to the Q31 input vector
+ * @param[out] *pDst points to the Q7 output vector
+ * @param[in] blockSize length of the input vector
+ * @return none.
+ *
+ * \par Description:
+ *
+ * The equation used for the conversion process is:
+ *
+ *
+ * pDst[n] = (q7_t) pSrc[n] >> 24; 0 <= n < blockSize.
+ *
+ *
+ */
+
+
+void arm_q31_to_q7(
+ q31_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize)
+{
+ q31_t *pIn = pSrc; /* Src pointer */
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ q31_t in1, in2, in3, in4;
+ q7_t out1, out2, out3, out4;
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (q7_t) A >> 24 */
+ /* convert from q31 to q7 and then store the results in the destination buffer */
+ in1 = *pIn++;
+ in2 = *pIn++;
+ in3 = *pIn++;
+ in4 = *pIn++;
+
+ out1 = (q7_t) (in1 >> 24);
+ out2 = (q7_t) (in2 >> 24);
+ out3 = (q7_t) (in3 >> 24);
+ out4 = (q7_t) (in4 >> 24);
+
+ *__SIMD32(pDst)++ = __PACKq7(out1, out2, out3, out4);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = (q7_t) A >> 24 */
+ /* convert from q31 to q7 and then store the results in the destination buffer */
+ *pDst++ = (q7_t) (*pIn++ >> 24);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+}
+
+/**
+ * @} end of q31_to_x group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q7_to_float.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q7_to_float.c
new file mode 100644
index 0000000..c9dff9c
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q7_to_float.c
@@ -0,0 +1,131 @@
+/* ----------------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_q7_to_float.c
+*
+* Description: Converts the elements of the Q7 vector to floating-point vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @defgroup q7_to_x Convert 8-bit Integer value
+ */
+
+/**
+ * @addtogroup q7_to_x
+ * @{
+ */
+
+/**
+ * @brief Converts the elements of the Q7 vector to floating-point vector.
+ * @param[in] *pSrc points to the Q7 input vector
+ * @param[out] *pDst points to the floating-point output vector
+ * @param[in] blockSize length of the input vector
+ * @return none.
+ *
+ * \par Description:
+ *
+ * The equation used for the conversion process is:
+ *
+ *
+ * pDst[n] = (float32_t) pSrc[n] / 128; 0 <= n < blockSize.
+ *
+ *
+ */
+
+
+void arm_q7_to_float(
+ q7_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize)
+{
+ q7_t *pIn = pSrc; /* Src pointer */
+ uint32_t blkCnt; /* loop counter */
+
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (float32_t) A / 128 */
+ /* convert from q7 to float and then store the results in the destination buffer */
+ *pDst++ = ((float32_t) * pIn++ / 128.0f);
+ *pDst++ = ((float32_t) * pIn++ / 128.0f);
+ *pDst++ = ((float32_t) * pIn++ / 128.0f);
+ *pDst++ = ((float32_t) * pIn++ / 128.0f);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = (float32_t) A / 128 */
+ /* convert from q7 to float and then store the results in the destination buffer */
+ *pDst++ = ((float32_t) * pIn++ / 128.0f);
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+}
+
+/**
+ * @} end of q7_to_x group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q7_to_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q7_to_q15.c
new file mode 100644
index 0000000..5b93546
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q7_to_q15.c
@@ -0,0 +1,157 @@
+/* ----------------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_q7_to_q15.c
+*
+* Description: Converts the elements of the Q7 vector to Q15 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @addtogroup q7_to_x
+ * @{
+ */
+
+
+
+
+/**
+ * @brief Converts the elements of the Q7 vector to Q15 vector.
+ * @param[in] *pSrc points to the Q7 input vector
+ * @param[out] *pDst points to the Q15 output vector
+ * @param[in] blockSize length of the input vector
+ * @return none.
+ *
+ * \par Description:
+ *
+ * The equation used for the conversion process is:
+ *
+ *
+ * pDst[n] = (q15_t) pSrc[n] << 8; 0 <= n < blockSize.
+ *
+ *
+ */
+
+
+void arm_q7_to_q15(
+ q7_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize)
+{
+ q7_t *pIn = pSrc; /* Src pointer */
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+ q31_t in;
+ q31_t in1, in2;
+ q31_t out1, out2;
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (q15_t) A << 8 */
+ /* convert from q7 to q15 and then store the results in the destination buffer */
+ in = *__SIMD32(pIn)++;
+
+ /* rotatate in by 8 and extend two q7_t values to q15_t values */
+ in1 = __SXTB16(__ROR(in, 8));
+
+ /* extend remainig two q7_t values to q15_t values */
+ in2 = __SXTB16(in);
+
+ in1 = in1 << 8u;
+ in2 = in2 << 8u;
+
+ in1 = in1 & 0xFF00FF00;
+ in2 = in2 & 0xFF00FF00;
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ out2 = __PKHTB(in1, in2, 16);
+ out1 = __PKHBT(in2, in1, 16);
+
+#else
+
+ out1 = __PKHTB(in1, in2, 16);
+ out2 = __PKHBT(in2, in1, 16);
+
+#endif
+
+ *__SIMD32(pDst)++ = out1;
+ *__SIMD32(pDst)++ = out2;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = (q15_t) A << 8 */
+ /* convert from q7 to q15 and then store the results in the destination buffer */
+ *pDst++ = (q15_t) * pIn++ << 8;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+}
+
+/**
+ * @} end of q7_to_x group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q7_to_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q7_to_q31.c
new file mode 100644
index 0000000..84e47a3
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/SupportFunctions/arm_q7_to_q31.c
@@ -0,0 +1,142 @@
+/* ----------------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_q7_to_q31.c
+*
+* Description: Converts the elements of the Q7 vector to Q31 vector.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupSupport
+ */
+
+/**
+ * @addtogroup q7_to_x
+ * @{
+ */
+
+/**
+ * @brief Converts the elements of the Q7 vector to Q31 vector.
+ * @param[in] *pSrc points to the Q7 input vector
+ * @param[out] *pDst points to the Q31 output vector
+ * @param[in] blockSize length of the input vector
+ * @return none.
+ *
+ * \par Description:
+ *
+ * The equation used for the conversion process is:
+ *
+ *
+ * pDst[n] = (q31_t) pSrc[n] << 24; 0 <= n < blockSize.
+ *
+ *
+ */
+
+
+void arm_q7_to_q31(
+ q7_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize)
+{
+ q7_t *pIn = pSrc; /* Src pointer */
+ uint32_t blkCnt; /* loop counter */
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ q31_t in;
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /*loop Unrolling */
+ blkCnt = blockSize >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ while(blkCnt > 0u)
+ {
+ /* C = (q31_t) A << 24 */
+ /* convert from q7 to q31 and then store the results in the destination buffer */
+ in = *__SIMD32(pIn)++;
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ *pDst++ = (__ROR(in, 8)) & 0xFF000000;
+ *pDst++ = (__ROR(in, 16)) & 0xFF000000;
+ *pDst++ = (__ROR(in, 24)) & 0xFF000000;
+ *pDst++ = (in & 0xFF000000);
+
+#else
+
+ *pDst++ = (in & 0xFF000000);
+ *pDst++ = (__ROR(in, 24)) & 0xFF000000;
+ *pDst++ = (__ROR(in, 16)) & 0xFF000000;
+ *pDst++ = (__ROR(in, 8)) & 0xFF000000;
+
+#endif // #ifndef ARM_MATH_BIG_ENDIAN
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ blkCnt = blockSize % 0x4u;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Loop over blockSize number of values */
+ blkCnt = blockSize;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+ while(blkCnt > 0u)
+ {
+ /* C = (q31_t) A << 24 */
+ /* convert from q7 to q31 and then store the results in the destination buffer */
+ *pDst++ = (q31_t) * pIn++ << 24;
+
+ /* Decrement the loop counter */
+ blkCnt--;
+ }
+
+}
+
+/**
+ * @} end of q7_to_x group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_bitreversal.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_bitreversal.c
new file mode 100644
index 0000000..dc62e63
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_bitreversal.c
@@ -0,0 +1,242 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_bitreversal.c
+*
+* Description: This file has common tables like Bitreverse, reciprocal etc which are used across different functions
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+#include "arm_common_tables.h"
+
+/*
+* @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)
+{
+ uint16_t fftLenBy2, fftLenBy2p1;
+ uint16_t i, j;
+ float32_t in;
+
+ /* Initializations */
+ j = 0u;
+ fftLenBy2 = fftSize >> 1u;
+ fftLenBy2p1 = (fftSize >> 1u) + 1u;
+
+ /* Bit Reversal Implementation */
+ for (i = 0u; i <= (fftLenBy2 - 2u); i += 2u)
+ {
+ if(i < j)
+ {
+ /* pSrc[i] <-> pSrc[j]; */
+ in = pSrc[2u * i];
+ pSrc[2u * i] = pSrc[2u * j];
+ pSrc[2u * j] = in;
+
+ /* pSrc[i+1u] <-> pSrc[j+1u] */
+ in = pSrc[(2u * i) + 1u];
+ pSrc[(2u * i) + 1u] = pSrc[(2u * j) + 1u];
+ pSrc[(2u * j) + 1u] = in;
+
+ /* pSrc[i+fftLenBy2p1] <-> pSrc[j+fftLenBy2p1] */
+ in = pSrc[2u * (i + fftLenBy2p1)];
+ pSrc[2u * (i + fftLenBy2p1)] = pSrc[2u * (j + fftLenBy2p1)];
+ pSrc[2u * (j + fftLenBy2p1)] = in;
+
+ /* pSrc[i+fftLenBy2p1+1u] <-> pSrc[j+fftLenBy2p1+1u] */
+ in = pSrc[(2u * (i + fftLenBy2p1)) + 1u];
+ pSrc[(2u * (i + fftLenBy2p1)) + 1u] =
+ pSrc[(2u * (j + fftLenBy2p1)) + 1u];
+ pSrc[(2u * (j + fftLenBy2p1)) + 1u] = in;
+
+ }
+
+ /* pSrc[i+1u] <-> pSrc[j+1u] */
+ in = pSrc[2u * (i + 1u)];
+ pSrc[2u * (i + 1u)] = pSrc[2u * (j + fftLenBy2)];
+ pSrc[2u * (j + fftLenBy2)] = in;
+
+ /* pSrc[i+2u] <-> pSrc[j+2u] */
+ in = pSrc[(2u * (i + 1u)) + 1u];
+ pSrc[(2u * (i + 1u)) + 1u] = pSrc[(2u * (j + fftLenBy2)) + 1u];
+ pSrc[(2u * (j + fftLenBy2)) + 1u] = in;
+
+ /* Reading the index for the bit reversal */
+ j = *pBitRevTab;
+
+ /* Updating the bit reversal index depending on the fft length */
+ pBitRevTab += bitRevFactor;
+ }
+}
+
+
+
+/*
+* @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 * pBitRevTable)
+{
+ uint32_t fftLenBy2, fftLenBy2p1, i, j;
+ q31_t in;
+
+ /* Initializations */
+ j = 0u;
+ fftLenBy2 = fftLen / 2u;
+ fftLenBy2p1 = (fftLen / 2u) + 1u;
+
+ /* Bit Reversal Implementation */
+ for (i = 0u; i <= (fftLenBy2 - 2u); i += 2u)
+ {
+ if(i < j)
+ {
+ /* pSrc[i] <-> pSrc[j]; */
+ in = pSrc[2u * i];
+ pSrc[2u * i] = pSrc[2u * j];
+ pSrc[2u * j] = in;
+
+ /* pSrc[i+1u] <-> pSrc[j+1u] */
+ in = pSrc[(2u * i) + 1u];
+ pSrc[(2u * i) + 1u] = pSrc[(2u * j) + 1u];
+ pSrc[(2u * j) + 1u] = in;
+
+ /* pSrc[i+fftLenBy2p1] <-> pSrc[j+fftLenBy2p1] */
+ in = pSrc[2u * (i + fftLenBy2p1)];
+ pSrc[2u * (i + fftLenBy2p1)] = pSrc[2u * (j + fftLenBy2p1)];
+ pSrc[2u * (j + fftLenBy2p1)] = in;
+
+ /* pSrc[i+fftLenBy2p1+1u] <-> pSrc[j+fftLenBy2p1+1u] */
+ in = pSrc[(2u * (i + fftLenBy2p1)) + 1u];
+ pSrc[(2u * (i + fftLenBy2p1)) + 1u] =
+ pSrc[(2u * (j + fftLenBy2p1)) + 1u];
+ pSrc[(2u * (j + fftLenBy2p1)) + 1u] = in;
+
+ }
+
+ /* pSrc[i+1u] <-> pSrc[j+1u] */
+ in = pSrc[2u * (i + 1u)];
+ pSrc[2u * (i + 1u)] = pSrc[2u * (j + fftLenBy2)];
+ pSrc[2u * (j + fftLenBy2)] = in;
+
+ /* pSrc[i+2u] <-> pSrc[j+2u] */
+ in = pSrc[(2u * (i + 1u)) + 1u];
+ pSrc[(2u * (i + 1u)) + 1u] = pSrc[(2u * (j + fftLenBy2)) + 1u];
+ pSrc[(2u * (j + fftLenBy2)) + 1u] = in;
+
+ /* Reading the index for the bit reversal */
+ j = *pBitRevTable;
+
+ /* Updating the bit reversal index depending on the fft length */
+ pBitRevTable += bitRevFactor;
+ }
+}
+
+
+
+/*
+ * @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 * pSrc16,
+uint32_t fftLen,
+uint16_t bitRevFactor,
+uint16_t * pBitRevTab)
+{
+ q31_t *pSrc = (q31_t *) pSrc16;
+ q31_t in;
+ uint32_t fftLenBy2, fftLenBy2p1;
+ uint32_t i, j;
+
+ /* Initializations */
+ j = 0u;
+ fftLenBy2 = fftLen / 2u;
+ fftLenBy2p1 = (fftLen / 2u) + 1u;
+
+ /* Bit Reversal Implementation */
+ for (i = 0u; i <= (fftLenBy2 - 2u); i += 2u)
+ {
+ if(i < j)
+ {
+ /* pSrc[i] <-> pSrc[j]; */
+ /* pSrc[i+1u] <-> pSrc[j+1u] */
+ in = pSrc[i];
+ pSrc[i] = pSrc[j];
+ pSrc[j] = in;
+
+ /* pSrc[i + fftLenBy2p1] <-> pSrc[j + fftLenBy2p1]; */
+ /* pSrc[i + fftLenBy2p1+1u] <-> pSrc[j + fftLenBy2p1+1u] */
+ in = pSrc[i + fftLenBy2p1];
+ pSrc[i + fftLenBy2p1] = pSrc[j + fftLenBy2p1];
+ pSrc[j + fftLenBy2p1] = in;
+ }
+
+ /* pSrc[i+1u] <-> pSrc[j+fftLenBy2]; */
+ /* pSrc[i+2] <-> pSrc[j+fftLenBy2+1u] */
+ in = pSrc[i + 1u];
+ pSrc[i + 1u] = pSrc[j + fftLenBy2];
+ pSrc[j + fftLenBy2] = in;
+
+ /* Reading the index for the bit reversal */
+ j = *pBitRevTab;
+
+ /* Updating the bit reversal index depending on the fft length */
+ pBitRevTab += bitRevFactor;
+ }
+}
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_f32.c
new file mode 100644
index 0000000..c287bb9
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_f32.c
@@ -0,0 +1,632 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_cfft_f32.c
+*
+* Description: Combined Radix Decimation in Frequency CFFT Floating point processing function
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+#include "arm_common_tables.h"
+
+extern void arm_radix8_butterfly_f32(
+ float32_t * pSrc,
+ uint16_t fftLen,
+ const float32_t * pCoef,
+ uint16_t twidCoefModifier);
+
+extern void arm_bitreversal_32(
+ uint32_t * pSrc,
+ const uint16_t bitRevLen,
+ const uint16_t * pBitRevTable);
+
+/**
+* @ingroup groupTransforms
+*/
+
+/**
+* @defgroup ComplexFFT Complex FFT Functions
+*
+* \par
+* The Fast Fourier Transform (FFT) is an efficient algorithm for computing the
+* Discrete Fourier Transform (DFT). The FFT can be orders of magnitude faster
+* than the DFT, especially for long lengths.
+* The algorithms described in this section
+* operate on complex data. A separate set of functions is devoted to handling
+* of real sequences.
+* \par
+* There are separate algorithms for handling floating-point, Q15, and Q31 data
+* types. The algorithms available for each data type are described next.
+* \par
+* The FFT functions operate in-place. That is, the array holding the input data
+* will also be used to hold the corresponding result. The input data is complex
+* and contains 2*fftLen
interleaved values as shown below.
+* {real[0], imag[0], real[1], imag[1],..}
+* The FFT result will be contained in the same array and the frequency domain
+* values will have the same interleaving.
+*
+* \par Floating-point
+* The floating-point complex FFT uses a mixed-radix algorithm. Multiple radix-8
+* stages are performed along with a single radix-2 or radix-4 stage, as needed.
+* The algorithm supports lengths of [16, 32, 64, ..., 4096] and each length uses
+* a different twiddle factor table.
+* \par
+* The function uses the standard FFT definition and output values may grow by a
+* factor of fftLen
when computing the forward transform. The
+* inverse transform includes a scale of 1/fftLen
as part of the
+* calculation and this matches the textbook definition of the inverse FFT.
+* \par
+* Pre-initialized data structures containing twiddle factors and bit reversal
+* tables are provided and defined in arm_const_structs.h
. Include
+* this header in your function and then pass one of the constant structures as
+* an argument to arm_cfft_f32. For example:
+* \par
+* arm_cfft_f32(arm_cfft_sR_f32_len64, pSrc, 1, 1)
+* \par
+* computes a 64-point inverse complex FFT including bit reversal.
+* The data structures are treated as constant data and not modified during the
+* calculation. The same data structure can be reused for multiple transforms
+* including mixing forward and inverse transforms.
+* \par
+* Earlier releases of the library provided separate radix-2 and radix-4
+* algorithms that operated on floating-point data. These functions are still
+* provided but are deprecated. The older functions are slower and less general
+* than the new functions.
+* \par
+* An example of initialization of the constants for the arm_cfft_f32 function follows:
+* \code
+* const static arm_cfft_instance_f32 *S;
+* ...
+* switch (length) {
+* case 16:
+* S = &arm_cfft_sR_f32_len16;
+* break;
+* case 32:
+* S = &arm_cfft_sR_f32_len32;
+* break;
+* case 64:
+* S = &arm_cfft_sR_f32_len64;
+* break;
+* case 128:
+* S = &arm_cfft_sR_f32_len128;
+* break;
+* case 256:
+* S = &arm_cfft_sR_f32_len256;
+* break;
+* case 512:
+* S = &arm_cfft_sR_f32_len512;
+* break;
+* case 1024:
+* S = &arm_cfft_sR_f32_len1024;
+* break;
+* case 2048:
+* S = &arm_cfft_sR_f32_len2048;
+* break;
+* case 4096:
+* S = &arm_cfft_sR_f32_len4096;
+* break;
+* }
+* \endcode
+* \par Q15 and Q31
+* The floating-point complex FFT uses a mixed-radix algorithm. Multiple radix-4
+* stages are performed along with a single radix-2 stage, as needed.
+* The algorithm supports lengths of [16, 32, 64, ..., 4096] and each length uses
+* a different twiddle factor table.
+* \par
+* The function uses the standard FFT definition and output values may grow by a
+* factor of fftLen
when computing the forward transform. The
+* inverse transform includes a scale of 1/fftLen
as part of the
+* calculation and this matches the textbook definition of the inverse FFT.
+* \par
+* Pre-initialized data structures containing twiddle factors and bit reversal
+* tables are provided and defined in arm_const_structs.h
. Include
+* this header in your function and then pass one of the constant structures as
+* an argument to arm_cfft_q31. For example:
+* \par
+* arm_cfft_q31(arm_cfft_sR_q31_len64, pSrc, 1, 1)
+* \par
+* computes a 64-point inverse complex FFT including bit reversal.
+* The data structures are treated as constant data and not modified during the
+* calculation. The same data structure can be reused for multiple transforms
+* including mixing forward and inverse transforms.
+* \par
+* Earlier releases of the library provided separate radix-2 and radix-4
+* algorithms that operated on floating-point data. These functions are still
+* provided but are deprecated. The older functions are slower and less general
+* than the new functions.
+* \par
+* An example of initialization of the constants for the arm_cfft_q31 function follows:
+* \code
+* const static arm_cfft_instance_q31 *S;
+* ...
+* switch (length) {
+* case 16:
+* S = &arm_cfft_sR_q31_len16;
+* break;
+* case 32:
+* S = &arm_cfft_sR_q31_len32;
+* break;
+* case 64:
+* S = &arm_cfft_sR_q31_len64;
+* break;
+* case 128:
+* S = &arm_cfft_sR_q31_len128;
+* break;
+* case 256:
+* S = &arm_cfft_sR_q31_len256;
+* break;
+* case 512:
+* S = &arm_cfft_sR_q31_len512;
+* break;
+* case 1024:
+* S = &arm_cfft_sR_q31_len1024;
+* break;
+* case 2048:
+* S = &arm_cfft_sR_q31_len2048;
+* break;
+* case 4096:
+* S = &arm_cfft_sR_q31_len4096;
+* break;
+* }
+* \endcode
+*
+*/
+
+void arm_cfft_radix8by2_f32( arm_cfft_instance_f32 * S, float32_t * p1)
+{
+ uint32_t L = S->fftLen;
+ float32_t * pCol1, * pCol2, * pMid1, * pMid2;
+ float32_t * p2 = p1 + L;
+ const float32_t * tw = (float32_t *) S->pTwiddle;
+ float32_t t1[4], t2[4], t3[4], t4[4], twR, twI;
+ float32_t m0, m1, m2, m3;
+ uint32_t l;
+
+ pCol1 = p1;
+ pCol2 = p2;
+
+ // Define new length
+ L >>= 1;
+ // Initialize mid pointers
+ pMid1 = p1 + L;
+ pMid2 = p2 + L;
+
+ // do two dot Fourier transform
+ for ( l = L >> 2; l > 0; l-- )
+ {
+ t1[0] = p1[0];
+ t1[1] = p1[1];
+ t1[2] = p1[2];
+ t1[3] = p1[3];
+
+ t2[0] = p2[0];
+ t2[1] = p2[1];
+ t2[2] = p2[2];
+ t2[3] = p2[3];
+
+ t3[0] = pMid1[0];
+ t3[1] = pMid1[1];
+ t3[2] = pMid1[2];
+ t3[3] = pMid1[3];
+
+ t4[0] = pMid2[0];
+ t4[1] = pMid2[1];
+ t4[2] = pMid2[2];
+ t4[3] = pMid2[3];
+
+ *p1++ = t1[0] + t2[0];
+ *p1++ = t1[1] + t2[1];
+ *p1++ = t1[2] + t2[2];
+ *p1++ = t1[3] + t2[3]; // col 1
+
+ t2[0] = t1[0] - t2[0];
+ t2[1] = t1[1] - t2[1];
+ t2[2] = t1[2] - t2[2];
+ t2[3] = t1[3] - t2[3]; // for col 2
+
+ *pMid1++ = t3[0] + t4[0];
+ *pMid1++ = t3[1] + t4[1];
+ *pMid1++ = t3[2] + t4[2];
+ *pMid1++ = t3[3] + t4[3]; // col 1
+
+ t4[0] = t4[0] - t3[0];
+ t4[1] = t4[1] - t3[1];
+ t4[2] = t4[2] - t3[2];
+ t4[3] = t4[3] - t3[3]; // for col 2
+
+ twR = *tw++;
+ twI = *tw++;
+
+ // multiply by twiddle factors
+ m0 = t2[0] * twR;
+ m1 = t2[1] * twI;
+ m2 = t2[1] * twR;
+ m3 = t2[0] * twI;
+
+ // R = R * Tr - I * Ti
+ *p2++ = m0 + m1;
+ // I = I * Tr + R * Ti
+ *p2++ = m2 - m3;
+
+ // use vertical symmetry
+ // 0.9988 - 0.0491i <==> -0.0491 - 0.9988i
+ m0 = t4[0] * twI;
+ m1 = t4[1] * twR;
+ m2 = t4[1] * twI;
+ m3 = t4[0] * twR;
+
+ *pMid2++ = m0 - m1;
+ *pMid2++ = m2 + m3;
+
+ twR = *tw++;
+ twI = *tw++;
+
+ m0 = t2[2] * twR;
+ m1 = t2[3] * twI;
+ m2 = t2[3] * twR;
+ m3 = t2[2] * twI;
+
+ *p2++ = m0 + m1;
+ *p2++ = m2 - m3;
+
+ m0 = t4[2] * twI;
+ m1 = t4[3] * twR;
+ m2 = t4[3] * twI;
+ m3 = t4[2] * twR;
+
+ *pMid2++ = m0 - m1;
+ *pMid2++ = m2 + m3;
+ }
+
+ // first col
+ arm_radix8_butterfly_f32( pCol1, L, (float32_t *) S->pTwiddle, 2u);
+ // second col
+ arm_radix8_butterfly_f32( pCol2, L, (float32_t *) S->pTwiddle, 2u);
+}
+
+void arm_cfft_radix8by4_f32( arm_cfft_instance_f32 * S, float32_t * p1)
+{
+ uint32_t L = S->fftLen >> 1;
+ float32_t * pCol1, *pCol2, *pCol3, *pCol4, *pEnd1, *pEnd2, *pEnd3, *pEnd4;
+ const float32_t *tw2, *tw3, *tw4;
+ float32_t * p2 = p1 + L;
+ float32_t * p3 = p2 + L;
+ float32_t * p4 = p3 + L;
+ float32_t t2[4], t3[4], t4[4], twR, twI;
+ float32_t p1ap3_0, p1sp3_0, p1ap3_1, p1sp3_1;
+ float32_t m0, m1, m2, m3;
+ uint32_t l, twMod2, twMod3, twMod4;
+
+ pCol1 = p1; // points to real values by default
+ pCol2 = p2;
+ pCol3 = p3;
+ pCol4 = p4;
+ pEnd1 = p2 - 1; // points to imaginary values by default
+ pEnd2 = p3 - 1;
+ pEnd3 = p4 - 1;
+ pEnd4 = pEnd3 + L;
+
+ tw2 = tw3 = tw4 = (float32_t *) S->pTwiddle;
+
+ L >>= 1;
+
+ // do four dot Fourier transform
+
+ twMod2 = 2;
+ twMod3 = 4;
+ twMod4 = 6;
+
+ // TOP
+ p1ap3_0 = p1[0] + p3[0];
+ p1sp3_0 = p1[0] - p3[0];
+ p1ap3_1 = p1[1] + p3[1];
+ p1sp3_1 = p1[1] - p3[1];
+
+ // col 2
+ t2[0] = p1sp3_0 + p2[1] - p4[1];
+ t2[1] = p1sp3_1 - p2[0] + p4[0];
+ // col 3
+ t3[0] = p1ap3_0 - p2[0] - p4[0];
+ t3[1] = p1ap3_1 - p2[1] - p4[1];
+ // col 4
+ t4[0] = p1sp3_0 - p2[1] + p4[1];
+ t4[1] = p1sp3_1 + p2[0] - p4[0];
+ // col 1
+ *p1++ = p1ap3_0 + p2[0] + p4[0];
+ *p1++ = p1ap3_1 + p2[1] + p4[1];
+
+ // Twiddle factors are ones
+ *p2++ = t2[0];
+ *p2++ = t2[1];
+ *p3++ = t3[0];
+ *p3++ = t3[1];
+ *p4++ = t4[0];
+ *p4++ = t4[1];
+
+ tw2 += twMod2;
+ tw3 += twMod3;
+ tw4 += twMod4;
+
+ for (l = (L - 2) >> 1; l > 0; l-- )
+ {
+ // TOP
+ p1ap3_0 = p1[0] + p3[0];
+ p1sp3_0 = p1[0] - p3[0];
+ p1ap3_1 = p1[1] + p3[1];
+ p1sp3_1 = p1[1] - p3[1];
+ // col 2
+ t2[0] = p1sp3_0 + p2[1] - p4[1];
+ t2[1] = p1sp3_1 - p2[0] + p4[0];
+ // col 3
+ t3[0] = p1ap3_0 - p2[0] - p4[0];
+ t3[1] = p1ap3_1 - p2[1] - p4[1];
+ // col 4
+ t4[0] = p1sp3_0 - p2[1] + p4[1];
+ t4[1] = p1sp3_1 + p2[0] - p4[0];
+ // col 1 - top
+ *p1++ = p1ap3_0 + p2[0] + p4[0];
+ *p1++ = p1ap3_1 + p2[1] + p4[1];
+
+ // BOTTOM
+ p1ap3_1 = pEnd1[-1] + pEnd3[-1];
+ p1sp3_1 = pEnd1[-1] - pEnd3[-1];
+ p1ap3_0 = pEnd1[0] + pEnd3[0];
+ p1sp3_0 = pEnd1[0] - pEnd3[0];
+ // col 2
+ t2[2] = pEnd2[0] - pEnd4[0] + p1sp3_1;
+ t2[3] = pEnd1[0] - pEnd3[0] - pEnd2[-1] + pEnd4[-1];
+ // col 3
+ t3[2] = p1ap3_1 - pEnd2[-1] - pEnd4[-1];
+ t3[3] = p1ap3_0 - pEnd2[0] - pEnd4[0];
+ // col 4
+ t4[2] = pEnd2[0] - pEnd4[0] - p1sp3_1;
+ t4[3] = pEnd4[-1] - pEnd2[-1] - p1sp3_0;
+ // col 1 - Bottom
+ *pEnd1-- = p1ap3_0 + pEnd2[0] + pEnd4[0];
+ *pEnd1-- = p1ap3_1 + pEnd2[-1] + pEnd4[-1];
+
+ // COL 2
+ // read twiddle factors
+ twR = *tw2++;
+ twI = *tw2++;
+ // multiply by twiddle factors
+ // let Z1 = a + i(b), Z2 = c + i(d)
+ // => Z1 * Z2 = (a*c - b*d) + i(b*c + a*d)
+
+ // Top
+ m0 = t2[0] * twR;
+ m1 = t2[1] * twI;
+ m2 = t2[1] * twR;
+ m3 = t2[0] * twI;
+
+ *p2++ = m0 + m1;
+ *p2++ = m2 - m3;
+ // use vertical symmetry col 2
+ // 0.9997 - 0.0245i <==> 0.0245 - 0.9997i
+ // Bottom
+ m0 = t2[3] * twI;
+ m1 = t2[2] * twR;
+ m2 = t2[2] * twI;
+ m3 = t2[3] * twR;
+
+ *pEnd2-- = m0 - m1;
+ *pEnd2-- = m2 + m3;
+
+ // COL 3
+ twR = tw3[0];
+ twI = tw3[1];
+ tw3 += twMod3;
+ // Top
+ m0 = t3[0] * twR;
+ m1 = t3[1] * twI;
+ m2 = t3[1] * twR;
+ m3 = t3[0] * twI;
+
+ *p3++ = m0 + m1;
+ *p3++ = m2 - m3;
+ // use vertical symmetry col 3
+ // 0.9988 - 0.0491i <==> -0.9988 - 0.0491i
+ // Bottom
+ m0 = -t3[3] * twR;
+ m1 = t3[2] * twI;
+ m2 = t3[2] * twR;
+ m3 = t3[3] * twI;
+
+ *pEnd3-- = m0 - m1;
+ *pEnd3-- = m3 - m2;
+
+ // COL 4
+ twR = tw4[0];
+ twI = tw4[1];
+ tw4 += twMod4;
+ // Top
+ m0 = t4[0] * twR;
+ m1 = t4[1] * twI;
+ m2 = t4[1] * twR;
+ m3 = t4[0] * twI;
+
+ *p4++ = m0 + m1;
+ *p4++ = m2 - m3;
+ // use vertical symmetry col 4
+ // 0.9973 - 0.0736i <==> -0.0736 + 0.9973i
+ // Bottom
+ m0 = t4[3] * twI;
+ m1 = t4[2] * twR;
+ m2 = t4[2] * twI;
+ m3 = t4[3] * twR;
+
+ *pEnd4-- = m0 - m1;
+ *pEnd4-- = m2 + m3;
+ }
+
+ //MIDDLE
+ // Twiddle factors are
+ // 1.0000 0.7071-0.7071i -1.0000i -0.7071-0.7071i
+ p1ap3_0 = p1[0] + p3[0];
+ p1sp3_0 = p1[0] - p3[0];
+ p1ap3_1 = p1[1] + p3[1];
+ p1sp3_1 = p1[1] - p3[1];
+
+ // col 2
+ t2[0] = p1sp3_0 + p2[1] - p4[1];
+ t2[1] = p1sp3_1 - p2[0] + p4[0];
+ // col 3
+ t3[0] = p1ap3_0 - p2[0] - p4[0];
+ t3[1] = p1ap3_1 - p2[1] - p4[1];
+ // col 4
+ t4[0] = p1sp3_0 - p2[1] + p4[1];
+ t4[1] = p1sp3_1 + p2[0] - p4[0];
+ // col 1 - Top
+ *p1++ = p1ap3_0 + p2[0] + p4[0];
+ *p1++ = p1ap3_1 + p2[1] + p4[1];
+
+ // COL 2
+ twR = tw2[0];
+ twI = tw2[1];
+
+ m0 = t2[0] * twR;
+ m1 = t2[1] * twI;
+ m2 = t2[1] * twR;
+ m3 = t2[0] * twI;
+
+ *p2++ = m0 + m1;
+ *p2++ = m2 - m3;
+ // COL 3
+ twR = tw3[0];
+ twI = tw3[1];
+
+ m0 = t3[0] * twR;
+ m1 = t3[1] * twI;
+ m2 = t3[1] * twR;
+ m3 = t3[0] * twI;
+
+ *p3++ = m0 + m1;
+ *p3++ = m2 - m3;
+ // COL 4
+ twR = tw4[0];
+ twI = tw4[1];
+
+ m0 = t4[0] * twR;
+ m1 = t4[1] * twI;
+ m2 = t4[1] * twR;
+ m3 = t4[0] * twI;
+
+ *p4++ = m0 + m1;
+ *p4++ = m2 - m3;
+
+ // first col
+ arm_radix8_butterfly_f32( pCol1, L, (float32_t *) S->pTwiddle, 4u);
+ // second col
+ arm_radix8_butterfly_f32( pCol2, L, (float32_t *) S->pTwiddle, 4u);
+ // third col
+ arm_radix8_butterfly_f32( pCol3, L, (float32_t *) S->pTwiddle, 4u);
+ // fourth col
+ arm_radix8_butterfly_f32( pCol4, L, (float32_t *) S->pTwiddle, 4u);
+}
+
+/**
+* @addtogroup ComplexFFT
+* @{
+*/
+
+/**
+* @details
+* @brief Processing function for the floating-point complex FFT.
+* @param[in] *S points to an instance of the floating-point CFFT structure.
+* @param[in, out] *p1 points to the complex data buffer of size 2*fftLen
. Processing occurs in-place.
+* @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 none.
+*/
+
+void arm_cfft_f32(
+ const arm_cfft_instance_f32 * S,
+ float32_t * p1,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag)
+{
+ uint32_t L = S->fftLen, l;
+ float32_t invL, * pSrc;
+
+ if(ifftFlag == 1u)
+ {
+ /* Conjugate input data */
+ pSrc = p1 + 1;
+ for(l=0; lpTwiddle, 1);
+ break;
+ }
+
+ if( bitReverseFlag )
+ arm_bitreversal_32((uint32_t*)p1,S->bitRevLength,S->pBitRevTable);
+
+ if(ifftFlag == 1u)
+ {
+ invL = 1.0f/(float32_t)L;
+ /* Conjugate and scale output data */
+ pSrc = p1;
+ for(l=0; l2*fftLen. Processing occurs in-place.
+* @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 none.
+*/
+
+void arm_cfft_q15(
+ const arm_cfft_instance_q15 * S,
+ q15_t * p1,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag)
+{
+ uint32_t L = S->fftLen;
+
+ if(ifftFlag == 1u)
+ {
+ switch (L)
+ {
+ case 16:
+ case 64:
+ case 256:
+ case 1024:
+ case 4096:
+ arm_radix4_butterfly_inverse_q15 ( p1, L, (q15_t*)S->pTwiddle, 1 );
+ break;
+
+ case 32:
+ case 128:
+ case 512:
+ case 2048:
+ arm_cfft_radix4by2_inverse_q15 ( p1, L, S->pTwiddle );
+ break;
+ }
+ }
+ else
+ {
+ switch (L)
+ {
+ case 16:
+ case 64:
+ case 256:
+ case 1024:
+ case 4096:
+ arm_radix4_butterfly_q15 ( p1, L, (q15_t*)S->pTwiddle, 1 );
+ break;
+
+ case 32:
+ case 128:
+ case 512:
+ case 2048:
+ arm_cfft_radix4by2_q15 ( p1, L, S->pTwiddle );
+ break;
+ }
+ }
+
+ if( bitReverseFlag )
+ arm_bitreversal_16((uint16_t*)p1,S->bitRevLength,S->pBitRevTable);
+}
+
+/**
+* @} end of ComplexFFT group
+*/
+
+void arm_cfft_radix4by2_q15(
+ q15_t * pSrc,
+ uint32_t fftLen,
+ const q15_t * pCoef)
+{
+ uint32_t i;
+ uint32_t n2;
+ q15_t p0, p1, p2, p3;
+#ifndef ARM_MATH_CM0_FAMILY
+ q31_t T, S, R;
+ q31_t coeff, out1, out2;
+ const q15_t *pC = pCoef;
+ q15_t *pSi = pSrc;
+ q15_t *pSl = pSrc + fftLen;
+#else
+ uint32_t ia, l;
+ q15_t xt, yt, cosVal, sinVal;
+#endif
+
+ n2 = fftLen >> 1;
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ for (i = n2; i > 0; i--)
+ {
+ coeff = _SIMD32_OFFSET(pC);
+ pC += 2;
+
+ T = _SIMD32_OFFSET(pSi);
+ T = __SHADD16(T, 0); // this is just a SIMD arithmetic shift right by 1
+
+ S = _SIMD32_OFFSET(pSl);
+ S = __SHADD16(S, 0); // this is just a SIMD arithmetic shift right by 1
+
+ R = __QSUB16(T, S);
+
+ _SIMD32_OFFSET(pSi) = __SHADD16(T, S);
+ pSi += 2;
+
+ #ifndef ARM_MATH_BIG_ENDIAN
+
+ out1 = __SMUAD(coeff, R) >> 16;
+ out2 = __SMUSDX(coeff, R);
+
+ #else
+
+ out1 = __SMUSDX(R, coeff) >> 16u;
+ out2 = __SMUAD(coeff, R);
+
+ #endif // #ifndef ARM_MATH_BIG_ENDIAN
+
+ _SIMD32_OFFSET(pSl) =
+ (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
+ pSl += 2;
+ }
+
+#else // #ifndef ARM_MATH_CM0_FAMILY
+
+ ia = 0;
+ for (i = 0; i < n2; i++)
+ {
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+ ia++;
+
+ l = i + n2;
+
+ xt = (pSrc[2 * i] >> 1u) - (pSrc[2 * l] >> 1u);
+ pSrc[2 * i] = ((pSrc[2 * i] >> 1u) + (pSrc[2 * l] >> 1u)) >> 1u;
+
+ yt = (pSrc[2 * i + 1] >> 1u) - (pSrc[2 * l + 1] >> 1u);
+ pSrc[2 * i + 1] =
+ ((pSrc[2 * l + 1] >> 1u) + (pSrc[2 * i + 1] >> 1u)) >> 1u;
+
+ pSrc[2u * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) +
+ ((int16_t) (((q31_t) yt * sinVal) >> 16)));
+
+ pSrc[2u * l + 1u] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) -
+ ((int16_t) (((q31_t) xt * sinVal) >> 16)));
+ }
+
+#endif // #ifndef ARM_MATH_CM0_FAMILY
+
+ // first col
+ arm_radix4_butterfly_q15( pSrc, n2, (q15_t*)pCoef, 2u);
+ // second col
+ arm_radix4_butterfly_q15( pSrc + fftLen, n2, (q15_t*)pCoef, 2u);
+
+ for (i = 0; i < fftLen >> 1; i++)
+ {
+ p0 = pSrc[4*i+0];
+ p1 = pSrc[4*i+1];
+ p2 = pSrc[4*i+2];
+ p3 = pSrc[4*i+3];
+
+ p0 <<= 1;
+ p1 <<= 1;
+ p2 <<= 1;
+ p3 <<= 1;
+
+ pSrc[4*i+0] = p0;
+ pSrc[4*i+1] = p1;
+ pSrc[4*i+2] = p2;
+ pSrc[4*i+3] = p3;
+ }
+}
+
+void arm_cfft_radix4by2_inverse_q15(
+ q15_t * pSrc,
+ uint32_t fftLen,
+ const q15_t * pCoef)
+{
+ uint32_t i;
+ uint32_t n2;
+ q15_t p0, p1, p2, p3;
+#ifndef ARM_MATH_CM0_FAMILY
+ q31_t T, S, R;
+ q31_t coeff, out1, out2;
+ const q15_t *pC = pCoef;
+ q15_t *pSi = pSrc;
+ q15_t *pSl = pSrc + fftLen;
+#else
+ uint32_t ia, l;
+ q15_t xt, yt, cosVal, sinVal;
+#endif
+
+ n2 = fftLen >> 1;
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ for (i = n2; i > 0; i--)
+ {
+ coeff = _SIMD32_OFFSET(pC);
+ pC += 2;
+
+ T = _SIMD32_OFFSET(pSi);
+ T = __SHADD16(T, 0); // this is just a SIMD arithmetic shift right by 1
+
+ S = _SIMD32_OFFSET(pSl);
+ S = __SHADD16(S, 0); // this is just a SIMD arithmetic shift right by 1
+
+ R = __QSUB16(T, S);
+
+ _SIMD32_OFFSET(pSi) = __SHADD16(T, S);
+ pSi += 2;
+
+ #ifndef ARM_MATH_BIG_ENDIAN
+
+ out1 = __SMUSD(coeff, R) >> 16;
+ out2 = __SMUADX(coeff, R);
+ #else
+
+ out1 = __SMUADX(R, coeff) >> 16u;
+ out2 = __SMUSD(__QSUB(0, coeff), R);
+
+ #endif // #ifndef ARM_MATH_BIG_ENDIAN
+
+ _SIMD32_OFFSET(pSl) =
+ (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
+ pSl += 2;
+ }
+
+#else // #ifndef ARM_MATH_CM0_FAMILY
+
+ ia = 0;
+ for (i = 0; i < n2; i++)
+ {
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+ ia++;
+
+ l = i + n2;
+ xt = (pSrc[2 * i] >> 1u) - (pSrc[2 * l] >> 1u);
+ pSrc[2 * i] = ((pSrc[2 * i] >> 1u) + (pSrc[2 * l] >> 1u)) >> 1u;
+
+ yt = (pSrc[2 * i + 1] >> 1u) - (pSrc[2 * l + 1] >> 1u);
+ pSrc[2 * i + 1] =
+ ((pSrc[2 * l + 1] >> 1u) + (pSrc[2 * i + 1] >> 1u)) >> 1u;
+
+ pSrc[2u * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) -
+ ((int16_t) (((q31_t) yt * sinVal) >> 16)));
+
+ pSrc[2u * l + 1u] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) +
+ ((int16_t) (((q31_t) xt * sinVal) >> 16)));
+ }
+
+#endif // #ifndef ARM_MATH_CM0_FAMILY
+
+ // first col
+ arm_radix4_butterfly_inverse_q15( pSrc, n2, (q15_t*)pCoef, 2u);
+ // second col
+ arm_radix4_butterfly_inverse_q15( pSrc + fftLen, n2, (q15_t*)pCoef, 2u);
+
+ for (i = 0; i < fftLen >> 1; i++)
+ {
+ p0 = pSrc[4*i+0];
+ p1 = pSrc[4*i+1];
+ p2 = pSrc[4*i+2];
+ p3 = pSrc[4*i+3];
+
+ p0 <<= 1;
+ p1 <<= 1;
+ p2 <<= 1;
+ p3 <<= 1;
+
+ pSrc[4*i+0] = p0;
+ pSrc[4*i+1] = p1;
+ pSrc[4*i+2] = p2;
+ pSrc[4*i+3] = p3;
+ }
+}
+
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_q31.c
new file mode 100644
index 0000000..401825b
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_q31.c
@@ -0,0 +1,264 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_cfft_q31.c
+*
+* Description: Combined Radix Decimation in Frequency CFFT fixed point processing function
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+extern void arm_radix4_butterfly_q31(
+ q31_t * pSrc,
+ uint32_t fftLen,
+ q31_t * pCoef,
+ uint32_t twidCoefModifier);
+
+extern void arm_radix4_butterfly_inverse_q31(
+ q31_t * pSrc,
+ uint32_t fftLen,
+ q31_t * pCoef,
+ uint32_t twidCoefModifier);
+
+extern void arm_bitreversal_32(
+ uint32_t * pSrc,
+ const uint16_t bitRevLen,
+ const uint16_t * pBitRevTable);
+
+void arm_cfft_radix4by2_q31(
+ q31_t * pSrc,
+ uint32_t fftLen,
+ const q31_t * pCoef);
+
+void arm_cfft_radix4by2_inverse_q31(
+ q31_t * pSrc,
+ uint32_t fftLen,
+ const q31_t * pCoef);
+
+/**
+* @ingroup groupTransforms
+*/
+
+/**
+* @addtogroup ComplexFFT
+* @{
+*/
+
+/**
+* @details
+* @brief Processing function for the fixed-point complex FFT in Q31 format.
+* @param[in] *S points to an instance of the fixed-point CFFT structure.
+* @param[in, out] *p1 points to the complex data buffer of size 2*fftLen
. Processing occurs in-place.
+* @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 none.
+*/
+
+void arm_cfft_q31(
+ const arm_cfft_instance_q31 * S,
+ q31_t * p1,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag)
+{
+ uint32_t L = S->fftLen;
+
+ if(ifftFlag == 1u)
+ {
+ switch (L)
+ {
+ case 16:
+ case 64:
+ case 256:
+ case 1024:
+ case 4096:
+ arm_radix4_butterfly_inverse_q31 ( p1, L, (q31_t*)S->pTwiddle, 1 );
+ break;
+
+ case 32:
+ case 128:
+ case 512:
+ case 2048:
+ arm_cfft_radix4by2_inverse_q31 ( p1, L, S->pTwiddle );
+ break;
+ }
+ }
+ else
+ {
+ switch (L)
+ {
+ case 16:
+ case 64:
+ case 256:
+ case 1024:
+ case 4096:
+ arm_radix4_butterfly_q31 ( p1, L, (q31_t*)S->pTwiddle, 1 );
+ break;
+
+ case 32:
+ case 128:
+ case 512:
+ case 2048:
+ arm_cfft_radix4by2_q31 ( p1, L, S->pTwiddle );
+ break;
+ }
+ }
+
+ if( bitReverseFlag )
+ arm_bitreversal_32((uint32_t*)p1,S->bitRevLength,S->pBitRevTable);
+}
+
+/**
+* @} end of ComplexFFT group
+*/
+
+void arm_cfft_radix4by2_q31(
+ q31_t * pSrc,
+ uint32_t fftLen,
+ const q31_t * pCoef)
+{
+ uint32_t i, l;
+ uint32_t n2, ia;
+ q31_t xt, yt, cosVal, sinVal;
+ q31_t p0, p1;
+
+ n2 = fftLen >> 1;
+ ia = 0;
+ for (i = 0; i < n2; i++)
+ {
+ cosVal = pCoef[2*ia];
+ sinVal = pCoef[2*ia + 1];
+ ia++;
+
+ l = i + n2;
+ xt = (pSrc[2 * i] >> 2) - (pSrc[2 * l] >> 2);
+ pSrc[2 * i] = (pSrc[2 * i] >> 2) + (pSrc[2 * l] >> 2);
+
+ yt = (pSrc[2 * i + 1] >> 2) - (pSrc[2 * l + 1] >> 2);
+ pSrc[2 * i + 1] = (pSrc[2 * l + 1] >> 2) + (pSrc[2 * i + 1] >> 2);
+
+ mult_32x32_keep32_R(p0, xt, cosVal);
+ mult_32x32_keep32_R(p1, yt, cosVal);
+ multAcc_32x32_keep32_R(p0, yt, sinVal);
+ multSub_32x32_keep32_R(p1, xt, sinVal);
+
+ pSrc[2u * l] = p0 << 1;
+ pSrc[2u * l + 1u] = p1 << 1;
+
+ }
+
+ // first col
+ arm_radix4_butterfly_q31( pSrc, n2, (q31_t*)pCoef, 2u);
+ // second col
+ arm_radix4_butterfly_q31( pSrc + fftLen, n2, (q31_t*)pCoef, 2u);
+
+ for (i = 0; i < fftLen >> 1; i++)
+ {
+ p0 = pSrc[4*i+0];
+ p1 = pSrc[4*i+1];
+ xt = pSrc[4*i+2];
+ yt = pSrc[4*i+3];
+
+ p0 <<= 1;
+ p1 <<= 1;
+ xt <<= 1;
+ yt <<= 1;
+
+ pSrc[4*i+0] = p0;
+ pSrc[4*i+1] = p1;
+ pSrc[4*i+2] = xt;
+ pSrc[4*i+3] = yt;
+ }
+
+}
+
+void arm_cfft_radix4by2_inverse_q31(
+ q31_t * pSrc,
+ uint32_t fftLen,
+ const q31_t * pCoef)
+{
+ uint32_t i, l;
+ uint32_t n2, ia;
+ q31_t xt, yt, cosVal, sinVal;
+ q31_t p0, p1;
+
+ n2 = fftLen >> 1;
+ ia = 0;
+ for (i = 0; i < n2; i++)
+ {
+ cosVal = pCoef[2*ia];
+ sinVal = pCoef[2*ia + 1];
+ ia++;
+
+ l = i + n2;
+ xt = (pSrc[2 * i] >> 2) - (pSrc[2 * l] >> 2);
+ pSrc[2 * i] = (pSrc[2 * i] >> 2) + (pSrc[2 * l] >> 2);
+
+ yt = (pSrc[2 * i + 1] >> 2) - (pSrc[2 * l + 1] >> 2);
+ pSrc[2 * i + 1] = (pSrc[2 * l + 1] >> 2) + (pSrc[2 * i + 1] >> 2);
+
+ mult_32x32_keep32_R(p0, xt, cosVal);
+ mult_32x32_keep32_R(p1, yt, cosVal);
+ multSub_32x32_keep32_R(p0, yt, sinVal);
+ multAcc_32x32_keep32_R(p1, xt, sinVal);
+
+ pSrc[2u * l] = p0 << 1;
+ pSrc[2u * l + 1u] = p1 << 1;
+
+ }
+
+ // first col
+ arm_radix4_butterfly_inverse_q31( pSrc, n2, (q31_t*)pCoef, 2u);
+ // second col
+ arm_radix4_butterfly_inverse_q31( pSrc + fftLen, n2, (q31_t*)pCoef, 2u);
+
+ for (i = 0; i < fftLen >> 1; i++)
+ {
+ p0 = pSrc[4*i+0];
+ p1 = pSrc[4*i+1];
+ xt = pSrc[4*i+2];
+ yt = pSrc[4*i+3];
+
+ p0 <<= 1;
+ p1 <<= 1;
+ xt <<= 1;
+ yt <<= 1;
+
+ pSrc[4*i+0] = p0;
+ pSrc[4*i+1] = p1;
+ pSrc[4*i+2] = xt;
+ pSrc[4*i+3] = yt;
+ }
+}
+
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_f32.c
new file mode 100644
index 0000000..b0632ac
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_f32.c
@@ -0,0 +1,485 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_cfft_radix2_f32.c
+*
+* Description: Radix-2 Decimation in Frequency CFFT & CIFFT Floating point processing function
+*
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+void arm_radix2_butterfly_f32(
+ float32_t * pSrc,
+ uint32_t fftLen,
+ float32_t * pCoef,
+ uint16_t twidCoefModifier);
+
+void arm_radix2_butterfly_inverse_f32(
+ float32_t * pSrc,
+ uint32_t fftLen,
+ float32_t * pCoef,
+ uint16_t twidCoefModifier,
+ float32_t onebyfftLen);
+
+extern void arm_bitreversal_f32(
+ float32_t * pSrc,
+ uint16_t fftSize,
+ uint16_t bitRevFactor,
+ uint16_t * pBitRevTab);
+
+/**
+* @ingroup groupTransforms
+*/
+
+/**
+* @addtogroup ComplexFFT
+* @{
+*/
+
+/**
+* @details
+* @brief Radix-2 CFFT/CIFFT.
+* @deprecated Do not use this function. It has been superseded by \ref arm_cfft_f32 and will be removed
+* in the future.
+* @param[in] *S points to an instance of the floating-point Radix-2 CFFT/CIFFT structure.
+* @param[in, out] *pSrc points to the complex data buffer of size 2*fftLen
. Processing occurs in-place.
+* @return none.
+*/
+
+void arm_cfft_radix2_f32(
+const arm_cfft_radix2_instance_f32 * S,
+float32_t * pSrc)
+{
+
+ if(S->ifftFlag == 1u)
+ {
+ /* Complex IFFT radix-2 */
+ arm_radix2_butterfly_inverse_f32(pSrc, S->fftLen, S->pTwiddle,
+ S->twidCoefModifier, S->onebyfftLen);
+ }
+ else
+ {
+ /* Complex FFT radix-2 */
+ arm_radix2_butterfly_f32(pSrc, S->fftLen, S->pTwiddle,
+ S->twidCoefModifier);
+ }
+
+ if(S->bitReverseFlag == 1u)
+ {
+ /* Bit Reversal */
+ arm_bitreversal_f32(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
+ }
+
+}
+
+
+/**
+* @} end of ComplexFFT group
+*/
+
+
+
+/* ----------------------------------------------------------------------
+** Internal helper function used by the FFTs
+** ------------------------------------------------------------------- */
+
+/*
+* @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_radix2_butterfly_f32(
+float32_t * pSrc,
+uint32_t fftLen,
+float32_t * pCoef,
+uint16_t twidCoefModifier)
+{
+
+ uint32_t i, j, k, l;
+ uint32_t n1, n2, ia;
+ float32_t xt, yt, cosVal, sinVal;
+ float32_t p0, p1, p2, p3;
+ float32_t a0, a1;
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Initializations for the first stage */
+ n2 = fftLen >> 1;
+ ia = 0;
+ i = 0;
+
+ // loop for groups
+ for (k = n2; k > 0; k--)
+ {
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+
+ /* Twiddle coefficients index modifier */
+ ia += twidCoefModifier;
+
+ /* index calculation for the input as, */
+ /* pSrc[i + 0], pSrc[i + fftLen/1] */
+ l = i + n2;
+
+ /* Butterfly implementation */
+ a0 = pSrc[2 * i] + pSrc[2 * l];
+ xt = pSrc[2 * i] - pSrc[2 * l];
+
+ yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
+ a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
+
+ p0 = xt * cosVal;
+ p1 = yt * sinVal;
+ p2 = yt * cosVal;
+ p3 = xt * sinVal;
+
+ pSrc[2 * i] = a0;
+ pSrc[2 * i + 1] = a1;
+
+ pSrc[2 * l] = p0 + p1;
+ pSrc[2 * l + 1] = p2 - p3;
+
+ i++;
+ } // groups loop end
+
+ twidCoefModifier <<= 1u;
+
+ // loop for stage
+ for (k = n2; k > 2; k = k >> 1)
+ {
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ // loop for groups
+ j = 0;
+ do
+ {
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+ ia += twidCoefModifier;
+
+ // loop for butterfly
+ i = j;
+ do
+ {
+ l = i + n2;
+ a0 = pSrc[2 * i] + pSrc[2 * l];
+ xt = pSrc[2 * i] - pSrc[2 * l];
+
+ yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
+ a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
+
+ p0 = xt * cosVal;
+ p1 = yt * sinVal;
+ p2 = yt * cosVal;
+ p3 = xt * sinVal;
+
+ pSrc[2 * i] = a0;
+ pSrc[2 * i + 1] = a1;
+
+ pSrc[2 * l] = p0 + p1;
+ pSrc[2 * l + 1] = p2 - p3;
+
+ i += n1;
+ } while( i < fftLen ); // butterfly loop end
+ j++;
+ } while( j < n2); // groups loop end
+ twidCoefModifier <<= 1u;
+ } // stages loop end
+
+ // loop for butterfly
+ for (i = 0; i < fftLen; i += 2)
+ {
+ a0 = pSrc[2 * i] + pSrc[2 * i + 2];
+ xt = pSrc[2 * i] - pSrc[2 * i + 2];
+
+ yt = pSrc[2 * i + 1] - pSrc[2 * i + 3];
+ a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1];
+
+ pSrc[2 * i] = a0;
+ pSrc[2 * i + 1] = a1;
+ pSrc[2 * i + 2] = xt;
+ pSrc[2 * i + 3] = yt;
+ } // groups loop end
+
+#else
+
+ n2 = fftLen;
+
+ // loop for stage
+ for (k = fftLen; k > 1; k = k >> 1)
+ {
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ // loop for groups
+ j = 0;
+ do
+ {
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+ ia += twidCoefModifier;
+
+ // loop for butterfly
+ i = j;
+ do
+ {
+ l = i + n2;
+ a0 = pSrc[2 * i] + pSrc[2 * l];
+ xt = pSrc[2 * i] - pSrc[2 * l];
+
+ yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
+ a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
+
+ p0 = xt * cosVal;
+ p1 = yt * sinVal;
+ p2 = yt * cosVal;
+ p3 = xt * sinVal;
+
+ pSrc[2 * i] = a0;
+ pSrc[2 * i + 1] = a1;
+
+ pSrc[2 * l] = p0 + p1;
+ pSrc[2 * l + 1] = p2 - p3;
+
+ i += n1;
+ } while(i < fftLen);
+ j++;
+ } while(j < n2);
+ twidCoefModifier <<= 1u;
+ }
+
+#endif // #ifndef ARM_MATH_CM0_FAMILY
+
+}
+
+
+void arm_radix2_butterfly_inverse_f32(
+float32_t * pSrc,
+uint32_t fftLen,
+float32_t * pCoef,
+uint16_t twidCoefModifier,
+float32_t onebyfftLen)
+{
+
+ uint32_t i, j, k, l;
+ uint32_t n1, n2, ia;
+ float32_t xt, yt, cosVal, sinVal;
+ float32_t p0, p1, p2, p3;
+ float32_t a0, a1;
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ n2 = fftLen >> 1;
+ ia = 0;
+
+ // loop for groups
+ for (i = 0; i < n2; i++)
+ {
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+ ia += twidCoefModifier;
+
+ l = i + n2;
+ a0 = pSrc[2 * i] + pSrc[2 * l];
+ xt = pSrc[2 * i] - pSrc[2 * l];
+
+ yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
+ a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
+
+ p0 = xt * cosVal;
+ p1 = yt * sinVal;
+ p2 = yt * cosVal;
+ p3 = xt * sinVal;
+
+ pSrc[2 * i] = a0;
+ pSrc[2 * i + 1] = a1;
+
+ pSrc[2 * l] = p0 - p1;
+ pSrc[2 * l + 1] = p2 + p3;
+ } // groups loop end
+
+ twidCoefModifier <<= 1u;
+
+ // loop for stage
+ for (k = fftLen / 2; k > 2; k = k >> 1)
+ {
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ // loop for groups
+ j = 0;
+ do
+ {
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+ ia += twidCoefModifier;
+
+ // loop for butterfly
+ i = j;
+ do
+ {
+ l = i + n2;
+ a0 = pSrc[2 * i] + pSrc[2 * l];
+ xt = pSrc[2 * i] - pSrc[2 * l];
+
+ yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
+ a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
+
+ p0 = xt * cosVal;
+ p1 = yt * sinVal;
+ p2 = yt * cosVal;
+ p3 = xt * sinVal;
+
+ pSrc[2 * i] = a0;
+ pSrc[2 * i + 1] = a1;
+
+ pSrc[2 * l] = p0 - p1;
+ pSrc[2 * l + 1] = p2 + p3;
+
+ i += n1;
+ } while( i < fftLen ); // butterfly loop end
+ j++;
+ } while(j < n2); // groups loop end
+
+ twidCoefModifier <<= 1u;
+ } // stages loop end
+
+ // loop for butterfly
+ for (i = 0; i < fftLen; i += 2)
+ {
+ a0 = pSrc[2 * i] + pSrc[2 * i + 2];
+ xt = pSrc[2 * i] - pSrc[2 * i + 2];
+
+ a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1];
+ yt = pSrc[2 * i + 1] - pSrc[2 * i + 3];
+
+ p0 = a0 * onebyfftLen;
+ p2 = xt * onebyfftLen;
+ p1 = a1 * onebyfftLen;
+ p3 = yt * onebyfftLen;
+
+ pSrc[2 * i] = p0;
+ pSrc[2 * i + 1] = p1;
+ pSrc[2 * i + 2] = p2;
+ pSrc[2 * i + 3] = p3;
+ } // butterfly loop end
+
+#else
+
+ n2 = fftLen;
+
+ // loop for stage
+ for (k = fftLen; k > 2; k = k >> 1)
+ {
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ // loop for groups
+ j = 0;
+ do
+ {
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+ ia = ia + twidCoefModifier;
+
+ // loop for butterfly
+ i = j;
+ do
+ {
+ l = i + n2;
+ a0 = pSrc[2 * i] + pSrc[2 * l];
+ xt = pSrc[2 * i] - pSrc[2 * l];
+
+ yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
+ a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
+
+ p0 = xt * cosVal;
+ p1 = yt * sinVal;
+ p2 = yt * cosVal;
+ p3 = xt * sinVal;
+
+ pSrc[2 * i] = a0;
+ pSrc[2 * i + 1] = a1;
+
+ pSrc[2 * l] = p0 - p1;
+ pSrc[2 * l + 1] = p2 + p3;
+
+ i += n1;
+ } while( i < fftLen ); // butterfly loop end
+ j++;
+ } while( j < n2 ); // groups loop end
+
+ twidCoefModifier = twidCoefModifier << 1u;
+ } // stages loop end
+
+ n1 = n2;
+ n2 = n2 >> 1;
+
+ // loop for butterfly
+ for (i = 0; i < fftLen; i += n1)
+ {
+ l = i + n2;
+
+ a0 = pSrc[2 * i] + pSrc[2 * l];
+ xt = pSrc[2 * i] - pSrc[2 * l];
+
+ a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
+ yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
+
+ p0 = a0 * onebyfftLen;
+ p2 = xt * onebyfftLen;
+ p1 = a1 * onebyfftLen;
+ p3 = yt * onebyfftLen;
+
+ pSrc[2 * i] = p0;
+ pSrc[2u * l] = p2;
+
+ pSrc[2 * i + 1] = p1;
+ pSrc[2u * l + 1u] = p3;
+ } // butterfly loop end
+
+#endif // #ifndef ARM_MATH_CM0_FAMILY
+
+}
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_f32.c
new file mode 100644
index 0000000..64fd956
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_f32.c
@@ -0,0 +1,205 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_cfft_radix4_init_f32.c
+*
+* Description: Radix-4 Decimation in Frequency Floating-point CFFT & CIFFT Initialization function
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+#include "arm_common_tables.h"
+
+/**
+ * @ingroup groupTransforms
+ */
+
+/**
+ * @addtogroup ComplexFFT
+ * @{
+ */
+
+/**
+* @brief Initialization function for the floating-point CFFT/CIFFT.
+* @deprecated Do not use this function. It has been superseded by \ref arm_cfft_f32 and will be removed
+* in the future.
+* @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.
+*
+* \par Description:
+* \par
+* The parameter ifftFlag
controls whether a forward or inverse transform is computed.
+* Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated
+* \par
+* The parameter bitReverseFlag
controls whether output is in normal order or bit reversed order.
+* Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order.
+* \par
+* The parameter fftLen
Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024.
+* \par
+* This Function also initializes Twiddle factor table pointer and Bit reversal table pointer.
+*/
+arm_status arm_cfft_radix2_init_f32(
+ arm_cfft_radix2_instance_f32 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag)
+{
+ /* Initialise the default arm status */
+ arm_status status = ARM_MATH_SUCCESS;
+
+ /* Initialise the FFT length */
+ S->fftLen = fftLen;
+
+ /* Initialise the Twiddle coefficient pointer */
+ S->pTwiddle = (float32_t *) twiddleCoef;
+
+ /* Initialise the Flag for selection of CFFT or CIFFT */
+ S->ifftFlag = ifftFlag;
+
+ /* Initialise the Flag for calculation Bit reversal or not */
+ S->bitReverseFlag = bitReverseFlag;
+
+ /* Initializations of structure parameters depending on the FFT length */
+ switch (S->fftLen)
+ {
+
+ case 4096u:
+ /* Initializations of structure parameters for 4096 point FFT */
+
+ /* Initialise the twiddle coef modifier value */
+ S->twidCoefModifier = 1u;
+ /* Initialise the bit reversal table modifier */
+ S->bitRevFactor = 1u;
+ /* Initialise the bit reversal table pointer */
+ S->pBitRevTable = (uint16_t *) armBitRevTable;
+ /* Initialise the 1/fftLen Value */
+ S->onebyfftLen = 0.000244140625;
+ break;
+
+ case 2048u:
+ /* Initializations of structure parameters for 2048 point FFT */
+
+ /* Initialise the twiddle coef modifier value */
+ S->twidCoefModifier = 2u;
+ /* Initialise the bit reversal table modifier */
+ S->bitRevFactor = 2u;
+ /* Initialise the bit reversal table pointer */
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[1];
+ /* Initialise the 1/fftLen Value */
+ S->onebyfftLen = 0.00048828125;
+ break;
+
+ case 1024u:
+ /* Initializations of structure parameters for 1024 point FFT */
+
+ /* Initialise the twiddle coef modifier value */
+ S->twidCoefModifier = 4u;
+ /* Initialise the bit reversal table modifier */
+ S->bitRevFactor = 4u;
+ /* Initialise the bit reversal table pointer */
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[3];
+ /* Initialise the 1/fftLen Value */
+ S->onebyfftLen = 0.0009765625f;
+ break;
+
+ case 512u:
+ /* Initializations of structure parameters for 512 point FFT */
+
+ /* Initialise the twiddle coef modifier value */
+ S->twidCoefModifier = 8u;
+ /* Initialise the bit reversal table modifier */
+ S->bitRevFactor = 8u;
+ /* Initialise the bit reversal table pointer */
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[7];
+ /* Initialise the 1/fftLen Value */
+ S->onebyfftLen = 0.001953125;
+ break;
+
+ case 256u:
+ /* Initializations of structure parameters for 256 point FFT */
+ S->twidCoefModifier = 16u;
+ S->bitRevFactor = 16u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[15];
+ S->onebyfftLen = 0.00390625f;
+ break;
+
+ case 128u:
+ /* Initializations of structure parameters for 128 point FFT */
+ S->twidCoefModifier = 32u;
+ S->bitRevFactor = 32u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[31];
+ S->onebyfftLen = 0.0078125;
+ break;
+
+ case 64u:
+ /* Initializations of structure parameters for 64 point FFT */
+ S->twidCoefModifier = 64u;
+ S->bitRevFactor = 64u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[63];
+ S->onebyfftLen = 0.015625f;
+ break;
+
+ case 32u:
+ /* Initializations of structure parameters for 64 point FFT */
+ S->twidCoefModifier = 128u;
+ S->bitRevFactor = 128u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[127];
+ S->onebyfftLen = 0.03125;
+ break;
+
+ case 16u:
+ /* Initializations of structure parameters for 16 point FFT */
+ S->twidCoefModifier = 256u;
+ S->bitRevFactor = 256u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[255];
+ S->onebyfftLen = 0.0625f;
+ break;
+
+
+ default:
+ /* Reporting argument error if fftSize is not valid value */
+ status = ARM_MATH_ARGUMENT_ERROR;
+ break;
+ }
+
+ return (status);
+}
+
+/**
+ * @} end of ComplexFFT group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_q15.c
new file mode 100644
index 0000000..1577c5e
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_q15.c
@@ -0,0 +1,189 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_cfft_radix2_init_q15.c
+*
+* Description: Radix-2 Decimation in Frequency Q15 FFT & IFFT initialization function
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+#include "arm_common_tables.h"
+
+/**
+ * @ingroup groupTransforms
+ */
+
+
+/**
+ * @addtogroup ComplexFFT
+ * @{
+ */
+
+/**
+* @brief Initialization function for the Q15 CFFT/CIFFT.
+* @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q15 and will be removed
+* @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 The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen
is not a supported value.
+*
+* \par Description:
+* \par
+* The parameter ifftFlag
controls whether a forward or inverse transform is computed.
+* Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated
+* \par
+* The parameter bitReverseFlag
controls whether output is in normal order or bit reversed order.
+* Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order.
+* \par
+* The parameter fftLen
Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024.
+* \par
+* This Function also initializes Twiddle factor table pointer and Bit reversal table pointer.
+*/
+
+arm_status arm_cfft_radix2_init_q15(
+ arm_cfft_radix2_instance_q15 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag)
+{
+ /* Initialise the default arm status */
+ arm_status status = ARM_MATH_SUCCESS;
+
+ /* Initialise the FFT length */
+ S->fftLen = fftLen;
+
+ /* Initialise the Twiddle coefficient pointer */
+ S->pTwiddle = (q15_t *) twiddleCoef_4096_q15;
+ /* Initialise the Flag for selection of CFFT or CIFFT */
+ S->ifftFlag = ifftFlag;
+ /* Initialise the Flag for calculation Bit reversal or not */
+ S->bitReverseFlag = bitReverseFlag;
+
+ /* Initializations of structure parameters depending on the FFT length */
+ switch (S->fftLen)
+ {
+ case 4096u:
+ /* Initializations of structure parameters for 4096 point FFT */
+
+ /* Initialise the twiddle coef modifier value */
+ S->twidCoefModifier = 1u;
+ /* Initialise the bit reversal table modifier */
+ S->bitRevFactor = 1u;
+ /* Initialise the bit reversal table pointer */
+ S->pBitRevTable = (uint16_t *) armBitRevTable;
+
+ break;
+
+ case 2048u:
+ /* Initializations of structure parameters for 2048 point FFT */
+
+ /* Initialise the twiddle coef modifier value */
+ S->twidCoefModifier = 2u;
+ /* Initialise the bit reversal table modifier */
+ S->bitRevFactor = 2u;
+ /* Initialise the bit reversal table pointer */
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[1];
+
+ break;
+
+ case 1024u:
+ /* Initializations of structure parameters for 1024 point FFT */
+ S->twidCoefModifier = 4u;
+ S->bitRevFactor = 4u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[3];
+
+ break;
+
+ case 512u:
+ /* Initializations of structure parameters for 512 point FFT */
+ S->twidCoefModifier = 8u;
+ S->bitRevFactor = 8u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[7];
+
+ break;
+
+ case 256u:
+ /* Initializations of structure parameters for 256 point FFT */
+ S->twidCoefModifier = 16u;
+ S->bitRevFactor = 16u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[15];
+
+ break;
+
+ case 128u:
+ /* Initializations of structure parameters for 128 point FFT */
+ S->twidCoefModifier = 32u;
+ S->bitRevFactor = 32u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[31];
+
+ break;
+
+ case 64u:
+ /* Initializations of structure parameters for 64 point FFT */
+ S->twidCoefModifier = 64u;
+ S->bitRevFactor = 64u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[63];
+
+ break;
+
+ case 32u:
+ /* Initializations of structure parameters for 32 point FFT */
+ S->twidCoefModifier = 128u;
+ S->bitRevFactor = 128u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[127];
+
+ break;
+
+ case 16u:
+ /* Initializations of structure parameters for 16 point FFT */
+ S->twidCoefModifier = 256u;
+ S->bitRevFactor = 256u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[255];
+
+ break;
+
+ default:
+ /* Reporting argument error if fftSize is not valid value */
+ status = ARM_MATH_ARGUMENT_ERROR;
+ break;
+ }
+
+ return (status);
+}
+
+/**
+ * @} end of ComplexFFT group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_q31.c
new file mode 100644
index 0000000..61ebaad
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_q31.c
@@ -0,0 +1,187 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_cfft_radix2_init_q31.c
+*
+* Description: Radix-2 Decimation in Frequency Fixed-point CFFT & CIFFT Initialization function
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+#include "arm_common_tables.h"
+
+/**
+ * @ingroup groupTransforms
+ */
+
+/**
+ * @addtogroup ComplexFFT
+ * @{
+ */
+
+
+/**
+*
+* @brief Initialization function for the Q31 CFFT/CIFFT.
+* @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q31 and will be removed
+* @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 The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen
is not a supported value.
+*
+* \par Description:
+* \par
+* The parameter ifftFlag
controls whether a forward or inverse transform is computed.
+* Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated
+* \par
+* The parameter bitReverseFlag
controls whether output is in normal order or bit reversed order.
+* Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order.
+* \par
+* The parameter fftLen
Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024.
+* \par
+* This Function also initializes Twiddle factor table pointer and Bit reversal table pointer.
+*/
+
+arm_status arm_cfft_radix2_init_q31(
+ arm_cfft_radix2_instance_q31 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag)
+{
+ /* Initialise the default arm status */
+ arm_status status = ARM_MATH_SUCCESS;
+
+ /* Initialise the FFT length */
+ S->fftLen = fftLen;
+
+ /* Initialise the Twiddle coefficient pointer */
+ S->pTwiddle = (q31_t *) twiddleCoef_4096_q31;
+ /* Initialise the Flag for selection of CFFT or CIFFT */
+ S->ifftFlag = ifftFlag;
+ /* Initialise the Flag for calculation Bit reversal or not */
+ S->bitReverseFlag = bitReverseFlag;
+
+ /* Initializations of Instance structure depending on the FFT length */
+ switch (S->fftLen)
+ {
+ /* Initializations of structure parameters for 4096 point FFT */
+ case 4096u:
+ /* Initialise the twiddle coef modifier value */
+ S->twidCoefModifier = 1u;
+ /* Initialise the bit reversal table modifier */
+ S->bitRevFactor = 1u;
+ /* Initialise the bit reversal table pointer */
+ S->pBitRevTable = (uint16_t *) armBitRevTable;
+ break;
+
+ /* Initializations of structure parameters for 2048 point FFT */
+ case 2048u:
+ /* Initialise the twiddle coef modifier value */
+ S->twidCoefModifier = 2u;
+ /* Initialise the bit reversal table modifier */
+ S->bitRevFactor = 2u;
+ /* Initialise the bit reversal table pointer */
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[1];
+ break;
+
+ /* Initializations of structure parameters for 1024 point FFT */
+ case 1024u:
+ /* Initialise the twiddle coef modifier value */
+ S->twidCoefModifier = 4u;
+ /* Initialise the bit reversal table modifier */
+ S->bitRevFactor = 4u;
+ /* Initialise the bit reversal table pointer */
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[3];
+ break;
+
+ /* Initializations of structure parameters for 512 point FFT */
+ case 512u:
+ /* Initialise the twiddle coef modifier value */
+ S->twidCoefModifier = 8u;
+ /* Initialise the bit reversal table modifier */
+ S->bitRevFactor = 8u;
+ /* Initialise the bit reversal table pointer */
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[7];
+ break;
+
+ case 256u:
+ /* Initializations of structure parameters for 256 point FFT */
+ S->twidCoefModifier = 16u;
+ S->bitRevFactor = 16u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[15];
+ break;
+
+ case 128u:
+ /* Initializations of structure parameters for 128 point FFT */
+ S->twidCoefModifier = 32u;
+ S->bitRevFactor = 32u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[31];
+ break;
+
+ case 64u:
+ /* Initializations of structure parameters for 64 point FFT */
+ S->twidCoefModifier = 64u;
+ S->bitRevFactor = 64u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[63];
+ break;
+
+ case 32u:
+ /* Initializations of structure parameters for 32 point FFT */
+ S->twidCoefModifier = 128u;
+ S->bitRevFactor = 128u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[127];
+ break;
+
+ case 16u:
+ /* Initializations of structure parameters for 16 point FFT */
+ S->twidCoefModifier = 256u;
+ S->bitRevFactor = 256u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[255];
+ break;
+
+
+ default:
+ /* Reporting argument error if fftSize is not valid value */
+ status = ARM_MATH_ARGUMENT_ERROR;
+ break;
+ }
+
+ return (status);
+}
+
+/**
+ * @} end of ComplexFFT group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_q15.c
new file mode 100644
index 0000000..ad05e1e
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_q15.c
@@ -0,0 +1,742 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_cfft_radix2_q15.c
+*
+* Description: Radix-2 Decimation in Frequency CFFT & CIFFT Fixed point processing function
+*
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+void arm_radix2_butterfly_q15(
+ q15_t * pSrc,
+ uint32_t fftLen,
+ q15_t * pCoef,
+ uint16_t twidCoefModifier);
+
+void arm_radix2_butterfly_inverse_q15(
+ q15_t * pSrc,
+ uint32_t fftLen,
+ q15_t * pCoef,
+ uint16_t twidCoefModifier);
+
+void arm_bitreversal_q15(
+ q15_t * pSrc,
+ uint32_t fftLen,
+ uint16_t bitRevFactor,
+ uint16_t * pBitRevTab);
+
+/**
+ * @ingroup groupTransforms
+ */
+
+/**
+ * @addtogroup ComplexFFT
+ * @{
+ */
+
+/**
+ * @details
+ * @brief Processing function for the fixed-point CFFT/CIFFT.
+ * @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q15 and will be removed
+ * @param[in] *S points to an instance of the fixed-point CFFT/CIFFT structure.
+ * @param[in, out] *pSrc points to the complex data buffer of size 2*fftLen
. Processing occurs in-place.
+ * @return none.
+ */
+
+void arm_cfft_radix2_q15(
+ const arm_cfft_radix2_instance_q15 * S,
+ q15_t * pSrc)
+{
+
+ if(S->ifftFlag == 1u)
+ {
+ arm_radix2_butterfly_inverse_q15(pSrc, S->fftLen,
+ S->pTwiddle, S->twidCoefModifier);
+ }
+ else
+ {
+ arm_radix2_butterfly_q15(pSrc, S->fftLen,
+ S->pTwiddle, S->twidCoefModifier);
+ }
+
+ arm_bitreversal_q15(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
+}
+
+/**
+ * @} end of ComplexFFT group
+ */
+
+void arm_radix2_butterfly_q15(
+ q15_t * pSrc,
+ uint32_t fftLen,
+ q15_t * pCoef,
+ uint16_t twidCoefModifier)
+{
+#ifndef ARM_MATH_CM0_FAMILY
+
+ unsigned i, j, k, l;
+ unsigned n1, n2, ia;
+ q15_t in;
+ q31_t T, S, R;
+ q31_t coeff, out1, out2;
+
+ //N = fftLen;
+ n2 = fftLen;
+
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ // loop for groups
+ for (i = 0; i < n2; i++)
+ {
+ coeff = _SIMD32_OFFSET(pCoef + (ia * 2u));
+
+ ia = ia + twidCoefModifier;
+
+ l = i + n2;
+
+ T = _SIMD32_OFFSET(pSrc + (2 * i));
+ in = ((int16_t) (T & 0xFFFF)) >> 1;
+ T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF);
+
+ S = _SIMD32_OFFSET(pSrc + (2 * l));
+ in = ((int16_t) (S & 0xFFFF)) >> 1;
+ S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF);
+
+ R = __QSUB16(T, S);
+
+ _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ out1 = __SMUAD(coeff, R) >> 16;
+ out2 = __SMUSDX(coeff, R);
+
+#else
+
+ out1 = __SMUSDX(R, coeff) >> 16u;
+ out2 = __SMUAD(coeff, R);
+
+#endif // #ifndef ARM_MATH_BIG_ENDIAN
+
+ _SIMD32_OFFSET(pSrc + (2u * l)) =
+ (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
+
+ coeff = _SIMD32_OFFSET(pCoef + (ia * 2u));
+
+ ia = ia + twidCoefModifier;
+
+ // loop for butterfly
+ i++;
+ l++;
+
+ T = _SIMD32_OFFSET(pSrc + (2 * i));
+ in = ((int16_t) (T & 0xFFFF)) >> 1;
+ T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF);
+
+ S = _SIMD32_OFFSET(pSrc + (2 * l));
+ in = ((int16_t) (S & 0xFFFF)) >> 1;
+ S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF);
+
+ R = __QSUB16(T, S);
+
+ _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ out1 = __SMUAD(coeff, R) >> 16;
+ out2 = __SMUSDX(coeff, R);
+
+#else
+
+ out1 = __SMUSDX(R, coeff) >> 16u;
+ out2 = __SMUAD(coeff, R);
+
+#endif // #ifndef ARM_MATH_BIG_ENDIAN
+
+ _SIMD32_OFFSET(pSrc + (2u * l)) =
+ (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
+
+ } // groups loop end
+
+ twidCoefModifier = twidCoefModifier << 1u;
+
+ // loop for stage
+ for (k = fftLen / 2; k > 2; k = k >> 1)
+ {
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ // loop for groups
+ for (j = 0; j < n2; j++)
+ {
+ coeff = _SIMD32_OFFSET(pCoef + (ia * 2u));
+
+ ia = ia + twidCoefModifier;
+
+ // loop for butterfly
+ for (i = j; i < fftLen; i += n1)
+ {
+ l = i + n2;
+
+ T = _SIMD32_OFFSET(pSrc + (2 * i));
+
+ S = _SIMD32_OFFSET(pSrc + (2 * l));
+
+ R = __QSUB16(T, S);
+
+ _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ out1 = __SMUAD(coeff, R) >> 16;
+ out2 = __SMUSDX(coeff, R);
+
+#else
+
+ out1 = __SMUSDX(R, coeff) >> 16u;
+ out2 = __SMUAD(coeff, R);
+
+#endif // #ifndef ARM_MATH_BIG_ENDIAN
+
+ _SIMD32_OFFSET(pSrc + (2u * l)) =
+ (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
+
+ i += n1;
+
+ l = i + n2;
+
+ T = _SIMD32_OFFSET(pSrc + (2 * i));
+
+ S = _SIMD32_OFFSET(pSrc + (2 * l));
+
+ R = __QSUB16(T, S);
+
+ _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ out1 = __SMUAD(coeff, R) >> 16;
+ out2 = __SMUSDX(coeff, R);
+
+#else
+
+ out1 = __SMUSDX(R, coeff) >> 16u;
+ out2 = __SMUAD(coeff, R);
+
+#endif // #ifndef ARM_MATH_BIG_ENDIAN
+
+ _SIMD32_OFFSET(pSrc + (2u * l)) =
+ (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
+
+ } // butterfly loop end
+
+ } // groups loop end
+
+ twidCoefModifier = twidCoefModifier << 1u;
+ } // stages loop end
+
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ coeff = _SIMD32_OFFSET(pCoef + (ia * 2u));
+
+ ia = ia + twidCoefModifier;
+
+ // loop for butterfly
+ for (i = 0; i < fftLen; i += n1)
+ {
+ l = i + n2;
+
+ T = _SIMD32_OFFSET(pSrc + (2 * i));
+
+ S = _SIMD32_OFFSET(pSrc + (2 * l));
+
+ R = __QSUB16(T, S);
+
+ _SIMD32_OFFSET(pSrc + (2 * i)) = __QADD16(T, S);
+
+ _SIMD32_OFFSET(pSrc + (2u * l)) = R;
+
+ i += n1;
+ l = i + n2;
+
+ T = _SIMD32_OFFSET(pSrc + (2 * i));
+
+ S = _SIMD32_OFFSET(pSrc + (2 * l));
+
+ R = __QSUB16(T, S);
+
+ _SIMD32_OFFSET(pSrc + (2 * i)) = __QADD16(T, S);
+
+ _SIMD32_OFFSET(pSrc + (2u * l)) = R;
+
+ } // groups loop end
+
+
+#else
+
+ unsigned i, j, k, l;
+ unsigned n1, n2, ia;
+ q15_t xt, yt, cosVal, sinVal;
+
+
+ //N = fftLen;
+ n2 = fftLen;
+
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ // loop for groups
+ for (j = 0; j < n2; j++)
+ {
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+ ia = ia + twidCoefModifier;
+
+ // loop for butterfly
+ for (i = j; i < fftLen; i += n1)
+ {
+ l = i + n2;
+ xt = (pSrc[2 * i] >> 1u) - (pSrc[2 * l] >> 1u);
+ pSrc[2 * i] = ((pSrc[2 * i] >> 1u) + (pSrc[2 * l] >> 1u)) >> 1u;
+
+ yt = (pSrc[2 * i + 1] >> 1u) - (pSrc[2 * l + 1] >> 1u);
+ pSrc[2 * i + 1] =
+ ((pSrc[2 * l + 1] >> 1u) + (pSrc[2 * i + 1] >> 1u)) >> 1u;
+
+ pSrc[2u * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) +
+ ((int16_t) (((q31_t) yt * sinVal) >> 16)));
+
+ pSrc[2u * l + 1u] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) -
+ ((int16_t) (((q31_t) xt * sinVal) >> 16)));
+
+ } // butterfly loop end
+
+ } // groups loop end
+
+ twidCoefModifier = twidCoefModifier << 1u;
+
+ // loop for stage
+ for (k = fftLen / 2; k > 2; k = k >> 1)
+ {
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ // loop for groups
+ for (j = 0; j < n2; j++)
+ {
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+ ia = ia + twidCoefModifier;
+
+ // loop for butterfly
+ for (i = j; i < fftLen; i += n1)
+ {
+ l = i + n2;
+ xt = pSrc[2 * i] - pSrc[2 * l];
+ pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1u;
+
+ yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
+ pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1u;
+
+ pSrc[2u * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) +
+ ((int16_t) (((q31_t) yt * sinVal) >> 16)));
+
+ pSrc[2u * l + 1u] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) -
+ ((int16_t) (((q31_t) xt * sinVal) >> 16)));
+
+ } // butterfly loop end
+
+ } // groups loop end
+
+ twidCoefModifier = twidCoefModifier << 1u;
+ } // stages loop end
+
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ // loop for groups
+ for (j = 0; j < n2; j++)
+ {
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+
+ ia = ia + twidCoefModifier;
+
+ // loop for butterfly
+ for (i = j; i < fftLen; i += n1)
+ {
+ l = i + n2;
+ xt = pSrc[2 * i] - pSrc[2 * l];
+ pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
+
+ yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
+ pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
+
+ pSrc[2u * l] = xt;
+
+ pSrc[2u * l + 1u] = yt;
+
+ } // butterfly loop end
+
+ } // groups loop end
+
+ twidCoefModifier = twidCoefModifier << 1u;
+
+#endif // #ifndef ARM_MATH_CM0_FAMILY
+
+}
+
+
+void arm_radix2_butterfly_inverse_q15(
+ q15_t * pSrc,
+ uint32_t fftLen,
+ q15_t * pCoef,
+ uint16_t twidCoefModifier)
+{
+#ifndef ARM_MATH_CM0_FAMILY
+
+ unsigned i, j, k, l;
+ unsigned n1, n2, ia;
+ q15_t in;
+ q31_t T, S, R;
+ q31_t coeff, out1, out2;
+
+ //N = fftLen;
+ n2 = fftLen;
+
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ // loop for groups
+ for (i = 0; i < n2; i++)
+ {
+ coeff = _SIMD32_OFFSET(pCoef + (ia * 2u));
+
+ ia = ia + twidCoefModifier;
+
+ l = i + n2;
+
+ T = _SIMD32_OFFSET(pSrc + (2 * i));
+ in = ((int16_t) (T & 0xFFFF)) >> 1;
+ T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF);
+
+ S = _SIMD32_OFFSET(pSrc + (2 * l));
+ in = ((int16_t) (S & 0xFFFF)) >> 1;
+ S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF);
+
+ R = __QSUB16(T, S);
+
+ _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ out1 = __SMUSD(coeff, R) >> 16;
+ out2 = __SMUADX(coeff, R);
+#else
+
+ out1 = __SMUADX(R, coeff) >> 16u;
+ out2 = __SMUSD(__QSUB(0, coeff), R);
+
+#endif // #ifndef ARM_MATH_BIG_ENDIAN
+
+ _SIMD32_OFFSET(pSrc + (2u * l)) =
+ (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
+
+ coeff = _SIMD32_OFFSET(pCoef + (ia * 2u));
+
+ ia = ia + twidCoefModifier;
+
+ // loop for butterfly
+ i++;
+ l++;
+
+ T = _SIMD32_OFFSET(pSrc + (2 * i));
+ in = ((int16_t) (T & 0xFFFF)) >> 1;
+ T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF);
+
+ S = _SIMD32_OFFSET(pSrc + (2 * l));
+ in = ((int16_t) (S & 0xFFFF)) >> 1;
+ S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF);
+
+ R = __QSUB16(T, S);
+
+ _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ out1 = __SMUSD(coeff, R) >> 16;
+ out2 = __SMUADX(coeff, R);
+#else
+
+ out1 = __SMUADX(R, coeff) >> 16u;
+ out2 = __SMUSD(__QSUB(0, coeff), R);
+
+#endif // #ifndef ARM_MATH_BIG_ENDIAN
+
+ _SIMD32_OFFSET(pSrc + (2u * l)) =
+ (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
+
+ } // groups loop end
+
+ twidCoefModifier = twidCoefModifier << 1u;
+
+ // loop for stage
+ for (k = fftLen / 2; k > 2; k = k >> 1)
+ {
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ // loop for groups
+ for (j = 0; j < n2; j++)
+ {
+ coeff = _SIMD32_OFFSET(pCoef + (ia * 2u));
+
+ ia = ia + twidCoefModifier;
+
+ // loop for butterfly
+ for (i = j; i < fftLen; i += n1)
+ {
+ l = i + n2;
+
+ T = _SIMD32_OFFSET(pSrc + (2 * i));
+
+ S = _SIMD32_OFFSET(pSrc + (2 * l));
+
+ R = __QSUB16(T, S);
+
+ _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ out1 = __SMUSD(coeff, R) >> 16;
+ out2 = __SMUADX(coeff, R);
+
+#else
+
+ out1 = __SMUADX(R, coeff) >> 16u;
+ out2 = __SMUSD(__QSUB(0, coeff), R);
+
+#endif // #ifndef ARM_MATH_BIG_ENDIAN
+
+ _SIMD32_OFFSET(pSrc + (2u * l)) =
+ (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
+
+ i += n1;
+
+ l = i + n2;
+
+ T = _SIMD32_OFFSET(pSrc + (2 * i));
+
+ S = _SIMD32_OFFSET(pSrc + (2 * l));
+
+ R = __QSUB16(T, S);
+
+ _SIMD32_OFFSET(pSrc + (2 * i)) = __SHADD16(T, S);
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ out1 = __SMUSD(coeff, R) >> 16;
+ out2 = __SMUADX(coeff, R);
+#else
+
+ out1 = __SMUADX(R, coeff) >> 16u;
+ out2 = __SMUSD(__QSUB(0, coeff), R);
+
+#endif // #ifndef ARM_MATH_BIG_ENDIAN
+
+ _SIMD32_OFFSET(pSrc + (2u * l)) =
+ (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
+
+ } // butterfly loop end
+
+ } // groups loop end
+
+ twidCoefModifier = twidCoefModifier << 1u;
+ } // stages loop end
+
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ // loop for groups
+ for (j = 0; j < n2; j++)
+ {
+ coeff = _SIMD32_OFFSET(pCoef + (ia * 2u));
+
+ ia = ia + twidCoefModifier;
+
+ // loop for butterfly
+ for (i = j; i < fftLen; i += n1)
+ {
+ l = i + n2;
+
+ T = _SIMD32_OFFSET(pSrc + (2 * i));
+
+ S = _SIMD32_OFFSET(pSrc + (2 * l));
+
+ R = __QSUB16(T, S);
+
+ _SIMD32_OFFSET(pSrc + (2 * i)) = __QADD16(T, S);
+
+ _SIMD32_OFFSET(pSrc + (2u * l)) = R;
+
+ } // butterfly loop end
+
+ } // groups loop end
+
+ twidCoefModifier = twidCoefModifier << 1u;
+
+#else
+
+
+ unsigned i, j, k, l;
+ unsigned n1, n2, ia;
+ q15_t xt, yt, cosVal, sinVal;
+
+ //N = fftLen;
+ n2 = fftLen;
+
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ // loop for groups
+ for (j = 0; j < n2; j++)
+ {
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+ ia = ia + twidCoefModifier;
+
+ // loop for butterfly
+ for (i = j; i < fftLen; i += n1)
+ {
+ l = i + n2;
+ xt = (pSrc[2 * i] >> 1u) - (pSrc[2 * l] >> 1u);
+ pSrc[2 * i] = ((pSrc[2 * i] >> 1u) + (pSrc[2 * l] >> 1u)) >> 1u;
+
+ yt = (pSrc[2 * i + 1] >> 1u) - (pSrc[2 * l + 1] >> 1u);
+ pSrc[2 * i + 1] =
+ ((pSrc[2 * l + 1] >> 1u) + (pSrc[2 * i + 1] >> 1u)) >> 1u;
+
+ pSrc[2u * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) -
+ ((int16_t) (((q31_t) yt * sinVal) >> 16)));
+
+ pSrc[2u * l + 1u] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) +
+ ((int16_t) (((q31_t) xt * sinVal) >> 16)));
+
+ } // butterfly loop end
+
+ } // groups loop end
+
+ twidCoefModifier = twidCoefModifier << 1u;
+
+ // loop for stage
+ for (k = fftLen / 2; k > 2; k = k >> 1)
+ {
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ // loop for groups
+ for (j = 0; j < n2; j++)
+ {
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+ ia = ia + twidCoefModifier;
+
+ // loop for butterfly
+ for (i = j; i < fftLen; i += n1)
+ {
+ l = i + n2;
+ xt = pSrc[2 * i] - pSrc[2 * l];
+ pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1u;
+
+ yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
+ pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1u;
+
+ pSrc[2u * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) -
+ ((int16_t) (((q31_t) yt * sinVal) >> 16)));
+
+ pSrc[2u * l + 1u] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) +
+ ((int16_t) (((q31_t) xt * sinVal) >> 16)));
+
+ } // butterfly loop end
+
+ } // groups loop end
+
+ twidCoefModifier = twidCoefModifier << 1u;
+ } // stages loop end
+
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+
+ ia = ia + twidCoefModifier;
+
+ // loop for butterfly
+ for (i = 0; i < fftLen; i += n1)
+ {
+ l = i + n2;
+ xt = pSrc[2 * i] - pSrc[2 * l];
+ pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
+
+ yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
+ pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
+
+ pSrc[2u * l] = xt;
+
+ pSrc[2u * l + 1u] = yt;
+
+ } // groups loop end
+
+
+#endif // #ifndef ARM_MATH_CM0_FAMILY
+
+}
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_q31.c
new file mode 100644
index 0000000..e72408f
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_q31.c
@@ -0,0 +1,351 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_cfft_radix2_q31.c
+*
+* Description: Radix-2 Decimation in Frequency CFFT & CIFFT Fixed point processing function
+*
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+void arm_radix2_butterfly_q31(
+ q31_t * pSrc,
+ uint32_t fftLen,
+ q31_t * pCoef,
+ uint16_t twidCoefModifier);
+
+void arm_radix2_butterfly_inverse_q31(
+ q31_t * pSrc,
+ uint32_t fftLen,
+ q31_t * pCoef,
+ uint16_t twidCoefModifier);
+
+void arm_bitreversal_q31(
+ q31_t * pSrc,
+ uint32_t fftLen,
+ uint16_t bitRevFactor,
+ uint16_t * pBitRevTab);
+
+/**
+* @ingroup groupTransforms
+*/
+
+/**
+* @addtogroup ComplexFFT
+* @{
+*/
+
+/**
+* @details
+* @brief Processing function for the fixed-point CFFT/CIFFT.
+* @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q31 and will be removed
+* @param[in] *S points to an instance of the fixed-point CFFT/CIFFT structure.
+* @param[in, out] *pSrc points to the complex data buffer of size 2*fftLen
. Processing occurs in-place.
+* @return none.
+*/
+
+void arm_cfft_radix2_q31(
+const arm_cfft_radix2_instance_q31 * S,
+q31_t * pSrc)
+{
+
+ if(S->ifftFlag == 1u)
+ {
+ arm_radix2_butterfly_inverse_q31(pSrc, S->fftLen,
+ S->pTwiddle, S->twidCoefModifier);
+ }
+ else
+ {
+ arm_radix2_butterfly_q31(pSrc, S->fftLen,
+ S->pTwiddle, S->twidCoefModifier);
+ }
+
+ arm_bitreversal_q31(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
+}
+
+/**
+* @} end of ComplexFFT group
+*/
+
+void arm_radix2_butterfly_q31(
+q31_t * pSrc,
+uint32_t fftLen,
+q31_t * pCoef,
+uint16_t twidCoefModifier)
+{
+
+ unsigned i, j, k, l, m;
+ unsigned n1, n2, ia;
+ q31_t xt, yt, cosVal, sinVal;
+ q31_t p0, p1;
+
+ //N = fftLen;
+ n2 = fftLen;
+
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ // loop for groups
+ for (i = 0; i < n2; i++)
+ {
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+ ia = ia + twidCoefModifier;
+
+ l = i + n2;
+ xt = (pSrc[2 * i] >> 1u) - (pSrc[2 * l] >> 1u);
+ pSrc[2 * i] = ((pSrc[2 * i] >> 1u) + (pSrc[2 * l] >> 1u)) >> 1u;
+
+ yt = (pSrc[2 * i + 1] >> 1u) - (pSrc[2 * l + 1] >> 1u);
+ pSrc[2 * i + 1] =
+ ((pSrc[2 * l + 1] >> 1u) + (pSrc[2 * i + 1] >> 1u)) >> 1u;
+
+ mult_32x32_keep32_R(p0, xt, cosVal);
+ mult_32x32_keep32_R(p1, yt, cosVal);
+ multAcc_32x32_keep32_R(p0, yt, sinVal);
+ multSub_32x32_keep32_R(p1, xt, sinVal);
+
+ pSrc[2u * l] = p0;
+ pSrc[2u * l + 1u] = p1;
+
+ } // groups loop end
+
+ twidCoefModifier <<= 1u;
+
+ // loop for stage
+ for (k = fftLen / 2; k > 2; k = k >> 1)
+ {
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ // loop for groups
+ for (j = 0; j < n2; j++)
+ {
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+ ia = ia + twidCoefModifier;
+
+ // loop for butterfly
+ i = j;
+ m = fftLen / n1;
+ do
+ {
+ l = i + n2;
+ xt = pSrc[2 * i] - pSrc[2 * l];
+ pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1u;
+
+ yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
+ pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1u;
+
+ mult_32x32_keep32_R(p0, xt, cosVal);
+ mult_32x32_keep32_R(p1, yt, cosVal);
+ multAcc_32x32_keep32_R(p0, yt, sinVal);
+ multSub_32x32_keep32_R(p1, xt, sinVal);
+
+ pSrc[2u * l] = p0;
+ pSrc[2u * l + 1u] = p1;
+ i += n1;
+ m--;
+ } while( m > 0); // butterfly loop end
+
+ } // groups loop end
+
+ twidCoefModifier <<= 1u;
+ } // stages loop end
+
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+ ia = ia + twidCoefModifier;
+
+ // loop for butterfly
+ for (i = 0; i < fftLen; i += n1)
+ {
+ l = i + n2;
+ xt = pSrc[2 * i] - pSrc[2 * l];
+ pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
+
+ yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
+ pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
+
+ pSrc[2u * l] = xt;
+
+ pSrc[2u * l + 1u] = yt;
+
+ i += n1;
+ l = i + n2;
+
+ xt = pSrc[2 * i] - pSrc[2 * l];
+ pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
+
+ yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
+ pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
+
+ pSrc[2u * l] = xt;
+
+ pSrc[2u * l + 1u] = yt;
+
+ } // butterfly loop end
+
+}
+
+
+void arm_radix2_butterfly_inverse_q31(
+q31_t * pSrc,
+uint32_t fftLen,
+q31_t * pCoef,
+uint16_t twidCoefModifier)
+{
+
+ unsigned i, j, k, l;
+ unsigned n1, n2, ia;
+ q31_t xt, yt, cosVal, sinVal;
+ q31_t p0, p1;
+
+ //N = fftLen;
+ n2 = fftLen;
+
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ // loop for groups
+ for (i = 0; i < n2; i++)
+ {
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+ ia = ia + twidCoefModifier;
+
+ l = i + n2;
+ xt = (pSrc[2 * i] >> 1u) - (pSrc[2 * l] >> 1u);
+ pSrc[2 * i] = ((pSrc[2 * i] >> 1u) + (pSrc[2 * l] >> 1u)) >> 1u;
+
+ yt = (pSrc[2 * i + 1] >> 1u) - (pSrc[2 * l + 1] >> 1u);
+ pSrc[2 * i + 1] =
+ ((pSrc[2 * l + 1] >> 1u) + (pSrc[2 * i + 1] >> 1u)) >> 1u;
+
+ mult_32x32_keep32_R(p0, xt, cosVal);
+ mult_32x32_keep32_R(p1, yt, cosVal);
+ multSub_32x32_keep32_R(p0, yt, sinVal);
+ multAcc_32x32_keep32_R(p1, xt, sinVal);
+
+ pSrc[2u * l] = p0;
+ pSrc[2u * l + 1u] = p1;
+ } // groups loop end
+
+ twidCoefModifier = twidCoefModifier << 1u;
+
+ // loop for stage
+ for (k = fftLen / 2; k > 2; k = k >> 1)
+ {
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ // loop for groups
+ for (j = 0; j < n2; j++)
+ {
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+ ia = ia + twidCoefModifier;
+
+ // loop for butterfly
+ for (i = j; i < fftLen; i += n1)
+ {
+ l = i + n2;
+ xt = pSrc[2 * i] - pSrc[2 * l];
+ pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1u;
+
+ yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
+ pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1u;
+
+ mult_32x32_keep32_R(p0, xt, cosVal);
+ mult_32x32_keep32_R(p1, yt, cosVal);
+ multSub_32x32_keep32_R(p0, yt, sinVal);
+ multAcc_32x32_keep32_R(p1, xt, sinVal);
+
+ pSrc[2u * l] = p0;
+ pSrc[2u * l + 1u] = p1;
+ } // butterfly loop end
+
+ } // groups loop end
+
+ twidCoefModifier = twidCoefModifier << 1u;
+ } // stages loop end
+
+ n1 = n2;
+ n2 = n2 >> 1;
+ ia = 0;
+
+ cosVal = pCoef[ia * 2];
+ sinVal = pCoef[(ia * 2) + 1];
+ ia = ia + twidCoefModifier;
+
+ // loop for butterfly
+ for (i = 0; i < fftLen; i += n1)
+ {
+ l = i + n2;
+ xt = pSrc[2 * i] - pSrc[2 * l];
+ pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
+
+ yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
+ pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
+
+ pSrc[2u * l] = xt;
+
+ pSrc[2u * l + 1u] = yt;
+
+ i += n1;
+ l = i + n2;
+
+ xt = pSrc[2 * i] - pSrc[2 * l];
+ pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
+
+ yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
+ pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
+
+ pSrc[2u * l] = xt;
+
+ pSrc[2u * l + 1u] = yt;
+
+ } // butterfly loop end
+
+}
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_f32.c
new file mode 100644
index 0000000..b0f0a94
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_f32.c
@@ -0,0 +1,1210 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_cfft_radix4_f32.c
+*
+* Description: Radix-4 Decimation in Frequency CFFT & CIFFT Floating point processing function
+*
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+extern void arm_bitreversal_f32(
+float32_t * pSrc,
+uint16_t fftSize,
+uint16_t bitRevFactor,
+uint16_t * pBitRevTab);
+
+/**
+* @ingroup groupTransforms
+*/
+
+/* ----------------------------------------------------------------------
+** Internal helper function used by the FFTs
+** ------------------------------------------------------------------- */
+
+/*
+* @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)
+{
+
+ float32_t co1, co2, co3, si1, si2, si3;
+ uint32_t ia1, ia2, ia3;
+ uint32_t i0, i1, i2, i3;
+ uint32_t n1, n2, j, k;
+
+#ifndef ARM_MATH_CM0_FAMILY_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ float32_t xaIn, yaIn, xbIn, ybIn, xcIn, ycIn, xdIn, ydIn;
+ float32_t Xaplusc, Xbplusd, Yaplusc, Ybplusd, Xaminusc, Xbminusd, Yaminusc,
+ Ybminusd;
+ float32_t Xb12C_out, Yb12C_out, Xc12C_out, Yc12C_out, Xd12C_out, Yd12C_out;
+ float32_t Xb12_out, Yb12_out, Xc12_out, Yc12_out, Xd12_out, Yd12_out;
+ float32_t *ptr1;
+ float32_t p0,p1,p2,p3,p4,p5;
+ float32_t a0,a1,a2,a3,a4,a5,a6,a7;
+
+ /* Initializations for the first stage */
+ n2 = fftLen;
+ n1 = n2;
+
+ /* n2 = fftLen/4 */
+ n2 >>= 2u;
+ i0 = 0u;
+ ia1 = 0u;
+
+ j = n2;
+
+ /* Calculation of first stage */
+ do
+ {
+ /* index calculation for the input as, */
+ /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
+ i1 = i0 + n2;
+ i2 = i1 + n2;
+ i3 = i2 + n2;
+
+ xaIn = pSrc[(2u * i0)];
+ yaIn = pSrc[(2u * i0) + 1u];
+
+ xbIn = pSrc[(2u * i1)];
+ ybIn = pSrc[(2u * i1) + 1u];
+
+ xcIn = pSrc[(2u * i2)];
+ ycIn = pSrc[(2u * i2) + 1u];
+
+ xdIn = pSrc[(2u * i3)];
+ ydIn = pSrc[(2u * i3) + 1u];
+
+ /* xa + xc */
+ Xaplusc = xaIn + xcIn;
+ /* xb + xd */
+ Xbplusd = xbIn + xdIn;
+ /* ya + yc */
+ Yaplusc = yaIn + ycIn;
+ /* yb + yd */
+ Ybplusd = ybIn + ydIn;
+
+ /* index calculation for the coefficients */
+ ia2 = ia1 + ia1;
+ co2 = pCoef[ia2 * 2u];
+ si2 = pCoef[(ia2 * 2u) + 1u];
+
+ /* xa - xc */
+ Xaminusc = xaIn - xcIn;
+ /* xb - xd */
+ Xbminusd = xbIn - xdIn;
+ /* ya - yc */
+ Yaminusc = yaIn - ycIn;
+ /* yb - yd */
+ Ybminusd = ybIn - ydIn;
+
+ /* xa' = xa + xb + xc + xd */
+ pSrc[(2u * i0)] = Xaplusc + Xbplusd;
+ /* ya' = ya + yb + yc + yd */
+ pSrc[(2u * i0) + 1u] = Yaplusc + Ybplusd;
+
+ /* (xa - xc) + (yb - yd) */
+ Xb12C_out = (Xaminusc + Ybminusd);
+ /* (ya - yc) + (xb - xd) */
+ Yb12C_out = (Yaminusc - Xbminusd);
+ /* (xa + xc) - (xb + xd) */
+ Xc12C_out = (Xaplusc - Xbplusd);
+ /* (ya + yc) - (yb + yd) */
+ Yc12C_out = (Yaplusc - Ybplusd);
+ /* (xa - xc) - (yb - yd) */
+ Xd12C_out = (Xaminusc - Ybminusd);
+ /* (ya - yc) + (xb - xd) */
+ Yd12C_out = (Xbminusd + Yaminusc);
+
+ co1 = pCoef[ia1 * 2u];
+ si1 = pCoef[(ia1 * 2u) + 1u];
+
+ /* index calculation for the coefficients */
+ ia3 = ia2 + ia1;
+ co3 = pCoef[ia3 * 2u];
+ si3 = pCoef[(ia3 * 2u) + 1u];
+
+ Xb12_out = Xb12C_out * co1;
+ Yb12_out = Yb12C_out * co1;
+ Xc12_out = Xc12C_out * co2;
+ Yc12_out = Yc12C_out * co2;
+ Xd12_out = Xd12C_out * co3;
+ Yd12_out = Yd12C_out * co3;
+
+ /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
+ //Xb12_out -= Yb12C_out * si1;
+ p0 = Yb12C_out * si1;
+ /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
+ //Yb12_out += Xb12C_out * si1;
+ p1 = Xb12C_out * si1;
+ /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
+ //Xc12_out -= Yc12C_out * si2;
+ p2 = Yc12C_out * si2;
+ /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
+ //Yc12_out += Xc12C_out * si2;
+ p3 = Xc12C_out * si2;
+ /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
+ //Xd12_out -= Yd12C_out * si3;
+ p4 = Yd12C_out * si3;
+ /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
+ //Yd12_out += Xd12C_out * si3;
+ p5 = Xd12C_out * si3;
+
+ Xb12_out += p0;
+ Yb12_out -= p1;
+ Xc12_out += p2;
+ Yc12_out -= p3;
+ Xd12_out += p4;
+ Yd12_out -= p5;
+
+ /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */
+ pSrc[2u * i1] = Xc12_out;
+
+ /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */
+ pSrc[(2u * i1) + 1u] = Yc12_out;
+
+ /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */
+ pSrc[2u * i2] = Xb12_out;
+
+ /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */
+ pSrc[(2u * i2) + 1u] = Yb12_out;
+
+ /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */
+ pSrc[2u * i3] = Xd12_out;
+
+ /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */
+ pSrc[(2u * i3) + 1u] = Yd12_out;
+
+ /* Twiddle coefficients index modifier */
+ ia1 += twidCoefModifier;
+
+ /* Updating input index */
+ i0++;
+
+ }
+ while(--j);
+
+ twidCoefModifier <<= 2u;
+
+ /* Calculation of second stage to excluding last stage */
+ for (k = fftLen >> 2u; k > 4u; k >>= 2u)
+ {
+ /* Initializations for the first stage */
+ n1 = n2;
+ n2 >>= 2u;
+ ia1 = 0u;
+
+ /* Calculation of first stage */
+ j = 0;
+ do
+ {
+ /* index calculation for the coefficients */
+ ia2 = ia1 + ia1;
+ ia3 = ia2 + ia1;
+ co1 = pCoef[ia1 * 2u];
+ si1 = pCoef[(ia1 * 2u) + 1u];
+ co2 = pCoef[ia2 * 2u];
+ si2 = pCoef[(ia2 * 2u) + 1u];
+ co3 = pCoef[ia3 * 2u];
+ si3 = pCoef[(ia3 * 2u) + 1u];
+
+ /* Twiddle coefficients index modifier */
+ ia1 += twidCoefModifier;
+
+ i0 = j;
+ do
+ {
+ /* index calculation for the input as, */
+ /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
+ i1 = i0 + n2;
+ i2 = i1 + n2;
+ i3 = i2 + n2;
+
+ xaIn = pSrc[(2u * i0)];
+ yaIn = pSrc[(2u * i0) + 1u];
+
+ xbIn = pSrc[(2u * i1)];
+ ybIn = pSrc[(2u * i1) + 1u];
+
+ xcIn = pSrc[(2u * i2)];
+ ycIn = pSrc[(2u * i2) + 1u];
+
+ xdIn = pSrc[(2u * i3)];
+ ydIn = pSrc[(2u * i3) + 1u];
+
+ /* xa - xc */
+ Xaminusc = xaIn - xcIn;
+ /* (xb - xd) */
+ Xbminusd = xbIn - xdIn;
+ /* ya - yc */
+ Yaminusc = yaIn - ycIn;
+ /* (yb - yd) */
+ Ybminusd = ybIn - ydIn;
+
+ /* xa + xc */
+ Xaplusc = xaIn + xcIn;
+ /* xb + xd */
+ Xbplusd = xbIn + xdIn;
+ /* ya + yc */
+ Yaplusc = yaIn + ycIn;
+ /* yb + yd */
+ Ybplusd = ybIn + ydIn;
+
+ /* (xa - xc) + (yb - yd) */
+ Xb12C_out = (Xaminusc + Ybminusd);
+ /* (ya - yc) - (xb - xd) */
+ Yb12C_out = (Yaminusc - Xbminusd);
+ /* xa + xc -(xb + xd) */
+ Xc12C_out = (Xaplusc - Xbplusd);
+ /* (ya + yc) - (yb + yd) */
+ Yc12C_out = (Yaplusc - Ybplusd);
+ /* (xa - xc) - (yb - yd) */
+ Xd12C_out = (Xaminusc - Ybminusd);
+ /* (ya - yc) + (xb - xd) */
+ Yd12C_out = (Xbminusd + Yaminusc);
+
+ pSrc[(2u * i0)] = Xaplusc + Xbplusd;
+ pSrc[(2u * i0) + 1u] = Yaplusc + Ybplusd;
+
+ Xb12_out = Xb12C_out * co1;
+ Yb12_out = Yb12C_out * co1;
+ Xc12_out = Xc12C_out * co2;
+ Yc12_out = Yc12C_out * co2;
+ Xd12_out = Xd12C_out * co3;
+ Yd12_out = Yd12C_out * co3;
+
+ /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
+ //Xb12_out -= Yb12C_out * si1;
+ p0 = Yb12C_out * si1;
+ /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
+ //Yb12_out += Xb12C_out * si1;
+ p1 = Xb12C_out * si1;
+ /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
+ //Xc12_out -= Yc12C_out * si2;
+ p2 = Yc12C_out * si2;
+ /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
+ //Yc12_out += Xc12C_out * si2;
+ p3 = Xc12C_out * si2;
+ /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
+ //Xd12_out -= Yd12C_out * si3;
+ p4 = Yd12C_out * si3;
+ /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
+ //Yd12_out += Xd12C_out * si3;
+ p5 = Xd12C_out * si3;
+
+ Xb12_out += p0;
+ Yb12_out -= p1;
+ Xc12_out += p2;
+ Yc12_out -= p3;
+ Xd12_out += p4;
+ Yd12_out -= p5;
+
+ /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */
+ pSrc[2u * i1] = Xc12_out;
+
+ /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */
+ pSrc[(2u * i1) + 1u] = Yc12_out;
+
+ /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */
+ pSrc[2u * i2] = Xb12_out;
+
+ /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */
+ pSrc[(2u * i2) + 1u] = Yb12_out;
+
+ /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */
+ pSrc[2u * i3] = Xd12_out;
+
+ /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */
+ pSrc[(2u * i3) + 1u] = Yd12_out;
+
+ i0 += n1;
+ } while(i0 < fftLen);
+ j++;
+ } while(j <= (n2 - 1u));
+ twidCoefModifier <<= 2u;
+ }
+
+ j = fftLen >> 2;
+ ptr1 = &pSrc[0];
+
+ /* Calculations of last stage */
+ do
+ {
+ xaIn = ptr1[0];
+ yaIn = ptr1[1];
+ xbIn = ptr1[2];
+ ybIn = ptr1[3];
+ xcIn = ptr1[4];
+ ycIn = ptr1[5];
+ xdIn = ptr1[6];
+ ydIn = ptr1[7];
+
+ /* xa + xc */
+ Xaplusc = xaIn + xcIn;
+
+ /* xa - xc */
+ Xaminusc = xaIn - xcIn;
+
+ /* ya + yc */
+ Yaplusc = yaIn + ycIn;
+
+ /* ya - yc */
+ Yaminusc = yaIn - ycIn;
+
+ /* xb + xd */
+ Xbplusd = xbIn + xdIn;
+
+ /* yb + yd */
+ Ybplusd = ybIn + ydIn;
+
+ /* (xb-xd) */
+ Xbminusd = xbIn - xdIn;
+
+ /* (yb-yd) */
+ Ybminusd = ybIn - ydIn;
+
+ /* xa' = xa + xb + xc + xd */
+ a0 = (Xaplusc + Xbplusd);
+ /* ya' = ya + yb + yc + yd */
+ a1 = (Yaplusc + Ybplusd);
+ /* xc' = (xa-xb+xc-xd) */
+ a2 = (Xaplusc - Xbplusd);
+ /* yc' = (ya-yb+yc-yd) */
+ a3 = (Yaplusc - Ybplusd);
+ /* xb' = (xa+yb-xc-yd) */
+ a4 = (Xaminusc + Ybminusd);
+ /* yb' = (ya-xb-yc+xd) */
+ a5 = (Yaminusc - Xbminusd);
+ /* xd' = (xa-yb-xc+yd)) */
+ a6 = (Xaminusc - Ybminusd);
+ /* yd' = (ya+xb-yc-xd) */
+ a7 = (Xbminusd + Yaminusc);
+
+ ptr1[0] = a0;
+ ptr1[1] = a1;
+ ptr1[2] = a2;
+ ptr1[3] = a3;
+ ptr1[4] = a4;
+ ptr1[5] = a5;
+ ptr1[6] = a6;
+ ptr1[7] = a7;
+
+ /* increment pointer by 8 */
+ ptr1 += 8u;
+ } while(--j);
+
+#else
+
+ float32_t t1, t2, r1, r2, s1, s2;
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Initializations for the fft calculation */
+ n2 = fftLen;
+ n1 = n2;
+ for (k = fftLen; k > 1u; k >>= 2u)
+ {
+ /* Initializations for the fft calculation */
+ n1 = n2;
+ n2 >>= 2u;
+ ia1 = 0u;
+
+ /* FFT Calculation */
+ j = 0;
+ do
+ {
+ /* index calculation for the coefficients */
+ ia2 = ia1 + ia1;
+ ia3 = ia2 + ia1;
+ co1 = pCoef[ia1 * 2u];
+ si1 = pCoef[(ia1 * 2u) + 1u];
+ co2 = pCoef[ia2 * 2u];
+ si2 = pCoef[(ia2 * 2u) + 1u];
+ co3 = pCoef[ia3 * 2u];
+ si3 = pCoef[(ia3 * 2u) + 1u];
+
+ /* Twiddle coefficients index modifier */
+ ia1 = ia1 + twidCoefModifier;
+
+ i0 = j;
+ do
+ {
+ /* index calculation for the input as, */
+ /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
+ i1 = i0 + n2;
+ i2 = i1 + n2;
+ i3 = i2 + n2;
+
+ /* xa + xc */
+ r1 = pSrc[(2u * i0)] + pSrc[(2u * i2)];
+
+ /* xa - xc */
+ r2 = pSrc[(2u * i0)] - pSrc[(2u * i2)];
+
+ /* ya + yc */
+ s1 = pSrc[(2u * i0) + 1u] + pSrc[(2u * i2) + 1u];
+
+ /* ya - yc */
+ s2 = pSrc[(2u * i0) + 1u] - pSrc[(2u * i2) + 1u];
+
+ /* xb + xd */
+ t1 = pSrc[2u * i1] + pSrc[2u * i3];
+
+ /* xa' = xa + xb + xc + xd */
+ pSrc[2u * i0] = r1 + t1;
+
+ /* xa + xc -(xb + xd) */
+ r1 = r1 - t1;
+
+ /* yb + yd */
+ t2 = pSrc[(2u * i1) + 1u] + pSrc[(2u * i3) + 1u];
+
+ /* ya' = ya + yb + yc + yd */
+ pSrc[(2u * i0) + 1u] = s1 + t2;
+
+ /* (ya + yc) - (yb + yd) */
+ s1 = s1 - t2;
+
+ /* (yb - yd) */
+ t1 = pSrc[(2u * i1) + 1u] - pSrc[(2u * i3) + 1u];
+
+ /* (xb - xd) */
+ t2 = pSrc[2u * i1] - pSrc[2u * i3];
+
+ /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */
+ pSrc[2u * i1] = (r1 * co2) + (s1 * si2);
+
+ /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */
+ pSrc[(2u * i1) + 1u] = (s1 * co2) - (r1 * si2);
+
+ /* (xa - xc) + (yb - yd) */
+ r1 = r2 + t1;
+
+ /* (xa - xc) - (yb - yd) */
+ r2 = r2 - t1;
+
+ /* (ya - yc) - (xb - xd) */
+ s1 = s2 - t2;
+
+ /* (ya - yc) + (xb - xd) */
+ s2 = s2 + t2;
+
+ /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */
+ pSrc[2u * i2] = (r1 * co1) + (s1 * si1);
+
+ /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */
+ pSrc[(2u * i2) + 1u] = (s1 * co1) - (r1 * si1);
+
+ /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */
+ pSrc[2u * i3] = (r2 * co3) + (s2 * si3);
+
+ /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */
+ pSrc[(2u * i3) + 1u] = (s2 * co3) - (r2 * si3);
+
+ i0 += n1;
+ } while( i0 < fftLen);
+ j++;
+ } while(j <= (n2 - 1u));
+ twidCoefModifier <<= 2u;
+ }
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY_FAMILY */
+
+}
+
+/*
+* @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)
+{
+ float32_t co1, co2, co3, si1, si2, si3;
+ uint32_t ia1, ia2, ia3;
+ uint32_t i0, i1, i2, i3;
+ uint32_t n1, n2, j, k;
+
+#ifndef ARM_MATH_CM0_FAMILY_FAMILY
+
+ float32_t xaIn, yaIn, xbIn, ybIn, xcIn, ycIn, xdIn, ydIn;
+ float32_t Xaplusc, Xbplusd, Yaplusc, Ybplusd, Xaminusc, Xbminusd, Yaminusc,
+ Ybminusd;
+ float32_t Xb12C_out, Yb12C_out, Xc12C_out, Yc12C_out, Xd12C_out, Yd12C_out;
+ float32_t Xb12_out, Yb12_out, Xc12_out, Yc12_out, Xd12_out, Yd12_out;
+ float32_t *ptr1;
+ float32_t p0,p1,p2,p3,p4,p5,p6,p7;
+ float32_t a0,a1,a2,a3,a4,a5,a6,a7;
+
+
+ /* Initializations for the first stage */
+ n2 = fftLen;
+ n1 = n2;
+
+ /* n2 = fftLen/4 */
+ n2 >>= 2u;
+ i0 = 0u;
+ ia1 = 0u;
+
+ j = n2;
+
+ /* Calculation of first stage */
+ do
+ {
+ /* index calculation for the input as, */
+ /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
+ i1 = i0 + n2;
+ i2 = i1 + n2;
+ i3 = i2 + n2;
+
+ /* Butterfly implementation */
+ xaIn = pSrc[(2u * i0)];
+ yaIn = pSrc[(2u * i0) + 1u];
+
+ xcIn = pSrc[(2u * i2)];
+ ycIn = pSrc[(2u * i2) + 1u];
+
+ xbIn = pSrc[(2u * i1)];
+ ybIn = pSrc[(2u * i1) + 1u];
+
+ xdIn = pSrc[(2u * i3)];
+ ydIn = pSrc[(2u * i3) + 1u];
+
+ /* xa + xc */
+ Xaplusc = xaIn + xcIn;
+ /* xb + xd */
+ Xbplusd = xbIn + xdIn;
+ /* ya + yc */
+ Yaplusc = yaIn + ycIn;
+ /* yb + yd */
+ Ybplusd = ybIn + ydIn;
+
+ /* index calculation for the coefficients */
+ ia2 = ia1 + ia1;
+ co2 = pCoef[ia2 * 2u];
+ si2 = pCoef[(ia2 * 2u) + 1u];
+
+ /* xa - xc */
+ Xaminusc = xaIn - xcIn;
+ /* xb - xd */
+ Xbminusd = xbIn - xdIn;
+ /* ya - yc */
+ Yaminusc = yaIn - ycIn;
+ /* yb - yd */
+ Ybminusd = ybIn - ydIn;
+
+ /* xa' = xa + xb + xc + xd */
+ pSrc[(2u * i0)] = Xaplusc + Xbplusd;
+
+ /* ya' = ya + yb + yc + yd */
+ pSrc[(2u * i0) + 1u] = Yaplusc + Ybplusd;
+
+ /* (xa - xc) - (yb - yd) */
+ Xb12C_out = (Xaminusc - Ybminusd);
+ /* (ya - yc) + (xb - xd) */
+ Yb12C_out = (Yaminusc + Xbminusd);
+ /* (xa + xc) - (xb + xd) */
+ Xc12C_out = (Xaplusc - Xbplusd);
+ /* (ya + yc) - (yb + yd) */
+ Yc12C_out = (Yaplusc - Ybplusd);
+ /* (xa - xc) + (yb - yd) */
+ Xd12C_out = (Xaminusc + Ybminusd);
+ /* (ya - yc) - (xb - xd) */
+ Yd12C_out = (Yaminusc - Xbminusd);
+
+ co1 = pCoef[ia1 * 2u];
+ si1 = pCoef[(ia1 * 2u) + 1u];
+
+ /* index calculation for the coefficients */
+ ia3 = ia2 + ia1;
+ co3 = pCoef[ia3 * 2u];
+ si3 = pCoef[(ia3 * 2u) + 1u];
+
+ Xb12_out = Xb12C_out * co1;
+ Yb12_out = Yb12C_out * co1;
+ Xc12_out = Xc12C_out * co2;
+ Yc12_out = Yc12C_out * co2;
+ Xd12_out = Xd12C_out * co3;
+ Yd12_out = Yd12C_out * co3;
+
+ /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
+ //Xb12_out -= Yb12C_out * si1;
+ p0 = Yb12C_out * si1;
+ /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
+ //Yb12_out += Xb12C_out * si1;
+ p1 = Xb12C_out * si1;
+ /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
+ //Xc12_out -= Yc12C_out * si2;
+ p2 = Yc12C_out * si2;
+ /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
+ //Yc12_out += Xc12C_out * si2;
+ p3 = Xc12C_out * si2;
+ /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
+ //Xd12_out -= Yd12C_out * si3;
+ p4 = Yd12C_out * si3;
+ /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
+ //Yd12_out += Xd12C_out * si3;
+ p5 = Xd12C_out * si3;
+
+ Xb12_out -= p0;
+ Yb12_out += p1;
+ Xc12_out -= p2;
+ Yc12_out += p3;
+ Xd12_out -= p4;
+ Yd12_out += p5;
+
+ /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
+ pSrc[2u * i1] = Xc12_out;
+
+ /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
+ pSrc[(2u * i1) + 1u] = Yc12_out;
+
+ /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
+ pSrc[2u * i2] = Xb12_out;
+
+ /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
+ pSrc[(2u * i2) + 1u] = Yb12_out;
+
+ /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
+ pSrc[2u * i3] = Xd12_out;
+
+ /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
+ pSrc[(2u * i3) + 1u] = Yd12_out;
+
+ /* Twiddle coefficients index modifier */
+ ia1 = ia1 + twidCoefModifier;
+
+ /* Updating input index */
+ i0 = i0 + 1u;
+
+ } while(--j);
+
+ twidCoefModifier <<= 2u;
+
+ /* Calculation of second stage to excluding last stage */
+ for (k = fftLen >> 2u; k > 4u; k >>= 2u)
+ {
+ /* Initializations for the first stage */
+ n1 = n2;
+ n2 >>= 2u;
+ ia1 = 0u;
+
+ /* Calculation of first stage */
+ j = 0;
+ do
+ {
+ /* index calculation for the coefficients */
+ ia2 = ia1 + ia1;
+ ia3 = ia2 + ia1;
+ co1 = pCoef[ia1 * 2u];
+ si1 = pCoef[(ia1 * 2u) + 1u];
+ co2 = pCoef[ia2 * 2u];
+ si2 = pCoef[(ia2 * 2u) + 1u];
+ co3 = pCoef[ia3 * 2u];
+ si3 = pCoef[(ia3 * 2u) + 1u];
+
+ /* Twiddle coefficients index modifier */
+ ia1 = ia1 + twidCoefModifier;
+
+ i0 = j;
+ do
+ {
+ /* index calculation for the input as, */
+ /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
+ i1 = i0 + n2;
+ i2 = i1 + n2;
+ i3 = i2 + n2;
+
+ xaIn = pSrc[(2u * i0)];
+ yaIn = pSrc[(2u * i0) + 1u];
+
+ xbIn = pSrc[(2u * i1)];
+ ybIn = pSrc[(2u * i1) + 1u];
+
+ xcIn = pSrc[(2u * i2)];
+ ycIn = pSrc[(2u * i2) + 1u];
+
+ xdIn = pSrc[(2u * i3)];
+ ydIn = pSrc[(2u * i3) + 1u];
+
+ /* xa - xc */
+ Xaminusc = xaIn - xcIn;
+ /* (xb - xd) */
+ Xbminusd = xbIn - xdIn;
+ /* ya - yc */
+ Yaminusc = yaIn - ycIn;
+ /* (yb - yd) */
+ Ybminusd = ybIn - ydIn;
+
+ /* xa + xc */
+ Xaplusc = xaIn + xcIn;
+ /* xb + xd */
+ Xbplusd = xbIn + xdIn;
+ /* ya + yc */
+ Yaplusc = yaIn + ycIn;
+ /* yb + yd */
+ Ybplusd = ybIn + ydIn;
+
+ /* (xa - xc) - (yb - yd) */
+ Xb12C_out = (Xaminusc - Ybminusd);
+ /* (ya - yc) + (xb - xd) */
+ Yb12C_out = (Yaminusc + Xbminusd);
+ /* xa + xc -(xb + xd) */
+ Xc12C_out = (Xaplusc - Xbplusd);
+ /* (ya + yc) - (yb + yd) */
+ Yc12C_out = (Yaplusc - Ybplusd);
+ /* (xa - xc) + (yb - yd) */
+ Xd12C_out = (Xaminusc + Ybminusd);
+ /* (ya - yc) - (xb - xd) */
+ Yd12C_out = (Yaminusc - Xbminusd);
+
+ pSrc[(2u * i0)] = Xaplusc + Xbplusd;
+ pSrc[(2u * i0) + 1u] = Yaplusc + Ybplusd;
+
+ Xb12_out = Xb12C_out * co1;
+ Yb12_out = Yb12C_out * co1;
+ Xc12_out = Xc12C_out * co2;
+ Yc12_out = Yc12C_out * co2;
+ Xd12_out = Xd12C_out * co3;
+ Yd12_out = Yd12C_out * co3;
+
+ /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
+ //Xb12_out -= Yb12C_out * si1;
+ p0 = Yb12C_out * si1;
+ /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
+ //Yb12_out += Xb12C_out * si1;
+ p1 = Xb12C_out * si1;
+ /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
+ //Xc12_out -= Yc12C_out * si2;
+ p2 = Yc12C_out * si2;
+ /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
+ //Yc12_out += Xc12C_out * si2;
+ p3 = Xc12C_out * si2;
+ /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
+ //Xd12_out -= Yd12C_out * si3;
+ p4 = Yd12C_out * si3;
+ /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
+ //Yd12_out += Xd12C_out * si3;
+ p5 = Xd12C_out * si3;
+
+ Xb12_out -= p0;
+ Yb12_out += p1;
+ Xc12_out -= p2;
+ Yc12_out += p3;
+ Xd12_out -= p4;
+ Yd12_out += p5;
+
+ /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
+ pSrc[2u * i1] = Xc12_out;
+
+ /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
+ pSrc[(2u * i1) + 1u] = Yc12_out;
+
+ /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
+ pSrc[2u * i2] = Xb12_out;
+
+ /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
+ pSrc[(2u * i2) + 1u] = Yb12_out;
+
+ /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
+ pSrc[2u * i3] = Xd12_out;
+
+ /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
+ pSrc[(2u * i3) + 1u] = Yd12_out;
+
+ i0 += n1;
+ } while(i0 < fftLen);
+ j++;
+ } while(j <= (n2 - 1u));
+ twidCoefModifier <<= 2u;
+ }
+ /* Initializations of last stage */
+
+ j = fftLen >> 2;
+ ptr1 = &pSrc[0];
+
+ /* Calculations of last stage */
+ do
+ {
+ xaIn = ptr1[0];
+ yaIn = ptr1[1];
+ xbIn = ptr1[2];
+ ybIn = ptr1[3];
+ xcIn = ptr1[4];
+ ycIn = ptr1[5];
+ xdIn = ptr1[6];
+ ydIn = ptr1[7];
+
+ /* Butterfly implementation */
+ /* xa + xc */
+ Xaplusc = xaIn + xcIn;
+
+ /* xa - xc */
+ Xaminusc = xaIn - xcIn;
+
+ /* ya + yc */
+ Yaplusc = yaIn + ycIn;
+
+ /* ya - yc */
+ Yaminusc = yaIn - ycIn;
+
+ /* xb + xd */
+ Xbplusd = xbIn + xdIn;
+
+ /* yb + yd */
+ Ybplusd = ybIn + ydIn;
+
+ /* (xb-xd) */
+ Xbminusd = xbIn - xdIn;
+
+ /* (yb-yd) */
+ Ybminusd = ybIn - ydIn;
+
+ /* xa' = (xa+xb+xc+xd) * onebyfftLen */
+ a0 = (Xaplusc + Xbplusd);
+ /* ya' = (ya+yb+yc+yd) * onebyfftLen */
+ a1 = (Yaplusc + Ybplusd);
+ /* xc' = (xa-xb+xc-xd) * onebyfftLen */
+ a2 = (Xaplusc - Xbplusd);
+ /* yc' = (ya-yb+yc-yd) * onebyfftLen */
+ a3 = (Yaplusc - Ybplusd);
+ /* xb' = (xa-yb-xc+yd) * onebyfftLen */
+ a4 = (Xaminusc - Ybminusd);
+ /* yb' = (ya+xb-yc-xd) * onebyfftLen */
+ a5 = (Yaminusc + Xbminusd);
+ /* xd' = (xa-yb-xc+yd) * onebyfftLen */
+ a6 = (Xaminusc + Ybminusd);
+ /* yd' = (ya-xb-yc+xd) * onebyfftLen */
+ a7 = (Yaminusc - Xbminusd);
+
+ p0 = a0 * onebyfftLen;
+ p1 = a1 * onebyfftLen;
+ p2 = a2 * onebyfftLen;
+ p3 = a3 * onebyfftLen;
+ p4 = a4 * onebyfftLen;
+ p5 = a5 * onebyfftLen;
+ p6 = a6 * onebyfftLen;
+ p7 = a7 * onebyfftLen;
+
+ /* xa' = (xa+xb+xc+xd) * onebyfftLen */
+ ptr1[0] = p0;
+ /* ya' = (ya+yb+yc+yd) * onebyfftLen */
+ ptr1[1] = p1;
+ /* xc' = (xa-xb+xc-xd) * onebyfftLen */
+ ptr1[2] = p2;
+ /* yc' = (ya-yb+yc-yd) * onebyfftLen */
+ ptr1[3] = p3;
+ /* xb' = (xa-yb-xc+yd) * onebyfftLen */
+ ptr1[4] = p4;
+ /* yb' = (ya+xb-yc-xd) * onebyfftLen */
+ ptr1[5] = p5;
+ /* xd' = (xa-yb-xc+yd) * onebyfftLen */
+ ptr1[6] = p6;
+ /* yd' = (ya-xb-yc+xd) * onebyfftLen */
+ ptr1[7] = p7;
+
+ /* increment source pointer by 8 for next calculations */
+ ptr1 = ptr1 + 8u;
+
+ } while(--j);
+
+#else
+
+ float32_t t1, t2, r1, r2, s1, s2;
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Initializations for the first stage */
+ n2 = fftLen;
+ n1 = n2;
+
+ /* Calculation of first stage */
+ for (k = fftLen; k > 4u; k >>= 2u)
+ {
+ /* Initializations for the first stage */
+ n1 = n2;
+ n2 >>= 2u;
+ ia1 = 0u;
+
+ /* Calculation of first stage */
+ j = 0;
+ do
+ {
+ /* index calculation for the coefficients */
+ ia2 = ia1 + ia1;
+ ia3 = ia2 + ia1;
+ co1 = pCoef[ia1 * 2u];
+ si1 = pCoef[(ia1 * 2u) + 1u];
+ co2 = pCoef[ia2 * 2u];
+ si2 = pCoef[(ia2 * 2u) + 1u];
+ co3 = pCoef[ia3 * 2u];
+ si3 = pCoef[(ia3 * 2u) + 1u];
+
+ /* Twiddle coefficients index modifier */
+ ia1 = ia1 + twidCoefModifier;
+
+ i0 = j;
+ do
+ {
+ /* index calculation for the input as, */
+ /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
+ i1 = i0 + n2;
+ i2 = i1 + n2;
+ i3 = i2 + n2;
+
+ /* xa + xc */
+ r1 = pSrc[(2u * i0)] + pSrc[(2u * i2)];
+
+ /* xa - xc */
+ r2 = pSrc[(2u * i0)] - pSrc[(2u * i2)];
+
+ /* ya + yc */
+ s1 = pSrc[(2u * i0) + 1u] + pSrc[(2u * i2) + 1u];
+
+ /* ya - yc */
+ s2 = pSrc[(2u * i0) + 1u] - pSrc[(2u * i2) + 1u];
+
+ /* xb + xd */
+ t1 = pSrc[2u * i1] + pSrc[2u * i3];
+
+ /* xa' = xa + xb + xc + xd */
+ pSrc[2u * i0] = r1 + t1;
+
+ /* xa + xc -(xb + xd) */
+ r1 = r1 - t1;
+
+ /* yb + yd */
+ t2 = pSrc[(2u * i1) + 1u] + pSrc[(2u * i3) + 1u];
+
+ /* ya' = ya + yb + yc + yd */
+ pSrc[(2u * i0) + 1u] = s1 + t2;
+
+ /* (ya + yc) - (yb + yd) */
+ s1 = s1 - t2;
+
+ /* (yb - yd) */
+ t1 = pSrc[(2u * i1) + 1u] - pSrc[(2u * i3) + 1u];
+
+ /* (xb - xd) */
+ t2 = pSrc[2u * i1] - pSrc[2u * i3];
+
+ /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
+ pSrc[2u * i1] = (r1 * co2) - (s1 * si2);
+
+ /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
+ pSrc[(2u * i1) + 1u] = (s1 * co2) + (r1 * si2);
+
+ /* (xa - xc) - (yb - yd) */
+ r1 = r2 - t1;
+
+ /* (xa - xc) + (yb - yd) */
+ r2 = r2 + t1;
+
+ /* (ya - yc) + (xb - xd) */
+ s1 = s2 + t2;
+
+ /* (ya - yc) - (xb - xd) */
+ s2 = s2 - t2;
+
+ /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
+ pSrc[2u * i2] = (r1 * co1) - (s1 * si1);
+
+ /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
+ pSrc[(2u * i2) + 1u] = (s1 * co1) + (r1 * si1);
+
+ /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
+ pSrc[2u * i3] = (r2 * co3) - (s2 * si3);
+
+ /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
+ pSrc[(2u * i3) + 1u] = (s2 * co3) + (r2 * si3);
+
+ i0 += n1;
+ } while( i0 < fftLen);
+ j++;
+ } while(j <= (n2 - 1u));
+ twidCoefModifier <<= 2u;
+ }
+ /* Initializations of last stage */
+ n1 = n2;
+ n2 >>= 2u;
+
+ /* Calculations of last stage */
+ for (i0 = 0u; i0 <= (fftLen - n1); i0 += n1)
+ {
+ /* index calculation for the input as, */
+ /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */
+ i1 = i0 + n2;
+ i2 = i1 + n2;
+ i3 = i2 + n2;
+
+ /* Butterfly implementation */
+ /* xa + xc */
+ r1 = pSrc[2u * i0] + pSrc[2u * i2];
+
+ /* xa - xc */
+ r2 = pSrc[2u * i0] - pSrc[2u * i2];
+
+ /* ya + yc */
+ s1 = pSrc[(2u * i0) + 1u] + pSrc[(2u * i2) + 1u];
+
+ /* ya - yc */
+ s2 = pSrc[(2u * i0) + 1u] - pSrc[(2u * i2) + 1u];
+
+ /* xc + xd */
+ t1 = pSrc[2u * i1] + pSrc[2u * i3];
+
+ /* xa' = xa + xb + xc + xd */
+ pSrc[2u * i0] = (r1 + t1) * onebyfftLen;
+
+ /* (xa + xb) - (xc + xd) */
+ r1 = r1 - t1;
+
+ /* yb + yd */
+ t2 = pSrc[(2u * i1) + 1u] + pSrc[(2u * i3) + 1u];
+
+ /* ya' = ya + yb + yc + yd */
+ pSrc[(2u * i0) + 1u] = (s1 + t2) * onebyfftLen;
+
+ /* (ya + yc) - (yb + yd) */
+ s1 = s1 - t2;
+
+ /* (yb-yd) */
+ t1 = pSrc[(2u * i1) + 1u] - pSrc[(2u * i3) + 1u];
+
+ /* (xb-xd) */
+ t2 = pSrc[2u * i1] - pSrc[2u * i3];
+
+ /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */
+ pSrc[2u * i1] = r1 * onebyfftLen;
+
+ /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */
+ pSrc[(2u * i1) + 1u] = s1 * onebyfftLen;
+
+ /* (xa - xc) - (yb-yd) */
+ r1 = r2 - t1;
+
+ /* (xa - xc) + (yb-yd) */
+ r2 = r2 + t1;
+
+ /* (ya - yc) + (xb-xd) */
+ s1 = s2 + t2;
+
+ /* (ya - yc) - (xb-xd) */
+ s2 = s2 - t2;
+
+ /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */
+ pSrc[2u * i2] = r1 * onebyfftLen;
+
+ /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */
+ pSrc[(2u * i2) + 1u] = s1 * onebyfftLen;
+
+ /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */
+ pSrc[2u * i3] = r2 * onebyfftLen;
+
+ /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */
+ pSrc[(2u * i3) + 1u] = s2 * onebyfftLen;
+ }
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY_FAMILY */
+}
+
+/**
+* @addtogroup ComplexFFT
+* @{
+*/
+
+/**
+* @details
+* @brief Processing function for the floating-point Radix-4 CFFT/CIFFT.
+* @deprecated Do not use this function. It has been superseded by \ref arm_cfft_f32 and will be removed
+* in the future.
+* @param[in] *S points to an instance of the floating-point Radix-4 CFFT/CIFFT structure.
+* @param[in, out] *pSrc points to the complex data buffer of size 2*fftLen
. Processing occurs in-place.
+* @return none.
+*/
+
+void arm_cfft_radix4_f32(
+const arm_cfft_radix4_instance_f32 * S,
+float32_t * pSrc)
+{
+
+ if(S->ifftFlag == 1u)
+ {
+ /* Complex IFFT radix-4 */
+ arm_radix4_butterfly_inverse_f32(pSrc, S->fftLen, S->pTwiddle,
+ S->twidCoefModifier, S->onebyfftLen);
+ }
+ else
+ {
+ /* Complex FFT radix-4 */
+ arm_radix4_butterfly_f32(pSrc, S->fftLen, S->pTwiddle,
+ S->twidCoefModifier);
+ }
+
+ if(S->bitReverseFlag == 1u)
+ {
+ /* Bit Reversal */
+ arm_bitreversal_f32(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
+ }
+
+}
+
+/**
+* @} end of ComplexFFT group
+*/
+
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_f32.c
new file mode 100644
index 0000000..815c3d2
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_f32.c
@@ -0,0 +1,165 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_cfft_radix4_init_f32.c
+*
+* Description: Radix-4 Decimation in Frequency Floating-point CFFT & CIFFT Initialization function
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+#include "arm_common_tables.h"
+
+/**
+ * @ingroup groupTransforms
+ */
+
+/**
+ * @addtogroup ComplexFFT
+ * @{
+ */
+
+/**
+* @brief Initialization function for the floating-point CFFT/CIFFT.
+* @deprecated Do not use this function. It has been superceded by \ref arm_cfft_f32 and will be removed
+* in the future.
+* @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.
+*
+* \par Description:
+* \par
+* The parameter ifftFlag
controls whether a forward or inverse transform is computed.
+* Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated
+* \par
+* The parameter bitReverseFlag
controls whether output is in normal order or bit reversed order.
+* Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order.
+* \par
+* The parameter fftLen
Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024.
+* \par
+* This Function also initializes Twiddle factor table pointer and Bit reversal table pointer.
+*/
+
+arm_status arm_cfft_radix4_init_f32(
+ arm_cfft_radix4_instance_f32 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag)
+{
+ /* Initialise the default arm status */
+ arm_status status = ARM_MATH_SUCCESS;
+
+ /* Initialise the FFT length */
+ S->fftLen = fftLen;
+
+ /* Initialise the Twiddle coefficient pointer */
+ S->pTwiddle = (float32_t *) twiddleCoef;
+
+ /* Initialise the Flag for selection of CFFT or CIFFT */
+ S->ifftFlag = ifftFlag;
+
+ /* Initialise the Flag for calculation Bit reversal or not */
+ S->bitReverseFlag = bitReverseFlag;
+
+ /* Initializations of structure parameters depending on the FFT length */
+ switch (S->fftLen)
+ {
+
+ case 4096u:
+ /* Initializations of structure parameters for 4096 point FFT */
+
+ /* Initialise the twiddle coef modifier value */
+ S->twidCoefModifier = 1u;
+ /* Initialise the bit reversal table modifier */
+ S->bitRevFactor = 1u;
+ /* Initialise the bit reversal table pointer */
+ S->pBitRevTable = (uint16_t *) armBitRevTable;
+ /* Initialise the 1/fftLen Value */
+ S->onebyfftLen = 0.000244140625;
+ break;
+
+ case 1024u:
+ /* Initializations of structure parameters for 1024 point FFT */
+
+ /* Initialise the twiddle coef modifier value */
+ S->twidCoefModifier = 4u;
+ /* Initialise the bit reversal table modifier */
+ S->bitRevFactor = 4u;
+ /* Initialise the bit reversal table pointer */
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[3];
+ /* Initialise the 1/fftLen Value */
+ S->onebyfftLen = 0.0009765625f;
+ break;
+
+
+ case 256u:
+ /* Initializations of structure parameters for 256 point FFT */
+ S->twidCoefModifier = 16u;
+ S->bitRevFactor = 16u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[15];
+ S->onebyfftLen = 0.00390625f;
+ break;
+
+ case 64u:
+ /* Initializations of structure parameters for 64 point FFT */
+ S->twidCoefModifier = 64u;
+ S->bitRevFactor = 64u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[63];
+ S->onebyfftLen = 0.015625f;
+ break;
+
+ case 16u:
+ /* Initializations of structure parameters for 16 point FFT */
+ S->twidCoefModifier = 256u;
+ S->bitRevFactor = 256u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[255];
+ S->onebyfftLen = 0.0625f;
+ break;
+
+
+ default:
+ /* Reporting argument error if fftSize is not valid value */
+ status = ARM_MATH_ARGUMENT_ERROR;
+ break;
+ }
+
+ return (status);
+}
+
+/**
+ * @} end of ComplexFFT group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_q15.c
new file mode 100644
index 0000000..791480e
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_q15.c
@@ -0,0 +1,152 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_cfft_radix4_init_q15.c
+*
+* Description: Radix-4 Decimation in Frequency Q15 FFT & IFFT initialization function
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+#include "arm_common_tables.h"
+
+/**
+ * @ingroup groupTransforms
+ */
+
+
+/**
+ * @addtogroup ComplexFFT
+ * @{
+ */
+
+
+/**
+* @brief Initialization function for the Q15 CFFT/CIFFT.
+* @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q15 and will be removed
+* @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 The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen
is not a supported value.
+*
+* \par Description:
+* \par
+* The parameter ifftFlag
controls whether a forward or inverse transform is computed.
+* Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated
+* \par
+* The parameter bitReverseFlag
controls whether output is in normal order or bit reversed order.
+* Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order.
+* \par
+* The parameter fftLen
Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024.
+* \par
+* This Function also initializes Twiddle factor table pointer and Bit reversal table pointer.
+*/
+
+arm_status arm_cfft_radix4_init_q15(
+ arm_cfft_radix4_instance_q15 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag)
+{
+ /* Initialise the default arm status */
+ arm_status status = ARM_MATH_SUCCESS;
+ /* Initialise the FFT length */
+ S->fftLen = fftLen;
+ /* Initialise the Twiddle coefficient pointer */
+ S->pTwiddle = (q15_t *) twiddleCoef_4096_q15;
+ /* Initialise the Flag for selection of CFFT or CIFFT */
+ S->ifftFlag = ifftFlag;
+ /* Initialise the Flag for calculation Bit reversal or not */
+ S->bitReverseFlag = bitReverseFlag;
+
+ /* Initializations of structure parameters depending on the FFT length */
+ switch (S->fftLen)
+ {
+ case 4096u:
+ /* Initializations of structure parameters for 4096 point FFT */
+
+ /* Initialise the twiddle coef modifier value */
+ S->twidCoefModifier = 1u;
+ /* Initialise the bit reversal table modifier */
+ S->bitRevFactor = 1u;
+ /* Initialise the bit reversal table pointer */
+ S->pBitRevTable = (uint16_t *) armBitRevTable;
+
+ break;
+
+ case 1024u:
+ /* Initializations of structure parameters for 1024 point FFT */
+ S->twidCoefModifier = 4u;
+ S->bitRevFactor = 4u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[3];
+
+ break;
+
+ case 256u:
+ /* Initializations of structure parameters for 256 point FFT */
+ S->twidCoefModifier = 16u;
+ S->bitRevFactor = 16u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[15];
+
+ break;
+
+ case 64u:
+ /* Initializations of structure parameters for 64 point FFT */
+ S->twidCoefModifier = 64u;
+ S->bitRevFactor = 64u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[63];
+
+ break;
+
+ case 16u:
+ /* Initializations of structure parameters for 16 point FFT */
+ S->twidCoefModifier = 256u;
+ S->bitRevFactor = 256u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[255];
+
+ break;
+
+ default:
+ /* Reporting argument error if fftSize is not valid value */
+ status = ARM_MATH_ARGUMENT_ERROR;
+ break;
+ }
+
+ return (status);
+}
+
+/**
+ * @} end of ComplexFFT group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_q31.c
new file mode 100644
index 0000000..9674f6e
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_q31.c
@@ -0,0 +1,148 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_cfft_radix4_init_q31.c
+*
+* Description: Radix-4 Decimation in Frequency Q31 FFT & IFFT initialization function
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+#include "arm_common_tables.h"
+
+/**
+ * @ingroup groupTransforms
+ */
+
+/**
+ * @addtogroup ComplexFFT
+ * @{
+ */
+
+/**
+*
+* @brief Initialization function for the Q31 CFFT/CIFFT.
+* @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q31 and will be removed
+* @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 The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen
is not a supported value.
+*
+* \par Description:
+* \par
+* The parameter ifftFlag
controls whether a forward or inverse transform is computed.
+* Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated
+* \par
+* The parameter bitReverseFlag
controls whether output is in normal order or bit reversed order.
+* Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order.
+* \par
+* The parameter fftLen
Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024.
+* \par
+* This Function also initializes Twiddle factor table pointer and Bit reversal table pointer.
+*/
+
+arm_status arm_cfft_radix4_init_q31(
+ arm_cfft_radix4_instance_q31 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag)
+{
+ /* Initialise the default arm status */
+ arm_status status = ARM_MATH_SUCCESS;
+ /* Initialise the FFT length */
+ S->fftLen = fftLen;
+ /* Initialise the Twiddle coefficient pointer */
+ S->pTwiddle = (q31_t *) twiddleCoef_4096_q31;
+ /* Initialise the Flag for selection of CFFT or CIFFT */
+ S->ifftFlag = ifftFlag;
+ /* Initialise the Flag for calculation Bit reversal or not */
+ S->bitReverseFlag = bitReverseFlag;
+
+ /* Initializations of Instance structure depending on the FFT length */
+ switch (S->fftLen)
+ {
+ /* Initializations of structure parameters for 4096 point FFT */
+ case 4096u:
+ /* Initialise the twiddle coef modifier value */
+ S->twidCoefModifier = 1u;
+ /* Initialise the bit reversal table modifier */
+ S->bitRevFactor = 1u;
+ /* Initialise the bit reversal table pointer */
+ S->pBitRevTable = (uint16_t *) armBitRevTable;
+ break;
+
+ /* Initializations of structure parameters for 1024 point FFT */
+ case 1024u:
+ /* Initialise the twiddle coef modifier value */
+ S->twidCoefModifier = 4u;
+ /* Initialise the bit reversal table modifier */
+ S->bitRevFactor = 4u;
+ /* Initialise the bit reversal table pointer */
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[3];
+ break;
+
+ case 256u:
+ /* Initializations of structure parameters for 256 point FFT */
+ S->twidCoefModifier = 16u;
+ S->bitRevFactor = 16u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[15];
+ break;
+
+ case 64u:
+ /* Initializations of structure parameters for 64 point FFT */
+ S->twidCoefModifier = 64u;
+ S->bitRevFactor = 64u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[63];
+ break;
+
+ case 16u:
+ /* Initializations of structure parameters for 16 point FFT */
+ S->twidCoefModifier = 256u;
+ S->bitRevFactor = 256u;
+ S->pBitRevTable = (uint16_t *) & armBitRevTable[255];
+ break;
+
+ default:
+ /* Reporting argument error if fftSize is not valid value */
+ status = ARM_MATH_ARGUMENT_ERROR;
+ break;
+ }
+
+ return (status);
+}
+
+/**
+ * @} end of ComplexFFT group
+ */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_q31.c
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix8_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix8_f32.c
new file mode 100644
index 0000000..d811b92
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_cfft_radix8_f32.c
@@ -0,0 +1,384 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_cfft_radix8_f32.c
+*
+* Description: Radix-8 Decimation in Frequency CFFT & CIFFT Floating point processing function
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+* @ingroup groupTransforms
+*/
+
+/**
+* @defgroup Radix8_CFFT_CIFFT Radix-8 Complex FFT Functions
+*
+* \par
+* Complex Fast Fourier Transform(CFFT) and Complex Inverse Fast Fourier Transform(CIFFT) is an efficient algorithm to compute Discrete Fourier Transform(DFT) and Inverse Discrete Fourier Transform(IDFT).
+* Computational complexity of CFFT reduces drastically when compared to DFT.
+* \par
+* This set of functions implements CFFT/CIFFT
+* for floating-point data types. The functions operates on in-place buffer which uses same buffer for input and output.
+* Complex input is stored in input buffer in an interleaved fashion.
+*
+* \par
+* The functions operate on blocks of input and output data and each call to the function processes
+* 2*fftLen
samples through the transform. pSrc
points to In-place arrays containing 2*fftLen
values.
+* \par
+* The pSrc
points to the array of in-place buffer of size 2*fftLen
and inputs and outputs are stored in an interleaved fashion as shown below.
+* {real[0], imag[0], real[1], imag[1],..}
+*
+* \par Lengths supported by the transform:
+* \par
+* Internally, the function utilize a Radix-8 decimation in frequency(DIF) algorithm
+* and the size of the FFT supported are of the lengths [ 64, 512, 4096].
+*
+*
+* \par Algorithm:
+*
+* Complex Fast Fourier Transform:
+* \par
+* Input real and imaginary data:
+*
+* x(n) = xa + j * ya
+* x(n+N/4 ) = xb + j * yb
+* x(n+N/2 ) = xc + j * yc
+* x(n+3N 4) = xd + j * yd
+*
+* where N is length of FFT
+* \par
+* Output real and imaginary data:
+*
+* X(4r) = xa'+ j * ya'
+* X(4r+1) = xb'+ j * yb'
+* X(4r+2) = xc'+ j * yc'
+* X(4r+3) = xd'+ j * yd'
+*
+* \par
+* Twiddle factors for Radix-8 FFT:
+*
+* Wn = co1 + j * (- si1)
+* W2n = co2 + j * (- si2)
+* W3n = co3 + j * (- si3)
+*
+*
+* \par
+* \image html CFFT.gif "Radix-8 Decimation-in Frequency Complex Fast Fourier Transform"
+*
+* \par
+* Output from Radix-8 CFFT Results in Digit reversal order. Interchange middle two branches of every butterfly results in Bit reversed output.
+* \par
+* Butterfly CFFT equations:
+*
+* xa' = xa + xb + xc + xd
+* ya' = ya + yb + yc + yd
+* xc' = (xa+yb-xc-yd)* co1 + (ya-xb-yc+xd)* (si1)
+* yc' = (ya-xb-yc+xd)* co1 - (xa+yb-xc-yd)* (si1)
+* xb' = (xa-xb+xc-xd)* co2 + (ya-yb+yc-yd)* (si2)
+* yb' = (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2)
+* xd' = (xa-yb-xc+yd)* co3 + (ya+xb-yc-xd)* (si3)
+* yd' = (ya+xb-yc-xd)* co3 - (xa-yb-xc+yd)* (si3)
+*
+*
+* \par
+* where fftLen
length of CFFT/CIFFT; ifftFlag
Flag for selection of CFFT or CIFFT(Set ifftFlag to calculate CIFFT otherwise calculates CFFT);
+* bitReverseFlag
Flag for selection of output order(Set bitReverseFlag to output in normal order otherwise output in bit reversed order);
+* pTwiddle
points to array of twiddle coefficients; pBitRevTable
points to the array of bit reversal table.
+* twidCoefModifier
modifier for twiddle factor table which supports all FFT lengths with same table;
+* pBitRevTable
modifier for bit reversal table which supports all FFT lengths with same table.
+* onebyfftLen
value of 1/fftLen to calculate CIFFT;
+*
+* \par Fixed-Point Behavior
+* Care must be taken when using the fixed-point versions of the CFFT/CIFFT function.
+* Refer to the function specific documentation below for usage guidelines.
+*/
+
+
+/*
+* @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_radix8_butterfly_f32(
+float32_t * pSrc,
+uint16_t fftLen,
+const float32_t * pCoef,
+uint16_t twidCoefModifier)
+{
+ uint32_t ia1, ia2, ia3, ia4, ia5, ia6, ia7;
+ uint32_t i1, i2, i3, i4, i5, i6, i7, i8;
+ uint32_t id;
+ uint32_t n1, n2, j;
+
+ float32_t r1, r2, r3, r4, r5, r6, r7, r8;
+ float32_t t1, t2;
+ float32_t s1, s2, s3, s4, s5, s6, s7, s8;
+ float32_t p1, p2, p3, p4;
+ float32_t co2, co3, co4, co5, co6, co7, co8;
+ float32_t si2, si3, si4, si5, si6, si7, si8;
+ const float32_t C81 = 0.70710678118f;
+
+ n2 = fftLen;
+
+ do
+ {
+ n1 = n2;
+ n2 = n2 >> 3;
+ i1 = 0;
+
+ do
+ {
+ i2 = i1 + n2;
+ i3 = i2 + n2;
+ i4 = i3 + n2;
+ i5 = i4 + n2;
+ i6 = i5 + n2;
+ i7 = i6 + n2;
+ i8 = i7 + n2;
+ r1 = pSrc[2 * i1] + pSrc[2 * i5];
+ r5 = pSrc[2 * i1] - pSrc[2 * i5];
+ r2 = pSrc[2 * i2] + pSrc[2 * i6];
+ r6 = pSrc[2 * i2] - pSrc[2 * i6];
+ r3 = pSrc[2 * i3] + pSrc[2 * i7];
+ r7 = pSrc[2 * i3] - pSrc[2 * i7];
+ r4 = pSrc[2 * i4] + pSrc[2 * i8];
+ r8 = pSrc[2 * i4] - pSrc[2 * i8];
+ t1 = r1 - r3;
+ r1 = r1 + r3;
+ r3 = r2 - r4;
+ r2 = r2 + r4;
+ pSrc[2 * i1] = r1 + r2;
+ pSrc[2 * i5] = r1 - r2;
+ r1 = pSrc[2 * i1 + 1] + pSrc[2 * i5 + 1];
+ s5 = pSrc[2 * i1 + 1] - pSrc[2 * i5 + 1];
+ r2 = pSrc[2 * i2 + 1] + pSrc[2 * i6 + 1];
+ s6 = pSrc[2 * i2 + 1] - pSrc[2 * i6 + 1];
+ s3 = pSrc[2 * i3 + 1] + pSrc[2 * i7 + 1];
+ s7 = pSrc[2 * i3 + 1] - pSrc[2 * i7 + 1];
+ r4 = pSrc[2 * i4 + 1] + pSrc[2 * i8 + 1];
+ s8 = pSrc[2 * i4 + 1] - pSrc[2 * i8 + 1];
+ t2 = r1 - s3;
+ r1 = r1 + s3;
+ s3 = r2 - r4;
+ r2 = r2 + r4;
+ pSrc[2 * i1 + 1] = r1 + r2;
+ pSrc[2 * i5 + 1] = r1 - r2;
+ pSrc[2 * i3] = t1 + s3;
+ pSrc[2 * i7] = t1 - s3;
+ pSrc[2 * i3 + 1] = t2 - r3;
+ pSrc[2 * i7 + 1] = t2 + r3;
+ r1 = (r6 - r8) * C81;
+ r6 = (r6 + r8) * C81;
+ r2 = (s6 - s8) * C81;
+ s6 = (s6 + s8) * C81;
+ t1 = r5 - r1;
+ r5 = r5 + r1;
+ r8 = r7 - r6;
+ r7 = r7 + r6;
+ t2 = s5 - r2;
+ s5 = s5 + r2;
+ s8 = s7 - s6;
+ s7 = s7 + s6;
+ pSrc[2 * i2] = r5 + s7;
+ pSrc[2 * i8] = r5 - s7;
+ pSrc[2 * i6] = t1 + s8;
+ pSrc[2 * i4] = t1 - s8;
+ pSrc[2 * i2 + 1] = s5 - r7;
+ pSrc[2 * i8 + 1] = s5 + r7;
+ pSrc[2 * i6 + 1] = t2 - r8;
+ pSrc[2 * i4 + 1] = t2 + r8;
+
+ i1 += n1;
+ } while(i1 < fftLen);
+
+ if(n2 < 8)
+ break;
+
+ ia1 = 0;
+ j = 1;
+
+ do
+ {
+ /* index calculation for the coefficients */
+ id = ia1 + twidCoefModifier;
+ ia1 = id;
+ ia2 = ia1 + id;
+ ia3 = ia2 + id;
+ ia4 = ia3 + id;
+ ia5 = ia4 + id;
+ ia6 = ia5 + id;
+ ia7 = ia6 + id;
+
+ co2 = pCoef[2 * ia1];
+ co3 = pCoef[2 * ia2];
+ co4 = pCoef[2 * ia3];
+ co5 = pCoef[2 * ia4];
+ co6 = pCoef[2 * ia5];
+ co7 = pCoef[2 * ia6];
+ co8 = pCoef[2 * ia7];
+ si2 = pCoef[2 * ia1 + 1];
+ si3 = pCoef[2 * ia2 + 1];
+ si4 = pCoef[2 * ia3 + 1];
+ si5 = pCoef[2 * ia4 + 1];
+ si6 = pCoef[2 * ia5 + 1];
+ si7 = pCoef[2 * ia6 + 1];
+ si8 = pCoef[2 * ia7 + 1];
+
+ i1 = j;
+
+ do
+ {
+ /* index calculation for the input */
+ i2 = i1 + n2;
+ i3 = i2 + n2;
+ i4 = i3 + n2;
+ i5 = i4 + n2;
+ i6 = i5 + n2;
+ i7 = i6 + n2;
+ i8 = i7 + n2;
+ r1 = pSrc[2 * i1] + pSrc[2 * i5];
+ r5 = pSrc[2 * i1] - pSrc[2 * i5];
+ r2 = pSrc[2 * i2] + pSrc[2 * i6];
+ r6 = pSrc[2 * i2] - pSrc[2 * i6];
+ r3 = pSrc[2 * i3] + pSrc[2 * i7];
+ r7 = pSrc[2 * i3] - pSrc[2 * i7];
+ r4 = pSrc[2 * i4] + pSrc[2 * i8];
+ r8 = pSrc[2 * i4] - pSrc[2 * i8];
+ t1 = r1 - r3;
+ r1 = r1 + r3;
+ r3 = r2 - r4;
+ r2 = r2 + r4;
+ pSrc[2 * i1] = r1 + r2;
+ r2 = r1 - r2;
+ s1 = pSrc[2 * i1 + 1] + pSrc[2 * i5 + 1];
+ s5 = pSrc[2 * i1 + 1] - pSrc[2 * i5 + 1];
+ s2 = pSrc[2 * i2 + 1] + pSrc[2 * i6 + 1];
+ s6 = pSrc[2 * i2 + 1] - pSrc[2 * i6 + 1];
+ s3 = pSrc[2 * i3 + 1] + pSrc[2 * i7 + 1];
+ s7 = pSrc[2 * i3 + 1] - pSrc[2 * i7 + 1];
+ s4 = pSrc[2 * i4 + 1] + pSrc[2 * i8 + 1];
+ s8 = pSrc[2 * i4 + 1] - pSrc[2 * i8 + 1];
+ t2 = s1 - s3;
+ s1 = s1 + s3;
+ s3 = s2 - s4;
+ s2 = s2 + s4;
+ r1 = t1 + s3;
+ t1 = t1 - s3;
+ pSrc[2 * i1 + 1] = s1 + s2;
+ s2 = s1 - s2;
+ s1 = t2 - r3;
+ t2 = t2 + r3;
+ p1 = co5 * r2;
+ p2 = si5 * s2;
+ p3 = co5 * s2;
+ p4 = si5 * r2;
+ pSrc[2 * i5] = p1 + p2;
+ pSrc[2 * i5 + 1] = p3 - p4;
+ p1 = co3 * r1;
+ p2 = si3 * s1;
+ p3 = co3 * s1;
+ p4 = si3 * r1;
+ pSrc[2 * i3] = p1 + p2;
+ pSrc[2 * i3 + 1] = p3 - p4;
+ p1 = co7 * t1;
+ p2 = si7 * t2;
+ p3 = co7 * t2;
+ p4 = si7 * t1;
+ pSrc[2 * i7] = p1 + p2;
+ pSrc[2 * i7 + 1] = p3 - p4;
+ r1 = (r6 - r8) * C81;
+ r6 = (r6 + r8) * C81;
+ s1 = (s6 - s8) * C81;
+ s6 = (s6 + s8) * C81;
+ t1 = r5 - r1;
+ r5 = r5 + r1;
+ r8 = r7 - r6;
+ r7 = r7 + r6;
+ t2 = s5 - s1;
+ s5 = s5 + s1;
+ s8 = s7 - s6;
+ s7 = s7 + s6;
+ r1 = r5 + s7;
+ r5 = r5 - s7;
+ r6 = t1 + s8;
+ t1 = t1 - s8;
+ s1 = s5 - r7;
+ s5 = s5 + r7;
+ s6 = t2 - r8;
+ t2 = t2 + r8;
+ p1 = co2 * r1;
+ p2 = si2 * s1;
+ p3 = co2 * s1;
+ p4 = si2 * r1;
+ pSrc[2 * i2] = p1 + p2;
+ pSrc[2 * i2 + 1] = p3 - p4;
+ p1 = co8 * r5;
+ p2 = si8 * s5;
+ p3 = co8 * s5;
+ p4 = si8 * r5;
+ pSrc[2 * i8] = p1 + p2;
+ pSrc[2 * i8 + 1] = p3 - p4;
+ p1 = co6 * r6;
+ p2 = si6 * s6;
+ p3 = co6 * s6;
+ p4 = si6 * r6;
+ pSrc[2 * i6] = p1 + p2;
+ pSrc[2 * i6 + 1] = p3 - p4;
+ p1 = co4 * t1;
+ p2 = si4 * t2;
+ p3 = co4 * t2;
+ p4 = si4 * t1;
+ pSrc[2 * i4] = p1 + p2;
+ pSrc[2 * i4 + 1] = p3 - p4;
+
+ i1 += n1;
+ } while(i1 < fftLen);
+
+ j++;
+ } while(j < n2);
+
+ twidCoefModifier <<= 3;
+ } while(n2 > 7);
+}
+
+/**
+* @} end of Radix8_CFFT_CIFFT group
+*/
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_f32.c
new file mode 100644
index 0000000..91149cc
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_f32.c
@@ -0,0 +1,461 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_dct4_f32.c
+*
+* Description: Processing function of DCT4 & IDCT4 F32.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @ingroup groupTransforms
+ */
+
+/**
+ * @defgroup DCT4_IDCT4 DCT Type IV Functions
+ * Representation of signals by minimum number of values is important for storage and transmission.
+ * The possibility of large discontinuity between the beginning and end of a period of a signal
+ * in DFT can be avoided by extending the signal so that it is even-symmetric.
+ * Discrete Cosine Transform (DCT) is constructed such that its energy is heavily concentrated in the lower part of the
+ * spectrum and is very widely used in signal and image coding applications.
+ * The family of DCTs (DCT type- 1,2,3,4) is the outcome of different combinations of homogeneous boundary conditions.
+ * DCT has an excellent energy-packing capability, hence has many applications and in data compression in particular.
+ *
+ * DCT is essentially the Discrete Fourier Transform(DFT) of an even-extended real signal.
+ * Reordering of the input data makes the computation of DCT just a problem of
+ * computing the DFT of a real signal with a few additional operations.
+ * This approach provides regular, simple, and very efficient DCT algorithms for practical hardware and software implementations.
+ *
+ * DCT type-II can be implemented using Fast fourier transform (FFT) internally, as the transform is applied on real values, Real FFT can be used.
+ * DCT4 is implemented using DCT2 as their implementations are similar except with some added pre-processing and post-processing.
+ * DCT2 implementation can be described in the following steps:
+ * - Re-ordering input
+ * - Calculating Real FFT
+ * - Multiplication of weights and Real FFT output and getting real part from the product.
+ *
+ * This process is explained by the block diagram below:
+ * \image html DCT4.gif "Discrete Cosine Transform - type-IV"
+ *
+ * \par Algorithm:
+ * The N-point type-IV DCT is defined as a real, linear transformation by the formula:
+ * \image html DCT4Equation.gif
+ * where k = 0,1,2,.....N-1
+ *\par
+ * Its inverse is defined as follows:
+ * \image html IDCT4Equation.gif
+ * where n = 0,1,2,.....N-1
+ *\par
+ * The DCT4 matrices become involutory (i.e. they are self-inverse) by multiplying with an overall scale factor of sqrt(2/N).
+ * The symmetry of the transform matrix indicates that the fast algorithms for the forward
+ * and inverse transform computation are identical.
+ * Note that the implementation of Inverse DCT4 and DCT4 is same, hence same process function can be used for both.
+ *
+ * \par Lengths supported by the transform:
+ * As DCT4 internally uses Real FFT, it supports all the lengths supported by arm_rfft_f32().
+ * The library provides separate functions for Q15, Q31, and floating-point data types.
+ * \par Instance Structure
+ * The instances for Real FFT and FFT, cosine values table and twiddle factor table are stored in an instance data structure.
+ * A separate instance structure must be defined for each transform.
+ * There are separate instance structure declarations for each of the 3 supported data types.
+ *
+ * \par Initialization Functions
+ * There is also an associated initialization function for each data type.
+ * The initialization function performs the following operations:
+ * - Sets the values of the internal structure fields.
+ * - Initializes Real FFT as its process function is used internally in DCT4, by calling arm_rfft_init_f32().
+ * \par
+ * Use of the initialization function is optional.
+ * However, if the initialization function is used, then the instance structure cannot be placed into a const data section.
+ * To place an instance structure into a const data section, the instance structure must be manually initialized.
+ * Manually initialize the instance structure as follows:
+ *
+ *arm_dct4_instance_f32 S = {N, Nby2, normalize, pTwiddle, pCosFactor, pRfft, pCfft};
+ *arm_dct4_instance_q31 S = {N, Nby2, normalize, pTwiddle, pCosFactor, pRfft, pCfft};
+ *arm_dct4_instance_q15 S = {N, Nby2, normalize, pTwiddle, pCosFactor, pRfft, pCfft};
+ *
+ * where \c N is the length of the DCT4; \c Nby2 is half of the length of the DCT4;
+ * \c normalize is normalizing factor used and is equal to sqrt(2/N)
;
+ * \c pTwiddle points to the twiddle factor table;
+ * \c pCosFactor points to the cosFactor table;
+ * \c pRfft points to the real FFT instance;
+ * \c pCfft points to the complex FFT instance;
+ * The CFFT and RFFT structures also needs to be initialized, refer to arm_cfft_radix4_f32()
+ * and arm_rfft_f32() respectively for details regarding static initialization.
+ *
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the fixed-point versions of the DCT4 transform 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 DCT4_IDCT4
+ * @{
+ */
+
+/**
+ * @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)
+{
+ uint32_t i; /* Loop counter */
+ float32_t *weights = S->pTwiddle; /* Pointer to the Weights table */
+ float32_t *cosFact = S->pCosFactor; /* Pointer to the cos factors table */
+ float32_t *pS1, *pS2, *pbuff; /* Temporary pointers for input buffer and pState buffer */
+ float32_t in; /* Temporary variable */
+
+
+ /* DCT4 computation involves DCT2 (which is calculated using RFFT)
+ * along with some pre-processing and post-processing.
+ * Computational procedure is explained as follows:
+ * (a) Pre-processing involves multiplying input with cos factor,
+ * r(n) = 2 * u(n) * cos(pi*(2*n+1)/(4*n))
+ * where,
+ * r(n) -- output of preprocessing
+ * u(n) -- input to preprocessing(actual Source buffer)
+ * (b) Calculation of DCT2 using FFT is divided into three steps:
+ * Step1: Re-ordering of even and odd elements of input.
+ * Step2: Calculating FFT of the re-ordered input.
+ * Step3: Taking the real part of the product of FFT output and weights.
+ * (c) Post-processing - DCT4 can be obtained from DCT2 output using the following equation:
+ * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
+ * where,
+ * Y4 -- DCT4 output, Y2 -- DCT2 output
+ * (d) Multiplying the output with the normalizing factor sqrt(2/N).
+ */
+
+ /*-------- Pre-processing ------------*/
+ /* Multiplying input with cos factor i.e. r(n) = 2 * x(n) * cos(pi*(2*n+1)/(4*n)) */
+ arm_scale_f32(pInlineBuffer, 2.0f, pInlineBuffer, S->N);
+ arm_mult_f32(pInlineBuffer, cosFact, pInlineBuffer, S->N);
+
+ /* ----------------------------------------------------------------
+ * Step1: Re-ordering of even and odd elements as,
+ * pState[i] = pInlineBuffer[2*i] and
+ * pState[N-i-1] = pInlineBuffer[2*i+1] where i = 0 to N/2
+ ---------------------------------------------------------------------*/
+
+ /* pS1 initialized to pState */
+ pS1 = pState;
+
+ /* pS2 initialized to pState+N-1, so that it points to the end of the state buffer */
+ pS2 = pState + (S->N - 1u);
+
+ /* pbuff initialized to input buffer */
+ pbuff = pInlineBuffer;
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /* Initializing the loop counter to N/2 >> 2 for loop unrolling by 4 */
+ i = (uint32_t) S->Nby2 >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ do
+ {
+ /* Re-ordering of even and odd elements */
+ /* pState[i] = pInlineBuffer[2*i] */
+ *pS1++ = *pbuff++;
+ /* pState[N-i-1] = pInlineBuffer[2*i+1] */
+ *pS2-- = *pbuff++;
+
+ *pS1++ = *pbuff++;
+ *pS2-- = *pbuff++;
+
+ *pS1++ = *pbuff++;
+ *pS2-- = *pbuff++;
+
+ *pS1++ = *pbuff++;
+ *pS2-- = *pbuff++;
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+ /* pbuff initialized to input buffer */
+ pbuff = pInlineBuffer;
+
+ /* pS1 initialized to pState */
+ pS1 = pState;
+
+ /* Initializing the loop counter to N/4 instead of N for loop unrolling */
+ i = (uint32_t) S->N >> 2u;
+
+ /* Processing with loop unrolling 4 times as N is always multiple of 4.
+ * Compute 4 outputs at a time */
+ do
+ {
+ /* Writing the re-ordered output back to inplace input buffer */
+ *pbuff++ = *pS1++;
+ *pbuff++ = *pS1++;
+ *pbuff++ = *pS1++;
+ *pbuff++ = *pS1++;
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+
+ /* ---------------------------------------------------------
+ * Step2: Calculate RFFT for N-point input
+ * ---------------------------------------------------------- */
+ /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */
+ arm_rfft_f32(S->pRfft, pInlineBuffer, pState);
+
+ /*----------------------------------------------------------------------
+ * Step3: Multiply the FFT output with the weights.
+ *----------------------------------------------------------------------*/
+ arm_cmplx_mult_cmplx_f32(pState, weights, pState, S->N);
+
+ /* ----------- Post-processing ---------- */
+ /* DCT-IV can be obtained from DCT-II by the equation,
+ * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
+ * Hence, Y4(0) = Y2(0)/2 */
+ /* Getting only real part from the output and Converting to DCT-IV */
+
+ /* Initializing the loop counter to N >> 2 for loop unrolling by 4 */
+ i = ((uint32_t) S->N - 1u) >> 2u;
+
+ /* pbuff initialized to input buffer. */
+ pbuff = pInlineBuffer;
+
+ /* pS1 initialized to pState */
+ pS1 = pState;
+
+ /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */
+ in = *pS1++ * (float32_t) 0.5;
+ /* input buffer acts as inplace, so output values are stored in the input itself. */
+ *pbuff++ = in;
+
+ /* pState pointer is incremented twice as the real values are located alternatively in the array */
+ pS1++;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ do
+ {
+ /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
+ /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
+ in = *pS1++ - in;
+ *pbuff++ = in;
+ /* points to the next real value */
+ pS1++;
+
+ in = *pS1++ - in;
+ *pbuff++ = in;
+ pS1++;
+
+ in = *pS1++ - in;
+ *pbuff++ = in;
+ pS1++;
+
+ in = *pS1++ - in;
+ *pbuff++ = in;
+ pS1++;
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ i = ((uint32_t) S->N - 1u) % 0x4u;
+
+ while(i > 0u)
+ {
+ /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
+ /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
+ in = *pS1++ - in;
+ *pbuff++ = in;
+ /* points to the next real value */
+ pS1++;
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+
+ /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/
+
+ /* Initializing the loop counter to N/4 instead of N for loop unrolling */
+ i = (uint32_t) S->N >> 2u;
+
+ /* pbuff initialized to the pInlineBuffer(now contains the output values) */
+ pbuff = pInlineBuffer;
+
+ /* Processing with loop unrolling 4 times as N is always multiple of 4. Compute 4 outputs at a time */
+ do
+ {
+ /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */
+ in = *pbuff;
+ *pbuff++ = in * S->normalize;
+
+ in = *pbuff;
+ *pbuff++ = in * S->normalize;
+
+ in = *pbuff;
+ *pbuff++ = in * S->normalize;
+
+ in = *pbuff;
+ *pbuff++ = in * S->normalize;
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Initializing the loop counter to N/2 */
+ i = (uint32_t) S->Nby2;
+
+ do
+ {
+ /* Re-ordering of even and odd elements */
+ /* pState[i] = pInlineBuffer[2*i] */
+ *pS1++ = *pbuff++;
+ /* pState[N-i-1] = pInlineBuffer[2*i+1] */
+ *pS2-- = *pbuff++;
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+ /* pbuff initialized to input buffer */
+ pbuff = pInlineBuffer;
+
+ /* pS1 initialized to pState */
+ pS1 = pState;
+
+ /* Initializing the loop counter */
+ i = (uint32_t) S->N;
+
+ do
+ {
+ /* Writing the re-ordered output back to inplace input buffer */
+ *pbuff++ = *pS1++;
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+
+ /* ---------------------------------------------------------
+ * Step2: Calculate RFFT for N-point input
+ * ---------------------------------------------------------- */
+ /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */
+ arm_rfft_f32(S->pRfft, pInlineBuffer, pState);
+
+ /*----------------------------------------------------------------------
+ * Step3: Multiply the FFT output with the weights.
+ *----------------------------------------------------------------------*/
+ arm_cmplx_mult_cmplx_f32(pState, weights, pState, S->N);
+
+ /* ----------- Post-processing ---------- */
+ /* DCT-IV can be obtained from DCT-II by the equation,
+ * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
+ * Hence, Y4(0) = Y2(0)/2 */
+ /* Getting only real part from the output and Converting to DCT-IV */
+
+ /* pbuff initialized to input buffer. */
+ pbuff = pInlineBuffer;
+
+ /* pS1 initialized to pState */
+ pS1 = pState;
+
+ /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */
+ in = *pS1++ * (float32_t) 0.5;
+ /* input buffer acts as inplace, so output values are stored in the input itself. */
+ *pbuff++ = in;
+
+ /* pState pointer is incremented twice as the real values are located alternatively in the array */
+ pS1++;
+
+ /* Initializing the loop counter */
+ i = ((uint32_t) S->N - 1u);
+
+ do
+ {
+ /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
+ /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
+ in = *pS1++ - in;
+ *pbuff++ = in;
+ /* points to the next real value */
+ pS1++;
+
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+
+ /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/
+
+ /* Initializing the loop counter */
+ i = (uint32_t) S->N;
+
+ /* pbuff initialized to the pInlineBuffer(now contains the output values) */
+ pbuff = pInlineBuffer;
+
+ do
+ {
+ /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */
+ in = *pbuff;
+ *pbuff++ = in * S->normalize;
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+}
+
+/**
+ * @} end of DCT4_IDCT4 group
+ */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_init_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_init_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_init_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_init_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_init_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_init_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_init_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_init_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_init_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_init_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_init_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_init_q31.c
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_q15.c
new file mode 100644
index 0000000..b6b3712
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_q15.c
@@ -0,0 +1,394 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_dct4_q15.c
+*
+* Description: Processing function of DCT4 & IDCT4 Q15.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @addtogroup DCT4_IDCT4
+ * @{
+ */
+
+/**
+ * @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.
+ *
+ * \par Input an output formats:
+ * Internally inputs are downscaled in the RFFT process function to avoid overflows.
+ * Number of bits downscaled, depends on the size of the transform.
+ * The input and output formats for different DCT sizes and number of bits to upscale are mentioned in the table below:
+ *
+ * \image html dct4FormatsQ15Table.gif
+ */
+
+void arm_dct4_q15(
+ const arm_dct4_instance_q15 * S,
+ q15_t * pState,
+ q15_t * pInlineBuffer)
+{
+ uint32_t i; /* Loop counter */
+ q15_t *weights = S->pTwiddle; /* Pointer to the Weights table */
+ q15_t *cosFact = S->pCosFactor; /* Pointer to the cos factors table */
+ q15_t *pS1, *pS2, *pbuff; /* Temporary pointers for input buffer and pState buffer */
+ q15_t in; /* Temporary variable */
+
+
+ /* DCT4 computation involves DCT2 (which is calculated using RFFT)
+ * along with some pre-processing and post-processing.
+ * Computational procedure is explained as follows:
+ * (a) Pre-processing involves multiplying input with cos factor,
+ * r(n) = 2 * u(n) * cos(pi*(2*n+1)/(4*n))
+ * where,
+ * r(n) -- output of preprocessing
+ * u(n) -- input to preprocessing(actual Source buffer)
+ * (b) Calculation of DCT2 using FFT is divided into three steps:
+ * Step1: Re-ordering of even and odd elements of input.
+ * Step2: Calculating FFT of the re-ordered input.
+ * Step3: Taking the real part of the product of FFT output and weights.
+ * (c) Post-processing - DCT4 can be obtained from DCT2 output using the following equation:
+ * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
+ * where,
+ * Y4 -- DCT4 output, Y2 -- DCT2 output
+ * (d) Multiplying the output with the normalizing factor sqrt(2/N).
+ */
+
+ /*-------- Pre-processing ------------*/
+ /* Multiplying input with cos factor i.e. r(n) = 2 * x(n) * cos(pi*(2*n+1)/(4*n)) */
+ arm_mult_q15(pInlineBuffer, cosFact, pInlineBuffer, S->N);
+ arm_shift_q15(pInlineBuffer, 1, pInlineBuffer, S->N);
+
+ /* ----------------------------------------------------------------
+ * Step1: Re-ordering of even and odd elements as
+ * pState[i] = pInlineBuffer[2*i] and
+ * pState[N-i-1] = pInlineBuffer[2*i+1] where i = 0 to N/2
+ ---------------------------------------------------------------------*/
+
+ /* pS1 initialized to pState */
+ pS1 = pState;
+
+ /* pS2 initialized to pState+N-1, so that it points to the end of the state buffer */
+ pS2 = pState + (S->N - 1u);
+
+ /* pbuff initialized to input buffer */
+ pbuff = pInlineBuffer;
+
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /* Initializing the loop counter to N/2 >> 2 for loop unrolling by 4 */
+ i = (uint32_t) S->Nby2 >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ do
+ {
+ /* Re-ordering of even and odd elements */
+ /* pState[i] = pInlineBuffer[2*i] */
+ *pS1++ = *pbuff++;
+ /* pState[N-i-1] = pInlineBuffer[2*i+1] */
+ *pS2-- = *pbuff++;
+
+ *pS1++ = *pbuff++;
+ *pS2-- = *pbuff++;
+
+ *pS1++ = *pbuff++;
+ *pS2-- = *pbuff++;
+
+ *pS1++ = *pbuff++;
+ *pS2-- = *pbuff++;
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+ /* pbuff initialized to input buffer */
+ pbuff = pInlineBuffer;
+
+ /* pS1 initialized to pState */
+ pS1 = pState;
+
+ /* Initializing the loop counter to N/4 instead of N for loop unrolling */
+ i = (uint32_t) S->N >> 2u;
+
+ /* Processing with loop unrolling 4 times as N is always multiple of 4.
+ * Compute 4 outputs at a time */
+ do
+ {
+ /* Writing the re-ordered output back to inplace input buffer */
+ *pbuff++ = *pS1++;
+ *pbuff++ = *pS1++;
+ *pbuff++ = *pS1++;
+ *pbuff++ = *pS1++;
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+
+ /* ---------------------------------------------------------
+ * Step2: Calculate RFFT for N-point input
+ * ---------------------------------------------------------- */
+ /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */
+ arm_rfft_q15(S->pRfft, pInlineBuffer, pState);
+
+ /*----------------------------------------------------------------------
+ * Step3: Multiply the FFT output with the weights.
+ *----------------------------------------------------------------------*/
+ arm_cmplx_mult_cmplx_q15(pState, weights, pState, S->N);
+
+ /* The output of complex multiplication is in 3.13 format.
+ * Hence changing the format of N (i.e. 2*N elements) complex numbers to 1.15 format by shifting left by 2 bits. */
+ arm_shift_q15(pState, 2, pState, S->N * 2);
+
+ /* ----------- Post-processing ---------- */
+ /* DCT-IV can be obtained from DCT-II by the equation,
+ * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
+ * Hence, Y4(0) = Y2(0)/2 */
+ /* Getting only real part from the output and Converting to DCT-IV */
+
+ /* Initializing the loop counter to N >> 2 for loop unrolling by 4 */
+ i = ((uint32_t) S->N - 1u) >> 2u;
+
+ /* pbuff initialized to input buffer. */
+ pbuff = pInlineBuffer;
+
+ /* pS1 initialized to pState */
+ pS1 = pState;
+
+ /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */
+ in = *pS1++ >> 1u;
+ /* input buffer acts as inplace, so output values are stored in the input itself. */
+ *pbuff++ = in;
+
+ /* pState pointer is incremented twice as the real values are located alternatively in the array */
+ pS1++;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ do
+ {
+ /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
+ /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
+ in = *pS1++ - in;
+ *pbuff++ = in;
+ /* points to the next real value */
+ pS1++;
+
+ in = *pS1++ - in;
+ *pbuff++ = in;
+ pS1++;
+
+ in = *pS1++ - in;
+ *pbuff++ = in;
+ pS1++;
+
+ in = *pS1++ - in;
+ *pbuff++ = in;
+ pS1++;
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ i = ((uint32_t) S->N - 1u) % 0x4u;
+
+ while(i > 0u)
+ {
+ /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
+ /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
+ in = *pS1++ - in;
+ *pbuff++ = in;
+ /* points to the next real value */
+ pS1++;
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+
+ /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/
+
+ /* Initializing the loop counter to N/4 instead of N for loop unrolling */
+ i = (uint32_t) S->N >> 2u;
+
+ /* pbuff initialized to the pInlineBuffer(now contains the output values) */
+ pbuff = pInlineBuffer;
+
+ /* Processing with loop unrolling 4 times as N is always multiple of 4. Compute 4 outputs at a time */
+ do
+ {
+ /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */
+ in = *pbuff;
+ *pbuff++ = ((q15_t) (((q31_t) in * S->normalize) >> 15));
+
+ in = *pbuff;
+ *pbuff++ = ((q15_t) (((q31_t) in * S->normalize) >> 15));
+
+ in = *pbuff;
+ *pbuff++ = ((q15_t) (((q31_t) in * S->normalize) >> 15));
+
+ in = *pbuff;
+ *pbuff++ = ((q15_t) (((q31_t) in * S->normalize) >> 15));
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Initializing the loop counter to N/2 */
+ i = (uint32_t) S->Nby2;
+
+ do
+ {
+ /* Re-ordering of even and odd elements */
+ /* pState[i] = pInlineBuffer[2*i] */
+ *pS1++ = *pbuff++;
+ /* pState[N-i-1] = pInlineBuffer[2*i+1] */
+ *pS2-- = *pbuff++;
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+ /* pbuff initialized to input buffer */
+ pbuff = pInlineBuffer;
+
+ /* pS1 initialized to pState */
+ pS1 = pState;
+
+ /* Initializing the loop counter */
+ i = (uint32_t) S->N;
+
+ do
+ {
+ /* Writing the re-ordered output back to inplace input buffer */
+ *pbuff++ = *pS1++;
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+
+ /* ---------------------------------------------------------
+ * Step2: Calculate RFFT for N-point input
+ * ---------------------------------------------------------- */
+ /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */
+ arm_rfft_q15(S->pRfft, pInlineBuffer, pState);
+
+ /*----------------------------------------------------------------------
+ * Step3: Multiply the FFT output with the weights.
+ *----------------------------------------------------------------------*/
+ arm_cmplx_mult_cmplx_q15(pState, weights, pState, S->N);
+
+ /* The output of complex multiplication is in 3.13 format.
+ * Hence changing the format of N (i.e. 2*N elements) complex numbers to 1.15 format by shifting left by 2 bits. */
+ arm_shift_q15(pState, 2, pState, S->N * 2);
+
+ /* ----------- Post-processing ---------- */
+ /* DCT-IV can be obtained from DCT-II by the equation,
+ * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
+ * Hence, Y4(0) = Y2(0)/2 */
+ /* Getting only real part from the output and Converting to DCT-IV */
+
+ /* Initializing the loop counter */
+ i = ((uint32_t) S->N - 1u);
+
+ /* pbuff initialized to input buffer. */
+ pbuff = pInlineBuffer;
+
+ /* pS1 initialized to pState */
+ pS1 = pState;
+
+ /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */
+ in = *pS1++ >> 1u;
+ /* input buffer acts as inplace, so output values are stored in the input itself. */
+ *pbuff++ = in;
+
+ /* pState pointer is incremented twice as the real values are located alternatively in the array */
+ pS1++;
+
+ do
+ {
+ /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
+ /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
+ in = *pS1++ - in;
+ *pbuff++ = in;
+ /* points to the next real value */
+ pS1++;
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+ /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/
+
+ /* Initializing the loop counter */
+ i = (uint32_t) S->N;
+
+ /* pbuff initialized to the pInlineBuffer(now contains the output values) */
+ pbuff = pInlineBuffer;
+
+ do
+ {
+ /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */
+ in = *pbuff;
+ *pbuff++ = ((q15_t) (((q31_t) in * S->normalize) >> 15));
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+}
+
+/**
+ * @} end of DCT4_IDCT4 group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_q31.c
new file mode 100644
index 0000000..6f2c2b3
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_dct4_q31.c
@@ -0,0 +1,395 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_dct4_q31.c
+*
+* Description: Processing function of DCT4 & IDCT4 Q31.
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/**
+ * @addtogroup DCT4_IDCT4
+ * @{
+ */
+
+/**
+ * @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.
+ * \par Input an output formats:
+ * Input samples need to be downscaled by 1 bit to avoid saturations in the Q31 DCT process,
+ * as the conversion from DCT2 to DCT4 involves one subtraction.
+ * Internally inputs are downscaled in the RFFT process function to avoid overflows.
+ * Number of bits downscaled, depends on the size of the transform.
+ * The input and output formats for different DCT sizes and number of bits to upscale are mentioned in the table below:
+ *
+ * \image html dct4FormatsQ31Table.gif
+ */
+
+void arm_dct4_q31(
+ const arm_dct4_instance_q31 * S,
+ q31_t * pState,
+ q31_t * pInlineBuffer)
+{
+ uint16_t i; /* Loop counter */
+ q31_t *weights = S->pTwiddle; /* Pointer to the Weights table */
+ q31_t *cosFact = S->pCosFactor; /* Pointer to the cos factors table */
+ q31_t *pS1, *pS2, *pbuff; /* Temporary pointers for input buffer and pState buffer */
+ q31_t in; /* Temporary variable */
+
+
+ /* DCT4 computation involves DCT2 (which is calculated using RFFT)
+ * along with some pre-processing and post-processing.
+ * Computational procedure is explained as follows:
+ * (a) Pre-processing involves multiplying input with cos factor,
+ * r(n) = 2 * u(n) * cos(pi*(2*n+1)/(4*n))
+ * where,
+ * r(n) -- output of preprocessing
+ * u(n) -- input to preprocessing(actual Source buffer)
+ * (b) Calculation of DCT2 using FFT is divided into three steps:
+ * Step1: Re-ordering of even and odd elements of input.
+ * Step2: Calculating FFT of the re-ordered input.
+ * Step3: Taking the real part of the product of FFT output and weights.
+ * (c) Post-processing - DCT4 can be obtained from DCT2 output using the following equation:
+ * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
+ * where,
+ * Y4 -- DCT4 output, Y2 -- DCT2 output
+ * (d) Multiplying the output with the normalizing factor sqrt(2/N).
+ */
+
+ /*-------- Pre-processing ------------*/
+ /* Multiplying input with cos factor i.e. r(n) = 2 * x(n) * cos(pi*(2*n+1)/(4*n)) */
+ arm_mult_q31(pInlineBuffer, cosFact, pInlineBuffer, S->N);
+ arm_shift_q31(pInlineBuffer, 1, pInlineBuffer, S->N);
+
+ /* ----------------------------------------------------------------
+ * Step1: Re-ordering of even and odd elements as
+ * pState[i] = pInlineBuffer[2*i] and
+ * pState[N-i-1] = pInlineBuffer[2*i+1] where i = 0 to N/2
+ ---------------------------------------------------------------------*/
+
+ /* pS1 initialized to pState */
+ pS1 = pState;
+
+ /* pS2 initialized to pState+N-1, so that it points to the end of the state buffer */
+ pS2 = pState + (S->N - 1u);
+
+ /* pbuff initialized to input buffer */
+ pbuff = pInlineBuffer;
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+
+ /* Initializing the loop counter to N/2 >> 2 for loop unrolling by 4 */
+ i = S->Nby2 >> 2u;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ do
+ {
+ /* Re-ordering of even and odd elements */
+ /* pState[i] = pInlineBuffer[2*i] */
+ *pS1++ = *pbuff++;
+ /* pState[N-i-1] = pInlineBuffer[2*i+1] */
+ *pS2-- = *pbuff++;
+
+ *pS1++ = *pbuff++;
+ *pS2-- = *pbuff++;
+
+ *pS1++ = *pbuff++;
+ *pS2-- = *pbuff++;
+
+ *pS1++ = *pbuff++;
+ *pS2-- = *pbuff++;
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+ /* pbuff initialized to input buffer */
+ pbuff = pInlineBuffer;
+
+ /* pS1 initialized to pState */
+ pS1 = pState;
+
+ /* Initializing the loop counter to N/4 instead of N for loop unrolling */
+ i = S->N >> 2u;
+
+ /* Processing with loop unrolling 4 times as N is always multiple of 4.
+ * Compute 4 outputs at a time */
+ do
+ {
+ /* Writing the re-ordered output back to inplace input buffer */
+ *pbuff++ = *pS1++;
+ *pbuff++ = *pS1++;
+ *pbuff++ = *pS1++;
+ *pbuff++ = *pS1++;
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+
+ /* ---------------------------------------------------------
+ * Step2: Calculate RFFT for N-point input
+ * ---------------------------------------------------------- */
+ /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */
+ arm_rfft_q31(S->pRfft, pInlineBuffer, pState);
+
+ /*----------------------------------------------------------------------
+ * Step3: Multiply the FFT output with the weights.
+ *----------------------------------------------------------------------*/
+ arm_cmplx_mult_cmplx_q31(pState, weights, pState, S->N);
+
+ /* The output of complex multiplication is in 3.29 format.
+ * Hence changing the format of N (i.e. 2*N elements) complex numbers to 1.31 format by shifting left by 2 bits. */
+ arm_shift_q31(pState, 2, pState, S->N * 2);
+
+ /* ----------- Post-processing ---------- */
+ /* DCT-IV can be obtained from DCT-II by the equation,
+ * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
+ * Hence, Y4(0) = Y2(0)/2 */
+ /* Getting only real part from the output and Converting to DCT-IV */
+
+ /* Initializing the loop counter to N >> 2 for loop unrolling by 4 */
+ i = (S->N - 1u) >> 2u;
+
+ /* pbuff initialized to input buffer. */
+ pbuff = pInlineBuffer;
+
+ /* pS1 initialized to pState */
+ pS1 = pState;
+
+ /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */
+ in = *pS1++ >> 1u;
+ /* input buffer acts as inplace, so output values are stored in the input itself. */
+ *pbuff++ = in;
+
+ /* pState pointer is incremented twice as the real values are located alternatively in the array */
+ pS1++;
+
+ /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
+ ** a second loop below computes the remaining 1 to 3 samples. */
+ do
+ {
+ /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
+ /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
+ in = *pS1++ - in;
+ *pbuff++ = in;
+ /* points to the next real value */
+ pS1++;
+
+ in = *pS1++ - in;
+ *pbuff++ = in;
+ pS1++;
+
+ in = *pS1++ - in;
+ *pbuff++ = in;
+ pS1++;
+
+ in = *pS1++ - in;
+ *pbuff++ = in;
+ pS1++;
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+ /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
+ ** No loop unrolling is used. */
+ i = (S->N - 1u) % 0x4u;
+
+ while(i > 0u)
+ {
+ /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
+ /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
+ in = *pS1++ - in;
+ *pbuff++ = in;
+ /* points to the next real value */
+ pS1++;
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+
+ /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/
+
+ /* Initializing the loop counter to N/4 instead of N for loop unrolling */
+ i = S->N >> 2u;
+
+ /* pbuff initialized to the pInlineBuffer(now contains the output values) */
+ pbuff = pInlineBuffer;
+
+ /* Processing with loop unrolling 4 times as N is always multiple of 4. Compute 4 outputs at a time */
+ do
+ {
+ /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */
+ in = *pbuff;
+ *pbuff++ = ((q31_t) (((q63_t) in * S->normalize) >> 31));
+
+ in = *pbuff;
+ *pbuff++ = ((q31_t) (((q63_t) in * S->normalize) >> 31));
+
+ in = *pbuff;
+ *pbuff++ = ((q31_t) (((q63_t) in * S->normalize) >> 31));
+
+ in = *pbuff;
+ *pbuff++ = ((q31_t) (((q63_t) in * S->normalize) >> 31));
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+
+ /* Initializing the loop counter to N/2 */
+ i = S->Nby2;
+
+ do
+ {
+ /* Re-ordering of even and odd elements */
+ /* pState[i] = pInlineBuffer[2*i] */
+ *pS1++ = *pbuff++;
+ /* pState[N-i-1] = pInlineBuffer[2*i+1] */
+ *pS2-- = *pbuff++;
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+ /* pbuff initialized to input buffer */
+ pbuff = pInlineBuffer;
+
+ /* pS1 initialized to pState */
+ pS1 = pState;
+
+ /* Initializing the loop counter */
+ i = S->N;
+
+ do
+ {
+ /* Writing the re-ordered output back to inplace input buffer */
+ *pbuff++ = *pS1++;
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+
+ /* ---------------------------------------------------------
+ * Step2: Calculate RFFT for N-point input
+ * ---------------------------------------------------------- */
+ /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */
+ arm_rfft_q31(S->pRfft, pInlineBuffer, pState);
+
+ /*----------------------------------------------------------------------
+ * Step3: Multiply the FFT output with the weights.
+ *----------------------------------------------------------------------*/
+ arm_cmplx_mult_cmplx_q31(pState, weights, pState, S->N);
+
+ /* The output of complex multiplication is in 3.29 format.
+ * Hence changing the format of N (i.e. 2*N elements) complex numbers to 1.31 format by shifting left by 2 bits. */
+ arm_shift_q31(pState, 2, pState, S->N * 2);
+
+ /* ----------- Post-processing ---------- */
+ /* DCT-IV can be obtained from DCT-II by the equation,
+ * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0)
+ * Hence, Y4(0) = Y2(0)/2 */
+ /* Getting only real part from the output and Converting to DCT-IV */
+
+ /* pbuff initialized to input buffer. */
+ pbuff = pInlineBuffer;
+
+ /* pS1 initialized to pState */
+ pS1 = pState;
+
+ /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */
+ in = *pS1++ >> 1u;
+ /* input buffer acts as inplace, so output values are stored in the input itself. */
+ *pbuff++ = in;
+
+ /* pState pointer is incremented twice as the real values are located alternatively in the array */
+ pS1++;
+
+ /* Initializing the loop counter */
+ i = (S->N - 1u);
+
+ while(i > 0u)
+ {
+ /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */
+ /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */
+ in = *pS1++ - in;
+ *pbuff++ = in;
+ /* points to the next real value */
+ pS1++;
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+
+ /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/
+
+ /* Initializing the loop counter */
+ i = S->N;
+
+ /* pbuff initialized to the pInlineBuffer(now contains the output values) */
+ pbuff = pInlineBuffer;
+
+ do
+ {
+ /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */
+ in = *pbuff;
+ *pbuff++ = ((q31_t) (((q63_t) in * S->normalize) >> 31));
+
+ /* Decrement the loop counter */
+ i--;
+ } while(i > 0u);
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+
+}
+
+/**
+ * @} end of DCT4_IDCT4 group
+ */
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_f32.c
new file mode 100644
index 0000000..f7db9fa
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_f32.c
@@ -0,0 +1,329 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_rfft_f32.c
+*
+* Description: RFFT & RIFFT Floating point process function
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+extern void arm_radix4_butterfly_f32(
+ float32_t * pSrc,
+ uint16_t fftLen,
+ float32_t * pCoef,
+ uint16_t twidCoefModifier);
+
+extern void arm_radix4_butterfly_inverse_f32(
+ float32_t * pSrc,
+ uint16_t fftLen,
+ float32_t * pCoef,
+ uint16_t twidCoefModifier,
+ float32_t onebyfftLen);
+
+extern void arm_bitreversal_f32(
+ float32_t * pSrc,
+ uint16_t fftSize,
+ uint16_t bitRevFactor,
+ uint16_t * pBitRevTab);
+
+/**
+ * @ingroup groupTransforms
+ */
+
+/*--------------------------------------------------------------------
+ * Internal functions prototypes
+ *--------------------------------------------------------------------*/
+
+void arm_split_rfft_f32(
+ float32_t * pSrc,
+ uint32_t fftLen,
+ float32_t * pATable,
+ float32_t * pBTable,
+ float32_t * pDst,
+ uint32_t modifier);
+void arm_split_rifft_f32(
+ float32_t * pSrc,
+ uint32_t fftLen,
+ float32_t * pATable,
+ float32_t * pBTable,
+ float32_t * pDst,
+ uint32_t modifier);
+
+/**
+ * @addtogroup RealFFT
+ * @{
+ */
+
+/**
+ * @brief Processing function for the floating-point RFFT/RIFFT.
+ * @deprecated Do not use this function. It has been superceded by \ref arm_rfft_fast_f32 and will be removed
+ * in the future.
+ * @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)
+{
+ const arm_cfft_radix4_instance_f32 *S_CFFT = S->pCfft;
+
+
+ /* Calculation of Real IFFT of input */
+ if(S->ifftFlagR == 1u)
+ {
+ /* Real IFFT core process */
+ arm_split_rifft_f32(pSrc, S->fftLenBy2, S->pTwiddleAReal,
+ S->pTwiddleBReal, pDst, S->twidCoefRModifier);
+
+
+ /* Complex radix-4 IFFT process */
+ arm_radix4_butterfly_inverse_f32(pDst, S_CFFT->fftLen,
+ S_CFFT->pTwiddle,
+ S_CFFT->twidCoefModifier,
+ S_CFFT->onebyfftLen);
+
+ /* Bit reversal process */
+ if(S->bitReverseFlagR == 1u)
+ {
+ arm_bitreversal_f32(pDst, S_CFFT->fftLen,
+ S_CFFT->bitRevFactor, S_CFFT->pBitRevTable);
+ }
+ }
+ else
+ {
+
+ /* Calculation of RFFT of input */
+
+ /* Complex radix-4 FFT process */
+ arm_radix4_butterfly_f32(pSrc, S_CFFT->fftLen,
+ S_CFFT->pTwiddle, S_CFFT->twidCoefModifier);
+
+ /* Bit reversal process */
+ if(S->bitReverseFlagR == 1u)
+ {
+ arm_bitreversal_f32(pSrc, S_CFFT->fftLen,
+ S_CFFT->bitRevFactor, S_CFFT->pBitRevTable);
+ }
+
+
+ /* Real FFT core process */
+ arm_split_rfft_f32(pSrc, S->fftLenBy2, S->pTwiddleAReal,
+ S->pTwiddleBReal, pDst, S->twidCoefRModifier);
+ }
+
+}
+
+/**
+ * @} end of RealFFT group
+ */
+
+/**
+ * @brief Core Real FFT process
+ * @param[in] *pSrc points to the input buffer.
+ * @param[in] fftLen length of FFT.
+ * @param[in] *pATable points to the twiddle Coef A buffer.
+ * @param[in] *pBTable points to the twiddle Coef B buffer.
+ * @param[out] *pDst points to the output buffer.
+ * @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
+ * @return none.
+ */
+
+void arm_split_rfft_f32(
+ float32_t * pSrc,
+ uint32_t fftLen,
+ float32_t * pATable,
+ float32_t * pBTable,
+ float32_t * pDst,
+ uint32_t modifier)
+{
+ uint32_t i; /* Loop Counter */
+ float32_t outR, outI; /* Temporary variables for output */
+ float32_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
+ float32_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */
+ float32_t *pDst1 = &pDst[2], *pDst2 = &pDst[(4u * fftLen) - 1u]; /* temp pointers for output buffer */
+ float32_t *pSrc1 = &pSrc[2], *pSrc2 = &pSrc[(2u * fftLen) - 1u]; /* temp pointers for input buffer */
+
+ /* Init coefficient pointers */
+ pCoefA = &pATable[modifier * 2u];
+ pCoefB = &pBTable[modifier * 2u];
+
+ i = fftLen - 1u;
+
+ while(i > 0u)
+ {
+ /*
+ outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1]
+ + pSrc[2 * n - 2 * i] * pBTable[2 * i] +
+ pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
+ */
+
+ /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] +
+ pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
+ pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); */
+
+ /* read pATable[2 * i] */
+ CoefA1 = *pCoefA++;
+ /* pATable[2 * i + 1] */
+ CoefA2 = *pCoefA;
+
+ /* pSrc[2 * i] * pATable[2 * i] */
+ outR = *pSrc1 * CoefA1;
+ /* pSrc[2 * i] * CoefA2 */
+ outI = *pSrc1++ * CoefA2;
+
+ /* (pSrc[2 * i + 1] + pSrc[2 * fftLen - 2 * i + 1]) * CoefA2 */
+ outR -= (*pSrc1 + *pSrc2) * CoefA2;
+ /* pSrc[2 * i + 1] * CoefA1 */
+ outI += *pSrc1++ * CoefA1;
+
+ CoefB1 = *pCoefB;
+
+ /* pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */
+ outI -= *pSrc2-- * CoefB1;
+ /* pSrc[2 * fftLen - 2 * i] * CoefA2 */
+ outI -= *pSrc2 * CoefA2;
+
+ /* pSrc[2 * fftLen - 2 * i] * CoefB1 */
+ outR += *pSrc2-- * CoefB1;
+
+ /* write output */
+ *pDst1++ = outR;
+ *pDst1++ = outI;
+
+ /* write complex conjugate output */
+ *pDst2-- = -outI;
+ *pDst2-- = outR;
+
+ /* update coefficient pointer */
+ pCoefB = pCoefB + (modifier * 2u);
+ pCoefA = pCoefA + ((modifier * 2u) - 1u);
+
+ i--;
+
+ }
+
+ pDst[2u * fftLen] = pSrc[0] - pSrc[1];
+ pDst[(2u * fftLen) + 1u] = 0.0f;
+
+ pDst[0] = pSrc[0] + pSrc[1];
+ pDst[1] = 0.0f;
+
+}
+
+
+/**
+ * @brief Core Real IFFT process
+ * @param[in] *pSrc points to the input buffer.
+ * @param[in] fftLen length of FFT.
+ * @param[in] *pATable points to the twiddle Coef A buffer.
+ * @param[in] *pBTable points to the twiddle Coef B buffer.
+ * @param[out] *pDst points to the output buffer.
+ * @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
+ * @return none.
+ */
+
+void arm_split_rifft_f32(
+ float32_t * pSrc,
+ uint32_t fftLen,
+ float32_t * pATable,
+ float32_t * pBTable,
+ float32_t * pDst,
+ uint32_t modifier)
+{
+ float32_t outR, outI; /* Temporary variables for output */
+ float32_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
+ float32_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */
+ float32_t *pSrc1 = &pSrc[0], *pSrc2 = &pSrc[(2u * fftLen) + 1u];
+
+ pCoefA = &pATable[0];
+ pCoefB = &pBTable[0];
+
+ while(fftLen > 0u)
+ {
+ /*
+ outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
+ pIn[2 * n - 2 * i] * pBTable[2 * i] -
+ pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
+
+ outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] -
+ pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
+ pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
+
+ */
+
+ CoefA1 = *pCoefA++;
+ CoefA2 = *pCoefA;
+
+ /* outR = (pSrc[2 * i] * CoefA1 */
+ outR = *pSrc1 * CoefA1;
+
+ /* - pSrc[2 * i] * CoefA2 */
+ outI = -(*pSrc1++) * CoefA2;
+
+ /* (pSrc[2 * i + 1] + pSrc[2 * fftLen - 2 * i + 1]) * CoefA2 */
+ outR += (*pSrc1 + *pSrc2) * CoefA2;
+
+ /* pSrc[2 * i + 1] * CoefA1 */
+ outI += (*pSrc1++) * CoefA1;
+
+ CoefB1 = *pCoefB;
+
+ /* - pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */
+ outI -= *pSrc2-- * CoefB1;
+
+ /* pSrc[2 * fftLen - 2 * i] * CoefB1 */
+ outR += *pSrc2 * CoefB1;
+
+ /* pSrc[2 * fftLen - 2 * i] * CoefA2 */
+ outI += *pSrc2-- * CoefA2;
+
+ /* write output */
+ *pDst++ = outR;
+ *pDst++ = outI;
+
+ /* update coefficient pointer */
+ pCoefB = pCoefB + (modifier * 2u);
+ pCoefA = pCoefA + ((modifier * 2u) - 1u);
+
+ /* Decrement loop count */
+ fftLen--;
+ }
+
+}
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_fast_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_fast_f32.c
new file mode 100644
index 0000000..e9cea12
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_fast_f32.c
@@ -0,0 +1,353 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_rfft_f32.c
+*
+* Description: RFFT & RIFFT Floating point process function
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+void stage_rfft_f32(
+ arm_rfft_fast_instance_f32 * S,
+ float32_t * p, float32_t * pOut)
+{
+ uint32_t k; /* Loop Counter */
+ float32_t twR, twI; /* RFFT Twiddle coefficients */
+ float32_t * pCoeff = S->pTwiddleRFFT; /* Points to RFFT Twiddle factors */
+ float32_t *pA = p; /* increasing pointer */
+ float32_t *pB = p; /* decreasing pointer */
+ float32_t xAR, xAI, xBR, xBI; /* temporary variables */
+ float32_t t1a, t1b; /* temporary variables */
+ float32_t p0, p1, p2, p3; /* temporary variables */
+
+
+ k = (S->Sint).fftLen - 1;
+
+ /* Pack first and last sample of the frequency domain together */
+
+ xBR = pB[0];
+ xBI = pB[1];
+ xAR = pA[0];
+ xAI = pA[1];
+
+ twR = *pCoeff++ ;
+ twI = *pCoeff++ ;
+
+ // U1 = XA(1) + XB(1); % It is real
+ t1a = xBR + xAR ;
+
+ // U2 = XB(1) - XA(1); % It is imaginary
+ t1b = xBI + xAI ;
+
+ // real(tw * (xB - xA)) = twR * (xBR - xAR) - twI * (xBI - xAI);
+ // imag(tw * (xB - xA)) = twI * (xBR - xAR) + twR * (xBI - xAI);
+ *pOut++ = 0.5f * ( t1a + t1b );
+ *pOut++ = 0.5f * ( t1a - t1b );
+
+ // XA(1) = 1/2*( U1 - imag(U2) + i*( U1 +imag(U2) ));
+ pB = p + 2*k;
+ pA += 2;
+
+ do
+ {
+ /*
+ function X = my_split_rfft(X, ifftFlag)
+ % X is a series of real numbers
+ L = length(X);
+ XC = X(1:2:end) +i*X(2:2:end);
+ XA = fft(XC);
+ XB = conj(XA([1 end:-1:2]));
+ TW = i*exp(-2*pi*i*[0:L/2-1]/L).';
+ for l = 2:L/2
+ XA(l) = 1/2 * (XA(l) + XB(l) + TW(l) * (XB(l) - XA(l)));
+ end
+ XA(1) = 1/2* (XA(1) + XB(1) + TW(1) * (XB(1) - XA(1))) + i*( 1/2*( XA(1) + XB(1) + i*( XA(1) - XB(1))));
+ X = XA;
+ */
+
+ xBI = pB[1];
+ xBR = pB[0];
+ xAR = pA[0];
+ xAI = pA[1];
+
+ twR = *pCoeff++;
+ twI = *pCoeff++;
+
+ t1a = xBR - xAR ;
+ t1b = xBI + xAI ;
+
+ // real(tw * (xB - xA)) = twR * (xBR - xAR) - twI * (xBI - xAI);
+ // imag(tw * (xB - xA)) = twI * (xBR - xAR) + twR * (xBI - xAI);
+ p0 = twR * t1a;
+ p1 = twI * t1a;
+ p2 = twR * t1b;
+ p3 = twI * t1b;
+
+ *pOut++ = 0.5f * (xAR + xBR + p0 + p3 ); //xAR
+ *pOut++ = 0.5f * (xAI - xBI + p1 - p2 ); //xAI
+
+ pA += 2;
+ pB -= 2;
+ k--;
+ } while(k > 0u);
+}
+
+/* Prepares data for inverse cfft */
+void merge_rfft_f32(
+arm_rfft_fast_instance_f32 * S,
+float32_t * p, float32_t * pOut)
+{
+ uint32_t k; /* Loop Counter */
+ float32_t twR, twI; /* RFFT Twiddle coefficients */
+ float32_t *pCoeff = S->pTwiddleRFFT; /* Points to RFFT Twiddle factors */
+ float32_t *pA = p; /* increasing pointer */
+ float32_t *pB = p; /* decreasing pointer */
+ float32_t xAR, xAI, xBR, xBI; /* temporary variables */
+ float32_t t1a, t1b, r, s, t, u; /* temporary variables */
+
+ k = (S->Sint).fftLen - 1;
+
+ xAR = pA[0];
+ xAI = pA[1];
+
+ pCoeff += 2 ;
+
+ *pOut++ = 0.5f * ( xAR + xAI );
+ *pOut++ = 0.5f * ( xAR - xAI );
+
+ pB = p + 2*k ;
+ pA += 2 ;
+
+ while(k > 0u)
+ {
+ /* G is half of the frequency complex spectrum */
+ //for k = 2:N
+ // Xk(k) = 1/2 * (G(k) + conj(G(N-k+2)) + Tw(k)*( G(k) - conj(G(N-k+2))));
+ xBI = pB[1] ;
+ xBR = pB[0] ;
+ xAR = pA[0];
+ xAI = pA[1];
+
+ twR = *pCoeff++;
+ twI = *pCoeff++;
+
+ t1a = xAR - xBR ;
+ t1b = xAI + xBI ;
+
+ r = twR * t1a;
+ s = twI * t1b;
+ t = twI * t1a;
+ u = twR * t1b;
+
+ // real(tw * (xA - xB)) = twR * (xAR - xBR) - twI * (xAI - xBI);
+ // imag(tw * (xA - xB)) = twI * (xAR - xBR) + twR * (xAI - xBI);
+ *pOut++ = 0.5f * (xAR + xBR - r - s ); //xAR
+ *pOut++ = 0.5f * (xAI - xBI + t - u ); //xAI
+
+ pA += 2;
+ pB -= 2;
+ k--;
+ }
+
+}
+
+/**
+* @ingroup groupTransforms
+*/
+
+/**
+ * @defgroup Fast Real FFT Functions
+ *
+ * \par
+ * The CMSIS DSP library includes specialized algorithms for computing the
+ * FFT of real data sequences. The FFT is defined over complex data but
+ * in many applications the input is real. Real FFT algorithms take advantage
+ * of the symmetry properties of the FFT and have a speed advantage over complex
+ * algorithms of the same length.
+ * \par
+ * The Fast RFFT algorith relays on the mixed radix CFFT that save processor usage.
+ * \par
+ * The real length N forward FFT of a sequence is computed using the steps shown below.
+ * \par
+ * \image html RFFT.gif "Real Fast Fourier Transform"
+ * \par
+ * The real sequence is initially treated as if it were complex to perform a CFFT.
+ * Later, a processing stage reshapes the data to obtain half of the frequency spectrum
+ * in complex format. Except the first complex number that contains the two real numbers
+ * X[0] and X[N/2] all the data is complex. In other words, the first complex sample
+ * contains two real values packed.
+ * \par
+ * The input for the inverse RFFT should keep the same format as the output of the
+ * forward RFFT. A first processing stage pre-process the data to later perform an
+ * inverse CFFT.
+ * \par
+ * \image html RIFFT.gif "Real Inverse Fast Fourier Transform"
+ * \par
+ * The algorithms for floating-point, Q15, and Q31 data are slightly different
+ * and we describe each algorithm in turn.
+ * \par Floating-point
+ * The main functions are arm_rfft_fast_f32()
+ * and arm_rfft_fast_init_f32()
. The older functions
+ * arm_rfft_f32()
and arm_rfft_init_f32()
have been
+ * deprecated but are still documented.
+ * \par
+ * The FFT of a real N-point sequence has even symmetry in the frequency
+ * domain. The second half of the data equals the conjugate of the first half
+ * flipped in frequency:
+ *
+ *X[0] - real data
+ *X[1] - complex data
+ *X[2] - complex data
+ *...
+ *X[fftLen/2-1] - complex data
+ *X[fftLen/2] - real data
+ *X[fftLen/2+1] - conjugate of X[fftLen/2-1]
+ *X[fftLen/2+2] - conjugate of X[fftLen/2-2]
+ *...
+ *X[fftLen-1] - conjugate of X[1]
+ *
+ * Looking at the data, we see that we can uniquely represent the FFT using only
+ *
+ *N/2+1 samples:
+ *X[0] - real data
+ *X[1] - complex data
+ *X[2] - complex data
+ *...
+ *X[fftLen/2-1] - complex data
+ *X[fftLen/2] - real data
+ *
+ * Looking more closely we see that the first and last samples are real valued.
+ * They can be packed together and we can thus represent the FFT of an N-point
+ * real sequence by N/2 complex values:
+ *
+ *X[0],X[N/2] - packed real data: X[0] + jX[N/2]
+ *X[1] - complex data
+ *X[2] - complex data
+ *...
+ *X[fftLen/2-1] - complex data
+ *
+ * The real FFT functions pack the frequency domain data in this fashion. The
+ * forward transform outputs the data in this form and the inverse transform
+ * expects input data in this form. The function always performs the needed
+ * bitreversal so that the input and output data is always in normal order. The
+ * functions support lengths of [32, 64, 128, ..., 4096] samples.
+ * \par
+ * The forward and inverse real FFT functions apply the standard FFT scaling; no
+ * scaling on the forward transform and 1/fftLen scaling on the inverse
+ * transform.
+ * \par Q15 and Q31
+ * The real algorithms are defined in a similar manner and utilize N/2 complex
+ * transforms behind the scenes.
+ * \par
+ * The complex transforms used internally include scaling to prevent fixed-point
+ * overflows. The overall scaling equals 1/(fftLen/2).
+ * \par
+ * A separate instance structure must be defined for each transform used but
+ * twiddle factor and bit reversal tables can be reused.
+ * \par
+ * There is also an associated initialization function for each data type.
+ * The initialization function performs the following operations:
+ * - Sets the values of the internal structure fields.
+ * - Initializes twiddle factor table and bit reversal table pointers.
+ * - Initializes the internal complex FFT data structure.
+ * \par
+ * Use of the initialization function is optional.
+ * However, if the initialization function is used, then the instance structure
+ * cannot be placed into a const data section. To place an instance structure
+ * into a const data section, the instance structure should be manually
+ * initialized as follows:
+ *
+ *arm_rfft_instance_q31 S = {fftLenReal, fftLenBy2, ifftFlagR, bitReverseFlagR, twidCoefRModifier, pTwiddleAReal, pTwiddleBReal, pCfft};
+ *arm_rfft_instance_q15 S = {fftLenReal, fftLenBy2, ifftFlagR, bitReverseFlagR, twidCoefRModifier, pTwiddleAReal, pTwiddleBReal, pCfft};
+ *
+ * where fftLenReal
is the length of the real transform;
+ * fftLenBy2
length of the internal complex transform.
+ * ifftFlagR
Selects forward (=0) or inverse (=1) transform.
+ * bitReverseFlagR
Selects bit reversed output (=0) or normal order
+ * output (=1).
+ * twidCoefRModifier
stride modifier for the twiddle factor table.
+ * The value is based on the FFT length;
+ * pTwiddleAReal
points to the A array of twiddle coefficients;
+ * pTwiddleBReal
points to the B array of twiddle coefficients;
+ * pCfft
points to the CFFT Instance structure. The CFFT structure
+ * must also be initialized. Refer to arm_cfft_radix4_f32() for details regarding
+ * static initialization of the complex FFT instance structure.
+ */
+
+/**
+* @addtogroup RealFFT
+* @{
+*/
+
+/**
+* @brief Processing function for the floating-point real FFT.
+* @param[in] *S points to an arm_rfft_fast_instance_f32 structure.
+* @param[in] *p points to the input buffer.
+* @param[in] *pOut points to the output buffer.
+* @param[in] ifftFlag RFFT if flag is 0, RIFFT if flag is 1
+* @return none.
+*/
+
+void arm_rfft_fast_f32(
+arm_rfft_fast_instance_f32 * S,
+float32_t * p, float32_t * pOut,
+uint8_t ifftFlag)
+{
+ arm_cfft_instance_f32 * Sint = &(S->Sint);
+ Sint->fftLen = S->fftLenRFFT / 2;
+
+ /* Calculation of Real FFT */
+ if(ifftFlag)
+ {
+ /* Real FFT compression */
+ merge_rfft_f32(S, p, pOut);
+
+ /* Complex radix-4 IFFT process */
+ arm_cfft_f32( Sint, pOut, ifftFlag, 1);
+ }
+ else
+ {
+ /* Calculation of RFFT of input */
+ arm_cfft_f32( Sint, p, ifftFlag, 1);
+
+ /* Real FFT extraction */
+ stage_rfft_f32(S, p, pOut);
+ }
+}
+
+/**
+* @} end of RealFFT group
+*/
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_fast_init_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_fast_init_f32.c
new file mode 100644
index 0000000..c9fa0c1
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_fast_init_f32.c
@@ -0,0 +1,143 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_cfft_init_f32.c
+*
+* Description: Split Radix Decimation in Frequency CFFT Floating point processing function
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+#include "arm_common_tables.h"
+
+/**
+ * @ingroup groupTransforms
+ */
+
+/**
+ * @addtogroup RealFFT
+ * @{
+ */
+
+/**
+* @brief Initialization function for the floating-point real FFT.
+* @param[in,out] *S points to an arm_rfft_fast_instance_f32 structure.
+* @param[in] fftLen length of the Real Sequence.
+* @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen
is not a supported value.
+*
+* \par Description:
+* \par
+* The parameter fftLen
Specifies length of RFFT/CIFFT process. Supported FFT Lengths are 32, 64, 128, 256, 512, 1024, 2048, 4096.
+* \par
+* This Function also initializes Twiddle factor table pointer and Bit reversal table pointer.
+*/
+arm_status arm_rfft_fast_init_f32(
+ arm_rfft_fast_instance_f32 * S,
+ uint16_t fftLen)
+{
+ arm_cfft_instance_f32 * Sint;
+ /* Initialise the default arm status */
+ arm_status status = ARM_MATH_SUCCESS;
+ /* Initialise the FFT length */
+ Sint = &(S->Sint);
+ Sint->fftLen = fftLen/2;
+ S->fftLenRFFT = fftLen;
+
+ /* Initializations of structure parameters depending on the FFT length */
+ switch (Sint->fftLen)
+ {
+ case 2048u:
+ /* Initializations of structure parameters for 2048 point FFT */
+ /* Initialise the bit reversal table length */
+ Sint->bitRevLength = ARMBITREVINDEXTABLE2048_TABLE_LENGTH;
+ /* Initialise the bit reversal table pointer */
+ Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable2048;
+ /* Initialise the Twiddle coefficient pointers */
+ Sint->pTwiddle = (float32_t *) twiddleCoef_2048;
+ S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_4096;
+ break;
+ case 1024u:
+ Sint->bitRevLength = ARMBITREVINDEXTABLE1024_TABLE_LENGTH;
+ Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable1024;
+ Sint->pTwiddle = (float32_t *) twiddleCoef_1024;
+ S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_2048;
+ break;
+ case 512u:
+ Sint->bitRevLength = ARMBITREVINDEXTABLE_512_TABLE_LENGTH;
+ Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable512;
+ Sint->pTwiddle = (float32_t *) twiddleCoef_512;
+ S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_1024;
+ break;
+ case 256u:
+ Sint->bitRevLength = ARMBITREVINDEXTABLE_256_TABLE_LENGTH;
+ Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable256;
+ Sint->pTwiddle = (float32_t *) twiddleCoef_256;
+ S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_512;
+ break;
+ case 128u:
+ Sint->bitRevLength = ARMBITREVINDEXTABLE_128_TABLE_LENGTH;
+ Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable128;
+ Sint->pTwiddle = (float32_t *) twiddleCoef_128;
+ S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_256;
+ break;
+ case 64u:
+ Sint->bitRevLength = ARMBITREVINDEXTABLE__64_TABLE_LENGTH;
+ Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable64;
+ Sint->pTwiddle = (float32_t *) twiddleCoef_64;
+ S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_128;
+ break;
+ case 32u:
+ Sint->bitRevLength = ARMBITREVINDEXTABLE__32_TABLE_LENGTH;
+ Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable32;
+ Sint->pTwiddle = (float32_t *) twiddleCoef_32;
+ S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_64;
+ break;
+ case 16u:
+ Sint->bitRevLength = ARMBITREVINDEXTABLE__16_TABLE_LENGTH;
+ Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable16;
+ Sint->pTwiddle = (float32_t *) twiddleCoef_16;
+ S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_32;
+ break;
+ default:
+ /* Reporting argument error if fftSize is not valid value */
+ status = ARM_MATH_ARGUMENT_ERROR;
+ break;
+ }
+
+ return (status);
+}
+
+/**
+ * @} end of RealFFT group
+ */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_init_f32.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_init_f32.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_init_f32.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_init_f32.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_init_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_init_q15.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_init_q15.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_init_q15.c
diff --git a/assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_init_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_init_q31.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_init_q31.c
rename to templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_init_q31.c
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_q15.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_q15.c
new file mode 100644
index 0000000..8d2e918
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_q15.c
@@ -0,0 +1,439 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_rfft_q15.c
+*
+* Description: RFFT & RIFFT Q15 process function
+*
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/*--------------------------------------------------------------------
+* Internal functions prototypes
+--------------------------------------------------------------------*/
+
+void arm_split_rfft_q15(
+ q15_t * pSrc,
+ uint32_t fftLen,
+ q15_t * pATable,
+ q15_t * pBTable,
+ q15_t * pDst,
+ uint32_t modifier);
+
+void arm_split_rifft_q15(
+ q15_t * pSrc,
+ uint32_t fftLen,
+ q15_t * pATable,
+ q15_t * pBTable,
+ q15_t * pDst,
+ uint32_t modifier);
+
+/**
+* @addtogroup RealFFT
+* @{
+*/
+
+/**
+* @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.
+*
+* \par Input an output formats:
+* \par
+* Internally input is downscaled by 2 for every stage to avoid saturations inside CFFT/CIFFT process.
+* Hence the output format is different for different RFFT sizes.
+* The input and output formats for different RFFT sizes and number of bits to upscale are mentioned in the tables below for RFFT and RIFFT:
+* \par
+* \image html RFFTQ15.gif "Input and Output Formats for Q15 RFFT"
+* \par
+* \image html RIFFTQ15.gif "Input and Output Formats for Q15 RIFFT"
+*/
+
+void arm_rfft_q15(
+ const arm_rfft_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst)
+{
+ const arm_cfft_instance_q15 *S_CFFT = S->pCfft;
+ uint32_t i;
+ uint32_t L2 = S->fftLenReal >> 1;
+
+ /* Calculation of RIFFT of input */
+ if(S->ifftFlagR == 1u)
+ {
+ /* Real IFFT core process */
+ arm_split_rifft_q15(pSrc, L2, S->pTwiddleAReal,
+ S->pTwiddleBReal, pDst, S->twidCoefRModifier);
+
+ /* Complex IFFT process */
+ arm_cfft_q15(S_CFFT, pDst, S->ifftFlagR, S->bitReverseFlagR);
+
+ for(i=0;ifftLenReal;i++)
+ {
+ pDst[i] = pDst[i] << 1;
+ }
+ }
+ else
+ {
+ /* Calculation of RFFT of input */
+
+ /* Complex FFT process */
+ arm_cfft_q15(S_CFFT, pSrc, S->ifftFlagR, S->bitReverseFlagR);
+
+ /* Real FFT core process */
+ arm_split_rfft_q15(pSrc, L2, S->pTwiddleAReal,
+ S->pTwiddleBReal, pDst, S->twidCoefRModifier);
+ }
+}
+
+/**
+* @} end of RealFFT group
+*/
+
+/**
+* @brief Core Real FFT process
+* @param *pSrc points to the input buffer.
+* @param fftLen length of FFT.
+* @param *pATable points to the A twiddle Coef buffer.
+* @param *pBTable points to the B twiddle Coef buffer.
+* @param *pDst points to the output buffer.
+* @param modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
+* @return none.
+* The function implements a Real FFT
+*/
+
+void arm_split_rfft_q15(
+ q15_t * pSrc,
+ uint32_t fftLen,
+ q15_t * pATable,
+ q15_t * pBTable,
+ q15_t * pDst,
+ uint32_t modifier)
+{
+ uint32_t i; /* Loop Counter */
+ q31_t outR, outI; /* Temporary variables for output */
+ q15_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
+ q15_t *pSrc1, *pSrc2;
+#ifndef ARM_MATH_CM0_FAMILY
+ q15_t *pD1, *pD2;
+#endif
+
+ // pSrc[2u * fftLen] = pSrc[0];
+ // pSrc[(2u * fftLen) + 1u] = pSrc[1];
+
+ pCoefA = &pATable[modifier * 2u];
+ pCoefB = &pBTable[modifier * 2u];
+
+ pSrc1 = &pSrc[2];
+ pSrc2 = &pSrc[(2u * fftLen) - 2u];
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ i = 1u;
+ pD1 = pDst + 2;
+ pD2 = pDst + (4u * fftLen) - 2;
+
+ for(i = fftLen - 1; i > 0; i--)
+ {
+ /*
+ outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1]
+ + pSrc[2 * n - 2 * i] * pBTable[2 * i] +
+ pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
+ */
+
+ /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] +
+ pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
+ pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); */
+
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ /* pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1] */
+ outR = __SMUSD(*__SIMD32(pSrc1), *__SIMD32(pCoefA));
+
+#else
+
+ /* -(pSrc[2 * i + 1] * pATable[2 * i + 1] - pSrc[2 * i] * pATable[2 * i]) */
+ outR = -(__SMUSD(*__SIMD32(pSrc1), *__SIMD32(pCoefA)));
+
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+
+ /* pSrc[2 * n - 2 * i] * pBTable[2 * i] +
+ pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]) */
+ outR = __SMLAD(*__SIMD32(pSrc2), *__SIMD32(pCoefB), outR) >> 16u;
+
+ /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
+ pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ outI = __SMUSDX(*__SIMD32(pSrc2)--, *__SIMD32(pCoefB));
+
+#else
+
+ outI = __SMUSDX(*__SIMD32(pCoefB), *__SIMD32(pSrc2)--);
+
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+
+ /* (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] */
+ outI = __SMLADX(*__SIMD32(pSrc1)++, *__SIMD32(pCoefA), outI);
+
+ /* write output */
+ *pD1++ = (q15_t) outR;
+ *pD1++ = outI >> 16u;
+
+ /* write complex conjugate output */
+ pD2[0] = (q15_t) outR;
+ pD2[1] = -(outI >> 16u);
+ pD2 -= 2;
+
+ /* update coefficient pointer */
+ pCoefB = pCoefB + (2u * modifier);
+ pCoefA = pCoefA + (2u * modifier);
+ }
+
+ pDst[2u * fftLen] = (pSrc[0] - pSrc[1]) >> 1;
+ pDst[(2u * fftLen) + 1u] = 0;
+
+ pDst[0] = (pSrc[0] + pSrc[1]) >> 1;
+ pDst[1] = 0;
+
+#else
+
+ /* Run the below code for Cortex-M0 */
+ i = 1u;
+
+ while(i < fftLen)
+ {
+ /*
+ outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1]
+ + pSrc[2 * n - 2 * i] * pBTable[2 * i] +
+ pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
+ */
+
+ outR = *pSrc1 * *pCoefA;
+ outR = outR - (*(pSrc1 + 1) * *(pCoefA + 1));
+ outR = outR + (*pSrc2 * *pCoefB);
+ outR = (outR + (*(pSrc2 + 1) * *(pCoefB + 1))) >> 16;
+
+
+ /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] +
+ pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
+ pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
+ */
+
+ outI = *pSrc2 * *(pCoefB + 1);
+ outI = outI - (*(pSrc2 + 1) * *pCoefB);
+ outI = outI + (*(pSrc1 + 1) * *pCoefA);
+ outI = outI + (*pSrc1 * *(pCoefA + 1));
+
+ /* update input pointers */
+ pSrc1 += 2u;
+ pSrc2 -= 2u;
+
+ /* write output */
+ pDst[2u * i] = (q15_t) outR;
+ pDst[(2u * i) + 1u] = outI >> 16u;
+
+ /* write complex conjugate output */
+ pDst[(4u * fftLen) - (2u * i)] = (q15_t) outR;
+ pDst[((4u * fftLen) - (2u * i)) + 1u] = -(outI >> 16u);
+
+ /* update coefficient pointer */
+ pCoefB = pCoefB + (2u * modifier);
+ pCoefA = pCoefA + (2u * modifier);
+
+ i++;
+ }
+
+ pDst[2u * fftLen] = (pSrc[0] - pSrc[1]) >> 1;
+ pDst[(2u * fftLen) + 1u] = 0;
+
+ pDst[0] = (pSrc[0] + pSrc[1]) >> 1;
+ pDst[1] = 0;
+
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+}
+
+
+/**
+* @brief Core Real IFFT process
+* @param[in] *pSrc points to the input buffer.
+* @param[in] fftLen length of FFT.
+* @param[in] *pATable points to the twiddle Coef A buffer.
+* @param[in] *pBTable points to the twiddle Coef B buffer.
+* @param[out] *pDst points to the output buffer.
+* @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
+* @return none.
+* The function implements a Real IFFT
+*/
+void arm_split_rifft_q15(
+ q15_t * pSrc,
+ uint32_t fftLen,
+ q15_t * pATable,
+ q15_t * pBTable,
+ q15_t * pDst,
+ uint32_t modifier)
+{
+ uint32_t i; /* Loop Counter */
+ q31_t outR, outI; /* Temporary variables for output */
+ q15_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
+ q15_t *pSrc1, *pSrc2;
+ q15_t *pDst1 = &pDst[0];
+
+ pCoefA = &pATable[0];
+ pCoefB = &pBTable[0];
+
+ pSrc1 = &pSrc[0];
+ pSrc2 = &pSrc[2u * fftLen];
+
+#ifndef ARM_MATH_CM0_FAMILY
+
+ /* Run the below code for Cortex-M4 and Cortex-M3 */
+ i = fftLen;
+
+ while(i > 0u)
+ {
+ /*
+ outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
+ pIn[2 * n - 2 * i] * pBTable[2 * i] -
+ pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
+
+ outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] -
+ pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
+ pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
+ */
+
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ /* pIn[2 * n - 2 * i] * pBTable[2 * i] -
+ pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]) */
+ outR = __SMUSD(*__SIMD32(pSrc2), *__SIMD32(pCoefB));
+
+#else
+
+ /* -(-pIn[2 * n - 2 * i] * pBTable[2 * i] +
+ pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1])) */
+ outR = -(__SMUSD(*__SIMD32(pSrc2), *__SIMD32(pCoefB)));
+
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+
+ /* pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
+ pIn[2 * n - 2 * i] * pBTable[2 * i] */
+ outR = __SMLAD(*__SIMD32(pSrc1), *__SIMD32(pCoefA), outR) >> 16u;
+
+ /*
+ -pIn[2 * n - 2 * i] * pBTable[2 * i + 1] +
+ pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */
+ outI = __SMUADX(*__SIMD32(pSrc2)--, *__SIMD32(pCoefB));
+
+ /* pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] */
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ outI = __SMLSDX(*__SIMD32(pCoefA), *__SIMD32(pSrc1)++, -outI);
+
+#else
+
+ outI = __SMLSDX(*__SIMD32(pSrc1)++, *__SIMD32(pCoefA), -outI);
+
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+ /* write output */
+
+#ifndef ARM_MATH_BIG_ENDIAN
+
+ *__SIMD32(pDst1)++ = __PKHBT(outR, (outI >> 16u), 16);
+
+#else
+
+ *__SIMD32(pDst1)++ = __PKHBT((outI >> 16u), outR, 16);
+
+#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
+
+ /* update coefficient pointer */
+ pCoefB = pCoefB + (2u * modifier);
+ pCoefA = pCoefA + (2u * modifier);
+
+ i--;
+ }
+#else
+ /* Run the below code for Cortex-M0 */
+ i = fftLen;
+
+ while(i > 0u)
+ {
+ /*
+ outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
+ pIn[2 * n - 2 * i] * pBTable[2 * i] -
+ pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
+ */
+
+ outR = *pSrc2 * *pCoefB;
+ outR = outR - (*(pSrc2 + 1) * *(pCoefB + 1));
+ outR = outR + (*pSrc1 * *pCoefA);
+ outR = (outR + (*(pSrc1 + 1) * *(pCoefA + 1))) >> 16;
+
+ /*
+ outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] -
+ pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
+ pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
+ */
+
+ outI = *(pSrc1 + 1) * *pCoefA;
+ outI = outI - (*pSrc1 * *(pCoefA + 1));
+ outI = outI - (*pSrc2 * *(pCoefB + 1));
+ outI = outI - (*(pSrc2 + 1) * *(pCoefB));
+
+ /* update input pointers */
+ pSrc1 += 2u;
+ pSrc2 -= 2u;
+
+ /* write output */
+ *pDst1++ = (q15_t) outR;
+ *pDst1++ = (q15_t) (outI >> 16);
+
+ /* update coefficient pointer */
+ pCoefB = pCoefB + (2u * modifier);
+ pCoefA = pCoefA + (2u * modifier);
+
+ i--;
+ }
+#endif /* #ifndef ARM_MATH_CM0_FAMILY */
+}
diff --git a/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_q31.c b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_q31.c
new file mode 100644
index 0000000..2f1cd0a
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/DSP_Lib/Source/TransformFunctions/arm_rfft_q31.c
@@ -0,0 +1,296 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_rfft_q31.c
+*
+* Description: RFFT & RIFFT Q31 process function
+*
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* 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 ARM LIMITED 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 "arm_math.h"
+
+/*--------------------------------------------------------------------
+* Internal functions prototypes
+--------------------------------------------------------------------*/
+
+void arm_split_rfft_q31(
+ q31_t * pSrc,
+ uint32_t fftLen,
+ q31_t * pATable,
+ q31_t * pBTable,
+ q31_t * pDst,
+ uint32_t modifier);
+
+void arm_split_rifft_q31(
+ q31_t * pSrc,
+ uint32_t fftLen,
+ q31_t * pATable,
+ q31_t * pBTable,
+ q31_t * pDst,
+ uint32_t modifier);
+
+/**
+* @addtogroup RealFFT
+* @{
+*/
+
+/**
+* @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.
+*
+* \par Input an output formats:
+* \par
+* Internally input is downscaled by 2 for every stage to avoid saturations inside CFFT/CIFFT process.
+* Hence the output format is different for different RFFT sizes.
+* The input and output formats for different RFFT sizes and number of bits to upscale are mentioned in the tables below for RFFT and RIFFT:
+* \par
+* \image html RFFTQ31.gif "Input and Output Formats for Q31 RFFT"
+*
+* \par
+* \image html RIFFTQ31.gif "Input and Output Formats for Q31 RIFFT"
+*/
+void arm_rfft_q31(
+ const arm_rfft_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst)
+{
+ const arm_cfft_instance_q31 *S_CFFT = S->pCfft;
+ uint32_t i;
+ uint32_t L2 = S->fftLenReal >> 1;
+
+ /* Calculation of RIFFT of input */
+ if(S->ifftFlagR == 1u)
+ {
+ /* Real IFFT core process */
+ arm_split_rifft_q31(pSrc, L2, S->pTwiddleAReal,
+ S->pTwiddleBReal, pDst, S->twidCoefRModifier);
+
+ /* Complex IFFT process */
+ arm_cfft_q31(S_CFFT, pDst, S->ifftFlagR, S->bitReverseFlagR);
+
+ for(i=0;ifftLenReal;i++)
+ {
+ pDst[i] = pDst[i] << 1;
+ }
+ }
+ else
+ {
+ /* Calculation of RFFT of input */
+
+ /* Complex FFT process */
+ arm_cfft_q31(S_CFFT, pSrc, S->ifftFlagR, S->bitReverseFlagR);
+
+ /* Real FFT core process */
+ arm_split_rfft_q31(pSrc, L2, S->pTwiddleAReal,
+ S->pTwiddleBReal, pDst, S->twidCoefRModifier);
+ }
+}
+
+/**
+* @} end of RealFFT group
+*/
+
+/**
+* @brief Core Real FFT process
+* @param[in] *pSrc points to the input buffer.
+* @param[in] fftLen length of FFT.
+* @param[in] *pATable points to the twiddle Coef A buffer.
+* @param[in] *pBTable points to the twiddle Coef B buffer.
+* @param[out] *pDst points to the output buffer.
+* @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
+* @return none.
+*/
+void arm_split_rfft_q31(
+ q31_t * pSrc,
+ uint32_t fftLen,
+ q31_t * pATable,
+ q31_t * pBTable,
+ q31_t * pDst,
+ uint32_t modifier)
+{
+ uint32_t i; /* Loop Counter */
+ q31_t outR, outI; /* Temporary variables for output */
+ q31_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
+ q31_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */
+ q31_t *pOut1 = &pDst[2], *pOut2 = &pDst[(4u * fftLen) - 1u];
+ q31_t *pIn1 = &pSrc[2], *pIn2 = &pSrc[(2u * fftLen) - 1u];
+
+ /* Init coefficient pointers */
+ pCoefA = &pATable[modifier * 2u];
+ pCoefB = &pBTable[modifier * 2u];
+
+ i = fftLen - 1u;
+
+ while(i > 0u)
+ {
+ /*
+ outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1]
+ + pSrc[2 * n - 2 * i] * pBTable[2 * i] +
+ pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
+ */
+
+ /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] +
+ pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
+ pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); */
+
+ CoefA1 = *pCoefA++;
+ CoefA2 = *pCoefA;
+
+ /* outR = (pSrc[2 * i] * pATable[2 * i] */
+ mult_32x32_keep32_R(outR, *pIn1, CoefA1);
+
+ /* outI = pIn[2 * i] * pATable[2 * i + 1] */
+ mult_32x32_keep32_R(outI, *pIn1++, CoefA2);
+
+ /* - pSrc[2 * i + 1] * pATable[2 * i + 1] */
+ multSub_32x32_keep32_R(outR, *pIn1, CoefA2);
+
+ /* (pIn[2 * i + 1] * pATable[2 * i] */
+ multAcc_32x32_keep32_R(outI, *pIn1++, CoefA1);
+
+ /* pSrc[2 * n - 2 * i] * pBTable[2 * i] */
+ multSub_32x32_keep32_R(outR, *pIn2, CoefA2);
+ CoefB1 = *pCoefB;
+
+ /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] */
+ multSub_32x32_keep32_R(outI, *pIn2--, CoefB1);
+
+ /* pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1] */
+ multAcc_32x32_keep32_R(outR, *pIn2, CoefB1);
+
+ /* pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */
+ multSub_32x32_keep32_R(outI, *pIn2--, CoefA2);
+
+ /* write output */
+ *pOut1++ = outR;
+ *pOut1++ = outI;
+
+ /* write complex conjugate output */
+ *pOut2-- = -outI;
+ *pOut2-- = outR;
+
+ /* update coefficient pointer */
+ pCoefB = pCoefB + (modifier * 2u);
+ pCoefA = pCoefA + ((modifier * 2u) - 1u);
+
+ i--;
+ }
+ pDst[2u * fftLen] = (pSrc[0] - pSrc[1]) >> 1;
+ pDst[(2u * fftLen) + 1u] = 0;
+
+ pDst[0] = (pSrc[0] + pSrc[1]) >> 1;
+ pDst[1] = 0;
+}
+
+/**
+* @brief Core Real IFFT process
+* @param[in] *pSrc points to the input buffer.
+* @param[in] fftLen length of FFT.
+* @param[in] *pATable points to the twiddle Coef A buffer.
+* @param[in] *pBTable points to the twiddle Coef B buffer.
+* @param[out] *pDst points to the output buffer.
+* @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
+* @return none.
+*/
+void arm_split_rifft_q31(
+ q31_t * pSrc,
+ uint32_t fftLen,
+ q31_t * pATable,
+ q31_t * pBTable,
+ q31_t * pDst,
+ uint32_t modifier)
+{
+ q31_t outR, outI; /* Temporary variables for output */
+ q31_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */
+ q31_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */
+ q31_t *pIn1 = &pSrc[0], *pIn2 = &pSrc[(2u * fftLen) + 1u];
+
+ pCoefA = &pATable[0];
+ pCoefB = &pBTable[0];
+
+ while(fftLen > 0u)
+ {
+ /*
+ outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
+ pIn[2 * n - 2 * i] * pBTable[2 * i] -
+ pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
+
+ outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] -
+ pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
+ pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
+ */
+ CoefA1 = *pCoefA++;
+ CoefA2 = *pCoefA;
+
+ /* outR = (pIn[2 * i] * pATable[2 * i] */
+ mult_32x32_keep32_R(outR, *pIn1, CoefA1);
+
+ /* - pIn[2 * i] * pATable[2 * i + 1] */
+ mult_32x32_keep32_R(outI, *pIn1++, -CoefA2);
+
+ /* pIn[2 * i + 1] * pATable[2 * i + 1] */
+ multAcc_32x32_keep32_R(outR, *pIn1, CoefA2);
+
+ /* pIn[2 * i + 1] * pATable[2 * i] */
+ multAcc_32x32_keep32_R(outI, *pIn1++, CoefA1);
+
+ /* pIn[2 * n - 2 * i] * pBTable[2 * i] */
+ multAcc_32x32_keep32_R(outR, *pIn2, CoefA2);
+ CoefB1 = *pCoefB;
+
+ /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] */
+ multSub_32x32_keep32_R(outI, *pIn2--, CoefB1);
+
+ /* pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1] */
+ multAcc_32x32_keep32_R(outR, *pIn2, CoefB1);
+
+ /* pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */
+ multAcc_32x32_keep32_R(outI, *pIn2--, CoefA2);
+
+ /* write output */
+ *pDst++ = outR;
+ *pDst++ = outI;
+
+ /* update coefficient pointer */
+ pCoefB = pCoefB + (modifier * 2u);
+ pCoefA = pCoefA + ((modifier * 2u) - 1u);
+
+ /* Decrement loop count */
+ fftLen--;
+ }
+}
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f100xb.h b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f100xb.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f100xb.h
rename to templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f100xb.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f100xe.h b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f100xe.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f100xe.h
rename to templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f100xe.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101x6.h b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101x6.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101x6.h
rename to templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101x6.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101xb.h b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101xb.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101xb.h
rename to templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101xb.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101xe.h b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101xe.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101xe.h
rename to templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101xe.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101xg.h b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101xg.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101xg.h
rename to templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101xg.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f102x6.h b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f102x6.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f102x6.h
rename to templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f102x6.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f102xb.h b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f102xb.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f102xb.h
rename to templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f102xb.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103x6.h b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103x6.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103x6.h
rename to templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103x6.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h
rename to templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xe.h b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xe.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xe.h
rename to templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xe.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xg.h b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xg.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xg.h
rename to templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xg.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f105xc.h b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f105xc.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f105xc.h
rename to templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f105xc.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f107xc.h b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f107xc.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f107xc.h
rename to templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f107xc.h
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h
new file mode 100644
index 0000000..333095b
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h
@@ -0,0 +1,238 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx.h
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @brief CMSIS STM32F1xx Device Peripheral Access Layer Header File.
+ *
+ * The file is the unique include file that the application programmer
+ * is using in the C source code, usually in main.c. This file contains:
+ * - Configuration section that allows to select:
+ * - The STM32F1xx device used in the target application
+ * - To use or not the peripheral’s drivers in application code(i.e.
+ * code will be based on direct access to peripheral’s registers
+ * rather than drivers API), this option is controlled by
+ * "#define USE_HAL_DRIVER"
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup stm32f1xx
+ * @{
+ */
+
+#ifndef __STM32F1XX_H
+#define __STM32F1XX_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif /* __cplusplus */
+
+/** @addtogroup Library_configuration_section
+ * @{
+ */
+
+/**
+ * @brief STM32 Family
+ */
+#if !defined (STM32F1)
+#define STM32F1
+#endif /* STM32F1 */
+
+/* Uncomment the line below according to the target STM32L device used in your
+ application
+ */
+
+#if !defined (STM32F100xB) && !defined (STM32F100xE) && !defined (STM32F101x6) && \
+ !defined (STM32F101xB) && !defined (STM32F101xE) && !defined (STM32F101xG) && !defined (STM32F102x6) && !defined (STM32F102xB) && !defined (STM32F103x6) && \
+ !defined (STM32F103xB) && !defined (STM32F103xE) && !defined (STM32F103xG) && !defined (STM32F105xC) && !defined (STM32F107xC)
+ /* #define STM32F100xB */ /*!< STM32F100C4, STM32F100R4, STM32F100C6, STM32F100R6, STM32F100C8, STM32F100R8, STM32F100V8, STM32F100CB, STM32F100RB and STM32F100VB */
+ /* #define STM32F100xE */ /*!< STM32F100RC, STM32F100VC, STM32F100ZC, STM32F100RD, STM32F100VD, STM32F100ZD, STM32F100RE, STM32F100VE and STM32F100ZE */
+ /* #define STM32F101x6 */ /*!< STM32F101C4, STM32F101R4, STM32F101T4, STM32F101C6, STM32F101R6 and STM32F101T6 Devices */
+ /* #define STM32F101xB */ /*!< STM32F101C8, STM32F101R8, STM32F101T8, STM32F101V8, STM32F101CB, STM32F101RB, STM32F101TB and STM32F101VB */
+ /* #define STM32F101xE */ /*!< STM32F101RC, STM32F101VC, STM32F101ZC, STM32F101RD, STM32F101VD, STM32F101ZD, STM32F101RE, STM32F101VE and STM32F101ZE */
+ /* #define STM32F101xG */ /*!< STM32F101RF, STM32F101VF, STM32F101ZF, STM32F101RG, STM32F101VG and STM32F101ZG */
+ /* #define STM32F102x6 */ /*!< STM32F102C4, STM32F102R4, STM32F102C6 and STM32F102R6 */
+ /* #define STM32F102xB */ /*!< STM32F102C8, STM32F102R8, STM32F102CB and STM32F102RB */
+ /* #define STM32F103x6 */ /*!< STM32F103C4, STM32F103R4, STM32F103T4, STM32F103C6, STM32F103R6 and STM32F103T6 */
+ /* #define STM32F103xB */ /*!< STM32F103C8, STM32F103R8, STM32F103T8, STM32F103V8, STM32F103CB, STM32F103RB, STM32F103TB and STM32F103VB */
+ /* #define STM32F103xE */ /*!< STM32F103RC, STM32F103VC, STM32F103ZC, STM32F103RD, STM32F103VD, STM32F103ZD, STM32F103RE, STM32F103VE and STM32F103ZE */
+ /* #define STM32F103xG */ /*!< STM32F103RF, STM32F103VF, STM32F103ZF, STM32F103RG, STM32F103VG and STM32F103ZG */
+ /* #define STM32F105xC */ /*!< STM32F105R8, STM32F105V8, STM32F105RB, STM32F105VB, STM32F105RC and STM32F105VC */
+ /* #define STM32F107xC */ /*!< STM32F107RB, STM32F107VB, STM32F107RC and STM32F107VC */
+#endif
+
+/* Tip: To avoid modifying this file each time you need to switch between these
+ devices, you can define the device in your toolchain compiler preprocessor.
+ */
+
+#if !defined (USE_HAL_DRIVER)
+/**
+ * @brief Comment the line below if you will not use the peripherals drivers.
+ In this case, these drivers will not be included and the application code will
+ be based on direct access to peripherals registers
+ */
+ /*#define USE_HAL_DRIVER */
+#endif /* USE_HAL_DRIVER */
+
+/**
+ * @brief CMSIS Device version number V4.2.0
+ */
+#define __STM32F1_CMSIS_VERSION_MAIN (0x04) /*!< [31:24] main version */
+#define __STM32F1_CMSIS_VERSION_SUB1 (0x02) /*!< [23:16] sub1 version */
+#define __STM32F1_CMSIS_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */
+#define __STM32F1_CMSIS_VERSION_RC (0x00) /*!< [7:0] release candidate */
+#define __STM32F1_CMSIS_VERSION ((__STM32F1_CMSIS_VERSION_MAIN << 24)\
+ |(__STM32F1_CMSIS_VERSION_SUB1 << 16)\
+ |(__STM32F1_CMSIS_VERSION_SUB2 << 8 )\
+ |(__STM32F1_CMSIS_VERSION_RC))
+
+/**
+ * @}
+ */
+
+/** @addtogroup Device_Included
+ * @{
+ */
+
+#if defined(STM32F100xB)
+ #include "stm32f100xb.h"
+#elif defined(STM32F100xE)
+ #include "stm32f100xe.h"
+#elif defined(STM32F101x6)
+ #include "stm32f101x6.h"
+#elif defined(STM32F101xB)
+ #include "stm32f101xb.h"
+#elif defined(STM32F101xE)
+ #include "stm32f101xe.h"
+#elif defined(STM32F101xG)
+ #include "stm32f101xg.h"
+#elif defined(STM32F102x6)
+ #include "stm32f102x6.h"
+#elif defined(STM32F102xB)
+ #include "stm32f102xb.h"
+#elif defined(STM32F103x6)
+ #include "stm32f103x6.h"
+#elif defined(STM32F103xB)
+ #include "stm32f103xb.h"
+#elif defined(STM32F103xE)
+ #include "stm32f103xe.h"
+#elif defined(STM32F103xG)
+ #include "stm32f103xg.h"
+#elif defined(STM32F105xC)
+ #include "stm32f105xc.h"
+#elif defined(STM32F107xC)
+ #include "stm32f107xc.h"
+#else
+ #error "Please select first the target STM32F1xx device used in your application (in stm32f1xx.h file)"
+#endif
+
+/**
+ * @}
+ */
+
+/** @addtogroup Exported_types
+ * @{
+ */
+typedef enum
+{
+ RESET = 0,
+ SET = !RESET
+} FlagStatus, ITStatus;
+
+typedef enum
+{
+ DISABLE = 0,
+ ENABLE = !DISABLE
+} FunctionalState;
+#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
+
+typedef enum
+{
+ ERROR = 0,
+ SUCCESS = !ERROR
+} ErrorStatus;
+
+/**
+ * @}
+ */
+
+
+/** @addtogroup Exported_macros
+ * @{
+ */
+#define SET_BIT(REG, BIT) ((REG) |= (BIT))
+
+#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
+
+#define READ_BIT(REG, BIT) ((REG) & (BIT))
+
+#define CLEAR_REG(REG) ((REG) = (0x0))
+
+#define WRITE_REG(REG, VAL) ((REG) = (VAL))
+
+#define READ_REG(REG) ((REG))
+
+#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
+
+#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL)))
+
+
+/**
+ * @}
+ */
+
+#if defined (USE_HAL_DRIVER)
+ #include "stm32f1xx_hal.h"
+#endif /* USE_HAL_DRIVER */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __STM32F1xx_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h
new file mode 100644
index 0000000..3652ff5
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h
@@ -0,0 +1,116 @@
+/**
+ ******************************************************************************
+ * @file system_stm32f10x.h
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Header File.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup stm32f10x_system
+ * @{
+ */
+
+/**
+ * @brief Define to prevent recursive inclusion
+ */
+#ifndef __SYSTEM_STM32F10X_H
+#define __SYSTEM_STM32F10X_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/** @addtogroup STM32F10x_System_Includes
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @addtogroup STM32F10x_System_Exported_types
+ * @{
+ */
+
+extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
+extern const uint8_t AHBPrescTable[16U]; /*!< AHB prescalers table values */
+extern const uint8_t APBPrescTable[8U]; /*!< APB prescalers table values */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F10x_System_Exported_Constants
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F10x_System_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F10x_System_Exported_Functions
+ * @{
+ */
+
+extern void SystemInit(void);
+extern void SystemCoreClockUpdate(void);
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__SYSTEM_STM32F10X_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f100xb.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f100xb.s
new file mode 100644
index 0000000..860cf6a
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f100xb.s
@@ -0,0 +1,332 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f100xb.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F100xB Devices vector table for MDK-ARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == Reset_Handler
+;* - Set the vector table entries with the exceptions ISR address
+;* - Configure the clock system
+;* - Branches to __main in the C library (which eventually
+;* calls main()).
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;
+;*******************************************************************************
+
+; Amount of memory (in bytes) allocated for Stack
+; Tailor this value to your application needs
+; Stack Configuration
+; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Stack_Size EQU 0x00000400
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem SPACE Stack_Size
+__initial_sp
+
+
+; Heap Configuration
+; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Heap_Size EQU 0x00000200
+
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem SPACE Heap_Size
+__heap_limit
+
+ PRESERVE8
+ THUMB
+
+
+; Vector Table Mapped to Address 0 at Reset
+ AREA RESET, DATA, READONLY
+ EXPORT __Vectors
+ EXPORT __Vectors_End
+ EXPORT __Vectors_Size
+
+__Vectors DCD __initial_sp ; Top of Stack
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_IRQHandler ; ADC1
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD TIM1_BRK_TIM15_IRQHandler ; TIM1 Break and TIM15
+ DCD TIM1_UP_TIM16_IRQHandler ; TIM1 Update and TIM16
+ DCD TIM1_TRG_COM_TIM17_IRQHandler ; TIM1 Trigger and Commutation and TIM17
+ DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C2 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD CEC_IRQHandler ; HDMI-CEC
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD TIM6_DAC_IRQHandler ; TIM6 and DAC underrun
+ DCD TIM7_IRQHandler ; TIM7
+__Vectors_End
+
+__Vectors_Size EQU __Vectors_End - __Vectors
+
+ AREA |.text|, CODE, READONLY
+
+; Reset handler
+Reset_Handler PROC
+ EXPORT Reset_Handler [WEAK]
+ IMPORT __main
+ IMPORT SystemInit
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__main
+ BX R0
+ ENDP
+
+; Dummy Exception Handlers (infinite loops which can be modified)
+
+NMI_Handler PROC
+ EXPORT NMI_Handler [WEAK]
+ B .
+ ENDP
+HardFault_Handler\
+ PROC
+ EXPORT HardFault_Handler [WEAK]
+ B .
+ ENDP
+MemManage_Handler\
+ PROC
+ EXPORT MemManage_Handler [WEAK]
+ B .
+ ENDP
+BusFault_Handler\
+ PROC
+ EXPORT BusFault_Handler [WEAK]
+ B .
+ ENDP
+UsageFault_Handler\
+ PROC
+ EXPORT UsageFault_Handler [WEAK]
+ B .
+ ENDP
+SVC_Handler PROC
+ EXPORT SVC_Handler [WEAK]
+ B .
+ ENDP
+DebugMon_Handler\
+ PROC
+ EXPORT DebugMon_Handler [WEAK]
+ B .
+ ENDP
+PendSV_Handler PROC
+ EXPORT PendSV_Handler [WEAK]
+ B .
+ ENDP
+SysTick_Handler PROC
+ EXPORT SysTick_Handler [WEAK]
+ B .
+ ENDP
+
+Default_Handler PROC
+
+ EXPORT WWDG_IRQHandler [WEAK]
+ EXPORT PVD_IRQHandler [WEAK]
+ EXPORT TAMPER_IRQHandler [WEAK]
+ EXPORT RTC_IRQHandler [WEAK]
+ EXPORT FLASH_IRQHandler [WEAK]
+ EXPORT RCC_IRQHandler [WEAK]
+ EXPORT EXTI0_IRQHandler [WEAK]
+ EXPORT EXTI1_IRQHandler [WEAK]
+ EXPORT EXTI2_IRQHandler [WEAK]
+ EXPORT EXTI3_IRQHandler [WEAK]
+ EXPORT EXTI4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel1_IRQHandler [WEAK]
+ EXPORT DMA1_Channel2_IRQHandler [WEAK]
+ EXPORT DMA1_Channel3_IRQHandler [WEAK]
+ EXPORT DMA1_Channel4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel5_IRQHandler [WEAK]
+ EXPORT DMA1_Channel6_IRQHandler [WEAK]
+ EXPORT DMA1_Channel7_IRQHandler [WEAK]
+ EXPORT ADC1_IRQHandler [WEAK]
+ EXPORT EXTI9_5_IRQHandler [WEAK]
+ EXPORT TIM1_BRK_TIM15_IRQHandler [WEAK]
+ EXPORT TIM1_UP_TIM16_IRQHandler [WEAK]
+ EXPORT TIM1_TRG_COM_TIM17_IRQHandler [WEAK]
+ EXPORT TIM1_CC_IRQHandler [WEAK]
+ EXPORT TIM2_IRQHandler [WEAK]
+ EXPORT TIM3_IRQHandler [WEAK]
+ EXPORT TIM4_IRQHandler [WEAK]
+ EXPORT I2C1_EV_IRQHandler [WEAK]
+ EXPORT I2C1_ER_IRQHandler [WEAK]
+ EXPORT I2C2_EV_IRQHandler [WEAK]
+ EXPORT I2C2_ER_IRQHandler [WEAK]
+ EXPORT SPI1_IRQHandler [WEAK]
+ EXPORT SPI2_IRQHandler [WEAK]
+ EXPORT USART1_IRQHandler [WEAK]
+ EXPORT USART2_IRQHandler [WEAK]
+ EXPORT USART3_IRQHandler [WEAK]
+ EXPORT EXTI15_10_IRQHandler [WEAK]
+ EXPORT RTC_Alarm_IRQHandler [WEAK]
+ EXPORT CEC_IRQHandler [WEAK]
+ EXPORT TIM6_DAC_IRQHandler [WEAK]
+ EXPORT TIM7_IRQHandler [WEAK]
+
+WWDG_IRQHandler
+PVD_IRQHandler
+TAMPER_IRQHandler
+RTC_IRQHandler
+FLASH_IRQHandler
+RCC_IRQHandler
+EXTI0_IRQHandler
+EXTI1_IRQHandler
+EXTI2_IRQHandler
+EXTI3_IRQHandler
+EXTI4_IRQHandler
+DMA1_Channel1_IRQHandler
+DMA1_Channel2_IRQHandler
+DMA1_Channel3_IRQHandler
+DMA1_Channel4_IRQHandler
+DMA1_Channel5_IRQHandler
+DMA1_Channel6_IRQHandler
+DMA1_Channel7_IRQHandler
+ADC1_IRQHandler
+EXTI9_5_IRQHandler
+TIM1_BRK_TIM15_IRQHandler
+TIM1_UP_TIM16_IRQHandler
+TIM1_TRG_COM_TIM17_IRQHandler
+TIM1_CC_IRQHandler
+TIM2_IRQHandler
+TIM3_IRQHandler
+TIM4_IRQHandler
+I2C1_EV_IRQHandler
+I2C1_ER_IRQHandler
+I2C2_EV_IRQHandler
+I2C2_ER_IRQHandler
+SPI1_IRQHandler
+SPI2_IRQHandler
+USART1_IRQHandler
+USART2_IRQHandler
+USART3_IRQHandler
+EXTI15_10_IRQHandler
+RTC_Alarm_IRQHandler
+CEC_IRQHandler
+TIM6_DAC_IRQHandler
+TIM7_IRQHandler
+ B .
+
+ ENDP
+
+ ALIGN
+
+;*******************************************************************************
+; User Stack and Heap initialization
+;*******************************************************************************
+ IF :DEF:__MICROLIB
+
+ EXPORT __initial_sp
+ EXPORT __heap_base
+ EXPORT __heap_limit
+
+ ELSE
+
+ IMPORT __use_two_region_memory
+ EXPORT __user_initial_stackheap
+
+__user_initial_stackheap
+
+ LDR R0, = Heap_Mem
+ LDR R1, =(Stack_Mem + Stack_Size)
+ LDR R2, = (Heap_Mem + Heap_Size)
+ LDR R3, = Stack_Mem
+ BX LR
+
+ ALIGN
+
+ ENDIF
+
+ END
+
+;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f100xe.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f100xe.s
new file mode 100644
index 0000000..1d77f58
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f100xe.s
@@ -0,0 +1,363 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f100xe.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F100xE Devices vector table for MDK-ARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == Reset_Handler
+;* - Set the vector table entries with the exceptions ISR address
+;* - Configure the clock system and also configure the external
+;* SRAM mounted on STM32100E-EVAL board to be used as data
+;* memory (optional, to be enabled by user)
+;* - Branches to __main in the C library (which eventually
+;* calls main()).
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;
+;*******************************************************************************
+
+; Amount of memory (in bytes) allocated for Stack
+; Tailor this value to your application needs
+; Stack Configuration
+; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Stack_Size EQU 0x00000400
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem SPACE Stack_Size
+__initial_sp
+
+
+; Heap Configuration
+; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Heap_Size EQU 0x00000200
+
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem SPACE Heap_Size
+__heap_limit
+
+ PRESERVE8
+ THUMB
+
+
+; Vector Table Mapped to Address 0 at Reset
+ AREA RESET, DATA, READONLY
+ EXPORT __Vectors
+ EXPORT __Vectors_End
+ EXPORT __Vectors_Size
+
+__Vectors DCD __initial_sp ; Top of Stack
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_IRQHandler ; ADC1
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD TIM1_BRK_TIM15_IRQHandler ; TIM1 Break and TIM15
+ DCD TIM1_UP_TIM16_IRQHandler ; TIM1 Update and TIM16
+ DCD TIM1_TRG_COM_TIM17_IRQHandler ; TIM1 Trigger and Commutation and TIM17
+ DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C2 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD CEC_IRQHandler ; HDMI CEC
+ DCD TIM12_IRQHandler ; TIM12
+ DCD TIM13_IRQHandler ; TIM13
+ DCD TIM14_IRQHandler ; TIM14
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD TIM5_IRQHandler ; TIM5
+ DCD SPI3_IRQHandler ; SPI3
+ DCD UART4_IRQHandler ; UART4
+ DCD UART5_IRQHandler ; UART5
+ DCD TIM6_DAC_IRQHandler ; TIM6 and DAC underrun
+ DCD TIM7_IRQHandler ; TIM7
+ DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
+ DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
+ DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
+ DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
+ DCD DMA2_Channel5_IRQHandler ; DMA2 Channel5
+__Vectors_End
+
+__Vectors_Size EQU __Vectors_End - __Vectors
+
+ AREA |.text|, CODE, READONLY
+
+; Reset handler
+Reset_Handler PROC
+ EXPORT Reset_Handler [WEAK]
+ IMPORT __main
+ IMPORT SystemInit
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__main
+ BX R0
+ ENDP
+
+; Dummy Exception Handlers (infinite loops which can be modified)
+
+NMI_Handler PROC
+ EXPORT NMI_Handler [WEAK]
+ B .
+ ENDP
+HardFault_Handler\
+ PROC
+ EXPORT HardFault_Handler [WEAK]
+ B .
+ ENDP
+MemManage_Handler\
+ PROC
+ EXPORT MemManage_Handler [WEAK]
+ B .
+ ENDP
+BusFault_Handler\
+ PROC
+ EXPORT BusFault_Handler [WEAK]
+ B .
+ ENDP
+UsageFault_Handler\
+ PROC
+ EXPORT UsageFault_Handler [WEAK]
+ B .
+ ENDP
+SVC_Handler PROC
+ EXPORT SVC_Handler [WEAK]
+ B .
+ ENDP
+DebugMon_Handler\
+ PROC
+ EXPORT DebugMon_Handler [WEAK]
+ B .
+ ENDP
+PendSV_Handler PROC
+ EXPORT PendSV_Handler [WEAK]
+ B .
+ ENDP
+SysTick_Handler PROC
+ EXPORT SysTick_Handler [WEAK]
+ B .
+ ENDP
+
+Default_Handler PROC
+
+ EXPORT WWDG_IRQHandler [WEAK]
+ EXPORT PVD_IRQHandler [WEAK]
+ EXPORT TAMPER_IRQHandler [WEAK]
+ EXPORT RTC_IRQHandler [WEAK]
+ EXPORT FLASH_IRQHandler [WEAK]
+ EXPORT RCC_IRQHandler [WEAK]
+ EXPORT EXTI0_IRQHandler [WEAK]
+ EXPORT EXTI1_IRQHandler [WEAK]
+ EXPORT EXTI2_IRQHandler [WEAK]
+ EXPORT EXTI3_IRQHandler [WEAK]
+ EXPORT EXTI4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel1_IRQHandler [WEAK]
+ EXPORT DMA1_Channel2_IRQHandler [WEAK]
+ EXPORT DMA1_Channel3_IRQHandler [WEAK]
+ EXPORT DMA1_Channel4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel5_IRQHandler [WEAK]
+ EXPORT DMA1_Channel6_IRQHandler [WEAK]
+ EXPORT DMA1_Channel7_IRQHandler [WEAK]
+ EXPORT ADC1_IRQHandler [WEAK]
+ EXPORT EXTI9_5_IRQHandler [WEAK]
+ EXPORT TIM1_BRK_TIM15_IRQHandler [WEAK]
+ EXPORT TIM1_UP_TIM16_IRQHandler [WEAK]
+ EXPORT TIM1_TRG_COM_TIM17_IRQHandler [WEAK]
+ EXPORT TIM1_CC_IRQHandler [WEAK]
+ EXPORT TIM2_IRQHandler [WEAK]
+ EXPORT TIM3_IRQHandler [WEAK]
+ EXPORT TIM4_IRQHandler [WEAK]
+ EXPORT I2C1_EV_IRQHandler [WEAK]
+ EXPORT I2C1_ER_IRQHandler [WEAK]
+ EXPORT I2C2_EV_IRQHandler [WEAK]
+ EXPORT I2C2_ER_IRQHandler [WEAK]
+ EXPORT SPI1_IRQHandler [WEAK]
+ EXPORT SPI2_IRQHandler [WEAK]
+ EXPORT USART1_IRQHandler [WEAK]
+ EXPORT USART2_IRQHandler [WEAK]
+ EXPORT USART3_IRQHandler [WEAK]
+ EXPORT EXTI15_10_IRQHandler [WEAK]
+ EXPORT RTC_Alarm_IRQHandler [WEAK]
+ EXPORT CEC_IRQHandler [WEAK]
+ EXPORT TIM12_IRQHandler [WEAK]
+ EXPORT TIM13_IRQHandler [WEAK]
+ EXPORT TIM14_IRQHandler [WEAK]
+ EXPORT TIM5_IRQHandler [WEAK]
+ EXPORT SPI3_IRQHandler [WEAK]
+ EXPORT UART4_IRQHandler [WEAK]
+ EXPORT UART5_IRQHandler [WEAK]
+ EXPORT TIM6_DAC_IRQHandler [WEAK]
+ EXPORT TIM7_IRQHandler [WEAK]
+ EXPORT DMA2_Channel1_IRQHandler [WEAK]
+ EXPORT DMA2_Channel2_IRQHandler [WEAK]
+ EXPORT DMA2_Channel3_IRQHandler [WEAK]
+ EXPORT DMA2_Channel4_5_IRQHandler [WEAK]
+ EXPORT DMA2_Channel5_IRQHandler [WEAK]
+
+WWDG_IRQHandler
+PVD_IRQHandler
+TAMPER_IRQHandler
+RTC_IRQHandler
+FLASH_IRQHandler
+RCC_IRQHandler
+EXTI0_IRQHandler
+EXTI1_IRQHandler
+EXTI2_IRQHandler
+EXTI3_IRQHandler
+EXTI4_IRQHandler
+DMA1_Channel1_IRQHandler
+DMA1_Channel2_IRQHandler
+DMA1_Channel3_IRQHandler
+DMA1_Channel4_IRQHandler
+DMA1_Channel5_IRQHandler
+DMA1_Channel6_IRQHandler
+DMA1_Channel7_IRQHandler
+ADC1_IRQHandler
+EXTI9_5_IRQHandler
+TIM1_BRK_TIM15_IRQHandler
+TIM1_UP_TIM16_IRQHandler
+TIM1_TRG_COM_TIM17_IRQHandler
+TIM1_CC_IRQHandler
+TIM2_IRQHandler
+TIM3_IRQHandler
+TIM4_IRQHandler
+I2C1_EV_IRQHandler
+I2C1_ER_IRQHandler
+I2C2_EV_IRQHandler
+I2C2_ER_IRQHandler
+SPI1_IRQHandler
+SPI2_IRQHandler
+USART1_IRQHandler
+USART2_IRQHandler
+USART3_IRQHandler
+EXTI15_10_IRQHandler
+RTC_Alarm_IRQHandler
+CEC_IRQHandler
+TIM12_IRQHandler
+TIM13_IRQHandler
+TIM14_IRQHandler
+TIM5_IRQHandler
+SPI3_IRQHandler
+UART4_IRQHandler
+UART5_IRQHandler
+TIM6_DAC_IRQHandler
+TIM7_IRQHandler
+DMA2_Channel1_IRQHandler
+DMA2_Channel2_IRQHandler
+DMA2_Channel3_IRQHandler
+DMA2_Channel4_5_IRQHandler
+DMA2_Channel5_IRQHandler
+ B .
+
+ ENDP
+
+ ALIGN
+
+;*******************************************************************************
+; User Stack and Heap initialization
+;*******************************************************************************
+ IF :DEF:__MICROLIB
+
+ EXPORT __initial_sp
+ EXPORT __heap_base
+ EXPORT __heap_limit
+
+ ELSE
+
+ IMPORT __use_two_region_memory
+ EXPORT __user_initial_stackheap
+
+__user_initial_stackheap
+
+ LDR R0, = Heap_Mem
+ LDR R1, =(Stack_Mem + Stack_Size)
+ LDR R2, = (Heap_Mem + Heap_Size)
+ LDR R3, = Stack_Mem
+ BX LR
+
+ ALIGN
+
+ ENDIF
+
+ END
+
+;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101x6.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101x6.s
new file mode 100644
index 0000000..ab9813a
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101x6.s
@@ -0,0 +1,295 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f101x6.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F101x6 Devices vector table for MDK-ARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == Reset_Handler
+;* - Set the vector table entries with the exceptions ISR address
+;* - Configure the clock system
+;* - Branches to __main in the C library (which eventually
+;* calls main()).
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;
+;*******************************************************************************
+
+; Amount of memory (in bytes) allocated for Stack
+; Tailor this value to your application needs
+; Stack Configuration
+; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Stack_Size EQU 0x00000400
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem SPACE Stack_Size
+__initial_sp
+
+
+; Heap Configuration
+; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Heap_Size EQU 0x00000200
+
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem SPACE Heap_Size
+__heap_limit
+
+ PRESERVE8
+ THUMB
+
+
+; Vector Table Mapped to Address 0 at Reset
+ AREA RESET, DATA, READONLY
+ EXPORT __Vectors
+ EXPORT __Vectors_End
+ EXPORT __Vectors_Size
+
+__Vectors DCD __initial_sp ; Top of Stack
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_IRQHandler ; ADC1
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD 0 ; Reserved
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SPI1_IRQHandler ; SPI1
+ DCD 0 ; Reserved
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD 0 ; Reserved
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+__Vectors_End
+
+__Vectors_Size EQU __Vectors_End - __Vectors
+
+ AREA |.text|, CODE, READONLY
+
+; Reset handler routine
+Reset_Handler PROC
+ EXPORT Reset_Handler [WEAK]
+ IMPORT __main
+ IMPORT SystemInit
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__main
+ BX R0
+ ENDP
+
+; Dummy Exception Handlers (infinite loops which can be modified)
+
+NMI_Handler PROC
+ EXPORT NMI_Handler [WEAK]
+ B .
+ ENDP
+HardFault_Handler\
+ PROC
+ EXPORT HardFault_Handler [WEAK]
+ B .
+ ENDP
+MemManage_Handler\
+ PROC
+ EXPORT MemManage_Handler [WEAK]
+ B .
+ ENDP
+BusFault_Handler\
+ PROC
+ EXPORT BusFault_Handler [WEAK]
+ B .
+ ENDP
+UsageFault_Handler\
+ PROC
+ EXPORT UsageFault_Handler [WEAK]
+ B .
+ ENDP
+SVC_Handler PROC
+ EXPORT SVC_Handler [WEAK]
+ B .
+ ENDP
+DebugMon_Handler\
+ PROC
+ EXPORT DebugMon_Handler [WEAK]
+ B .
+ ENDP
+PendSV_Handler PROC
+ EXPORT PendSV_Handler [WEAK]
+ B .
+ ENDP
+SysTick_Handler PROC
+ EXPORT SysTick_Handler [WEAK]
+ B .
+ ENDP
+
+Default_Handler PROC
+
+ EXPORT WWDG_IRQHandler [WEAK]
+ EXPORT PVD_IRQHandler [WEAK]
+ EXPORT TAMPER_IRQHandler [WEAK]
+ EXPORT RTC_IRQHandler [WEAK]
+ EXPORT FLASH_IRQHandler [WEAK]
+ EXPORT RCC_IRQHandler [WEAK]
+ EXPORT EXTI0_IRQHandler [WEAK]
+ EXPORT EXTI1_IRQHandler [WEAK]
+ EXPORT EXTI2_IRQHandler [WEAK]
+ EXPORT EXTI3_IRQHandler [WEAK]
+ EXPORT EXTI4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel1_IRQHandler [WEAK]
+ EXPORT DMA1_Channel2_IRQHandler [WEAK]
+ EXPORT DMA1_Channel3_IRQHandler [WEAK]
+ EXPORT DMA1_Channel4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel5_IRQHandler [WEAK]
+ EXPORT DMA1_Channel6_IRQHandler [WEAK]
+ EXPORT DMA1_Channel7_IRQHandler [WEAK]
+ EXPORT ADC1_IRQHandler [WEAK]
+ EXPORT EXTI9_5_IRQHandler [WEAK]
+ EXPORT TIM2_IRQHandler [WEAK]
+ EXPORT TIM3_IRQHandler [WEAK]
+ EXPORT I2C1_EV_IRQHandler [WEAK]
+ EXPORT I2C1_ER_IRQHandler [WEAK]
+ EXPORT SPI1_IRQHandler [WEAK]
+ EXPORT USART1_IRQHandler [WEAK]
+ EXPORT USART2_IRQHandler [WEAK]
+ EXPORT EXTI15_10_IRQHandler [WEAK]
+ EXPORT RTC_Alarm_IRQHandler [WEAK]
+
+WWDG_IRQHandler
+PVD_IRQHandler
+TAMPER_IRQHandler
+RTC_IRQHandler
+FLASH_IRQHandler
+RCC_IRQHandler
+EXTI0_IRQHandler
+EXTI1_IRQHandler
+EXTI2_IRQHandler
+EXTI3_IRQHandler
+EXTI4_IRQHandler
+DMA1_Channel1_IRQHandler
+DMA1_Channel2_IRQHandler
+DMA1_Channel3_IRQHandler
+DMA1_Channel4_IRQHandler
+DMA1_Channel5_IRQHandler
+DMA1_Channel6_IRQHandler
+DMA1_Channel7_IRQHandler
+ADC1_IRQHandler
+EXTI9_5_IRQHandler
+TIM2_IRQHandler
+TIM3_IRQHandler
+I2C1_EV_IRQHandler
+I2C1_ER_IRQHandler
+SPI1_IRQHandler
+USART1_IRQHandler
+USART2_IRQHandler
+EXTI15_10_IRQHandler
+RTC_Alarm_IRQHandler
+
+ B .
+
+ ENDP
+
+ ALIGN
+
+;*******************************************************************************
+; User Stack and Heap initialization
+;*******************************************************************************
+ IF :DEF:__MICROLIB
+
+ EXPORT __initial_sp
+ EXPORT __heap_base
+ EXPORT __heap_limit
+
+ ELSE
+
+ IMPORT __use_two_region_memory
+ EXPORT __user_initial_stackheap
+
+__user_initial_stackheap
+
+ LDR R0, = Heap_Mem
+ LDR R1, =(Stack_Mem + Stack_Size)
+ LDR R2, = (Heap_Mem + Heap_Size)
+ LDR R3, = Stack_Mem
+ BX LR
+
+ ALIGN
+
+ ENDIF
+
+ END
+
+;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101xb.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101xb.s
new file mode 100644
index 0000000..74aed8d
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101xb.s
@@ -0,0 +1,305 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f101xb.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F101xB Devices vector table for MDK-ARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == Reset_Handler
+;* - Set the vector table entries with the exceptions ISR address
+;* - Configure the clock system
+;* - Branches to __main in the C library (which eventually
+;* calls main()).
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;
+;*******************************************************************************
+
+; Amount of memory (in bytes) allocated for Stack
+; Tailor this value to your application needs
+; Stack Configuration
+; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Stack_Size EQU 0x00000400
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem SPACE Stack_Size
+__initial_sp
+
+
+; Heap Configuration
+; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Heap_Size EQU 0x00000200
+
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem SPACE Heap_Size
+__heap_limit
+
+ PRESERVE8
+ THUMB
+
+
+; Vector Table Mapped to Address 0 at Reset
+ AREA RESET, DATA, READONLY
+ EXPORT __Vectors
+ EXPORT __Vectors_End
+ EXPORT __Vectors_Size
+
+__Vectors DCD __initial_sp ; Top of Stack
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_IRQHandler ; ADC1
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C2 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+__Vectors_End
+
+__Vectors_Size EQU __Vectors_End - __Vectors
+
+ AREA |.text|, CODE, READONLY
+
+; Reset handler
+Reset_Handler PROC
+ EXPORT Reset_Handler [WEAK]
+ IMPORT __main
+ IMPORT SystemInit
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__main
+ BX R0
+ ENDP
+
+; Dummy Exception Handlers (infinite loops which can be modified)
+
+NMI_Handler PROC
+ EXPORT NMI_Handler [WEAK]
+ B .
+ ENDP
+HardFault_Handler\
+ PROC
+ EXPORT HardFault_Handler [WEAK]
+ B .
+ ENDP
+MemManage_Handler\
+ PROC
+ EXPORT MemManage_Handler [WEAK]
+ B .
+ ENDP
+BusFault_Handler\
+ PROC
+ EXPORT BusFault_Handler [WEAK]
+ B .
+ ENDP
+UsageFault_Handler\
+ PROC
+ EXPORT UsageFault_Handler [WEAK]
+ B .
+ ENDP
+SVC_Handler PROC
+ EXPORT SVC_Handler [WEAK]
+ B .
+ ENDP
+DebugMon_Handler\
+ PROC
+ EXPORT DebugMon_Handler [WEAK]
+ B .
+ ENDP
+PendSV_Handler PROC
+ EXPORT PendSV_Handler [WEAK]
+ B .
+ ENDP
+SysTick_Handler PROC
+ EXPORT SysTick_Handler [WEAK]
+ B .
+ ENDP
+
+Default_Handler PROC
+
+ EXPORT WWDG_IRQHandler [WEAK]
+ EXPORT PVD_IRQHandler [WEAK]
+ EXPORT TAMPER_IRQHandler [WEAK]
+ EXPORT RTC_IRQHandler [WEAK]
+ EXPORT FLASH_IRQHandler [WEAK]
+ EXPORT RCC_IRQHandler [WEAK]
+ EXPORT EXTI0_IRQHandler [WEAK]
+ EXPORT EXTI1_IRQHandler [WEAK]
+ EXPORT EXTI2_IRQHandler [WEAK]
+ EXPORT EXTI3_IRQHandler [WEAK]
+ EXPORT EXTI4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel1_IRQHandler [WEAK]
+ EXPORT DMA1_Channel2_IRQHandler [WEAK]
+ EXPORT DMA1_Channel3_IRQHandler [WEAK]
+ EXPORT DMA1_Channel4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel5_IRQHandler [WEAK]
+ EXPORT DMA1_Channel6_IRQHandler [WEAK]
+ EXPORT DMA1_Channel7_IRQHandler [WEAK]
+ EXPORT ADC1_IRQHandler [WEAK]
+ EXPORT EXTI9_5_IRQHandler [WEAK]
+ EXPORT TIM2_IRQHandler [WEAK]
+ EXPORT TIM3_IRQHandler [WEAK]
+ EXPORT TIM4_IRQHandler [WEAK]
+ EXPORT I2C1_EV_IRQHandler [WEAK]
+ EXPORT I2C1_ER_IRQHandler [WEAK]
+ EXPORT I2C2_EV_IRQHandler [WEAK]
+ EXPORT I2C2_ER_IRQHandler [WEAK]
+ EXPORT SPI1_IRQHandler [WEAK]
+ EXPORT SPI2_IRQHandler [WEAK]
+ EXPORT USART1_IRQHandler [WEAK]
+ EXPORT USART2_IRQHandler [WEAK]
+ EXPORT USART3_IRQHandler [WEAK]
+ EXPORT EXTI15_10_IRQHandler [WEAK]
+ EXPORT RTC_Alarm_IRQHandler [WEAK]
+
+WWDG_IRQHandler
+PVD_IRQHandler
+TAMPER_IRQHandler
+RTC_IRQHandler
+FLASH_IRQHandler
+RCC_IRQHandler
+EXTI0_IRQHandler
+EXTI1_IRQHandler
+EXTI2_IRQHandler
+EXTI3_IRQHandler
+EXTI4_IRQHandler
+DMA1_Channel1_IRQHandler
+DMA1_Channel2_IRQHandler
+DMA1_Channel3_IRQHandler
+DMA1_Channel4_IRQHandler
+DMA1_Channel5_IRQHandler
+DMA1_Channel6_IRQHandler
+DMA1_Channel7_IRQHandler
+ADC1_IRQHandler
+EXTI9_5_IRQHandler
+TIM2_IRQHandler
+TIM3_IRQHandler
+TIM4_IRQHandler
+I2C1_EV_IRQHandler
+I2C1_ER_IRQHandler
+I2C2_EV_IRQHandler
+I2C2_ER_IRQHandler
+SPI1_IRQHandler
+SPI2_IRQHandler
+USART1_IRQHandler
+USART2_IRQHandler
+USART3_IRQHandler
+EXTI15_10_IRQHandler
+RTC_Alarm_IRQHandler
+
+ B .
+
+ ENDP
+
+ ALIGN
+
+;*******************************************************************************
+; User Stack and Heap initialization
+;*******************************************************************************
+ IF :DEF:__MICROLIB
+
+ EXPORT __initial_sp
+ EXPORT __heap_base
+ EXPORT __heap_limit
+
+ ELSE
+
+ IMPORT __use_two_region_memory
+ EXPORT __user_initial_stackheap
+
+__user_initial_stackheap
+
+ LDR R0, = Heap_Mem
+ LDR R1, =(Stack_Mem + Stack_Size)
+ LDR R2, = (Heap_Mem + Heap_Size)
+ LDR R3, = Stack_Mem
+ BX LR
+
+ ALIGN
+
+ ENDIF
+
+ END
+
+;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101xe.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101xe.s
new file mode 100644
index 0000000..865dcd1
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101xe.s
@@ -0,0 +1,343 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f101xe.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F101xE Devices vector table for MDK-ARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == Reset_Handler
+;* - Set the vector table entries with the exceptions ISR address
+;* - Configure the clock system
+;* - Branches to __main in the C library (which eventually
+;* calls main()).
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;
+;*******************************************************************************
+
+; Amount of memory (in bytes) allocated for Stack
+; Tailor this value to your application needs
+; Stack Configuration
+; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Stack_Size EQU 0x00000400
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem SPACE Stack_Size
+__initial_sp
+
+; Heap Configuration
+; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Heap_Size EQU 0x00000200
+
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem SPACE Heap_Size
+__heap_limit
+
+ PRESERVE8
+ THUMB
+
+
+; Vector Table Mapped to Address 0 at Reset
+ AREA RESET, DATA, READONLY
+ EXPORT __Vectors
+ EXPORT __Vectors_End
+ EXPORT __Vectors_Size
+
+__Vectors DCD __initial_sp ; Top of Stack
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_IRQHandler ; ADC1
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C2 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD FSMC_IRQHandler ; FSMC
+ DCD 0 ; Reserved
+ DCD TIM5_IRQHandler ; TIM5
+ DCD SPI3_IRQHandler ; SPI3
+ DCD UART4_IRQHandler ; UART4
+ DCD UART5_IRQHandler ; UART5
+ DCD TIM6_IRQHandler ; TIM6
+ DCD TIM7_IRQHandler ; TIM7
+ DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
+ DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
+ DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
+ DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
+__Vectors_End
+
+__Vectors_Size EQU __Vectors_End - __Vectors
+
+ AREA |.text|, CODE, READONLY
+
+; Reset handler
+Reset_Handler PROC
+ EXPORT Reset_Handler [WEAK]
+ IMPORT __main
+ IMPORT SystemInit
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__main
+ BX R0
+ ENDP
+
+; Dummy Exception Handlers (infinite loops which can be modified)
+
+NMI_Handler PROC
+ EXPORT NMI_Handler [WEAK]
+ B .
+ ENDP
+HardFault_Handler\
+ PROC
+ EXPORT HardFault_Handler [WEAK]
+ B .
+ ENDP
+MemManage_Handler\
+ PROC
+ EXPORT MemManage_Handler [WEAK]
+ B .
+ ENDP
+BusFault_Handler\
+ PROC
+ EXPORT BusFault_Handler [WEAK]
+ B .
+ ENDP
+UsageFault_Handler\
+ PROC
+ EXPORT UsageFault_Handler [WEAK]
+ B .
+ ENDP
+SVC_Handler PROC
+ EXPORT SVC_Handler [WEAK]
+ B .
+ ENDP
+DebugMon_Handler\
+ PROC
+ EXPORT DebugMon_Handler [WEAK]
+ B .
+ ENDP
+PendSV_Handler PROC
+ EXPORT PendSV_Handler [WEAK]
+ B .
+ ENDP
+SysTick_Handler PROC
+ EXPORT SysTick_Handler [WEAK]
+ B .
+ ENDP
+
+Default_Handler PROC
+
+ EXPORT WWDG_IRQHandler [WEAK]
+ EXPORT PVD_IRQHandler [WEAK]
+ EXPORT TAMPER_IRQHandler [WEAK]
+ EXPORT RTC_IRQHandler [WEAK]
+ EXPORT FLASH_IRQHandler [WEAK]
+ EXPORT RCC_IRQHandler [WEAK]
+ EXPORT EXTI0_IRQHandler [WEAK]
+ EXPORT EXTI1_IRQHandler [WEAK]
+ EXPORT EXTI2_IRQHandler [WEAK]
+ EXPORT EXTI3_IRQHandler [WEAK]
+ EXPORT EXTI4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel1_IRQHandler [WEAK]
+ EXPORT DMA1_Channel2_IRQHandler [WEAK]
+ EXPORT DMA1_Channel3_IRQHandler [WEAK]
+ EXPORT DMA1_Channel4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel5_IRQHandler [WEAK]
+ EXPORT DMA1_Channel6_IRQHandler [WEAK]
+ EXPORT DMA1_Channel7_IRQHandler [WEAK]
+ EXPORT ADC1_IRQHandler [WEAK]
+ EXPORT EXTI9_5_IRQHandler [WEAK]
+ EXPORT TIM2_IRQHandler [WEAK]
+ EXPORT TIM3_IRQHandler [WEAK]
+ EXPORT TIM4_IRQHandler [WEAK]
+ EXPORT I2C1_EV_IRQHandler [WEAK]
+ EXPORT I2C1_ER_IRQHandler [WEAK]
+ EXPORT I2C2_EV_IRQHandler [WEAK]
+ EXPORT I2C2_ER_IRQHandler [WEAK]
+ EXPORT SPI1_IRQHandler [WEAK]
+ EXPORT SPI2_IRQHandler [WEAK]
+ EXPORT USART1_IRQHandler [WEAK]
+ EXPORT USART2_IRQHandler [WEAK]
+ EXPORT USART3_IRQHandler [WEAK]
+ EXPORT EXTI15_10_IRQHandler [WEAK]
+ EXPORT RTC_Alarm_IRQHandler [WEAK]
+ EXPORT FSMC_IRQHandler [WEAK]
+ EXPORT TIM5_IRQHandler [WEAK]
+ EXPORT SPI3_IRQHandler [WEAK]
+ EXPORT UART4_IRQHandler [WEAK]
+ EXPORT UART5_IRQHandler [WEAK]
+ EXPORT TIM6_IRQHandler [WEAK]
+ EXPORT TIM7_IRQHandler [WEAK]
+ EXPORT DMA2_Channel1_IRQHandler [WEAK]
+ EXPORT DMA2_Channel2_IRQHandler [WEAK]
+ EXPORT DMA2_Channel3_IRQHandler [WEAK]
+ EXPORT DMA2_Channel4_5_IRQHandler [WEAK]
+
+WWDG_IRQHandler
+PVD_IRQHandler
+TAMPER_IRQHandler
+RTC_IRQHandler
+FLASH_IRQHandler
+RCC_IRQHandler
+EXTI0_IRQHandler
+EXTI1_IRQHandler
+EXTI2_IRQHandler
+EXTI3_IRQHandler
+EXTI4_IRQHandler
+DMA1_Channel1_IRQHandler
+DMA1_Channel2_IRQHandler
+DMA1_Channel3_IRQHandler
+DMA1_Channel4_IRQHandler
+DMA1_Channel5_IRQHandler
+DMA1_Channel6_IRQHandler
+DMA1_Channel7_IRQHandler
+ADC1_IRQHandler
+EXTI9_5_IRQHandler
+TIM2_IRQHandler
+TIM3_IRQHandler
+TIM4_IRQHandler
+I2C1_EV_IRQHandler
+I2C1_ER_IRQHandler
+I2C2_EV_IRQHandler
+I2C2_ER_IRQHandler
+SPI1_IRQHandler
+SPI2_IRQHandler
+USART1_IRQHandler
+USART2_IRQHandler
+USART3_IRQHandler
+EXTI15_10_IRQHandler
+RTC_Alarm_IRQHandler
+FSMC_IRQHandler
+TIM5_IRQHandler
+SPI3_IRQHandler
+UART4_IRQHandler
+UART5_IRQHandler
+TIM6_IRQHandler
+TIM7_IRQHandler
+DMA2_Channel1_IRQHandler
+DMA2_Channel2_IRQHandler
+DMA2_Channel3_IRQHandler
+DMA2_Channel4_5_IRQHandler
+ B .
+
+ ENDP
+
+ ALIGN
+
+;*******************************************************************************
+; User Stack and Heap initialization
+;*******************************************************************************
+ IF :DEF:__MICROLIB
+
+ EXPORT __initial_sp
+ EXPORT __heap_base
+ EXPORT __heap_limit
+
+ ELSE
+
+ IMPORT __use_two_region_memory
+ EXPORT __user_initial_stackheap
+
+__user_initial_stackheap
+
+ LDR R0, = Heap_Mem
+ LDR R1, =(Stack_Mem + Stack_Size)
+ LDR R2, = (Heap_Mem + Heap_Size)
+ LDR R3, = Stack_Mem
+ BX LR
+
+ ALIGN
+
+ ENDIF
+
+ END
+
+;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101xg.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101xg.s
new file mode 100644
index 0000000..15276ac
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f101xg.s
@@ -0,0 +1,355 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f101xg.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F101xG Devices vector table for MDK-ARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == Reset_Handler
+;* - Set the vector table entries with the exceptions ISR address
+;* - Configure the clock system
+;* - Branches to __main in the C library (which eventually
+;* calls main()).
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;
+;*******************************************************************************
+
+; Amount of memory (in bytes) allocated for Stack
+; Tailor this value to your application needs
+; Stack Configuration
+; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Stack_Size EQU 0x00000400
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem SPACE Stack_Size
+__initial_sp
+
+; Heap Configuration
+; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Heap_Size EQU 0x00000200
+
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem SPACE Heap_Size
+__heap_limit
+
+ PRESERVE8
+ THUMB
+
+
+; Vector Table Mapped to Address 0 at Reset
+ AREA RESET, DATA, READONLY
+ EXPORT __Vectors
+ EXPORT __Vectors_End
+ EXPORT __Vectors_Size
+
+__Vectors DCD __initial_sp ; Top of Stack
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_2_IRQHandler ; ADC1_2
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD TIM9_IRQHandler ; TIM9
+ DCD TIM10_IRQHandler ; TIM10
+ DCD TIM11_IRQHandler ; TIM11
+ DCD 0 ; Reserved
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C2 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD 0 ; Reserved
+ DCD TIM12_IRQHandler ; TIM12
+ DCD TIM13_IRQHandler ; TIM13
+ DCD TIM14_IRQHandler ; TIM14
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD FSMC_IRQHandler ; FSMC
+ DCD 0 ; Reserved
+ DCD TIM5_IRQHandler ; TIM5
+ DCD SPI3_IRQHandler ; SPI3
+ DCD UART4_IRQHandler ; UART4
+ DCD UART5_IRQHandler ; UART5
+ DCD TIM6_IRQHandler ; TIM6
+ DCD TIM7_IRQHandler ; TIM7
+ DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
+ DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
+ DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
+ DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
+__Vectors_End
+
+__Vectors_Size EQU __Vectors_End - __Vectors
+
+ AREA |.text|, CODE, READONLY
+
+; Reset handler
+Reset_Handler PROC
+ EXPORT Reset_Handler [WEAK]
+ IMPORT __main
+ IMPORT SystemInit
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__main
+ BX R0
+ ENDP
+
+; Dummy Exception Handlers (infinite loops which can be modified)
+
+NMI_Handler PROC
+ EXPORT NMI_Handler [WEAK]
+ B .
+ ENDP
+HardFault_Handler\
+ PROC
+ EXPORT HardFault_Handler [WEAK]
+ B .
+ ENDP
+MemManage_Handler\
+ PROC
+ EXPORT MemManage_Handler [WEAK]
+ B .
+ ENDP
+BusFault_Handler\
+ PROC
+ EXPORT BusFault_Handler [WEAK]
+ B .
+ ENDP
+UsageFault_Handler\
+ PROC
+ EXPORT UsageFault_Handler [WEAK]
+ B .
+ ENDP
+SVC_Handler PROC
+ EXPORT SVC_Handler [WEAK]
+ B .
+ ENDP
+DebugMon_Handler\
+ PROC
+ EXPORT DebugMon_Handler [WEAK]
+ B .
+ ENDP
+PendSV_Handler PROC
+ EXPORT PendSV_Handler [WEAK]
+ B .
+ ENDP
+SysTick_Handler PROC
+ EXPORT SysTick_Handler [WEAK]
+ B .
+ ENDP
+
+Default_Handler PROC
+
+ EXPORT WWDG_IRQHandler [WEAK]
+ EXPORT PVD_IRQHandler [WEAK]
+ EXPORT TAMPER_IRQHandler [WEAK]
+ EXPORT RTC_IRQHandler [WEAK]
+ EXPORT FLASH_IRQHandler [WEAK]
+ EXPORT RCC_IRQHandler [WEAK]
+ EXPORT EXTI0_IRQHandler [WEAK]
+ EXPORT EXTI1_IRQHandler [WEAK]
+ EXPORT EXTI2_IRQHandler [WEAK]
+ EXPORT EXTI3_IRQHandler [WEAK]
+ EXPORT EXTI4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel1_IRQHandler [WEAK]
+ EXPORT DMA1_Channel2_IRQHandler [WEAK]
+ EXPORT DMA1_Channel3_IRQHandler [WEAK]
+ EXPORT DMA1_Channel4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel5_IRQHandler [WEAK]
+ EXPORT DMA1_Channel6_IRQHandler [WEAK]
+ EXPORT DMA1_Channel7_IRQHandler [WEAK]
+ EXPORT ADC1_2_IRQHandler [WEAK]
+ EXPORT EXTI9_5_IRQHandler [WEAK]
+ EXPORT TIM9_IRQHandler [WEAK]
+ EXPORT TIM10_IRQHandler [WEAK]
+ EXPORT TIM11_IRQHandler [WEAK]
+ EXPORT TIM2_IRQHandler [WEAK]
+ EXPORT TIM3_IRQHandler [WEAK]
+ EXPORT TIM4_IRQHandler [WEAK]
+ EXPORT I2C1_EV_IRQHandler [WEAK]
+ EXPORT I2C1_ER_IRQHandler [WEAK]
+ EXPORT I2C2_EV_IRQHandler [WEAK]
+ EXPORT I2C2_ER_IRQHandler [WEAK]
+ EXPORT SPI1_IRQHandler [WEAK]
+ EXPORT SPI2_IRQHandler [WEAK]
+ EXPORT USART1_IRQHandler [WEAK]
+ EXPORT USART2_IRQHandler [WEAK]
+ EXPORT USART3_IRQHandler [WEAK]
+ EXPORT EXTI15_10_IRQHandler [WEAK]
+ EXPORT RTC_Alarm_IRQHandler [WEAK]
+ EXPORT TIM12_IRQHandler [WEAK]
+ EXPORT TIM13_IRQHandler [WEAK]
+ EXPORT TIM14_IRQHandler [WEAK]
+ EXPORT FSMC_IRQHandler [WEAK]
+ EXPORT TIM5_IRQHandler [WEAK]
+ EXPORT SPI3_IRQHandler [WEAK]
+ EXPORT UART4_IRQHandler [WEAK]
+ EXPORT UART5_IRQHandler [WEAK]
+ EXPORT TIM6_IRQHandler [WEAK]
+ EXPORT TIM7_IRQHandler [WEAK]
+ EXPORT DMA2_Channel1_IRQHandler [WEAK]
+ EXPORT DMA2_Channel2_IRQHandler [WEAK]
+ EXPORT DMA2_Channel3_IRQHandler [WEAK]
+ EXPORT DMA2_Channel4_5_IRQHandler [WEAK]
+
+WWDG_IRQHandler
+PVD_IRQHandler
+TAMPER_IRQHandler
+RTC_IRQHandler
+FLASH_IRQHandler
+RCC_IRQHandler
+EXTI0_IRQHandler
+EXTI1_IRQHandler
+EXTI2_IRQHandler
+EXTI3_IRQHandler
+EXTI4_IRQHandler
+DMA1_Channel1_IRQHandler
+DMA1_Channel2_IRQHandler
+DMA1_Channel3_IRQHandler
+DMA1_Channel4_IRQHandler
+DMA1_Channel5_IRQHandler
+DMA1_Channel6_IRQHandler
+DMA1_Channel7_IRQHandler
+ADC1_2_IRQHandler
+EXTI9_5_IRQHandler
+TIM9_IRQHandler
+TIM10_IRQHandler
+TIM11_IRQHandler
+TIM2_IRQHandler
+TIM3_IRQHandler
+TIM4_IRQHandler
+I2C1_EV_IRQHandler
+I2C1_ER_IRQHandler
+I2C2_EV_IRQHandler
+I2C2_ER_IRQHandler
+SPI1_IRQHandler
+SPI2_IRQHandler
+USART1_IRQHandler
+USART2_IRQHandler
+USART3_IRQHandler
+EXTI15_10_IRQHandler
+RTC_Alarm_IRQHandler
+TIM12_IRQHandler
+TIM13_IRQHandler
+TIM14_IRQHandler
+FSMC_IRQHandler
+TIM5_IRQHandler
+SPI3_IRQHandler
+UART4_IRQHandler
+UART5_IRQHandler
+TIM6_IRQHandler
+TIM7_IRQHandler
+DMA2_Channel1_IRQHandler
+DMA2_Channel2_IRQHandler
+DMA2_Channel3_IRQHandler
+DMA2_Channel4_5_IRQHandler
+ B .
+
+ ENDP
+
+ ALIGN
+
+;*******************************************************************************
+; User Stack and Heap initialization
+;*******************************************************************************
+ IF :DEF:__MICROLIB
+
+ EXPORT __initial_sp
+ EXPORT __heap_base
+ EXPORT __heap_limit
+
+ ELSE
+
+ IMPORT __use_two_region_memory
+ EXPORT __user_initial_stackheap
+
+__user_initial_stackheap
+
+ LDR R0, = Heap_Mem
+ LDR R1, =(Stack_Mem + Stack_Size)
+ LDR R2, = (Heap_Mem + Heap_Size)
+ LDR R3, = Stack_Mem
+ BX LR
+
+ ALIGN
+
+ ENDIF
+
+ END
+
+;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f102x6.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f102x6.s
new file mode 100644
index 0000000..f6e46bc
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f102x6.s
@@ -0,0 +1,302 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f102x6.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F102x6 Devices vector table for MDK-ARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == Reset_Handler
+;* - Set the vector table entries with the exceptions ISR address
+;* - Configure the clock system
+;* - Branches to __main in the C library (which eventually
+;* calls main()).
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;
+;*******************************************************************************
+
+; Amount of memory (in bytes) allocated for Stack
+; Tailor this value to your application needs
+; Stack Configuration
+; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Stack_Size EQU 0x00000400
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem SPACE Stack_Size
+__initial_sp
+
+
+; Heap Configuration
+; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Heap_Size EQU 0x00000200
+
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem SPACE Heap_Size
+__heap_limit
+
+ PRESERVE8
+ THUMB
+
+
+; Vector Table Mapped to Address 0 at Reset
+ AREA RESET, DATA, READONLY
+ EXPORT __Vectors
+ EXPORT __Vectors_End
+ EXPORT __Vectors_Size
+
+__Vectors DCD __initial_sp ; Top of Stack
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_IRQHandler ; ADC1
+ DCD USB_HP_IRQHandler ; USB High Priority
+ DCD USB_LP_IRQHandler ; USB Low Priority
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD 0 ; Reserved
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SPI1_IRQHandler ; SPI1
+ DCD 0 ; Reserved
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD 0 ; Reserved
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
+__Vectors_End
+
+__Vectors_Size EQU __Vectors_End - __Vectors
+
+ AREA |.text|, CODE, READONLY
+
+; Reset handler routine
+Reset_Handler PROC
+ EXPORT Reset_Handler [WEAK]
+ IMPORT __main
+ IMPORT SystemInit
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__main
+ BX R0
+ ENDP
+
+; Dummy Exception Handlers (infinite loops which can be modified)
+
+NMI_Handler PROC
+ EXPORT NMI_Handler [WEAK]
+ B .
+ ENDP
+HardFault_Handler\
+ PROC
+ EXPORT HardFault_Handler [WEAK]
+ B .
+ ENDP
+MemManage_Handler\
+ PROC
+ EXPORT MemManage_Handler [WEAK]
+ B .
+ ENDP
+BusFault_Handler\
+ PROC
+ EXPORT BusFault_Handler [WEAK]
+ B .
+ ENDP
+UsageFault_Handler\
+ PROC
+ EXPORT UsageFault_Handler [WEAK]
+ B .
+ ENDP
+SVC_Handler PROC
+ EXPORT SVC_Handler [WEAK]
+ B .
+ ENDP
+DebugMon_Handler\
+ PROC
+ EXPORT DebugMon_Handler [WEAK]
+ B .
+ ENDP
+PendSV_Handler PROC
+ EXPORT PendSV_Handler [WEAK]
+ B .
+ ENDP
+SysTick_Handler PROC
+ EXPORT SysTick_Handler [WEAK]
+ B .
+ ENDP
+
+Default_Handler PROC
+
+ EXPORT WWDG_IRQHandler [WEAK]
+ EXPORT PVD_IRQHandler [WEAK]
+ EXPORT TAMPER_IRQHandler [WEAK]
+ EXPORT RTC_IRQHandler [WEAK]
+ EXPORT FLASH_IRQHandler [WEAK]
+ EXPORT RCC_IRQHandler [WEAK]
+ EXPORT EXTI0_IRQHandler [WEAK]
+ EXPORT EXTI1_IRQHandler [WEAK]
+ EXPORT EXTI2_IRQHandler [WEAK]
+ EXPORT EXTI3_IRQHandler [WEAK]
+ EXPORT EXTI4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel1_IRQHandler [WEAK]
+ EXPORT DMA1_Channel2_IRQHandler [WEAK]
+ EXPORT DMA1_Channel3_IRQHandler [WEAK]
+ EXPORT DMA1_Channel4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel5_IRQHandler [WEAK]
+ EXPORT DMA1_Channel6_IRQHandler [WEAK]
+ EXPORT DMA1_Channel7_IRQHandler [WEAK]
+ EXPORT ADC1_IRQHandler [WEAK]
+ EXPORT USB_HP_IRQHandler [WEAK]
+ EXPORT USB_LP_IRQHandler [WEAK]
+ EXPORT EXTI9_5_IRQHandler [WEAK]
+ EXPORT TIM2_IRQHandler [WEAK]
+ EXPORT TIM3_IRQHandler [WEAK]
+ EXPORT I2C1_EV_IRQHandler [WEAK]
+ EXPORT I2C1_ER_IRQHandler [WEAK]
+ EXPORT SPI1_IRQHandler [WEAK]
+ EXPORT USART1_IRQHandler [WEAK]
+ EXPORT USART2_IRQHandler [WEAK]
+ EXPORT EXTI15_10_IRQHandler [WEAK]
+ EXPORT RTC_Alarm_IRQHandler [WEAK]
+ EXPORT USBWakeUp_IRQHandler [WEAK]
+
+WWDG_IRQHandler
+PVD_IRQHandler
+TAMPER_IRQHandler
+RTC_IRQHandler
+FLASH_IRQHandler
+RCC_IRQHandler
+EXTI0_IRQHandler
+EXTI1_IRQHandler
+EXTI2_IRQHandler
+EXTI3_IRQHandler
+EXTI4_IRQHandler
+DMA1_Channel1_IRQHandler
+DMA1_Channel2_IRQHandler
+DMA1_Channel3_IRQHandler
+DMA1_Channel4_IRQHandler
+DMA1_Channel5_IRQHandler
+DMA1_Channel6_IRQHandler
+DMA1_Channel7_IRQHandler
+ADC1_IRQHandler
+USB_HP_IRQHandler
+USB_LP_IRQHandler
+EXTI9_5_IRQHandler
+TIM2_IRQHandler
+TIM3_IRQHandler
+I2C1_EV_IRQHandler
+I2C1_ER_IRQHandler
+SPI1_IRQHandler
+USART1_IRQHandler
+USART2_IRQHandler
+EXTI15_10_IRQHandler
+RTC_Alarm_IRQHandler
+USBWakeUp_IRQHandler
+
+ B .
+
+ ENDP
+
+ ALIGN
+
+;*******************************************************************************
+; User Stack and Heap initialization
+;*******************************************************************************
+ IF :DEF:__MICROLIB
+
+ EXPORT __initial_sp
+ EXPORT __heap_base
+ EXPORT __heap_limit
+
+ ELSE
+
+ IMPORT __use_two_region_memory
+ EXPORT __user_initial_stackheap
+
+__user_initial_stackheap
+
+ LDR R0, = Heap_Mem
+ LDR R1, =(Stack_Mem + Stack_Size)
+ LDR R2, = (Heap_Mem + Heap_Size)
+ LDR R3, = Stack_Mem
+ BX LR
+
+ ALIGN
+
+ ENDIF
+
+ END
+
+;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f102xb.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f102xb.s
new file mode 100644
index 0000000..b8f2930
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f102xb.s
@@ -0,0 +1,312 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f102xb.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F102xB Devices vector table for MDK-ARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == Reset_Handler
+;* - Set the vector table entries with the exceptions ISR address
+;* - Configure the clock system
+;* - Branches to __main in the C library (which eventually
+;* calls main()).
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;
+;*******************************************************************************
+
+; Amount of memory (in bytes) allocated for Stack
+; Tailor this value to your application needs
+; Stack Configuration
+; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Stack_Size EQU 0x00000400
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem SPACE Stack_Size
+__initial_sp
+
+
+; Heap Configuration
+; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Heap_Size EQU 0x00000200
+
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem SPACE Heap_Size
+__heap_limit
+
+ PRESERVE8
+ THUMB
+
+
+; Vector Table Mapped to Address 0 at Reset
+ AREA RESET, DATA, READONLY
+ EXPORT __Vectors
+ EXPORT __Vectors_End
+ EXPORT __Vectors_Size
+
+__Vectors DCD __initial_sp ; Top of Stack
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_IRQHandler ; ADC1
+ DCD USB_HP_IRQHandler ; USB High Priority
+ DCD USB_LP_IRQHandler ; USB Low Priority
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C2 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
+__Vectors_End
+
+__Vectors_Size EQU __Vectors_End - __Vectors
+
+ AREA |.text|, CODE, READONLY
+
+; Reset handler
+Reset_Handler PROC
+ EXPORT Reset_Handler [WEAK]
+ IMPORT __main
+ IMPORT SystemInit
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__main
+ BX R0
+ ENDP
+
+; Dummy Exception Handlers (infinite loops which can be modified)
+
+NMI_Handler PROC
+ EXPORT NMI_Handler [WEAK]
+ B .
+ ENDP
+HardFault_Handler\
+ PROC
+ EXPORT HardFault_Handler [WEAK]
+ B .
+ ENDP
+MemManage_Handler\
+ PROC
+ EXPORT MemManage_Handler [WEAK]
+ B .
+ ENDP
+BusFault_Handler\
+ PROC
+ EXPORT BusFault_Handler [WEAK]
+ B .
+ ENDP
+UsageFault_Handler\
+ PROC
+ EXPORT UsageFault_Handler [WEAK]
+ B .
+ ENDP
+SVC_Handler PROC
+ EXPORT SVC_Handler [WEAK]
+ B .
+ ENDP
+DebugMon_Handler\
+ PROC
+ EXPORT DebugMon_Handler [WEAK]
+ B .
+ ENDP
+PendSV_Handler PROC
+ EXPORT PendSV_Handler [WEAK]
+ B .
+ ENDP
+SysTick_Handler PROC
+ EXPORT SysTick_Handler [WEAK]
+ B .
+ ENDP
+
+Default_Handler PROC
+
+ EXPORT WWDG_IRQHandler [WEAK]
+ EXPORT PVD_IRQHandler [WEAK]
+ EXPORT TAMPER_IRQHandler [WEAK]
+ EXPORT RTC_IRQHandler [WEAK]
+ EXPORT FLASH_IRQHandler [WEAK]
+ EXPORT RCC_IRQHandler [WEAK]
+ EXPORT EXTI0_IRQHandler [WEAK]
+ EXPORT EXTI1_IRQHandler [WEAK]
+ EXPORT EXTI2_IRQHandler [WEAK]
+ EXPORT EXTI3_IRQHandler [WEAK]
+ EXPORT EXTI4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel1_IRQHandler [WEAK]
+ EXPORT DMA1_Channel2_IRQHandler [WEAK]
+ EXPORT DMA1_Channel3_IRQHandler [WEAK]
+ EXPORT DMA1_Channel4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel5_IRQHandler [WEAK]
+ EXPORT DMA1_Channel6_IRQHandler [WEAK]
+ EXPORT DMA1_Channel7_IRQHandler [WEAK]
+ EXPORT ADC1_IRQHandler [WEAK]
+ EXPORT USB_HP_IRQHandler [WEAK]
+ EXPORT USB_LP_IRQHandler [WEAK]
+ EXPORT EXTI9_5_IRQHandler [WEAK]
+ EXPORT TIM2_IRQHandler [WEAK]
+ EXPORT TIM3_IRQHandler [WEAK]
+ EXPORT TIM4_IRQHandler [WEAK]
+ EXPORT I2C1_EV_IRQHandler [WEAK]
+ EXPORT I2C1_ER_IRQHandler [WEAK]
+ EXPORT I2C2_EV_IRQHandler [WEAK]
+ EXPORT I2C2_ER_IRQHandler [WEAK]
+ EXPORT SPI1_IRQHandler [WEAK]
+ EXPORT SPI2_IRQHandler [WEAK]
+ EXPORT USART1_IRQHandler [WEAK]
+ EXPORT USART2_IRQHandler [WEAK]
+ EXPORT USART3_IRQHandler [WEAK]
+ EXPORT EXTI15_10_IRQHandler [WEAK]
+ EXPORT RTC_Alarm_IRQHandler [WEAK]
+ EXPORT USBWakeUp_IRQHandler [WEAK]
+
+WWDG_IRQHandler
+PVD_IRQHandler
+TAMPER_IRQHandler
+RTC_IRQHandler
+FLASH_IRQHandler
+RCC_IRQHandler
+EXTI0_IRQHandler
+EXTI1_IRQHandler
+EXTI2_IRQHandler
+EXTI3_IRQHandler
+EXTI4_IRQHandler
+DMA1_Channel1_IRQHandler
+DMA1_Channel2_IRQHandler
+DMA1_Channel3_IRQHandler
+DMA1_Channel4_IRQHandler
+DMA1_Channel5_IRQHandler
+DMA1_Channel6_IRQHandler
+DMA1_Channel7_IRQHandler
+ADC1_IRQHandler
+USB_HP_IRQHandler
+USB_LP_IRQHandler
+EXTI9_5_IRQHandler
+TIM2_IRQHandler
+TIM3_IRQHandler
+TIM4_IRQHandler
+I2C1_EV_IRQHandler
+I2C1_ER_IRQHandler
+I2C2_EV_IRQHandler
+I2C2_ER_IRQHandler
+SPI1_IRQHandler
+SPI2_IRQHandler
+USART1_IRQHandler
+USART2_IRQHandler
+USART3_IRQHandler
+EXTI15_10_IRQHandler
+RTC_Alarm_IRQHandler
+USBWakeUp_IRQHandler
+
+ B .
+
+ ENDP
+
+ ALIGN
+
+;*******************************************************************************
+; User Stack and Heap initialization
+;*******************************************************************************
+ IF :DEF:__MICROLIB
+
+ EXPORT __initial_sp
+ EXPORT __heap_base
+ EXPORT __heap_limit
+
+ ELSE
+
+ IMPORT __use_two_region_memory
+ EXPORT __user_initial_stackheap
+
+__user_initial_stackheap
+
+ LDR R0, = Heap_Mem
+ LDR R1, =(Stack_Mem + Stack_Size)
+ LDR R2, = (Heap_Mem + Heap_Size)
+ LDR R3, = Stack_Mem
+ BX LR
+
+ ALIGN
+
+ ENDIF
+
+ END
+
+;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103x6.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103x6.s
new file mode 100644
index 0000000..e824c53
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103x6.s
@@ -0,0 +1,314 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f103x6.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F103x6 Devices vector table for MDK-ARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == Reset_Handler
+;* - Set the vector table entries with the exceptions ISR address
+;* - Configure the clock system
+;* - Branches to __main in the C library (which eventually
+;* calls main()).
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;
+;*******************************************************************************
+
+; Amount of memory (in bytes) allocated for Stack
+; Tailor this value to your application needs
+; Stack Configuration
+; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Stack_Size EQU 0x00000400
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem SPACE Stack_Size
+__initial_sp
+
+
+; Heap Configuration
+; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Heap_Size EQU 0x00000200
+
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem SPACE Heap_Size
+__heap_limit
+
+ PRESERVE8
+ THUMB
+
+
+; Vector Table Mapped to Address 0 at Reset
+ AREA RESET, DATA, READONLY
+ EXPORT __Vectors
+ EXPORT __Vectors_End
+ EXPORT __Vectors_Size
+
+__Vectors DCD __initial_sp ; Top of Stack
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_2_IRQHandler ; ADC1_2
+ DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
+ DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
+ DCD CAN1_RX1_IRQHandler ; CAN1 RX1
+ DCD CAN1_SCE_IRQHandler ; CAN1 SCE
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD TIM1_BRK_IRQHandler ; TIM1 Break
+ DCD TIM1_UP_IRQHandler ; TIM1 Update
+ DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
+ DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD 0 ; Reserved
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SPI1_IRQHandler ; SPI1
+ DCD 0 ; Reserved
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD 0 ; Reserved
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
+__Vectors_End
+
+__Vectors_Size EQU __Vectors_End - __Vectors
+
+ AREA |.text|, CODE, READONLY
+
+; Reset handler routine
+Reset_Handler PROC
+ EXPORT Reset_Handler [WEAK]
+ IMPORT __main
+ IMPORT SystemInit
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__main
+ BX R0
+ ENDP
+
+; Dummy Exception Handlers (infinite loops which can be modified)
+
+NMI_Handler PROC
+ EXPORT NMI_Handler [WEAK]
+ B .
+ ENDP
+HardFault_Handler\
+ PROC
+ EXPORT HardFault_Handler [WEAK]
+ B .
+ ENDP
+MemManage_Handler\
+ PROC
+ EXPORT MemManage_Handler [WEAK]
+ B .
+ ENDP
+BusFault_Handler\
+ PROC
+ EXPORT BusFault_Handler [WEAK]
+ B .
+ ENDP
+UsageFault_Handler\
+ PROC
+ EXPORT UsageFault_Handler [WEAK]
+ B .
+ ENDP
+SVC_Handler PROC
+ EXPORT SVC_Handler [WEAK]
+ B .
+ ENDP
+DebugMon_Handler\
+ PROC
+ EXPORT DebugMon_Handler [WEAK]
+ B .
+ ENDP
+PendSV_Handler PROC
+ EXPORT PendSV_Handler [WEAK]
+ B .
+ ENDP
+SysTick_Handler PROC
+ EXPORT SysTick_Handler [WEAK]
+ B .
+ ENDP
+
+Default_Handler PROC
+
+ EXPORT WWDG_IRQHandler [WEAK]
+ EXPORT PVD_IRQHandler [WEAK]
+ EXPORT TAMPER_IRQHandler [WEAK]
+ EXPORT RTC_IRQHandler [WEAK]
+ EXPORT FLASH_IRQHandler [WEAK]
+ EXPORT RCC_IRQHandler [WEAK]
+ EXPORT EXTI0_IRQHandler [WEAK]
+ EXPORT EXTI1_IRQHandler [WEAK]
+ EXPORT EXTI2_IRQHandler [WEAK]
+ EXPORT EXTI3_IRQHandler [WEAK]
+ EXPORT EXTI4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel1_IRQHandler [WEAK]
+ EXPORT DMA1_Channel2_IRQHandler [WEAK]
+ EXPORT DMA1_Channel3_IRQHandler [WEAK]
+ EXPORT DMA1_Channel4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel5_IRQHandler [WEAK]
+ EXPORT DMA1_Channel6_IRQHandler [WEAK]
+ EXPORT DMA1_Channel7_IRQHandler [WEAK]
+ EXPORT ADC1_2_IRQHandler [WEAK]
+ EXPORT USB_HP_CAN1_TX_IRQHandler [WEAK]
+ EXPORT USB_LP_CAN1_RX0_IRQHandler [WEAK]
+ EXPORT CAN1_RX1_IRQHandler [WEAK]
+ EXPORT CAN1_SCE_IRQHandler [WEAK]
+ EXPORT EXTI9_5_IRQHandler [WEAK]
+ EXPORT TIM1_BRK_IRQHandler [WEAK]
+ EXPORT TIM1_UP_IRQHandler [WEAK]
+ EXPORT TIM1_TRG_COM_IRQHandler [WEAK]
+ EXPORT TIM1_CC_IRQHandler [WEAK]
+ EXPORT TIM2_IRQHandler [WEAK]
+ EXPORT TIM3_IRQHandler [WEAK]
+ EXPORT I2C1_EV_IRQHandler [WEAK]
+ EXPORT I2C1_ER_IRQHandler [WEAK]
+ EXPORT SPI1_IRQHandler [WEAK]
+ EXPORT USART1_IRQHandler [WEAK]
+ EXPORT USART2_IRQHandler [WEAK]
+ EXPORT EXTI15_10_IRQHandler [WEAK]
+ EXPORT RTC_Alarm_IRQHandler [WEAK]
+ EXPORT USBWakeUp_IRQHandler [WEAK]
+
+WWDG_IRQHandler
+PVD_IRQHandler
+TAMPER_IRQHandler
+RTC_IRQHandler
+FLASH_IRQHandler
+RCC_IRQHandler
+EXTI0_IRQHandler
+EXTI1_IRQHandler
+EXTI2_IRQHandler
+EXTI3_IRQHandler
+EXTI4_IRQHandler
+DMA1_Channel1_IRQHandler
+DMA1_Channel2_IRQHandler
+DMA1_Channel3_IRQHandler
+DMA1_Channel4_IRQHandler
+DMA1_Channel5_IRQHandler
+DMA1_Channel6_IRQHandler
+DMA1_Channel7_IRQHandler
+ADC1_2_IRQHandler
+USB_HP_CAN1_TX_IRQHandler
+USB_LP_CAN1_RX0_IRQHandler
+CAN1_RX1_IRQHandler
+CAN1_SCE_IRQHandler
+EXTI9_5_IRQHandler
+TIM1_BRK_IRQHandler
+TIM1_UP_IRQHandler
+TIM1_TRG_COM_IRQHandler
+TIM1_CC_IRQHandler
+TIM2_IRQHandler
+TIM3_IRQHandler
+I2C1_EV_IRQHandler
+I2C1_ER_IRQHandler
+SPI1_IRQHandler
+USART1_IRQHandler
+USART2_IRQHandler
+EXTI15_10_IRQHandler
+RTC_Alarm_IRQHandler
+USBWakeUp_IRQHandler
+
+ B .
+
+ ENDP
+
+ ALIGN
+
+;*******************************************************************************
+; User Stack and Heap initialization
+;*******************************************************************************
+ IF :DEF:__MICROLIB
+
+ EXPORT __initial_sp
+ EXPORT __heap_base
+ EXPORT __heap_limit
+
+ ELSE
+
+ IMPORT __use_two_region_memory
+ EXPORT __user_initial_stackheap
+
+__user_initial_stackheap
+
+ LDR R0, = Heap_Mem
+ LDR R1, =(Stack_Mem + Stack_Size)
+ LDR R2, = (Heap_Mem + Heap_Size)
+ LDR R3, = Stack_Mem
+ BX LR
+
+ ALIGN
+
+ ENDIF
+
+ END
+
+;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xb.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xb.s
new file mode 100644
index 0000000..b9bc319
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xb.s
@@ -0,0 +1,324 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f103xb.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F103xB Devices vector table for MDK-ARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == Reset_Handler
+;* - Set the vector table entries with the exceptions ISR address
+;* - Configure the clock system
+;* - Branches to __main in the C library (which eventually
+;* calls main()).
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;
+;*******************************************************************************
+
+; Amount of memory (in bytes) allocated for Stack
+; Tailor this value to your application needs
+; Stack Configuration
+; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Stack_Size EQU 0x00000400
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem SPACE Stack_Size
+__initial_sp
+
+
+; Heap Configuration
+; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Heap_Size EQU 0x00000200
+
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem SPACE Heap_Size
+__heap_limit
+
+ PRESERVE8
+ THUMB
+
+
+; Vector Table Mapped to Address 0 at Reset
+ AREA RESET, DATA, READONLY
+ EXPORT __Vectors
+ EXPORT __Vectors_End
+ EXPORT __Vectors_Size
+
+__Vectors DCD __initial_sp ; Top of Stack
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_2_IRQHandler ; ADC1_2
+ DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
+ DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
+ DCD CAN1_RX1_IRQHandler ; CAN1 RX1
+ DCD CAN1_SCE_IRQHandler ; CAN1 SCE
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD TIM1_BRK_IRQHandler ; TIM1 Break
+ DCD TIM1_UP_IRQHandler ; TIM1 Update
+ DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
+ DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C2 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
+__Vectors_End
+
+__Vectors_Size EQU __Vectors_End - __Vectors
+
+ AREA |.text|, CODE, READONLY
+
+; Reset handler
+Reset_Handler PROC
+ EXPORT Reset_Handler [WEAK]
+ IMPORT __main
+ IMPORT SystemInit
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__main
+ BX R0
+ ENDP
+
+; Dummy Exception Handlers (infinite loops which can be modified)
+
+NMI_Handler PROC
+ EXPORT NMI_Handler [WEAK]
+ B .
+ ENDP
+HardFault_Handler\
+ PROC
+ EXPORT HardFault_Handler [WEAK]
+ B .
+ ENDP
+MemManage_Handler\
+ PROC
+ EXPORT MemManage_Handler [WEAK]
+ B .
+ ENDP
+BusFault_Handler\
+ PROC
+ EXPORT BusFault_Handler [WEAK]
+ B .
+ ENDP
+UsageFault_Handler\
+ PROC
+ EXPORT UsageFault_Handler [WEAK]
+ B .
+ ENDP
+SVC_Handler PROC
+ EXPORT SVC_Handler [WEAK]
+ B .
+ ENDP
+DebugMon_Handler\
+ PROC
+ EXPORT DebugMon_Handler [WEAK]
+ B .
+ ENDP
+PendSV_Handler PROC
+ EXPORT PendSV_Handler [WEAK]
+ B .
+ ENDP
+SysTick_Handler PROC
+ EXPORT SysTick_Handler [WEAK]
+ B .
+ ENDP
+
+Default_Handler PROC
+
+ EXPORT WWDG_IRQHandler [WEAK]
+ EXPORT PVD_IRQHandler [WEAK]
+ EXPORT TAMPER_IRQHandler [WEAK]
+ EXPORT RTC_IRQHandler [WEAK]
+ EXPORT FLASH_IRQHandler [WEAK]
+ EXPORT RCC_IRQHandler [WEAK]
+ EXPORT EXTI0_IRQHandler [WEAK]
+ EXPORT EXTI1_IRQHandler [WEAK]
+ EXPORT EXTI2_IRQHandler [WEAK]
+ EXPORT EXTI3_IRQHandler [WEAK]
+ EXPORT EXTI4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel1_IRQHandler [WEAK]
+ EXPORT DMA1_Channel2_IRQHandler [WEAK]
+ EXPORT DMA1_Channel3_IRQHandler [WEAK]
+ EXPORT DMA1_Channel4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel5_IRQHandler [WEAK]
+ EXPORT DMA1_Channel6_IRQHandler [WEAK]
+ EXPORT DMA1_Channel7_IRQHandler [WEAK]
+ EXPORT ADC1_2_IRQHandler [WEAK]
+ EXPORT USB_HP_CAN1_TX_IRQHandler [WEAK]
+ EXPORT USB_LP_CAN1_RX0_IRQHandler [WEAK]
+ EXPORT CAN1_RX1_IRQHandler [WEAK]
+ EXPORT CAN1_SCE_IRQHandler [WEAK]
+ EXPORT EXTI9_5_IRQHandler [WEAK]
+ EXPORT TIM1_BRK_IRQHandler [WEAK]
+ EXPORT TIM1_UP_IRQHandler [WEAK]
+ EXPORT TIM1_TRG_COM_IRQHandler [WEAK]
+ EXPORT TIM1_CC_IRQHandler [WEAK]
+ EXPORT TIM2_IRQHandler [WEAK]
+ EXPORT TIM3_IRQHandler [WEAK]
+ EXPORT TIM4_IRQHandler [WEAK]
+ EXPORT I2C1_EV_IRQHandler [WEAK]
+ EXPORT I2C1_ER_IRQHandler [WEAK]
+ EXPORT I2C2_EV_IRQHandler [WEAK]
+ EXPORT I2C2_ER_IRQHandler [WEAK]
+ EXPORT SPI1_IRQHandler [WEAK]
+ EXPORT SPI2_IRQHandler [WEAK]
+ EXPORT USART1_IRQHandler [WEAK]
+ EXPORT USART2_IRQHandler [WEAK]
+ EXPORT USART3_IRQHandler [WEAK]
+ EXPORT EXTI15_10_IRQHandler [WEAK]
+ EXPORT RTC_Alarm_IRQHandler [WEAK]
+ EXPORT USBWakeUp_IRQHandler [WEAK]
+
+WWDG_IRQHandler
+PVD_IRQHandler
+TAMPER_IRQHandler
+RTC_IRQHandler
+FLASH_IRQHandler
+RCC_IRQHandler
+EXTI0_IRQHandler
+EXTI1_IRQHandler
+EXTI2_IRQHandler
+EXTI3_IRQHandler
+EXTI4_IRQHandler
+DMA1_Channel1_IRQHandler
+DMA1_Channel2_IRQHandler
+DMA1_Channel3_IRQHandler
+DMA1_Channel4_IRQHandler
+DMA1_Channel5_IRQHandler
+DMA1_Channel6_IRQHandler
+DMA1_Channel7_IRQHandler
+ADC1_2_IRQHandler
+USB_HP_CAN1_TX_IRQHandler
+USB_LP_CAN1_RX0_IRQHandler
+CAN1_RX1_IRQHandler
+CAN1_SCE_IRQHandler
+EXTI9_5_IRQHandler
+TIM1_BRK_IRQHandler
+TIM1_UP_IRQHandler
+TIM1_TRG_COM_IRQHandler
+TIM1_CC_IRQHandler
+TIM2_IRQHandler
+TIM3_IRQHandler
+TIM4_IRQHandler
+I2C1_EV_IRQHandler
+I2C1_ER_IRQHandler
+I2C2_EV_IRQHandler
+I2C2_ER_IRQHandler
+SPI1_IRQHandler
+SPI2_IRQHandler
+USART1_IRQHandler
+USART2_IRQHandler
+USART3_IRQHandler
+EXTI15_10_IRQHandler
+RTC_Alarm_IRQHandler
+USBWakeUp_IRQHandler
+
+ B .
+
+ ENDP
+
+ ALIGN
+
+;*******************************************************************************
+; User Stack and Heap initialization
+;*******************************************************************************
+ IF :DEF:__MICROLIB
+
+ EXPORT __initial_sp
+ EXPORT __heap_base
+ EXPORT __heap_limit
+
+ ELSE
+
+ IMPORT __use_two_region_memory
+ EXPORT __user_initial_stackheap
+
+__user_initial_stackheap
+
+ LDR R0, = Heap_Mem
+ LDR R1, =(Stack_Mem + Stack_Size)
+ LDR R2, = (Heap_Mem + Heap_Size)
+ LDR R3, = Stack_Mem
+ BX LR
+
+ ALIGN
+
+ ENDIF
+
+ END
+
+;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xe.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xe.s
new file mode 100644
index 0000000..f23f07c
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xe.s
@@ -0,0 +1,373 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f103xe.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F103xE Devices vector table for MDK-ARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == Reset_Handler
+;* - Set the vector table entries with the exceptions ISR address
+;* - Configure the clock system
+;* - Branches to __main in the C library (which eventually
+;* calls main()).
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;
+;*******************************************************************************
+
+; Amount of memory (in bytes) allocated for Stack
+; Tailor this value to your application needs
+; Stack Configuration
+; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Stack_Size EQU 0x00000400
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem SPACE Stack_Size
+__initial_sp
+
+; Heap Configuration
+; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Heap_Size EQU 0x00000200
+
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem SPACE Heap_Size
+__heap_limit
+
+ PRESERVE8
+ THUMB
+
+
+; Vector Table Mapped to Address 0 at Reset
+ AREA RESET, DATA, READONLY
+ EXPORT __Vectors
+ EXPORT __Vectors_End
+ EXPORT __Vectors_Size
+
+__Vectors DCD __initial_sp ; Top of Stack
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_2_IRQHandler ; ADC1 & ADC2
+ DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
+ DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
+ DCD CAN1_RX1_IRQHandler ; CAN1 RX1
+ DCD CAN1_SCE_IRQHandler ; CAN1 SCE
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD TIM1_BRK_IRQHandler ; TIM1 Break
+ DCD TIM1_UP_IRQHandler ; TIM1 Update
+ DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
+ DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C2 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
+ DCD TIM8_BRK_IRQHandler ; TIM8 Break
+ DCD TIM8_UP_IRQHandler ; TIM8 Update
+ DCD TIM8_TRG_COM_IRQHandler ; TIM8 Trigger and Commutation
+ DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare
+ DCD ADC3_IRQHandler ; ADC3
+ DCD FSMC_IRQHandler ; FSMC
+ DCD SDIO_IRQHandler ; SDIO
+ DCD TIM5_IRQHandler ; TIM5
+ DCD SPI3_IRQHandler ; SPI3
+ DCD UART4_IRQHandler ; UART4
+ DCD UART5_IRQHandler ; UART5
+ DCD TIM6_IRQHandler ; TIM6
+ DCD TIM7_IRQHandler ; TIM7
+ DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
+ DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
+ DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
+ DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
+__Vectors_End
+
+__Vectors_Size EQU __Vectors_End - __Vectors
+
+ AREA |.text|, CODE, READONLY
+
+; Reset handler
+Reset_Handler PROC
+ EXPORT Reset_Handler [WEAK]
+ IMPORT __main
+ IMPORT SystemInit
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__main
+ BX R0
+ ENDP
+
+; Dummy Exception Handlers (infinite loops which can be modified)
+
+NMI_Handler PROC
+ EXPORT NMI_Handler [WEAK]
+ B .
+ ENDP
+HardFault_Handler\
+ PROC
+ EXPORT HardFault_Handler [WEAK]
+ B .
+ ENDP
+MemManage_Handler\
+ PROC
+ EXPORT MemManage_Handler [WEAK]
+ B .
+ ENDP
+BusFault_Handler\
+ PROC
+ EXPORT BusFault_Handler [WEAK]
+ B .
+ ENDP
+UsageFault_Handler\
+ PROC
+ EXPORT UsageFault_Handler [WEAK]
+ B .
+ ENDP
+SVC_Handler PROC
+ EXPORT SVC_Handler [WEAK]
+ B .
+ ENDP
+DebugMon_Handler\
+ PROC
+ EXPORT DebugMon_Handler [WEAK]
+ B .
+ ENDP
+PendSV_Handler PROC
+ EXPORT PendSV_Handler [WEAK]
+ B .
+ ENDP
+SysTick_Handler PROC
+ EXPORT SysTick_Handler [WEAK]
+ B .
+ ENDP
+
+Default_Handler PROC
+
+ EXPORT WWDG_IRQHandler [WEAK]
+ EXPORT PVD_IRQHandler [WEAK]
+ EXPORT TAMPER_IRQHandler [WEAK]
+ EXPORT RTC_IRQHandler [WEAK]
+ EXPORT FLASH_IRQHandler [WEAK]
+ EXPORT RCC_IRQHandler [WEAK]
+ EXPORT EXTI0_IRQHandler [WEAK]
+ EXPORT EXTI1_IRQHandler [WEAK]
+ EXPORT EXTI2_IRQHandler [WEAK]
+ EXPORT EXTI3_IRQHandler [WEAK]
+ EXPORT EXTI4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel1_IRQHandler [WEAK]
+ EXPORT DMA1_Channel2_IRQHandler [WEAK]
+ EXPORT DMA1_Channel3_IRQHandler [WEAK]
+ EXPORT DMA1_Channel4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel5_IRQHandler [WEAK]
+ EXPORT DMA1_Channel6_IRQHandler [WEAK]
+ EXPORT DMA1_Channel7_IRQHandler [WEAK]
+ EXPORT ADC1_2_IRQHandler [WEAK]
+ EXPORT USB_HP_CAN1_TX_IRQHandler [WEAK]
+ EXPORT USB_LP_CAN1_RX0_IRQHandler [WEAK]
+ EXPORT CAN1_RX1_IRQHandler [WEAK]
+ EXPORT CAN1_SCE_IRQHandler [WEAK]
+ EXPORT EXTI9_5_IRQHandler [WEAK]
+ EXPORT TIM1_BRK_IRQHandler [WEAK]
+ EXPORT TIM1_UP_IRQHandler [WEAK]
+ EXPORT TIM1_TRG_COM_IRQHandler [WEAK]
+ EXPORT TIM1_CC_IRQHandler [WEAK]
+ EXPORT TIM2_IRQHandler [WEAK]
+ EXPORT TIM3_IRQHandler [WEAK]
+ EXPORT TIM4_IRQHandler [WEAK]
+ EXPORT I2C1_EV_IRQHandler [WEAK]
+ EXPORT I2C1_ER_IRQHandler [WEAK]
+ EXPORT I2C2_EV_IRQHandler [WEAK]
+ EXPORT I2C2_ER_IRQHandler [WEAK]
+ EXPORT SPI1_IRQHandler [WEAK]
+ EXPORT SPI2_IRQHandler [WEAK]
+ EXPORT USART1_IRQHandler [WEAK]
+ EXPORT USART2_IRQHandler [WEAK]
+ EXPORT USART3_IRQHandler [WEAK]
+ EXPORT EXTI15_10_IRQHandler [WEAK]
+ EXPORT RTC_Alarm_IRQHandler [WEAK]
+ EXPORT USBWakeUp_IRQHandler [WEAK]
+ EXPORT TIM8_BRK_IRQHandler [WEAK]
+ EXPORT TIM8_UP_IRQHandler [WEAK]
+ EXPORT TIM8_TRG_COM_IRQHandler [WEAK]
+ EXPORT TIM8_CC_IRQHandler [WEAK]
+ EXPORT ADC3_IRQHandler [WEAK]
+ EXPORT FSMC_IRQHandler [WEAK]
+ EXPORT SDIO_IRQHandler [WEAK]
+ EXPORT TIM5_IRQHandler [WEAK]
+ EXPORT SPI3_IRQHandler [WEAK]
+ EXPORT UART4_IRQHandler [WEAK]
+ EXPORT UART5_IRQHandler [WEAK]
+ EXPORT TIM6_IRQHandler [WEAK]
+ EXPORT TIM7_IRQHandler [WEAK]
+ EXPORT DMA2_Channel1_IRQHandler [WEAK]
+ EXPORT DMA2_Channel2_IRQHandler [WEAK]
+ EXPORT DMA2_Channel3_IRQHandler [WEAK]
+ EXPORT DMA2_Channel4_5_IRQHandler [WEAK]
+
+WWDG_IRQHandler
+PVD_IRQHandler
+TAMPER_IRQHandler
+RTC_IRQHandler
+FLASH_IRQHandler
+RCC_IRQHandler
+EXTI0_IRQHandler
+EXTI1_IRQHandler
+EXTI2_IRQHandler
+EXTI3_IRQHandler
+EXTI4_IRQHandler
+DMA1_Channel1_IRQHandler
+DMA1_Channel2_IRQHandler
+DMA1_Channel3_IRQHandler
+DMA1_Channel4_IRQHandler
+DMA1_Channel5_IRQHandler
+DMA1_Channel6_IRQHandler
+DMA1_Channel7_IRQHandler
+ADC1_2_IRQHandler
+USB_HP_CAN1_TX_IRQHandler
+USB_LP_CAN1_RX0_IRQHandler
+CAN1_RX1_IRQHandler
+CAN1_SCE_IRQHandler
+EXTI9_5_IRQHandler
+TIM1_BRK_IRQHandler
+TIM1_UP_IRQHandler
+TIM1_TRG_COM_IRQHandler
+TIM1_CC_IRQHandler
+TIM2_IRQHandler
+TIM3_IRQHandler
+TIM4_IRQHandler
+I2C1_EV_IRQHandler
+I2C1_ER_IRQHandler
+I2C2_EV_IRQHandler
+I2C2_ER_IRQHandler
+SPI1_IRQHandler
+SPI2_IRQHandler
+USART1_IRQHandler
+USART2_IRQHandler
+USART3_IRQHandler
+EXTI15_10_IRQHandler
+RTC_Alarm_IRQHandler
+USBWakeUp_IRQHandler
+TIM8_BRK_IRQHandler
+TIM8_UP_IRQHandler
+TIM8_TRG_COM_IRQHandler
+TIM8_CC_IRQHandler
+ADC3_IRQHandler
+FSMC_IRQHandler
+SDIO_IRQHandler
+TIM5_IRQHandler
+SPI3_IRQHandler
+UART4_IRQHandler
+UART5_IRQHandler
+TIM6_IRQHandler
+TIM7_IRQHandler
+DMA2_Channel1_IRQHandler
+DMA2_Channel2_IRQHandler
+DMA2_Channel3_IRQHandler
+DMA2_Channel4_5_IRQHandler
+ B .
+
+ ENDP
+
+ ALIGN
+
+;*******************************************************************************
+; User Stack and Heap initialization
+;*******************************************************************************
+ IF :DEF:__MICROLIB
+
+ EXPORT __initial_sp
+ EXPORT __heap_base
+ EXPORT __heap_limit
+
+ ELSE
+
+ IMPORT __use_two_region_memory
+ EXPORT __user_initial_stackheap
+
+__user_initial_stackheap
+
+ LDR R0, = Heap_Mem
+ LDR R1, =(Stack_Mem + Stack_Size)
+ LDR R2, = (Heap_Mem + Heap_Size)
+ LDR R3, = Stack_Mem
+ BX LR
+
+ ALIGN
+
+ ENDIF
+
+ END
+
+;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xg.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xg.s
new file mode 100644
index 0000000..60296a1
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f103xg.s
@@ -0,0 +1,373 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f103xg.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F103xG Devices vector table for MDK-ARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == Reset_Handler
+;* - Set the vector table entries with the exceptions ISR address
+;* - Configure the clock system
+;* - Branches to __main in the C library (which eventually
+;* calls main()).
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;
+;*******************************************************************************
+
+; Amount of memory (in bytes) allocated for Stack
+; Tailor this value to your application needs
+; Stack Configuration
+; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Stack_Size EQU 0x00000400
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem SPACE Stack_Size
+__initial_sp
+
+; Heap Configuration
+; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Heap_Size EQU 0x00000200
+
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem SPACE Heap_Size
+__heap_limit
+
+ PRESERVE8
+ THUMB
+
+
+; Vector Table Mapped to Address 0 at Reset
+ AREA RESET, DATA, READONLY
+ EXPORT __Vectors
+ EXPORT __Vectors_End
+ EXPORT __Vectors_Size
+
+__Vectors DCD __initial_sp ; Top of Stack
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_2_IRQHandler ; ADC1 & ADC2
+ DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
+ DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
+ DCD CAN1_RX1_IRQHandler ; CAN1 RX1
+ DCD CAN1_SCE_IRQHandler ; CAN1 SCE
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD TIM1_BRK_TIM9_IRQHandler ; TIM1 Break and TIM9
+ DCD TIM1_UP_TIM10_IRQHandler ; TIM1 Update and TIM10
+ DCD TIM1_TRG_COM_TIM11_IRQHandler ; TIM1 Trigger and Commutation and TIM11
+ DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C2 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
+ DCD TIM8_BRK_TIM12_IRQHandler ; TIM8 Break and TIM12
+ DCD TIM8_UP_TIM13_IRQHandler ; TIM8 Update and TIM13
+ DCD TIM8_TRG_COM_TIM14_IRQHandler ; TIM8 Trigger and Commutation and TIM14
+ DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare
+ DCD ADC3_IRQHandler ; ADC3
+ DCD FSMC_IRQHandler ; FSMC
+ DCD SDIO_IRQHandler ; SDIO
+ DCD TIM5_IRQHandler ; TIM5
+ DCD SPI3_IRQHandler ; SPI3
+ DCD UART4_IRQHandler ; UART4
+ DCD UART5_IRQHandler ; UART5
+ DCD TIM6_IRQHandler ; TIM6
+ DCD TIM7_IRQHandler ; TIM7
+ DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
+ DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
+ DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
+ DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
+__Vectors_End
+
+__Vectors_Size EQU __Vectors_End - __Vectors
+
+ AREA |.text|, CODE, READONLY
+
+; Reset handler
+Reset_Handler PROC
+ EXPORT Reset_Handler [WEAK]
+ IMPORT __main
+ IMPORT SystemInit
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__main
+ BX R0
+ ENDP
+
+; Dummy Exception Handlers (infinite loops which can be modified)
+
+NMI_Handler PROC
+ EXPORT NMI_Handler [WEAK]
+ B .
+ ENDP
+HardFault_Handler\
+ PROC
+ EXPORT HardFault_Handler [WEAK]
+ B .
+ ENDP
+MemManage_Handler\
+ PROC
+ EXPORT MemManage_Handler [WEAK]
+ B .
+ ENDP
+BusFault_Handler\
+ PROC
+ EXPORT BusFault_Handler [WEAK]
+ B .
+ ENDP
+UsageFault_Handler\
+ PROC
+ EXPORT UsageFault_Handler [WEAK]
+ B .
+ ENDP
+SVC_Handler PROC
+ EXPORT SVC_Handler [WEAK]
+ B .
+ ENDP
+DebugMon_Handler\
+ PROC
+ EXPORT DebugMon_Handler [WEAK]
+ B .
+ ENDP
+PendSV_Handler PROC
+ EXPORT PendSV_Handler [WEAK]
+ B .
+ ENDP
+SysTick_Handler PROC
+ EXPORT SysTick_Handler [WEAK]
+ B .
+ ENDP
+
+Default_Handler PROC
+
+ EXPORT WWDG_IRQHandler [WEAK]
+ EXPORT PVD_IRQHandler [WEAK]
+ EXPORT TAMPER_IRQHandler [WEAK]
+ EXPORT RTC_IRQHandler [WEAK]
+ EXPORT FLASH_IRQHandler [WEAK]
+ EXPORT RCC_IRQHandler [WEAK]
+ EXPORT EXTI0_IRQHandler [WEAK]
+ EXPORT EXTI1_IRQHandler [WEAK]
+ EXPORT EXTI2_IRQHandler [WEAK]
+ EXPORT EXTI3_IRQHandler [WEAK]
+ EXPORT EXTI4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel1_IRQHandler [WEAK]
+ EXPORT DMA1_Channel2_IRQHandler [WEAK]
+ EXPORT DMA1_Channel3_IRQHandler [WEAK]
+ EXPORT DMA1_Channel4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel5_IRQHandler [WEAK]
+ EXPORT DMA1_Channel6_IRQHandler [WEAK]
+ EXPORT DMA1_Channel7_IRQHandler [WEAK]
+ EXPORT ADC1_2_IRQHandler [WEAK]
+ EXPORT USB_HP_CAN1_TX_IRQHandler [WEAK]
+ EXPORT USB_LP_CAN1_RX0_IRQHandler [WEAK]
+ EXPORT CAN1_RX1_IRQHandler [WEAK]
+ EXPORT CAN1_SCE_IRQHandler [WEAK]
+ EXPORT EXTI9_5_IRQHandler [WEAK]
+ EXPORT TIM1_BRK_TIM9_IRQHandler [WEAK]
+ EXPORT TIM1_UP_TIM10_IRQHandler [WEAK]
+ EXPORT TIM1_TRG_COM_TIM11_IRQHandler [WEAK]
+ EXPORT TIM1_CC_IRQHandler [WEAK]
+ EXPORT TIM2_IRQHandler [WEAK]
+ EXPORT TIM3_IRQHandler [WEAK]
+ EXPORT TIM4_IRQHandler [WEAK]
+ EXPORT I2C1_EV_IRQHandler [WEAK]
+ EXPORT I2C1_ER_IRQHandler [WEAK]
+ EXPORT I2C2_EV_IRQHandler [WEAK]
+ EXPORT I2C2_ER_IRQHandler [WEAK]
+ EXPORT SPI1_IRQHandler [WEAK]
+ EXPORT SPI2_IRQHandler [WEAK]
+ EXPORT USART1_IRQHandler [WEAK]
+ EXPORT USART2_IRQHandler [WEAK]
+ EXPORT USART3_IRQHandler [WEAK]
+ EXPORT EXTI15_10_IRQHandler [WEAK]
+ EXPORT RTC_Alarm_IRQHandler [WEAK]
+ EXPORT USBWakeUp_IRQHandler [WEAK]
+ EXPORT TIM8_BRK_TIM12_IRQHandler [WEAK]
+ EXPORT TIM8_UP_TIM13_IRQHandler [WEAK]
+ EXPORT TIM8_TRG_COM_TIM14_IRQHandler [WEAK]
+ EXPORT TIM8_CC_IRQHandler [WEAK]
+ EXPORT ADC3_IRQHandler [WEAK]
+ EXPORT FSMC_IRQHandler [WEAK]
+ EXPORT SDIO_IRQHandler [WEAK]
+ EXPORT TIM5_IRQHandler [WEAK]
+ EXPORT SPI3_IRQHandler [WEAK]
+ EXPORT UART4_IRQHandler [WEAK]
+ EXPORT UART5_IRQHandler [WEAK]
+ EXPORT TIM6_IRQHandler [WEAK]
+ EXPORT TIM7_IRQHandler [WEAK]
+ EXPORT DMA2_Channel1_IRQHandler [WEAK]
+ EXPORT DMA2_Channel2_IRQHandler [WEAK]
+ EXPORT DMA2_Channel3_IRQHandler [WEAK]
+ EXPORT DMA2_Channel4_5_IRQHandler [WEAK]
+
+WWDG_IRQHandler
+PVD_IRQHandler
+TAMPER_IRQHandler
+RTC_IRQHandler
+FLASH_IRQHandler
+RCC_IRQHandler
+EXTI0_IRQHandler
+EXTI1_IRQHandler
+EXTI2_IRQHandler
+EXTI3_IRQHandler
+EXTI4_IRQHandler
+DMA1_Channel1_IRQHandler
+DMA1_Channel2_IRQHandler
+DMA1_Channel3_IRQHandler
+DMA1_Channel4_IRQHandler
+DMA1_Channel5_IRQHandler
+DMA1_Channel6_IRQHandler
+DMA1_Channel7_IRQHandler
+ADC1_2_IRQHandler
+USB_HP_CAN1_TX_IRQHandler
+USB_LP_CAN1_RX0_IRQHandler
+CAN1_RX1_IRQHandler
+CAN1_SCE_IRQHandler
+EXTI9_5_IRQHandler
+TIM1_BRK_TIM9_IRQHandler
+TIM1_UP_TIM10_IRQHandler
+TIM1_TRG_COM_TIM11_IRQHandler
+TIM1_CC_IRQHandler
+TIM2_IRQHandler
+TIM3_IRQHandler
+TIM4_IRQHandler
+I2C1_EV_IRQHandler
+I2C1_ER_IRQHandler
+I2C2_EV_IRQHandler
+I2C2_ER_IRQHandler
+SPI1_IRQHandler
+SPI2_IRQHandler
+USART1_IRQHandler
+USART2_IRQHandler
+USART3_IRQHandler
+EXTI15_10_IRQHandler
+RTC_Alarm_IRQHandler
+USBWakeUp_IRQHandler
+TIM8_BRK_TIM12_IRQHandler
+TIM8_UP_TIM13_IRQHandler
+TIM8_TRG_COM_TIM14_IRQHandler
+TIM8_CC_IRQHandler
+ADC3_IRQHandler
+FSMC_IRQHandler
+SDIO_IRQHandler
+TIM5_IRQHandler
+SPI3_IRQHandler
+UART4_IRQHandler
+UART5_IRQHandler
+TIM6_IRQHandler
+TIM7_IRQHandler
+DMA2_Channel1_IRQHandler
+DMA2_Channel2_IRQHandler
+DMA2_Channel3_IRQHandler
+DMA2_Channel4_5_IRQHandler
+ B .
+
+ ENDP
+
+ ALIGN
+
+;*******************************************************************************
+; User Stack and Heap initialization
+;*******************************************************************************
+ IF :DEF:__MICROLIB
+
+ EXPORT __initial_sp
+ EXPORT __heap_base
+ EXPORT __heap_limit
+
+ ELSE
+
+ IMPORT __use_two_region_memory
+ EXPORT __user_initial_stackheap
+
+__user_initial_stackheap
+
+ LDR R0, = Heap_Mem
+ LDR R1, =(Stack_Mem + Stack_Size)
+ LDR R2, = (Heap_Mem + Heap_Size)
+ LDR R3, = Stack_Mem
+ BX LR
+
+ ALIGN
+
+ ENDIF
+
+ END
+
+;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f105xc.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f105xc.s
new file mode 100644
index 0000000..d6e177d
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f105xc.s
@@ -0,0 +1,381 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f105xc.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F105xC Devices vector table for MDK-ARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == Reset_Handler
+;* - Set the vector table entries with the exceptions ISR address
+;* - Configure the clock system
+;* - Branches to __main in the C library (which eventually
+;* calls main()).
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;
+;*******************************************************************************
+
+; Amount of memory (in bytes) allocated for Stack
+; Tailor this value to your application needs
+; Stack Configuration
+; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Stack_Size EQU 0x00000400
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem SPACE Stack_Size
+__initial_sp
+
+
+; Heap Configuration
+; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Heap_Size EQU 0x00000200
+
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem SPACE Heap_Size
+__heap_limit
+
+ PRESERVE8
+ THUMB
+
+
+; Vector Table Mapped to Address 0 at Reset
+ AREA RESET, DATA, READONLY
+ EXPORT __Vectors
+ EXPORT __Vectors_End
+ EXPORT __Vectors_Size
+
+__Vectors DCD __initial_sp ; Top of Stack
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_2_IRQHandler ; ADC1 and ADC2
+ DCD CAN1_TX_IRQHandler ; CAN1 TX
+ DCD CAN1_RX0_IRQHandler ; CAN1 RX0
+ DCD CAN1_RX1_IRQHandler ; CAN1 RX1
+ DCD CAN1_SCE_IRQHandler ; CAN1 SCE
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD TIM1_BRK_IRQHandler ; TIM1 Break
+ DCD TIM1_UP_IRQHandler ; TIM1 Update
+ DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
+ DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C1 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC alarm through EXTI line
+ DCD OTG_FS_WKUP_IRQHandler ; USB OTG FS Wakeup through EXTI line
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD TIM5_IRQHandler ; TIM5
+ DCD SPI3_IRQHandler ; SPI3
+ DCD UART4_IRQHandler ; UART4
+ DCD UART5_IRQHandler ; UART5
+ DCD TIM6_IRQHandler ; TIM6
+ DCD TIM7_IRQHandler ; TIM7
+ DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
+ DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
+ DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
+ DCD DMA2_Channel4_IRQHandler ; DMA2 Channel4
+ DCD DMA2_Channel5_IRQHandler ; DMA2 Channel5
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD CAN2_TX_IRQHandler ; CAN2 TX
+ DCD CAN2_RX0_IRQHandler ; CAN2 RX0
+ DCD CAN2_RX1_IRQHandler ; CAN2 RX1
+ DCD CAN2_SCE_IRQHandler ; CAN2 SCE
+ DCD OTG_FS_IRQHandler ; USB OTG FS
+__Vectors_End
+
+__Vectors_Size EQU __Vectors_End - __Vectors
+
+ AREA |.text|, CODE, READONLY
+
+; Reset handler
+Reset_Handler PROC
+ EXPORT Reset_Handler [WEAK]
+ IMPORT SystemInit
+ IMPORT __main
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__main
+ BX R0
+ ENDP
+
+; Dummy Exception Handlers (infinite loops which can be modified)
+
+NMI_Handler PROC
+ EXPORT NMI_Handler [WEAK]
+ B .
+ ENDP
+HardFault_Handler\
+ PROC
+ EXPORT HardFault_Handler [WEAK]
+ B .
+ ENDP
+MemManage_Handler\
+ PROC
+ EXPORT MemManage_Handler [WEAK]
+ B .
+ ENDP
+BusFault_Handler\
+ PROC
+ EXPORT BusFault_Handler [WEAK]
+ B .
+ ENDP
+UsageFault_Handler\
+ PROC
+ EXPORT UsageFault_Handler [WEAK]
+ B .
+ ENDP
+SVC_Handler PROC
+ EXPORT SVC_Handler [WEAK]
+ B .
+ ENDP
+DebugMon_Handler\
+ PROC
+ EXPORT DebugMon_Handler [WEAK]
+ B .
+ ENDP
+PendSV_Handler PROC
+ EXPORT PendSV_Handler [WEAK]
+ B .
+ ENDP
+SysTick_Handler PROC
+ EXPORT SysTick_Handler [WEAK]
+ B .
+ ENDP
+
+Default_Handler PROC
+
+ EXPORT WWDG_IRQHandler [WEAK]
+ EXPORT PVD_IRQHandler [WEAK]
+ EXPORT TAMPER_IRQHandler [WEAK]
+ EXPORT RTC_IRQHandler [WEAK]
+ EXPORT FLASH_IRQHandler [WEAK]
+ EXPORT RCC_IRQHandler [WEAK]
+ EXPORT EXTI0_IRQHandler [WEAK]
+ EXPORT EXTI1_IRQHandler [WEAK]
+ EXPORT EXTI2_IRQHandler [WEAK]
+ EXPORT EXTI3_IRQHandler [WEAK]
+ EXPORT EXTI4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel1_IRQHandler [WEAK]
+ EXPORT DMA1_Channel2_IRQHandler [WEAK]
+ EXPORT DMA1_Channel3_IRQHandler [WEAK]
+ EXPORT DMA1_Channel4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel5_IRQHandler [WEAK]
+ EXPORT DMA1_Channel6_IRQHandler [WEAK]
+ EXPORT DMA1_Channel7_IRQHandler [WEAK]
+ EXPORT ADC1_2_IRQHandler [WEAK]
+ EXPORT CAN1_TX_IRQHandler [WEAK]
+ EXPORT CAN1_RX0_IRQHandler [WEAK]
+ EXPORT CAN1_RX1_IRQHandler [WEAK]
+ EXPORT CAN1_SCE_IRQHandler [WEAK]
+ EXPORT EXTI9_5_IRQHandler [WEAK]
+ EXPORT TIM1_BRK_IRQHandler [WEAK]
+ EXPORT TIM1_UP_IRQHandler [WEAK]
+ EXPORT TIM1_TRG_COM_IRQHandler [WEAK]
+ EXPORT TIM1_CC_IRQHandler [WEAK]
+ EXPORT TIM2_IRQHandler [WEAK]
+ EXPORT TIM3_IRQHandler [WEAK]
+ EXPORT TIM4_IRQHandler [WEAK]
+ EXPORT I2C1_EV_IRQHandler [WEAK]
+ EXPORT I2C1_ER_IRQHandler [WEAK]
+ EXPORT I2C2_EV_IRQHandler [WEAK]
+ EXPORT I2C2_ER_IRQHandler [WEAK]
+ EXPORT SPI1_IRQHandler [WEAK]
+ EXPORT SPI2_IRQHandler [WEAK]
+ EXPORT USART1_IRQHandler [WEAK]
+ EXPORT USART2_IRQHandler [WEAK]
+ EXPORT USART3_IRQHandler [WEAK]
+ EXPORT EXTI15_10_IRQHandler [WEAK]
+ EXPORT RTC_Alarm_IRQHandler [WEAK]
+ EXPORT OTG_FS_WKUP_IRQHandler [WEAK]
+ EXPORT TIM5_IRQHandler [WEAK]
+ EXPORT SPI3_IRQHandler [WEAK]
+ EXPORT UART4_IRQHandler [WEAK]
+ EXPORT UART5_IRQHandler [WEAK]
+ EXPORT TIM6_IRQHandler [WEAK]
+ EXPORT TIM7_IRQHandler [WEAK]
+ EXPORT DMA2_Channel1_IRQHandler [WEAK]
+ EXPORT DMA2_Channel2_IRQHandler [WEAK]
+ EXPORT DMA2_Channel3_IRQHandler [WEAK]
+ EXPORT DMA2_Channel4_IRQHandler [WEAK]
+ EXPORT DMA2_Channel5_IRQHandler [WEAK]
+ EXPORT CAN2_TX_IRQHandler [WEAK]
+ EXPORT CAN2_RX0_IRQHandler [WEAK]
+ EXPORT CAN2_RX1_IRQHandler [WEAK]
+ EXPORT CAN2_SCE_IRQHandler [WEAK]
+ EXPORT OTG_FS_IRQHandler [WEAK]
+
+WWDG_IRQHandler
+PVD_IRQHandler
+TAMPER_IRQHandler
+RTC_IRQHandler
+FLASH_IRQHandler
+RCC_IRQHandler
+EXTI0_IRQHandler
+EXTI1_IRQHandler
+EXTI2_IRQHandler
+EXTI3_IRQHandler
+EXTI4_IRQHandler
+DMA1_Channel1_IRQHandler
+DMA1_Channel2_IRQHandler
+DMA1_Channel3_IRQHandler
+DMA1_Channel4_IRQHandler
+DMA1_Channel5_IRQHandler
+DMA1_Channel6_IRQHandler
+DMA1_Channel7_IRQHandler
+ADC1_2_IRQHandler
+CAN1_TX_IRQHandler
+CAN1_RX0_IRQHandler
+CAN1_RX1_IRQHandler
+CAN1_SCE_IRQHandler
+EXTI9_5_IRQHandler
+TIM1_BRK_IRQHandler
+TIM1_UP_IRQHandler
+TIM1_TRG_COM_IRQHandler
+TIM1_CC_IRQHandler
+TIM2_IRQHandler
+TIM3_IRQHandler
+TIM4_IRQHandler
+I2C1_EV_IRQHandler
+I2C1_ER_IRQHandler
+I2C2_EV_IRQHandler
+I2C2_ER_IRQHandler
+SPI1_IRQHandler
+SPI2_IRQHandler
+USART1_IRQHandler
+USART2_IRQHandler
+USART3_IRQHandler
+EXTI15_10_IRQHandler
+RTC_Alarm_IRQHandler
+OTG_FS_WKUP_IRQHandler
+TIM5_IRQHandler
+SPI3_IRQHandler
+UART4_IRQHandler
+UART5_IRQHandler
+TIM6_IRQHandler
+TIM7_IRQHandler
+DMA2_Channel1_IRQHandler
+DMA2_Channel2_IRQHandler
+DMA2_Channel3_IRQHandler
+DMA2_Channel4_IRQHandler
+DMA2_Channel5_IRQHandler
+CAN2_TX_IRQHandler
+CAN2_RX0_IRQHandler
+CAN2_RX1_IRQHandler
+CAN2_SCE_IRQHandler
+OTG_FS_IRQHandler
+
+ B .
+
+ ENDP
+
+ ALIGN
+
+;*******************************************************************************
+; User Stack and Heap initialization
+;*******************************************************************************
+ IF :DEF:__MICROLIB
+
+ EXPORT __initial_sp
+ EXPORT __heap_base
+ EXPORT __heap_limit
+
+ ELSE
+
+ IMPORT __use_two_region_memory
+ EXPORT __user_initial_stackheap
+
+__user_initial_stackheap
+
+ LDR R0, = Heap_Mem
+ LDR R1, =(Stack_Mem + Stack_Size)
+ LDR R2, = (Heap_Mem + Heap_Size)
+ LDR R3, = Stack_Mem
+ BX LR
+
+ ALIGN
+
+ ENDIF
+
+ END
+
+;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f107xc.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f107xc.s
new file mode 100644
index 0000000..6a6edbd
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/arm/startup_stm32f107xc.s
@@ -0,0 +1,385 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f107xc.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F107xC Devices vector table for MDK-ARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == Reset_Handler
+;* - Set the vector table entries with the exceptions ISR address
+;* - Configure the clock system
+;* - Branches to __main in the C library (which eventually
+;* calls main()).
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;
+;*******************************************************************************
+
+; Amount of memory (in bytes) allocated for Stack
+; Tailor this value to your application needs
+; Stack Configuration
+; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Stack_Size EQU 0x00000400
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem SPACE Stack_Size
+__initial_sp
+
+
+; Heap Configuration
+; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+
+Heap_Size EQU 0x00000200
+
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem SPACE Heap_Size
+__heap_limit
+
+ PRESERVE8
+ THUMB
+
+
+; Vector Table Mapped to Address 0 at Reset
+ AREA RESET, DATA, READONLY
+ EXPORT __Vectors
+ EXPORT __Vectors_End
+ EXPORT __Vectors_Size
+
+__Vectors DCD __initial_sp ; Top of Stack
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_2_IRQHandler ; ADC1 and ADC2
+ DCD CAN1_TX_IRQHandler ; CAN1 TX
+ DCD CAN1_RX0_IRQHandler ; CAN1 RX0
+ DCD CAN1_RX1_IRQHandler ; CAN1 RX1
+ DCD CAN1_SCE_IRQHandler ; CAN1 SCE
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD TIM1_BRK_IRQHandler ; TIM1 Break
+ DCD TIM1_UP_IRQHandler ; TIM1 Update
+ DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
+ DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C1 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC alarm through EXTI line
+ DCD OTG_FS_WKUP_IRQHandler ; USB OTG FS Wakeup through EXTI line
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD TIM5_IRQHandler ; TIM5
+ DCD SPI3_IRQHandler ; SPI3
+ DCD UART4_IRQHandler ; UART4
+ DCD UART5_IRQHandler ; UART5
+ DCD TIM6_IRQHandler ; TIM6
+ DCD TIM7_IRQHandler ; TIM7
+ DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
+ DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
+ DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
+ DCD DMA2_Channel4_IRQHandler ; DMA2 Channel4
+ DCD DMA2_Channel5_IRQHandler ; DMA2 Channel5
+ DCD ETH_IRQHandler ; Ethernet
+ DCD ETH_WKUP_IRQHandler ; Ethernet Wakeup through EXTI line
+ DCD CAN2_TX_IRQHandler ; CAN2 TX
+ DCD CAN2_RX0_IRQHandler ; CAN2 RX0
+ DCD CAN2_RX1_IRQHandler ; CAN2 RX1
+ DCD CAN2_SCE_IRQHandler ; CAN2 SCE
+ DCD OTG_FS_IRQHandler ; USB OTG FS
+__Vectors_End
+
+__Vectors_Size EQU __Vectors_End - __Vectors
+
+ AREA |.text|, CODE, READONLY
+
+; Reset handler
+Reset_Handler PROC
+ EXPORT Reset_Handler [WEAK]
+ IMPORT SystemInit
+ IMPORT __main
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__main
+ BX R0
+ ENDP
+
+; Dummy Exception Handlers (infinite loops which can be modified)
+
+NMI_Handler PROC
+ EXPORT NMI_Handler [WEAK]
+ B .
+ ENDP
+HardFault_Handler\
+ PROC
+ EXPORT HardFault_Handler [WEAK]
+ B .
+ ENDP
+MemManage_Handler\
+ PROC
+ EXPORT MemManage_Handler [WEAK]
+ B .
+ ENDP
+BusFault_Handler\
+ PROC
+ EXPORT BusFault_Handler [WEAK]
+ B .
+ ENDP
+UsageFault_Handler\
+ PROC
+ EXPORT UsageFault_Handler [WEAK]
+ B .
+ ENDP
+SVC_Handler PROC
+ EXPORT SVC_Handler [WEAK]
+ B .
+ ENDP
+DebugMon_Handler\
+ PROC
+ EXPORT DebugMon_Handler [WEAK]
+ B .
+ ENDP
+PendSV_Handler PROC
+ EXPORT PendSV_Handler [WEAK]
+ B .
+ ENDP
+SysTick_Handler PROC
+ EXPORT SysTick_Handler [WEAK]
+ B .
+ ENDP
+
+Default_Handler PROC
+
+ EXPORT WWDG_IRQHandler [WEAK]
+ EXPORT PVD_IRQHandler [WEAK]
+ EXPORT TAMPER_IRQHandler [WEAK]
+ EXPORT RTC_IRQHandler [WEAK]
+ EXPORT FLASH_IRQHandler [WEAK]
+ EXPORT RCC_IRQHandler [WEAK]
+ EXPORT EXTI0_IRQHandler [WEAK]
+ EXPORT EXTI1_IRQHandler [WEAK]
+ EXPORT EXTI2_IRQHandler [WEAK]
+ EXPORT EXTI3_IRQHandler [WEAK]
+ EXPORT EXTI4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel1_IRQHandler [WEAK]
+ EXPORT DMA1_Channel2_IRQHandler [WEAK]
+ EXPORT DMA1_Channel3_IRQHandler [WEAK]
+ EXPORT DMA1_Channel4_IRQHandler [WEAK]
+ EXPORT DMA1_Channel5_IRQHandler [WEAK]
+ EXPORT DMA1_Channel6_IRQHandler [WEAK]
+ EXPORT DMA1_Channel7_IRQHandler [WEAK]
+ EXPORT ADC1_2_IRQHandler [WEAK]
+ EXPORT CAN1_TX_IRQHandler [WEAK]
+ EXPORT CAN1_RX0_IRQHandler [WEAK]
+ EXPORT CAN1_RX1_IRQHandler [WEAK]
+ EXPORT CAN1_SCE_IRQHandler [WEAK]
+ EXPORT EXTI9_5_IRQHandler [WEAK]
+ EXPORT TIM1_BRK_IRQHandler [WEAK]
+ EXPORT TIM1_UP_IRQHandler [WEAK]
+ EXPORT TIM1_TRG_COM_IRQHandler [WEAK]
+ EXPORT TIM1_CC_IRQHandler [WEAK]
+ EXPORT TIM2_IRQHandler [WEAK]
+ EXPORT TIM3_IRQHandler [WEAK]
+ EXPORT TIM4_IRQHandler [WEAK]
+ EXPORT I2C1_EV_IRQHandler [WEAK]
+ EXPORT I2C1_ER_IRQHandler [WEAK]
+ EXPORT I2C2_EV_IRQHandler [WEAK]
+ EXPORT I2C2_ER_IRQHandler [WEAK]
+ EXPORT SPI1_IRQHandler [WEAK]
+ EXPORT SPI2_IRQHandler [WEAK]
+ EXPORT USART1_IRQHandler [WEAK]
+ EXPORT USART2_IRQHandler [WEAK]
+ EXPORT USART3_IRQHandler [WEAK]
+ EXPORT EXTI15_10_IRQHandler [WEAK]
+ EXPORT RTC_Alarm_IRQHandler [WEAK]
+ EXPORT OTG_FS_WKUP_IRQHandler [WEAK]
+ EXPORT TIM5_IRQHandler [WEAK]
+ EXPORT SPI3_IRQHandler [WEAK]
+ EXPORT UART4_IRQHandler [WEAK]
+ EXPORT UART5_IRQHandler [WEAK]
+ EXPORT TIM6_IRQHandler [WEAK]
+ EXPORT TIM7_IRQHandler [WEAK]
+ EXPORT DMA2_Channel1_IRQHandler [WEAK]
+ EXPORT DMA2_Channel2_IRQHandler [WEAK]
+ EXPORT DMA2_Channel3_IRQHandler [WEAK]
+ EXPORT DMA2_Channel4_IRQHandler [WEAK]
+ EXPORT DMA2_Channel5_IRQHandler [WEAK]
+ EXPORT ETH_IRQHandler [WEAK]
+ EXPORT ETH_WKUP_IRQHandler [WEAK]
+ EXPORT CAN2_TX_IRQHandler [WEAK]
+ EXPORT CAN2_RX0_IRQHandler [WEAK]
+ EXPORT CAN2_RX1_IRQHandler [WEAK]
+ EXPORT CAN2_SCE_IRQHandler [WEAK]
+ EXPORT OTG_FS_IRQHandler [WEAK]
+
+WWDG_IRQHandler
+PVD_IRQHandler
+TAMPER_IRQHandler
+RTC_IRQHandler
+FLASH_IRQHandler
+RCC_IRQHandler
+EXTI0_IRQHandler
+EXTI1_IRQHandler
+EXTI2_IRQHandler
+EXTI3_IRQHandler
+EXTI4_IRQHandler
+DMA1_Channel1_IRQHandler
+DMA1_Channel2_IRQHandler
+DMA1_Channel3_IRQHandler
+DMA1_Channel4_IRQHandler
+DMA1_Channel5_IRQHandler
+DMA1_Channel6_IRQHandler
+DMA1_Channel7_IRQHandler
+ADC1_2_IRQHandler
+CAN1_TX_IRQHandler
+CAN1_RX0_IRQHandler
+CAN1_RX1_IRQHandler
+CAN1_SCE_IRQHandler
+EXTI9_5_IRQHandler
+TIM1_BRK_IRQHandler
+TIM1_UP_IRQHandler
+TIM1_TRG_COM_IRQHandler
+TIM1_CC_IRQHandler
+TIM2_IRQHandler
+TIM3_IRQHandler
+TIM4_IRQHandler
+I2C1_EV_IRQHandler
+I2C1_ER_IRQHandler
+I2C2_EV_IRQHandler
+I2C2_ER_IRQHandler
+SPI1_IRQHandler
+SPI2_IRQHandler
+USART1_IRQHandler
+USART2_IRQHandler
+USART3_IRQHandler
+EXTI15_10_IRQHandler
+RTC_Alarm_IRQHandler
+OTG_FS_WKUP_IRQHandler
+TIM5_IRQHandler
+SPI3_IRQHandler
+UART4_IRQHandler
+UART5_IRQHandler
+TIM6_IRQHandler
+TIM7_IRQHandler
+DMA2_Channel1_IRQHandler
+DMA2_Channel2_IRQHandler
+DMA2_Channel3_IRQHandler
+DMA2_Channel4_IRQHandler
+DMA2_Channel5_IRQHandler
+ETH_IRQHandler
+ETH_WKUP_IRQHandler
+CAN2_TX_IRQHandler
+CAN2_RX0_IRQHandler
+CAN2_RX1_IRQHandler
+CAN2_SCE_IRQHandler
+OTG_FS_IRQHandler
+
+ B .
+
+ ENDP
+
+ ALIGN
+
+;*******************************************************************************
+; User Stack and Heap initialization
+;*******************************************************************************
+ IF :DEF:__MICROLIB
+
+ EXPORT __initial_sp
+ EXPORT __heap_base
+ EXPORT __heap_limit
+
+ ELSE
+
+ IMPORT __use_two_region_memory
+ EXPORT __user_initial_stackheap
+
+__user_initial_stackheap
+
+ LDR R0, = Heap_Mem
+ LDR R1, =(Stack_Mem + Stack_Size)
+ LDR R2, = (Heap_Mem + Heap_Size)
+ LDR R3, = Stack_Mem
+ BX LR
+
+ ALIGN
+
+ ENDIF
+
+ END
+
+;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f100xb.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f100xb.s
new file mode 100644
index 0000000..fbf19b7
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f100xb.s
@@ -0,0 +1,422 @@
+/**
+ *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
+ * @file startup_stm32f100xb.s
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @brief STM32F100xB Devices vector table for Atollic toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Configure the clock system
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M3 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m3
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+
+.equ BootRAM, 0xF108F85F
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ *
+ * @param None
+ * @retval : None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler
+ .word PVD_IRQHandler
+ .word TAMPER_IRQHandler
+ .word RTC_IRQHandler
+ .word FLASH_IRQHandler
+ .word RCC_IRQHandler
+ .word EXTI0_IRQHandler
+ .word EXTI1_IRQHandler
+ .word EXTI2_IRQHandler
+ .word EXTI3_IRQHandler
+ .word EXTI4_IRQHandler
+ .word DMA1_Channel1_IRQHandler
+ .word DMA1_Channel2_IRQHandler
+ .word DMA1_Channel3_IRQHandler
+ .word DMA1_Channel4_IRQHandler
+ .word DMA1_Channel5_IRQHandler
+ .word DMA1_Channel6_IRQHandler
+ .word DMA1_Channel7_IRQHandler
+ .word ADC1_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word EXTI9_5_IRQHandler
+ .word TIM1_BRK_TIM15_IRQHandler
+ .word TIM1_UP_TIM16_IRQHandler
+ .word TIM1_TRG_COM_TIM17_IRQHandler
+ .word TIM1_CC_IRQHandler
+ .word TIM2_IRQHandler
+ .word TIM3_IRQHandler
+ .word TIM4_IRQHandler
+ .word I2C1_EV_IRQHandler
+ .word I2C1_ER_IRQHandler
+ .word I2C2_EV_IRQHandler
+ .word I2C2_ER_IRQHandler
+ .word SPI1_IRQHandler
+ .word SPI2_IRQHandler
+ .word USART1_IRQHandler
+ .word USART2_IRQHandler
+ .word USART3_IRQHandler
+ .word EXTI15_10_IRQHandler
+ .word RTC_Alarm_IRQHandler
+ .word CEC_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word TIM6_DAC_IRQHandler
+ .word TIM7_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word BootRAM /* @0x01CC. This is for boot in RAM mode for
+ STM32F10xB Value Line devices. */
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+
+
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMPER_IRQHandler
+ .thumb_set TAMPER_IRQHandler,Default_Handler
+
+ .weak RTC_IRQHandler
+ .thumb_set RTC_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_IRQHandler
+ .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel3_IRQHandler
+ .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_IRQHandler
+ .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel5_IRQHandler
+ .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel6_IRQHandler
+ .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel7_IRQHandler
+ .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
+
+ .weak ADC1_IRQHandler
+ .thumb_set ADC1_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM1_BRK_TIM15_IRQHandler
+ .thumb_set TIM1_BRK_TIM15_IRQHandler,Default_Handler
+
+ .weak TIM1_UP_TIM16_IRQHandler
+ .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler
+
+ .weak TIM1_TRG_COM_TIM17_IRQHandler
+ .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler
+
+ .weak TIM1_CC_IRQHandler
+ .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak USART3_IRQHandler
+ .thumb_set USART3_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak CEC_IRQHandler
+ .thumb_set CEC_IRQHandler,Default_Handler
+
+ .weak TIM6_DAC_IRQHandler
+ .thumb_set TIM6_DAC_IRQHandler,Default_Handler
+
+ .weak TIM7_IRQHandler
+ .thumb_set TIM7_IRQHandler,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f100xe.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f100xe.s
new file mode 100644
index 0000000..1159ddf
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f100xe.s
@@ -0,0 +1,464 @@
+/**
+ *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
+ * @file startup_stm32f100xe.s
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @brief STM32F100xE Devices vector table for Atollic toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Configure the clock system
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M3 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m3
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+
+.equ BootRAM, 0xF108F85F
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ *
+ * @param None
+ * @retval : None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler
+ .word PVD_IRQHandler
+ .word TAMPER_IRQHandler
+ .word RTC_IRQHandler
+ .word FLASH_IRQHandler
+ .word RCC_IRQHandler
+ .word EXTI0_IRQHandler
+ .word EXTI1_IRQHandler
+ .word EXTI2_IRQHandler
+ .word EXTI3_IRQHandler
+ .word EXTI4_IRQHandler
+ .word DMA1_Channel1_IRQHandler
+ .word DMA1_Channel2_IRQHandler
+ .word DMA1_Channel3_IRQHandler
+ .word DMA1_Channel4_IRQHandler
+ .word DMA1_Channel5_IRQHandler
+ .word DMA1_Channel6_IRQHandler
+ .word DMA1_Channel7_IRQHandler
+ .word ADC1_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word EXTI9_5_IRQHandler
+ .word TIM1_BRK_TIM15_IRQHandler
+ .word TIM1_UP_TIM16_IRQHandler
+ .word TIM1_TRG_COM_TIM17_IRQHandler
+ .word TIM1_CC_IRQHandler
+ .word TIM2_IRQHandler
+ .word TIM3_IRQHandler
+ .word TIM4_IRQHandler
+ .word I2C1_EV_IRQHandler
+ .word I2C1_ER_IRQHandler
+ .word I2C2_EV_IRQHandler
+ .word I2C2_ER_IRQHandler
+ .word SPI1_IRQHandler
+ .word SPI2_IRQHandler
+ .word USART1_IRQHandler
+ .word USART2_IRQHandler
+ .word USART3_IRQHandler
+ .word EXTI15_10_IRQHandler
+ .word RTC_Alarm_IRQHandler
+ .word CEC_IRQHandler
+ .word TIM12_IRQHandler
+ .word TIM13_IRQHandler
+ .word TIM14_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word TIM5_IRQHandler
+ .word SPI3_IRQHandler
+ .word UART4_IRQHandler
+ .word UART5_IRQHandler
+ .word TIM6_DAC_IRQHandler
+ .word TIM7_IRQHandler
+ .word DMA2_Channel1_IRQHandler
+ .word DMA2_Channel2_IRQHandler
+ .word DMA2_Channel3_IRQHandler
+ .word DMA2_Channel4_5_IRQHandler
+ .word DMA2_Channel5_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word BootRAM /* @0x1E0. This is for boot in RAM mode for
+ STM32F10x High Density Value line devices. */
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+
+
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMPER_IRQHandler
+ .thumb_set TAMPER_IRQHandler,Default_Handler
+
+ .weak RTC_IRQHandler
+ .thumb_set RTC_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_IRQHandler
+ .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel3_IRQHandler
+ .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_IRQHandler
+ .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel5_IRQHandler
+ .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel6_IRQHandler
+ .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel7_IRQHandler
+ .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
+
+ .weak ADC1_IRQHandler
+ .thumb_set ADC1_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM1_BRK_TIM15_IRQHandler
+ .thumb_set TIM1_BRK_TIM15_IRQHandler,Default_Handler
+
+ .weak TIM1_UP_TIM16_IRQHandler
+ .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler
+
+ .weak TIM1_TRG_COM_TIM17_IRQHandler
+ .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler
+
+ .weak TIM1_CC_IRQHandler
+ .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak USART3_IRQHandler
+ .thumb_set USART3_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak CEC_IRQHandler
+ .thumb_set CEC_IRQHandler,Default_Handler
+
+ .weak TIM12_IRQHandler
+ .thumb_set TIM12_IRQHandler,Default_Handler
+
+ .weak TIM13_IRQHandler
+ .thumb_set TIM13_IRQHandler,Default_Handler
+
+ .weak TIM14_IRQHandler
+ .thumb_set TIM14_IRQHandler,Default_Handler
+
+ .weak TIM5_IRQHandler
+ .thumb_set TIM5_IRQHandler,Default_Handler
+
+ .weak SPI3_IRQHandler
+ .thumb_set SPI3_IRQHandler,Default_Handler
+
+ .weak UART4_IRQHandler
+ .thumb_set UART4_IRQHandler,Default_Handler
+
+ .weak UART5_IRQHandler
+ .thumb_set UART5_IRQHandler,Default_Handler
+
+ .weak TIM6_DAC_IRQHandler
+ .thumb_set TIM6_DAC_IRQHandler,Default_Handler
+
+ .weak TIM7_IRQHandler
+ .thumb_set TIM7_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel1_IRQHandler
+ .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel2_IRQHandler
+ .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel3_IRQHandler
+ .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel4_5_IRQHandler
+ .thumb_set DMA2_Channel4_5_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel5_IRQHandler
+ .thumb_set DMA2_Channel5_IRQHandler,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101x6.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101x6.s
new file mode 100644
index 0000000..07915af
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101x6.s
@@ -0,0 +1,337 @@
+/**
+ *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
+ * @file startup_stm32f101x6.s
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @brief STM32F101x6 Devices vector table for Atollic toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Configure the clock system
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M3 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m3
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+
+.equ BootRAM, 0xF108F85F
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ *
+ * @param None
+ * @retval : None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+
+
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler
+ .word PVD_IRQHandler
+ .word TAMPER_IRQHandler
+ .word RTC_IRQHandler
+ .word FLASH_IRQHandler
+ .word RCC_IRQHandler
+ .word EXTI0_IRQHandler
+ .word EXTI1_IRQHandler
+ .word EXTI2_IRQHandler
+ .word EXTI3_IRQHandler
+ .word EXTI4_IRQHandler
+ .word DMA1_Channel1_IRQHandler
+ .word DMA1_Channel2_IRQHandler
+ .word DMA1_Channel3_IRQHandler
+ .word DMA1_Channel4_IRQHandler
+ .word DMA1_Channel5_IRQHandler
+ .word DMA1_Channel6_IRQHandler
+ .word DMA1_Channel7_IRQHandler
+ .word ADC1_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word EXTI9_5_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word TIM2_IRQHandler
+ .word TIM3_IRQHandler
+ .word 0
+ .word I2C1_EV_IRQHandler
+ .word I2C1_ER_IRQHandler
+ .word 0
+ .word 0
+ .word SPI1_IRQHandler
+ .word 0
+ .word USART1_IRQHandler
+ .word USART2_IRQHandler
+ .word 0
+ .word EXTI15_10_IRQHandler
+ .word RTC_Alarm_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word BootRAM /* @0x108. This is for boot in RAM mode for
+ STM32F10x Low Density devices.*/
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMPER_IRQHandler
+ .thumb_set TAMPER_IRQHandler,Default_Handler
+
+ .weak RTC_IRQHandler
+ .thumb_set RTC_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_IRQHandler
+ .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel3_IRQHandler
+ .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_IRQHandler
+ .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel5_IRQHandler
+ .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel6_IRQHandler
+ .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel7_IRQHandler
+ .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
+
+ .weak ADC1_IRQHandler
+ .thumb_set ADC1_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101xb.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101xb.s
new file mode 100644
index 0000000..52b3297
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101xb.s
@@ -0,0 +1,353 @@
+/**
+ *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
+ * @file startup_stm32f101xb.s
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @brief STM32F101xB Devices vector table for Atollic toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Configure the clock system
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M3 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m3
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+
+.equ BootRAM, 0xF108F85F
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ *
+ * @param None
+ * @retval : None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler
+ .word PVD_IRQHandler
+ .word TAMPER_IRQHandler
+ .word RTC_IRQHandler
+ .word FLASH_IRQHandler
+ .word RCC_IRQHandler
+ .word EXTI0_IRQHandler
+ .word EXTI1_IRQHandler
+ .word EXTI2_IRQHandler
+ .word EXTI3_IRQHandler
+ .word EXTI4_IRQHandler
+ .word DMA1_Channel1_IRQHandler
+ .word DMA1_Channel2_IRQHandler
+ .word DMA1_Channel3_IRQHandler
+ .word DMA1_Channel4_IRQHandler
+ .word DMA1_Channel5_IRQHandler
+ .word DMA1_Channel6_IRQHandler
+ .word DMA1_Channel7_IRQHandler
+ .word ADC1_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word EXTI9_5_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word TIM2_IRQHandler
+ .word TIM3_IRQHandler
+ .word TIM4_IRQHandler
+ .word I2C1_EV_IRQHandler
+ .word I2C1_ER_IRQHandler
+ .word I2C2_EV_IRQHandler
+ .word I2C2_ER_IRQHandler
+ .word SPI1_IRQHandler
+ .word SPI2_IRQHandler
+ .word USART1_IRQHandler
+ .word USART2_IRQHandler
+ .word USART3_IRQHandler
+ .word EXTI15_10_IRQHandler
+ .word RTC_Alarm_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word BootRAM /* @0x108. This is for boot in RAM mode for
+ STM32F10x Medium Density devices. */
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMPER_IRQHandler
+ .thumb_set TAMPER_IRQHandler,Default_Handler
+
+ .weak RTC_IRQHandler
+ .thumb_set RTC_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_IRQHandler
+ .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel3_IRQHandler
+ .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_IRQHandler
+ .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel5_IRQHandler
+ .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel6_IRQHandler
+ .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel7_IRQHandler
+ .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
+
+ .weak ADC1_IRQHandler
+ .thumb_set ADC1_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak USART3_IRQHandler
+ .thumb_set USART3_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101xe.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101xe.s
new file mode 100644
index 0000000..f4aefc2
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101xe.s
@@ -0,0 +1,438 @@
+/**
+ *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
+ * @file startup_stm32f101xe.s
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @brief STM32F101xE Value Line Devices vector table for Atollic toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Configure the clock system
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M3 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m3
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+
+.equ BootRAM, 0xF1E0F85F
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ *
+ * @param None
+ * @retval : None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler
+ .word PVD_IRQHandler
+ .word TAMPER_IRQHandler
+ .word RTC_IRQHandler
+ .word FLASH_IRQHandler
+ .word RCC_IRQHandler
+ .word EXTI0_IRQHandler
+ .word EXTI1_IRQHandler
+ .word EXTI2_IRQHandler
+ .word EXTI3_IRQHandler
+ .word EXTI4_IRQHandler
+ .word DMA1_Channel1_IRQHandler
+ .word DMA1_Channel2_IRQHandler
+ .word DMA1_Channel3_IRQHandler
+ .word DMA1_Channel4_IRQHandler
+ .word DMA1_Channel5_IRQHandler
+ .word DMA1_Channel6_IRQHandler
+ .word DMA1_Channel7_IRQHandler
+ .word ADC1_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word EXTI9_5_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word TIM2_IRQHandler
+ .word TIM3_IRQHandler
+ .word TIM4_IRQHandler
+ .word I2C1_EV_IRQHandler
+ .word I2C1_ER_IRQHandler
+ .word I2C2_EV_IRQHandler
+ .word I2C2_ER_IRQHandler
+ .word SPI1_IRQHandler
+ .word SPI2_IRQHandler
+ .word USART1_IRQHandler
+ .word USART2_IRQHandler
+ .word USART3_IRQHandler
+ .word EXTI15_10_IRQHandler
+ .word RTC_Alarm_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word FSMC_IRQHandler
+ .word 0
+ .word TIM5_IRQHandler
+ .word SPI3_IRQHandler
+ .word UART4_IRQHandler
+ .word UART5_IRQHandler
+ .word TIM6_IRQHandler
+ .word TIM7_IRQHandler
+ .word DMA2_Channel1_IRQHandler
+ .word DMA2_Channel2_IRQHandler
+ .word DMA2_Channel3_IRQHandler
+ .word DMA2_Channel4_5_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word BootRAM /* @0x1E0. This is for boot in RAM mode for
+ STM32F10x High Density devices. */
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMPER_IRQHandler
+ .thumb_set TAMPER_IRQHandler,Default_Handler
+
+ .weak RTC_IRQHandler
+ .thumb_set RTC_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_IRQHandler
+ .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel3_IRQHandler
+ .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_IRQHandler
+ .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel5_IRQHandler
+ .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel6_IRQHandler
+ .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel7_IRQHandler
+ .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
+
+ .weak ADC1_IRQHandler
+ .thumb_set ADC1_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak USART3_IRQHandler
+ .thumb_set USART3_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak FSMC_IRQHandler
+ .thumb_set FSMC_IRQHandler,Default_Handler
+
+ .weak TIM5_IRQHandler
+ .thumb_set TIM5_IRQHandler,Default_Handler
+
+ .weak SPI3_IRQHandler
+ .thumb_set SPI3_IRQHandler,Default_Handler
+
+ .weak UART4_IRQHandler
+ .thumb_set UART4_IRQHandler,Default_Handler
+
+ .weak UART5_IRQHandler
+ .thumb_set UART5_IRQHandler,Default_Handler
+
+ .weak TIM6_IRQHandler
+ .thumb_set TIM6_IRQHandler,Default_Handler
+
+ .weak TIM7_IRQHandler
+ .thumb_set TIM7_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel1_IRQHandler
+ .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel2_IRQHandler
+ .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel3_IRQHandler
+ .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel4_5_IRQHandler
+ .thumb_set DMA2_Channel4_5_IRQHandler,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101xg.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101xg.s
new file mode 100644
index 0000000..7e79d0c
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f101xg.s
@@ -0,0 +1,454 @@
+/**
+ *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
+ * @file startup_stm32f101xg.s
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @brief STM32F101xG Devices vector table for Atollic toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Configure the clock system
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M3 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m3
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+
+.equ BootRAM, 0xF1E0F85F
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ * @param None
+ * @retval None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler
+ .word PVD_IRQHandler
+ .word TAMPER_IRQHandler
+ .word RTC_IRQHandler
+ .word FLASH_IRQHandler
+ .word RCC_IRQHandler
+ .word EXTI0_IRQHandler
+ .word EXTI1_IRQHandler
+ .word EXTI2_IRQHandler
+ .word EXTI3_IRQHandler
+ .word EXTI4_IRQHandler
+ .word DMA1_Channel1_IRQHandler
+ .word DMA1_Channel2_IRQHandler
+ .word DMA1_Channel3_IRQHandler
+ .word DMA1_Channel4_IRQHandler
+ .word DMA1_Channel5_IRQHandler
+ .word DMA1_Channel6_IRQHandler
+ .word DMA1_Channel7_IRQHandler
+ .word ADC1_2_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word EXTI9_5_IRQHandler
+ .word TIM9_IRQHandler
+ .word TIM10_IRQHandler
+ .word TIM11_IRQHandler
+ .word 0
+ .word TIM2_IRQHandler
+ .word TIM3_IRQHandler
+ .word TIM4_IRQHandler
+ .word I2C1_EV_IRQHandler
+ .word I2C1_ER_IRQHandler
+ .word I2C2_EV_IRQHandler
+ .word I2C2_ER_IRQHandler
+ .word SPI1_IRQHandler
+ .word SPI2_IRQHandler
+ .word USART1_IRQHandler
+ .word USART2_IRQHandler
+ .word USART3_IRQHandler
+ .word EXTI15_10_IRQHandler
+ .word RTC_Alarm_IRQHandler
+ .word 0
+ .word TIM12_IRQHandler
+ .word TIM13_IRQHandler
+ .word TIM14_IRQHandler
+ .word 0
+ .word 0
+ .word FSMC_IRQHandler
+ .word 0
+ .word TIM5_IRQHandler
+ .word SPI3_IRQHandler
+ .word UART4_IRQHandler
+ .word UART5_IRQHandler
+ .word TIM6_IRQHandler
+ .word TIM7_IRQHandler
+ .word DMA2_Channel1_IRQHandler
+ .word DMA2_Channel2_IRQHandler
+ .word DMA2_Channel3_IRQHandler
+ .word DMA2_Channel4_5_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word BootRAM /* @0x1E0. This is for boot in RAM mode for
+ STM32F10x XL-Density devices. */
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMPER_IRQHandler
+ .thumb_set TAMPER_IRQHandler,Default_Handler
+
+ .weak RTC_IRQHandler
+ .thumb_set RTC_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_IRQHandler
+ .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel3_IRQHandler
+ .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_IRQHandler
+ .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel5_IRQHandler
+ .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel6_IRQHandler
+ .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel7_IRQHandler
+ .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
+
+ .weak ADC1_2_IRQHandler
+ .thumb_set ADC1_2_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM9_IRQHandler
+ .thumb_set TIM9_IRQHandler,Default_Handler
+
+ .weak TIM10_IRQHandler
+ .thumb_set TIM10_IRQHandler,Default_Handler
+
+ .weak TIM11_IRQHandler
+ .thumb_set TIM11_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak USART3_IRQHandler
+ .thumb_set USART3_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak TIM12_IRQHandler
+ .thumb_set TIM12_IRQHandler,Default_Handler
+
+ .weak TIM13_IRQHandler
+ .thumb_set TIM13_IRQHandler,Default_Handler
+
+ .weak TIM14_IRQHandler
+ .thumb_set TIM14_IRQHandler,Default_Handler
+
+ .weak FSMC_IRQHandler
+ .thumb_set FSMC_IRQHandler,Default_Handler
+
+ .weak TIM5_IRQHandler
+ .thumb_set TIM5_IRQHandler,Default_Handler
+
+ .weak SPI3_IRQHandler
+ .thumb_set SPI3_IRQHandler,Default_Handler
+
+ .weak UART4_IRQHandler
+ .thumb_set UART4_IRQHandler,Default_Handler
+
+ .weak UART5_IRQHandler
+ .thumb_set UART5_IRQHandler,Default_Handler
+
+ .weak TIM6_IRQHandler
+ .thumb_set TIM6_IRQHandler,Default_Handler
+
+ .weak TIM7_IRQHandler
+ .thumb_set TIM7_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel1_IRQHandler
+ .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel2_IRQHandler
+ .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel3_IRQHandler
+ .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel4_5_IRQHandler
+ .thumb_set DMA2_Channel4_5_IRQHandler,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f102x6.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f102x6.s
new file mode 100644
index 0000000..219c326
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f102x6.s
@@ -0,0 +1,345 @@
+/**
+ *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
+ * @file startup_stm32f102x6.s
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @brief STM32F102x6 Devices vector table for Atollic toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Configure the clock system
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M3 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m3
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+
+.equ BootRAM, 0xF108F85F
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ *
+ * @param None
+ * @retval : None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler
+ .word PVD_IRQHandler
+ .word TAMPER_IRQHandler
+ .word RTC_IRQHandler
+ .word FLASH_IRQHandler
+ .word RCC_IRQHandler
+ .word EXTI0_IRQHandler
+ .word EXTI1_IRQHandler
+ .word EXTI2_IRQHandler
+ .word EXTI3_IRQHandler
+ .word EXTI4_IRQHandler
+ .word DMA1_Channel1_IRQHandler
+ .word DMA1_Channel2_IRQHandler
+ .word DMA1_Channel3_IRQHandler
+ .word DMA1_Channel4_IRQHandler
+ .word DMA1_Channel5_IRQHandler
+ .word DMA1_Channel6_IRQHandler
+ .word DMA1_Channel7_IRQHandler
+ .word ADC1_IRQHandler
+ .word USB_HP_IRQHandler
+ .word USB_LP_IRQHandler
+ .word 0
+ .word 0
+ .word EXTI9_5_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word TIM2_IRQHandler
+ .word TIM3_IRQHandler
+ .word 0
+ .word I2C1_EV_IRQHandler
+ .word I2C1_ER_IRQHandler
+ .word 0
+ .word 0
+ .word SPI1_IRQHandler
+ .word 0
+ .word USART1_IRQHandler
+ .word USART2_IRQHandler
+ .word 0
+ .word EXTI15_10_IRQHandler
+ .word RTC_Alarm_IRQHandler
+ .word USBWakeUp_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word BootRAM /* @0x108. This is for boot in RAM mode for
+ STM32F10x Low Density devices.*/
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMPER_IRQHandler
+ .thumb_set TAMPER_IRQHandler,Default_Handler
+
+ .weak RTC_IRQHandler
+ .thumb_set RTC_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_IRQHandler
+ .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel3_IRQHandler
+ .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_IRQHandler
+ .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel5_IRQHandler
+ .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel6_IRQHandler
+ .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel7_IRQHandler
+ .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
+
+ .weak ADC1_IRQHandler
+ .thumb_set ADC1_IRQHandler,Default_Handler
+
+ .weak USB_HP_IRQHandler
+ .thumb_set USB_HP_IRQHandler,Default_Handler
+
+ .weak USB_LP_IRQHandler
+ .thumb_set USB_LP_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak USBWakeUp_IRQHandler
+ .thumb_set USBWakeUp_IRQHandler,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f102xb.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f102xb.s
new file mode 100644
index 0000000..2372c69
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f102xb.s
@@ -0,0 +1,361 @@
+/**
+ *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
+ * @file startup_stm32f102xb.s
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @brief STM32F102xB Value Line Devices vector table for Atollic toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Configure the clock system
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M3 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m3
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+
+.equ BootRAM, 0xF108F85F
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ *
+ * @param None
+ * @retval : None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler
+ .word PVD_IRQHandler
+ .word TAMPER_IRQHandler
+ .word RTC_IRQHandler
+ .word FLASH_IRQHandler
+ .word RCC_IRQHandler
+ .word EXTI0_IRQHandler
+ .word EXTI1_IRQHandler
+ .word EXTI2_IRQHandler
+ .word EXTI3_IRQHandler
+ .word EXTI4_IRQHandler
+ .word DMA1_Channel1_IRQHandler
+ .word DMA1_Channel2_IRQHandler
+ .word DMA1_Channel3_IRQHandler
+ .word DMA1_Channel4_IRQHandler
+ .word DMA1_Channel5_IRQHandler
+ .word DMA1_Channel6_IRQHandler
+ .word DMA1_Channel7_IRQHandler
+ .word ADC1_IRQHandler
+ .word USB_HP_IRQHandler
+ .word USB_LP_IRQHandler
+ .word 0
+ .word 0
+ .word EXTI9_5_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word TIM2_IRQHandler
+ .word TIM3_IRQHandler
+ .word TIM4_IRQHandler
+ .word I2C1_EV_IRQHandler
+ .word I2C1_ER_IRQHandler
+ .word I2C2_EV_IRQHandler
+ .word I2C2_ER_IRQHandler
+ .word SPI1_IRQHandler
+ .word SPI2_IRQHandler
+ .word USART1_IRQHandler
+ .word USART2_IRQHandler
+ .word USART3_IRQHandler
+ .word EXTI15_10_IRQHandler
+ .word RTC_Alarm_IRQHandler
+ .word USBWakeUp_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word BootRAM /* @0x108. This is for boot in RAM mode for
+ STM32F10x Medium Density devices. */
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMPER_IRQHandler
+ .thumb_set TAMPER_IRQHandler,Default_Handler
+
+ .weak RTC_IRQHandler
+ .thumb_set RTC_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_IRQHandler
+ .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel3_IRQHandler
+ .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_IRQHandler
+ .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel5_IRQHandler
+ .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel6_IRQHandler
+ .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel7_IRQHandler
+ .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
+
+ .weak ADC1_IRQHandler
+ .thumb_set ADC1_IRQHandler,Default_Handler
+
+ .weak USB_HP_IRQHandler
+ .thumb_set USB_HP_IRQHandler,Default_Handler
+
+ .weak USB_LP_IRQHandler
+ .thumb_set USB_LP_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak USART3_IRQHandler
+ .thumb_set USART3_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak USBWakeUp_IRQHandler
+ .thumb_set USBWakeUp_IRQHandler,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103x6.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103x6.s
new file mode 100644
index 0000000..1e033fb
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103x6.s
@@ -0,0 +1,363 @@
+/**
+ *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
+ * @file startup_stm32f103x6.s
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @brief STM32F103x6 Devices vector table for Atollic toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Configure the clock system
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M3 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m3
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+
+.equ BootRAM, 0xF108F85F
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ *
+ * @param None
+ * @retval : None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler
+ .word PVD_IRQHandler
+ .word TAMPER_IRQHandler
+ .word RTC_IRQHandler
+ .word FLASH_IRQHandler
+ .word RCC_IRQHandler
+ .word EXTI0_IRQHandler
+ .word EXTI1_IRQHandler
+ .word EXTI2_IRQHandler
+ .word EXTI3_IRQHandler
+ .word EXTI4_IRQHandler
+ .word DMA1_Channel1_IRQHandler
+ .word DMA1_Channel2_IRQHandler
+ .word DMA1_Channel3_IRQHandler
+ .word DMA1_Channel4_IRQHandler
+ .word DMA1_Channel5_IRQHandler
+ .word DMA1_Channel6_IRQHandler
+ .word DMA1_Channel7_IRQHandler
+ .word ADC1_2_IRQHandler
+ .word USB_HP_CAN1_TX_IRQHandler
+ .word USB_LP_CAN1_RX0_IRQHandler
+ .word CAN1_RX1_IRQHandler
+ .word CAN1_SCE_IRQHandler
+ .word EXTI9_5_IRQHandler
+ .word TIM1_BRK_IRQHandler
+ .word TIM1_UP_IRQHandler
+ .word TIM1_TRG_COM_IRQHandler
+ .word TIM1_CC_IRQHandler
+ .word TIM2_IRQHandler
+ .word TIM3_IRQHandler
+ .word 0
+ .word I2C1_EV_IRQHandler
+ .word I2C1_ER_IRQHandler
+ .word 0
+ .word 0
+ .word SPI1_IRQHandler
+ .word 0
+ .word USART1_IRQHandler
+ .word USART2_IRQHandler
+ .word 0
+ .word EXTI15_10_IRQHandler
+ .word RTC_Alarm_IRQHandler
+ .word USBWakeUp_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word BootRAM /* @0x108. This is for boot in RAM mode for
+ STM32F10x Low Density devices.*/
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMPER_IRQHandler
+ .thumb_set TAMPER_IRQHandler,Default_Handler
+
+ .weak RTC_IRQHandler
+ .thumb_set RTC_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_IRQHandler
+ .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel3_IRQHandler
+ .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_IRQHandler
+ .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel5_IRQHandler
+ .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel6_IRQHandler
+ .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel7_IRQHandler
+ .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
+
+ .weak ADC1_2_IRQHandler
+ .thumb_set ADC1_2_IRQHandler,Default_Handler
+
+ .weak USB_HP_CAN1_TX_IRQHandler
+ .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
+
+ .weak USB_LP_CAN1_RX0_IRQHandler
+ .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
+
+ .weak CAN1_RX1_IRQHandler
+ .thumb_set CAN1_RX1_IRQHandler,Default_Handler
+
+ .weak CAN1_SCE_IRQHandler
+ .thumb_set CAN1_SCE_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM1_BRK_IRQHandler
+ .thumb_set TIM1_BRK_IRQHandler,Default_Handler
+
+ .weak TIM1_UP_IRQHandler
+ .thumb_set TIM1_UP_IRQHandler,Default_Handler
+
+ .weak TIM1_TRG_COM_IRQHandler
+ .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
+
+ .weak TIM1_CC_IRQHandler
+ .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak USBWakeUp_IRQHandler
+ .thumb_set USBWakeUp_IRQHandler,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xb.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xb.s
new file mode 100644
index 0000000..1bdd524
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xb.s
@@ -0,0 +1,379 @@
+/**
+ *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
+ * @file startup_stm32f103xb.s
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @brief STM32F103xB Devices vector table for Atollic toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Configure the clock system
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M3 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m3
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+
+.equ BootRAM, 0xF108F85F
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ *
+ * @param None
+ * @retval : None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler
+ .word PVD_IRQHandler
+ .word TAMPER_IRQHandler
+ .word RTC_IRQHandler
+ .word FLASH_IRQHandler
+ .word RCC_IRQHandler
+ .word EXTI0_IRQHandler
+ .word EXTI1_IRQHandler
+ .word EXTI2_IRQHandler
+ .word EXTI3_IRQHandler
+ .word EXTI4_IRQHandler
+ .word DMA1_Channel1_IRQHandler
+ .word DMA1_Channel2_IRQHandler
+ .word DMA1_Channel3_IRQHandler
+ .word DMA1_Channel4_IRQHandler
+ .word DMA1_Channel5_IRQHandler
+ .word DMA1_Channel6_IRQHandler
+ .word DMA1_Channel7_IRQHandler
+ .word ADC1_2_IRQHandler
+ .word USB_HP_CAN1_TX_IRQHandler
+ .word USB_LP_CAN1_RX0_IRQHandler
+ .word CAN1_RX1_IRQHandler
+ .word CAN1_SCE_IRQHandler
+ .word EXTI9_5_IRQHandler
+ .word TIM1_BRK_IRQHandler
+ .word TIM1_UP_IRQHandler
+ .word TIM1_TRG_COM_IRQHandler
+ .word TIM1_CC_IRQHandler
+ .word TIM2_IRQHandler
+ .word TIM3_IRQHandler
+ .word TIM4_IRQHandler
+ .word I2C1_EV_IRQHandler
+ .word I2C1_ER_IRQHandler
+ .word I2C2_EV_IRQHandler
+ .word I2C2_ER_IRQHandler
+ .word SPI1_IRQHandler
+ .word SPI2_IRQHandler
+ .word USART1_IRQHandler
+ .word USART2_IRQHandler
+ .word USART3_IRQHandler
+ .word EXTI15_10_IRQHandler
+ .word RTC_Alarm_IRQHandler
+ .word USBWakeUp_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word BootRAM /* @0x108. This is for boot in RAM mode for
+ STM32F10x Medium Density devices. */
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMPER_IRQHandler
+ .thumb_set TAMPER_IRQHandler,Default_Handler
+
+ .weak RTC_IRQHandler
+ .thumb_set RTC_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_IRQHandler
+ .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel3_IRQHandler
+ .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_IRQHandler
+ .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel5_IRQHandler
+ .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel6_IRQHandler
+ .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel7_IRQHandler
+ .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
+
+ .weak ADC1_2_IRQHandler
+ .thumb_set ADC1_2_IRQHandler,Default_Handler
+
+ .weak USB_HP_CAN1_TX_IRQHandler
+ .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
+
+ .weak USB_LP_CAN1_RX0_IRQHandler
+ .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
+
+ .weak CAN1_RX1_IRQHandler
+ .thumb_set CAN1_RX1_IRQHandler,Default_Handler
+
+ .weak CAN1_SCE_IRQHandler
+ .thumb_set CAN1_SCE_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM1_BRK_IRQHandler
+ .thumb_set TIM1_BRK_IRQHandler,Default_Handler
+
+ .weak TIM1_UP_IRQHandler
+ .thumb_set TIM1_UP_IRQHandler,Default_Handler
+
+ .weak TIM1_TRG_COM_IRQHandler
+ .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
+
+ .weak TIM1_CC_IRQHandler
+ .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak USART3_IRQHandler
+ .thumb_set USART3_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak USBWakeUp_IRQHandler
+ .thumb_set USBWakeUp_IRQHandler,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xe.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xe.s
new file mode 100644
index 0000000..0727d65
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xe.s
@@ -0,0 +1,485 @@
+/**
+ *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
+ * @file startup_stm32f103xe.s
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @brief STM32F103xE Devices vector table for Atollic toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Configure the clock system
+ * - Configure external SRAM mounted on STM3210E-EVAL board
+ * to be used as data memory (optional, to be enabled by user)
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M3 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m3
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+
+.equ BootRAM, 0xF1E0F85F
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ *
+ * @param None
+ * @retval : None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler
+ .word PVD_IRQHandler
+ .word TAMPER_IRQHandler
+ .word RTC_IRQHandler
+ .word FLASH_IRQHandler
+ .word RCC_IRQHandler
+ .word EXTI0_IRQHandler
+ .word EXTI1_IRQHandler
+ .word EXTI2_IRQHandler
+ .word EXTI3_IRQHandler
+ .word EXTI4_IRQHandler
+ .word DMA1_Channel1_IRQHandler
+ .word DMA1_Channel2_IRQHandler
+ .word DMA1_Channel3_IRQHandler
+ .word DMA1_Channel4_IRQHandler
+ .word DMA1_Channel5_IRQHandler
+ .word DMA1_Channel6_IRQHandler
+ .word DMA1_Channel7_IRQHandler
+ .word ADC1_2_IRQHandler
+ .word USB_HP_CAN1_TX_IRQHandler
+ .word USB_LP_CAN1_RX0_IRQHandler
+ .word CAN1_RX1_IRQHandler
+ .word CAN1_SCE_IRQHandler
+ .word EXTI9_5_IRQHandler
+ .word TIM1_BRK_IRQHandler
+ .word TIM1_UP_IRQHandler
+ .word TIM1_TRG_COM_IRQHandler
+ .word TIM1_CC_IRQHandler
+ .word TIM2_IRQHandler
+ .word TIM3_IRQHandler
+ .word TIM4_IRQHandler
+ .word I2C1_EV_IRQHandler
+ .word I2C1_ER_IRQHandler
+ .word I2C2_EV_IRQHandler
+ .word I2C2_ER_IRQHandler
+ .word SPI1_IRQHandler
+ .word SPI2_IRQHandler
+ .word USART1_IRQHandler
+ .word USART2_IRQHandler
+ .word USART3_IRQHandler
+ .word EXTI15_10_IRQHandler
+ .word RTC_Alarm_IRQHandler
+ .word USBWakeUp_IRQHandler
+ .word TIM8_BRK_IRQHandler
+ .word TIM8_UP_IRQHandler
+ .word TIM8_TRG_COM_IRQHandler
+ .word TIM8_CC_IRQHandler
+ .word ADC3_IRQHandler
+ .word FSMC_IRQHandler
+ .word SDIO_IRQHandler
+ .word TIM5_IRQHandler
+ .word SPI3_IRQHandler
+ .word UART4_IRQHandler
+ .word UART5_IRQHandler
+ .word TIM6_IRQHandler
+ .word TIM7_IRQHandler
+ .word DMA2_Channel1_IRQHandler
+ .word DMA2_Channel2_IRQHandler
+ .word DMA2_Channel3_IRQHandler
+ .word DMA2_Channel4_5_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word BootRAM /* @0x1E0. This is for boot in RAM mode for
+ STM32F10x High Density devices. */
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMPER_IRQHandler
+ .thumb_set TAMPER_IRQHandler,Default_Handler
+
+ .weak RTC_IRQHandler
+ .thumb_set RTC_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_IRQHandler
+ .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel3_IRQHandler
+ .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_IRQHandler
+ .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel5_IRQHandler
+ .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel6_IRQHandler
+ .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel7_IRQHandler
+ .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
+
+ .weak ADC1_2_IRQHandler
+ .thumb_set ADC1_2_IRQHandler,Default_Handler
+
+ .weak USB_HP_CAN1_TX_IRQHandler
+ .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
+
+ .weak USB_LP_CAN1_RX0_IRQHandler
+ .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
+
+ .weak CAN1_RX1_IRQHandler
+ .thumb_set CAN1_RX1_IRQHandler,Default_Handler
+
+ .weak CAN1_SCE_IRQHandler
+ .thumb_set CAN1_SCE_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM1_BRK_IRQHandler
+ .thumb_set TIM1_BRK_IRQHandler,Default_Handler
+
+ .weak TIM1_UP_IRQHandler
+ .thumb_set TIM1_UP_IRQHandler,Default_Handler
+
+ .weak TIM1_TRG_COM_IRQHandler
+ .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
+
+ .weak TIM1_CC_IRQHandler
+ .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak USART3_IRQHandler
+ .thumb_set USART3_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak USBWakeUp_IRQHandler
+ .thumb_set USBWakeUp_IRQHandler,Default_Handler
+
+ .weak TIM8_BRK_IRQHandler
+ .thumb_set TIM8_BRK_IRQHandler,Default_Handler
+
+ .weak TIM8_UP_IRQHandler
+ .thumb_set TIM8_UP_IRQHandler,Default_Handler
+
+ .weak TIM8_TRG_COM_IRQHandler
+ .thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler
+
+ .weak TIM8_CC_IRQHandler
+ .thumb_set TIM8_CC_IRQHandler,Default_Handler
+
+ .weak ADC3_IRQHandler
+ .thumb_set ADC3_IRQHandler,Default_Handler
+
+ .weak FSMC_IRQHandler
+ .thumb_set FSMC_IRQHandler,Default_Handler
+
+ .weak SDIO_IRQHandler
+ .thumb_set SDIO_IRQHandler,Default_Handler
+
+ .weak TIM5_IRQHandler
+ .thumb_set TIM5_IRQHandler,Default_Handler
+
+ .weak SPI3_IRQHandler
+ .thumb_set SPI3_IRQHandler,Default_Handler
+
+ .weak UART4_IRQHandler
+ .thumb_set UART4_IRQHandler,Default_Handler
+
+ .weak UART5_IRQHandler
+ .thumb_set UART5_IRQHandler,Default_Handler
+
+ .weak TIM6_IRQHandler
+ .thumb_set TIM6_IRQHandler,Default_Handler
+
+ .weak TIM7_IRQHandler
+ .thumb_set TIM7_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel1_IRQHandler
+ .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel2_IRQHandler
+ .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel3_IRQHandler
+ .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel4_5_IRQHandler
+ .thumb_set DMA2_Channel4_5_IRQHandler,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xg.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xg.s
new file mode 100644
index 0000000..1ae0faf
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xg.s
@@ -0,0 +1,482 @@
+/**
+ *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
+ * @file startup_stm32f103xb.s
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @brief STM32F103xB Devices vector table for Atollic toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Configure the clock system
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M3 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m3
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+
+.equ BootRAM, 0xF1E0F85F
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ * @param None
+ * @retval None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+*******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler
+ .word PVD_IRQHandler
+ .word TAMPER_IRQHandler
+ .word RTC_IRQHandler
+ .word FLASH_IRQHandler
+ .word RCC_IRQHandler
+ .word EXTI0_IRQHandler
+ .word EXTI1_IRQHandler
+ .word EXTI2_IRQHandler
+ .word EXTI3_IRQHandler
+ .word EXTI4_IRQHandler
+ .word DMA1_Channel1_IRQHandler
+ .word DMA1_Channel2_IRQHandler
+ .word DMA1_Channel3_IRQHandler
+ .word DMA1_Channel4_IRQHandler
+ .word DMA1_Channel5_IRQHandler
+ .word DMA1_Channel6_IRQHandler
+ .word DMA1_Channel7_IRQHandler
+ .word ADC1_2_IRQHandler
+ .word USB_HP_CAN1_TX_IRQHandler
+ .word USB_LP_CAN1_RX0_IRQHandler
+ .word CAN1_RX1_IRQHandler
+ .word CAN1_SCE_IRQHandler
+ .word EXTI9_5_IRQHandler
+ .word TIM1_BRK_TIM9_IRQHandler
+ .word TIM1_UP_TIM10_IRQHandler
+ .word TIM1_TRG_COM_TIM11_IRQHandler
+ .word TIM1_CC_IRQHandler
+ .word TIM2_IRQHandler
+ .word TIM3_IRQHandler
+ .word TIM4_IRQHandler
+ .word I2C1_EV_IRQHandler
+ .word I2C1_ER_IRQHandler
+ .word I2C2_EV_IRQHandler
+ .word I2C2_ER_IRQHandler
+ .word SPI1_IRQHandler
+ .word SPI2_IRQHandler
+ .word USART1_IRQHandler
+ .word USART2_IRQHandler
+ .word USART3_IRQHandler
+ .word EXTI15_10_IRQHandler
+ .word RTC_Alarm_IRQHandler
+ .word USBWakeUp_IRQHandler
+ .word TIM8_BRK_TIM12_IRQHandler
+ .word TIM8_UP_TIM13_IRQHandler
+ .word TIM8_TRG_COM_TIM14_IRQHandler
+ .word TIM8_CC_IRQHandler
+ .word ADC3_IRQHandler
+ .word FSMC_IRQHandler
+ .word SDIO_IRQHandler
+ .word TIM5_IRQHandler
+ .word SPI3_IRQHandler
+ .word UART4_IRQHandler
+ .word UART5_IRQHandler
+ .word TIM6_IRQHandler
+ .word TIM7_IRQHandler
+ .word DMA2_Channel1_IRQHandler
+ .word DMA2_Channel2_IRQHandler
+ .word DMA2_Channel3_IRQHandler
+ .word DMA2_Channel4_5_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word BootRAM /* @0x1E0. This is for boot in RAM mode for
+ STM32F10x XL-Density devices. */
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMPER_IRQHandler
+ .thumb_set TAMPER_IRQHandler,Default_Handler
+
+ .weak RTC_IRQHandler
+ .thumb_set RTC_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_IRQHandler
+ .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel3_IRQHandler
+ .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_IRQHandler
+ .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel5_IRQHandler
+ .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel6_IRQHandler
+ .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel7_IRQHandler
+ .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
+
+ .weak ADC1_2_IRQHandler
+ .thumb_set ADC1_2_IRQHandler,Default_Handler
+
+ .weak USB_HP_CAN1_TX_IRQHandler
+ .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
+
+ .weak USB_LP_CAN1_RX0_IRQHandler
+ .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
+
+ .weak CAN1_RX1_IRQHandler
+ .thumb_set CAN1_RX1_IRQHandler,Default_Handler
+
+ .weak CAN1_SCE_IRQHandler
+ .thumb_set CAN1_SCE_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM1_BRK_TIM9_IRQHandler
+ .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler
+
+ .weak TIM1_UP_TIM10_IRQHandler
+ .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler
+
+ .weak TIM1_TRG_COM_TIM11_IRQHandler
+ .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler
+
+ .weak TIM1_CC_IRQHandler
+ .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak USART3_IRQHandler
+ .thumb_set USART3_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak USBWakeUp_IRQHandler
+ .thumb_set USBWakeUp_IRQHandler,Default_Handler
+
+ .weak TIM8_BRK_TIM12_IRQHandler
+ .thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler
+
+ .weak TIM8_UP_TIM13_IRQHandler
+ .thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler
+
+ .weak TIM8_TRG_COM_TIM14_IRQHandler
+ .thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler
+
+ .weak TIM8_CC_IRQHandler
+ .thumb_set TIM8_CC_IRQHandler,Default_Handler
+
+ .weak ADC3_IRQHandler
+ .thumb_set ADC3_IRQHandler,Default_Handler
+
+ .weak FSMC_IRQHandler
+ .thumb_set FSMC_IRQHandler,Default_Handler
+
+ .weak SDIO_IRQHandler
+ .thumb_set SDIO_IRQHandler,Default_Handler
+
+ .weak TIM5_IRQHandler
+ .thumb_set TIM5_IRQHandler,Default_Handler
+
+ .weak SPI3_IRQHandler
+ .thumb_set SPI3_IRQHandler,Default_Handler
+
+ .weak UART4_IRQHandler
+ .thumb_set UART4_IRQHandler,Default_Handler
+
+ .weak UART5_IRQHandler
+ .thumb_set UART5_IRQHandler,Default_Handler
+
+ .weak TIM6_IRQHandler
+ .thumb_set TIM6_IRQHandler,Default_Handler
+
+ .weak TIM7_IRQHandler
+ .thumb_set TIM7_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel1_IRQHandler
+ .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel2_IRQHandler
+ .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel3_IRQHandler
+ .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel4_5_IRQHandler
+ .thumb_set DMA2_Channel4_5_IRQHandler,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f105xc.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f105xc.s
new file mode 100644
index 0000000..dc57f1d
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f105xc.s
@@ -0,0 +1,476 @@
+/**
+ *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
+ * @file startup_stm32f105xc.s
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @brief STM32F105xC Devices vector table for Atollic toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Configure the clock system
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M3 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m3
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+
+.equ BootRAM, 0xF1E0F85F
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ * @param None
+ * @retval None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler
+ .word PVD_IRQHandler
+ .word TAMPER_IRQHandler
+ .word RTC_IRQHandler
+ .word FLASH_IRQHandler
+ .word RCC_IRQHandler
+ .word EXTI0_IRQHandler
+ .word EXTI1_IRQHandler
+ .word EXTI2_IRQHandler
+ .word EXTI3_IRQHandler
+ .word EXTI4_IRQHandler
+ .word DMA1_Channel1_IRQHandler
+ .word DMA1_Channel2_IRQHandler
+ .word DMA1_Channel3_IRQHandler
+ .word DMA1_Channel4_IRQHandler
+ .word DMA1_Channel5_IRQHandler
+ .word DMA1_Channel6_IRQHandler
+ .word DMA1_Channel7_IRQHandler
+ .word ADC1_2_IRQHandler
+ .word CAN1_TX_IRQHandler
+ .word CAN1_RX0_IRQHandler
+ .word CAN1_RX1_IRQHandler
+ .word CAN1_SCE_IRQHandler
+ .word EXTI9_5_IRQHandler
+ .word TIM1_BRK_IRQHandler
+ .word TIM1_UP_IRQHandler
+ .word TIM1_TRG_COM_IRQHandler
+ .word TIM1_CC_IRQHandler
+ .word TIM2_IRQHandler
+ .word TIM3_IRQHandler
+ .word TIM4_IRQHandler
+ .word I2C1_EV_IRQHandler
+ .word I2C1_ER_IRQHandler
+ .word I2C2_EV_IRQHandler
+ .word I2C2_ER_IRQHandler
+ .word SPI1_IRQHandler
+ .word SPI2_IRQHandler
+ .word USART1_IRQHandler
+ .word USART2_IRQHandler
+ .word USART3_IRQHandler
+ .word EXTI15_10_IRQHandler
+ .word RTC_Alarm_IRQHandler
+ .word OTG_FS_WKUP_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word TIM5_IRQHandler
+ .word SPI3_IRQHandler
+ .word UART4_IRQHandler
+ .word UART5_IRQHandler
+ .word TIM6_IRQHandler
+ .word TIM7_IRQHandler
+ .word DMA2_Channel1_IRQHandler
+ .word DMA2_Channel2_IRQHandler
+ .word DMA2_Channel3_IRQHandler
+ .word DMA2_Channel4_IRQHandler
+ .word DMA2_Channel5_IRQHandler
+ .word 0
+ .word 0
+ .word CAN2_TX_IRQHandler
+ .word CAN2_RX0_IRQHandler
+ .word CAN2_RX1_IRQHandler
+ .word CAN2_SCE_IRQHandler
+ .word OTG_FS_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word BootRAM /* @0x1E0. This is for boot in RAM mode for
+ STM32F10x Connectivity line Devices. */
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMPER_IRQHandler
+ .thumb_set TAMPER_IRQHandler,Default_Handler
+
+ .weak RTC_IRQHandler
+ .thumb_set RTC_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_IRQHandler
+ .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel3_IRQHandler
+ .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_IRQHandler
+ .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel5_IRQHandler
+ .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel6_IRQHandler
+ .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel7_IRQHandler
+ .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
+
+ .weak ADC1_2_IRQHandler
+ .thumb_set ADC1_2_IRQHandler,Default_Handler
+
+ .weak CAN1_TX_IRQHandler
+ .thumb_set CAN1_TX_IRQHandler,Default_Handler
+
+ .weak CAN1_RX0_IRQHandler
+ .thumb_set CAN1_RX0_IRQHandler,Default_Handler
+
+ .weak CAN1_RX1_IRQHandler
+ .thumb_set CAN1_RX1_IRQHandler,Default_Handler
+
+ .weak CAN1_SCE_IRQHandler
+ .thumb_set CAN1_SCE_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM1_BRK_IRQHandler
+ .thumb_set TIM1_BRK_IRQHandler,Default_Handler
+
+ .weak TIM1_UP_IRQHandler
+ .thumb_set TIM1_UP_IRQHandler,Default_Handler
+
+ .weak TIM1_TRG_COM_IRQHandler
+ .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
+
+ .weak TIM1_CC_IRQHandler
+ .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak USART3_IRQHandler
+ .thumb_set USART3_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak OTG_FS_WKUP_IRQHandler
+ .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
+
+ .weak TIM5_IRQHandler
+ .thumb_set TIM5_IRQHandler,Default_Handler
+
+ .weak SPI3_IRQHandler
+ .thumb_set SPI3_IRQHandler,Default_Handler
+
+ .weak UART4_IRQHandler
+ .thumb_set UART4_IRQHandler,Default_Handler
+
+ .weak UART5_IRQHandler
+ .thumb_set UART5_IRQHandler,Default_Handler
+
+ .weak TIM6_IRQHandler
+ .thumb_set TIM6_IRQHandler,Default_Handler
+
+ .weak TIM7_IRQHandler
+ .thumb_set TIM7_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel1_IRQHandler
+ .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel2_IRQHandler
+ .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel3_IRQHandler
+ .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel4_IRQHandler
+ .thumb_set DMA2_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel5_IRQHandler
+ .thumb_set DMA2_Channel5_IRQHandler,Default_Handler
+
+ .weak CAN2_TX_IRQHandler
+ .thumb_set CAN2_TX_IRQHandler,Default_Handler
+
+ .weak CAN2_RX0_IRQHandler
+ .thumb_set CAN2_RX0_IRQHandler,Default_Handler
+
+ .weak CAN2_RX1_IRQHandler
+ .thumb_set CAN2_RX1_IRQHandler,Default_Handler
+
+ .weak CAN2_SCE_IRQHandler
+ .thumb_set CAN2_SCE_IRQHandler,Default_Handler
+
+ .weak OTG_FS_IRQHandler
+ .thumb_set OTG_FS_IRQHandler ,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f107xc.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f107xc.s
new file mode 100644
index 0000000..35bf316
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f107xc.s
@@ -0,0 +1,487 @@
+/**
+ *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
+ * @file startup_stm32f107xc.s
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @brief STM32F107xC Devices vector table for Atollic toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Configure the clock system
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M3 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m3
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+
+.equ BootRAM, 0xF1E0F85F
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ *
+ * @param None
+ * @retval : None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler
+ .word PVD_IRQHandler
+ .word TAMPER_IRQHandler
+ .word RTC_IRQHandler
+ .word FLASH_IRQHandler
+ .word RCC_IRQHandler
+ .word EXTI0_IRQHandler
+ .word EXTI1_IRQHandler
+ .word EXTI2_IRQHandler
+ .word EXTI3_IRQHandler
+ .word EXTI4_IRQHandler
+ .word DMA1_Channel1_IRQHandler
+ .word DMA1_Channel2_IRQHandler
+ .word DMA1_Channel3_IRQHandler
+ .word DMA1_Channel4_IRQHandler
+ .word DMA1_Channel5_IRQHandler
+ .word DMA1_Channel6_IRQHandler
+ .word DMA1_Channel7_IRQHandler
+ .word ADC1_2_IRQHandler
+ .word CAN1_TX_IRQHandler
+ .word CAN1_RX0_IRQHandler
+ .word CAN1_RX1_IRQHandler
+ .word CAN1_SCE_IRQHandler
+ .word EXTI9_5_IRQHandler
+ .word TIM1_BRK_IRQHandler
+ .word TIM1_UP_IRQHandler
+ .word TIM1_TRG_COM_IRQHandler
+ .word TIM1_CC_IRQHandler
+ .word TIM2_IRQHandler
+ .word TIM3_IRQHandler
+ .word TIM4_IRQHandler
+ .word I2C1_EV_IRQHandler
+ .word I2C1_ER_IRQHandler
+ .word I2C2_EV_IRQHandler
+ .word I2C2_ER_IRQHandler
+ .word SPI1_IRQHandler
+ .word SPI2_IRQHandler
+ .word USART1_IRQHandler
+ .word USART2_IRQHandler
+ .word USART3_IRQHandler
+ .word EXTI15_10_IRQHandler
+ .word RTC_Alarm_IRQHandler
+ .word OTG_FS_WKUP_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word TIM5_IRQHandler
+ .word SPI3_IRQHandler
+ .word UART4_IRQHandler
+ .word UART5_IRQHandler
+ .word TIM6_IRQHandler
+ .word TIM7_IRQHandler
+ .word DMA2_Channel1_IRQHandler
+ .word DMA2_Channel2_IRQHandler
+ .word DMA2_Channel3_IRQHandler
+ .word DMA2_Channel4_IRQHandler
+ .word DMA2_Channel5_IRQHandler
+ .word ETH_IRQHandler
+ .word ETH_WKUP_IRQHandler
+ .word CAN2_TX_IRQHandler
+ .word CAN2_RX0_IRQHandler
+ .word CAN2_RX1_IRQHandler
+ .word CAN2_SCE_IRQHandler
+ .word OTG_FS_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word BootRAM /* @0x1E0. This is for boot in RAM mode for
+ STM32F10x Connectivity line Devices. */
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMPER_IRQHandler
+ .thumb_set TAMPER_IRQHandler,Default_Handler
+
+ .weak RTC_IRQHandler
+ .thumb_set RTC_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_IRQHandler
+ .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel3_IRQHandler
+ .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_IRQHandler
+ .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel5_IRQHandler
+ .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel6_IRQHandler
+ .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel7_IRQHandler
+ .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
+
+ .weak ADC1_2_IRQHandler
+ .thumb_set ADC1_2_IRQHandler,Default_Handler
+
+ .weak CAN1_TX_IRQHandler
+ .thumb_set CAN1_TX_IRQHandler,Default_Handler
+
+ .weak CAN1_RX0_IRQHandler
+ .thumb_set CAN1_RX0_IRQHandler,Default_Handler
+
+ .weak CAN1_RX1_IRQHandler
+ .thumb_set CAN1_RX1_IRQHandler,Default_Handler
+
+ .weak CAN1_SCE_IRQHandler
+ .thumb_set CAN1_SCE_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM1_BRK_IRQHandler
+ .thumb_set TIM1_BRK_IRQHandler,Default_Handler
+
+ .weak TIM1_UP_IRQHandler
+ .thumb_set TIM1_UP_IRQHandler,Default_Handler
+
+ .weak TIM1_TRG_COM_IRQHandler
+ .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
+
+ .weak TIM1_CC_IRQHandler
+ .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak USART3_IRQHandler
+ .thumb_set USART3_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak OTG_FS_WKUP_IRQHandler
+ .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
+
+ .weak TIM5_IRQHandler
+ .thumb_set TIM5_IRQHandler,Default_Handler
+
+ .weak SPI3_IRQHandler
+ .thumb_set SPI3_IRQHandler,Default_Handler
+
+ .weak UART4_IRQHandler
+ .thumb_set UART4_IRQHandler,Default_Handler
+
+ .weak UART5_IRQHandler
+ .thumb_set UART5_IRQHandler,Default_Handler
+
+ .weak TIM6_IRQHandler
+ .thumb_set TIM6_IRQHandler,Default_Handler
+
+ .weak TIM7_IRQHandler
+ .thumb_set TIM7_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel1_IRQHandler
+ .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel2_IRQHandler
+ .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel3_IRQHandler
+ .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel4_IRQHandler
+ .thumb_set DMA2_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel5_IRQHandler
+ .thumb_set DMA2_Channel5_IRQHandler,Default_Handler
+
+ .weak ETH_IRQHandler
+ .thumb_set ETH_IRQHandler,Default_Handler
+
+ .weak ETH_WKUP_IRQHandler
+ .thumb_set ETH_WKUP_IRQHandler,Default_Handler
+
+ .weak CAN2_TX_IRQHandler
+ .thumb_set CAN2_TX_IRQHandler,Default_Handler
+
+ .weak CAN2_RX0_IRQHandler
+ .thumb_set CAN2_RX0_IRQHandler,Default_Handler
+
+ .weak CAN2_RX1_IRQHandler
+ .thumb_set CAN2_RX1_IRQHandler,Default_Handler
+
+ .weak CAN2_SCE_IRQHandler
+ .thumb_set CAN2_SCE_IRQHandler,Default_Handler
+
+ .weak OTG_FS_IRQHandler
+ .thumb_set OTG_FS_IRQHandler ,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xb_flash.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xb_flash.icf
new file mode 100644
index 0000000..b2a0288
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xb_flash.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x0801FFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20001FFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xb_sram.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xb_sram.icf
new file mode 100644
index 0000000..539a865
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xb_sram.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x20000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20001FFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xe_flash.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xe_flash.icf
new file mode 100644
index 0000000..aeb5671
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xe_flash.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x0807FFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xe_sram.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xe_sram.icf
new file mode 100644
index 0000000..65a054a
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f100xe_sram.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x20000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101x6_flash.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101x6_flash.icf
new file mode 100644
index 0000000..6cee5e9
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101x6_flash.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x08007FFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x200017FF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101x6_sram.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101x6_sram.icf
new file mode 100644
index 0000000..8165db3
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101x6_sram.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x20000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
+define symbol __ICFEDIT_region_RAM_end__ = 0x200017FF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xb_flash.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xb_flash.icf
new file mode 100644
index 0000000..9f1b2b2
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xb_flash.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x0801FFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20003FFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xb_sram.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xb_sram.icf
new file mode 100644
index 0000000..182c24e
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xb_sram.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x20000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20003FFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xe_flash.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xe_flash.icf
new file mode 100644
index 0000000..80f772a
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xe_flash.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x0807FFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x2000BFFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xe_sram.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xe_sram.icf
new file mode 100644
index 0000000..d0afe5e
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xe_sram.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x20000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
+define symbol __ICFEDIT_region_RAM_end__ = 0x2000BFFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xg_flash.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xg_flash.icf
new file mode 100644
index 0000000..874cd64
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xg_flash.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x080FFFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20013FFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xg_sram.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xg_sram.icf
new file mode 100644
index 0000000..e0faa07
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f101xg_sram.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x20000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20013FFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102x6_flash.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102x6_flash.icf
new file mode 100644
index 0000000..6cee5e9
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102x6_flash.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x08007FFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x200017FF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102x6_sram.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102x6_sram.icf
new file mode 100644
index 0000000..8165db3
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102x6_sram.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x20000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
+define symbol __ICFEDIT_region_RAM_end__ = 0x200017FF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102xb_flash.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102xb_flash.icf
new file mode 100644
index 0000000..9f1b2b2
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102xb_flash.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x0801FFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20003FFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102xb_sram.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102xb_sram.icf
new file mode 100644
index 0000000..182c24e
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f102xb_sram.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x20000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20003FFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103x6_flash.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103x6_flash.icf
new file mode 100644
index 0000000..a2b392d
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103x6_flash.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x08007FFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x200027FF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103x6_sram.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103x6_sram.icf
new file mode 100644
index 0000000..5588236
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103x6_sram.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x20000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
+define symbol __ICFEDIT_region_RAM_end__ = 0x200027FF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xb_flash.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xb_flash.icf
new file mode 100644
index 0000000..7d8ef19
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xb_flash.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x0801FFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20004FFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xb_sram.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xb_sram.icf
new file mode 100644
index 0000000..4207bc5
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xb_sram.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x20000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20004FFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xe_flash.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xe_flash.icf
new file mode 100644
index 0000000..a042ad4
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xe_flash.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x0807FFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xe_sram.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xe_sram.icf
new file mode 100644
index 0000000..a9335b5
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xe_sram.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x20000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
+define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xg_flash.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xg_flash.icf
new file mode 100644
index 0000000..1e71d00
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xg_flash.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x080FFFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20017FFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xg_sram.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xg_sram.icf
new file mode 100644
index 0000000..4a15dac
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f103xg_sram.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x20000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20017FFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f105xc_flash.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f105xc_flash.icf
new file mode 100644
index 0000000..a96235f
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f105xc_flash.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x0803FFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f105xc_sram.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f105xc_sram.icf
new file mode 100644
index 0000000..a9335b5
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f105xc_sram.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x20000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
+define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f107xc_flash.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f107xc_flash.icf
new file mode 100644
index 0000000..a96235f
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f107xc_flash.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x0803FFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f107xc_sram.icf b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f107xc_sram.icf
new file mode 100644
index 0000000..a9335b5
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/linker/stm32f107xc_sram.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x20000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x20000000 ;
+define symbol __ICFEDIT_region_ROM_end__ = 0x200013FF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20001400;
+define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x400;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f100xb.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f100xb.s
new file mode 100644
index 0000000..27c7ab4
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f100xb.s
@@ -0,0 +1,413 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f100xb.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F100xB Value Line Devices vector table
+;* for EWARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Configure the clock system
+;* - Set the initial PC == __iar_program_start,
+;* - Set the vector table entries with the exceptions ISR
+;* address.
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;*
+;*******************************************************************************
+;
+;
+; The modules in this file are included in the libraries, and may be replaced
+; by any user-defined modules that define the PUBLIC symbol _program_start or
+; a user defined start symbol.
+; To override the cstartup defined in the library, simply add your modified
+; version to the workbench project.
+;
+; The vector table is normally located at address 0.
+; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
+; The name "__vector_table" has special meaning for C-SPY:
+; it is where the SP start value is found, and the NVIC vector
+; table register (VTOR) is initialized to this address if != 0.
+;
+; Cortex-M version
+;
+
+ MODULE ?cstartup
+
+ ;; Forward declaration of sections.
+ SECTION CSTACK:DATA:NOROOT(3)
+
+ SECTION .intvec:CODE:NOROOT(2)
+
+ EXTERN __iar_program_start
+ EXTERN SystemInit
+ PUBLIC __vector_table
+
+ DATA
+__vector_table
+ DCD sfe(CSTACK)
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_IRQHandler ; ADC1
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD TIM1_BRK_TIM15_IRQHandler ; TIM1 Break and TIM15
+ DCD TIM1_UP_TIM16_IRQHandler ; TIM1 Update and TIM16
+ DCD TIM1_TRG_COM_TIM17_IRQHandler ; TIM1 Trigger and Commutation and TIM17
+ DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C2 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD CEC_IRQHandler ; HDMI-CEC
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD TIM6_DAC_IRQHandler ; TIM6 and DAC underrun
+ DCD TIM7_IRQHandler ; TIM7
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Default interrupt handlers.
+;;
+ THUMB
+
+ PUBWEAK Reset_Handler
+ SECTION .text:CODE:REORDER:NOROOT(2)
+Reset_Handler
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__iar_program_start
+ BX R0
+
+ PUBWEAK NMI_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+NMI_Handler
+ B NMI_Handler
+
+ PUBWEAK HardFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+HardFault_Handler
+ B HardFault_Handler
+
+ PUBWEAK MemManage_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+MemManage_Handler
+ B MemManage_Handler
+
+ PUBWEAK BusFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+BusFault_Handler
+ B BusFault_Handler
+
+ PUBWEAK UsageFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UsageFault_Handler
+ B UsageFault_Handler
+
+ PUBWEAK SVC_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SVC_Handler
+ B SVC_Handler
+
+ PUBWEAK DebugMon_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DebugMon_Handler
+ B DebugMon_Handler
+
+ PUBWEAK PendSV_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PendSV_Handler
+ B PendSV_Handler
+
+ PUBWEAK SysTick_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SysTick_Handler
+ B SysTick_Handler
+
+ PUBWEAK WWDG_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+WWDG_IRQHandler
+ B WWDG_IRQHandler
+
+ PUBWEAK PVD_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PVD_IRQHandler
+ B PVD_IRQHandler
+
+ PUBWEAK TAMPER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TAMPER_IRQHandler
+ B TAMPER_IRQHandler
+
+ PUBWEAK RTC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_IRQHandler
+ B RTC_IRQHandler
+
+ PUBWEAK FLASH_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+FLASH_IRQHandler
+ B FLASH_IRQHandler
+
+ PUBWEAK RCC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RCC_IRQHandler
+ B RCC_IRQHandler
+
+ PUBWEAK EXTI0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI0_IRQHandler
+ B EXTI0_IRQHandler
+
+ PUBWEAK EXTI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI1_IRQHandler
+ B EXTI1_IRQHandler
+
+ PUBWEAK EXTI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI2_IRQHandler
+ B EXTI2_IRQHandler
+
+ PUBWEAK EXTI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI3_IRQHandler
+ B EXTI3_IRQHandler
+
+ PUBWEAK EXTI4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI4_IRQHandler
+ B EXTI4_IRQHandler
+
+ PUBWEAK DMA1_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel1_IRQHandler
+ B DMA1_Channel1_IRQHandler
+
+ PUBWEAK DMA1_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel2_IRQHandler
+ B DMA1_Channel2_IRQHandler
+
+ PUBWEAK DMA1_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel3_IRQHandler
+ B DMA1_Channel3_IRQHandler
+
+ PUBWEAK DMA1_Channel4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel4_IRQHandler
+ B DMA1_Channel4_IRQHandler
+
+ PUBWEAK DMA1_Channel5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel5_IRQHandler
+ B DMA1_Channel5_IRQHandler
+
+ PUBWEAK DMA1_Channel6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel6_IRQHandler
+ B DMA1_Channel6_IRQHandler
+
+ PUBWEAK DMA1_Channel7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel7_IRQHandler
+ B DMA1_Channel7_IRQHandler
+
+ PUBWEAK ADC1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ADC1_IRQHandler
+ B ADC1_IRQHandler
+
+ PUBWEAK EXTI9_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI9_5_IRQHandler
+ B EXTI9_5_IRQHandler
+
+ PUBWEAK TIM1_BRK_TIM15_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_BRK_TIM15_IRQHandler
+ B TIM1_BRK_TIM15_IRQHandler
+
+ PUBWEAK TIM1_UP_TIM16_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_UP_TIM16_IRQHandler
+ B TIM1_UP_TIM16_IRQHandler
+
+ PUBWEAK TIM1_TRG_COM_TIM17_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_TRG_COM_TIM17_IRQHandler
+ B TIM1_TRG_COM_TIM17_IRQHandler
+
+ PUBWEAK TIM1_CC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_CC_IRQHandler
+ B TIM1_CC_IRQHandler
+
+ PUBWEAK TIM2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM2_IRQHandler
+ B TIM2_IRQHandler
+
+ PUBWEAK TIM3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM3_IRQHandler
+ B TIM3_IRQHandler
+
+ PUBWEAK TIM4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM4_IRQHandler
+ B TIM4_IRQHandler
+
+ PUBWEAK I2C1_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_EV_IRQHandler
+ B I2C1_EV_IRQHandler
+
+ PUBWEAK I2C1_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_ER_IRQHandler
+ B I2C1_ER_IRQHandler
+
+ PUBWEAK I2C2_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_EV_IRQHandler
+ B I2C2_EV_IRQHandler
+
+ PUBWEAK I2C2_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_ER_IRQHandler
+ B I2C2_ER_IRQHandler
+
+ PUBWEAK SPI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI1_IRQHandler
+ B SPI1_IRQHandler
+
+ PUBWEAK SPI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI2_IRQHandler
+ B SPI2_IRQHandler
+
+ PUBWEAK USART1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART1_IRQHandler
+ B USART1_IRQHandler
+
+ PUBWEAK USART2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART2_IRQHandler
+ B USART2_IRQHandler
+
+ PUBWEAK USART3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART3_IRQHandler
+ B USART3_IRQHandler
+
+ PUBWEAK EXTI15_10_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI15_10_IRQHandler
+ B EXTI15_10_IRQHandler
+
+ PUBWEAK RTC_Alarm_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_Alarm_IRQHandler
+ B RTC_Alarm_IRQHandler
+
+ PUBWEAK CEC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CEC_IRQHandler
+ B CEC_IRQHandler
+
+ PUBWEAK TIM6_DAC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM6_DAC_IRQHandler
+ B TIM6_DAC_IRQHandler
+
+ PUBWEAK TIM7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM7_IRQHandler
+ B TIM7_IRQHandler
+
+ END
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f100xe.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f100xe.s
new file mode 100644
index 0000000..abc9d4b
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f100xe.s
@@ -0,0 +1,479 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f100xe.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F100xE Value Line Devices vector table
+;* for EWARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == __iar_program_start,
+;* - Set the vector table entries with the exceptions ISR
+;* address.
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;*
+;*******************************************************************************
+;
+;
+; The modules in this file are included in the libraries, and may be replaced
+; by any user-defined modules that define the PUBLIC symbol _program_start or
+; a user defined start symbol.
+; To override the cstartup defined in the library, simply add your modified
+; version to the workbench project.
+;
+; The vector table is normally located at address 0.
+; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
+; The name "__vector_table" has special meaning for C-SPY:
+; it is where the SP start value is found, and the NVIC vector
+; table register (VTOR) is initialized to this address if != 0.
+;
+; Cortex-M version
+;
+
+ MODULE ?cstartup
+
+ ;; Forward declaration of sections.
+ SECTION CSTACK:DATA:NOROOT(3)
+
+ SECTION .intvec:CODE:NOROOT(2)
+
+ EXTERN __iar_program_start
+ EXTERN SystemInit
+ PUBLIC __vector_table
+
+ DATA
+__vector_table
+ DCD sfe(CSTACK)
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_IRQHandler ; ADC1
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD TIM1_BRK_TIM15_IRQHandler ; TIM1 Break and TIM15
+ DCD TIM1_UP_TIM16_IRQHandler ; TIM1 Update and TIM16
+ DCD TIM1_TRG_COM_TIM17_IRQHandler ; TIM1 Trigger and Commutation and TIM17
+ DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C2 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD CEC_IRQHandler ; HDMI CEC
+ DCD TIM12_IRQHandler ; TIM12
+ DCD TIM13_IRQHandler ; TIM13
+ DCD TIM14_IRQHandler ; TIM14
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD TIM5_IRQHandler ; TIM5
+ DCD SPI3_IRQHandler ; SPI3
+ DCD UART4_IRQHandler ; UART4
+ DCD UART5_IRQHandler ; UART5
+ DCD TIM6_DAC_IRQHandler ; TIM6 and DAC underrun
+ DCD TIM7_IRQHandler ; TIM7
+ DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
+ DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
+ DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
+ DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5 if MISC_REMAP is not set
+ ; or DMA2 Channel4 if MISC_REMAP is set
+ DCD DMA2_Channel5_IRQHandler ; DMA2 Channel5 if MISC_REMAP is set
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Default interrupt handlers.
+;;
+ THUMB
+
+ PUBWEAK Reset_Handler
+ SECTION .text:CODE:REORDER:NOROOT(2)
+Reset_Handler
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__iar_program_start
+ BX R0
+
+ PUBWEAK NMI_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+NMI_Handler
+ B NMI_Handler
+
+ PUBWEAK HardFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+HardFault_Handler
+ B HardFault_Handler
+
+ PUBWEAK MemManage_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+MemManage_Handler
+ B MemManage_Handler
+
+ PUBWEAK BusFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+BusFault_Handler
+ B BusFault_Handler
+
+ PUBWEAK UsageFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UsageFault_Handler
+ B UsageFault_Handler
+
+ PUBWEAK SVC_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SVC_Handler
+ B SVC_Handler
+
+ PUBWEAK DebugMon_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DebugMon_Handler
+ B DebugMon_Handler
+
+ PUBWEAK PendSV_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PendSV_Handler
+ B PendSV_Handler
+
+ PUBWEAK SysTick_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SysTick_Handler
+ B SysTick_Handler
+
+ PUBWEAK WWDG_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+WWDG_IRQHandler
+ B WWDG_IRQHandler
+
+ PUBWEAK PVD_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PVD_IRQHandler
+ B PVD_IRQHandler
+
+ PUBWEAK TAMPER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TAMPER_IRQHandler
+ B TAMPER_IRQHandler
+
+ PUBWEAK RTC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_IRQHandler
+ B RTC_IRQHandler
+
+ PUBWEAK FLASH_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+FLASH_IRQHandler
+ B FLASH_IRQHandler
+
+ PUBWEAK RCC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RCC_IRQHandler
+ B RCC_IRQHandler
+
+ PUBWEAK EXTI0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI0_IRQHandler
+ B EXTI0_IRQHandler
+
+ PUBWEAK EXTI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI1_IRQHandler
+ B EXTI1_IRQHandler
+
+ PUBWEAK EXTI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI2_IRQHandler
+ B EXTI2_IRQHandler
+
+ PUBWEAK EXTI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI3_IRQHandler
+ B EXTI3_IRQHandler
+
+ PUBWEAK EXTI4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI4_IRQHandler
+ B EXTI4_IRQHandler
+
+ PUBWEAK DMA1_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel1_IRQHandler
+ B DMA1_Channel1_IRQHandler
+
+ PUBWEAK DMA1_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel2_IRQHandler
+ B DMA1_Channel2_IRQHandler
+
+ PUBWEAK DMA1_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel3_IRQHandler
+ B DMA1_Channel3_IRQHandler
+
+ PUBWEAK DMA1_Channel4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel4_IRQHandler
+ B DMA1_Channel4_IRQHandler
+
+ PUBWEAK DMA1_Channel5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel5_IRQHandler
+ B DMA1_Channel5_IRQHandler
+
+ PUBWEAK DMA1_Channel6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel6_IRQHandler
+ B DMA1_Channel6_IRQHandler
+
+ PUBWEAK DMA1_Channel7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel7_IRQHandler
+ B DMA1_Channel7_IRQHandler
+
+ PUBWEAK ADC1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ADC1_IRQHandler
+ B ADC1_IRQHandler
+
+ PUBWEAK EXTI9_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI9_5_IRQHandler
+ B EXTI9_5_IRQHandler
+
+ PUBWEAK TIM1_BRK_TIM15_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_BRK_TIM15_IRQHandler
+ B TIM1_BRK_TIM15_IRQHandler
+
+ PUBWEAK TIM1_UP_TIM16_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_UP_TIM16_IRQHandler
+ B TIM1_UP_TIM16_IRQHandler
+
+ PUBWEAK TIM1_TRG_COM_TIM17_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_TRG_COM_TIM17_IRQHandler
+ B TIM1_TRG_COM_TIM17_IRQHandler
+
+ PUBWEAK TIM1_CC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_CC_IRQHandler
+ B TIM1_CC_IRQHandler
+
+ PUBWEAK TIM2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM2_IRQHandler
+ B TIM2_IRQHandler
+
+ PUBWEAK TIM3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM3_IRQHandler
+ B TIM3_IRQHandler
+
+ PUBWEAK TIM4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM4_IRQHandler
+ B TIM4_IRQHandler
+
+ PUBWEAK I2C1_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_EV_IRQHandler
+ B I2C1_EV_IRQHandler
+
+ PUBWEAK I2C1_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_ER_IRQHandler
+ B I2C1_ER_IRQHandler
+
+ PUBWEAK I2C2_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_EV_IRQHandler
+ B I2C2_EV_IRQHandler
+
+ PUBWEAK I2C2_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_ER_IRQHandler
+ B I2C2_ER_IRQHandler
+
+ PUBWEAK SPI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI1_IRQHandler
+ B SPI1_IRQHandler
+
+ PUBWEAK SPI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI2_IRQHandler
+ B SPI2_IRQHandler
+
+ PUBWEAK USART1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART1_IRQHandler
+ B USART1_IRQHandler
+
+ PUBWEAK USART2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART2_IRQHandler
+ B USART2_IRQHandler
+
+ PUBWEAK USART3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART3_IRQHandler
+ B USART3_IRQHandler
+
+ PUBWEAK EXTI15_10_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI15_10_IRQHandler
+ B EXTI15_10_IRQHandler
+
+ PUBWEAK RTC_Alarm_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_Alarm_IRQHandler
+ B RTC_Alarm_IRQHandler
+
+
+ PUBWEAK CEC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CEC_IRQHandler
+ B CEC_IRQHandler
+
+ PUBWEAK TIM12_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM12_IRQHandler
+ B TIM12_IRQHandler
+
+ PUBWEAK TIM13_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM13_IRQHandler
+ B TIM13_IRQHandler
+
+ PUBWEAK TIM14_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM14_IRQHandler
+ B TIM14_IRQHandler
+
+ PUBWEAK TIM5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM5_IRQHandler
+ B TIM5_IRQHandler
+
+ PUBWEAK SPI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI3_IRQHandler
+ B SPI3_IRQHandler
+
+ PUBWEAK UART4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UART4_IRQHandler
+ B UART4_IRQHandler
+
+ PUBWEAK UART5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UART5_IRQHandler
+ B UART5_IRQHandler
+
+ PUBWEAK TIM6_DAC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM6_DAC_IRQHandler
+ B TIM6_DAC_IRQHandler
+
+ PUBWEAK TIM7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM7_IRQHandler
+ B TIM7_IRQHandler
+
+ PUBWEAK DMA2_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel1_IRQHandler
+ B DMA2_Channel1_IRQHandler
+
+ PUBWEAK DMA2_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel2_IRQHandler
+ B DMA2_Channel2_IRQHandler
+
+ PUBWEAK DMA2_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel3_IRQHandler
+ B DMA2_Channel3_IRQHandler
+
+ PUBWEAK DMA2_Channel4_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel4_5_IRQHandler
+ B DMA2_Channel4_5_IRQHandler
+
+ PUBWEAK DMA2_Channel5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel5_IRQHandler
+ B DMA2_Channel5_IRQHandler
+
+ END
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101x6.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101x6.s
new file mode 100644
index 0000000..41ea902
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101x6.s
@@ -0,0 +1,340 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f101x6.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F101x6 Access Line Devices vector table for EWARM
+;* toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Configure the clock system
+;* - Set the initial PC == __iar_program_start,
+;* - Set the vector table entries with the exceptions ISR
+;* address.
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;*
+;*******************************************************************************
+;
+;
+; The modules in this file are included in the libraries, and may be replaced
+; by any user-defined modules that define the PUBLIC symbol _program_start or
+; a user defined start symbol.
+; To override the cstartup defined in the library, simply add your modified
+; version to the workbench project.
+;
+; The vector table is normally located at address 0.
+; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
+; The name "__vector_table" has special meaning for C-SPY:
+; it is where the SP start value is found, and the NVIC vector
+; table register (VTOR) is initialized to this address if != 0.
+;
+; Cortex-M version
+;
+
+ MODULE ?cstartup
+
+ ;; Forward declaration of sections.
+ SECTION CSTACK:DATA:NOROOT(3)
+
+ SECTION .intvec:CODE:NOROOT(2)
+
+ EXTERN __iar_program_start
+ EXTERN SystemInit
+ PUBLIC __vector_table
+
+ DATA
+__vector_table
+ DCD sfe(CSTACK)
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_IRQHandler ; ADC1
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD 0 ; Reserved
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SPI1_IRQHandler ; SPI1
+ DCD 0 ; Reserved
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD 0 ; Reserved
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD 0 ; Reserved
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Default interrupt handlers.
+;;
+ THUMB
+
+ PUBWEAK Reset_Handler
+ SECTION .text:CODE:REORDER:NOROOT(2)
+Reset_Handler
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__iar_program_start
+ BX R0
+
+ PUBWEAK NMI_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+NMI_Handler
+ B NMI_Handler
+
+ PUBWEAK HardFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+HardFault_Handler
+ B HardFault_Handler
+
+ PUBWEAK MemManage_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+MemManage_Handler
+ B MemManage_Handler
+
+ PUBWEAK BusFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+BusFault_Handler
+ B BusFault_Handler
+
+ PUBWEAK UsageFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UsageFault_Handler
+ B UsageFault_Handler
+
+ PUBWEAK SVC_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SVC_Handler
+ B SVC_Handler
+
+ PUBWEAK DebugMon_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DebugMon_Handler
+ B DebugMon_Handler
+
+ PUBWEAK PendSV_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PendSV_Handler
+ B PendSV_Handler
+
+ PUBWEAK SysTick_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SysTick_Handler
+ B SysTick_Handler
+
+ PUBWEAK WWDG_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+WWDG_IRQHandler
+ B WWDG_IRQHandler
+
+ PUBWEAK PVD_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PVD_IRQHandler
+ B PVD_IRQHandler
+
+ PUBWEAK TAMPER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TAMPER_IRQHandler
+ B TAMPER_IRQHandler
+
+ PUBWEAK RTC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_IRQHandler
+ B RTC_IRQHandler
+
+ PUBWEAK FLASH_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+FLASH_IRQHandler
+ B FLASH_IRQHandler
+
+ PUBWEAK RCC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RCC_IRQHandler
+ B RCC_IRQHandler
+
+ PUBWEAK EXTI0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI0_IRQHandler
+ B EXTI0_IRQHandler
+
+ PUBWEAK EXTI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI1_IRQHandler
+ B EXTI1_IRQHandler
+
+ PUBWEAK EXTI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI2_IRQHandler
+ B EXTI2_IRQHandler
+
+ PUBWEAK EXTI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI3_IRQHandler
+ B EXTI3_IRQHandler
+
+ PUBWEAK EXTI4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI4_IRQHandler
+ B EXTI4_IRQHandler
+
+ PUBWEAK DMA1_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel1_IRQHandler
+ B DMA1_Channel1_IRQHandler
+
+ PUBWEAK DMA1_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel2_IRQHandler
+ B DMA1_Channel2_IRQHandler
+
+ PUBWEAK DMA1_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel3_IRQHandler
+ B DMA1_Channel3_IRQHandler
+
+ PUBWEAK DMA1_Channel4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel4_IRQHandler
+ B DMA1_Channel4_IRQHandler
+
+ PUBWEAK DMA1_Channel5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel5_IRQHandler
+ B DMA1_Channel5_IRQHandler
+
+ PUBWEAK DMA1_Channel6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel6_IRQHandler
+ B DMA1_Channel6_IRQHandler
+
+ PUBWEAK DMA1_Channel7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel7_IRQHandler
+ B DMA1_Channel7_IRQHandler
+
+ PUBWEAK ADC1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ADC1_IRQHandler
+ B ADC1_IRQHandler
+
+ PUBWEAK EXTI9_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI9_5_IRQHandler
+ B EXTI9_5_IRQHandler
+
+ PUBWEAK TIM2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM2_IRQHandler
+ B TIM2_IRQHandler
+
+ PUBWEAK TIM3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM3_IRQHandler
+ B TIM3_IRQHandler
+
+ PUBWEAK I2C1_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_EV_IRQHandler
+ B I2C1_EV_IRQHandler
+
+ PUBWEAK I2C1_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_ER_IRQHandler
+ B I2C1_ER_IRQHandler
+
+ PUBWEAK SPI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI1_IRQHandler
+ B SPI1_IRQHandler
+
+ PUBWEAK USART1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART1_IRQHandler
+ B USART1_IRQHandler
+
+ PUBWEAK USART2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART2_IRQHandler
+ B USART2_IRQHandler
+
+ PUBWEAK EXTI15_10_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI15_10_IRQHandler
+ B EXTI15_10_IRQHandler
+
+ PUBWEAK RTC_Alarm_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_Alarm_IRQHandler
+ B RTC_Alarm_IRQHandler
+
+ END
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101xb.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101xb.s
new file mode 100644
index 0000000..f079123
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101xb.s
@@ -0,0 +1,365 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f101xb.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F101xB Access Line Devices vector table for
+;* EWARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Configure the clock system
+;* - Set the initial PC == __iar_program_start,
+;* - Set the vector table entries with the exceptions ISR
+;* address.
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;*
+;*******************************************************************************
+;
+;
+; The modules in this file are included in the libraries, and may be replaced
+; by any user-defined modules that define the PUBLIC symbol _program_start or
+; a user defined start symbol.
+; To override the cstartup defined in the library, simply add your modified
+; version to the workbench project.
+;
+; The vector table is normally located at address 0.
+; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
+; The name "__vector_table" has special meaning for C-SPY:
+; it is where the SP start value is found, and the NVIC vector
+; table register (VTOR) is initialized to this address if != 0.
+;
+; Cortex-M version
+;
+
+ MODULE ?cstartup
+
+ ;; Forward declaration of sections.
+ SECTION CSTACK:DATA:NOROOT(3)
+
+ SECTION .intvec:CODE:NOROOT(2)
+
+ EXTERN __iar_program_start
+ EXTERN SystemInit
+ PUBLIC __vector_table
+
+ DATA
+__vector_table
+ DCD sfe(CSTACK)
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_IRQHandler ; ADC1
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C2 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD 0 ; Reserved
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Default interrupt handlers.
+;;
+ THUMB
+
+ PUBWEAK Reset_Handler
+ SECTION .text:CODE:REORDER:NOROOT(2)
+Reset_Handler
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__iar_program_start
+ BX R0
+
+ PUBWEAK NMI_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+NMI_Handler
+ B NMI_Handler
+
+ PUBWEAK HardFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+HardFault_Handler
+ B HardFault_Handler
+
+ PUBWEAK MemManage_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+MemManage_Handler
+ B MemManage_Handler
+
+ PUBWEAK BusFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+BusFault_Handler
+ B BusFault_Handler
+
+ PUBWEAK UsageFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UsageFault_Handler
+ B UsageFault_Handler
+
+ PUBWEAK SVC_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SVC_Handler
+ B SVC_Handler
+
+ PUBWEAK DebugMon_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DebugMon_Handler
+ B DebugMon_Handler
+
+ PUBWEAK PendSV_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PendSV_Handler
+ B PendSV_Handler
+
+ PUBWEAK SysTick_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SysTick_Handler
+ B SysTick_Handler
+
+ PUBWEAK WWDG_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+WWDG_IRQHandler
+ B WWDG_IRQHandler
+
+ PUBWEAK PVD_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PVD_IRQHandler
+ B PVD_IRQHandler
+
+ PUBWEAK TAMPER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TAMPER_IRQHandler
+ B TAMPER_IRQHandler
+
+ PUBWEAK RTC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_IRQHandler
+ B RTC_IRQHandler
+
+ PUBWEAK FLASH_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+FLASH_IRQHandler
+ B FLASH_IRQHandler
+
+ PUBWEAK RCC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RCC_IRQHandler
+ B RCC_IRQHandler
+
+ PUBWEAK EXTI0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI0_IRQHandler
+ B EXTI0_IRQHandler
+
+ PUBWEAK EXTI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI1_IRQHandler
+ B EXTI1_IRQHandler
+
+ PUBWEAK EXTI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI2_IRQHandler
+ B EXTI2_IRQHandler
+
+ PUBWEAK EXTI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI3_IRQHandler
+ B EXTI3_IRQHandler
+
+ PUBWEAK EXTI4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI4_IRQHandler
+ B EXTI4_IRQHandler
+
+ PUBWEAK DMA1_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel1_IRQHandler
+ B DMA1_Channel1_IRQHandler
+
+ PUBWEAK DMA1_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel2_IRQHandler
+ B DMA1_Channel2_IRQHandler
+
+ PUBWEAK DMA1_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel3_IRQHandler
+ B DMA1_Channel3_IRQHandler
+
+ PUBWEAK DMA1_Channel4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel4_IRQHandler
+ B DMA1_Channel4_IRQHandler
+
+ PUBWEAK DMA1_Channel5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel5_IRQHandler
+ B DMA1_Channel5_IRQHandler
+
+ PUBWEAK DMA1_Channel6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel6_IRQHandler
+ B DMA1_Channel6_IRQHandler
+
+ PUBWEAK DMA1_Channel7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel7_IRQHandler
+ B DMA1_Channel7_IRQHandler
+
+ PUBWEAK ADC1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ADC1_IRQHandler
+ B ADC1_IRQHandler
+
+ PUBWEAK EXTI9_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI9_5_IRQHandler
+ B EXTI9_5_IRQHandler
+
+ PUBWEAK TIM2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM2_IRQHandler
+ B TIM2_IRQHandler
+
+ PUBWEAK TIM3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM3_IRQHandler
+ B TIM3_IRQHandler
+
+ PUBWEAK TIM4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM4_IRQHandler
+ B TIM4_IRQHandler
+
+ PUBWEAK I2C1_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_EV_IRQHandler
+ B I2C1_EV_IRQHandler
+
+ PUBWEAK I2C1_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_ER_IRQHandler
+ B I2C1_ER_IRQHandler
+
+ PUBWEAK I2C2_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_EV_IRQHandler
+ B I2C2_EV_IRQHandler
+
+ PUBWEAK I2C2_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_ER_IRQHandler
+ B I2C2_ER_IRQHandler
+
+ PUBWEAK SPI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI1_IRQHandler
+ B SPI1_IRQHandler
+
+ PUBWEAK SPI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI2_IRQHandler
+ B SPI2_IRQHandler
+
+ PUBWEAK USART1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART1_IRQHandler
+ B USART1_IRQHandler
+
+ PUBWEAK USART2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART2_IRQHandler
+ B USART2_IRQHandler
+
+ PUBWEAK USART3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART3_IRQHandler
+ B USART3_IRQHandler
+
+ PUBWEAK EXTI15_10_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI15_10_IRQHandler
+ B EXTI15_10_IRQHandler
+
+ PUBWEAK RTC_Alarm_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_Alarm_IRQHandler
+ B RTC_Alarm_IRQHandler
+
+ END
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101xe.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101xe.s
new file mode 100644
index 0000000..af58461
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101xe.s
@@ -0,0 +1,445 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f101xe.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F101xE Access Line Devices vector table for EWARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == __iar_program_start,
+;* - Set the vector table entries with the exceptions ISR
+;* address.
+;* - Configure the system clock
+;* - Branches to main in the C library (which eventually
+;* calls main()).
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;*
+;*******************************************************************************
+;
+;
+; The modules in this file are included in the libraries, and may be replaced
+; by any user-defined modules that define the PUBLIC symbol _program_start or
+; a user defined start symbol.
+; To override the cstartup defined in the library, simply add your modified
+; version to the workbench project.
+;
+; The vector table is normally located at address 0.
+; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
+; The name "__vector_table" has special meaning for C-SPY:
+; it is where the SP start value is found, and the NVIC vector
+; table register (VTOR) is initialized to this address if != 0.
+;
+; Cortex-M version
+;
+
+ MODULE ?cstartup
+
+ ;; Forward declaration of sections.
+ SECTION CSTACK:DATA:NOROOT(3)
+
+ SECTION .intvec:CODE:NOROOT(2)
+
+ EXTERN __iar_program_start
+ EXTERN SystemInit
+ PUBLIC __vector_table
+
+ DATA
+
+__vector_table
+ DCD sfe(CSTACK)
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_IRQHandler ; ADC1
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C2 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD FSMC_IRQHandler ; FSMC
+ DCD 0 ; Reserved
+ DCD TIM5_IRQHandler ; TIM5
+ DCD SPI3_IRQHandler ; SPI3
+ DCD UART4_IRQHandler ; UART4
+ DCD UART5_IRQHandler ; UART5
+ DCD TIM6_IRQHandler ; TIM6
+ DCD TIM7_IRQHandler ; TIM7
+ DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
+ DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
+ DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
+ DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Default interrupt handlers.
+;;
+ THUMB
+
+ PUBWEAK Reset_Handler
+ SECTION .text:CODE:REORDER:NOROOT(2)
+Reset_Handler
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__iar_program_start
+ BX R0
+
+ PUBWEAK NMI_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+NMI_Handler
+ B NMI_Handler
+
+ PUBWEAK HardFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+HardFault_Handler
+ B HardFault_Handler
+
+ PUBWEAK MemManage_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+MemManage_Handler
+ B MemManage_Handler
+
+ PUBWEAK BusFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+BusFault_Handler
+ B BusFault_Handler
+
+ PUBWEAK UsageFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UsageFault_Handler
+ B UsageFault_Handler
+
+ PUBWEAK SVC_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SVC_Handler
+ B SVC_Handler
+
+ PUBWEAK DebugMon_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DebugMon_Handler
+ B DebugMon_Handler
+
+ PUBWEAK PendSV_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PendSV_Handler
+ B PendSV_Handler
+
+ PUBWEAK SysTick_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SysTick_Handler
+ B SysTick_Handler
+
+ PUBWEAK WWDG_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+WWDG_IRQHandler
+ B WWDG_IRQHandler
+
+ PUBWEAK PVD_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PVD_IRQHandler
+ B PVD_IRQHandler
+
+ PUBWEAK TAMPER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TAMPER_IRQHandler
+ B TAMPER_IRQHandler
+
+ PUBWEAK RTC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_IRQHandler
+ B RTC_IRQHandler
+
+ PUBWEAK FLASH_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+FLASH_IRQHandler
+ B FLASH_IRQHandler
+
+ PUBWEAK RCC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RCC_IRQHandler
+ B RCC_IRQHandler
+
+ PUBWEAK EXTI0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI0_IRQHandler
+ B EXTI0_IRQHandler
+
+ PUBWEAK EXTI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI1_IRQHandler
+ B EXTI1_IRQHandler
+
+ PUBWEAK EXTI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI2_IRQHandler
+ B EXTI2_IRQHandler
+
+ PUBWEAK EXTI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI3_IRQHandler
+ B EXTI3_IRQHandler
+
+ PUBWEAK EXTI4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI4_IRQHandler
+ B EXTI4_IRQHandler
+
+ PUBWEAK DMA1_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel1_IRQHandler
+ B DMA1_Channel1_IRQHandler
+
+ PUBWEAK DMA1_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel2_IRQHandler
+ B DMA1_Channel2_IRQHandler
+
+ PUBWEAK DMA1_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel3_IRQHandler
+ B DMA1_Channel3_IRQHandler
+
+ PUBWEAK DMA1_Channel4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel4_IRQHandler
+ B DMA1_Channel4_IRQHandler
+
+ PUBWEAK DMA1_Channel5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel5_IRQHandler
+ B DMA1_Channel5_IRQHandler
+
+ PUBWEAK DMA1_Channel6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel6_IRQHandler
+ B DMA1_Channel6_IRQHandler
+
+ PUBWEAK DMA1_Channel7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel7_IRQHandler
+ B DMA1_Channel7_IRQHandler
+
+ PUBWEAK ADC1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ADC1_IRQHandler
+ B ADC1_IRQHandler
+
+ PUBWEAK EXTI9_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI9_5_IRQHandler
+ B EXTI9_5_IRQHandler
+
+ PUBWEAK TIM2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM2_IRQHandler
+ B TIM2_IRQHandler
+
+ PUBWEAK TIM3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM3_IRQHandler
+ B TIM3_IRQHandler
+
+ PUBWEAK TIM4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM4_IRQHandler
+ B TIM4_IRQHandler
+
+ PUBWEAK I2C1_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_EV_IRQHandler
+ B I2C1_EV_IRQHandler
+
+ PUBWEAK I2C1_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_ER_IRQHandler
+ B I2C1_ER_IRQHandler
+
+ PUBWEAK I2C2_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_EV_IRQHandler
+ B I2C2_EV_IRQHandler
+
+ PUBWEAK I2C2_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_ER_IRQHandler
+ B I2C2_ER_IRQHandler
+
+ PUBWEAK SPI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI1_IRQHandler
+ B SPI1_IRQHandler
+
+ PUBWEAK SPI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI2_IRQHandler
+ B SPI2_IRQHandler
+
+ PUBWEAK USART1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART1_IRQHandler
+ B USART1_IRQHandler
+
+ PUBWEAK USART2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART2_IRQHandler
+ B USART2_IRQHandler
+
+ PUBWEAK USART3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART3_IRQHandler
+ B USART3_IRQHandler
+
+ PUBWEAK EXTI15_10_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI15_10_IRQHandler
+ B EXTI15_10_IRQHandler
+
+ PUBWEAK RTC_Alarm_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_Alarm_IRQHandler
+ B RTC_Alarm_IRQHandler
+
+ PUBWEAK FSMC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+FSMC_IRQHandler
+ B FSMC_IRQHandler
+
+ PUBWEAK SDIO_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SDIO_IRQHandler
+ B SDIO_IRQHandler
+
+ PUBWEAK TIM5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM5_IRQHandler
+ B TIM5_IRQHandler
+
+ PUBWEAK SPI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI3_IRQHandler
+ B SPI3_IRQHandler
+
+ PUBWEAK UART4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UART4_IRQHandler
+ B UART4_IRQHandler
+
+ PUBWEAK UART5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UART5_IRQHandler
+ B UART5_IRQHandler
+
+ PUBWEAK TIM6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM6_IRQHandler
+ B TIM6_IRQHandler
+
+ PUBWEAK TIM7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM7_IRQHandler
+ B TIM7_IRQHandler
+
+ PUBWEAK DMA2_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel1_IRQHandler
+ B DMA2_Channel1_IRQHandler
+
+ PUBWEAK DMA2_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel2_IRQHandler
+ B DMA2_Channel2_IRQHandler
+
+ PUBWEAK DMA2_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel3_IRQHandler
+ B DMA2_Channel3_IRQHandler
+
+ PUBWEAK DMA2_Channel4_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel4_5_IRQHandler
+ B DMA2_Channel4_5_IRQHandler
+
+
+ END
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101xg.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101xg.s
new file mode 100644
index 0000000..9ffbe36
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f101xg.s
@@ -0,0 +1,476 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f101xg.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F101xG Access Line Devices vector table for EWARM
+;* toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == __iar_program_start,
+;* - Set the vector table entries with the exceptions ISR
+;* address.
+;* - Configure the system clock
+;* - Branches to main in the C library (which eventually
+;* calls main()).
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;*
+;*******************************************************************************
+;
+;
+; The modules in this file are included in the libraries, and may be replaced
+; by any user-defined modules that define the PUBLIC symbol _program_start or
+; a user defined start symbol.
+; To override the cstartup defined in the library, simply add your modified
+; version to the workbench project.
+;
+; The vector table is normally located at address 0.
+; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
+; The name "__vector_table" has special meaning for C-SPY:
+; it is where the SP start value is found, and the NVIC vector
+; table register (VTOR) is initialized to this address if != 0.
+;
+; Cortex-M version
+;
+
+ MODULE ?cstartup
+
+ ;; Forward declaration of sections.
+ SECTION CSTACK:DATA:NOROOT(3)
+
+ SECTION .intvec:CODE:NOROOT(2)
+
+ EXTERN __iar_program_start
+ EXTERN SystemInit
+ PUBLIC __vector_table
+
+ DATA
+
+__vector_table
+ DCD sfe(CSTACK)
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_2_IRQHandler ; ADC1 & ADC2
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD TIM9_IRQHandler ; TIM9
+ DCD TIM10_IRQHandler ; TIM10
+ DCD TIM11_IRQHandler ; TIM11
+ DCD 0 ; Reserved
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C2 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD 0 ; Reserved
+ DCD TIM12_IRQHandler ; TIM12
+ DCD TIM13_IRQHandler ; TIM13
+ DCD TIM14_IRQHandler ; TIM14
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD FSMC_IRQHandler ; FSMC
+ DCD 0 ; Reserved
+ DCD TIM5_IRQHandler ; TIM5
+ DCD SPI3_IRQHandler ; SPI3
+ DCD UART4_IRQHandler ; UART4
+ DCD UART5_IRQHandler ; UART5
+ DCD TIM6_IRQHandler ; TIM6
+ DCD TIM7_IRQHandler ; TIM7
+ DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
+ DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
+ DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
+ DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Default interrupt handlers.
+;;
+ THUMB
+
+ PUBWEAK Reset_Handler
+ SECTION .text:CODE:REORDER:NOROOT(2)
+Reset_Handler
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__iar_program_start
+ BX R0
+
+ PUBWEAK NMI_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+NMI_Handler
+ B NMI_Handler
+
+ PUBWEAK HardFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+HardFault_Handler
+ B HardFault_Handler
+
+ PUBWEAK MemManage_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+MemManage_Handler
+ B MemManage_Handler
+
+ PUBWEAK BusFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+BusFault_Handler
+ B BusFault_Handler
+
+ PUBWEAK UsageFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UsageFault_Handler
+ B UsageFault_Handler
+
+ PUBWEAK SVC_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SVC_Handler
+ B SVC_Handler
+
+ PUBWEAK DebugMon_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DebugMon_Handler
+ B DebugMon_Handler
+
+ PUBWEAK PendSV_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PendSV_Handler
+ B PendSV_Handler
+
+ PUBWEAK SysTick_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SysTick_Handler
+ B SysTick_Handler
+
+ PUBWEAK WWDG_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+WWDG_IRQHandler
+ B WWDG_IRQHandler
+
+ PUBWEAK PVD_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PVD_IRQHandler
+ B PVD_IRQHandler
+
+ PUBWEAK TAMPER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TAMPER_IRQHandler
+ B TAMPER_IRQHandler
+
+ PUBWEAK RTC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_IRQHandler
+ B RTC_IRQHandler
+
+ PUBWEAK FLASH_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+FLASH_IRQHandler
+ B FLASH_IRQHandler
+
+ PUBWEAK RCC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RCC_IRQHandler
+ B RCC_IRQHandler
+
+ PUBWEAK EXTI0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI0_IRQHandler
+ B EXTI0_IRQHandler
+
+ PUBWEAK EXTI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI1_IRQHandler
+ B EXTI1_IRQHandler
+
+ PUBWEAK EXTI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI2_IRQHandler
+ B EXTI2_IRQHandler
+
+ PUBWEAK EXTI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI3_IRQHandler
+ B EXTI3_IRQHandler
+
+ PUBWEAK EXTI4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI4_IRQHandler
+ B EXTI4_IRQHandler
+
+ PUBWEAK DMA1_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel1_IRQHandler
+ B DMA1_Channel1_IRQHandler
+
+ PUBWEAK DMA1_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel2_IRQHandler
+ B DMA1_Channel2_IRQHandler
+
+ PUBWEAK DMA1_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel3_IRQHandler
+ B DMA1_Channel3_IRQHandler
+
+ PUBWEAK DMA1_Channel4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel4_IRQHandler
+ B DMA1_Channel4_IRQHandler
+
+ PUBWEAK DMA1_Channel5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel5_IRQHandler
+ B DMA1_Channel5_IRQHandler
+
+ PUBWEAK DMA1_Channel6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel6_IRQHandler
+ B DMA1_Channel6_IRQHandler
+
+ PUBWEAK DMA1_Channel7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel7_IRQHandler
+ B DMA1_Channel7_IRQHandler
+
+ PUBWEAK ADC1_2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ADC1_2_IRQHandler
+ B ADC1_2_IRQHandler
+
+ PUBWEAK EXTI9_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI9_5_IRQHandler
+ B EXTI9_5_IRQHandler
+
+ PUBWEAK TIM9_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM9_IRQHandler
+ B TIM9_IRQHandler
+
+ PUBWEAK TIM10_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM10_IRQHandler
+ B TIM10_IRQHandler
+
+ PUBWEAK TIM11_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM11_IRQHandler
+ B TIM11_IRQHandler
+
+ PUBWEAK TIM1_CC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_CC_IRQHandler
+ B TIM1_CC_IRQHandler
+
+ PUBWEAK TIM2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM2_IRQHandler
+ B TIM2_IRQHandler
+
+ PUBWEAK TIM3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM3_IRQHandler
+ B TIM3_IRQHandler
+
+ PUBWEAK TIM4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM4_IRQHandler
+ B TIM4_IRQHandler
+
+ PUBWEAK I2C1_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_EV_IRQHandler
+ B I2C1_EV_IRQHandler
+
+ PUBWEAK I2C1_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_ER_IRQHandler
+ B I2C1_ER_IRQHandler
+
+ PUBWEAK I2C2_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_EV_IRQHandler
+ B I2C2_EV_IRQHandler
+
+ PUBWEAK I2C2_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_ER_IRQHandler
+ B I2C2_ER_IRQHandler
+
+ PUBWEAK SPI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI1_IRQHandler
+ B SPI1_IRQHandler
+
+ PUBWEAK SPI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI2_IRQHandler
+ B SPI2_IRQHandler
+
+ PUBWEAK USART1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART1_IRQHandler
+ B USART1_IRQHandler
+
+ PUBWEAK USART2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART2_IRQHandler
+ B USART2_IRQHandler
+
+ PUBWEAK USART3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART3_IRQHandler
+ B USART3_IRQHandler
+
+ PUBWEAK EXTI15_10_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI15_10_IRQHandler
+ B EXTI15_10_IRQHandler
+
+ PUBWEAK RTC_Alarm_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_Alarm_IRQHandler
+ B RTC_Alarm_IRQHandler
+
+ PUBWEAK FSMC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+FSMC_IRQHandler
+ B FSMC_IRQHandler
+
+ PUBWEAK TIM12_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM12_IRQHandler
+ B TIM12_IRQHandler
+
+ PUBWEAK TIM13_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM13_IRQHandler
+ B TIM13_IRQHandler
+
+ PUBWEAK TIM14_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM14_IRQHandler
+ B TIM14_IRQHandler
+
+ PUBWEAK TIM5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM5_IRQHandler
+ B TIM5_IRQHandler
+
+ PUBWEAK SPI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI3_IRQHandler
+ B SPI3_IRQHandler
+
+ PUBWEAK UART4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UART4_IRQHandler
+ B UART4_IRQHandler
+
+ PUBWEAK UART5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UART5_IRQHandler
+ B UART5_IRQHandler
+
+ PUBWEAK TIM6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM6_IRQHandler
+ B TIM6_IRQHandler
+
+ PUBWEAK TIM7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM7_IRQHandler
+ B TIM7_IRQHandler
+
+ PUBWEAK DMA2_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel1_IRQHandler
+ B DMA2_Channel1_IRQHandler
+
+ PUBWEAK DMA2_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel2_IRQHandler
+ B DMA2_Channel2_IRQHandler
+
+ PUBWEAK DMA2_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel3_IRQHandler
+ B DMA2_Channel3_IRQHandler
+
+ PUBWEAK DMA2_Channel4_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel4_5_IRQHandler
+ B DMA2_Channel4_5_IRQHandler
+
+
+ END
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f102x6.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f102x6.s
new file mode 100644
index 0000000..d032b0d
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f102x6.s
@@ -0,0 +1,355 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f102x6.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F102x6 USB Line Devices vector table for EWARM
+;* toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Configure the clock system
+;* - Set the initial PC == __iar_program_start,
+;* - Set the vector table entries with the exceptions ISR
+;* address.
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;*
+;*******************************************************************************
+;
+;
+; The modules in this file are included in the libraries, and may be replaced
+; by any user-defined modules that define the PUBLIC symbol _program_start or
+; a user defined start symbol.
+; To override the cstartup defined in the library, simply add your modified
+; version to the workbench project.
+;
+; The vector table is normally located at address 0.
+; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
+; The name "__vector_table" has special meaning for C-SPY:
+; it is where the SP start value is found, and the NVIC vector
+; table register (VTOR) is initialized to this address if != 0.
+;
+; Cortex-M version
+;
+
+ MODULE ?cstartup
+
+ ;; Forward declaration of sections.
+ SECTION CSTACK:DATA:NOROOT(3)
+
+ SECTION .intvec:CODE:NOROOT(2)
+
+ EXTERN __iar_program_start
+ EXTERN SystemInit
+ PUBLIC __vector_table
+
+ DATA
+__vector_table
+ DCD sfe(CSTACK)
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_IRQHandler ; ADC1
+ DCD USB_HP_IRQHandler ; USB High Priority
+ DCD USB_LP_IRQHandler ; USB Low Priority
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD 0 ; Reserved
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SPI1_IRQHandler ; SPI1
+ DCD 0 ; Reserved
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD 0 ; Reserved
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Default interrupt handlers.
+;;
+ THUMB
+
+ PUBWEAK Reset_Handler
+ SECTION .text:CODE:REORDER:NOROOT(2)
+Reset_Handler
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__iar_program_start
+ BX R0
+
+ PUBWEAK NMI_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+NMI_Handler
+ B NMI_Handler
+
+ PUBWEAK HardFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+HardFault_Handler
+ B HardFault_Handler
+
+ PUBWEAK MemManage_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+MemManage_Handler
+ B MemManage_Handler
+
+ PUBWEAK BusFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+BusFault_Handler
+ B BusFault_Handler
+
+ PUBWEAK UsageFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UsageFault_Handler
+ B UsageFault_Handler
+
+ PUBWEAK SVC_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SVC_Handler
+ B SVC_Handler
+
+ PUBWEAK DebugMon_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DebugMon_Handler
+ B DebugMon_Handler
+
+ PUBWEAK PendSV_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PendSV_Handler
+ B PendSV_Handler
+
+ PUBWEAK SysTick_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SysTick_Handler
+ B SysTick_Handler
+
+ PUBWEAK WWDG_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+WWDG_IRQHandler
+ B WWDG_IRQHandler
+
+ PUBWEAK PVD_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PVD_IRQHandler
+ B PVD_IRQHandler
+
+ PUBWEAK TAMPER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TAMPER_IRQHandler
+ B TAMPER_IRQHandler
+
+ PUBWEAK RTC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_IRQHandler
+ B RTC_IRQHandler
+
+ PUBWEAK FLASH_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+FLASH_IRQHandler
+ B FLASH_IRQHandler
+
+ PUBWEAK RCC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RCC_IRQHandler
+ B RCC_IRQHandler
+
+ PUBWEAK EXTI0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI0_IRQHandler
+ B EXTI0_IRQHandler
+
+ PUBWEAK EXTI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI1_IRQHandler
+ B EXTI1_IRQHandler
+
+ PUBWEAK EXTI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI2_IRQHandler
+ B EXTI2_IRQHandler
+
+ PUBWEAK EXTI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI3_IRQHandler
+ B EXTI3_IRQHandler
+
+ PUBWEAK EXTI4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI4_IRQHandler
+ B EXTI4_IRQHandler
+
+ PUBWEAK DMA1_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel1_IRQHandler
+ B DMA1_Channel1_IRQHandler
+
+ PUBWEAK DMA1_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel2_IRQHandler
+ B DMA1_Channel2_IRQHandler
+
+ PUBWEAK DMA1_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel3_IRQHandler
+ B DMA1_Channel3_IRQHandler
+
+ PUBWEAK DMA1_Channel4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel4_IRQHandler
+ B DMA1_Channel4_IRQHandler
+
+ PUBWEAK DMA1_Channel5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel5_IRQHandler
+ B DMA1_Channel5_IRQHandler
+
+ PUBWEAK DMA1_Channel6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel6_IRQHandler
+ B DMA1_Channel6_IRQHandler
+
+ PUBWEAK DMA1_Channel7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel7_IRQHandler
+ B DMA1_Channel7_IRQHandler
+
+ PUBWEAK ADC1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ADC1_IRQHandler
+ B ADC1_IRQHandler
+
+ PUBWEAK USB_HP_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USB_HP_IRQHandler
+ B USB_HP_IRQHandler
+
+ PUBWEAK USB_LP_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USB_LP_IRQHandler
+ B USB_LP_IRQHandler
+
+ PUBWEAK EXTI9_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI9_5_IRQHandler
+ B EXTI9_5_IRQHandler
+
+ PUBWEAK TIM2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM2_IRQHandler
+ B TIM2_IRQHandler
+
+ PUBWEAK TIM3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM3_IRQHandler
+ B TIM3_IRQHandler
+
+ PUBWEAK I2C1_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_EV_IRQHandler
+ B I2C1_EV_IRQHandler
+
+ PUBWEAK I2C1_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_ER_IRQHandler
+ B I2C1_ER_IRQHandler
+
+ PUBWEAK SPI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI1_IRQHandler
+ B SPI1_IRQHandler
+
+ PUBWEAK USART1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART1_IRQHandler
+ B USART1_IRQHandler
+
+ PUBWEAK USART2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART2_IRQHandler
+ B USART2_IRQHandler
+
+ PUBWEAK EXTI15_10_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI15_10_IRQHandler
+ B EXTI15_10_IRQHandler
+
+ PUBWEAK RTC_Alarm_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_Alarm_IRQHandler
+ B RTC_Alarm_IRQHandler
+
+ PUBWEAK USBWakeUp_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USBWakeUp_IRQHandler
+ B USBWakeUp_IRQHandler
+
+ END
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f102xb.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f102xb.s
new file mode 100644
index 0000000..099c304
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f102xb.s
@@ -0,0 +1,380 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f102xb.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F102xB USB Line Devices vector table for
+;* EWARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Configure the clock system
+;* - Set the initial PC == __iar_program_start,
+;* - Set the vector table entries with the exceptions ISR
+;* address.
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;*
+;*******************************************************************************
+;
+;
+; The modules in this file are included in the libraries, and may be replaced
+; by any user-defined modules that define the PUBLIC symbol _program_start or
+; a user defined start symbol.
+; To override the cstartup defined in the library, simply add your modified
+; version to the workbench project.
+;
+; The vector table is normally located at address 0.
+; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
+; The name "__vector_table" has special meaning for C-SPY:
+; it is where the SP start value is found, and the NVIC vector
+; table register (VTOR) is initialized to this address if != 0.
+;
+; Cortex-M version
+;
+
+ MODULE ?cstartup
+
+ ;; Forward declaration of sections.
+ SECTION CSTACK:DATA:NOROOT(3)
+
+ SECTION .intvec:CODE:NOROOT(2)
+
+ EXTERN __iar_program_start
+ EXTERN SystemInit
+ PUBLIC __vector_table
+
+ DATA
+__vector_table
+ DCD sfe(CSTACK)
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_IRQHandler ; ADC1
+ DCD USB_HP_IRQHandler ; USB High Priority
+ DCD USB_LP_IRQHandler ; USB Low Priority
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C2 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Default interrupt handlers.
+;;
+ THUMB
+
+ PUBWEAK Reset_Handler
+ SECTION .text:CODE:REORDER:NOROOT(2)
+Reset_Handler
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__iar_program_start
+ BX R0
+
+ PUBWEAK NMI_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+NMI_Handler
+ B NMI_Handler
+
+ PUBWEAK HardFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+HardFault_Handler
+ B HardFault_Handler
+
+ PUBWEAK MemManage_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+MemManage_Handler
+ B MemManage_Handler
+
+ PUBWEAK BusFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+BusFault_Handler
+ B BusFault_Handler
+
+ PUBWEAK UsageFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UsageFault_Handler
+ B UsageFault_Handler
+
+ PUBWEAK SVC_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SVC_Handler
+ B SVC_Handler
+
+ PUBWEAK DebugMon_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DebugMon_Handler
+ B DebugMon_Handler
+
+ PUBWEAK PendSV_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PendSV_Handler
+ B PendSV_Handler
+
+ PUBWEAK SysTick_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SysTick_Handler
+ B SysTick_Handler
+
+ PUBWEAK WWDG_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+WWDG_IRQHandler
+ B WWDG_IRQHandler
+
+ PUBWEAK PVD_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PVD_IRQHandler
+ B PVD_IRQHandler
+
+ PUBWEAK TAMPER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TAMPER_IRQHandler
+ B TAMPER_IRQHandler
+
+ PUBWEAK RTC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_IRQHandler
+ B RTC_IRQHandler
+
+ PUBWEAK FLASH_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+FLASH_IRQHandler
+ B FLASH_IRQHandler
+
+ PUBWEAK RCC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RCC_IRQHandler
+ B RCC_IRQHandler
+
+ PUBWEAK EXTI0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI0_IRQHandler
+ B EXTI0_IRQHandler
+
+ PUBWEAK EXTI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI1_IRQHandler
+ B EXTI1_IRQHandler
+
+ PUBWEAK EXTI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI2_IRQHandler
+ B EXTI2_IRQHandler
+
+ PUBWEAK EXTI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI3_IRQHandler
+ B EXTI3_IRQHandler
+
+ PUBWEAK EXTI4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI4_IRQHandler
+ B EXTI4_IRQHandler
+
+ PUBWEAK DMA1_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel1_IRQHandler
+ B DMA1_Channel1_IRQHandler
+
+ PUBWEAK DMA1_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel2_IRQHandler
+ B DMA1_Channel2_IRQHandler
+
+ PUBWEAK DMA1_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel3_IRQHandler
+ B DMA1_Channel3_IRQHandler
+
+ PUBWEAK DMA1_Channel4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel4_IRQHandler
+ B DMA1_Channel4_IRQHandler
+
+ PUBWEAK DMA1_Channel5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel5_IRQHandler
+ B DMA1_Channel5_IRQHandler
+
+ PUBWEAK DMA1_Channel6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel6_IRQHandler
+ B DMA1_Channel6_IRQHandler
+
+ PUBWEAK DMA1_Channel7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel7_IRQHandler
+ B DMA1_Channel7_IRQHandler
+
+ PUBWEAK ADC1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ADC1_IRQHandler
+ B ADC1_IRQHandler
+
+ PUBWEAK USB_HP_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USB_HP_IRQHandler
+ B USB_HP_IRQHandler
+
+ PUBWEAK USB_LP_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USB_LP_IRQHandler
+ B USB_LP_IRQHandler
+
+ PUBWEAK EXTI9_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI9_5_IRQHandler
+ B EXTI9_5_IRQHandler
+
+ PUBWEAK TIM2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM2_IRQHandler
+ B TIM2_IRQHandler
+
+ PUBWEAK TIM3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM3_IRQHandler
+ B TIM3_IRQHandler
+
+ PUBWEAK TIM4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM4_IRQHandler
+ B TIM4_IRQHandler
+
+ PUBWEAK I2C1_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_EV_IRQHandler
+ B I2C1_EV_IRQHandler
+
+ PUBWEAK I2C1_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_ER_IRQHandler
+ B I2C1_ER_IRQHandler
+
+ PUBWEAK I2C2_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_EV_IRQHandler
+ B I2C2_EV_IRQHandler
+
+ PUBWEAK I2C2_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_ER_IRQHandler
+ B I2C2_ER_IRQHandler
+
+ PUBWEAK SPI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI1_IRQHandler
+ B SPI1_IRQHandler
+
+ PUBWEAK SPI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI2_IRQHandler
+ B SPI2_IRQHandler
+
+ PUBWEAK USART1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART1_IRQHandler
+ B USART1_IRQHandler
+
+ PUBWEAK USART2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART2_IRQHandler
+ B USART2_IRQHandler
+
+ PUBWEAK USART3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART3_IRQHandler
+ B USART3_IRQHandler
+
+ PUBWEAK EXTI15_10_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI15_10_IRQHandler
+ B EXTI15_10_IRQHandler
+
+ PUBWEAK RTC_Alarm_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_Alarm_IRQHandler
+ B RTC_Alarm_IRQHandler
+
+ PUBWEAK USBWakeUp_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USBWakeUp_IRQHandler
+ B USBWakeUp_IRQHandler
+
+ END
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103x6.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103x6.s
new file mode 100644
index 0000000..14b1653
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103x6.s
@@ -0,0 +1,385 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f103x6.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F103x6 Performance Line Devices vector table for EWARM
+;* toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Configure the clock system
+;* - Set the initial PC == __iar_program_start,
+;* - Set the vector table entries with the exceptions ISR
+;* address.
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;*
+;*******************************************************************************
+;
+;
+; The modules in this file are included in the libraries, and may be replaced
+; by any user-defined modules that define the PUBLIC symbol _program_start or
+; a user defined start symbol.
+; To override the cstartup defined in the library, simply add your modified
+; version to the workbench project.
+;
+; The vector table is normally located at address 0.
+; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
+; The name "__vector_table" has special meaning for C-SPY:
+; it is where the SP start value is found, and the NVIC vector
+; table register (VTOR) is initialized to this address if != 0.
+;
+; Cortex-M version
+;
+
+ MODULE ?cstartup
+
+ ;; Forward declaration of sections.
+ SECTION CSTACK:DATA:NOROOT(3)
+
+ SECTION .intvec:CODE:NOROOT(2)
+
+ EXTERN __iar_program_start
+ EXTERN SystemInit
+ PUBLIC __vector_table
+
+ DATA
+__vector_table
+ DCD sfe(CSTACK)
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_2_IRQHandler ; ADC1 & ADC2
+ DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
+ DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
+ DCD CAN1_RX1_IRQHandler ; CAN1 RX1
+ DCD CAN1_SCE_IRQHandler ; CAN1 SCE
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD TIM1_BRK_IRQHandler ; TIM1 Break
+ DCD TIM1_UP_IRQHandler ; TIM1 Update
+ DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
+ DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD 0 ; Reserved
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SPI1_IRQHandler ; SPI1
+ DCD 0 ; Reserved
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD 0 ; Reserved
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Default interrupt handlers.
+;;
+ THUMB
+
+ PUBWEAK Reset_Handler
+ SECTION .text:CODE:REORDER:NOROOT(2)
+Reset_Handler
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__iar_program_start
+ BX R0
+
+ PUBWEAK NMI_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+NMI_Handler
+ B NMI_Handler
+
+ PUBWEAK HardFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+HardFault_Handler
+ B HardFault_Handler
+
+ PUBWEAK MemManage_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+MemManage_Handler
+ B MemManage_Handler
+
+ PUBWEAK BusFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+BusFault_Handler
+ B BusFault_Handler
+
+ PUBWEAK UsageFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UsageFault_Handler
+ B UsageFault_Handler
+
+ PUBWEAK SVC_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SVC_Handler
+ B SVC_Handler
+
+ PUBWEAK DebugMon_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DebugMon_Handler
+ B DebugMon_Handler
+
+ PUBWEAK PendSV_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PendSV_Handler
+ B PendSV_Handler
+
+ PUBWEAK SysTick_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SysTick_Handler
+ B SysTick_Handler
+
+ PUBWEAK WWDG_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+WWDG_IRQHandler
+ B WWDG_IRQHandler
+
+ PUBWEAK PVD_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PVD_IRQHandler
+ B PVD_IRQHandler
+
+ PUBWEAK TAMPER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TAMPER_IRQHandler
+ B TAMPER_IRQHandler
+
+ PUBWEAK RTC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_IRQHandler
+ B RTC_IRQHandler
+
+ PUBWEAK FLASH_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+FLASH_IRQHandler
+ B FLASH_IRQHandler
+
+ PUBWEAK RCC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RCC_IRQHandler
+ B RCC_IRQHandler
+
+ PUBWEAK EXTI0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI0_IRQHandler
+ B EXTI0_IRQHandler
+
+ PUBWEAK EXTI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI1_IRQHandler
+ B EXTI1_IRQHandler
+
+ PUBWEAK EXTI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI2_IRQHandler
+ B EXTI2_IRQHandler
+
+ PUBWEAK EXTI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI3_IRQHandler
+ B EXTI3_IRQHandler
+
+ PUBWEAK EXTI4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI4_IRQHandler
+ B EXTI4_IRQHandler
+
+ PUBWEAK DMA1_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel1_IRQHandler
+ B DMA1_Channel1_IRQHandler
+
+ PUBWEAK DMA1_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel2_IRQHandler
+ B DMA1_Channel2_IRQHandler
+
+ PUBWEAK DMA1_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel3_IRQHandler
+ B DMA1_Channel3_IRQHandler
+
+ PUBWEAK DMA1_Channel4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel4_IRQHandler
+ B DMA1_Channel4_IRQHandler
+
+ PUBWEAK DMA1_Channel5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel5_IRQHandler
+ B DMA1_Channel5_IRQHandler
+
+ PUBWEAK DMA1_Channel6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel6_IRQHandler
+ B DMA1_Channel6_IRQHandler
+
+ PUBWEAK DMA1_Channel7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel7_IRQHandler
+ B DMA1_Channel7_IRQHandler
+
+ PUBWEAK ADC1_2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ADC1_2_IRQHandler
+ B ADC1_2_IRQHandler
+
+ PUBWEAK USB_HP_CAN1_TX_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USB_HP_CAN1_TX_IRQHandler
+ B USB_HP_CAN1_TX_IRQHandler
+
+ PUBWEAK USB_LP_CAN1_RX0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USB_LP_CAN1_RX0_IRQHandler
+ B USB_LP_CAN1_RX0_IRQHandler
+
+ PUBWEAK CAN1_RX1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN1_RX1_IRQHandler
+ B CAN1_RX1_IRQHandler
+
+ PUBWEAK CAN1_SCE_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN1_SCE_IRQHandler
+ B CAN1_SCE_IRQHandler
+
+ PUBWEAK EXTI9_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI9_5_IRQHandler
+ B EXTI9_5_IRQHandler
+
+ PUBWEAK TIM1_BRK_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_BRK_IRQHandler
+ B TIM1_BRK_IRQHandler
+
+ PUBWEAK TIM1_UP_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_UP_IRQHandler
+ B TIM1_UP_IRQHandler
+
+ PUBWEAK TIM1_TRG_COM_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_TRG_COM_IRQHandler
+ B TIM1_TRG_COM_IRQHandler
+
+ PUBWEAK TIM1_CC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_CC_IRQHandler
+ B TIM1_CC_IRQHandler
+
+ PUBWEAK TIM2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM2_IRQHandler
+ B TIM2_IRQHandler
+
+ PUBWEAK TIM3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM3_IRQHandler
+ B TIM3_IRQHandler
+
+ PUBWEAK I2C1_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_EV_IRQHandler
+ B I2C1_EV_IRQHandler
+
+ PUBWEAK I2C1_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_ER_IRQHandler
+ B I2C1_ER_IRQHandler
+
+ PUBWEAK SPI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI1_IRQHandler
+ B SPI1_IRQHandler
+
+ PUBWEAK USART1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART1_IRQHandler
+ B USART1_IRQHandler
+
+ PUBWEAK USART2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART2_IRQHandler
+ B USART2_IRQHandler
+
+ PUBWEAK EXTI15_10_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI15_10_IRQHandler
+ B EXTI15_10_IRQHandler
+
+ PUBWEAK RTC_Alarm_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_Alarm_IRQHandler
+ B RTC_Alarm_IRQHandler
+
+ PUBWEAK USBWakeUp_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USBWakeUp_IRQHandler
+ B USBWakeUp_IRQHandler
+
+ END
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103xb.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103xb.s
new file mode 100644
index 0000000..101a3d5
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103xb.s
@@ -0,0 +1,410 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f103xb.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F103xB Performance Line Devices vector table for
+;* EWARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Configure the clock system
+;* - Set the initial PC == __iar_program_start,
+;* - Set the vector table entries with the exceptions ISR
+;* address.
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;*
+;*******************************************************************************
+;
+;
+; The modules in this file are included in the libraries, and may be replaced
+; by any user-defined modules that define the PUBLIC symbol _program_start or
+; a user defined start symbol.
+; To override the cstartup defined in the library, simply add your modified
+; version to the workbench project.
+;
+; The vector table is normally located at address 0.
+; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
+; The name "__vector_table" has special meaning for C-SPY:
+; it is where the SP start value is found, and the NVIC vector
+; table register (VTOR) is initialized to this address if != 0.
+;
+; Cortex-M version
+;
+
+ MODULE ?cstartup
+
+ ;; Forward declaration of sections.
+ SECTION CSTACK:DATA:NOROOT(3)
+
+ SECTION .intvec:CODE:NOROOT(2)
+
+ EXTERN __iar_program_start
+ EXTERN SystemInit
+ PUBLIC __vector_table
+
+ DATA
+__vector_table
+ DCD sfe(CSTACK)
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_2_IRQHandler ; ADC1 & ADC2
+ DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
+ DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
+ DCD CAN1_RX1_IRQHandler ; CAN1 RX1
+ DCD CAN1_SCE_IRQHandler ; CAN1 SCE
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD TIM1_BRK_IRQHandler ; TIM1 Break
+ DCD TIM1_UP_IRQHandler ; TIM1 Update
+ DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
+ DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C2 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Default interrupt handlers.
+;;
+ THUMB
+
+ PUBWEAK Reset_Handler
+ SECTION .text:CODE:REORDER:NOROOT(2)
+Reset_Handler
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__iar_program_start
+ BX R0
+
+ PUBWEAK NMI_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+NMI_Handler
+ B NMI_Handler
+
+ PUBWEAK HardFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+HardFault_Handler
+ B HardFault_Handler
+
+ PUBWEAK MemManage_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+MemManage_Handler
+ B MemManage_Handler
+
+ PUBWEAK BusFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+BusFault_Handler
+ B BusFault_Handler
+
+ PUBWEAK UsageFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UsageFault_Handler
+ B UsageFault_Handler
+
+ PUBWEAK SVC_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SVC_Handler
+ B SVC_Handler
+
+ PUBWEAK DebugMon_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DebugMon_Handler
+ B DebugMon_Handler
+
+ PUBWEAK PendSV_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PendSV_Handler
+ B PendSV_Handler
+
+ PUBWEAK SysTick_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SysTick_Handler
+ B SysTick_Handler
+
+ PUBWEAK WWDG_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+WWDG_IRQHandler
+ B WWDG_IRQHandler
+
+ PUBWEAK PVD_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PVD_IRQHandler
+ B PVD_IRQHandler
+
+ PUBWEAK TAMPER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TAMPER_IRQHandler
+ B TAMPER_IRQHandler
+
+ PUBWEAK RTC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_IRQHandler
+ B RTC_IRQHandler
+
+ PUBWEAK FLASH_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+FLASH_IRQHandler
+ B FLASH_IRQHandler
+
+ PUBWEAK RCC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RCC_IRQHandler
+ B RCC_IRQHandler
+
+ PUBWEAK EXTI0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI0_IRQHandler
+ B EXTI0_IRQHandler
+
+ PUBWEAK EXTI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI1_IRQHandler
+ B EXTI1_IRQHandler
+
+ PUBWEAK EXTI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI2_IRQHandler
+ B EXTI2_IRQHandler
+
+ PUBWEAK EXTI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI3_IRQHandler
+ B EXTI3_IRQHandler
+
+ PUBWEAK EXTI4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI4_IRQHandler
+ B EXTI4_IRQHandler
+
+ PUBWEAK DMA1_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel1_IRQHandler
+ B DMA1_Channel1_IRQHandler
+
+ PUBWEAK DMA1_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel2_IRQHandler
+ B DMA1_Channel2_IRQHandler
+
+ PUBWEAK DMA1_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel3_IRQHandler
+ B DMA1_Channel3_IRQHandler
+
+ PUBWEAK DMA1_Channel4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel4_IRQHandler
+ B DMA1_Channel4_IRQHandler
+
+ PUBWEAK DMA1_Channel5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel5_IRQHandler
+ B DMA1_Channel5_IRQHandler
+
+ PUBWEAK DMA1_Channel6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel6_IRQHandler
+ B DMA1_Channel6_IRQHandler
+
+ PUBWEAK DMA1_Channel7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel7_IRQHandler
+ B DMA1_Channel7_IRQHandler
+
+ PUBWEAK ADC1_2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ADC1_2_IRQHandler
+ B ADC1_2_IRQHandler
+
+ PUBWEAK USB_HP_CAN1_TX_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USB_HP_CAN1_TX_IRQHandler
+ B USB_HP_CAN1_TX_IRQHandler
+
+ PUBWEAK USB_LP_CAN1_RX0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USB_LP_CAN1_RX0_IRQHandler
+ B USB_LP_CAN1_RX0_IRQHandler
+
+ PUBWEAK CAN1_RX1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN1_RX1_IRQHandler
+ B CAN1_RX1_IRQHandler
+
+ PUBWEAK CAN1_SCE_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN1_SCE_IRQHandler
+ B CAN1_SCE_IRQHandler
+
+ PUBWEAK EXTI9_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI9_5_IRQHandler
+ B EXTI9_5_IRQHandler
+
+ PUBWEAK TIM1_BRK_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_BRK_IRQHandler
+ B TIM1_BRK_IRQHandler
+
+ PUBWEAK TIM1_UP_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_UP_IRQHandler
+ B TIM1_UP_IRQHandler
+
+ PUBWEAK TIM1_TRG_COM_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_TRG_COM_IRQHandler
+ B TIM1_TRG_COM_IRQHandler
+
+ PUBWEAK TIM1_CC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_CC_IRQHandler
+ B TIM1_CC_IRQHandler
+
+ PUBWEAK TIM2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM2_IRQHandler
+ B TIM2_IRQHandler
+
+ PUBWEAK TIM3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM3_IRQHandler
+ B TIM3_IRQHandler
+
+ PUBWEAK TIM4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM4_IRQHandler
+ B TIM4_IRQHandler
+
+ PUBWEAK I2C1_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_EV_IRQHandler
+ B I2C1_EV_IRQHandler
+
+ PUBWEAK I2C1_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_ER_IRQHandler
+ B I2C1_ER_IRQHandler
+
+ PUBWEAK I2C2_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_EV_IRQHandler
+ B I2C2_EV_IRQHandler
+
+ PUBWEAK I2C2_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_ER_IRQHandler
+ B I2C2_ER_IRQHandler
+
+ PUBWEAK SPI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI1_IRQHandler
+ B SPI1_IRQHandler
+
+ PUBWEAK SPI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI2_IRQHandler
+ B SPI2_IRQHandler
+
+ PUBWEAK USART1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART1_IRQHandler
+ B USART1_IRQHandler
+
+ PUBWEAK USART2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART2_IRQHandler
+ B USART2_IRQHandler
+
+ PUBWEAK USART3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART3_IRQHandler
+ B USART3_IRQHandler
+
+ PUBWEAK EXTI15_10_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI15_10_IRQHandler
+ B EXTI15_10_IRQHandler
+
+ PUBWEAK RTC_Alarm_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_Alarm_IRQHandler
+ B RTC_Alarm_IRQHandler
+
+ PUBWEAK USBWakeUp_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USBWakeUp_IRQHandler
+ B USBWakeUp_IRQHandler
+
+ END
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103xe.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103xe.s
new file mode 100644
index 0000000..f5ee1e8
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103xe.s
@@ -0,0 +1,515 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f103xe.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F103xE Performance Line Devices vector table for EWARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == __iar_program_start,
+;* - Set the vector table entries with the exceptions ISR
+;* address.
+;* - Configure the system clock
+;* - Branches to main in the C library (which eventually
+;* calls main()).
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;*
+;*******************************************************************************
+;
+;
+; The modules in this file are included in the libraries, and may be replaced
+; by any user-defined modules that define the PUBLIC symbol _program_start or
+; a user defined start symbol.
+; To override the cstartup defined in the library, simply add your modified
+; version to the workbench project.
+;
+; The vector table is normally located at address 0.
+; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
+; The name "__vector_table" has special meaning for C-SPY:
+; it is where the SP start value is found, and the NVIC vector
+; table register (VTOR) is initialized to this address if != 0.
+;
+; Cortex-M version
+;
+
+ MODULE ?cstartup
+
+ ;; Forward declaration of sections.
+ SECTION CSTACK:DATA:NOROOT(3)
+
+ SECTION .intvec:CODE:NOROOT(2)
+
+ EXTERN __iar_program_start
+ EXTERN SystemInit
+ PUBLIC __vector_table
+
+ DATA
+
+__vector_table
+ DCD sfe(CSTACK)
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_2_IRQHandler ; ADC1 & ADC2
+ DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
+ DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
+ DCD CAN1_RX1_IRQHandler ; CAN1 RX1
+ DCD CAN1_SCE_IRQHandler ; CAN1 SCE
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD TIM1_BRK_IRQHandler ; TIM1 Break
+ DCD TIM1_UP_IRQHandler ; TIM1 Update
+ DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
+ DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C2 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
+ DCD TIM8_BRK_IRQHandler ; TIM8 Break
+ DCD TIM8_UP_IRQHandler ; TIM8 Update
+ DCD TIM8_TRG_COM_IRQHandler ; TIM8 Trigger and Commutation
+ DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare
+ DCD ADC3_IRQHandler ; ADC3
+ DCD FSMC_IRQHandler ; FSMC
+ DCD SDIO_IRQHandler ; SDIO
+ DCD TIM5_IRQHandler ; TIM5
+ DCD SPI3_IRQHandler ; SPI3
+ DCD UART4_IRQHandler ; UART4
+ DCD UART5_IRQHandler ; UART5
+ DCD TIM6_IRQHandler ; TIM6
+ DCD TIM7_IRQHandler ; TIM7
+ DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
+ DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
+ DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
+ DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Default interrupt handlers.
+;;
+ THUMB
+
+ PUBWEAK Reset_Handler
+ SECTION .text:CODE:REORDER:NOROOT(2)
+Reset_Handler
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__iar_program_start
+ BX R0
+
+ PUBWEAK NMI_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+NMI_Handler
+ B NMI_Handler
+
+ PUBWEAK HardFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+HardFault_Handler
+ B HardFault_Handler
+
+ PUBWEAK MemManage_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+MemManage_Handler
+ B MemManage_Handler
+
+ PUBWEAK BusFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+BusFault_Handler
+ B BusFault_Handler
+
+ PUBWEAK UsageFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UsageFault_Handler
+ B UsageFault_Handler
+
+ PUBWEAK SVC_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SVC_Handler
+ B SVC_Handler
+
+ PUBWEAK DebugMon_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DebugMon_Handler
+ B DebugMon_Handler
+
+ PUBWEAK PendSV_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PendSV_Handler
+ B PendSV_Handler
+
+ PUBWEAK SysTick_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SysTick_Handler
+ B SysTick_Handler
+
+ PUBWEAK WWDG_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+WWDG_IRQHandler
+ B WWDG_IRQHandler
+
+ PUBWEAK PVD_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PVD_IRQHandler
+ B PVD_IRQHandler
+
+ PUBWEAK TAMPER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TAMPER_IRQHandler
+ B TAMPER_IRQHandler
+
+ PUBWEAK RTC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_IRQHandler
+ B RTC_IRQHandler
+
+ PUBWEAK FLASH_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+FLASH_IRQHandler
+ B FLASH_IRQHandler
+
+ PUBWEAK RCC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RCC_IRQHandler
+ B RCC_IRQHandler
+
+ PUBWEAK EXTI0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI0_IRQHandler
+ B EXTI0_IRQHandler
+
+ PUBWEAK EXTI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI1_IRQHandler
+ B EXTI1_IRQHandler
+
+ PUBWEAK EXTI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI2_IRQHandler
+ B EXTI2_IRQHandler
+
+ PUBWEAK EXTI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI3_IRQHandler
+ B EXTI3_IRQHandler
+
+ PUBWEAK EXTI4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI4_IRQHandler
+ B EXTI4_IRQHandler
+
+ PUBWEAK DMA1_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel1_IRQHandler
+ B DMA1_Channel1_IRQHandler
+
+ PUBWEAK DMA1_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel2_IRQHandler
+ B DMA1_Channel2_IRQHandler
+
+ PUBWEAK DMA1_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel3_IRQHandler
+ B DMA1_Channel3_IRQHandler
+
+ PUBWEAK DMA1_Channel4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel4_IRQHandler
+ B DMA1_Channel4_IRQHandler
+
+ PUBWEAK DMA1_Channel5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel5_IRQHandler
+ B DMA1_Channel5_IRQHandler
+
+ PUBWEAK DMA1_Channel6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel6_IRQHandler
+ B DMA1_Channel6_IRQHandler
+
+ PUBWEAK DMA1_Channel7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel7_IRQHandler
+ B DMA1_Channel7_IRQHandler
+
+ PUBWEAK ADC1_2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ADC1_2_IRQHandler
+ B ADC1_2_IRQHandler
+
+ PUBWEAK USB_HP_CAN1_TX_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USB_HP_CAN1_TX_IRQHandler
+ B USB_HP_CAN1_TX_IRQHandler
+
+ PUBWEAK USB_LP_CAN1_RX0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USB_LP_CAN1_RX0_IRQHandler
+ B USB_LP_CAN1_RX0_IRQHandler
+
+ PUBWEAK CAN1_RX1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN1_RX1_IRQHandler
+ B CAN1_RX1_IRQHandler
+
+ PUBWEAK CAN1_SCE_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN1_SCE_IRQHandler
+ B CAN1_SCE_IRQHandler
+
+ PUBWEAK EXTI9_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI9_5_IRQHandler
+ B EXTI9_5_IRQHandler
+
+ PUBWEAK TIM1_BRK_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_BRK_IRQHandler
+ B TIM1_BRK_IRQHandler
+
+ PUBWEAK TIM1_UP_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_UP_IRQHandler
+ B TIM1_UP_IRQHandler
+
+ PUBWEAK TIM1_TRG_COM_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_TRG_COM_IRQHandler
+ B TIM1_TRG_COM_IRQHandler
+
+ PUBWEAK TIM1_CC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_CC_IRQHandler
+ B TIM1_CC_IRQHandler
+
+ PUBWEAK TIM2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM2_IRQHandler
+ B TIM2_IRQHandler
+
+ PUBWEAK TIM3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM3_IRQHandler
+ B TIM3_IRQHandler
+
+ PUBWEAK TIM4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM4_IRQHandler
+ B TIM4_IRQHandler
+
+ PUBWEAK I2C1_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_EV_IRQHandler
+ B I2C1_EV_IRQHandler
+
+ PUBWEAK I2C1_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_ER_IRQHandler
+ B I2C1_ER_IRQHandler
+
+ PUBWEAK I2C2_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_EV_IRQHandler
+ B I2C2_EV_IRQHandler
+
+ PUBWEAK I2C2_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_ER_IRQHandler
+ B I2C2_ER_IRQHandler
+
+ PUBWEAK SPI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI1_IRQHandler
+ B SPI1_IRQHandler
+
+ PUBWEAK SPI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI2_IRQHandler
+ B SPI2_IRQHandler
+
+ PUBWEAK USART1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART1_IRQHandler
+ B USART1_IRQHandler
+
+ PUBWEAK USART2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART2_IRQHandler
+ B USART2_IRQHandler
+
+ PUBWEAK USART3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART3_IRQHandler
+ B USART3_IRQHandler
+
+ PUBWEAK EXTI15_10_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI15_10_IRQHandler
+ B EXTI15_10_IRQHandler
+
+ PUBWEAK RTC_Alarm_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_Alarm_IRQHandler
+ B RTC_Alarm_IRQHandler
+
+ PUBWEAK USBWakeUp_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USBWakeUp_IRQHandler
+ B USBWakeUp_IRQHandler
+
+ PUBWEAK TIM8_BRK_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM8_BRK_IRQHandler
+ B TIM8_BRK_IRQHandler
+
+ PUBWEAK TIM8_UP_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM8_UP_IRQHandler
+ B TIM8_UP_IRQHandler
+
+ PUBWEAK TIM8_TRG_COM_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM8_TRG_COM_IRQHandler
+ B TIM8_TRG_COM_IRQHandler
+
+ PUBWEAK TIM8_CC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM8_CC_IRQHandler
+ B TIM8_CC_IRQHandler
+
+ PUBWEAK ADC3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ADC3_IRQHandler
+ B ADC3_IRQHandler
+
+ PUBWEAK FSMC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+FSMC_IRQHandler
+ B FSMC_IRQHandler
+
+ PUBWEAK SDIO_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SDIO_IRQHandler
+ B SDIO_IRQHandler
+
+ PUBWEAK TIM5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM5_IRQHandler
+ B TIM5_IRQHandler
+
+ PUBWEAK SPI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI3_IRQHandler
+ B SPI3_IRQHandler
+
+ PUBWEAK UART4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UART4_IRQHandler
+ B UART4_IRQHandler
+
+ PUBWEAK UART5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UART5_IRQHandler
+ B UART5_IRQHandler
+
+ PUBWEAK TIM6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM6_IRQHandler
+ B TIM6_IRQHandler
+
+ PUBWEAK TIM7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM7_IRQHandler
+ B TIM7_IRQHandler
+
+ PUBWEAK DMA2_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel1_IRQHandler
+ B DMA2_Channel1_IRQHandler
+
+ PUBWEAK DMA2_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel2_IRQHandler
+ B DMA2_Channel2_IRQHandler
+
+ PUBWEAK DMA2_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel3_IRQHandler
+ B DMA2_Channel3_IRQHandler
+
+ PUBWEAK DMA2_Channel4_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel4_5_IRQHandler
+ B DMA2_Channel4_5_IRQHandler
+
+
+ END
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103xg.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103xg.s
new file mode 100644
index 0000000..f745b4b
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f103xg.s
@@ -0,0 +1,512 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
+;* File Name : startup_stm32f103xg.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F103xG Performances Line Devices vector table for EWARM
+;* toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == __iar_program_start,
+;* - Set the vector table entries with the exceptions ISR address,
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;*
+;*******************************************************************************
+;
+;
+; The modules in this file are included in the libraries, and may be replaced
+; by any user-defined modules that define the PUBLIC symbol _program_start or
+; a user defined start symbol.
+; To override the cstartup defined in the library, simply add your modified
+; version to the workbench project.
+;
+; The vector table is normally located at address 0.
+; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
+; The name "__vector_table" has special meaning for C-SPY:
+; it is where the SP start value is found, and the NVIC vector
+; table register (VTOR) is initialized to this address if != 0.
+;
+; Cortex-M version
+;
+
+ MODULE ?cstartup
+
+ ;; Forward declaration of sections.
+ SECTION CSTACK:DATA:NOROOT(3)
+
+ SECTION .intvec:CODE:NOROOT(2)
+
+ EXTERN __iar_program_start
+ EXTERN SystemInit
+ PUBLIC __vector_table
+
+ DATA
+
+__vector_table
+ DCD sfe(CSTACK)
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_2_IRQHandler ; ADC1 & ADC2
+ DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
+ DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
+ DCD CAN1_RX1_IRQHandler ; CAN1 RX1
+ DCD CAN1_SCE_IRQHandler ; CAN1 SCE
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD TIM1_BRK_TIM9_IRQHandler ; TIM1 Break and TIM9
+ DCD TIM1_UP_TIM10_IRQHandler ; TIM1 Update and TIM10
+ DCD TIM1_TRG_COM_TIM11_IRQHandler ; TIM1 Trigger and Commutation and TIM11
+ DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C2 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
+ DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
+ DCD TIM8_BRK_TIM12_IRQHandler ; TIM8 Break and TIM12
+ DCD TIM8_UP_TIM13_IRQHandler ; TIM8 Update and TIM13
+ DCD TIM8_TRG_COM_TIM14_IRQHandler ; TIM8 Trigger and Commutation and TIM14
+ DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare
+ DCD ADC3_IRQHandler ; ADC3
+ DCD FSMC_IRQHandler ; FSMC
+ DCD SDIO_IRQHandler ; SDIO
+ DCD TIM5_IRQHandler ; TIM5
+ DCD SPI3_IRQHandler ; SPI3
+ DCD UART4_IRQHandler ; UART4
+ DCD UART5_IRQHandler ; UART5
+ DCD TIM6_IRQHandler ; TIM6
+ DCD TIM7_IRQHandler ; TIM7
+ DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
+ DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
+ DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
+ DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Default interrupt handlers.
+;;
+ THUMB
+
+ PUBWEAK Reset_Handler
+ SECTION .text:CODE:REORDER:NOROOT(2)
+Reset_Handler
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__iar_program_start
+ BX R0
+
+ PUBWEAK NMI_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+NMI_Handler
+ B NMI_Handler
+
+ PUBWEAK HardFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+HardFault_Handler
+ B HardFault_Handler
+
+ PUBWEAK MemManage_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+MemManage_Handler
+ B MemManage_Handler
+
+ PUBWEAK BusFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+BusFault_Handler
+ B BusFault_Handler
+
+ PUBWEAK UsageFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UsageFault_Handler
+ B UsageFault_Handler
+
+ PUBWEAK SVC_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SVC_Handler
+ B SVC_Handler
+
+ PUBWEAK DebugMon_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DebugMon_Handler
+ B DebugMon_Handler
+
+ PUBWEAK PendSV_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PendSV_Handler
+ B PendSV_Handler
+
+ PUBWEAK SysTick_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SysTick_Handler
+ B SysTick_Handler
+
+ PUBWEAK WWDG_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+WWDG_IRQHandler
+ B WWDG_IRQHandler
+
+ PUBWEAK PVD_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PVD_IRQHandler
+ B PVD_IRQHandler
+
+ PUBWEAK TAMPER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TAMPER_IRQHandler
+ B TAMPER_IRQHandler
+
+ PUBWEAK RTC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_IRQHandler
+ B RTC_IRQHandler
+
+ PUBWEAK FLASH_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+FLASH_IRQHandler
+ B FLASH_IRQHandler
+
+ PUBWEAK RCC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RCC_IRQHandler
+ B RCC_IRQHandler
+
+ PUBWEAK EXTI0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI0_IRQHandler
+ B EXTI0_IRQHandler
+
+ PUBWEAK EXTI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI1_IRQHandler
+ B EXTI1_IRQHandler
+
+ PUBWEAK EXTI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI2_IRQHandler
+ B EXTI2_IRQHandler
+
+ PUBWEAK EXTI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI3_IRQHandler
+ B EXTI3_IRQHandler
+
+ PUBWEAK EXTI4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI4_IRQHandler
+ B EXTI4_IRQHandler
+
+ PUBWEAK DMA1_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel1_IRQHandler
+ B DMA1_Channel1_IRQHandler
+
+ PUBWEAK DMA1_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel2_IRQHandler
+ B DMA1_Channel2_IRQHandler
+
+ PUBWEAK DMA1_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel3_IRQHandler
+ B DMA1_Channel3_IRQHandler
+
+ PUBWEAK DMA1_Channel4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel4_IRQHandler
+ B DMA1_Channel4_IRQHandler
+
+ PUBWEAK DMA1_Channel5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel5_IRQHandler
+ B DMA1_Channel5_IRQHandler
+
+ PUBWEAK DMA1_Channel6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel6_IRQHandler
+ B DMA1_Channel6_IRQHandler
+
+ PUBWEAK DMA1_Channel7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel7_IRQHandler
+ B DMA1_Channel7_IRQHandler
+
+ PUBWEAK ADC1_2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ADC1_2_IRQHandler
+ B ADC1_2_IRQHandler
+
+ PUBWEAK USB_HP_CAN1_TX_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USB_HP_CAN1_TX_IRQHandler
+ B USB_HP_CAN1_TX_IRQHandler
+
+ PUBWEAK USB_LP_CAN1_RX0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USB_LP_CAN1_RX0_IRQHandler
+ B USB_LP_CAN1_RX0_IRQHandler
+
+ PUBWEAK CAN1_RX1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN1_RX1_IRQHandler
+ B CAN1_RX1_IRQHandler
+
+ PUBWEAK CAN1_SCE_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN1_SCE_IRQHandler
+ B CAN1_SCE_IRQHandler
+
+ PUBWEAK EXTI9_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI9_5_IRQHandler
+ B EXTI9_5_IRQHandler
+
+ PUBWEAK TIM1_BRK_TIM9_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_BRK_TIM9_IRQHandler
+ B TIM1_BRK_TIM9_IRQHandler
+
+ PUBWEAK TIM1_UP_TIM10_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_UP_TIM10_IRQHandler
+ B TIM1_UP_TIM10_IRQHandler
+
+ PUBWEAK TIM1_TRG_COM_TIM11_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_TRG_COM_TIM11_IRQHandler
+ B TIM1_TRG_COM_TIM11_IRQHandler
+
+ PUBWEAK TIM1_CC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_CC_IRQHandler
+ B TIM1_CC_IRQHandler
+
+ PUBWEAK TIM2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM2_IRQHandler
+ B TIM2_IRQHandler
+
+ PUBWEAK TIM3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM3_IRQHandler
+ B TIM3_IRQHandler
+
+ PUBWEAK TIM4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM4_IRQHandler
+ B TIM4_IRQHandler
+
+ PUBWEAK I2C1_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_EV_IRQHandler
+ B I2C1_EV_IRQHandler
+
+ PUBWEAK I2C1_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_ER_IRQHandler
+ B I2C1_ER_IRQHandler
+
+ PUBWEAK I2C2_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_EV_IRQHandler
+ B I2C2_EV_IRQHandler
+
+ PUBWEAK I2C2_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_ER_IRQHandler
+ B I2C2_ER_IRQHandler
+
+ PUBWEAK SPI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI1_IRQHandler
+ B SPI1_IRQHandler
+
+ PUBWEAK SPI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI2_IRQHandler
+ B SPI2_IRQHandler
+
+ PUBWEAK USART1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART1_IRQHandler
+ B USART1_IRQHandler
+
+ PUBWEAK USART2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART2_IRQHandler
+ B USART2_IRQHandler
+
+ PUBWEAK USART3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART3_IRQHandler
+ B USART3_IRQHandler
+
+ PUBWEAK EXTI15_10_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI15_10_IRQHandler
+ B EXTI15_10_IRQHandler
+
+ PUBWEAK RTC_Alarm_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_Alarm_IRQHandler
+ B RTC_Alarm_IRQHandler
+
+ PUBWEAK USBWakeUp_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USBWakeUp_IRQHandler
+ B USBWakeUp_IRQHandler
+
+ PUBWEAK TIM8_BRK_TIM12_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM8_BRK_TIM12_IRQHandler
+ B TIM8_BRK_TIM12_IRQHandler
+
+ PUBWEAK TIM8_UP_TIM13_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM8_UP_TIM13_IRQHandler
+ B TIM8_UP_TIM13_IRQHandler
+
+ PUBWEAK TIM8_TRG_COM_TIM14_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM8_TRG_COM_TIM14_IRQHandler
+ B TIM8_TRG_COM_TIM14_IRQHandler
+
+ PUBWEAK TIM8_CC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM8_CC_IRQHandler
+ B TIM8_CC_IRQHandler
+
+ PUBWEAK ADC3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ADC3_IRQHandler
+ B ADC3_IRQHandler
+
+ PUBWEAK FSMC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+FSMC_IRQHandler
+ B FSMC_IRQHandler
+
+ PUBWEAK SDIO_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SDIO_IRQHandler
+ B SDIO_IRQHandler
+
+ PUBWEAK TIM5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM5_IRQHandler
+ B TIM5_IRQHandler
+
+ PUBWEAK SPI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI3_IRQHandler
+ B SPI3_IRQHandler
+
+ PUBWEAK UART4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UART4_IRQHandler
+ B UART4_IRQHandler
+
+ PUBWEAK UART5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UART5_IRQHandler
+ B UART5_IRQHandler
+
+ PUBWEAK TIM6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM6_IRQHandler
+ B TIM6_IRQHandler
+
+ PUBWEAK TIM7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM7_IRQHandler
+ B TIM7_IRQHandler
+
+ PUBWEAK DMA2_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel1_IRQHandler
+ B DMA2_Channel1_IRQHandler
+
+ PUBWEAK DMA2_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel2_IRQHandler
+ B DMA2_Channel2_IRQHandler
+
+ PUBWEAK DMA2_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel3_IRQHandler
+ B DMA2_Channel3_IRQHandler
+
+ PUBWEAK DMA2_Channel4_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel4_5_IRQHandler
+ B DMA2_Channel4_5_IRQHandler
+
+
+ END
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f105xc.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f105xc.s
new file mode 100644
index 0000000..26302e1
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f105xc.s
@@ -0,0 +1,526 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics *******************
+;* File Name : startup_stm32f105xc.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F105xC Connectivity line devices vector table for
+;* EWARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Configure the clock system
+;* - Set the initial PC == __iar_program_start,
+;* - Set the vector table entries with the exceptions ISR
+;* address.
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;*
+;*******************************************************************************
+;
+;
+; The modules in this file are included in the libraries, and may be replaced
+; by any user-defined modules that define the PUBLIC symbol _program_start or
+; a user defined start symbol.
+; To override the cstartup defined in the library, simply add your modified
+; version to the workbench project.
+;
+; The vector table is normally located at address 0.
+; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
+; The name "__vector_table" has special meaning for C-SPY:
+; it is where the SP start value is found, and the NVIC vector
+; table register (VTOR) is initialized to this address if != 0.
+;
+; Cortex-M version
+;
+
+ MODULE ?cstartup
+
+ ;; Forward declaration of sections.
+ SECTION CSTACK:DATA:NOROOT(3)
+
+ SECTION .intvec:CODE:NOROOT(2)
+
+ EXTERN __iar_program_start
+ EXTERN SystemInit
+ PUBLIC __vector_table
+
+ DATA
+__vector_table
+ DCD sfe(CSTACK)
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_2_IRQHandler ; ADC1 and ADC2
+ DCD CAN1_TX_IRQHandler ; CAN1 TX
+ DCD CAN1_RX0_IRQHandler ; CAN1 RX0
+ DCD CAN1_RX1_IRQHandler ; CAN1 RX1
+ DCD CAN1_SCE_IRQHandler ; CAN1 SCE
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD TIM1_BRK_IRQHandler ; TIM1 Break
+ DCD TIM1_UP_IRQHandler ; TIM1 Update
+ DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
+ DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C1 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC alarm through EXTI line
+ DCD OTG_FS_WKUP_IRQHandler ; USB OTG FS Wakeup through EXTI line
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD TIM5_IRQHandler ; TIM5
+ DCD SPI3_IRQHandler ; SPI3
+ DCD UART4_IRQHandler ; UART4
+ DCD UART5_IRQHandler ; UART5
+ DCD TIM6_IRQHandler ; TIM6
+ DCD TIM7_IRQHandler ; TIM7
+ DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
+ DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
+ DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
+ DCD DMA2_Channel4_IRQHandler ; DMA2 Channel4
+ DCD DMA2_Channel5_IRQHandler ; DMA2 Channel5
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD CAN2_TX_IRQHandler ; CAN2 TX
+ DCD CAN2_RX0_IRQHandler ; CAN2 RX0
+ DCD CAN2_RX1_IRQHandler ; CAN2 RX1
+ DCD CAN2_SCE_IRQHandler ; CAN2 SCE
+ DCD OTG_FS_IRQHandler ; USB OTG FS
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Default interrupt handlers.
+;;
+ THUMB
+
+ PUBWEAK Reset_Handler
+ SECTION .text:CODE:REORDER:NOROOT(2)
+Reset_Handler
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__iar_program_start
+ BX R0
+
+ PUBWEAK NMI_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+NMI_Handler
+ B NMI_Handler
+
+ PUBWEAK HardFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+HardFault_Handler
+ B HardFault_Handler
+
+ PUBWEAK MemManage_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+MemManage_Handler
+ B MemManage_Handler
+
+ PUBWEAK BusFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+BusFault_Handler
+ B BusFault_Handler
+
+ PUBWEAK UsageFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UsageFault_Handler
+ B UsageFault_Handler
+
+ PUBWEAK SVC_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SVC_Handler
+ B SVC_Handler
+
+ PUBWEAK DebugMon_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DebugMon_Handler
+ B DebugMon_Handler
+
+ PUBWEAK PendSV_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PendSV_Handler
+ B PendSV_Handler
+
+ PUBWEAK SysTick_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SysTick_Handler
+ B SysTick_Handler
+
+ PUBWEAK WWDG_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+WWDG_IRQHandler
+ B WWDG_IRQHandler
+
+ PUBWEAK PVD_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PVD_IRQHandler
+ B PVD_IRQHandler
+
+ PUBWEAK TAMPER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TAMPER_IRQHandler
+ B TAMPER_IRQHandler
+
+ PUBWEAK RTC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_IRQHandler
+ B RTC_IRQHandler
+
+ PUBWEAK FLASH_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+FLASH_IRQHandler
+ B FLASH_IRQHandler
+
+ PUBWEAK RCC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RCC_IRQHandler
+ B RCC_IRQHandler
+
+ PUBWEAK EXTI0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI0_IRQHandler
+ B EXTI0_IRQHandler
+
+ PUBWEAK EXTI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI1_IRQHandler
+ B EXTI1_IRQHandler
+
+ PUBWEAK EXTI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI2_IRQHandler
+ B EXTI2_IRQHandler
+
+ PUBWEAK EXTI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI3_IRQHandler
+ B EXTI3_IRQHandler
+
+
+ PUBWEAK EXTI4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI4_IRQHandler
+ B EXTI4_IRQHandler
+
+ PUBWEAK DMA1_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel1_IRQHandler
+ B DMA1_Channel1_IRQHandler
+
+ PUBWEAK DMA1_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel2_IRQHandler
+ B DMA1_Channel2_IRQHandler
+
+ PUBWEAK DMA1_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel3_IRQHandler
+ B DMA1_Channel3_IRQHandler
+
+ PUBWEAK DMA1_Channel4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel4_IRQHandler
+ B DMA1_Channel4_IRQHandler
+
+ PUBWEAK DMA1_Channel5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel5_IRQHandler
+ B DMA1_Channel5_IRQHandler
+
+ PUBWEAK DMA1_Channel6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel6_IRQHandler
+ B DMA1_Channel6_IRQHandler
+
+ PUBWEAK DMA1_Channel7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel7_IRQHandler
+ B DMA1_Channel7_IRQHandler
+
+ PUBWEAK ADC1_2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ADC1_2_IRQHandler
+ B ADC1_2_IRQHandler
+
+ PUBWEAK CAN1_TX_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN1_TX_IRQHandler
+ B CAN1_TX_IRQHandler
+
+ PUBWEAK CAN1_RX0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN1_RX0_IRQHandler
+ B CAN1_RX0_IRQHandler
+
+ PUBWEAK CAN1_RX1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN1_RX1_IRQHandler
+ B CAN1_RX1_IRQHandler
+
+ PUBWEAK CAN1_SCE_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN1_SCE_IRQHandler
+ B CAN1_SCE_IRQHandler
+
+ PUBWEAK EXTI9_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI9_5_IRQHandler
+ B EXTI9_5_IRQHandler
+
+ PUBWEAK TIM1_BRK_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_BRK_IRQHandler
+ B TIM1_BRK_IRQHandler
+
+ PUBWEAK TIM1_UP_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_UP_IRQHandler
+ B TIM1_UP_IRQHandler
+
+ PUBWEAK TIM1_TRG_COM_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_TRG_COM_IRQHandler
+ B TIM1_TRG_COM_IRQHandler
+
+ PUBWEAK TIM1_CC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_CC_IRQHandler
+ B TIM1_CC_IRQHandler
+
+ PUBWEAK TIM2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM2_IRQHandler
+ B TIM2_IRQHandler
+
+ PUBWEAK TIM3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM3_IRQHandler
+ B TIM3_IRQHandler
+
+ PUBWEAK TIM4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM4_IRQHandler
+ B TIM4_IRQHandler
+
+ PUBWEAK I2C1_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_EV_IRQHandler
+ B I2C1_EV_IRQHandler
+
+ PUBWEAK I2C1_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_ER_IRQHandler
+ B I2C1_ER_IRQHandler
+
+ PUBWEAK I2C2_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_EV_IRQHandler
+ B I2C2_EV_IRQHandler
+
+ PUBWEAK I2C2_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_ER_IRQHandler
+ B I2C2_ER_IRQHandler
+
+ PUBWEAK SPI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI1_IRQHandler
+ B SPI1_IRQHandler
+
+ PUBWEAK SPI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI2_IRQHandler
+ B SPI2_IRQHandler
+
+ PUBWEAK USART1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART1_IRQHandler
+ B USART1_IRQHandler
+
+ PUBWEAK USART2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART2_IRQHandler
+ B USART2_IRQHandler
+
+ PUBWEAK USART3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART3_IRQHandler
+ B USART3_IRQHandler
+
+ PUBWEAK EXTI15_10_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI15_10_IRQHandler
+ B EXTI15_10_IRQHandler
+
+ PUBWEAK RTC_Alarm_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_Alarm_IRQHandler
+ B RTC_Alarm_IRQHandler
+
+ PUBWEAK OTG_FS_WKUP_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+OTG_FS_WKUP_IRQHandler
+ B OTG_FS_WKUP_IRQHandler
+
+ PUBWEAK TIM5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM5_IRQHandler
+ B TIM5_IRQHandler
+
+ PUBWEAK SPI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI3_IRQHandler
+ B SPI3_IRQHandler
+
+ PUBWEAK UART4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UART4_IRQHandler
+ B UART4_IRQHandler
+
+ PUBWEAK UART5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UART5_IRQHandler
+ B UART5_IRQHandler
+
+ PUBWEAK TIM6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM6_IRQHandler
+ B TIM6_IRQHandler
+
+ PUBWEAK TIM7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM7_IRQHandler
+ B TIM7_IRQHandler
+
+ PUBWEAK DMA2_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel1_IRQHandler
+ B DMA2_Channel1_IRQHandler
+
+ PUBWEAK DMA2_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel2_IRQHandler
+ B DMA2_Channel2_IRQHandler
+
+ PUBWEAK DMA2_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel3_IRQHandler
+ B DMA2_Channel3_IRQHandler
+
+ PUBWEAK DMA2_Channel4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel4_IRQHandler
+ B DMA2_Channel4_IRQHandler
+
+ PUBWEAK DMA2_Channel5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel5_IRQHandler
+ B DMA2_Channel5_IRQHandler
+
+ PUBWEAK ETH_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ETH_IRQHandler
+ B ETH_IRQHandler
+
+ PUBWEAK ETH_WKUP_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ETH_WKUP_IRQHandler
+ B ETH_WKUP_IRQHandler
+
+ PUBWEAK CAN2_TX_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN2_TX_IRQHandler
+ B CAN2_TX_IRQHandler
+
+ PUBWEAK CAN2_RX0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN2_RX0_IRQHandler
+ B CAN2_RX0_IRQHandler
+
+ PUBWEAK CAN2_RX1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN2_RX1_IRQHandler
+ B CAN2_RX1_IRQHandler
+
+ PUBWEAK CAN2_SCE_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN2_SCE_IRQHandler
+ B CAN2_SCE_IRQHandler
+
+ PUBWEAK OTG_FS_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+OTG_FS_IRQHandler
+ B OTG_FS_IRQHandler
+
+ END
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f107xc.s b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f107xc.s
new file mode 100644
index 0000000..635c0d3
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/iar/startup_stm32f107xc.s
@@ -0,0 +1,526 @@
+;******************** (C) COPYRIGHT 2017 STMicroelectronics *******************
+;* File Name : startup_stm32f107xc.s
+;* Author : MCD Application Team
+;* Version : V4.2.0
+;* Date : 31-March-2017
+;* Description : STM32F107xC Connectivity line devices vector table for
+;* EWARM toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Configure the clock system
+;* - Set the initial PC == __iar_program_start,
+;* - Set the vector table entries with the exceptions ISR
+;* address.
+;* After Reset the Cortex-M3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;*
+;* © COPYRIGHT(c) 2017 STMicroelectronics
+;*
+;* Redistribution and use in source and binary forms, with or without modification,
+;* are permitted provided that the following conditions are met:
+;* 1. Redistributions of source code must retain the above copyright notice,
+;* this list of conditions and the following disclaimer.
+;* 2. 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.
+;* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+;*
+;*******************************************************************************
+;
+;
+; The modules in this file are included in the libraries, and may be replaced
+; by any user-defined modules that define the PUBLIC symbol _program_start or
+; a user defined start symbol.
+; To override the cstartup defined in the library, simply add your modified
+; version to the workbench project.
+;
+; The vector table is normally located at address 0.
+; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
+; The name "__vector_table" has special meaning for C-SPY:
+; it is where the SP start value is found, and the NVIC vector
+; table register (VTOR) is initialized to this address if != 0.
+;
+; Cortex-M version
+;
+
+ MODULE ?cstartup
+
+ ;; Forward declaration of sections.
+ SECTION CSTACK:DATA:NOROOT(3)
+
+ SECTION .intvec:CODE:NOROOT(2)
+
+ EXTERN __iar_program_start
+ EXTERN SystemInit
+ PUBLIC __vector_table
+
+ DATA
+__vector_table
+ DCD sfe(CSTACK)
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; NMI Handler
+ DCD HardFault_Handler ; Hard Fault Handler
+ DCD MemManage_Handler ; MPU Fault Handler
+ DCD BusFault_Handler ; Bus Fault Handler
+ DCD UsageFault_Handler ; Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; SVCall Handler
+ DCD DebugMon_Handler ; Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; PendSV Handler
+ DCD SysTick_Handler ; SysTick Handler
+
+ ; External Interrupts
+ DCD WWDG_IRQHandler ; Window Watchdog
+ DCD PVD_IRQHandler ; PVD through EXTI Line detect
+ DCD TAMPER_IRQHandler ; Tamper
+ DCD RTC_IRQHandler ; RTC
+ DCD FLASH_IRQHandler ; Flash
+ DCD RCC_IRQHandler ; RCC
+ DCD EXTI0_IRQHandler ; EXTI Line 0
+ DCD EXTI1_IRQHandler ; EXTI Line 1
+ DCD EXTI2_IRQHandler ; EXTI Line 2
+ DCD EXTI3_IRQHandler ; EXTI Line 3
+ DCD EXTI4_IRQHandler ; EXTI Line 4
+ DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
+ DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
+ DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
+ DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
+ DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
+ DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
+ DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
+ DCD ADC1_2_IRQHandler ; ADC1 and ADC2
+ DCD CAN1_TX_IRQHandler ; CAN1 TX
+ DCD CAN1_RX0_IRQHandler ; CAN1 RX0
+ DCD CAN1_RX1_IRQHandler ; CAN1 RX1
+ DCD CAN1_SCE_IRQHandler ; CAN1 SCE
+ DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
+ DCD TIM1_BRK_IRQHandler ; TIM1 Break
+ DCD TIM1_UP_IRQHandler ; TIM1 Update
+ DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
+ DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
+ DCD TIM2_IRQHandler ; TIM2
+ DCD TIM3_IRQHandler ; TIM3
+ DCD TIM4_IRQHandler ; TIM4
+ DCD I2C1_EV_IRQHandler ; I2C1 Event
+ DCD I2C1_ER_IRQHandler ; I2C1 Error
+ DCD I2C2_EV_IRQHandler ; I2C2 Event
+ DCD I2C2_ER_IRQHandler ; I2C1 Error
+ DCD SPI1_IRQHandler ; SPI1
+ DCD SPI2_IRQHandler ; SPI2
+ DCD USART1_IRQHandler ; USART1
+ DCD USART2_IRQHandler ; USART2
+ DCD USART3_IRQHandler ; USART3
+ DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
+ DCD RTC_Alarm_IRQHandler ; RTC alarm through EXTI line
+ DCD OTG_FS_WKUP_IRQHandler ; USB OTG FS Wakeup through EXTI line
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD TIM5_IRQHandler ; TIM5
+ DCD SPI3_IRQHandler ; SPI3
+ DCD UART4_IRQHandler ; UART4
+ DCD UART5_IRQHandler ; UART5
+ DCD TIM6_IRQHandler ; TIM6
+ DCD TIM7_IRQHandler ; TIM7
+ DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
+ DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
+ DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
+ DCD DMA2_Channel4_IRQHandler ; DMA2 Channel4
+ DCD DMA2_Channel5_IRQHandler ; DMA2 Channel5
+ DCD ETH_IRQHandler ; Ethernet
+ DCD ETH_WKUP_IRQHandler ; Ethernet Wakeup through EXTI line
+ DCD CAN2_TX_IRQHandler ; CAN2 TX
+ DCD CAN2_RX0_IRQHandler ; CAN2 RX0
+ DCD CAN2_RX1_IRQHandler ; CAN2 RX1
+ DCD CAN2_SCE_IRQHandler ; CAN2 SCE
+ DCD OTG_FS_IRQHandler ; USB OTG FS
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Default interrupt handlers.
+;;
+ THUMB
+
+ PUBWEAK Reset_Handler
+ SECTION .text:CODE:REORDER:NOROOT(2)
+Reset_Handler
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__iar_program_start
+ BX R0
+
+ PUBWEAK NMI_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+NMI_Handler
+ B NMI_Handler
+
+ PUBWEAK HardFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+HardFault_Handler
+ B HardFault_Handler
+
+ PUBWEAK MemManage_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+MemManage_Handler
+ B MemManage_Handler
+
+ PUBWEAK BusFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+BusFault_Handler
+ B BusFault_Handler
+
+ PUBWEAK UsageFault_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UsageFault_Handler
+ B UsageFault_Handler
+
+ PUBWEAK SVC_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SVC_Handler
+ B SVC_Handler
+
+ PUBWEAK DebugMon_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DebugMon_Handler
+ B DebugMon_Handler
+
+ PUBWEAK PendSV_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PendSV_Handler
+ B PendSV_Handler
+
+ PUBWEAK SysTick_Handler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SysTick_Handler
+ B SysTick_Handler
+
+ PUBWEAK WWDG_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+WWDG_IRQHandler
+ B WWDG_IRQHandler
+
+ PUBWEAK PVD_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+PVD_IRQHandler
+ B PVD_IRQHandler
+
+ PUBWEAK TAMPER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TAMPER_IRQHandler
+ B TAMPER_IRQHandler
+
+ PUBWEAK RTC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_IRQHandler
+ B RTC_IRQHandler
+
+ PUBWEAK FLASH_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+FLASH_IRQHandler
+ B FLASH_IRQHandler
+
+ PUBWEAK RCC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RCC_IRQHandler
+ B RCC_IRQHandler
+
+ PUBWEAK EXTI0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI0_IRQHandler
+ B EXTI0_IRQHandler
+
+ PUBWEAK EXTI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI1_IRQHandler
+ B EXTI1_IRQHandler
+
+ PUBWEAK EXTI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI2_IRQHandler
+ B EXTI2_IRQHandler
+
+ PUBWEAK EXTI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI3_IRQHandler
+ B EXTI3_IRQHandler
+
+
+ PUBWEAK EXTI4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI4_IRQHandler
+ B EXTI4_IRQHandler
+
+ PUBWEAK DMA1_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel1_IRQHandler
+ B DMA1_Channel1_IRQHandler
+
+ PUBWEAK DMA1_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel2_IRQHandler
+ B DMA1_Channel2_IRQHandler
+
+ PUBWEAK DMA1_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel3_IRQHandler
+ B DMA1_Channel3_IRQHandler
+
+ PUBWEAK DMA1_Channel4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel4_IRQHandler
+ B DMA1_Channel4_IRQHandler
+
+ PUBWEAK DMA1_Channel5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel5_IRQHandler
+ B DMA1_Channel5_IRQHandler
+
+ PUBWEAK DMA1_Channel6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel6_IRQHandler
+ B DMA1_Channel6_IRQHandler
+
+ PUBWEAK DMA1_Channel7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA1_Channel7_IRQHandler
+ B DMA1_Channel7_IRQHandler
+
+ PUBWEAK ADC1_2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ADC1_2_IRQHandler
+ B ADC1_2_IRQHandler
+
+ PUBWEAK CAN1_TX_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN1_TX_IRQHandler
+ B CAN1_TX_IRQHandler
+
+ PUBWEAK CAN1_RX0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN1_RX0_IRQHandler
+ B CAN1_RX0_IRQHandler
+
+ PUBWEAK CAN1_RX1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN1_RX1_IRQHandler
+ B CAN1_RX1_IRQHandler
+
+ PUBWEAK CAN1_SCE_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN1_SCE_IRQHandler
+ B CAN1_SCE_IRQHandler
+
+ PUBWEAK EXTI9_5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI9_5_IRQHandler
+ B EXTI9_5_IRQHandler
+
+ PUBWEAK TIM1_BRK_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_BRK_IRQHandler
+ B TIM1_BRK_IRQHandler
+
+ PUBWEAK TIM1_UP_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_UP_IRQHandler
+ B TIM1_UP_IRQHandler
+
+ PUBWEAK TIM1_TRG_COM_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_TRG_COM_IRQHandler
+ B TIM1_TRG_COM_IRQHandler
+
+ PUBWEAK TIM1_CC_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM1_CC_IRQHandler
+ B TIM1_CC_IRQHandler
+
+ PUBWEAK TIM2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM2_IRQHandler
+ B TIM2_IRQHandler
+
+ PUBWEAK TIM3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM3_IRQHandler
+ B TIM3_IRQHandler
+
+ PUBWEAK TIM4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM4_IRQHandler
+ B TIM4_IRQHandler
+
+ PUBWEAK I2C1_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_EV_IRQHandler
+ B I2C1_EV_IRQHandler
+
+ PUBWEAK I2C1_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C1_ER_IRQHandler
+ B I2C1_ER_IRQHandler
+
+ PUBWEAK I2C2_EV_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_EV_IRQHandler
+ B I2C2_EV_IRQHandler
+
+ PUBWEAK I2C2_ER_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+I2C2_ER_IRQHandler
+ B I2C2_ER_IRQHandler
+
+ PUBWEAK SPI1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI1_IRQHandler
+ B SPI1_IRQHandler
+
+ PUBWEAK SPI2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI2_IRQHandler
+ B SPI2_IRQHandler
+
+ PUBWEAK USART1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART1_IRQHandler
+ B USART1_IRQHandler
+
+ PUBWEAK USART2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART2_IRQHandler
+ B USART2_IRQHandler
+
+ PUBWEAK USART3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+USART3_IRQHandler
+ B USART3_IRQHandler
+
+ PUBWEAK EXTI15_10_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+EXTI15_10_IRQHandler
+ B EXTI15_10_IRQHandler
+
+ PUBWEAK RTC_Alarm_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+RTC_Alarm_IRQHandler
+ B RTC_Alarm_IRQHandler
+
+ PUBWEAK OTG_FS_WKUP_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+OTG_FS_WKUP_IRQHandler
+ B OTG_FS_WKUP_IRQHandler
+
+ PUBWEAK TIM5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM5_IRQHandler
+ B TIM5_IRQHandler
+
+ PUBWEAK SPI3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+SPI3_IRQHandler
+ B SPI3_IRQHandler
+
+ PUBWEAK UART4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UART4_IRQHandler
+ B UART4_IRQHandler
+
+ PUBWEAK UART5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+UART5_IRQHandler
+ B UART5_IRQHandler
+
+ PUBWEAK TIM6_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM6_IRQHandler
+ B TIM6_IRQHandler
+
+ PUBWEAK TIM7_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+TIM7_IRQHandler
+ B TIM7_IRQHandler
+
+ PUBWEAK DMA2_Channel1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel1_IRQHandler
+ B DMA2_Channel1_IRQHandler
+
+ PUBWEAK DMA2_Channel2_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel2_IRQHandler
+ B DMA2_Channel2_IRQHandler
+
+ PUBWEAK DMA2_Channel3_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel3_IRQHandler
+ B DMA2_Channel3_IRQHandler
+
+ PUBWEAK DMA2_Channel4_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel4_IRQHandler
+ B DMA2_Channel4_IRQHandler
+
+ PUBWEAK DMA2_Channel5_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+DMA2_Channel5_IRQHandler
+ B DMA2_Channel5_IRQHandler
+
+ PUBWEAK ETH_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ETH_IRQHandler
+ B ETH_IRQHandler
+
+ PUBWEAK ETH_WKUP_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+ETH_WKUP_IRQHandler
+ B ETH_WKUP_IRQHandler
+
+ PUBWEAK CAN2_TX_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN2_TX_IRQHandler
+ B CAN2_TX_IRQHandler
+
+ PUBWEAK CAN2_RX0_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN2_RX0_IRQHandler
+ B CAN2_RX0_IRQHandler
+
+ PUBWEAK CAN2_RX1_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN2_RX1_IRQHandler
+ B CAN2_RX1_IRQHandler
+
+ PUBWEAK CAN2_SCE_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+CAN2_SCE_IRQHandler
+ B CAN2_SCE_IRQHandler
+
+ PUBWEAK OTG_FS_IRQHandler
+ SECTION .text:CODE:REORDER:NOROOT(1)
+OTG_FS_IRQHandler
+ B OTG_FS_IRQHandler
+
+ END
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c
new file mode 100644
index 0000000..789b551
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c
@@ -0,0 +1,448 @@
+/**
+ ******************************************************************************
+ * @file system_stm32f1xx.c
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @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_stm32f1xx_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_stm32f1xx_xx.s" file, to
+ * configure the system clock before to branch to main program.
+ *
+ * 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depending on
+ * the product used), refer to "HSE_VALUE".
+ * 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
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup stm32f1xx_system
+ * @{
+ */
+
+/** @addtogroup STM32F1xx_System_Private_Includes
+ * @{
+ */
+
+#include "stm32f1xx.h"
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F1xx_System_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F1xx_System_Private_Defines
+ * @{
+ */
+
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE 8000000U /*!< Default value of the External oscillator in Hz.
+ This value can be provided and adapted by the user application. */
+#endif /* HSE_VALUE */
+
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE 8000000U /*!< Default value of the Internal oscillator in Hz.
+ This value can be provided and adapted by the user application. */
+#endif /* HSI_VALUE */
+
+/*!< Uncomment the following line if you need to use external SRAM */
+#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
+/* #define DATA_IN_ExtSRAM */
+#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
+
+/*!< Uncomment the following line if you need to relocate your vector Table in
+ Internal SRAM. */
+/* #define VECT_TAB_SRAM */
+#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
+ This value must be a multiple of 0x200. */
+
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F1xx_System_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F1xx_System_Private_Variables
+ * @{
+ */
+
+/*******************************************************************************
+* Clock Definitions
+*******************************************************************************/
+#if defined(STM32F100xB) ||defined(STM32F100xE)
+ uint32_t SystemCoreClock = 24000000U; /*!< System Clock Frequency (Core Clock) */
+#else /*!< HSI Selected as System Clock source */
+ uint32_t SystemCoreClock = 72000000U; /*!< System Clock Frequency (Core Clock) */
+#endif
+
+const uint8_t AHBPrescTable[16U] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+const uint8_t APBPrescTable[8U] = {0, 0, 0, 0, 1, 2, 3, 4};
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F1xx_System_Private_FunctionPrototypes
+ * @{
+ */
+
+#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
+#ifdef DATA_IN_ExtSRAM
+ static void SystemInit_ExtMemCtl(void);
+#endif /* DATA_IN_ExtSRAM */
+#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F1xx_System_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Setup the microcontroller system
+ * Initialize the Embedded Flash Interface, the PLL and update the
+ * SystemCoreClock variable.
+ * @note This function should be used only after reset.
+ * @param None
+ * @retval None
+ */
+void SystemInit (void)
+{
+ /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
+ /* Set HSION bit */
+ RCC->CR |= 0x00000001U;
+
+ /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
+#if !defined(STM32F105xC) && !defined(STM32F107xC)
+ RCC->CFGR &= 0xF8FF0000U;
+#else
+ RCC->CFGR &= 0xF0FF0000U;
+#endif /* STM32F105xC */
+
+ /* Reset HSEON, CSSON and PLLON bits */
+ RCC->CR &= 0xFEF6FFFFU;
+
+ /* Reset HSEBYP bit */
+ RCC->CR &= 0xFFFBFFFFU;
+
+ /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
+ RCC->CFGR &= 0xFF80FFFFU;
+
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ /* Reset PLL2ON and PLL3ON bits */
+ RCC->CR &= 0xEBFFFFFFU;
+
+ /* Disable all interrupts and clear pending bits */
+ RCC->CIR = 0x00FF0000U;
+
+ /* Reset CFGR2 register */
+ RCC->CFGR2 = 0x00000000U;
+#elif defined(STM32F100xB) || defined(STM32F100xE)
+ /* Disable all interrupts and clear pending bits */
+ RCC->CIR = 0x009F0000U;
+
+ /* Reset CFGR2 register */
+ RCC->CFGR2 = 0x00000000U;
+#else
+ /* Disable all interrupts and clear pending bits */
+ RCC->CIR = 0x009F0000U;
+#endif /* STM32F105xC */
+
+#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
+ #ifdef DATA_IN_ExtSRAM
+ SystemInit_ExtMemCtl();
+ #endif /* DATA_IN_ExtSRAM */
+#endif
+
+#ifdef VECT_TAB_SRAM
+ SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
+#else
+ SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
+#endif
+}
+
+/**
+ * @brief Update SystemCoreClock variable according to Clock Register Values.
+ * The SystemCoreClock variable contains the core clock (HCLK), it can
+ * be used by the user application to setup the SysTick timer or configure
+ * other parameters.
+ *
+ * @note Each time the core clock (HCLK) changes, this function must be called
+ * to update SystemCoreClock variable value. Otherwise, any configuration
+ * based on this variable will be incorrect.
+ *
+ * @note - The system frequency computed by this function is not the real
+ * frequency in the chip. It is calculated based on the predefined
+ * constant and the selected clock source:
+ *
+ * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
+ *
+ * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
+ *
+ * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
+ * or HSI_VALUE(*) multiplied by the PLL factors.
+ *
+ * (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
+ * 8 MHz) but the real value may vary depending on the variations
+ * in voltage and temperature.
+ *
+ * (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
+ * 8 MHz or 25 MHz, depending on the product used), user has to ensure
+ * that HSE_VALUE is same as the real frequency of the crystal used.
+ * Otherwise, this function may have wrong result.
+ *
+ * - The result of this function could be not correct when using fractional
+ * value for HSE crystal.
+ * @param None
+ * @retval None
+ */
+void SystemCoreClockUpdate (void)
+{
+ uint32_t tmp = 0U, pllmull = 0U, pllsource = 0U;
+
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ uint32_t prediv1source = 0U, prediv1factor = 0U, prediv2factor = 0U, pll2mull = 0U;
+#endif /* STM32F105xC */
+
+#if defined(STM32F100xB) || defined(STM32F100xE)
+ uint32_t prediv1factor = 0U;
+#endif /* STM32F100xB or STM32F100xE */
+
+ /* Get SYSCLK source -------------------------------------------------------*/
+ tmp = RCC->CFGR & RCC_CFGR_SWS;
+
+ switch (tmp)
+ {
+ case 0x00U: /* HSI used as system clock */
+ SystemCoreClock = HSI_VALUE;
+ break;
+ case 0x04U: /* HSE used as system clock */
+ SystemCoreClock = HSE_VALUE;
+ break;
+ case 0x08U: /* PLL used as system clock */
+
+ /* Get PLL clock source and multiplication factor ----------------------*/
+ pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
+ pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
+
+#if !defined(STM32F105xC) && !defined(STM32F107xC)
+ pllmull = ( pllmull >> 18U) + 2U;
+
+ if (pllsource == 0x00U)
+ {
+ /* HSI oscillator clock divided by 2 selected as PLL clock entry */
+ SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
+ }
+ else
+ {
+ #if defined(STM32F100xB) || defined(STM32F100xE)
+ prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
+ /* HSE oscillator clock selected as PREDIV1 clock entry */
+ SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
+ #else
+ /* HSE selected as PLL clock entry */
+ if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
+ {/* HSE oscillator clock divided by 2 */
+ SystemCoreClock = (HSE_VALUE >> 1U) * pllmull;
+ }
+ else
+ {
+ SystemCoreClock = HSE_VALUE * pllmull;
+ }
+ #endif
+ }
+#else
+ pllmull = pllmull >> 18U;
+
+ if (pllmull != 0x0DU)
+ {
+ pllmull += 2U;
+ }
+ else
+ { /* PLL multiplication factor = PLL input clock * 6.5 */
+ pllmull = 13U / 2U;
+ }
+
+ if (pllsource == 0x00U)
+ {
+ /* HSI oscillator clock divided by 2 selected as PLL clock entry */
+ SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
+ }
+ else
+ {/* PREDIV1 selected as PLL clock entry */
+
+ /* Get PREDIV1 clock source and division factor */
+ prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
+ prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
+
+ if (prediv1source == 0U)
+ {
+ /* HSE oscillator clock selected as PREDIV1 clock entry */
+ SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
+ }
+ else
+ {/* PLL2 clock selected as PREDIV1 clock entry */
+
+ /* Get PREDIV2 division factor and PLL2 multiplication factor */
+ prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4U) + 1U;
+ pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8U) + 2U;
+ SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
+ }
+ }
+#endif /* STM32F105xC */
+ break;
+
+ default:
+ SystemCoreClock = HSI_VALUE;
+ break;
+ }
+
+ /* Compute HCLK clock frequency ----------------*/
+ /* Get HCLK prescaler */
+ tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
+ /* HCLK clock frequency */
+ SystemCoreClock >>= tmp;
+}
+
+#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
+/**
+ * @brief Setup the external memory controller. Called in startup_stm32f1xx.s
+ * before jump to __main
+ * @param None
+ * @retval None
+ */
+#ifdef DATA_IN_ExtSRAM
+/**
+ * @brief Setup the external memory controller.
+ * Called in startup_stm32f1xx_xx.s/.c before jump to main.
+ * This function configures the external SRAM mounted on STM3210E-EVAL
+ * board (STM32 High density devices). This SRAM will be used as program
+ * data memory (including heap and stack).
+ * @param None
+ * @retval None
+ */
+void SystemInit_ExtMemCtl(void)
+{
+ __IO uint32_t tmpreg;
+ /*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
+ required, then adjust the Register Addresses */
+
+ /* Enable FSMC clock */
+ RCC->AHBENR = 0x00000114U;
+
+ /* Delay after an RCC peripheral clock enabling */
+ tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN);
+
+ /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
+ RCC->APB2ENR = 0x000001E0U;
+
+ /* Delay after an RCC peripheral clock enabling */
+ tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);
+
+ (void)(tmpreg);
+
+/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/
+/*---------------- SRAM Address lines configuration -------------------------*/
+/*---------------- NOE and NWE configuration --------------------------------*/
+/*---------------- NE3 configuration ----------------------------------------*/
+/*---------------- NBL0, NBL1 configuration ---------------------------------*/
+
+ GPIOD->CRL = 0x44BB44BBU;
+ GPIOD->CRH = 0xBBBBBBBBU;
+
+ GPIOE->CRL = 0xB44444BBU;
+ GPIOE->CRH = 0xBBBBBBBBU;
+
+ GPIOF->CRL = 0x44BBBBBBU;
+ GPIOF->CRH = 0xBBBB4444U;
+
+ GPIOG->CRL = 0x44BBBBBBU;
+ GPIOG->CRH = 0x444B4B44U;
+
+/*---------------- FSMC Configuration ---------------------------------------*/
+/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/
+
+ FSMC_Bank1->BTCR[4U] = 0x00001091U;
+ FSMC_Bank1->BTCR[5U] = 0x00110212U;
+}
+#endif /* DATA_IN_ExtSRAM */
+#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/CMSIS/Include/arm_common_tables.h b/templates/blackpill/Drivers/CMSIS/Include/arm_common_tables.h
new file mode 100644
index 0000000..d5d7241
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Include/arm_common_tables.h
@@ -0,0 +1,136 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. October 2015
+* $Revision: V.1.4.5 a
+*
+* 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
+*
+* 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 ARM LIMITED 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 _ARM_COMMON_TABLES_H
+#define _ARM_COMMON_TABLES_H
+
+#include "arm_math.h"
+
+extern const uint16_t armBitRevTable[1024];
+extern const q15_t armRecipTableQ15[64];
+extern const q31_t armRecipTableQ31[64];
+/* extern const q31_t realCoefAQ31[1024]; */
+/* extern const q31_t realCoefBQ31[1024]; */
+extern const float32_t twiddleCoef_16[32];
+extern const float32_t twiddleCoef_32[64];
+extern const float32_t twiddleCoef_64[128];
+extern const float32_t twiddleCoef_128[256];
+extern const float32_t twiddleCoef_256[512];
+extern const float32_t twiddleCoef_512[1024];
+extern const float32_t twiddleCoef_1024[2048];
+extern const float32_t twiddleCoef_2048[4096];
+extern const float32_t twiddleCoef_4096[8192];
+#define twiddleCoef twiddleCoef_4096
+extern const q31_t twiddleCoef_16_q31[24];
+extern const q31_t twiddleCoef_32_q31[48];
+extern const q31_t twiddleCoef_64_q31[96];
+extern const q31_t twiddleCoef_128_q31[192];
+extern const q31_t twiddleCoef_256_q31[384];
+extern const q31_t twiddleCoef_512_q31[768];
+extern const q31_t twiddleCoef_1024_q31[1536];
+extern const q31_t twiddleCoef_2048_q31[3072];
+extern const q31_t twiddleCoef_4096_q31[6144];
+extern const q15_t twiddleCoef_16_q15[24];
+extern const q15_t twiddleCoef_32_q15[48];
+extern const q15_t twiddleCoef_64_q15[96];
+extern const q15_t twiddleCoef_128_q15[192];
+extern const q15_t twiddleCoef_256_q15[384];
+extern const q15_t twiddleCoef_512_q15[768];
+extern const q15_t twiddleCoef_1024_q15[1536];
+extern const q15_t twiddleCoef_2048_q15[3072];
+extern const q15_t twiddleCoef_4096_q15[6144];
+extern const float32_t twiddleCoef_rfft_32[32];
+extern const float32_t twiddleCoef_rfft_64[64];
+extern const float32_t twiddleCoef_rfft_128[128];
+extern const float32_t twiddleCoef_rfft_256[256];
+extern const float32_t twiddleCoef_rfft_512[512];
+extern const float32_t twiddleCoef_rfft_1024[1024];
+extern const float32_t twiddleCoef_rfft_2048[2048];
+extern const float32_t twiddleCoef_rfft_4096[4096];
+
+
+/* floating-point bit reversal tables */
+#define ARMBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20 )
+#define ARMBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48 )
+#define ARMBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56 )
+#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 )
+#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 )
+#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 )
+#define ARMBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800)
+#define ARMBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808)
+#define ARMBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032)
+
+extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE__16_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE__32_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE__64_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE1024_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE2048_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE4096_TABLE_LENGTH];
+
+/* fixed-point bit reversal tables */
+#define ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH ((uint16_t)12 )
+#define ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH ((uint16_t)24 )
+#define ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH ((uint16_t)56 )
+#define ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH ((uint16_t)112 )
+#define ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH ((uint16_t)240 )
+#define ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH ((uint16_t)480 )
+#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992 )
+#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984)
+#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032)
+
+extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH];
+
+/* Tables for Fast Math Sine and Cosine */
+extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1];
+extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1];
+extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1];
+
+#endif /* ARM_COMMON_TABLES_H */
diff --git a/templates/blackpill/Drivers/CMSIS/Include/arm_const_structs.h b/templates/blackpill/Drivers/CMSIS/Include/arm_const_structs.h
new file mode 100644
index 0000000..54595f5
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Include/arm_const_structs.h
@@ -0,0 +1,79 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_const_structs.h
+*
+* Description: This file has constant structs that are initialized for
+* user convenience. For example, some can be given as
+* arguments to the arm_cfft_f32() function.
+*
+* Target Processor: Cortex-M4/Cortex-M3
+*
+* 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 ARM LIMITED 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 _ARM_CONST_STRUCTS_H
+#define _ARM_CONST_STRUCTS_H
+
+#include "arm_math.h"
+#include "arm_common_tables.h"
+
+ extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16;
+ extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32;
+ extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64;
+ extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128;
+ extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256;
+ extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512;
+ extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024;
+ extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048;
+ extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096;
+
+ extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16;
+ extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32;
+ extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64;
+ extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128;
+ extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256;
+ extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512;
+ extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024;
+ extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048;
+ extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096;
+
+ extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16;
+ extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32;
+ extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64;
+ extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128;
+ extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256;
+ extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512;
+ extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024;
+ extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048;
+ extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096;
+
+#endif
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Include/arm_math.h b/templates/blackpill/Drivers/CMSIS/Include/arm_math.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Include/arm_math.h
rename to templates/blackpill/Drivers/CMSIS/Include/arm_math.h
diff --git a/templates/blackpill/Drivers/CMSIS/Include/cmsis_armcc.h b/templates/blackpill/Drivers/CMSIS/Include/cmsis_armcc.h
new file mode 100644
index 0000000..f2bb66a
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Include/cmsis_armcc.h
@@ -0,0 +1,734 @@
+/**************************************************************************//**
+ * @file cmsis_armcc.h
+ * @brief CMSIS Cortex-M Core Function/Instruction Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ 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 ARM 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 COPYRIGHT HOLDERS AND 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 __CMSIS_ARMCC_H
+#define __CMSIS_ARMCC_H
+
+
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
+ #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
+#endif
+
+/* ########################### Core Function Access ########################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+ @{
+ */
+
+/* intrinsic void __enable_irq(); */
+/* intrinsic void __disable_irq(); */
+
+/**
+ \brief Get Control Register
+ \details Returns the content of the Control Register.
+ \return Control Register value
+ */
+__STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+ register uint32_t __regControl __ASM("control");
+ return(__regControl);
+}
+
+
+/**
+ \brief Set Control Register
+ \details Writes the given value to the Control Register.
+ \param [in] control Control Register value to set
+ */
+__STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+ register uint32_t __regControl __ASM("control");
+ __regControl = control;
+}
+
+
+/**
+ \brief Get IPSR Register
+ \details Returns the content of the IPSR Register.
+ \return IPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_IPSR(void)
+{
+ register uint32_t __regIPSR __ASM("ipsr");
+ return(__regIPSR);
+}
+
+
+/**
+ \brief Get APSR Register
+ \details Returns the content of the APSR Register.
+ \return APSR Register value
+ */
+__STATIC_INLINE uint32_t __get_APSR(void)
+{
+ register uint32_t __regAPSR __ASM("apsr");
+ return(__regAPSR);
+}
+
+
+/**
+ \brief Get xPSR Register
+ \details Returns the content of the xPSR Register.
+ \return xPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_xPSR(void)
+{
+ register uint32_t __regXPSR __ASM("xpsr");
+ return(__regXPSR);
+}
+
+
+/**
+ \brief Get Process Stack Pointer
+ \details Returns the current value of the Process Stack Pointer (PSP).
+ \return PSP Register value
+ */
+__STATIC_INLINE uint32_t __get_PSP(void)
+{
+ register uint32_t __regProcessStackPointer __ASM("psp");
+ return(__regProcessStackPointer);
+}
+
+
+/**
+ \brief Set Process Stack Pointer
+ \details Assigns the given value to the Process Stack Pointer (PSP).
+ \param [in] topOfProcStack Process Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+ register uint32_t __regProcessStackPointer __ASM("psp");
+ __regProcessStackPointer = topOfProcStack;
+}
+
+
+/**
+ \brief Get Main Stack Pointer
+ \details Returns the current value of the Main Stack Pointer (MSP).
+ \return MSP Register value
+ */
+__STATIC_INLINE uint32_t __get_MSP(void)
+{
+ register uint32_t __regMainStackPointer __ASM("msp");
+ return(__regMainStackPointer);
+}
+
+
+/**
+ \brief Set Main Stack Pointer
+ \details Assigns the given value to the Main Stack Pointer (MSP).
+ \param [in] topOfMainStack Main Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+ register uint32_t __regMainStackPointer __ASM("msp");
+ __regMainStackPointer = topOfMainStack;
+}
+
+
+/**
+ \brief Get Priority Mask
+ \details Returns the current state of the priority mask bit from the Priority Mask Register.
+ \return Priority Mask value
+ */
+__STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+ register uint32_t __regPriMask __ASM("primask");
+ return(__regPriMask);
+}
+
+
+/**
+ \brief Set Priority Mask
+ \details Assigns the given value to the Priority Mask Register.
+ \param [in] priMask Priority Mask
+ */
+__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+ register uint32_t __regPriMask __ASM("primask");
+ __regPriMask = (priMask);
+}
+
+
+#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+
+/**
+ \brief Enable FIQ
+ \details Enables FIQ interrupts by clearing the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+#define __enable_fault_irq __enable_fiq
+
+
+/**
+ \brief Disable FIQ
+ \details Disables FIQ interrupts by setting the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+#define __disable_fault_irq __disable_fiq
+
+
+/**
+ \brief Get Base Priority
+ \details Returns the current value of the Base Priority register.
+ \return Base Priority register value
+ */
+__STATIC_INLINE uint32_t __get_BASEPRI(void)
+{
+ register uint32_t __regBasePri __ASM("basepri");
+ return(__regBasePri);
+}
+
+
+/**
+ \brief Set Base Priority
+ \details Assigns the given value to the Base Priority register.
+ \param [in] basePri Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
+{
+ register uint32_t __regBasePri __ASM("basepri");
+ __regBasePri = (basePri & 0xFFU);
+}
+
+
+/**
+ \brief Set Base Priority with condition
+ \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
+ or the new value increases the BASEPRI priority level.
+ \param [in] basePri Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
+{
+ register uint32_t __regBasePriMax __ASM("basepri_max");
+ __regBasePriMax = (basePri & 0xFFU);
+}
+
+
+/**
+ \brief Get Fault Mask
+ \details Returns the current value of the Fault Mask register.
+ \return Fault Mask register value
+ */
+__STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+ register uint32_t __regFaultMask __ASM("faultmask");
+ return(__regFaultMask);
+}
+
+
+/**
+ \brief Set Fault Mask
+ \details Assigns the given value to the Fault Mask register.
+ \param [in] faultMask Fault Mask value to set
+ */
+__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+ register uint32_t __regFaultMask __ASM("faultmask");
+ __regFaultMask = (faultMask & (uint32_t)1);
+}
+
+#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
+
+
+#if (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U)
+
+/**
+ \brief Get FPSCR
+ \details Returns the current value of the Floating Point Status/Control register.
+ \return Floating Point Status/Control register value
+ */
+__STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+ register uint32_t __regfpscr __ASM("fpscr");
+ return(__regfpscr);
+#else
+ return(0U);
+#endif
+}
+
+
+/**
+ \brief Set FPSCR
+ \details Assigns the given value to the Floating Point Status/Control register.
+ \param [in] fpscr Floating Point Status/Control value to set
+ */
+__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+ register uint32_t __regfpscr __ASM("fpscr");
+ __regfpscr = (fpscr);
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */
+
+
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+/* ########################## Core Instruction Access ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+ Access to dedicated instructions
+ @{
+*/
+
+/**
+ \brief No Operation
+ \details No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+#define __NOP __nop
+
+
+/**
+ \brief Wait For Interrupt
+ \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
+ */
+#define __WFI __wfi
+
+
+/**
+ \brief Wait For Event
+ \details Wait For Event is a hint instruction that permits the processor to enter
+ a low-power state until one of a number of events occurs.
+ */
+#define __WFE __wfe
+
+
+/**
+ \brief Send Event
+ \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV __sev
+
+
+/**
+ \brief Instruction Synchronization Barrier
+ \details Instruction Synchronization Barrier flushes the pipeline in the processor,
+ so that all instructions following the ISB are fetched from cache or memory,
+ after the instruction has been completed.
+ */
+#define __ISB() do {\
+ __schedule_barrier();\
+ __isb(0xF);\
+ __schedule_barrier();\
+ } while (0U)
+
+/**
+ \brief Data Synchronization Barrier
+ \details Acts as a special kind of Data Memory Barrier.
+ It completes when all explicit memory accesses before this instruction complete.
+ */
+#define __DSB() do {\
+ __schedule_barrier();\
+ __dsb(0xF);\
+ __schedule_barrier();\
+ } while (0U)
+
+/**
+ \brief Data Memory Barrier
+ \details Ensures the apparent order of the explicit memory operations before
+ and after the instruction, without ensuring their completion.
+ */
+#define __DMB() do {\
+ __schedule_barrier();\
+ __dmb(0xF);\
+ __schedule_barrier();\
+ } while (0U)
+
+/**
+ \brief Reverse byte order (32 bit)
+ \details Reverses the byte order in integer value.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#define __REV __rev
+
+
+/**
+ \brief Reverse byte order (16 bit)
+ \details Reverses the byte order in two unsigned short values.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
+{
+ rev16 r0, r0
+ bx lr
+}
+#endif
+
+/**
+ \brief Reverse byte order in signed short value
+ \details Reverses the byte order in a signed short value with sign extension to integer.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
+{
+ revsh r0, r0
+ bx lr
+}
+#endif
+
+
+/**
+ \brief Rotate Right in unsigned value (32 bit)
+ \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+ \param [in] value Value to rotate
+ \param [in] value Number of Bits to rotate
+ \return Rotated value
+ */
+#define __ROR __ror
+
+
+/**
+ \brief Breakpoint
+ \details Causes the processor to enter Debug state.
+ Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+ \param [in] value is ignored by the processor.
+ If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value) __breakpoint(value)
+
+
+/**
+ \brief Reverse bit order of value
+ \details Reverses the bit order of the given value.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+ #define __RBIT __rbit
+#else
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+ uint32_t result;
+ int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
+
+ result = value; /* r will be reversed bits of v; first get LSB of v */
+ for (value >>= 1U; value; value >>= 1U)
+ {
+ result <<= 1U;
+ result |= value & 1U;
+ s--;
+ }
+ result <<= s; /* shift when v's highest bits are zero */
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Count leading zeros
+ \details Counts the number of leading zeros of a data value.
+ \param [in] value Value to count the leading zeros
+ \return number of leading zeros in value
+ */
+#define __CLZ __clz
+
+
+#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+
+/**
+ \brief LDR Exclusive (8 bit)
+ \details Executes a exclusive LDR instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
+#else
+ #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
+#endif
+
+
+/**
+ \brief LDR Exclusive (16 bit)
+ \details Executes a exclusive LDR instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
+#else
+ #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
+#endif
+
+
+/**
+ \brief LDR Exclusive (32 bit)
+ \details Executes a exclusive LDR instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
+#else
+ #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
+#endif
+
+
+/**
+ \brief STR Exclusive (8 bit)
+ \details Executes a exclusive STR instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __STREXB(value, ptr) __strex(value, ptr)
+#else
+ #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
+#endif
+
+
+/**
+ \brief STR Exclusive (16 bit)
+ \details Executes a exclusive STR instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __STREXH(value, ptr) __strex(value, ptr)
+#else
+ #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
+#endif
+
+
+/**
+ \brief STR Exclusive (32 bit)
+ \details Executes a exclusive STR instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __STREXW(value, ptr) __strex(value, ptr)
+#else
+ #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
+#endif
+
+
+/**
+ \brief Remove the exclusive lock
+ \details Removes the exclusive lock which is created by LDREX.
+ */
+#define __CLREX __clrex
+
+
+/**
+ \brief Signed Saturate
+ \details Saturates a signed value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (1..32)
+ \return Saturated value
+ */
+#define __SSAT __ssat
+
+
+/**
+ \brief Unsigned Saturate
+ \details Saturates an unsigned value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+#define __USAT __usat
+
+
+/**
+ \brief Rotate Right with Extend (32 bit)
+ \details Moves each bit of a bitstring right by one bit.
+ The carry input is shifted in at the left end of the bitstring.
+ \param [in] value Value to rotate
+ \return Rotated value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
+{
+ rrx r0, r0
+ bx lr
+}
+#endif
+
+
+/**
+ \brief LDRT Unprivileged (8 bit)
+ \details Executes a Unprivileged LDRT instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
+
+
+/**
+ \brief LDRT Unprivileged (16 bit)
+ \details Executes a Unprivileged LDRT instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
+
+
+/**
+ \brief LDRT Unprivileged (32 bit)
+ \details Executes a Unprivileged LDRT instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
+
+
+/**
+ \brief STRT Unprivileged (8 bit)
+ \details Executes a Unprivileged STRT instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+#define __STRBT(value, ptr) __strt(value, ptr)
+
+
+/**
+ \brief STRT Unprivileged (16 bit)
+ \details Executes a Unprivileged STRT instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+#define __STRHT(value, ptr) __strt(value, ptr)
+
+
+/**
+ \brief STRT Unprivileged (32 bit)
+ \details Executes a Unprivileged STRT instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+#define __STRT(value, ptr) __strt(value, ptr)
+
+#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+ Access to dedicated SIMD instructions
+ @{
+*/
+
+#if (__CORTEX_M >= 0x04U) /* only for Cortex-M4 and above */
+
+#define __SADD8 __sadd8
+#define __QADD8 __qadd8
+#define __SHADD8 __shadd8
+#define __UADD8 __uadd8
+#define __UQADD8 __uqadd8
+#define __UHADD8 __uhadd8
+#define __SSUB8 __ssub8
+#define __QSUB8 __qsub8
+#define __SHSUB8 __shsub8
+#define __USUB8 __usub8
+#define __UQSUB8 __uqsub8
+#define __UHSUB8 __uhsub8
+#define __SADD16 __sadd16
+#define __QADD16 __qadd16
+#define __SHADD16 __shadd16
+#define __UADD16 __uadd16
+#define __UQADD16 __uqadd16
+#define __UHADD16 __uhadd16
+#define __SSUB16 __ssub16
+#define __QSUB16 __qsub16
+#define __SHSUB16 __shsub16
+#define __USUB16 __usub16
+#define __UQSUB16 __uqsub16
+#define __UHSUB16 __uhsub16
+#define __SASX __sasx
+#define __QASX __qasx
+#define __SHASX __shasx
+#define __UASX __uasx
+#define __UQASX __uqasx
+#define __UHASX __uhasx
+#define __SSAX __ssax
+#define __QSAX __qsax
+#define __SHSAX __shsax
+#define __USAX __usax
+#define __UQSAX __uqsax
+#define __UHSAX __uhsax
+#define __USAD8 __usad8
+#define __USADA8 __usada8
+#define __SSAT16 __ssat16
+#define __USAT16 __usat16
+#define __UXTB16 __uxtb16
+#define __UXTAB16 __uxtab16
+#define __SXTB16 __sxtb16
+#define __SXTAB16 __sxtab16
+#define __SMUAD __smuad
+#define __SMUADX __smuadx
+#define __SMLAD __smlad
+#define __SMLADX __smladx
+#define __SMLALD __smlald
+#define __SMLALDX __smlaldx
+#define __SMUSD __smusd
+#define __SMUSDX __smusdx
+#define __SMLSD __smlsd
+#define __SMLSDX __smlsdx
+#define __SMLSLD __smlsld
+#define __SMLSLDX __smlsldx
+#define __SEL __sel
+#define __QADD __qadd
+#define __QSUB __qsub
+
+#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
+ ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
+
+#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
+ ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
+
+#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
+ ((int64_t)(ARG3) << 32U) ) >> 32U))
+
+#endif /* (__CORTEX_M >= 0x04) */
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#endif /* __CMSIS_ARMCC_H */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Include/cmsis_armcc_V6.h b/templates/blackpill/Drivers/CMSIS/Include/cmsis_armcc_V6.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Include/cmsis_armcc_V6.h
rename to templates/blackpill/Drivers/CMSIS/Include/cmsis_armcc_V6.h
diff --git a/templates/blackpill/Drivers/CMSIS/Include/cmsis_gcc.h b/templates/blackpill/Drivers/CMSIS/Include/cmsis_gcc.h
new file mode 100644
index 0000000..d868f2e
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Include/cmsis_gcc.h
@@ -0,0 +1,1373 @@
+/**************************************************************************//**
+ * @file cmsis_gcc.h
+ * @brief CMSIS Cortex-M Core Function/Instruction Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ 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 ARM 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 COPYRIGHT HOLDERS AND 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 __CMSIS_GCC_H
+#define __CMSIS_GCC_H
+
+/* ignore some GCC warnings */
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsign-conversion"
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+
+/* ########################### Core Function Access ########################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+ @{
+ */
+
+/**
+ \brief Enable IRQ Interrupts
+ \details Enables IRQ interrupts by clearing the I-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
+{
+ __ASM volatile ("cpsie i" : : : "memory");
+}
+
+
+/**
+ \brief Disable IRQ Interrupts
+ \details Disables IRQ interrupts by setting the I-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
+{
+ __ASM volatile ("cpsid i" : : : "memory");
+}
+
+
+/**
+ \brief Get Control Register
+ \details Returns the content of the Control Register.
+ \return Control Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, control" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Set Control Register
+ \details Writes the given value to the Control Register.
+ \param [in] control Control Register value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+ __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
+}
+
+
+/**
+ \brief Get IPSR Register
+ \details Returns the content of the IPSR Register.
+ \return IPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Get APSR Register
+ \details Returns the content of the APSR Register.
+ \return APSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, apsr" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Get xPSR Register
+ \details Returns the content of the xPSR Register.
+
+ \return xPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Get Process Stack Pointer
+ \details Returns the current value of the Process Stack Pointer (PSP).
+ \return PSP Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, psp\n" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Set Process Stack Pointer
+ \details Assigns the given value to the Process Stack Pointer (PSP).
+ \param [in] topOfProcStack Process Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+ __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
+}
+
+
+/**
+ \brief Get Main Stack Pointer
+ \details Returns the current value of the Main Stack Pointer (MSP).
+ \return MSP Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, msp\n" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Set Main Stack Pointer
+ \details Assigns the given value to the Main Stack Pointer (MSP).
+
+ \param [in] topOfMainStack Main Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+ __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
+}
+
+
+/**
+ \brief Get Priority Mask
+ \details Returns the current state of the priority mask bit from the Priority Mask Register.
+ \return Priority Mask value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, primask" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Set Priority Mask
+ \details Assigns the given value to the Priority Mask Register.
+ \param [in] priMask Priority Mask
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+ __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
+}
+
+
+#if (__CORTEX_M >= 0x03U)
+
+/**
+ \brief Enable FIQ
+ \details Enables FIQ interrupts by clearing the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
+{
+ __ASM volatile ("cpsie f" : : : "memory");
+}
+
+
+/**
+ \brief Disable FIQ
+ \details Disables FIQ interrupts by setting the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
+{
+ __ASM volatile ("cpsid f" : : : "memory");
+}
+
+
+/**
+ \brief Get Base Priority
+ \details Returns the current value of the Base Priority register.
+ \return Base Priority register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, basepri" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Set Base Priority
+ \details Assigns the given value to the Base Priority register.
+ \param [in] basePri Base Priority value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
+{
+ __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
+}
+
+
+/**
+ \brief Set Base Priority with condition
+ \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
+ or the new value increases the BASEPRI priority level.
+ \param [in] basePri Base Priority value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value)
+{
+ __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory");
+}
+
+
+/**
+ \brief Get Fault Mask
+ \details Returns the current value of the Fault Mask register.
+ \return Fault Mask register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Set Fault Mask
+ \details Assigns the given value to the Fault Mask register.
+ \param [in] faultMask Fault Mask value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+ __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
+}
+
+#endif /* (__CORTEX_M >= 0x03U) */
+
+
+#if (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U)
+
+/**
+ \brief Get FPSCR
+ \details Returns the current value of the Floating Point Status/Control register.
+ \return Floating Point Status/Control register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+ uint32_t result;
+
+ /* Empty asm statement works as a scheduling barrier */
+ __ASM volatile ("");
+ __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
+ __ASM volatile ("");
+ return(result);
+#else
+ return(0);
+#endif
+}
+
+
+/**
+ \brief Set FPSCR
+ \details Assigns the given value to the Floating Point Status/Control register.
+ \param [in] fpscr Floating Point Status/Control value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+ /* Empty asm statement works as a scheduling barrier */
+ __ASM volatile ("");
+ __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
+ __ASM volatile ("");
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */
+
+
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+/* ########################## Core Instruction Access ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+ Access to dedicated instructions
+ @{
+*/
+
+/* Define macros for porting to both thumb1 and thumb2.
+ * For thumb1, use low register (r0-r7), specified by constraint "l"
+ * Otherwise, use general registers, specified by constraint "r" */
+#if defined (__thumb__) && !defined (__thumb2__)
+#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
+#define __CMSIS_GCC_USE_REG(r) "l" (r)
+#else
+#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
+#define __CMSIS_GCC_USE_REG(r) "r" (r)
+#endif
+
+/**
+ \brief No Operation
+ \details No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __NOP(void)
+{
+ __ASM volatile ("nop");
+}
+
+
+/**
+ \brief Wait For Interrupt
+ \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __WFI(void)
+{
+ __ASM volatile ("wfi");
+}
+
+
+/**
+ \brief Wait For Event
+ \details Wait For Event is a hint instruction that permits the processor to enter
+ a low-power state until one of a number of events occurs.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __WFE(void)
+{
+ __ASM volatile ("wfe");
+}
+
+
+/**
+ \brief Send Event
+ \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __SEV(void)
+{
+ __ASM volatile ("sev");
+}
+
+
+/**
+ \brief Instruction Synchronization Barrier
+ \details Instruction Synchronization Barrier flushes the pipeline in the processor,
+ so that all instructions following the ISB are fetched from cache or memory,
+ after the instruction has been completed.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __ISB(void)
+{
+ __ASM volatile ("isb 0xF":::"memory");
+}
+
+
+/**
+ \brief Data Synchronization Barrier
+ \details Acts as a special kind of Data Memory Barrier.
+ It completes when all explicit memory accesses before this instruction complete.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __DSB(void)
+{
+ __ASM volatile ("dsb 0xF":::"memory");
+}
+
+
+/**
+ \brief Data Memory Barrier
+ \details Ensures the apparent order of the explicit memory operations before
+ and after the instruction, without ensuring their completion.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __DMB(void)
+{
+ __ASM volatile ("dmb 0xF":::"memory");
+}
+
+
+/**
+ \brief Reverse byte order (32 bit)
+ \details Reverses the byte order in integer value.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value)
+{
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+ return __builtin_bswap32(value);
+#else
+ uint32_t result;
+
+ __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+ return(result);
+#endif
+}
+
+
+/**
+ \brief Reverse byte order (16 bit)
+ \details Reverses the byte order in two unsigned short values.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
+{
+ uint32_t result;
+
+ __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+ return(result);
+}
+
+
+/**
+ \brief Reverse byte order in signed short value
+ \details Reverses the byte order in a signed short value with sign extension to integer.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)
+{
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+ return (short)__builtin_bswap16(value);
+#else
+ int32_t result;
+
+ __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+ return(result);
+#endif
+}
+
+
+/**
+ \brief Rotate Right in unsigned value (32 bit)
+ \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+ \param [in] value Value to rotate
+ \param [in] value Number of Bits to rotate
+ \return Rotated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
+{
+ return (op1 >> op2) | (op1 << (32U - op2));
+}
+
+
+/**
+ \brief Breakpoint
+ \details Causes the processor to enter Debug state.
+ Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+ \param [in] value is ignored by the processor.
+ If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value) __ASM volatile ("bkpt "#value)
+
+
+/**
+ \brief Reverse bit order of value
+ \details Reverses the bit order of the given value.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+ uint32_t result;
+
+#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+ __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
+#else
+ int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
+
+ result = value; /* r will be reversed bits of v; first get LSB of v */
+ for (value >>= 1U; value; value >>= 1U)
+ {
+ result <<= 1U;
+ result |= value & 1U;
+ s--;
+ }
+ result <<= s; /* shift when v's highest bits are zero */
+#endif
+ return(result);
+}
+
+
+/**
+ \brief Count leading zeros
+ \details Counts the number of leading zeros of a data value.
+ \param [in] value Value to count the leading zeros
+ \return number of leading zeros in value
+ */
+#define __CLZ __builtin_clz
+
+
+#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+
+/**
+ \brief LDR Exclusive (8 bit)
+ \details Executes a exclusive LDR instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
+{
+ uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+ __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+ /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+ accepted by assembler. So has to use following less efficient pattern.
+ */
+ __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+ return ((uint8_t) result); /* Add explicit type cast here */
+}
+
+
+/**
+ \brief LDR Exclusive (16 bit)
+ \details Executes a exclusive LDR instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
+{
+ uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+ __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+ /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+ accepted by assembler. So has to use following less efficient pattern.
+ */
+ __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+ return ((uint16_t) result); /* Add explicit type cast here */
+}
+
+
+/**
+ \brief LDR Exclusive (32 bit)
+ \details Executes a exclusive LDR instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
+ return(result);
+}
+
+
+/**
+ \brief STR Exclusive (8 bit)
+ \details Executes a exclusive STR instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
+ return(result);
+}
+
+
+/**
+ \brief STR Exclusive (16 bit)
+ \details Executes a exclusive STR instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
+ return(result);
+}
+
+
+/**
+ \brief STR Exclusive (32 bit)
+ \details Executes a exclusive STR instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
+ return(result);
+}
+
+
+/**
+ \brief Remove the exclusive lock
+ \details Removes the exclusive lock which is created by LDREX.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void)
+{
+ __ASM volatile ("clrex" ::: "memory");
+}
+
+
+/**
+ \brief Signed Saturate
+ \details Saturates a signed value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (1..32)
+ \return Saturated value
+ */
+#define __SSAT(ARG1,ARG2) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+
+/**
+ \brief Unsigned Saturate
+ \details Saturates an unsigned value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+#define __USAT(ARG1,ARG2) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+
+/**
+ \brief Rotate Right with Extend (32 bit)
+ \details Moves each bit of a bitstring right by one bit.
+ The carry input is shifted in at the left end of the bitstring.
+ \param [in] value Value to rotate
+ \return Rotated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value)
+{
+ uint32_t result;
+
+ __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+ return(result);
+}
+
+
+/**
+ \brief LDRT Unprivileged (8 bit)
+ \details Executes a Unprivileged LDRT instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
+{
+ uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+ __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+ /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+ accepted by assembler. So has to use following less efficient pattern.
+ */
+ __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+ return ((uint8_t) result); /* Add explicit type cast here */
+}
+
+
+/**
+ \brief LDRT Unprivileged (16 bit)
+ \details Executes a Unprivileged LDRT instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
+{
+ uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+ __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+ /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+ accepted by assembler. So has to use following less efficient pattern.
+ */
+ __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+ return ((uint16_t) result); /* Add explicit type cast here */
+}
+
+
+/**
+ \brief LDRT Unprivileged (32 bit)
+ \details Executes a Unprivileged LDRT instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) );
+ return(result);
+}
+
+
+/**
+ \brief STRT Unprivileged (8 bit)
+ \details Executes a Unprivileged STRT instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
+{
+ __ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+ \brief STRT Unprivileged (16 bit)
+ \details Executes a Unprivileged STRT instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
+{
+ __ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+ \brief STRT Unprivileged (32 bit)
+ \details Executes a Unprivileged STRT instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
+{
+ __ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) );
+}
+
+#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+ Access to dedicated SIMD instructions
+ @{
+*/
+
+#if (__CORTEX_M >= 0x04U) /* only for Cortex-M4 and above */
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+#define __SSAT16(ARG1,ARG2) \
+({ \
+ int32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+#define __USAT16(ARG1,ARG2) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
+{
+ uint32_t result;
+
+ __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
+{
+ uint32_t result;
+
+ __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u{
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ /* Little endian */
+ __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else /* Big endian */
+ __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+ return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u{
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ /* Little endian */
+ __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else /* Big endian */
+ __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+ return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u{
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ /* Little endian */
+ __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else /* Big endian */
+ __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+ return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u{
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ /* Little endian */
+ __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else /* Big endian */
+ __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+ return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __QADD( int32_t op1, int32_t op2)
+{
+ int32_t result;
+
+ __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __QSUB( int32_t op1, int32_t op2)
+{
+ int32_t result;
+
+ __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+#define __PKHBT(ARG1,ARG2,ARG3) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+ __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
+ __RES; \
+ })
+
+#define __PKHTB(ARG1,ARG2,ARG3) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+ if (ARG3 == 0) \
+ __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
+ else \
+ __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
+ __RES; \
+ })
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
+{
+ int32_t result;
+
+ __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+#endif /* (__CORTEX_M >= 0x04) */
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic pop
+#endif
+
+#endif /* __CMSIS_GCC_H */
diff --git a/templates/blackpill/Drivers/CMSIS/Include/core_cm0.h b/templates/blackpill/Drivers/CMSIS/Include/core_cm0.h
new file mode 100644
index 0000000..fdee521
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Include/core_cm0.h
@@ -0,0 +1,798 @@
+/**************************************************************************//**
+ * @file core_cm0.h
+ * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ 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 ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM0_H_GENERIC
+#define __CORE_CM0_H_GENERIC
+
+#include
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+ \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
+ CMSIS violates the following MISRA-C:2004 rules:
+
+ \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'.
+
+ \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers.
+
+ \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ * CMSIS definitions
+ ******************************************************************************/
+/**
+ \ingroup Cortex_M0
+ @{
+ */
+
+/* CMSIS CM0 definitions */
+#define __CM0_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
+#define __CM0_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
+#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \
+ __CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M (0x00U) /*!< Cortex-M Core */
+
+
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TMS470__ )
+ #define __ASM __asm /*!< asm keyword for TI CCS Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __CSMC__ )
+ #define __packed
+ #define __ASM _asm /*!< asm keyword for COSMIC Compiler */
+ #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+ #define __STATIC_INLINE static inline
+
+#else
+ #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+ This core does not support an FPU at all
+*/
+#define __FPU_USED 0U
+
+#if defined ( __CC_ARM )
+ #if defined __TARGET_FPU_VFP
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #if defined __ARM_PCS_VFP
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __GNUC__ )
+ #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __ICCARM__ )
+ #if defined __ARMVFP__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TMS470__ )
+ #if defined __TI_VFP_SUPPORT__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TASKING__ )
+ #if defined __FPU_VFP__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __CSMC__ )
+ #if ( __CSMC__ & 0x400U)
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#endif
+
+#include "core_cmInstr.h" /* Core Instruction Access */
+#include "core_cmFunc.h" /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM0_H_DEPENDANT
+#define __CORE_CM0_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+ #ifndef __CM0_REV
+ #define __CM0_REV 0x0000U
+ #warning "__CM0_REV not defined in device header file; using default!"
+ #endif
+
+ #ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 2U
+ #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+ #endif
+
+ #ifndef __Vendor_SysTickConfig
+ #define __Vendor_SysTickConfig 0U
+ #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+ #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+ \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+ IO Type Qualifiers are used
+ \li to specify the access to peripheral variables.
+ \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+ #define __I volatile /*!< Defines 'read only' permissions */
+#else
+ #define __I volatile const /*!< Defines 'read only' permissions */
+#endif
+#define __O volatile /*!< Defines 'write only' permissions */
+#define __IO volatile /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define __IM volatile const /*! Defines 'read only' structure member permissions */
+#define __OM volatile /*! Defines 'write only' structure member permissions */
+#define __IOM volatile /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex_M0 */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ Core Register contain:
+ - Core Register
+ - Core NVIC Register
+ - Core SCB Register
+ - Core SysTick Register
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_core_register Defines and Type Definitions
+ \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CORE Status and Control Registers
+ \brief Core Register type definitions.
+ @{
+ */
+
+/**
+ \brief Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos 31U /*!< APSR: N Position */
+#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
+
+#define APSR_Z_Pos 30U /*!< APSR: Z Position */
+#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
+
+#define APSR_C_Pos 29U /*!< APSR: C Position */
+#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
+
+#define APSR_V_Pos 28U /*!< APSR: V Position */
+#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
+
+
+/**
+ \brief Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
+ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
+ uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos 31U /*!< xPSR: N Position */
+#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
+#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos 29U /*!< xPSR: C Position */
+#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos 28U /*!< xPSR: V Position */
+#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
+
+#define xPSR_T_Pos 24U /*!< xPSR: T Position */
+#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t _reserved0:1; /*!< bit: 0 Reserved */
+ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
+ uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
+ \brief Type definitions for the NVIC Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+ __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
+ uint32_t RESERVED0[31U];
+ __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
+ uint32_t RSERVED1[31U];
+ __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
+ uint32_t RESERVED2[31U];
+ __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
+ uint32_t RESERVED3[31U];
+ uint32_t RESERVED4[64U];
+ __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
+} NVIC_Type;
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCB System Control Block (SCB)
+ \brief Type definitions for the System Control Block Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+ __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
+ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
+ uint32_t RESERVED0;
+ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
+ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
+ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
+ uint32_t RESERVED1;
+ __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
+ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SysTick System Tick Timer (SysTick)
+ \brief Type definitions for the System Timer Registers.
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+ __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
+ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
+ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
+ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
+ \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
+ Therefore they are not covered by the Cortex-M0 header file.
+ @{
+ */
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_bitfield Core register bit field macros
+ \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+ @{
+ */
+
+/**
+ \brief Mask and shift a bit field value for use in a register bit range.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of the bit field.
+ \return Masked and shifted value.
+*/
+#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
+
+/**
+ \brief Mask and shift a register value to extract a bit filed value.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of register.
+ \return Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_base Core Definitions
+ \brief Definitions for base addresses, unions, and structures.
+ @{
+ */
+
+/* Memory mapping of Cortex-M0 Hardware */
+#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
+
+#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
+
+
+/*@} */
+
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ Core Function Interface contains:
+ - Core NVIC Functions
+ - Core SysTick Functions
+ - Core Register Access Functions
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ########################## NVIC functions #################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+ \brief Functions that manage interrupts and exceptions via the NVIC.
+ @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
+#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
+#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
+
+
+/**
+ \brief Enable External Interrupt
+ \details Enables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Disable External Interrupt
+ \details Disables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Get Pending Interrupt
+ \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+ \param [in] IRQn Interrupt number.
+ \return 0 Interrupt status is not pending.
+ \return 1 Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+ \brief Set Pending Interrupt
+ \details Sets the pending bit of an external interrupt.
+ \param [in] IRQn Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Clear Pending Interrupt
+ \details Clears the pending bit of an external interrupt.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Set Interrupt Priority
+ \details Sets the priority of an interrupt.
+ \note The priority cannot be set for every core interrupt.
+ \param [in] IRQn Interrupt number.
+ \param [in] priority Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if ((int32_t)(IRQn) < 0)
+ {
+ SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+ }
+ else
+ {
+ NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+ }
+}
+
+
+/**
+ \brief Get Interrupt Priority
+ \details Reads the priority of an interrupt.
+ The interrupt number can be positive to specify an external (device specific) interrupt,
+ or negative to specify an internal (core) interrupt.
+ \param [in] IRQn Interrupt number.
+ \return Interrupt Priority.
+ Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if ((int32_t)(IRQn) < 0)
+ {
+ return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+ }
+ else
+ {
+ return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+ }
+}
+
+
+/**
+ \brief System Reset
+ \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+ __DSB(); /* Ensure all outstanding memory accesses included
+ buffered write are completed before reset */
+ SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+ SCB_AIRCR_SYSRESETREQ_Msk);
+ __DSB(); /* Ensure completion of memory access */
+
+ for(;;) /* wait until reset */
+ {
+ __NOP();
+ }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ################################## SysTick function ############################################ */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+ \brief Functions that configure the System.
+ @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+ \brief System Tick Configuration
+ \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+ Counter is in free running mode to generate periodic interrupts.
+ \param [in] ticks Number of ticks between two interrupts.
+ \return 0 Function succeeded.
+ \return 1 Function failed.
+ \note When the variable __Vendor_SysTickConfig is set to 1, then the
+ function SysTick_Config is not included. In this case, the file device.h
+ must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+ {
+ return (1UL); /* Reload value impossible */
+ }
+
+ SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_TICKINT_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
+ return (0UL); /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/templates/blackpill/Drivers/CMSIS/Include/core_cm0plus.h b/templates/blackpill/Drivers/CMSIS/Include/core_cm0plus.h
new file mode 100644
index 0000000..7614450
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Include/core_cm0plus.h
@@ -0,0 +1,914 @@
+/**************************************************************************//**
+ * @file core_cm0plus.h
+ * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ 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 ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM0PLUS_H_GENERIC
+#define __CORE_CM0PLUS_H_GENERIC
+
+#include
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+ \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
+ CMSIS violates the following MISRA-C:2004 rules:
+
+ \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'.
+
+ \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers.
+
+ \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ * CMSIS definitions
+ ******************************************************************************/
+/**
+ \ingroup Cortex-M0+
+ @{
+ */
+
+/* CMSIS CM0+ definitions */
+#define __CM0PLUS_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
+#define __CM0PLUS_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
+#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \
+ __CM0PLUS_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M (0x00U) /*!< Cortex-M Core */
+
+
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TMS470__ )
+ #define __ASM __asm /*!< asm keyword for TI CCS Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __CSMC__ )
+ #define __packed
+ #define __ASM _asm /*!< asm keyword for COSMIC Compiler */
+ #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+ #define __STATIC_INLINE static inline
+
+#else
+ #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+ This core does not support an FPU at all
+*/
+#define __FPU_USED 0U
+
+#if defined ( __CC_ARM )
+ #if defined __TARGET_FPU_VFP
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #if defined __ARM_PCS_VFP
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __GNUC__ )
+ #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __ICCARM__ )
+ #if defined __ARMVFP__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TMS470__ )
+ #if defined __TI_VFP_SUPPORT__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TASKING__ )
+ #if defined __FPU_VFP__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __CSMC__ )
+ #if ( __CSMC__ & 0x400U)
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#endif
+
+#include "core_cmInstr.h" /* Core Instruction Access */
+#include "core_cmFunc.h" /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0PLUS_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM0PLUS_H_DEPENDANT
+#define __CORE_CM0PLUS_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+ #ifndef __CM0PLUS_REV
+ #define __CM0PLUS_REV 0x0000U
+ #warning "__CM0PLUS_REV not defined in device header file; using default!"
+ #endif
+
+ #ifndef __MPU_PRESENT
+ #define __MPU_PRESENT 0U
+ #warning "__MPU_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __VTOR_PRESENT
+ #define __VTOR_PRESENT 0U
+ #warning "__VTOR_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 2U
+ #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+ #endif
+
+ #ifndef __Vendor_SysTickConfig
+ #define __Vendor_SysTickConfig 0U
+ #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+ #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+ \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+ IO Type Qualifiers are used
+ \li to specify the access to peripheral variables.
+ \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+ #define __I volatile /*!< Defines 'read only' permissions */
+#else
+ #define __I volatile const /*!< Defines 'read only' permissions */
+#endif
+#define __O volatile /*!< Defines 'write only' permissions */
+#define __IO volatile /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define __IM volatile const /*! Defines 'read only' structure member permissions */
+#define __OM volatile /*! Defines 'write only' structure member permissions */
+#define __IOM volatile /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex-M0+ */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ Core Register contain:
+ - Core Register
+ - Core NVIC Register
+ - Core SCB Register
+ - Core SysTick Register
+ - Core MPU Register
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_core_register Defines and Type Definitions
+ \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CORE Status and Control Registers
+ \brief Core Register type definitions.
+ @{
+ */
+
+/**
+ \brief Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos 31U /*!< APSR: N Position */
+#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
+
+#define APSR_Z_Pos 30U /*!< APSR: Z Position */
+#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
+
+#define APSR_C_Pos 29U /*!< APSR: C Position */
+#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
+
+#define APSR_V_Pos 28U /*!< APSR: V Position */
+#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
+
+
+/**
+ \brief Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
+ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
+ uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos 31U /*!< xPSR: N Position */
+#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
+#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos 29U /*!< xPSR: C Position */
+#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos 28U /*!< xPSR: V Position */
+#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
+
+#define xPSR_T_Pos 24U /*!< xPSR: T Position */
+#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
+ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
+ uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
+ \brief Type definitions for the NVIC Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+ __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
+ uint32_t RESERVED0[31U];
+ __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
+ uint32_t RSERVED1[31U];
+ __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
+ uint32_t RESERVED2[31U];
+ __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
+ uint32_t RESERVED3[31U];
+ uint32_t RESERVED4[64U];
+ __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
+} NVIC_Type;
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCB System Control Block (SCB)
+ \brief Type definitions for the System Control Block Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+ __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
+ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
+#if (__VTOR_PRESENT == 1U)
+ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
+#else
+ uint32_t RESERVED0;
+#endif
+ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
+ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
+ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
+ uint32_t RESERVED1;
+ __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
+ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
+
+#if (__VTOR_PRESENT == 1U)
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
+#endif
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SysTick System Tick Timer (SysTick)
+ \brief Type definitions for the System Timer Registers.
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+ __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
+ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
+ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
+ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+#if (__MPU_PRESENT == 1U)
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_MPU Memory Protection Unit (MPU)
+ \brief Type definitions for the Memory Protection Unit (MPU)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+ __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
+ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
+ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
+ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
+ __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
+ \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
+ Therefore they are not covered by the Cortex-M0+ header file.
+ @{
+ */
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_bitfield Core register bit field macros
+ \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+ @{
+ */
+
+/**
+ \brief Mask and shift a bit field value for use in a register bit range.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of the bit field.
+ \return Masked and shifted value.
+*/
+#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
+
+/**
+ \brief Mask and shift a register value to extract a bit filed value.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of register.
+ \return Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_base Core Definitions
+ \brief Definitions for base addresses, unions, and structures.
+ @{
+ */
+
+/* Memory mapping of Cortex-M0+ Hardware */
+#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
+
+#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+ #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
+ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ Core Function Interface contains:
+ - Core NVIC Functions
+ - Core SysTick Functions
+ - Core Register Access Functions
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ########################## NVIC functions #################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+ \brief Functions that manage interrupts and exceptions via the NVIC.
+ @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
+#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
+#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
+
+
+/**
+ \brief Enable External Interrupt
+ \details Enables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Disable External Interrupt
+ \details Disables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Get Pending Interrupt
+ \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+ \param [in] IRQn Interrupt number.
+ \return 0 Interrupt status is not pending.
+ \return 1 Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+ \brief Set Pending Interrupt
+ \details Sets the pending bit of an external interrupt.
+ \param [in] IRQn Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Clear Pending Interrupt
+ \details Clears the pending bit of an external interrupt.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Set Interrupt Priority
+ \details Sets the priority of an interrupt.
+ \note The priority cannot be set for every core interrupt.
+ \param [in] IRQn Interrupt number.
+ \param [in] priority Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if ((int32_t)(IRQn) < 0)
+ {
+ SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+ }
+ else
+ {
+ NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+ }
+}
+
+
+/**
+ \brief Get Interrupt Priority
+ \details Reads the priority of an interrupt.
+ The interrupt number can be positive to specify an external (device specific) interrupt,
+ or negative to specify an internal (core) interrupt.
+ \param [in] IRQn Interrupt number.
+ \return Interrupt Priority.
+ Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if ((int32_t)(IRQn) < 0)
+ {
+ return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+ }
+ else
+ {
+ return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+ }
+}
+
+
+/**
+ \brief System Reset
+ \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+ __DSB(); /* Ensure all outstanding memory accesses included
+ buffered write are completed before reset */
+ SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+ SCB_AIRCR_SYSRESETREQ_Msk);
+ __DSB(); /* Ensure completion of memory access */
+
+ for(;;) /* wait until reset */
+ {
+ __NOP();
+ }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ################################## SysTick function ############################################ */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+ \brief Functions that configure the System.
+ @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+ \brief System Tick Configuration
+ \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+ Counter is in free running mode to generate periodic interrupts.
+ \param [in] ticks Number of ticks between two interrupts.
+ \return 0 Function succeeded.
+ \return 1 Function failed.
+ \note When the variable __Vendor_SysTickConfig is set to 1, then the
+ function SysTick_Config is not included. In this case, the file device.h
+ must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+ {
+ return (1UL); /* Reload value impossible */
+ }
+
+ SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_TICKINT_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
+ return (0UL); /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0PLUS_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Include/core_cm3.h b/templates/blackpill/Drivers/CMSIS/Include/core_cm3.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Include/core_cm3.h
rename to templates/blackpill/Drivers/CMSIS/Include/core_cm3.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Include/core_cm4.h b/templates/blackpill/Drivers/CMSIS/Include/core_cm4.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Include/core_cm4.h
rename to templates/blackpill/Drivers/CMSIS/Include/core_cm4.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Include/core_cm7.h b/templates/blackpill/Drivers/CMSIS/Include/core_cm7.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Include/core_cm7.h
rename to templates/blackpill/Drivers/CMSIS/Include/core_cm7.h
diff --git a/templates/blackpill/Drivers/CMSIS/Include/core_cmFunc.h b/templates/blackpill/Drivers/CMSIS/Include/core_cmFunc.h
new file mode 100644
index 0000000..ca319a5
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Include/core_cmFunc.h
@@ -0,0 +1,87 @@
+/**************************************************************************//**
+ * @file core_cmFunc.h
+ * @brief CMSIS Cortex-M Core Function Access Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ 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 ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CMFUNC_H
+#define __CORE_CMFUNC_H
+
+
+/* ########################### Core Function Access ########################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+ @{
+*/
+
+/*------------------ RealView Compiler -----------------*/
+#if defined ( __CC_ARM )
+ #include "cmsis_armcc.h"
+
+/*------------------ ARM Compiler V6 -------------------*/
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #include "cmsis_armcc_V6.h"
+
+/*------------------ GNU Compiler ----------------------*/
+#elif defined ( __GNUC__ )
+ #include "cmsis_gcc.h"
+
+/*------------------ ICC Compiler ----------------------*/
+#elif defined ( __ICCARM__ )
+ #include
+
+/*------------------ TI CCS Compiler -------------------*/
+#elif defined ( __TMS470__ )
+ #include
+
+/*------------------ TASKING Compiler ------------------*/
+#elif defined ( __TASKING__ )
+ /*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all intrinsics,
+ * Including the CMSIS ones.
+ */
+
+/*------------------ COSMIC Compiler -------------------*/
+#elif defined ( __CSMC__ )
+ #include
+
+#endif
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+#endif /* __CORE_CMFUNC_H */
diff --git a/templates/blackpill/Drivers/CMSIS/Include/core_cmInstr.h b/templates/blackpill/Drivers/CMSIS/Include/core_cmInstr.h
new file mode 100644
index 0000000..a0a5064
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Include/core_cmInstr.h
@@ -0,0 +1,87 @@
+/**************************************************************************//**
+ * @file core_cmInstr.h
+ * @brief CMSIS Cortex-M Core Instruction Access Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ 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 ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CMINSTR_H
+#define __CORE_CMINSTR_H
+
+
+/* ########################## Core Instruction Access ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+ Access to dedicated instructions
+ @{
+*/
+
+/*------------------ RealView Compiler -----------------*/
+#if defined ( __CC_ARM )
+ #include "cmsis_armcc.h"
+
+/*------------------ ARM Compiler V6 -------------------*/
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #include "cmsis_armcc_V6.h"
+
+/*------------------ GNU Compiler ----------------------*/
+#elif defined ( __GNUC__ )
+ #include "cmsis_gcc.h"
+
+/*------------------ ICC Compiler ----------------------*/
+#elif defined ( __ICCARM__ )
+ #include
+
+/*------------------ TI CCS Compiler -------------------*/
+#elif defined ( __TMS470__ )
+ #include
+
+/*------------------ TASKING Compiler ------------------*/
+#elif defined ( __TASKING__ )
+ /*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all intrinsics,
+ * Including the CMSIS ones.
+ */
+
+/*------------------ COSMIC Compiler -------------------*/
+#elif defined ( __CSMC__ )
+ #include
+
+#endif
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+#endif /* __CORE_CMINSTR_H */
diff --git a/templates/blackpill/Drivers/CMSIS/Include/core_cmSimd.h b/templates/blackpill/Drivers/CMSIS/Include/core_cmSimd.h
new file mode 100644
index 0000000..4d76bf9
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Include/core_cmSimd.h
@@ -0,0 +1,96 @@
+/**************************************************************************//**
+ * @file core_cmSimd.h
+ * @brief CMSIS Cortex-M SIMD Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ 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 ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CMSIMD_H
+#define __CORE_CMSIMD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+ Access to dedicated SIMD instructions
+ @{
+*/
+
+/*------------------ RealView Compiler -----------------*/
+#if defined ( __CC_ARM )
+ #include "cmsis_armcc.h"
+
+/*------------------ ARM Compiler V6 -------------------*/
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #include "cmsis_armcc_V6.h"
+
+/*------------------ GNU Compiler ----------------------*/
+#elif defined ( __GNUC__ )
+ #include "cmsis_gcc.h"
+
+/*------------------ ICC Compiler ----------------------*/
+#elif defined ( __ICCARM__ )
+ #include
+
+/*------------------ TI CCS Compiler -------------------*/
+#elif defined ( __TMS470__ )
+ #include
+
+/*------------------ TASKING Compiler ------------------*/
+#elif defined ( __TASKING__ )
+ /*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all intrinsics,
+ * Including the CMSIS ones.
+ */
+
+/*------------------ COSMIC Compiler -------------------*/
+#elif defined ( __CSMC__ )
+ #include
+
+#endif
+
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CMSIMD_H */
diff --git a/templates/blackpill/Drivers/CMSIS/Include/core_sc000.h b/templates/blackpill/Drivers/CMSIS/Include/core_sc000.h
new file mode 100644
index 0000000..ea16bf3
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/Include/core_sc000.h
@@ -0,0 +1,926 @@
+/**************************************************************************//**
+ * @file core_sc000.h
+ * @brief CMSIS SC000 Core Peripheral Access Layer Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ 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 ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_SC000_H_GENERIC
+#define __CORE_SC000_H_GENERIC
+
+#include
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+ \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
+ CMSIS violates the following MISRA-C:2004 rules:
+
+ \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'.
+
+ \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers.
+
+ \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ * CMSIS definitions
+ ******************************************************************************/
+/**
+ \ingroup SC000
+ @{
+ */
+
+/* CMSIS SC000 definitions */
+#define __SC000_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
+#define __SC000_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
+#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16U) | \
+ __SC000_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
+
+#define __CORTEX_SC (000U) /*!< Cortex secure core */
+
+
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TMS470__ )
+ #define __ASM __asm /*!< asm keyword for TI CCS Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __CSMC__ )
+ #define __packed
+ #define __ASM _asm /*!< asm keyword for COSMIC Compiler */
+ #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+ #define __STATIC_INLINE static inline
+
+#else
+ #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+ This core does not support an FPU at all
+*/
+#define __FPU_USED 0U
+
+#if defined ( __CC_ARM )
+ #if defined __TARGET_FPU_VFP
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #if defined __ARM_PCS_VFP
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __GNUC__ )
+ #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __ICCARM__ )
+ #if defined __ARMVFP__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TMS470__ )
+ #if defined __TI_VFP_SUPPORT__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TASKING__ )
+ #if defined __FPU_VFP__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __CSMC__ )
+ #if ( __CSMC__ & 0x400U)
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#endif
+
+#include "core_cmInstr.h" /* Core Instruction Access */
+#include "core_cmFunc.h" /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_SC000_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_SC000_H_DEPENDANT
+#define __CORE_SC000_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+ #ifndef __SC000_REV
+ #define __SC000_REV 0x0000U
+ #warning "__SC000_REV not defined in device header file; using default!"
+ #endif
+
+ #ifndef __MPU_PRESENT
+ #define __MPU_PRESENT 0U
+ #warning "__MPU_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 2U
+ #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+ #endif
+
+ #ifndef __Vendor_SysTickConfig
+ #define __Vendor_SysTickConfig 0U
+ #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+ #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+ \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+ IO Type Qualifiers are used
+ \li to specify the access to peripheral variables.
+ \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+ #define __I volatile /*!< Defines 'read only' permissions */
+#else
+ #define __I volatile const /*!< Defines 'read only' permissions */
+#endif
+#define __O volatile /*!< Defines 'write only' permissions */
+#define __IO volatile /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define __IM volatile const /*! Defines 'read only' structure member permissions */
+#define __OM volatile /*! Defines 'write only' structure member permissions */
+#define __IOM volatile /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group SC000 */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ Core Register contain:
+ - Core Register
+ - Core NVIC Register
+ - Core SCB Register
+ - Core SysTick Register
+ - Core MPU Register
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_core_register Defines and Type Definitions
+ \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CORE Status and Control Registers
+ \brief Core Register type definitions.
+ @{
+ */
+
+/**
+ \brief Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos 31U /*!< APSR: N Position */
+#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
+
+#define APSR_Z_Pos 30U /*!< APSR: Z Position */
+#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
+
+#define APSR_C_Pos 29U /*!< APSR: C Position */
+#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
+
+#define APSR_V_Pos 28U /*!< APSR: V Position */
+#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
+
+
+/**
+ \brief Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
+ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
+ uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos 31U /*!< xPSR: N Position */
+#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
+#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos 29U /*!< xPSR: C Position */
+#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos 28U /*!< xPSR: V Position */
+#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
+
+#define xPSR_T_Pos 24U /*!< xPSR: T Position */
+#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t _reserved0:1; /*!< bit: 0 Reserved */
+ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
+ uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
+ \brief Type definitions for the NVIC Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+ __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
+ uint32_t RESERVED0[31U];
+ __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
+ uint32_t RSERVED1[31U];
+ __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
+ uint32_t RESERVED2[31U];
+ __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
+ uint32_t RESERVED3[31U];
+ uint32_t RESERVED4[64U];
+ __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
+} NVIC_Type;
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCB System Control Block (SCB)
+ \brief Type definitions for the System Control Block Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+ __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
+ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
+ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
+ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
+ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
+ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
+ uint32_t RESERVED0[1U];
+ __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
+ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
+ uint32_t RESERVED1[154U];
+ __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+ \brief Type definitions for the System Control and ID Register not in the SCB
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+ uint32_t RESERVED0[2U];
+ __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */
+} SCnSCB_Type;
+
+/* Auxiliary Control Register Definitions */
+#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SysTick System Tick Timer (SysTick)
+ \brief Type definitions for the System Timer Registers.
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+ __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
+ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
+ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
+ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+#if (__MPU_PRESENT == 1U)
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_MPU Memory Protection Unit (MPU)
+ \brief Type definitions for the Memory Protection Unit (MPU)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+ __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
+ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
+ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
+ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
+ __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
+ \brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
+ Therefore they are not covered by the SC000 header file.
+ @{
+ */
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_bitfield Core register bit field macros
+ \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+ @{
+ */
+
+/**
+ \brief Mask and shift a bit field value for use in a register bit range.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of the bit field.
+ \return Masked and shifted value.
+*/
+#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
+
+/**
+ \brief Mask and shift a register value to extract a bit filed value.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of register.
+ \return Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_base Core Definitions
+ \brief Definitions for base addresses, unions, and structures.
+ @{
+ */
+
+/* Memory mapping of SC000 Hardware */
+#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
+
+#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
+#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+ #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
+ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ Core Function Interface contains:
+ - Core NVIC Functions
+ - Core SysTick Functions
+ - Core Register Access Functions
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ########################## NVIC functions #################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+ \brief Functions that manage interrupts and exceptions via the NVIC.
+ @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
+#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
+#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
+
+
+/**
+ \brief Enable External Interrupt
+ \details Enables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Disable External Interrupt
+ \details Disables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Get Pending Interrupt
+ \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+ \param [in] IRQn Interrupt number.
+ \return 0 Interrupt status is not pending.
+ \return 1 Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+ \brief Set Pending Interrupt
+ \details Sets the pending bit of an external interrupt.
+ \param [in] IRQn Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Clear Pending Interrupt
+ \details Clears the pending bit of an external interrupt.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Set Interrupt Priority
+ \details Sets the priority of an interrupt.
+ \note The priority cannot be set for every core interrupt.
+ \param [in] IRQn Interrupt number.
+ \param [in] priority Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if ((int32_t)(IRQn) < 0)
+ {
+ SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+ }
+ else
+ {
+ NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+ }
+}
+
+
+/**
+ \brief Get Interrupt Priority
+ \details Reads the priority of an interrupt.
+ The interrupt number can be positive to specify an external (device specific) interrupt,
+ or negative to specify an internal (core) interrupt.
+ \param [in] IRQn Interrupt number.
+ \return Interrupt Priority.
+ Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if ((int32_t)(IRQn) < 0)
+ {
+ return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+ }
+ else
+ {
+ return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+ }
+}
+
+
+/**
+ \brief System Reset
+ \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+ __DSB(); /* Ensure all outstanding memory accesses included
+ buffered write are completed before reset */
+ SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+ SCB_AIRCR_SYSRESETREQ_Msk);
+ __DSB(); /* Ensure completion of memory access */
+
+ for(;;) /* wait until reset */
+ {
+ __NOP();
+ }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ################################## SysTick function ############################################ */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+ \brief Functions that configure the System.
+ @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+ \brief System Tick Configuration
+ \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+ Counter is in free running mode to generate periodic interrupts.
+ \param [in] ticks Number of ticks between two interrupts.
+ \return 0 Function succeeded.
+ \return 1 Function failed.
+ \note When the variable __Vendor_SysTickConfig is set to 1, then the
+ function SysTick_Config is not included. In this case, the file device.h
+ must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+ {
+ return (1UL); /* Reload value impossible */
+ }
+
+ SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_TICKINT_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
+ return (0UL); /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_SC000_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Include/core_sc300.h b/templates/blackpill/Drivers/CMSIS/Include/core_sc300.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Include/core_sc300.h
rename to templates/blackpill/Drivers/CMSIS/Include/core_sc300.h
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Lib/ARM/arm_cortexM3b_math.lib b/templates/blackpill/Drivers/CMSIS/Lib/ARM/arm_cortexM3b_math.lib
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Lib/ARM/arm_cortexM3b_math.lib
rename to templates/blackpill/Drivers/CMSIS/Lib/ARM/arm_cortexM3b_math.lib
Binary files a/assets/templates/blackpill/Drivers/CMSIS/Lib/ARM/arm_cortexM3b_math.lib and b/templates/blackpill/Drivers/CMSIS/Lib/ARM/arm_cortexM3b_math.lib differ
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Lib/ARM/arm_cortexM3l_math.lib b/templates/blackpill/Drivers/CMSIS/Lib/ARM/arm_cortexM3l_math.lib
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Lib/ARM/arm_cortexM3l_math.lib
rename to templates/blackpill/Drivers/CMSIS/Lib/ARM/arm_cortexM3l_math.lib
Binary files a/assets/templates/blackpill/Drivers/CMSIS/Lib/ARM/arm_cortexM3l_math.lib and b/templates/blackpill/Drivers/CMSIS/Lib/ARM/arm_cortexM3l_math.lib differ
diff --git a/assets/templates/blackpill/Drivers/CMSIS/Lib/GCC/libarm_cortexM3l_math.a b/templates/blackpill/Drivers/CMSIS/Lib/GCC/libarm_cortexM3l_math.a
similarity index 100%
rename from assets/templates/blackpill/Drivers/CMSIS/Lib/GCC/libarm_cortexM3l_math.a
rename to templates/blackpill/Drivers/CMSIS/Lib/GCC/libarm_cortexM3l_math.a
Binary files a/assets/templates/blackpill/Drivers/CMSIS/Lib/GCC/libarm_cortexM3l_math.a and b/templates/blackpill/Drivers/CMSIS/Lib/GCC/libarm_cortexM3l_math.a differ
diff --git a/templates/blackpill/Drivers/CMSIS/RTOS/Template/cmsis_os.h b/templates/blackpill/Drivers/CMSIS/RTOS/Template/cmsis_os.h
new file mode 100644
index 0000000..068ebca
--- /dev/null
+++ b/templates/blackpill/Drivers/CMSIS/RTOS/Template/cmsis_os.h
@@ -0,0 +1,707 @@
+/* ----------------------------------------------------------------------
+ * $Date: 5. February 2013
+ * $Revision: V1.02
+ *
+ * Project: CMSIS-RTOS API
+ * Title: cmsis_os.h template header file
+ *
+ * Version 0.02
+ * Initial Proposal Phase
+ * Version 0.03
+ * osKernelStart added, optional feature: main started as thread
+ * osSemaphores have standard behavior
+ * osTimerCreate does not start the timer, added osTimerStart
+ * osThreadPass is renamed to osThreadYield
+ * Version 1.01
+ * Support for C++ interface
+ * - const attribute removed from the osXxxxDef_t typedef's
+ * - const attribute added to the osXxxxDef macros
+ * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete
+ * Added: osKernelInitialize
+ * Version 1.02
+ * Control functions for short timeouts in microsecond resolution:
+ * Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec
+ * Removed: osSignalGet
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 2013 ARM LIMITED
+ * 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 ARM 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 COPYRIGHT HOLDERS AND 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 _CMSIS_OS_H
+#define _CMSIS_OS_H
+
+/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version.
+#define osCMSIS 0x10002 ///< API version (main [31:16] .sub [15:0])
+
+/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number.
+#define osCMSIS_KERNEL 0x10000 ///< RTOS identification and version (main [31:16] .sub [15:0])
+
+/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS.
+#define osKernelSystemId "KERNEL V1.00" ///< RTOS identification string
+
+/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS.
+#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available
+#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available
+#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available
+#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available
+#define osFeature_Signals 8 ///< maximum number of Signal Flags available per thread
+#define osFeature_Semaphore 30 ///< maximum count for \ref osSemaphoreCreate function
+#define osFeature_Wait 1 ///< osWait function: 1=available, 0=not available
+#define osFeature_SysTick 1 ///< osKernelSysTick functions: 1=available, 0=not available
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+// ==== Enumeration, structures, defines ====
+
+/// Priority used for thread control.
+/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS.
+typedef enum {
+ osPriorityIdle = -3, ///< priority: idle (lowest)
+ osPriorityLow = -2, ///< priority: low
+ osPriorityBelowNormal = -1, ///< priority: below normal
+ osPriorityNormal = 0, ///< priority: normal (default)
+ osPriorityAboveNormal = +1, ///< priority: above normal
+ osPriorityHigh = +2, ///< priority: high
+ osPriorityRealtime = +3, ///< priority: realtime (highest)
+ osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority
+} osPriority;
+
+/// Timeout value.
+/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS.
+#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value
+
+/// Status code values returned by CMSIS-RTOS functions.
+/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS.
+typedef enum {
+ osOK = 0, ///< function completed; no error or event occurred.
+ osEventSignal = 0x08, ///< function completed; signal event occurred.
+ osEventMessage = 0x10, ///< function completed; message event occurred.
+ osEventMail = 0x20, ///< function completed; mail event occurred.
+ osEventTimeout = 0x40, ///< function completed; timeout occurred.
+ osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object.
+ osErrorResource = 0x81, ///< resource not available: a specified resource was not available.
+ osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period.
+ osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines.
+ osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object.
+ osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority.
+ osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation.
+ osErrorValue = 0x86, ///< value of a parameter is out of range.
+ osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits.
+ os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization.
+} osStatus;
+
+
+/// Timer type value for the timer definition.
+/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS.
+typedef enum {
+ osTimerOnce = 0, ///< one-shot timer
+ osTimerPeriodic = 1 ///< repeating timer
+} os_timer_type;
+
+/// Entry point of a thread.
+/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS.
+typedef void (*os_pthread) (void const *argument);
+
+/// Entry point of a timer call back function.
+/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS.
+typedef void (*os_ptimer) (void const *argument);
+
+// >>> the following data type definitions may shall adapted towards a specific RTOS
+
+/// Thread ID identifies the thread (pointer to a thread control block).
+/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS.
+typedef struct os_thread_cb *osThreadId;
+
+/// Timer ID identifies the timer (pointer to a timer control block).
+/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS.
+typedef struct os_timer_cb *osTimerId;
+
+/// Mutex ID identifies the mutex (pointer to a mutex control block).
+/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS.
+typedef struct os_mutex_cb *osMutexId;
+
+/// Semaphore ID identifies the semaphore (pointer to a semaphore control block).
+/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS.
+typedef struct os_semaphore_cb *osSemaphoreId;
+
+/// Pool ID identifies the memory pool (pointer to a memory pool control block).
+/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS.
+typedef struct os_pool_cb *osPoolId;
+
+/// Message ID identifies the message queue (pointer to a message queue control block).
+/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS.
+typedef struct os_messageQ_cb *osMessageQId;
+
+/// Mail ID identifies the mail queue (pointer to a mail queue control block).
+/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS.
+typedef struct os_mailQ_cb *osMailQId;
+
+
+/// Thread Definition structure contains startup information of a thread.
+/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_thread_def {
+ os_pthread pthread; ///< start address of thread function
+ osPriority tpriority; ///< initial thread priority
+ uint32_t instances; ///< maximum number of instances of that thread function
+ uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size
+} osThreadDef_t;
+
+/// Timer Definition structure contains timer parameters.
+/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_timer_def {
+ os_ptimer ptimer; ///< start address of a timer function
+} osTimerDef_t;
+
+/// Mutex Definition structure contains setup information for a mutex.
+/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_mutex_def {
+ uint32_t dummy; ///< dummy value.
+} osMutexDef_t;
+
+/// Semaphore Definition structure contains setup information for a semaphore.
+/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_semaphore_def {
+ uint32_t dummy; ///< dummy value.
+} osSemaphoreDef_t;
+
+/// Definition structure for memory block allocation.
+/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_pool_def {
+ uint32_t pool_sz; ///< number of items (elements) in the pool
+ uint32_t item_sz; ///< size of an item
+ void *pool; ///< pointer to memory for pool
+} osPoolDef_t;
+
+/// Definition structure for message queue.
+/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_messageQ_def {
+ uint32_t queue_sz; ///< number of elements in the queue
+ uint32_t item_sz; ///< size of an item
+ void *pool; ///< memory array for messages
+} osMessageQDef_t;
+
+/// Definition structure for mail queue.
+/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_mailQ_def {
+ uint32_t queue_sz; ///< number of elements in the queue
+ uint32_t item_sz; ///< size of an item
+ void *pool; ///< memory array for mail
+} osMailQDef_t;
+
+/// Event structure contains detailed information about an event.
+/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS.
+/// However the struct may be extended at the end.
+typedef struct {
+ osStatus status; ///< status code: event or error information
+ union {
+ uint32_t v; ///< message as 32-bit value
+ void *p; ///< message or mail as void pointer
+ int32_t signals; ///< signal flags
+ } value; ///< event value
+ union {
+ osMailQId mail_id; ///< mail id obtained by \ref osMailCreate
+ osMessageQId message_id; ///< message id obtained by \ref osMessageCreate
+ } def; ///< event definition
+} osEvent;
+
+
+// ==== Kernel Control Functions ====
+
+/// Initialize the RTOS Kernel for creating objects.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS.
+osStatus osKernelInitialize (void);
+
+/// Start the RTOS Kernel.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS.
+osStatus osKernelStart (void);
+
+/// Check if the RTOS kernel is already started.
+/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS.
+/// \return 0 RTOS is not started, 1 RTOS is started.
+int32_t osKernelRunning(void);
+
+#if (defined (osFeature_SysTick) && (osFeature_SysTick != 0)) // System Timer available
+
+/// Get the RTOS kernel system timer counter
+/// \note MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS.
+/// \return RTOS kernel system timer as 32-bit value
+uint32_t osKernelSysTick (void);
+
+/// The RTOS kernel system timer frequency in Hz
+/// \note Reflects the system timer setting and is typically defined in a configuration file.
+#define osKernelSysTickFrequency 100000000
+
+/// Convert a microseconds value to a RTOS kernel system timer value.
+/// \param microsec time value in microseconds.
+/// \return time value normalized to the \ref osKernelSysTickFrequency
+#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000)
+
+#endif // System Timer available
+
+// ==== Thread Management ====
+
+/// Create a Thread Definition with function, priority, and stack requirements.
+/// \param name name of the thread function.
+/// \param priority initial priority of the thread function.
+/// \param instances number of possible thread instances.
+/// \param stacksz stack size (in bytes) requirements for the thread function.
+/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the
+/// macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal) // object is external
+#define osThreadDef(name, priority, instances, stacksz) \
+extern const osThreadDef_t os_thread_def_##name
+#else // define the object
+#define osThreadDef(name, priority, instances, stacksz) \
+const osThreadDef_t os_thread_def_##name = \
+{ (name), (priority), (instances), (stacksz) }
+#endif
+
+/// Access a Thread definition.
+/// \param name name of the thread definition object.
+/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the
+/// macro body is implementation specific in every CMSIS-RTOS.
+#define osThread(name) \
+&os_thread_def_##name
+
+/// Create a thread and add it to Active Threads and set it to state READY.
+/// \param[in] thread_def thread definition referenced with \ref osThread.
+/// \param[in] argument pointer that is passed to the thread function as start argument.
+/// \return thread ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS.
+osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument);
+
+/// Return the thread ID of the current running thread.
+/// \return thread ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS.
+osThreadId osThreadGetId (void);
+
+/// Terminate execution of a thread and remove it from Active Threads.
+/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS.
+osStatus osThreadTerminate (osThreadId thread_id);
+
+/// Pass control to next thread that is in state \b READY.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS.
+osStatus osThreadYield (void);
+
+/// Change priority of an active thread.
+/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in] priority new priority value for the thread function.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS.
+osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority);
+
+/// Get current priority of an active thread.
+/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \return current priority value of the thread function.
+/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS.
+osPriority osThreadGetPriority (osThreadId thread_id);
+
+
+// ==== Generic Wait Functions ====
+
+/// Wait for Timeout (Time Delay).
+/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "time delay" value
+/// \return status code that indicates the execution status of the function.
+osStatus osDelay (uint32_t millisec);
+
+#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available
+
+/// Wait for Signal, Message, Mail, or Timeout.
+/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
+/// \return event that contains signal, message, or mail information or error code.
+/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS.
+osEvent osWait (uint32_t millisec);
+
+#endif // Generic Wait available
+
+
+// ==== Timer Management Functions ====
+/// Define a Timer object.
+/// \param name name of the timer object.
+/// \param function name of the timer call back function.
+/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the
+/// macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal) // object is external
+#define osTimerDef(name, function) \
+extern const osTimerDef_t os_timer_def_##name
+#else // define the object
+#define osTimerDef(name, function) \
+const osTimerDef_t os_timer_def_##name = \
+{ (function) }
+#endif
+
+/// Access a Timer definition.
+/// \param name name of the timer object.
+/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the
+/// macro body is implementation specific in every CMSIS-RTOS.
+#define osTimer(name) \
+&os_timer_def_##name
+
+/// Create a timer.
+/// \param[in] timer_def timer object referenced with \ref osTimer.
+/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
+/// \param[in] argument argument to the timer call back function.
+/// \return timer ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS.
+osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument);
+
+/// Start or restart a timer.
+/// \param[in] timer_id timer ID obtained by \ref osTimerCreate.
+/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "time delay" value of the timer.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS.
+osStatus osTimerStart (osTimerId timer_id, uint32_t millisec);
+
+/// Stop the timer.
+/// \param[in] timer_id timer ID obtained by \ref osTimerCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS.
+osStatus osTimerStop (osTimerId timer_id);
+
+/// Delete a timer that was created by \ref osTimerCreate.
+/// \param[in] timer_id timer ID obtained by \ref osTimerCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS.
+osStatus osTimerDelete (osTimerId timer_id);
+
+
+// ==== Signal Management ====
+
+/// Set the specified Signal Flags of an active thread.
+/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in] signals specifies the signal flags of the thread that should be set.
+/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
+/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS.
+int32_t osSignalSet (osThreadId thread_id, int32_t signals);
+
+/// Clear the specified Signal Flags of an active thread.
+/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in] signals specifies the signal flags of the thread that shall be cleared.
+/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters or call from ISR.
+/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS.
+int32_t osSignalClear (osThreadId thread_id, int32_t signals);
+
+/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread.
+/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag.
+/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return event flag information or error code.
+/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS.
+osEvent osSignalWait (int32_t signals, uint32_t millisec);
+
+
+// ==== Mutex Management ====
+
+/// Define a Mutex.
+/// \param name name of the mutex object.
+/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the
+/// macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal) // object is external
+#define osMutexDef(name) \
+extern const osMutexDef_t os_mutex_def_##name
+#else // define the object
+#define osMutexDef(name) \
+const osMutexDef_t os_mutex_def_##name = { 0 }
+#endif
+
+/// Access a Mutex definition.
+/// \param name name of the mutex object.
+/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the
+/// macro body is implementation specific in every CMSIS-RTOS.
+#define osMutex(name) \
+&os_mutex_def_##name
+
+/// Create and Initialize a Mutex object.
+/// \param[in] mutex_def mutex definition referenced with \ref osMutex.
+/// \return mutex ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS.
+osMutexId osMutexCreate (const osMutexDef_t *mutex_def);
+
+/// Wait until a Mutex becomes available.
+/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate.
+/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS.
+osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec);
+
+/// Release a Mutex that was obtained by \ref osMutexWait.
+/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS.
+osStatus osMutexRelease (osMutexId mutex_id);
+
+/// Delete a Mutex that was created by \ref osMutexCreate.
+/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS.
+osStatus osMutexDelete (osMutexId mutex_id);
+
+
+// ==== Semaphore Management Functions ====
+
+#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available
+
+/// Define a Semaphore object.
+/// \param name name of the semaphore object.
+/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the
+/// macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal) // object is external
+#define osSemaphoreDef(name) \
+extern const osSemaphoreDef_t os_semaphore_def_##name
+#else // define the object
+#define osSemaphoreDef(name) \
+const osSemaphoreDef_t os_semaphore_def_##name = { 0 }
+#endif
+
+/// Access a Semaphore definition.
+/// \param name name of the semaphore object.
+/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the
+/// macro body is implementation specific in every CMSIS-RTOS.
+#define osSemaphore(name) \
+&os_semaphore_def_##name
+
+/// Create and Initialize a Semaphore object used for managing resources.
+/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore.
+/// \param[in] count number of available resources.
+/// \return semaphore ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS.
+osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count);
+
+/// Wait until a Semaphore token becomes available.
+/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate.
+/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return number of available tokens, or -1 in case of incorrect parameters.
+/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS.
+int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec);
+
+/// Release a Semaphore token.
+/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS.
+osStatus osSemaphoreRelease (osSemaphoreId semaphore_id);
+
+/// Delete a Semaphore that was created by \ref osSemaphoreCreate.
+/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS.
+osStatus osSemaphoreDelete (osSemaphoreId semaphore_id);
+
+#endif // Semaphore available
+
+
+// ==== Memory Pool Management Functions ====
+
+#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available
+
+/// \brief Define a Memory Pool.
+/// \param name name of the memory pool.
+/// \param no maximum number of blocks (objects) in the memory pool.
+/// \param type data type of a single block (object).
+/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the
+/// macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal) // object is external
+#define osPoolDef(name, no, type) \
+extern const osPoolDef_t os_pool_def_##name
+#else // define the object
+#define osPoolDef(name, no, type) \
+const osPoolDef_t os_pool_def_##name = \
+{ (no), sizeof(type), NULL }
+#endif
+
+/// \brief Access a Memory Pool definition.
+/// \param name name of the memory pool
+/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the
+/// macro body is implementation specific in every CMSIS-RTOS.
+#define osPool(name) \
+&os_pool_def_##name
+
+/// Create and Initialize a memory pool.
+/// \param[in] pool_def memory pool definition referenced with \ref osPool.
+/// \return memory pool ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS.
+osPoolId osPoolCreate (const osPoolDef_t *pool_def);
+
+/// Allocate a memory block from a memory pool.
+/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate.
+/// \return address of the allocated memory block or NULL in case of no memory available.
+/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS.
+void *osPoolAlloc (osPoolId pool_id);
+
+/// Allocate a memory block from a memory pool and set memory block to zero.
+/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate.
+/// \return address of the allocated memory block or NULL in case of no memory available.
+/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS.
+void *osPoolCAlloc (osPoolId pool_id);
+
+/// Return an allocated memory block back to a specific memory pool.
+/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate.
+/// \param[in] block address of the allocated memory block that is returned to the memory pool.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS.
+osStatus osPoolFree (osPoolId pool_id, void *block);
+
+#endif // Memory Pool Management available
+
+
+// ==== Message Queue Management Functions ====
+
+#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available
+
+/// \brief Create a Message Queue Definition.
+/// \param name name of the queue.
+/// \param queue_sz maximum number of messages in the queue.
+/// \param type data type of a single message element (for debugger).
+/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the
+/// macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal) // object is external
+#define osMessageQDef(name, queue_sz, type) \
+extern const osMessageQDef_t os_messageQ_def_##name
+#else // define the object
+#define osMessageQDef(name, queue_sz, type) \
+const osMessageQDef_t os_messageQ_def_##name = \
+{ (queue_sz), sizeof (type) }
+#endif
+
+/// \brief Access a Message Queue Definition.
+/// \param name name of the queue
+/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the
+/// macro body is implementation specific in every CMSIS-RTOS.
+#define osMessageQ(name) \
+&os_messageQ_def_##name
+
+/// Create and Initialize a Message Queue.
+/// \param[in] queue_def queue definition referenced with \ref osMessageQ.
+/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
+/// \return message queue ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS.
+osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id);
+
+/// Put a Message to a Queue.
+/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate.
+/// \param[in] info message information.
+/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS.
+osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec);
+
+/// Get a Message or Wait for a Message from a Queue.
+/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate.
+/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
+/// \return event information that includes status code.
+/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS.
+osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec);
+
+#endif // Message Queues available
+
+
+// ==== Mail Queue Management Functions ====
+
+#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available
+
+/// \brief Create a Mail Queue Definition.
+/// \param name name of the queue
+/// \param queue_sz maximum number of messages in queue
+/// \param type data type of a single message element
+/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the
+/// macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal) // object is external
+#define osMailQDef(name, queue_sz, type) \
+extern const osMailQDef_t os_mailQ_def_##name
+#else // define the object
+#define osMailQDef(name, queue_sz, type) \
+const osMailQDef_t os_mailQ_def_##name = \
+{ (queue_sz), sizeof (type) }
+#endif
+
+/// \brief Access a Mail Queue Definition.
+/// \param name name of the queue
+/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the
+/// macro body is implementation specific in every CMSIS-RTOS.
+#define osMailQ(name) \
+&os_mailQ_def_##name
+
+/// Create and Initialize mail queue.
+/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ
+/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
+/// \return mail queue ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS.
+osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id);
+
+/// Allocate a memory block from a mail.
+/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
+/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
+/// \return pointer to memory block that can be filled with mail or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS.
+void *osMailAlloc (osMailQId queue_id, uint32_t millisec);
+
+/// Allocate a memory block from a mail and set memory block to zero.
+/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
+/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
+/// \return pointer to memory block that can be filled with mail or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS.
+void *osMailCAlloc (osMailQId queue_id, uint32_t millisec);
+
+/// Put a mail to a queue.
+/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
+/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS.
+osStatus osMailPut (osMailQId queue_id, void *mail);
+
+/// Get a mail from a queue.
+/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
+/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
+/// \return event that contains mail information or error code.
+/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS.
+osEvent osMailGet (osMailQId queue_id, uint32_t millisec);
+
+/// Free a memory block from a mail.
+/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
+/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS.
+osStatus osMailFree (osMailQId queue_id, void *mail);
+
+#endif // Mail Queues available
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _CMSIS_OS_H
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h
rename to templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32f1xx_hal_can_ex_legacy.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32f1xx_hal_can_ex_legacy.h
new file mode 100644
index 0000000..b389603
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32f1xx_hal_can_ex_legacy.h
@@ -0,0 +1,144 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_can_ex.h
+ * @author MCD Application Team
+ * @brief Header file of CAN HAL Extension module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_CAN_EX_H
+#define __STM32F1xx_HAL_CAN_EX_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#if defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || \
+ defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup CANEx CANEx
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief CAN filter configuration structure definition
+ */
+/* CAN filter banks differences over STM32F1 devices: */
+/* - STM32F1 Connectivity line: 28 filter banks shared between CAN1 and CAN2 */
+/* - Other STM32F10x devices: 14 filter banks */
+
+typedef struct
+{
+ uint32_t FilterIdHigh; /*!< Specifies the filter identification number (MSBs for a 32-bit
+ configuration, first one for a 16-bit configuration).
+ This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
+
+ uint32_t FilterIdLow; /*!< Specifies the filter identification number (LSBs for a 32-bit
+ configuration, second one for a 16-bit configuration).
+ This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
+
+ uint32_t FilterMaskIdHigh; /*!< Specifies the filter mask number or identification number,
+ according to the mode (MSBs for a 32-bit configuration,
+ first one for a 16-bit configuration).
+ This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
+
+ uint32_t FilterMaskIdLow; /*!< Specifies the filter mask number or identification number,
+ according to the mode (LSBs for a 32-bit configuration,
+ second one for a 16-bit configuration).
+ This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
+
+ uint32_t FilterFIFOAssignment; /*!< Specifies the FIFO (0 or 1) which will be assigned to the filter.
+ This parameter can be a value of @ref CAN_filter_FIFO */
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ uint32_t FilterNumber; /*!< Specifies the filter which will be initialized.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 27. */
+#else
+ uint32_t FilterNumber; /*!< Specifies the filter which will be initialized.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 13. */
+#endif /* STM32F105xC || STM32F107xC */
+ uint32_t FilterMode; /*!< Specifies the filter mode to be initialized.
+ This parameter can be a value of @ref CAN_filter_mode */
+
+ uint32_t FilterScale; /*!< Specifies the filter scale.
+ This parameter can be a value of @ref CAN_filter_scale */
+
+ uint32_t FilterActivation; /*!< Enable or disable the filter.
+ This parameter can be set to ENABLE or DISABLE. */
+
+ uint32_t BankNumber; /*!< Select the start slave bank filter
+ This parameter must be a number between Min_Data = 0 and Max_Data = 28. */
+
+}CAN_FilterConfTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+
+/** @defgroup CANEx_Private_Macros CAN Extended Private Macros
+ * @{
+ */
+#if defined(STM32F105xC) || defined(STM32F107xC)
+#define IS_CAN_FILTER_NUMBER(NUMBER) ((NUMBER) <= 27U)
+#else
+#define IS_CAN_FILTER_NUMBER(NUMBER) ((NUMBER) <= 13U)
+#endif /* STM32F105xC || STM32F107xC */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F103x6) || STM32F103xB || STM32F103xE || STM32F103xG) || STM32F105xC || STM32F107xC */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_CAN_EX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32f1xx_hal_can_legacy.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32f1xx_hal_can_legacy.h
new file mode 100644
index 0000000..6af75e0
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32f1xx_hal_can_legacy.h
@@ -0,0 +1,796 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_can.h
+ * @author MCD Application Team
+ * @brief Header file of CAN HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_CAN_H
+#define __STM32F1xx_HAL_CAN_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#if defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || \
+ defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup CAN
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup CAN_Exported_Types CAN Exported Types
+ * @{
+ */
+
+/**
+ * @brief HAL State structures definition
+ */
+typedef enum
+{
+ HAL_CAN_STATE_RESET = 0x00U, /*!< CAN not yet initialized or disabled */
+ HAL_CAN_STATE_READY = 0x01U, /*!< CAN initialized and ready for use */
+ HAL_CAN_STATE_BUSY = 0x02U, /*!< CAN process is ongoing */
+ HAL_CAN_STATE_BUSY_TX = 0x12U, /*!< CAN process is ongoing */
+ HAL_CAN_STATE_BUSY_RX0 = 0x22U, /*!< CAN process is ongoing */
+ HAL_CAN_STATE_BUSY_RX1 = 0x32U, /*!< CAN process is ongoing */
+ HAL_CAN_STATE_BUSY_TX_RX0 = 0x42U, /*!< CAN process is ongoing */
+ HAL_CAN_STATE_BUSY_TX_RX1 = 0x52U, /*!< CAN process is ongoing */
+ HAL_CAN_STATE_BUSY_RX0_RX1 = 0x62U, /*!< CAN process is ongoing */
+ HAL_CAN_STATE_BUSY_TX_RX0_RX1 = 0x72U, /*!< CAN process is ongoing */
+ HAL_CAN_STATE_TIMEOUT = 0x03U, /*!< CAN in Timeout state */
+ HAL_CAN_STATE_ERROR = 0x04U /*!< CAN error state */
+
+}HAL_CAN_StateTypeDef;
+
+/**
+ * @brief CAN init structure definition
+ */
+typedef struct
+{
+ uint32_t Prescaler; /*!< Specifies the length of a time quantum.
+ This parameter must be a number between Min_Data = 1 and Max_Data = 1024 */
+
+ uint32_t Mode; /*!< Specifies the CAN operating mode.
+ This parameter can be a value of @ref CAN_operating_mode */
+
+ uint32_t SJW; /*!< Specifies the maximum number of time quanta
+ the CAN hardware is allowed to lengthen or
+ shorten a bit to perform resynchronization.
+ This parameter can be a value of @ref CAN_synchronisation_jump_width */
+
+ uint32_t BS1; /*!< Specifies the number of time quanta in Bit Segment 1.
+ This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_1 */
+
+ uint32_t BS2; /*!< Specifies the number of time quanta in Bit Segment 2.
+ This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_2 */
+
+ uint32_t TTCM; /*!< Enable or disable the time triggered communication mode.
+ This parameter can be set to ENABLE or DISABLE. */
+
+ uint32_t ABOM; /*!< Enable or disable the automatic bus-off management.
+ This parameter can be set to ENABLE or DISABLE */
+
+ uint32_t AWUM; /*!< Enable or disable the automatic wake-up mode.
+ This parameter can be set to ENABLE or DISABLE */
+
+ uint32_t NART; /*!< Enable or disable the non-automatic retransmission mode.
+ This parameter can be set to ENABLE or DISABLE */
+
+ uint32_t RFLM; /*!< Enable or disable the receive FIFO Locked mode.
+ This parameter can be set to ENABLE or DISABLE */
+
+ uint32_t TXFP; /*!< Enable or disable the transmit FIFO priority.
+ This parameter can be set to ENABLE or DISABLE */
+}CAN_InitTypeDef;
+
+/**
+ * @brief CAN Tx message structure definition
+ */
+typedef struct
+{
+ uint32_t StdId; /*!< Specifies the standard identifier.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF */
+
+ uint32_t ExtId; /*!< Specifies the extended identifier.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF */
+
+ uint32_t IDE; /*!< Specifies the type of identifier for the message that will be transmitted.
+ This parameter can be a value of @ref CAN_Identifier_Type */
+
+ uint32_t RTR; /*!< Specifies the type of frame for the message that will be transmitted.
+ This parameter can be a value of @ref CAN_remote_transmission_request */
+
+ uint32_t DLC; /*!< Specifies the length of the frame that will be transmitted.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 8 */
+
+ uint8_t Data[8]; /*!< Contains the data to be transmitted.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF */
+
+}CanTxMsgTypeDef;
+
+/**
+ * @brief CAN Rx message structure definition
+ */
+typedef struct
+{
+ uint32_t StdId; /*!< Specifies the standard identifier.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF */
+
+ uint32_t ExtId; /*!< Specifies the extended identifier.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF */
+
+ uint32_t IDE; /*!< Specifies the type of identifier for the message that will be received.
+ This parameter can be a value of @ref CAN_Identifier_Type */
+
+ uint32_t RTR; /*!< Specifies the type of frame for the received message.
+ This parameter can be a value of @ref CAN_remote_transmission_request */
+
+ uint32_t DLC; /*!< Specifies the length of the frame that will be received.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 8 */
+
+ uint8_t Data[8]; /*!< Contains the data to be received.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF */
+
+ uint32_t FMI; /*!< Specifies the index of the filter the message stored in the mailbox passes through.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF */
+
+ uint32_t FIFONumber; /*!< Specifies the receive FIFO number.
+ This parameter can be CAN_FIFO0 or CAN_FIFO1 */
+
+}CanRxMsgTypeDef;
+
+/**
+ * @brief CAN handle Structure definition
+ */
+typedef struct
+{
+ CAN_TypeDef *Instance; /*!< Register base address */
+
+ CAN_InitTypeDef Init; /*!< CAN required parameters */
+
+ CanTxMsgTypeDef* pTxMsg; /*!< Pointer to transmit structure */
+
+ CanRxMsgTypeDef* pRxMsg; /*!< Pointer to reception structure for RX FIFO0 msg */
+
+ CanRxMsgTypeDef* pRx1Msg; /*!< Pointer to reception structure for RX FIFO1 msg */
+
+ __IO HAL_CAN_StateTypeDef State; /*!< CAN communication state */
+
+ HAL_LockTypeDef Lock; /*!< CAN locking object */
+
+ __IO uint32_t ErrorCode; /*!< CAN Error code */
+
+}CAN_HandleTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup CAN_Exported_Constants CAN Exported Constants
+ * @{
+ */
+
+/** @defgroup CAN_Error_Code CAN Error Code
+ * @{
+ */
+#define HAL_CAN_ERROR_NONE 0x00000000U /*!< No error */
+#define HAL_CAN_ERROR_EWG 0x00000001U /*!< EWG error */
+#define HAL_CAN_ERROR_EPV 0x00000002U /*!< EPV error */
+#define HAL_CAN_ERROR_BOF 0x00000004U /*!< BOF error */
+#define HAL_CAN_ERROR_STF 0x00000008U /*!< Stuff error */
+#define HAL_CAN_ERROR_FOR 0x00000010U /*!< Form error */
+#define HAL_CAN_ERROR_ACK 0x00000020U /*!< Acknowledgment error */
+#define HAL_CAN_ERROR_BR 0x00000040U /*!< Bit recessive */
+#define HAL_CAN_ERROR_BD 0x00000080U /*!< LEC dominant */
+#define HAL_CAN_ERROR_CRC 0x00000100U /*!< LEC transfer error */
+#define HAL_CAN_ERROR_FOV0 0x00000200U /*!< FIFO0 overrun error */
+#define HAL_CAN_ERROR_FOV1 0x00000400U /*!< FIFO1 overrun error */
+#define HAL_CAN_ERROR_TXFAIL 0x00000800U /*!< Transmit failure */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_InitStatus CAN initialization Status
+ * @{
+ */
+#define CAN_INITSTATUS_FAILED 0x00000000U /*!< CAN initialization failed */
+#define CAN_INITSTATUS_SUCCESS 0x00000001U /*!< CAN initialization OK */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_operating_mode CAN Operating Mode
+ * @{
+ */
+#define CAN_MODE_NORMAL 0x00000000U /*!< Normal mode */
+#define CAN_MODE_LOOPBACK ((uint32_t)CAN_BTR_LBKM) /*!< Loopback mode */
+#define CAN_MODE_SILENT ((uint32_t)CAN_BTR_SILM) /*!< Silent mode */
+#define CAN_MODE_SILENT_LOOPBACK ((uint32_t)(CAN_BTR_LBKM | CAN_BTR_SILM)) /*!< Loopback combined with silent mode */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_synchronisation_jump_width CAN Synchronization Jump Width
+ * @{
+ */
+#define CAN_SJW_1TQ 0x00000000U /*!< 1 time quantum */
+#define CAN_SJW_2TQ ((uint32_t)CAN_BTR_SJW_0) /*!< 2 time quantum */
+#define CAN_SJW_3TQ ((uint32_t)CAN_BTR_SJW_1) /*!< 3 time quantum */
+#define CAN_SJW_4TQ ((uint32_t)CAN_BTR_SJW) /*!< 4 time quantum */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_time_quantum_in_bit_segment_1 CAN Time Quantum in Bit Segment 1
+ * @{
+ */
+#define CAN_BS1_1TQ 0x00000000U /*!< 1 time quantum */
+#define CAN_BS1_2TQ ((uint32_t)CAN_BTR_TS1_0) /*!< 2 time quantum */
+#define CAN_BS1_3TQ ((uint32_t)CAN_BTR_TS1_1) /*!< 3 time quantum */
+#define CAN_BS1_4TQ ((uint32_t)(CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 4 time quantum */
+#define CAN_BS1_5TQ ((uint32_t)CAN_BTR_TS1_2) /*!< 5 time quantum */
+#define CAN_BS1_6TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_0)) /*!< 6 time quantum */
+#define CAN_BS1_7TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_1)) /*!< 7 time quantum */
+#define CAN_BS1_8TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 8 time quantum */
+#define CAN_BS1_9TQ ((uint32_t)CAN_BTR_TS1_3) /*!< 9 time quantum */
+#define CAN_BS1_10TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_0)) /*!< 10 time quantum */
+#define CAN_BS1_11TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_1)) /*!< 11 time quantum */
+#define CAN_BS1_12TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 12 time quantum */
+#define CAN_BS1_13TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2)) /*!< 13 time quantum */
+#define CAN_BS1_14TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2 | CAN_BTR_TS1_0)) /*!< 14 time quantum */
+#define CAN_BS1_15TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2 | CAN_BTR_TS1_1)) /*!< 15 time quantum */
+#define CAN_BS1_16TQ ((uint32_t)CAN_BTR_TS1) /*!< 16 time quantum */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_time_quantum_in_bit_segment_2 CAN Time Quantum in bit segment 2
+ * @{
+ */
+#define CAN_BS2_1TQ 0x00000000U /*!< 1 time quantum */
+#define CAN_BS2_2TQ ((uint32_t)CAN_BTR_TS2_0) /*!< 2 time quantum */
+#define CAN_BS2_3TQ ((uint32_t)CAN_BTR_TS2_1) /*!< 3 time quantum */
+#define CAN_BS2_4TQ ((uint32_t)(CAN_BTR_TS2_1 | CAN_BTR_TS2_0)) /*!< 4 time quantum */
+#define CAN_BS2_5TQ ((uint32_t)CAN_BTR_TS2_2) /*!< 5 time quantum */
+#define CAN_BS2_6TQ ((uint32_t)(CAN_BTR_TS2_2 | CAN_BTR_TS2_0)) /*!< 6 time quantum */
+#define CAN_BS2_7TQ ((uint32_t)(CAN_BTR_TS2_2 | CAN_BTR_TS2_1)) /*!< 7 time quantum */
+#define CAN_BS2_8TQ ((uint32_t)CAN_BTR_TS2) /*!< 8 time quantum */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_filter_mode CAN Filter Mode
+ * @{
+ */
+#define CAN_FILTERMODE_IDMASK ((uint8_t)0x00) /*!< Identifier mask mode */
+#define CAN_FILTERMODE_IDLIST ((uint8_t)0x01) /*!< Identifier list mode */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_filter_scale CAN Filter Scale
+ * @{
+ */
+#define CAN_FILTERSCALE_16BIT ((uint8_t)0x00) /*!< Two 16-bit filters */
+#define CAN_FILTERSCALE_32BIT ((uint8_t)0x01) /*!< One 32-bit filter */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_filter_FIFO CAN Filter FIFO
+ * @{
+ */
+#define CAN_FILTER_FIFO0 ((uint8_t)0x00) /*!< Filter FIFO 0 assignment for filter x */
+#define CAN_FILTER_FIFO1 ((uint8_t)0x01) /*!< Filter FIFO 1 assignment for filter x */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_Identifier_Type CAN Identifier Type
+ * @{
+ */
+#define CAN_ID_STD 0x00000000U /*!< Standard Id */
+#define CAN_ID_EXT 0x00000004U /*!< Extended Id */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_remote_transmission_request CAN Remote Transmission Request
+ * @{
+ */
+#define CAN_RTR_DATA 0x00000000U /*!< Data frame */
+#define CAN_RTR_REMOTE 0x00000002U /*!< Remote frame */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_transmit_constants CAN Transmit Constants
+ * @{
+ */
+#define CAN_TXSTATUS_NOMAILBOX ((uint8_t)0x04) /*!< CAN cell did not provide CAN_TxStatus_NoMailBox */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_receive_FIFO_number_constants CAN Receive FIFO Number
+ * @{
+ */
+#define CAN_FIFO0 ((uint8_t)0x00) /*!< CAN FIFO 0 used to receive */
+#define CAN_FIFO1 ((uint8_t)0x01) /*!< CAN FIFO 1 used to receive */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_flags CAN Flags
+ * @{
+ */
+/* If the flag is 0x3XXXXXXX, it means that it can be used with CAN_GetFlagStatus()
+ and CAN_ClearFlag() functions. */
+/* If the flag is 0x1XXXXXXX, it means that it can only be used with
+ CAN_GetFlagStatus() function. */
+
+/* Transmit Flags */
+#define CAN_FLAG_RQCP0 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_RQCP0_BIT_POSITION)) /*!< Request MailBox0 flag */
+#define CAN_FLAG_RQCP1 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_RQCP1_BIT_POSITION)) /*!< Request MailBox1 flag */
+#define CAN_FLAG_RQCP2 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_RQCP2_BIT_POSITION)) /*!< Request MailBox2 flag */
+#define CAN_FLAG_TXOK0 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_TXOK0_BIT_POSITION)) /*!< Transmission OK MailBox0 flag */
+#define CAN_FLAG_TXOK1 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_TXOK1_BIT_POSITION)) /*!< Transmission OK MailBox1 flag */
+#define CAN_FLAG_TXOK2 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_TXOK2_BIT_POSITION)) /*!< Transmission OK MailBox2 flag */
+#define CAN_FLAG_TME0 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_TME0_BIT_POSITION)) /*!< Transmit mailbox 0 empty flag */
+#define CAN_FLAG_TME1 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_TME1_BIT_POSITION)) /*!< Transmit mailbox 0 empty flag */
+#define CAN_FLAG_TME2 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_TME2_BIT_POSITION)) /*!< Transmit mailbox 0 empty flag */
+
+/* Receive Flags */
+#define CAN_FLAG_FF0 ((uint32_t)((RF0R_REGISTER_INDEX << 8U) | CAN_RF0R_FF0_BIT_POSITION)) /*!< FIFO 0 Full flag */
+#define CAN_FLAG_FOV0 ((uint32_t)((RF0R_REGISTER_INDEX << 8U) | CAN_RF0R_FOV0_BIT_POSITION)) /*!< FIFO 0 Overrun flag */
+
+#define CAN_FLAG_FF1 ((uint32_t)((RF1R_REGISTER_INDEX << 8U) | CAN_RF1R_FF1_BIT_POSITION)) /*!< FIFO 1 Full flag */
+#define CAN_FLAG_FOV1 ((uint32_t)((RF1R_REGISTER_INDEX << 8U) | CAN_RF1R_FOV1_BIT_POSITION)) /*!< FIFO 1 Overrun flag */
+
+/* Operating Mode Flags */
+#define CAN_FLAG_WKU ((uint32_t)((MSR_REGISTER_INDEX << 8U) | CAN_MSR_WKU_BIT_POSITION)) /*!< Wake up flag */
+#define CAN_FLAG_SLAK ((uint32_t)((MSR_REGISTER_INDEX << 8U) | CAN_MSR_SLAK_BIT_POSITION)) /*!< Sleep acknowledge flag */
+#define CAN_FLAG_SLAKI ((uint32_t)((MSR_REGISTER_INDEX << 8U) | CAN_MSR_SLAKI_BIT_POSITION)) /*!< Sleep acknowledge flag */
+
+/* @note When SLAK interrupt is disabled (SLKIE=0), no polling on SLAKI is possible.
+ In this case the SLAK bit can be polled.*/
+
+/* Error Flags */
+#define CAN_FLAG_EWG ((uint32_t)((ESR_REGISTER_INDEX << 8U) | CAN_ESR_EWG_BIT_POSITION)) /*!< Error warning flag */
+#define CAN_FLAG_EPV ((uint32_t)((ESR_REGISTER_INDEX << 8U) | CAN_ESR_EPV_BIT_POSITION)) /*!< Error passive flag */
+#define CAN_FLAG_BOF ((uint32_t)((ESR_REGISTER_INDEX << 8U) | CAN_ESR_BOF_BIT_POSITION)) /*!< Bus-Off flag */
+
+/**
+ * @}
+ */
+
+/** @defgroup CAN_Interrupts CAN Interrupts
+ * @{
+ */
+#define CAN_IT_TME ((uint32_t)CAN_IER_TMEIE) /*!< Transmit mailbox empty interrupt */
+
+/* Receive Interrupts */
+#define CAN_IT_FMP0 ((uint32_t)CAN_IER_FMPIE0) /*!< FIFO 0 message pending interrupt */
+#define CAN_IT_FF0 ((uint32_t)CAN_IER_FFIE0) /*!< FIFO 0 full interrupt */
+#define CAN_IT_FOV0 ((uint32_t)CAN_IER_FOVIE0) /*!< FIFO 0 overrun interrupt */
+#define CAN_IT_FMP1 ((uint32_t)CAN_IER_FMPIE1) /*!< FIFO 1 message pending interrupt */
+#define CAN_IT_FF1 ((uint32_t)CAN_IER_FFIE1) /*!< FIFO 1 full interrupt */
+#define CAN_IT_FOV1 ((uint32_t)CAN_IER_FOVIE1) /*!< FIFO 1 overrun interrupt */
+
+/* Operating Mode Interrupts */
+#define CAN_IT_WKU ((uint32_t)CAN_IER_WKUIE) /*!< Wake-up interrupt */
+#define CAN_IT_SLK ((uint32_t)CAN_IER_SLKIE) /*!< Sleep acknowledge interrupt */
+
+/* Error Interrupts */
+#define CAN_IT_EWG ((uint32_t)CAN_IER_EWGIE) /*!< Error warning interrupt */
+#define CAN_IT_EPV ((uint32_t)CAN_IER_EPVIE) /*!< Error passive interrupt */
+#define CAN_IT_BOF ((uint32_t)CAN_IER_BOFIE) /*!< Bus-off interrupt */
+#define CAN_IT_LEC ((uint32_t)CAN_IER_LECIE) /*!< Last error code interrupt */
+#define CAN_IT_ERR ((uint32_t)CAN_IER_ERRIE) /*!< Error Interrupt */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup CAN_Private_Constants CAN Private Constants
+ * @{
+ */
+
+/* CAN intermediate shift values used for CAN flags */
+#define TSR_REGISTER_INDEX 0x5U
+#define RF0R_REGISTER_INDEX 0x2U
+#define RF1R_REGISTER_INDEX 0x4U
+#define MSR_REGISTER_INDEX 0x1U
+#define ESR_REGISTER_INDEX 0x3U
+
+/* CAN flags bits position into their respective register (TSR, RF0R, RF1R or MSR regsiters) */
+/* Transmit Flags */
+#define CAN_TSR_RQCP0_BIT_POSITION 0x00000000U
+#define CAN_TSR_RQCP1_BIT_POSITION 0x00000008U
+#define CAN_TSR_RQCP2_BIT_POSITION 0x00000010U
+#define CAN_TSR_TXOK0_BIT_POSITION 0x00000001U
+#define CAN_TSR_TXOK1_BIT_POSITION 0x00000009U
+#define CAN_TSR_TXOK2_BIT_POSITION 0x00000011U
+#define CAN_TSR_TME0_BIT_POSITION 0x0000001AU
+#define CAN_TSR_TME1_BIT_POSITION 0x0000001BU
+#define CAN_TSR_TME2_BIT_POSITION 0x0000001CU
+
+/* Receive Flags */
+#define CAN_RF0R_FF0_BIT_POSITION 0x00000003U
+#define CAN_RF0R_FOV0_BIT_POSITION 0x00000004U
+
+#define CAN_RF1R_FF1_BIT_POSITION 0x00000003U
+#define CAN_RF1R_FOV1_BIT_POSITION 0x00000004U
+
+/* Operating Mode Flags */
+#define CAN_MSR_WKU_BIT_POSITION 0x00000003U
+#define CAN_MSR_SLAK_BIT_POSITION 0x00000001U
+#define CAN_MSR_SLAKI_BIT_POSITION 0x00000004U
+
+/* Error Flags */
+#define CAN_ESR_EWG_BIT_POSITION 0x00000000U
+#define CAN_ESR_EPV_BIT_POSITION 0x00000001U
+#define CAN_ESR_BOF_BIT_POSITION 0x00000002U
+
+/* Mask used by macro to get/clear CAN flags*/
+#define CAN_FLAG_MASK 0x000000FFU
+
+/* Mailboxes definition */
+#define CAN_TXMAILBOX_0 ((uint8_t)0x00)
+#define CAN_TXMAILBOX_1 ((uint8_t)0x01)
+#define CAN_TXMAILBOX_2 ((uint8_t)0x02)
+/**
+ * @}
+ */
+
+/* Exported macros -----------------------------------------------------------*/
+/** @defgroup CAN_Exported_Macros CAN Exported Macros
+ * @{
+ */
+
+/** @brief Reset CAN handle state
+ * @param __HANDLE__: CAN handle.
+ * @retval None
+ */
+#define __HAL_CAN_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_CAN_STATE_RESET)
+
+/**
+ * @brief Enable the specified CAN interrupts
+ * @param __HANDLE__: CAN handle.
+ * @param __INTERRUPT__: CAN Interrupt.
+ * This parameter can be one of the following values:
+ * @arg CAN_IT_TME: Transmit mailbox empty interrupt enable
+ * @arg CAN_IT_FMP0: FIFO 0 message pending interrupt
+ * @arg CAN_IT_FF0 : FIFO 0 full interrupt
+ * @arg CAN_IT_FOV0: FIFO 0 overrun interrupt
+ * @arg CAN_IT_FMP1: FIFO 1 message pending interrupt
+ * @arg CAN_IT_FF1 : FIFO 1 full interrupt
+ * @arg CAN_IT_FOV1: FIFO 1 overrun interrupt
+ * @arg CAN_IT_WKU : Wake-up interrupt
+ * @arg CAN_IT_SLK : Sleep acknowledge interrupt
+ * @arg CAN_IT_EWG : Error warning interrupt
+ * @arg CAN_IT_EPV : Error passive interrupt
+ * @arg CAN_IT_BOF : Bus-off interrupt
+ * @arg CAN_IT_LEC : Last error code interrupt
+ * @arg CAN_IT_ERR : Error Interrupt
+ * @retval None.
+ */
+#define __HAL_CAN_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) |= (__INTERRUPT__))
+
+/**
+ * @brief Disable the specified CAN interrupts
+ * @param __HANDLE__: CAN handle.
+ * @param __INTERRUPT__: CAN Interrupt.
+ * This parameter can be one of the following values:
+ * @arg CAN_IT_TME: Transmit mailbox empty interrupt enable
+ * @arg CAN_IT_FMP0: FIFO 0 message pending interrupt
+ * @arg CAN_IT_FF0 : FIFO 0 full interrupt
+ * @arg CAN_IT_FOV0: FIFO 0 overrun interrupt
+ * @arg CAN_IT_FMP1: FIFO 1 message pending interrupt
+ * @arg CAN_IT_FF1 : FIFO 1 full interrupt
+ * @arg CAN_IT_FOV1: FIFO 1 overrun interrupt
+ * @arg CAN_IT_WKU : Wake-up interrupt
+ * @arg CAN_IT_SLK : Sleep acknowledge interrupt
+ * @arg CAN_IT_EWG : Error warning interrupt
+ * @arg CAN_IT_EPV : Error passive interrupt
+ * @arg CAN_IT_BOF : Bus-off interrupt
+ * @arg CAN_IT_LEC : Last error code interrupt
+ * @arg CAN_IT_ERR : Error Interrupt
+ * @retval None.
+ */
+#define __HAL_CAN_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) &= ~(__INTERRUPT__))
+
+/**
+ * @brief Return the number of pending received messages.
+ * @param __HANDLE__: CAN handle.
+ * @param __FIFONUMBER__: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.
+ * @retval The number of pending message.
+ */
+#define __HAL_CAN_MSG_PENDING(__HANDLE__, __FIFONUMBER__) (((__FIFONUMBER__) == CAN_FIFO0)? \
+((uint8_t)((__HANDLE__)->Instance->RF0R & 0x03U)) : ((uint8_t)((__HANDLE__)->Instance->RF1R & 0x03U)))
+
+/** @brief Check whether the specified CAN flag is set or not.
+ * @param __HANDLE__: specifies the CAN Handle.
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg CAN_TSR_RQCP0: Request MailBox0 Flag
+ * @arg CAN_TSR_RQCP1: Request MailBox1 Flag
+ * @arg CAN_TSR_RQCP2: Request MailBox2 Flag
+ * @arg CAN_FLAG_TXOK0: Transmission OK MailBox0 Flag
+ * @arg CAN_FLAG_TXOK1: Transmission OK MailBox1 Flag
+ * @arg CAN_FLAG_TXOK2: Transmission OK MailBox2 Flag
+ * @arg CAN_FLAG_TME0: Transmit mailbox 0 empty Flag
+ * @arg CAN_FLAG_TME1: Transmit mailbox 1 empty Flag
+ * @arg CAN_FLAG_TME2: Transmit mailbox 2 empty Flag
+ * @arg CAN_FLAG_FMP0: FIFO 0 Message Pending Flag
+ * @arg CAN_FLAG_FF0: FIFO 0 Full Flag
+ * @arg CAN_FLAG_FOV0: FIFO 0 Overrun Flag
+ * @arg CAN_FLAG_FMP1: FIFO 1 Message Pending Flag
+ * @arg CAN_FLAG_FF1: FIFO 1 Full Flag
+ * @arg CAN_FLAG_FOV1: FIFO 1 Overrun Flag
+ * @arg CAN_FLAG_WKU: Wake up Flag
+ * @arg CAN_FLAG_SLAK: Sleep acknowledge Flag
+ * @arg CAN_FLAG_SLAKI: Sleep acknowledge Flag
+ * @arg CAN_FLAG_EWG: Error Warning Flag
+ * @arg CAN_FLAG_EPV: Error Passive Flag
+ * @arg CAN_FLAG_BOF: Bus-Off Flag
+ * @retval The new state of __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_CAN_GET_FLAG(__HANDLE__, __FLAG__) \
+((((__FLAG__) >> 8U) == 5U)? ((((__HANDLE__)->Instance->TSR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
+ (((__FLAG__) >> 8U) == 2U)? ((((__HANDLE__)->Instance->RF0R) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
+ (((__FLAG__) >> 8U) == 4U)? ((((__HANDLE__)->Instance->RF1R) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
+ (((__FLAG__) >> 8U) == 1U)? ((((__HANDLE__)->Instance->MSR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
+ ((((__HANDLE__)->Instance->ESR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))))
+
+/** @brief Clear the specified CAN pending flag.
+ * @param __HANDLE__: specifies the CAN Handle.
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg CAN_TSR_RQCP0: Request MailBox0 Flag
+ * @arg CAN_TSR_RQCP1: Request MailBox1 Flag
+ * @arg CAN_TSR_RQCP2: Request MailBox2 Flag
+ * @arg CAN_FLAG_TXOK0: Transmission OK MailBox0 Flag
+ * @arg CAN_FLAG_TXOK1: Transmission OK MailBox1 Flag
+ * @arg CAN_FLAG_TXOK2: Transmission OK MailBox2 Flag
+ * @arg CAN_FLAG_TME0: Transmit mailbox 0 empty Flag
+ * @arg CAN_FLAG_TME1: Transmit mailbox 1 empty Flag
+ * @arg CAN_FLAG_TME2: Transmit mailbox 2 empty Flag
+ * @arg CAN_FLAG_FMP0: FIFO 0 Message Pending Flag
+ * @arg CAN_FLAG_FF0: FIFO 0 Full Flag
+ * @arg CAN_FLAG_FOV0: FIFO 0 Overrun Flag
+ * @arg CAN_FLAG_FMP1: FIFO 1 Message Pending Flag
+ * @arg CAN_FLAG_FF1: FIFO 1 Full Flag
+ * @arg CAN_FLAG_FOV1: FIFO 1 Overrun Flag
+ * @arg CAN_FLAG_WKU: Wake up Flag
+ * @arg CAN_FLAG_SLAKI: Sleep acknowledge Flag
+ * @retval The new state of __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_CAN_CLEAR_FLAG(__HANDLE__, __FLAG__) \
+((((__FLAG__) >> 8U) == TSR_REGISTER_INDEX) ? (((__HANDLE__)->Instance->TSR) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
+ (((__FLAG__) >> 8U) == RF0R_REGISTER_INDEX)? (((__HANDLE__)->Instance->RF0R) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
+ (((__FLAG__) >> 8U) == RF1R_REGISTER_INDEX)? (((__HANDLE__)->Instance->RF1R) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
+ (((__FLAG__) >> 8U) == MSR_REGISTER_INDEX) ? (((__HANDLE__)->Instance->MSR) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): 0U)
+
+/** @brief Check if the specified CAN interrupt source is enabled or disabled.
+ * @param __HANDLE__: specifies the CAN Handle.
+ * @param __INTERRUPT__: specifies the CAN interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg CAN_IT_TME: Transmit mailbox empty interrupt enable
+ * @arg CAN_IT_FMP0: FIFO 0 message pending interrupt
+ * @arg CAN_IT_FF0 : FIFO 0 full interrupt
+ * @arg CAN_IT_FOV0: FIFO 0 overrun interrupt
+ * @arg CAN_IT_FMP1: FIFO 1 message pending interrupt
+ * @arg CAN_IT_FF1 : FIFO 1 full interrupt
+ * @arg CAN_IT_FOV1: FIFO 1 overrun interrupt
+ * @arg CAN_IT_WKU : Wake-up interrupt
+ * @arg CAN_IT_SLK : Sleep acknowledge interrupt
+ * @arg CAN_IT_EWG : Error warning interrupt
+ * @arg CAN_IT_EPV : Error passive interrupt
+ * @arg CAN_IT_BOF : Bus-off interrupt
+ * @arg CAN_IT_LEC : Last error code interrupt
+ * @arg CAN_IT_ERR : Error Interrupt
+ * @retval The new state of __IT__ (TRUE or FALSE).
+ */
+#define __HAL_CAN_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->IER & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
+
+/**
+ * @brief Check the transmission status of a CAN Frame.
+ * @param __HANDLE__: specifies the CAN Handle.
+ * @param __TRANSMITMAILBOX__: the number of the mailbox that is used for transmission.
+ * @retval The new status of transmission (TRUE or FALSE).
+ */
+#define __HAL_CAN_TRANSMIT_STATUS(__HANDLE__, __TRANSMITMAILBOX__)\
+(((__TRANSMITMAILBOX__) == CAN_TXMAILBOX_0)? ((((__HANDLE__)->Instance->TSR) & (CAN_TSR_RQCP0 | CAN_TSR_TME0)) == (CAN_TSR_RQCP0 | CAN_TSR_TME0)) :\
+ ((__TRANSMITMAILBOX__) == CAN_TXMAILBOX_1)? ((((__HANDLE__)->Instance->TSR) & (CAN_TSR_RQCP1 | CAN_TSR_TME1)) == (CAN_TSR_RQCP1 | CAN_TSR_TME1)) :\
+ ((((__HANDLE__)->Instance->TSR) & (CAN_TSR_RQCP2 | CAN_TSR_TME2)) == (CAN_TSR_RQCP2 | CAN_TSR_TME2)))
+
+/**
+ * @brief Release the specified receive FIFO.
+ * @param __HANDLE__: CAN handle.
+ * @param __FIFONUMBER__: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.
+ * @retval None.
+ */
+#define __HAL_CAN_FIFO_RELEASE(__HANDLE__, __FIFONUMBER__) (((__FIFONUMBER__) == CAN_FIFO0)? \
+((__HANDLE__)->Instance->RF0R = CAN_RF0R_RFOM0) : ((__HANDLE__)->Instance->RF1R = CAN_RF1R_RFOM1))
+
+/**
+ * @brief Cancel a transmit request.
+ * @param __HANDLE__: specifies the CAN Handle.
+ * @param __TRANSMITMAILBOX__: the number of the mailbox that is used for transmission.
+ * @retval None.
+ */
+#define __HAL_CAN_CANCEL_TRANSMIT(__HANDLE__, __TRANSMITMAILBOX__)\
+(((__TRANSMITMAILBOX__) == CAN_TXMAILBOX_0)? ((__HANDLE__)->Instance->TSR = CAN_TSR_ABRQ0) :\
+ ((__TRANSMITMAILBOX__) == CAN_TXMAILBOX_1)? ((__HANDLE__)->Instance->TSR = CAN_TSR_ABRQ1) :\
+ ((__HANDLE__)->Instance->TSR = CAN_TSR_ABRQ2))
+
+/**
+ * @brief Enable or disables the DBG Freeze for CAN.
+ * @param __HANDLE__: specifies the CAN Handle.
+ * @param __NEWSTATE__: new state of the CAN peripheral.
+ * This parameter can be: ENABLE (CAN reception/transmission is frozen
+ * during debug. Reception FIFOs can still be accessed/controlled normally)
+ * or DISABLE (CAN is working during debug).
+ * @retval None
+ */
+#define __HAL_CAN_DBG_FREEZE(__HANDLE__, __NEWSTATE__) (((__NEWSTATE__) == ENABLE)? \
+((__HANDLE__)->Instance->MCR |= CAN_MCR_DBF) : ((__HANDLE__)->Instance->MCR &= ~CAN_MCR_DBF))
+
+/**
+ * @}
+ */
+
+/* Include CAN HAL Extension module */
+#include "stm32f1xx_hal_can_ex_legacy.h"
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup CAN_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup CAN_Exported_Functions_Group1
+ * @brief Initialization and Configuration functions
+ * @{
+ */
+/* Initialization and de-initialization functions *****************************/
+HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan);
+HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig);
+HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan);
+void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan);
+void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan);
+/**
+ * @}
+ */
+
+/** @addtogroup CAN_Exported_Functions_Group2
+ * @brief I/O operation functions
+ * @{
+ */
+/* I/O operation functions *****************************************************/
+HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef *hcan, uint32_t Timeout);
+HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef *hcan);
+HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef *hcan, uint8_t FIFONumber, uint32_t Timeout);
+HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef *hcan, uint8_t FIFONumber);
+HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef *hcan);
+HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef *hcan);
+void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan);
+void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan);
+void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan);
+void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan);
+/**
+ * @}
+ */
+
+/** @addtogroup CAN_Exported_Functions_Group3
+ * @brief CAN Peripheral State functions
+ * @{
+ */
+/* Peripheral State and Error functions ***************************************/
+uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan);
+HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private macros --------------------------------------------------------*/
+/** @defgroup CAN_Private_Macros CAN Private Macros
+ * @{
+ */
+
+#define IS_CAN_MODE(MODE) (((MODE) == CAN_MODE_NORMAL) || \
+ ((MODE) == CAN_MODE_LOOPBACK)|| \
+ ((MODE) == CAN_MODE_SILENT) || \
+ ((MODE) == CAN_MODE_SILENT_LOOPBACK))
+#define IS_CAN_SJW(SJW) (((SJW) == CAN_SJW_1TQ) || ((SJW) == CAN_SJW_2TQ)|| \
+ ((SJW) == CAN_SJW_3TQ) || ((SJW) == CAN_SJW_4TQ))
+#define IS_CAN_BS1(BS1) ((BS1) <= CAN_BS1_16TQ)
+#define IS_CAN_BS2(BS2) ((BS2) <= CAN_BS2_8TQ)
+#define IS_CAN_PRESCALER(PRESCALER) (((PRESCALER) >= 1U) && ((PRESCALER) <= 1024U))
+
+#define IS_CAN_FILTER_MODE(MODE) (((MODE) == CAN_FILTERMODE_IDMASK) || \
+ ((MODE) == CAN_FILTERMODE_IDLIST))
+#define IS_CAN_FILTER_SCALE(SCALE) (((SCALE) == CAN_FILTERSCALE_16BIT) || \
+ ((SCALE) == CAN_FILTERSCALE_32BIT))
+#define IS_CAN_FILTER_FIFO(FIFO) (((FIFO) == CAN_FILTER_FIFO0) || \
+ ((FIFO) == CAN_FILTER_FIFO1))
+#define IS_CAN_BANKNUMBER(BANKNUMBER) ((BANKNUMBER) <= 28U)
+
+#define IS_CAN_TRANSMITMAILBOX(TRANSMITMAILBOX) ((TRANSMITMAILBOX) <= ((uint8_t)0x02))
+#define IS_CAN_STDID(STDID) ((STDID) <= 0x00007FFU)
+#define IS_CAN_EXTID(EXTID) ((EXTID) <= 0x1FFFFFFFU)
+#define IS_CAN_DLC(DLC) ((DLC) <= ((uint8_t)0x08))
+
+#define IS_CAN_IDTYPE(IDTYPE) (((IDTYPE) == CAN_ID_STD) || \
+ ((IDTYPE) == CAN_ID_EXT))
+#define IS_CAN_RTR(RTR) (((RTR) == CAN_RTR_DATA) || ((RTR) == CAN_RTR_REMOTE))
+#define IS_CAN_FIFO(FIFO) (((FIFO) == CAN_FIFO0) || ((FIFO) == CAN_FIFO1))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F103x6) || STM32F103xB || STM32F103xE || STM32F103xG) || STM32F105xC || STM32F107xC */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_CAN_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32_assert_template.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32_assert_template.h
new file mode 100644
index 0000000..f647587
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32_assert_template.h
@@ -0,0 +1,73 @@
+/**
+ ******************************************************************************
+ * @file stm32_assert.h
+ * @author MCD Application Team
+ * @brief STM32 assert template file.
+ * This file should be copied to the application folder and renamed
+ * to stm32_assert.h.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32_ASSERT_H
+#define __STM32_ASSERT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Includes ------------------------------------------------------------------*/
+/* 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)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+void assert_failed(uint8_t *file, uint32_t line);
+#else
+#define assert_param(expr) ((void)0U)
+#endif /* USE_FULL_ASSERT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32_ASSERT_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
new file mode 100644
index 0000000..653a094
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
@@ -0,0 +1,367 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal.h
+ * @author MCD Application Team
+ * @brief This file contains all the functions prototypes for the HAL
+ * module driver.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_H
+#define __STM32F1xx_HAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_conf.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup HAL
+ * @{
+ */
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup HAL_Exported_Constants HAL Exported Constants
+ * @{
+ */
+
+/** @defgroup HAL_TICK_FREQ Tick Frequency
+ * @{
+ */
+typedef enum
+{
+ HAL_TICK_FREQ_10HZ = 100U,
+ HAL_TICK_FREQ_100HZ = 10U,
+ HAL_TICK_FREQ_1KHZ = 1U,
+ HAL_TICK_FREQ_DEFAULT = HAL_TICK_FREQ_1KHZ
+} HAL_TickFreqTypeDef;
+/**
+ * @}
+ */
+/* Exported types ------------------------------------------------------------*/
+extern uint32_t uwTickPrio;
+extern HAL_TickFreqTypeDef uwTickFreq;
+
+/**
+ * @}
+ */
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup HAL_Exported_Macros HAL Exported Macros
+ * @{
+ */
+
+/** @defgroup DBGMCU_Freeze_Unfreeze Freeze Unfreeze Peripherals in Debug mode
+ * @brief Freeze/Unfreeze Peripherals in Debug mode
+ * Note: On devices STM32F10xx8 and STM32F10xxB,
+ * STM32F101xC/D/E and STM32F103xC/D/E,
+ * STM32F101xF/G and STM32F103xF/G
+ * STM32F10xx4 and STM32F10xx6
+ * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
+ * debug mode (not accessible by the user software in normal mode).
+ * Refer to errata sheet of these devices for more details.
+ * @{
+ */
+
+/* Peripherals on APB1 */
+/**
+ * @brief TIM2 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_TIM2() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM2_STOP)
+#define __HAL_DBGMCU_UNFREEZE_TIM2() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM2_STOP)
+
+/**
+ * @brief TIM3 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_TIM3() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM3_STOP)
+#define __HAL_DBGMCU_UNFREEZE_TIM3() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM3_STOP)
+
+#if defined (DBGMCU_CR_DBG_TIM4_STOP)
+/**
+ * @brief TIM4 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_TIM4() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM4_STOP)
+#define __HAL_DBGMCU_UNFREEZE_TIM4() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM4_STOP)
+#endif
+
+#if defined (DBGMCU_CR_DBG_TIM5_STOP)
+/**
+ * @brief TIM5 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_TIM5() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM5_STOP)
+#define __HAL_DBGMCU_UNFREEZE_TIM5() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM5_STOP)
+#endif
+
+#if defined (DBGMCU_CR_DBG_TIM6_STOP)
+/**
+ * @brief TIM6 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_TIM6() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM6_STOP)
+#define __HAL_DBGMCU_UNFREEZE_TIM6() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM6_STOP)
+#endif
+
+#if defined (DBGMCU_CR_DBG_TIM7_STOP)
+/**
+ * @brief TIM7 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_TIM7() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM7_STOP)
+#define __HAL_DBGMCU_UNFREEZE_TIM7() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM7_STOP)
+#endif
+
+#if defined (DBGMCU_CR_DBG_TIM12_STOP)
+/**
+ * @brief TIM12 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_TIM12() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM12_STOP)
+#define __HAL_DBGMCU_UNFREEZE_TIM12() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM12_STOP)
+#endif
+
+#if defined (DBGMCU_CR_DBG_TIM13_STOP)
+/**
+ * @brief TIM13 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_TIM13() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM13_STOP)
+#define __HAL_DBGMCU_UNFREEZE_TIM13() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM13_STOP)
+#endif
+
+#if defined (DBGMCU_CR_DBG_TIM14_STOP)
+/**
+ * @brief TIM14 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_TIM14() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM14_STOP)
+#define __HAL_DBGMCU_UNFREEZE_TIM14() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM14_STOP)
+#endif
+
+/**
+ * @brief WWDG Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_WWDG() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_WWDG_STOP)
+#define __HAL_DBGMCU_UNFREEZE_WWDG() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_WWDG_STOP)
+
+/**
+ * @brief IWDG Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_IWDG() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_IWDG_STOP)
+#define __HAL_DBGMCU_UNFREEZE_IWDG() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_IWDG_STOP)
+
+/**
+ * @brief I2C1 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_I2C1_TIMEOUT() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_I2C1_SMBUS_TIMEOUT)
+#define __HAL_DBGMCU_UNFREEZE_I2C1_TIMEOUT() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_I2C1_SMBUS_TIMEOUT)
+
+#if defined (DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT)
+/**
+ * @brief I2C2 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_I2C2_TIMEOUT() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT)
+#define __HAL_DBGMCU_UNFREEZE_I2C2_TIMEOUT() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT)
+#endif
+
+#if defined (DBGMCU_CR_DBG_CAN1_STOP)
+/**
+ * @brief CAN1 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_CAN1() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_CAN1_STOP)
+#define __HAL_DBGMCU_UNFREEZE_CAN1() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_CAN1_STOP)
+#endif
+
+#if defined (DBGMCU_CR_DBG_CAN2_STOP)
+/**
+ * @brief CAN2 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_CAN2() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_CAN2_STOP)
+#define __HAL_DBGMCU_UNFREEZE_CAN2() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_CAN2_STOP)
+#endif
+
+/* Peripherals on APB2 */
+#if defined (DBGMCU_CR_DBG_TIM1_STOP)
+/**
+ * @brief TIM1 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_TIM1() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM1_STOP)
+#define __HAL_DBGMCU_UNFREEZE_TIM1() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM1_STOP)
+#endif
+
+#if defined (DBGMCU_CR_DBG_TIM8_STOP)
+/**
+ * @brief TIM8 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_TIM8() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM8_STOP)
+#define __HAL_DBGMCU_UNFREEZE_TIM8() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM8_STOP)
+#endif
+
+#if defined (DBGMCU_CR_DBG_TIM9_STOP)
+/**
+ * @brief TIM9 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_TIM9() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM9_STOP)
+#define __HAL_DBGMCU_UNFREEZE_TIM9() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM9_STOP)
+#endif
+
+#if defined (DBGMCU_CR_DBG_TIM10_STOP)
+/**
+ * @brief TIM10 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_TIM10() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM10_STOP)
+#define __HAL_DBGMCU_UNFREEZE_TIM10() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM10_STOP)
+#endif
+
+#if defined (DBGMCU_CR_DBG_TIM11_STOP)
+/**
+ * @brief TIM11 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_TIM11() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM11_STOP)
+#define __HAL_DBGMCU_UNFREEZE_TIM11() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM11_STOP)
+#endif
+
+
+#if defined (DBGMCU_CR_DBG_TIM15_STOP)
+/**
+ * @brief TIM15 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_TIM15() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM15_STOP)
+#define __HAL_DBGMCU_UNFREEZE_TIM15() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM15_STOP)
+#endif
+
+#if defined (DBGMCU_CR_DBG_TIM16_STOP)
+/**
+ * @brief TIM16 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_TIM16() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM16_STOP)
+#define __HAL_DBGMCU_UNFREEZE_TIM16() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM16_STOP)
+#endif
+
+#if defined (DBGMCU_CR_DBG_TIM17_STOP)
+/**
+ * @brief TIM17 Peripherals Debug mode
+ */
+#define __HAL_DBGMCU_FREEZE_TIM17() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM17_STOP)
+#define __HAL_DBGMCU_UNFREEZE_TIM17() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM17_STOP)
+#endif
+
+/**
+ * @}
+ */
+
+/** @defgroup HAL_Private_Macros HAL Private Macros
+ * @{
+ */
+#define IS_TICKFREQ(FREQ) (((FREQ) == HAL_TICK_FREQ_10HZ) || \
+ ((FREQ) == HAL_TICK_FREQ_100HZ) || \
+ ((FREQ) == HAL_TICK_FREQ_1KHZ))
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup HAL_Exported_Functions
+ * @{
+ */
+/** @addtogroup HAL_Exported_Functions_Group1
+ * @{
+ */
+/* Initialization and de-initialization functions ******************************/
+HAL_StatusTypeDef HAL_Init(void);
+HAL_StatusTypeDef HAL_DeInit(void);
+void HAL_MspInit(void);
+void HAL_MspDeInit(void);
+HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority);
+/**
+ * @}
+ */
+
+/** @addtogroup HAL_Exported_Functions_Group2
+ * @{
+ */
+/* Peripheral Control functions ************************************************/
+void HAL_IncTick(void);
+void HAL_Delay(uint32_t Delay);
+uint32_t HAL_GetTick(void);
+uint32_t HAL_GetTickPrio(void);
+HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq);
+HAL_TickFreqTypeDef HAL_GetTickFreq(void);
+void HAL_SuspendTick(void);
+void HAL_ResumeTick(void);
+uint32_t HAL_GetHalVersion(void);
+uint32_t HAL_GetREVID(void);
+uint32_t HAL_GetDEVID(void);
+void HAL_DBGMCU_EnableDBGSleepMode(void);
+void HAL_DBGMCU_DisableDBGSleepMode(void);
+void HAL_DBGMCU_EnableDBGStopMode(void);
+void HAL_DBGMCU_DisableDBGStopMode(void);
+void HAL_DBGMCU_EnableDBGStandbyMode(void);
+void HAL_DBGMCU_DisableDBGStandbyMode(void);
+void HAL_GetUID(uint32_t *UID);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/** @defgroup HAL_Private_Variables HAL Private Variables
+ * @{
+ */
+/**
+ * @}
+ */
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup HAL_Private_Constants HAL Private Constants
+ * @{
+ */
+/**
+ * @}
+ */
+/* Private macros ------------------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc.h
new file mode 100644
index 0000000..fd79972
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc.h
@@ -0,0 +1,965 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_adc.h
+ * @author MCD Application Team
+ * @brief Header file containing functions prototypes of ADC HAL library.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_ADC_H
+#define __STM32F1xx_HAL_ADC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup ADC
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup ADC_Exported_Types ADC Exported Types
+ * @{
+ */
+
+/**
+ * @brief Structure definition of ADC and regular group initialization
+ * @note Parameters of this structure are shared within 2 scopes:
+ * - Scope entire ADC (affects regular and injected groups): DataAlign, ScanConvMode.
+ * - Scope regular group: ContinuousConvMode, NbrOfConversion, DiscontinuousConvMode, NbrOfDiscConversion, ExternalTrigConvEdge, ExternalTrigConv.
+ * @note The setting of these parameters with function HAL_ADC_Init() is conditioned to ADC state.
+ * ADC can be either disabled or enabled without conversion on going on regular group.
+ */
+typedef struct
+{
+ uint32_t DataAlign; /*!< Specifies ADC data alignment to right (MSB on register bit 11 and LSB on register bit 0) (default setting)
+ or to left (if regular group: MSB on register bit 15 and LSB on register bit 4, if injected group (MSB kept as signed value due to potential negative value after offset application): MSB on register bit 14 and LSB on register bit 3).
+ This parameter can be a value of @ref ADC_Data_align */
+ uint32_t ScanConvMode; /*!< Configures the sequencer of regular and injected groups.
+ This parameter can be associated to parameter 'DiscontinuousConvMode' to have main sequence subdivided in successive parts.
+ If disabled: Conversion is performed in single mode (one channel converted, the one defined in rank 1).
+ Parameters 'NbrOfConversion' and 'InjectedNbrOfConversion' are discarded (equivalent to set to 1).
+ If enabled: Conversions are performed in sequence mode (multiple ranks defined by 'NbrOfConversion'/'InjectedNbrOfConversion' and each channel rank).
+ Scan direction is upward: from rank1 to rank 'n'.
+ This parameter can be a value of @ref ADC_Scan_mode
+ Note: For regular group, this parameter should be enabled in conversion either by polling (HAL_ADC_Start with Discontinuous mode and NbrOfDiscConversion=1)
+ or by DMA (HAL_ADC_Start_DMA), but not by interruption (HAL_ADC_Start_IT): in scan mode, interruption is triggered only on the
+ the last conversion of the sequence. All previous conversions would be overwritten by the last one.
+ Injected group used with scan mode has not this constraint: each rank has its own result register, no data is overwritten. */
+ uint32_t ContinuousConvMode; /*!< Specifies whether the conversion is performed in single mode (one conversion) or continuous mode for regular group,
+ after the selected trigger occurred (software start or external trigger).
+ This parameter can be set to ENABLE or DISABLE. */
+ uint32_t NbrOfConversion; /*!< Specifies the number of ranks that will be converted within the regular group sequencer.
+ To use regular group sequencer and convert several ranks, parameter 'ScanConvMode' must be enabled.
+ This parameter must be a number between Min_Data = 1 and Max_Data = 16. */
+ uint32_t DiscontinuousConvMode; /*!< Specifies whether the conversions sequence of regular group is performed in Complete-sequence/Discontinuous-sequence (main sequence subdivided in successive parts).
+ Discontinuous mode is used only if sequencer is enabled (parameter 'ScanConvMode'). If sequencer is disabled, this parameter is discarded.
+ Discontinuous mode can be enabled only if continuous mode is disabled. If continuous mode is enabled, this parameter setting is discarded.
+ This parameter can be set to ENABLE or DISABLE. */
+ uint32_t NbrOfDiscConversion; /*!< Specifies the number of discontinuous conversions in which the main sequence of regular group (parameter NbrOfConversion) will be subdivided.
+ If parameter 'DiscontinuousConvMode' is disabled, this parameter is discarded.
+ This parameter must be a number between Min_Data = 1 and Max_Data = 8. */
+ uint32_t ExternalTrigConv; /*!< Selects the external event used to trigger the conversion start of regular group.
+ If set to ADC_SOFTWARE_START, external triggers are disabled.
+ If set to external trigger source, triggering is on event rising edge.
+ This parameter can be a value of @ref ADC_External_trigger_source_Regular */
+}ADC_InitTypeDef;
+
+/**
+ * @brief Structure definition of ADC channel for regular group
+ * @note The setting of these parameters with function HAL_ADC_ConfigChannel() is conditioned to ADC state.
+ * ADC can be either disabled or enabled without conversion on going on regular group.
+ */
+typedef struct
+{
+ uint32_t Channel; /*!< Specifies the channel to configure into ADC regular group.
+ This parameter can be a value of @ref ADC_channels
+ Note: Depending on devices, some channels may not be available on package pins. Refer to device datasheet for channels availability.
+ Note: On STM32F1 devices with several ADC: Only ADC1 can access internal measurement channels (VrefInt/TempSensor)
+ Note: On STM32F10xx8 and STM32F10xxB devices: A low-amplitude voltage glitch may be generated (on ADC input 0) on the PA0 pin, when the ADC is converting with injection trigger.
+ It is advised to distribute the analog channels so that Channel 0 is configured as an injected channel.
+ Refer to errata sheet of these devices for more details. */
+ uint32_t Rank; /*!< Specifies the rank in the regular group sequencer
+ This parameter can be a value of @ref ADC_regular_rank
+ Note: In case of need to disable a channel or change order of conversion sequencer, rank containing a previous channel setting can be overwritten by the new channel setting (or parameter number of conversions can be adjusted) */
+ uint32_t SamplingTime; /*!< Sampling time value to be set for the selected channel.
+ Unit: ADC clock cycles
+ Conversion time is the addition of sampling time and processing time (12.5 ADC clock cycles at ADC resolution 12 bits).
+ This parameter can be a value of @ref ADC_sampling_times
+ Caution: This parameter updates the parameter property of the channel, that can be used into regular and/or injected groups.
+ If this same channel has been previously configured in the other group (regular/injected), it will be updated to last setting.
+ Note: In case of usage of internal measurement channels (VrefInt/TempSensor),
+ sampling time constraints must be respected (sampling time can be adjusted in function of ADC clock frequency and sampling time setting)
+ Refer to device datasheet for timings values, parameters TS_vrefint, TS_temp (values rough order: 5us to 17.1us min). */
+}ADC_ChannelConfTypeDef;
+
+/**
+ * @brief ADC Configuration analog watchdog definition
+ * @note The setting of these parameters with function is conditioned to ADC state.
+ * ADC state can be either disabled or enabled without conversion on going on regular and injected groups.
+ */
+typedef struct
+{
+ uint32_t WatchdogMode; /*!< Configures the ADC analog watchdog mode: single/all channels, regular/injected group.
+ This parameter can be a value of @ref ADC_analog_watchdog_mode. */
+ uint32_t Channel; /*!< Selects which ADC channel to monitor by analog watchdog.
+ This parameter has an effect only if watchdog mode is configured on single channel (parameter WatchdogMode)
+ This parameter can be a value of @ref ADC_channels. */
+ uint32_t ITMode; /*!< Specifies whether the analog watchdog is configured in interrupt or polling mode.
+ This parameter can be set to ENABLE or DISABLE */
+ uint32_t HighThreshold; /*!< Configures the ADC analog watchdog High threshold value.
+ This parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF. */
+ uint32_t LowThreshold; /*!< Configures the ADC analog watchdog High threshold value.
+ This parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF. */
+ uint32_t WatchdogNumber; /*!< Reserved for future use, can be set to 0 */
+}ADC_AnalogWDGConfTypeDef;
+
+/**
+ * @brief HAL ADC state machine: ADC states definition (bitfields)
+ */
+/* States of ADC global scope */
+#define HAL_ADC_STATE_RESET 0x00000000U /*!< ADC not yet initialized or disabled */
+#define HAL_ADC_STATE_READY 0x00000001U /*!< ADC peripheral ready for use */
+#define HAL_ADC_STATE_BUSY_INTERNAL 0x00000002U /*!< ADC is busy to internal process (initialization, calibration) */
+#define HAL_ADC_STATE_TIMEOUT 0x00000004U /*!< TimeOut occurrence */
+
+/* States of ADC errors */
+#define HAL_ADC_STATE_ERROR_INTERNAL 0x00000010U /*!< Internal error occurrence */
+#define HAL_ADC_STATE_ERROR_CONFIG 0x00000020U /*!< Configuration error occurrence */
+#define HAL_ADC_STATE_ERROR_DMA 0x00000040U /*!< DMA error occurrence */
+
+/* States of ADC group regular */
+#define HAL_ADC_STATE_REG_BUSY 0x00000100U /*!< A conversion on group regular is ongoing or can occur (either by continuous mode,
+ external trigger, low power auto power-on, multimode ADC master control) */
+#define HAL_ADC_STATE_REG_EOC 0x00000200U /*!< Conversion data available on group regular */
+#define HAL_ADC_STATE_REG_OVR 0x00000400U /*!< Not available on STM32F1 device: Overrun occurrence */
+#define HAL_ADC_STATE_REG_EOSMP 0x00000800U /*!< Not available on STM32F1 device: End Of Sampling flag raised */
+
+/* States of ADC group injected */
+#define HAL_ADC_STATE_INJ_BUSY 0x00001000U /*!< A conversion on group injected is ongoing or can occur (either by auto-injection mode,
+ external trigger, low power auto power-on, multimode ADC master control) */
+#define HAL_ADC_STATE_INJ_EOC 0x00002000U /*!< Conversion data available on group injected */
+#define HAL_ADC_STATE_INJ_JQOVF 0x00004000U /*!< Not available on STM32F1 device: Injected queue overflow occurrence */
+
+/* States of ADC analog watchdogs */
+#define HAL_ADC_STATE_AWD1 0x00010000U /*!< Out-of-window occurrence of analog watchdog 1 */
+#define HAL_ADC_STATE_AWD2 0x00020000U /*!< Not available on STM32F1 device: Out-of-window occurrence of analog watchdog 2 */
+#define HAL_ADC_STATE_AWD3 0x00040000U /*!< Not available on STM32F1 device: Out-of-window occurrence of analog watchdog 3 */
+
+/* States of ADC multi-mode */
+#define HAL_ADC_STATE_MULTIMODE_SLAVE 0x00100000U /*!< ADC in multimode slave state, controlled by another ADC master ( */
+
+
+/**
+ * @brief ADC handle Structure definition
+ */
+typedef struct
+{
+ ADC_TypeDef *Instance; /*!< Register base address */
+
+ ADC_InitTypeDef Init; /*!< ADC required parameters */
+
+ DMA_HandleTypeDef *DMA_Handle; /*!< Pointer DMA Handler */
+
+ HAL_LockTypeDef Lock; /*!< ADC locking object */
+
+ __IO uint32_t State; /*!< ADC communication state (bitmap of ADC states) */
+
+ __IO uint32_t ErrorCode; /*!< ADC Error code */
+}ADC_HandleTypeDef;
+/**
+ * @}
+ */
+
+
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup ADC_Exported_Constants ADC Exported Constants
+ * @{
+ */
+
+/** @defgroup ADC_Error_Code ADC Error Code
+ * @{
+ */
+#define HAL_ADC_ERROR_NONE 0x00U /*!< No error */
+#define HAL_ADC_ERROR_INTERNAL 0x01U /*!< ADC IP internal error: if problem of clocking,
+ enable/disable, erroneous state */
+#define HAL_ADC_ERROR_OVR 0x02U /*!< Overrun error */
+#define HAL_ADC_ERROR_DMA 0x04U /*!< DMA transfer error */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_Data_align ADC data alignment
+ * @{
+ */
+#define ADC_DATAALIGN_RIGHT 0x00000000U
+#define ADC_DATAALIGN_LEFT ((uint32_t)ADC_CR2_ALIGN)
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Scan_mode ADC scan mode
+ * @{
+ */
+/* Note: Scan mode values are not among binary choices ENABLE/DISABLE for */
+/* compatibility with other STM32 devices having a sequencer with */
+/* additional options. */
+#define ADC_SCAN_DISABLE 0x00000000U
+#define ADC_SCAN_ENABLE ((uint32_t)ADC_CR1_SCAN)
+/**
+ * @}
+ */
+
+/** @defgroup ADC_External_trigger_edge_Regular ADC external trigger enable for regular group
+ * @{
+ */
+#define ADC_EXTERNALTRIGCONVEDGE_NONE 0x00000000U
+#define ADC_EXTERNALTRIGCONVEDGE_RISING ((uint32_t)ADC_CR2_EXTTRIG)
+/**
+ * @}
+ */
+
+/** @defgroup ADC_channels ADC channels
+ * @{
+ */
+/* Note: Depending on devices, some channels may not be available on package */
+/* pins. Refer to device datasheet for channels availability. */
+#define ADC_CHANNEL_0 0x00000000U
+#define ADC_CHANNEL_1 ((uint32_t)( ADC_SQR3_SQ1_0))
+#define ADC_CHANNEL_2 ((uint32_t)( ADC_SQR3_SQ1_1 ))
+#define ADC_CHANNEL_3 ((uint32_t)( ADC_SQR3_SQ1_1 | ADC_SQR3_SQ1_0))
+#define ADC_CHANNEL_4 ((uint32_t)( ADC_SQR3_SQ1_2 ))
+#define ADC_CHANNEL_5 ((uint32_t)( ADC_SQR3_SQ1_2 | ADC_SQR3_SQ1_0))
+#define ADC_CHANNEL_6 ((uint32_t)( ADC_SQR3_SQ1_2 | ADC_SQR3_SQ1_1 ))
+#define ADC_CHANNEL_7 ((uint32_t)( ADC_SQR3_SQ1_2 | ADC_SQR3_SQ1_1 | ADC_SQR3_SQ1_0))
+#define ADC_CHANNEL_8 ((uint32_t)( ADC_SQR3_SQ1_3 ))
+#define ADC_CHANNEL_9 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_0))
+#define ADC_CHANNEL_10 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_1 ))
+#define ADC_CHANNEL_11 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_1 | ADC_SQR3_SQ1_0))
+#define ADC_CHANNEL_12 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_2 ))
+#define ADC_CHANNEL_13 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_2 | ADC_SQR3_SQ1_0))
+#define ADC_CHANNEL_14 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_2 | ADC_SQR3_SQ1_1 ))
+#define ADC_CHANNEL_15 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_2 | ADC_SQR3_SQ1_1 | ADC_SQR3_SQ1_0))
+#define ADC_CHANNEL_16 ((uint32_t)(ADC_SQR3_SQ1_4 ))
+#define ADC_CHANNEL_17 ((uint32_t)(ADC_SQR3_SQ1_4 | ADC_SQR3_SQ1_0))
+
+#define ADC_CHANNEL_TEMPSENSOR ADC_CHANNEL_16 /* ADC internal channel (no connection on device pin) */
+#define ADC_CHANNEL_VREFINT ADC_CHANNEL_17 /* ADC internal channel (no connection on device pin) */
+/**
+ * @}
+ */
+
+/** @defgroup ADC_sampling_times ADC sampling times
+ * @{
+ */
+#define ADC_SAMPLETIME_1CYCLE_5 0x00000000U /*!< Sampling time 1.5 ADC clock cycle */
+#define ADC_SAMPLETIME_7CYCLES_5 ((uint32_t)( ADC_SMPR2_SMP0_0)) /*!< Sampling time 7.5 ADC clock cycles */
+#define ADC_SAMPLETIME_13CYCLES_5 ((uint32_t)( ADC_SMPR2_SMP0_1 )) /*!< Sampling time 13.5 ADC clock cycles */
+#define ADC_SAMPLETIME_28CYCLES_5 ((uint32_t)( ADC_SMPR2_SMP0_1 | ADC_SMPR2_SMP0_0)) /*!< Sampling time 28.5 ADC clock cycles */
+#define ADC_SAMPLETIME_41CYCLES_5 ((uint32_t)(ADC_SMPR2_SMP0_2 )) /*!< Sampling time 41.5 ADC clock cycles */
+#define ADC_SAMPLETIME_55CYCLES_5 ((uint32_t)(ADC_SMPR2_SMP0_2 | ADC_SMPR2_SMP0_0)) /*!< Sampling time 55.5 ADC clock cycles */
+#define ADC_SAMPLETIME_71CYCLES_5 ((uint32_t)(ADC_SMPR2_SMP0_2 | ADC_SMPR2_SMP0_1 )) /*!< Sampling time 71.5 ADC clock cycles */
+#define ADC_SAMPLETIME_239CYCLES_5 ((uint32_t)(ADC_SMPR2_SMP0_2 | ADC_SMPR2_SMP0_1 | ADC_SMPR2_SMP0_0)) /*!< Sampling time 239.5 ADC clock cycles */
+/**
+ * @}
+ */
+
+/** @defgroup ADC_regular_rank ADC rank into regular group
+ * @{
+ */
+#define ADC_REGULAR_RANK_1 0x00000001U
+#define ADC_REGULAR_RANK_2 0x00000002U
+#define ADC_REGULAR_RANK_3 0x00000003U
+#define ADC_REGULAR_RANK_4 0x00000004U
+#define ADC_REGULAR_RANK_5 0x00000005U
+#define ADC_REGULAR_RANK_6 0x00000006U
+#define ADC_REGULAR_RANK_7 0x00000007U
+#define ADC_REGULAR_RANK_8 0x00000008U
+#define ADC_REGULAR_RANK_9 0x00000009U
+#define ADC_REGULAR_RANK_10 0x0000000AU
+#define ADC_REGULAR_RANK_11 0x0000000BU
+#define ADC_REGULAR_RANK_12 0x0000000CU
+#define ADC_REGULAR_RANK_13 0x0000000DU
+#define ADC_REGULAR_RANK_14 0x0000000EU
+#define ADC_REGULAR_RANK_15 0x0000000FU
+#define ADC_REGULAR_RANK_16 0x00000010U
+/**
+ * @}
+ */
+
+/** @defgroup ADC_analog_watchdog_mode ADC analog watchdog mode
+ * @{
+ */
+#define ADC_ANALOGWATCHDOG_NONE 0x00000000U
+#define ADC_ANALOGWATCHDOG_SINGLE_REG ((uint32_t)(ADC_CR1_AWDSGL | ADC_CR1_AWDEN))
+#define ADC_ANALOGWATCHDOG_SINGLE_INJEC ((uint32_t)(ADC_CR1_AWDSGL | ADC_CR1_JAWDEN))
+#define ADC_ANALOGWATCHDOG_SINGLE_REGINJEC ((uint32_t)(ADC_CR1_AWDSGL | ADC_CR1_AWDEN | ADC_CR1_JAWDEN))
+#define ADC_ANALOGWATCHDOG_ALL_REG ((uint32_t)ADC_CR1_AWDEN)
+#define ADC_ANALOGWATCHDOG_ALL_INJEC ((uint32_t)ADC_CR1_JAWDEN)
+#define ADC_ANALOGWATCHDOG_ALL_REGINJEC ((uint32_t)(ADC_CR1_AWDEN | ADC_CR1_JAWDEN))
+/**
+ * @}
+ */
+
+/** @defgroup ADC_conversion_group ADC conversion group
+ * @{
+ */
+#define ADC_REGULAR_GROUP ((uint32_t)(ADC_FLAG_EOC))
+#define ADC_INJECTED_GROUP ((uint32_t)(ADC_FLAG_JEOC))
+#define ADC_REGULAR_INJECTED_GROUP ((uint32_t)(ADC_FLAG_EOC | ADC_FLAG_JEOC))
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Event_type ADC Event type
+ * @{
+ */
+#define ADC_AWD_EVENT ((uint32_t)ADC_FLAG_AWD) /*!< ADC Analog watchdog event */
+
+#define ADC_AWD1_EVENT ADC_AWD_EVENT /*!< ADC Analog watchdog 1 event: Alternate naming for compatibility with other STM32 devices having several analog watchdogs */
+/**
+ * @}
+ */
+
+/** @defgroup ADC_interrupts_definition ADC interrupts definition
+ * @{
+ */
+#define ADC_IT_EOC ADC_CR1_EOCIE /*!< ADC End of Regular Conversion interrupt source */
+#define ADC_IT_JEOC ADC_CR1_JEOCIE /*!< ADC End of Injected Conversion interrupt source */
+#define ADC_IT_AWD ADC_CR1_AWDIE /*!< ADC Analog watchdog interrupt source */
+/**
+ * @}
+ */
+
+/** @defgroup ADC_flags_definition ADC flags definition
+ * @{
+ */
+#define ADC_FLAG_STRT ADC_SR_STRT /*!< ADC Regular group start flag */
+#define ADC_FLAG_JSTRT ADC_SR_JSTRT /*!< ADC Injected group start flag */
+#define ADC_FLAG_EOC ADC_SR_EOC /*!< ADC End of Regular conversion flag */
+#define ADC_FLAG_JEOC ADC_SR_JEOC /*!< ADC End of Injected conversion flag */
+#define ADC_FLAG_AWD ADC_SR_AWD /*!< ADC Analog watchdog flag */
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/* Private constants ---------------------------------------------------------*/
+
+/** @addtogroup ADC_Private_Constants ADC Private Constants
+ * @{
+ */
+
+/** @defgroup ADC_conversion_cycles ADC conversion cycles
+ * @{
+ */
+/* ADC conversion cycles (unit: ADC clock cycles) */
+/* (selected sampling time + conversion time of 12.5 ADC clock cycles, with */
+/* resolution 12 bits) */
+#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_1CYCLE5 14U
+#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_7CYCLES5 20U
+#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_13CYCLES5 26U
+#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_28CYCLES5 41U
+#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_41CYCLES5 54U
+#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_55CYCLES5 68U
+#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_71CYCLES5 84U
+#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_239CYCLES5 252U
+/**
+ * @}
+ */
+
+/** @defgroup ADC_sampling_times_all_channels ADC sampling times all channels
+ * @{
+ */
+#define ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT2 \
+ (ADC_SMPR2_SMP9_2 | ADC_SMPR2_SMP8_2 | ADC_SMPR2_SMP7_2 | ADC_SMPR2_SMP6_2 | \
+ ADC_SMPR2_SMP5_2 | ADC_SMPR2_SMP4_2 | ADC_SMPR2_SMP3_2 | ADC_SMPR2_SMP2_2 | \
+ ADC_SMPR2_SMP1_2 | ADC_SMPR2_SMP0_2)
+#define ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT2 \
+ (ADC_SMPR1_SMP17_2 | ADC_SMPR1_SMP16_2 | ADC_SMPR1_SMP15_2 | ADC_SMPR1_SMP14_2 | \
+ ADC_SMPR1_SMP13_2 | ADC_SMPR1_SMP12_2 | ADC_SMPR1_SMP11_2 | ADC_SMPR1_SMP10_2 )
+
+#define ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1 \
+ (ADC_SMPR2_SMP9_1 | ADC_SMPR2_SMP8_1 | ADC_SMPR2_SMP7_1 | ADC_SMPR2_SMP6_1 | \
+ ADC_SMPR2_SMP5_1 | ADC_SMPR2_SMP4_1 | ADC_SMPR2_SMP3_1 | ADC_SMPR2_SMP2_1 | \
+ ADC_SMPR2_SMP1_1 | ADC_SMPR2_SMP0_1)
+#define ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1 \
+ (ADC_SMPR1_SMP17_1 | ADC_SMPR1_SMP16_1 | ADC_SMPR1_SMP15_1 | ADC_SMPR1_SMP14_1 | \
+ ADC_SMPR1_SMP13_1 | ADC_SMPR1_SMP12_1 | ADC_SMPR1_SMP11_1 | ADC_SMPR1_SMP10_1 )
+
+#define ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT0 \
+ (ADC_SMPR2_SMP9_0 | ADC_SMPR2_SMP8_0 | ADC_SMPR2_SMP7_0 | ADC_SMPR2_SMP6_0 | \
+ ADC_SMPR2_SMP5_0 | ADC_SMPR2_SMP4_0 | ADC_SMPR2_SMP3_0 | ADC_SMPR2_SMP2_0 | \
+ ADC_SMPR2_SMP1_0 | ADC_SMPR2_SMP0_0)
+#define ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0 \
+ (ADC_SMPR1_SMP17_0 | ADC_SMPR1_SMP16_0 | ADC_SMPR1_SMP15_0 | ADC_SMPR1_SMP14_0 | \
+ ADC_SMPR1_SMP13_0 | ADC_SMPR1_SMP12_0 | ADC_SMPR1_SMP11_0 | ADC_SMPR1_SMP10_0 )
+
+#define ADC_SAMPLETIME_1CYCLE5_SMPR2ALLCHANNELS 0x00000000U
+#define ADC_SAMPLETIME_7CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT0)
+#define ADC_SAMPLETIME_13CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1)
+#define ADC_SAMPLETIME_28CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1 | ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT0)
+#define ADC_SAMPLETIME_41CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT2)
+#define ADC_SAMPLETIME_55CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT2 | ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT0)
+#define ADC_SAMPLETIME_71CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT2 | ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1)
+#define ADC_SAMPLETIME_239CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT2 | ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1 | ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT0)
+
+#define ADC_SAMPLETIME_1CYCLE5_SMPR1ALLCHANNELS 0x00000000U
+#define ADC_SAMPLETIME_7CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0)
+#define ADC_SAMPLETIME_13CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1)
+#define ADC_SAMPLETIME_28CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1 | ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0)
+#define ADC_SAMPLETIME_41CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT2)
+#define ADC_SAMPLETIME_55CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT2 | ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0)
+#define ADC_SAMPLETIME_71CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT2 | ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1)
+#define ADC_SAMPLETIME_239CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT2 | ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1 | ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0)
+/**
+ * @}
+ */
+
+/* Combination of all post-conversion flags bits: EOC/EOS, JEOC/JEOS, OVR, AWDx */
+#define ADC_FLAG_POSTCONV_ALL (ADC_FLAG_EOC | ADC_FLAG_JEOC | ADC_FLAG_AWD )
+
+/**
+ * @}
+ */
+
+
+/* Exported macro ------------------------------------------------------------*/
+
+/** @defgroup ADC_Exported_Macros ADC Exported Macros
+ * @{
+ */
+/* Macro for internal HAL driver usage, and possibly can be used into code of */
+/* final user. */
+
+/**
+ * @brief Enable the ADC peripheral
+ * @note ADC enable requires a delay for ADC stabilization time
+ * (refer to device datasheet, parameter tSTAB)
+ * @note On STM32F1, if ADC is already enabled this macro trigs a conversion
+ * SW start on regular group.
+ * @param __HANDLE__: ADC handle
+ * @retval None
+ */
+#define __HAL_ADC_ENABLE(__HANDLE__) \
+ (SET_BIT((__HANDLE__)->Instance->CR2, (ADC_CR2_ADON)))
+
+/**
+ * @brief Disable the ADC peripheral
+ * @param __HANDLE__: ADC handle
+ * @retval None
+ */
+#define __HAL_ADC_DISABLE(__HANDLE__) \
+ (CLEAR_BIT((__HANDLE__)->Instance->CR2, (ADC_CR2_ADON)))
+
+/** @brief Enable the ADC end of conversion interrupt.
+ * @param __HANDLE__: ADC handle
+ * @param __INTERRUPT__: ADC Interrupt
+ * This parameter can be any combination of the following values:
+ * @arg ADC_IT_EOC: ADC End of Regular Conversion interrupt source
+ * @arg ADC_IT_JEOC: ADC End of Injected Conversion interrupt source
+ * @arg ADC_IT_AWD: ADC Analog watchdog interrupt source
+ * @retval None
+ */
+#define __HAL_ADC_ENABLE_IT(__HANDLE__, __INTERRUPT__) \
+ (SET_BIT((__HANDLE__)->Instance->CR1, (__INTERRUPT__)))
+
+/** @brief Disable the ADC end of conversion interrupt.
+ * @param __HANDLE__: ADC handle
+ * @param __INTERRUPT__: ADC Interrupt
+ * This parameter can be any combination of the following values:
+ * @arg ADC_IT_EOC: ADC End of Regular Conversion interrupt source
+ * @arg ADC_IT_JEOC: ADC End of Injected Conversion interrupt source
+ * @arg ADC_IT_AWD: ADC Analog watchdog interrupt source
+ * @retval None
+ */
+#define __HAL_ADC_DISABLE_IT(__HANDLE__, __INTERRUPT__) \
+ (CLEAR_BIT((__HANDLE__)->Instance->CR1, (__INTERRUPT__)))
+
+/** @brief Checks if the specified ADC interrupt source is enabled or disabled.
+ * @param __HANDLE__: ADC handle
+ * @param __INTERRUPT__: ADC interrupt source to check
+ * This parameter can be any combination of the following values:
+ * @arg ADC_IT_EOC: ADC End of Regular Conversion interrupt source
+ * @arg ADC_IT_JEOC: ADC End of Injected Conversion interrupt source
+ * @arg ADC_IT_AWD: ADC Analog watchdog interrupt source
+ * @retval None
+ */
+#define __HAL_ADC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \
+ (((__HANDLE__)->Instance->CR1 & (__INTERRUPT__)) == (__INTERRUPT__))
+
+/** @brief Get the selected ADC's flag status.
+ * @param __HANDLE__: ADC handle
+ * @param __FLAG__: ADC flag
+ * This parameter can be any combination of the following values:
+ * @arg ADC_FLAG_STRT: ADC Regular group start flag
+ * @arg ADC_FLAG_JSTRT: ADC Injected group start flag
+ * @arg ADC_FLAG_EOC: ADC End of Regular conversion flag
+ * @arg ADC_FLAG_JEOC: ADC End of Injected conversion flag
+ * @arg ADC_FLAG_AWD: ADC Analog watchdog flag
+ * @retval None
+ */
+#define __HAL_ADC_GET_FLAG(__HANDLE__, __FLAG__) \
+ ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__))
+
+/** @brief Clear the ADC's pending flags
+ * @param __HANDLE__: ADC handle
+ * @param __FLAG__: ADC flag
+ * This parameter can be any combination of the following values:
+ * @arg ADC_FLAG_STRT: ADC Regular group start flag
+ * @arg ADC_FLAG_JSTRT: ADC Injected group start flag
+ * @arg ADC_FLAG_EOC: ADC End of Regular conversion flag
+ * @arg ADC_FLAG_JEOC: ADC End of Injected conversion flag
+ * @arg ADC_FLAG_AWD: ADC Analog watchdog flag
+ * @retval None
+ */
+#define __HAL_ADC_CLEAR_FLAG(__HANDLE__, __FLAG__) \
+ (WRITE_REG((__HANDLE__)->Instance->SR, ~(__FLAG__)))
+
+/** @brief Reset ADC handle state
+ * @param __HANDLE__: ADC handle
+ * @retval None
+ */
+#define __HAL_ADC_RESET_HANDLE_STATE(__HANDLE__) \
+ ((__HANDLE__)->State = HAL_ADC_STATE_RESET)
+
+/**
+ * @}
+ */
+
+/* Private macro ------------------------------------------------------------*/
+
+/** @defgroup ADC_Private_Macros ADC Private Macros
+ * @{
+ */
+/* Macro reserved for internal HAL driver usage, not intended to be used in */
+/* code of final user. */
+
+/**
+ * @brief Verification of ADC state: enabled or disabled
+ * @param __HANDLE__: ADC handle
+ * @retval SET (ADC enabled) or RESET (ADC disabled)
+ */
+#define ADC_IS_ENABLE(__HANDLE__) \
+ ((( ((__HANDLE__)->Instance->CR2 & ADC_CR2_ADON) == ADC_CR2_ADON ) \
+ ) ? SET : RESET)
+
+/**
+ * @brief Test if conversion trigger of regular group is software start
+ * or external trigger.
+ * @param __HANDLE__: ADC handle
+ * @retval SET (software start) or RESET (external trigger)
+ */
+#define ADC_IS_SOFTWARE_START_REGULAR(__HANDLE__) \
+ (READ_BIT((__HANDLE__)->Instance->CR2, ADC_CR2_EXTSEL) == ADC_SOFTWARE_START)
+
+/**
+ * @brief Test if conversion trigger of injected group is software start
+ * or external trigger.
+ * @param __HANDLE__: ADC handle
+ * @retval SET (software start) or RESET (external trigger)
+ */
+#define ADC_IS_SOFTWARE_START_INJECTED(__HANDLE__) \
+ (READ_BIT((__HANDLE__)->Instance->CR2, ADC_CR2_JEXTSEL) == ADC_INJECTED_SOFTWARE_START)
+
+/**
+ * @brief Simultaneously clears and sets specific bits of the handle State
+ * @note: ADC_STATE_CLR_SET() macro is merely aliased to generic macro MODIFY_REG(),
+ * the first parameter is the ADC handle State, the second parameter is the
+ * bit field to clear, the third and last parameter is the bit field to set.
+ * @retval None
+ */
+#define ADC_STATE_CLR_SET MODIFY_REG
+
+/**
+ * @brief Clear ADC error code (set it to error code: "no error")
+ * @param __HANDLE__: ADC handle
+ * @retval None
+ */
+#define ADC_CLEAR_ERRORCODE(__HANDLE__) \
+ ((__HANDLE__)->ErrorCode = HAL_ADC_ERROR_NONE)
+
+/**
+ * @brief Set ADC number of conversions into regular channel sequence length.
+ * @param _NbrOfConversion_: Regular channel sequence length
+ * @retval None
+ */
+#define ADC_SQR1_L_SHIFT(_NbrOfConversion_) \
+ (((_NbrOfConversion_) - (uint8_t)1) << ADC_SQR1_L_Pos)
+
+/**
+ * @brief Set the ADC's sample time for channel numbers between 10 and 18.
+ * @param _SAMPLETIME_: Sample time parameter.
+ * @param _CHANNELNB_: Channel number.
+ * @retval None
+ */
+#define ADC_SMPR1(_SAMPLETIME_, _CHANNELNB_) \
+ ((_SAMPLETIME_) << (ADC_SMPR1_SMP11_Pos * ((_CHANNELNB_) - 10)))
+
+/**
+ * @brief Set the ADC's sample time for channel numbers between 0 and 9.
+ * @param _SAMPLETIME_: Sample time parameter.
+ * @param _CHANNELNB_: Channel number.
+ * @retval None
+ */
+#define ADC_SMPR2(_SAMPLETIME_, _CHANNELNB_) \
+ ((_SAMPLETIME_) << (ADC_SMPR2_SMP1_Pos * (_CHANNELNB_)))
+
+/**
+ * @brief Set the selected regular channel rank for rank between 1 and 6.
+ * @param _CHANNELNB_: Channel number.
+ * @param _RANKNB_: Rank number.
+ * @retval None
+ */
+#define ADC_SQR3_RK(_CHANNELNB_, _RANKNB_) \
+ ((_CHANNELNB_) << (ADC_SQR3_SQ2_Pos * ((_RANKNB_) - 1)))
+
+/**
+ * @brief Set the selected regular channel rank for rank between 7 and 12.
+ * @param _CHANNELNB_: Channel number.
+ * @param _RANKNB_: Rank number.
+ * @retval None
+ */
+#define ADC_SQR2_RK(_CHANNELNB_, _RANKNB_) \
+ ((_CHANNELNB_) << (ADC_SQR2_SQ8_Pos * ((_RANKNB_) - 7)))
+
+/**
+ * @brief Set the selected regular channel rank for rank between 13 and 16.
+ * @param _CHANNELNB_: Channel number.
+ * @param _RANKNB_: Rank number.
+ * @retval None
+ */
+#define ADC_SQR1_RK(_CHANNELNB_, _RANKNB_) \
+ ((_CHANNELNB_) << (ADC_SQR1_SQ14_Pos * ((_RANKNB_) - 13)))
+
+/**
+ * @brief Set the injected sequence length.
+ * @param _JSQR_JL_: Sequence length.
+ * @retval None
+ */
+#define ADC_JSQR_JL_SHIFT(_JSQR_JL_) \
+ (((_JSQR_JL_) -1) << ADC_JSQR_JL_Pos)
+
+/**
+ * @brief Set the selected injected channel rank
+ * Note: on STM32F1 devices, channel rank position in JSQR register
+ * is depending on total number of ranks selected into
+ * injected sequencer (ranks sequence starting from 4-JL)
+ * @param _CHANNELNB_: Channel number.
+ * @param _RANKNB_: Rank number.
+ * @param _JSQR_JL_: Sequence length.
+ * @retval None
+ */
+#define ADC_JSQR_RK_JL(_CHANNELNB_, _RANKNB_, _JSQR_JL_) \
+ ((_CHANNELNB_) << (ADC_JSQR_JSQ2_Pos * ((4 - ((_JSQR_JL_) - (_RANKNB_))) - 1)))
+
+/**
+ * @brief Enable ADC continuous conversion mode.
+ * @param _CONTINUOUS_MODE_: Continuous mode.
+ * @retval None
+ */
+#define ADC_CR2_CONTINUOUS(_CONTINUOUS_MODE_) \
+ ((_CONTINUOUS_MODE_) << ADC_CR2_CONT_Pos)
+
+/**
+ * @brief Configures the number of discontinuous conversions for the regular group channels.
+ * @param _NBR_DISCONTINUOUS_CONV_: Number of discontinuous conversions.
+ * @retval None
+ */
+#define ADC_CR1_DISCONTINUOUS_NUM(_NBR_DISCONTINUOUS_CONV_) \
+ (((_NBR_DISCONTINUOUS_CONV_) - 1) << ADC_CR1_DISCNUM_Pos)
+
+/**
+ * @brief Enable ADC scan mode to convert multiple ranks with sequencer.
+ * @param _SCAN_MODE_: Scan conversion mode.
+ * @retval None
+ */
+/* Note: Scan mode is compared to ENABLE for legacy purpose, this parameter */
+/* is equivalent to ADC_SCAN_ENABLE. */
+#define ADC_CR1_SCAN_SET(_SCAN_MODE_) \
+ (( ((_SCAN_MODE_) == ADC_SCAN_ENABLE) || ((_SCAN_MODE_) == ENABLE) \
+ )? (ADC_SCAN_ENABLE) : (ADC_SCAN_DISABLE) \
+ )
+
+/**
+ * @brief Get the maximum ADC conversion cycles on all channels.
+ * Returns the selected sampling time + conversion time (12.5 ADC clock cycles)
+ * Approximation of sampling time within 4 ranges, returns the highest value:
+ * below 7.5 cycles {1.5 cycle; 7.5 cycles},
+ * between 13.5 cycles and 28.5 cycles {13.5 cycles; 28.5 cycles}
+ * between 41.5 cycles and 71.5 cycles {41.5 cycles; 55.5 cycles; 71.5cycles}
+ * equal to 239.5 cycles
+ * Unit: ADC clock cycles
+ * @param __HANDLE__: ADC handle
+ * @retval ADC conversion cycles on all channels
+ */
+#define ADC_CONVCYCLES_MAX_RANGE(__HANDLE__) \
+ (( (((__HANDLE__)->Instance->SMPR2 & ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT2) == RESET) && \
+ (((__HANDLE__)->Instance->SMPR1 & ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT2) == RESET) ) ? \
+ \
+ (( (((__HANDLE__)->Instance->SMPR2 & ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1) == RESET) && \
+ (((__HANDLE__)->Instance->SMPR1 & ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1) == RESET) ) ? \
+ ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_7CYCLES5 : ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_28CYCLES5) \
+ : \
+ ((((((__HANDLE__)->Instance->SMPR2 & ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1) == RESET) && \
+ (((__HANDLE__)->Instance->SMPR1 & ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1) == RESET)) || \
+ ((((__HANDLE__)->Instance->SMPR2 & ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0) == RESET) && \
+ (((__HANDLE__)->Instance->SMPR1 & ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0) == RESET))) ? \
+ ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_71CYCLES5 : ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_239CYCLES5) \
+ )
+
+#define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DATAALIGN_RIGHT) || \
+ ((ALIGN) == ADC_DATAALIGN_LEFT) )
+
+#define IS_ADC_SCAN_MODE(SCAN_MODE) (((SCAN_MODE) == ADC_SCAN_DISABLE) || \
+ ((SCAN_MODE) == ADC_SCAN_ENABLE) )
+
+#define IS_ADC_EXTTRIG_EDGE(EDGE) (((EDGE) == ADC_EXTERNALTRIGCONVEDGE_NONE) || \
+ ((EDGE) == ADC_EXTERNALTRIGCONVEDGE_RISING) )
+
+#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_CHANNEL_0) || \
+ ((CHANNEL) == ADC_CHANNEL_1) || \
+ ((CHANNEL) == ADC_CHANNEL_2) || \
+ ((CHANNEL) == ADC_CHANNEL_3) || \
+ ((CHANNEL) == ADC_CHANNEL_4) || \
+ ((CHANNEL) == ADC_CHANNEL_5) || \
+ ((CHANNEL) == ADC_CHANNEL_6) || \
+ ((CHANNEL) == ADC_CHANNEL_7) || \
+ ((CHANNEL) == ADC_CHANNEL_8) || \
+ ((CHANNEL) == ADC_CHANNEL_9) || \
+ ((CHANNEL) == ADC_CHANNEL_10) || \
+ ((CHANNEL) == ADC_CHANNEL_11) || \
+ ((CHANNEL) == ADC_CHANNEL_12) || \
+ ((CHANNEL) == ADC_CHANNEL_13) || \
+ ((CHANNEL) == ADC_CHANNEL_14) || \
+ ((CHANNEL) == ADC_CHANNEL_15) || \
+ ((CHANNEL) == ADC_CHANNEL_16) || \
+ ((CHANNEL) == ADC_CHANNEL_17) )
+
+#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SAMPLETIME_1CYCLE_5) || \
+ ((TIME) == ADC_SAMPLETIME_7CYCLES_5) || \
+ ((TIME) == ADC_SAMPLETIME_13CYCLES_5) || \
+ ((TIME) == ADC_SAMPLETIME_28CYCLES_5) || \
+ ((TIME) == ADC_SAMPLETIME_41CYCLES_5) || \
+ ((TIME) == ADC_SAMPLETIME_55CYCLES_5) || \
+ ((TIME) == ADC_SAMPLETIME_71CYCLES_5) || \
+ ((TIME) == ADC_SAMPLETIME_239CYCLES_5) )
+
+#define IS_ADC_REGULAR_RANK(CHANNEL) (((CHANNEL) == ADC_REGULAR_RANK_1 ) || \
+ ((CHANNEL) == ADC_REGULAR_RANK_2 ) || \
+ ((CHANNEL) == ADC_REGULAR_RANK_3 ) || \
+ ((CHANNEL) == ADC_REGULAR_RANK_4 ) || \
+ ((CHANNEL) == ADC_REGULAR_RANK_5 ) || \
+ ((CHANNEL) == ADC_REGULAR_RANK_6 ) || \
+ ((CHANNEL) == ADC_REGULAR_RANK_7 ) || \
+ ((CHANNEL) == ADC_REGULAR_RANK_8 ) || \
+ ((CHANNEL) == ADC_REGULAR_RANK_9 ) || \
+ ((CHANNEL) == ADC_REGULAR_RANK_10) || \
+ ((CHANNEL) == ADC_REGULAR_RANK_11) || \
+ ((CHANNEL) == ADC_REGULAR_RANK_12) || \
+ ((CHANNEL) == ADC_REGULAR_RANK_13) || \
+ ((CHANNEL) == ADC_REGULAR_RANK_14) || \
+ ((CHANNEL) == ADC_REGULAR_RANK_15) || \
+ ((CHANNEL) == ADC_REGULAR_RANK_16) )
+
+#define IS_ADC_ANALOG_WATCHDOG_MODE(WATCHDOG) (((WATCHDOG) == ADC_ANALOGWATCHDOG_NONE) || \
+ ((WATCHDOG) == ADC_ANALOGWATCHDOG_SINGLE_REG) || \
+ ((WATCHDOG) == ADC_ANALOGWATCHDOG_SINGLE_INJEC) || \
+ ((WATCHDOG) == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC) || \
+ ((WATCHDOG) == ADC_ANALOGWATCHDOG_ALL_REG) || \
+ ((WATCHDOG) == ADC_ANALOGWATCHDOG_ALL_INJEC) || \
+ ((WATCHDOG) == ADC_ANALOGWATCHDOG_ALL_REGINJEC) )
+
+#define IS_ADC_CONVERSION_GROUP(CONVERSION) (((CONVERSION) == ADC_REGULAR_GROUP) || \
+ ((CONVERSION) == ADC_INJECTED_GROUP) || \
+ ((CONVERSION) == ADC_REGULAR_INJECTED_GROUP) )
+
+#define IS_ADC_EVENT_TYPE(EVENT) ((EVENT) == ADC_AWD_EVENT)
+
+
+/** @defgroup ADC_range_verification ADC range verification
+ * For a unique ADC resolution: 12 bits
+ * @{
+ */
+#define IS_ADC_RANGE(ADC_VALUE) ((ADC_VALUE) <= 0x0FFFU)
+/**
+ * @}
+ */
+
+/** @defgroup ADC_regular_nb_conv_verification ADC regular nb conv verification
+ * @{
+ */
+#define IS_ADC_REGULAR_NB_CONV(LENGTH) (((LENGTH) >= 1U) && ((LENGTH) <= 16U))
+/**
+ * @}
+ */
+
+/** @defgroup ADC_regular_discontinuous_mode_number_verification ADC regular discontinuous mode number verification
+ * @{
+ */
+#define IS_ADC_REGULAR_DISCONT_NUMBER(NUMBER) (((NUMBER) >= 1U) && ((NUMBER) <= 8U))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Include ADC HAL Extension module */
+#include "stm32f1xx_hal_adc_ex.h"
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup ADC_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup ADC_Exported_Functions_Group1
+ * @{
+ */
+
+
+/* Initialization and de-initialization functions **********************************/
+HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc);
+HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef *hadc);
+void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc);
+void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc);
+/**
+ * @}
+ */
+
+/* IO operation functions *****************************************************/
+
+/** @addtogroup ADC_Exported_Functions_Group2
+ * @{
+ */
+
+
+/* Blocking mode: Polling */
+HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc);
+HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc);
+HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout);
+HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventType, uint32_t Timeout);
+
+/* Non-blocking mode: Interruption */
+HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc);
+HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc);
+
+/* Non-blocking mode: DMA */
+HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length);
+HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc);
+
+/* ADC retrieve conversion value intended to be used with polling or interruption */
+uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc);
+
+/* ADC IRQHandler and Callbacks used in non-blocking modes (Interruption and DMA) */
+void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc);
+void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc);
+void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc);
+void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc);
+void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc);
+/**
+ * @}
+ */
+
+
+/* Peripheral Control functions ***********************************************/
+/** @addtogroup ADC_Exported_Functions_Group3
+ * @{
+ */
+HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig);
+HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDGConfTypeDef* AnalogWDGConfig);
+/**
+ * @}
+ */
+
+
+/* Peripheral State functions *************************************************/
+/** @addtogroup ADC_Exported_Functions_Group4
+ * @{
+ */
+uint32_t HAL_ADC_GetState(ADC_HandleTypeDef* hadc);
+uint32_t HAL_ADC_GetError(ADC_HandleTypeDef *hadc);
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/* Internal HAL driver functions **********************************************/
+/** @addtogroup ADC_Private_Functions
+ * @{
+ */
+HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef* hadc);
+HAL_StatusTypeDef ADC_ConversionStop_Disable(ADC_HandleTypeDef* hadc);
+void ADC_StabilizationTime(uint32_t DelayUs);
+void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma);
+void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma);
+void ADC_DMAError(DMA_HandleTypeDef *hdma);
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __STM32F1xx_HAL_ADC_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc_ex.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc_ex.h
new file mode 100644
index 0000000..b923ce4
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc_ex.h
@@ -0,0 +1,726 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_adc_ex.h
+ * @author MCD Application Team
+ * @brief Header file of ADC HAL extension module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_ADC_EX_H
+#define __STM32F1xx_HAL_ADC_EX_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup ADCEx
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup ADCEx_Exported_Types ADCEx Exported Types
+ * @{
+ */
+
+/**
+ * @brief ADC Configuration injected Channel structure definition
+ * @note Parameters of this structure are shared within 2 scopes:
+ * - Scope channel: InjectedChannel, InjectedRank, InjectedSamplingTime, InjectedOffset
+ * - Scope injected group (affects all channels of injected group): InjectedNbrOfConversion, InjectedDiscontinuousConvMode,
+ * AutoInjectedConv, ExternalTrigInjecConvEdge, ExternalTrigInjecConv.
+ * @note The setting of these parameters with function HAL_ADCEx_InjectedConfigChannel() is conditioned to ADC state.
+ * ADC state can be either:
+ * - For all parameters: ADC disabled (this is the only possible ADC state to modify parameter 'ExternalTrigInjecConv')
+ * - For all except parameters 'ExternalTrigInjecConv': ADC enabled without conversion on going on injected group.
+ */
+typedef struct
+{
+ uint32_t InjectedChannel; /*!< Selection of ADC channel to configure
+ This parameter can be a value of @ref ADC_channels
+ Note: Depending on devices, some channels may not be available on package pins. Refer to device datasheet for channels availability.
+ Note: On STM32F1 devices with several ADC: Only ADC1 can access internal measurement channels (VrefInt/TempSensor)
+ Note: On STM32F10xx8 and STM32F10xxB devices: A low-amplitude voltage glitch may be generated (on ADC input 0) on the PA0 pin, when the ADC is converting with injection trigger.
+ It is advised to distribute the analog channels so that Channel 0 is configured as an injected channel.
+ Refer to errata sheet of these devices for more details. */
+ uint32_t InjectedRank; /*!< Rank in the injected group sequencer
+ This parameter must be a value of @ref ADCEx_injected_rank
+ Note: In case of need to disable a channel or change order of conversion sequencer, rank containing a previous channel setting can be overwritten by the new channel setting (or parameter number of conversions can be adjusted) */
+ uint32_t InjectedSamplingTime; /*!< Sampling time value to be set for the selected channel.
+ Unit: ADC clock cycles
+ Conversion time is the addition of sampling time and processing time (12.5 ADC clock cycles at ADC resolution 12 bits).
+ This parameter can be a value of @ref ADC_sampling_times
+ Caution: This parameter updates the parameter property of the channel, that can be used into regular and/or injected groups.
+ If this same channel has been previously configured in the other group (regular/injected), it will be updated to last setting.
+ Note: In case of usage of internal measurement channels (VrefInt/TempSensor),
+ sampling time constraints must be respected (sampling time can be adjusted in function of ADC clock frequency and sampling time setting)
+ Refer to device datasheet for timings values, parameters TS_vrefint, TS_temp (values rough order: 5us to 17.1us min). */
+ uint32_t InjectedOffset; /*!< Defines the offset to be subtracted from the raw converted data (for channels set on injected group only).
+ Offset value must be a positive number.
+ Depending of ADC resolution selected (12, 10, 8 or 6 bits),
+ this parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF, 0x3FF, 0xFF or 0x3F respectively. */
+ uint32_t InjectedNbrOfConversion; /*!< Specifies the number of ranks that will be converted within the injected group sequencer.
+ To use the injected group sequencer and convert several ranks, parameter 'ScanConvMode' must be enabled.
+ This parameter must be a number between Min_Data = 1 and Max_Data = 4.
+ Caution: this setting impacts the entire injected group. Therefore, call of HAL_ADCEx_InjectedConfigChannel() to
+ configure a channel on injected group can impact the configuration of other channels previously set. */
+ uint32_t InjectedDiscontinuousConvMode; /*!< Specifies whether the conversions sequence of injected group is performed in Complete-sequence/Discontinuous-sequence (main sequence subdivided in successive parts).
+ Discontinuous mode is used only if sequencer is enabled (parameter 'ScanConvMode'). If sequencer is disabled, this parameter is discarded.
+ Discontinuous mode can be enabled only if continuous mode is disabled. If continuous mode is enabled, this parameter setting is discarded.
+ This parameter can be set to ENABLE or DISABLE.
+ Note: For injected group, number of discontinuous ranks increment is fixed to one-by-one.
+ Caution: this setting impacts the entire injected group. Therefore, call of HAL_ADCEx_InjectedConfigChannel() to
+ configure a channel on injected group can impact the configuration of other channels previously set. */
+ uint32_t AutoInjectedConv; /*!< Enables or disables the selected ADC automatic injected group conversion after regular one
+ This parameter can be set to ENABLE or DISABLE.
+ Note: To use Automatic injected conversion, discontinuous mode must be disabled ('DiscontinuousConvMode' and 'InjectedDiscontinuousConvMode' set to DISABLE)
+ Note: To use Automatic injected conversion, injected group external triggers must be disabled ('ExternalTrigInjecConv' set to ADC_SOFTWARE_START)
+ Note: In case of DMA used with regular group: if DMA configured in normal mode (single shot) JAUTO will be stopped upon DMA transfer complete.
+ To maintain JAUTO always enabled, DMA must be configured in circular mode.
+ Caution: this setting impacts the entire injected group. Therefore, call of HAL_ADCEx_InjectedConfigChannel() to
+ configure a channel on injected group can impact the configuration of other channels previously set. */
+ uint32_t ExternalTrigInjecConv; /*!< Selects the external event used to trigger the conversion start of injected group.
+ If set to ADC_INJECTED_SOFTWARE_START, external triggers are disabled.
+ If set to external trigger source, triggering is on event rising edge.
+ This parameter can be a value of @ref ADCEx_External_trigger_source_Injected
+ Note: This parameter must be modified when ADC is disabled (before ADC start conversion or after ADC stop conversion).
+ If ADC is enabled, this parameter setting is bypassed without error reporting (as it can be the expected behaviour in case of another parameter update on the fly)
+ Caution: this setting impacts the entire injected group. Therefore, call of HAL_ADCEx_InjectedConfigChannel() to
+ configure a channel on injected group can impact the configuration of other channels previously set. */
+}ADC_InjectionConfTypeDef;
+
+#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
+/**
+ * @brief Structure definition of ADC multimode
+ * @note The setting of these parameters with function HAL_ADCEx_MultiModeConfigChannel() is conditioned to ADCs state (both ADCs of the common group).
+ * State of ADCs of the common group must be: disabled.
+ */
+typedef struct
+{
+ uint32_t Mode; /*!< Configures the ADC to operate in independent or multi mode.
+ This parameter can be a value of @ref ADCEx_Common_mode
+ Note: In dual mode, a change of channel configuration generates a restart that can produce a loss of synchronization. It is recommended to disable dual mode before any configuration change.
+ Note: In case of simultaneous mode used: Exactly the same sampling time should be configured for the 2 channels that will be sampled simultaneously by ACD1 and ADC2.
+ Note: In case of interleaved mode used: To avoid overlap between conversions, maximum sampling time allowed is 7 ADC clock cycles for fast interleaved mode and 14 ADC clock cycles for slow interleaved mode.
+ Note: Some multimode parameters are fixed on STM32F1 and can be configured on other STM32 devices with several ADC (multimode configuration structure can have additional parameters).
+ The equivalences are:
+ - Parameter 'DMAAccessMode': On STM32F1, this parameter is fixed to 1 DMA channel (one DMA channel for both ADC, DMA of ADC master). On other STM32 devices with several ADC, this is equivalent to parameter 'ADC_DMAACCESSMODE_12_10_BITS'.
+ - Parameter 'TwoSamplingDelay': On STM32F1, this parameter is fixed to 7 or 14 ADC clock cycles depending on fast or slow interleaved mode selected. On other STM32 devices with several ADC, this is equivalent to parameter 'ADC_TWOSAMPLINGDELAY_7CYCLES' (for fast interleaved mode). */
+
+
+}ADC_MultiModeTypeDef;
+#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
+
+/**
+ * @}
+ */
+
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup ADCEx_Exported_Constants ADCEx Exported Constants
+ * @{
+ */
+
+/** @defgroup ADCEx_injected_rank ADCEx rank into injected group
+ * @{
+ */
+#define ADC_INJECTED_RANK_1 0x00000001U
+#define ADC_INJECTED_RANK_2 0x00000002U
+#define ADC_INJECTED_RANK_3 0x00000003U
+#define ADC_INJECTED_RANK_4 0x00000004U
+/**
+ * @}
+ */
+
+/** @defgroup ADCEx_External_trigger_edge_Injected ADCEx external trigger enable for injected group
+ * @{
+ */
+#define ADC_EXTERNALTRIGINJECCONV_EDGE_NONE 0x00000000U
+#define ADC_EXTERNALTRIGINJECCONV_EDGE_RISING ((uint32_t)ADC_CR2_JEXTTRIG)
+/**
+ * @}
+ */
+
+/** @defgroup ADC_External_trigger_source_Regular ADC External trigger selection for regular group
+ * @{
+ */
+/*!< List of external triggers with generic trigger name, independently of */
+/* ADC target, sorted by trigger name: */
+
+/*!< External triggers of regular group for ADC1&ADC2 only */
+#define ADC_EXTERNALTRIGCONV_T1_CC1 ADC1_2_EXTERNALTRIG_T1_CC1
+#define ADC_EXTERNALTRIGCONV_T1_CC2 ADC1_2_EXTERNALTRIG_T1_CC2
+#define ADC_EXTERNALTRIGCONV_T2_CC2 ADC1_2_EXTERNALTRIG_T2_CC2
+#define ADC_EXTERNALTRIGCONV_T3_TRGO ADC1_2_EXTERNALTRIG_T3_TRGO
+#define ADC_EXTERNALTRIGCONV_T4_CC4 ADC1_2_EXTERNALTRIG_T4_CC4
+#define ADC_EXTERNALTRIGCONV_EXT_IT11 ADC1_2_EXTERNALTRIG_EXT_IT11
+
+#if defined (STM32F103xE) || defined (STM32F103xG)
+/*!< External triggers of regular group for ADC3 only */
+#define ADC_EXTERNALTRIGCONV_T2_CC3 ADC3_EXTERNALTRIG_T2_CC3
+#define ADC_EXTERNALTRIGCONV_T3_CC1 ADC3_EXTERNALTRIG_T3_CC1
+#define ADC_EXTERNALTRIGCONV_T5_CC1 ADC3_EXTERNALTRIG_T5_CC1
+#define ADC_EXTERNALTRIGCONV_T5_CC3 ADC3_EXTERNALTRIG_T5_CC3
+#define ADC_EXTERNALTRIGCONV_T8_CC1 ADC3_EXTERNALTRIG_T8_CC1
+#endif /* STM32F103xE || defined STM32F103xG */
+
+/*!< External triggers of regular group for all ADC instances */
+#define ADC_EXTERNALTRIGCONV_T1_CC3 ADC1_2_3_EXTERNALTRIG_T1_CC3
+
+#if defined (STM32F101xE) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC)
+/*!< Note: TIM8_TRGO is available on ADC1 and ADC2 only in high-density and */
+/* XL-density devices. */
+/* To use it on ADC or ADC2, a remap of trigger must be done from */
+/* EXTI line 11 to TIM8_TRGO with macro: */
+/* __HAL_AFIO_REMAP_ADC1_ETRGREG_ENABLE() */
+/* __HAL_AFIO_REMAP_ADC2_ETRGREG_ENABLE() */
+
+/* Note for internal constant value management: If TIM8_TRGO is available, */
+/* its definition is set to value for ADC1&ADC2 by default and changed to */
+/* value for ADC3 by HAL ADC driver if ADC3 is selected. */
+#define ADC_EXTERNALTRIGCONV_T8_TRGO ADC1_2_EXTERNALTRIG_T8_TRGO
+#endif /* STM32F101xE || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
+
+#define ADC_SOFTWARE_START ADC1_2_3_SWSTART
+/**
+ * @}
+ */
+
+/** @defgroup ADCEx_External_trigger_source_Injected ADCEx External trigger selection for injected group
+ * @{
+ */
+/*!< List of external triggers with generic trigger name, independently of */
+/* ADC target, sorted by trigger name: */
+
+/*!< External triggers of injected group for ADC1&ADC2 only */
+#define ADC_EXTERNALTRIGINJECCONV_T2_TRGO ADC1_2_EXTERNALTRIGINJEC_T2_TRGO
+#define ADC_EXTERNALTRIGINJECCONV_T2_CC1 ADC1_2_EXTERNALTRIGINJEC_T2_CC1
+#define ADC_EXTERNALTRIGINJECCONV_T3_CC4 ADC1_2_EXTERNALTRIGINJEC_T3_CC4
+#define ADC_EXTERNALTRIGINJECCONV_T4_TRGO ADC1_2_EXTERNALTRIGINJEC_T4_TRGO
+#define ADC_EXTERNALTRIGINJECCONV_EXT_IT15 ADC1_2_EXTERNALTRIGINJEC_EXT_IT15
+
+#if defined (STM32F103xE) || defined (STM32F103xG)
+/*!< External triggers of injected group for ADC3 only */
+#define ADC_EXTERNALTRIGINJECCONV_T4_CC3 ADC3_EXTERNALTRIGINJEC_T4_CC3
+#define ADC_EXTERNALTRIGINJECCONV_T8_CC2 ADC3_EXTERNALTRIGINJEC_T8_CC2
+#define ADC_EXTERNALTRIGINJECCONV_T5_TRGO ADC3_EXTERNALTRIGINJEC_T5_TRGO
+#define ADC_EXTERNALTRIGINJECCONV_T5_CC4 ADC3_EXTERNALTRIGINJEC_T5_CC4
+#endif /* STM32F103xE || defined STM32F103xG */
+
+/*!< External triggers of injected group for all ADC instances */
+#define ADC_EXTERNALTRIGINJECCONV_T1_CC4 ADC1_2_3_EXTERNALTRIGINJEC_T1_CC4
+#define ADC_EXTERNALTRIGINJECCONV_T1_TRGO ADC1_2_3_EXTERNALTRIGINJEC_T1_TRGO
+
+#if defined (STM32F101xE) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC)
+/*!< Note: TIM8_CC4 is available on ADC1 and ADC2 only in high-density and */
+/* XL-density devices. */
+/* To use it on ADC1 or ADC2, a remap of trigger must be done from */
+/* EXTI line 11 to TIM8_CC4 with macro: */
+/* __HAL_AFIO_REMAP_ADC1_ETRGINJ_ENABLE() */
+/* __HAL_AFIO_REMAP_ADC2_ETRGINJ_ENABLE() */
+
+/* Note for internal constant value management: If TIM8_CC4 is available, */
+/* its definition is set to value for ADC1&ADC2 by default and changed to */
+/* value for ADC3 by HAL ADC driver if ADC3 is selected. */
+#define ADC_EXTERNALTRIGINJECCONV_T8_CC4 ADC1_2_EXTERNALTRIGINJEC_T8_CC4
+#endif /* STM32F101xE || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
+
+#define ADC_INJECTED_SOFTWARE_START ADC1_2_3_JSWSTART
+/**
+ * @}
+ */
+
+#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
+/** @defgroup ADCEx_Common_mode ADC Extended Dual ADC Mode
+ * @{
+ */
+#define ADC_MODE_INDEPENDENT 0x00000000U /*!< ADC dual mode disabled (ADC independent mode) */
+#define ADC_DUALMODE_REGSIMULT_INJECSIMULT ((uint32_t)( ADC_CR1_DUALMOD_0)) /*!< ADC dual mode enabled: Combined regular simultaneous + injected simultaneous mode, on groups regular and injected */
+#define ADC_DUALMODE_REGSIMULT_ALTERTRIG ((uint32_t)( ADC_CR1_DUALMOD_1 )) /*!< ADC dual mode enabled: Combined regular simultaneous + alternate trigger mode, on groups regular and injected */
+#define ADC_DUALMODE_INJECSIMULT_INTERLFAST ((uint32_t)( ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0)) /*!< ADC dual mode enabled: Combined injected simultaneous + fast interleaved mode, on groups regular and injected (delay between ADC sampling phases: 7 ADC clock cycles (equivalent to parameter "TwoSamplingDelay" set to "ADC_TWOSAMPLINGDELAY_7CYCLES" on other STM32 devices)) */
+#define ADC_DUALMODE_INJECSIMULT_INTERLSLOW ((uint32_t)( ADC_CR1_DUALMOD_2 )) /*!< ADC dual mode enabled: Combined injected simultaneous + slow Interleaved mode, on groups regular and injected (delay between ADC sampling phases: 14 ADC clock cycles (equivalent to parameter "TwoSamplingDelay" set to "ADC_TWOSAMPLINGDELAY_7CYCLES" on other STM32 devices)) */
+#define ADC_DUALMODE_INJECSIMULT ((uint32_t)( ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_0)) /*!< ADC dual mode enabled: Injected simultaneous mode, on group injected */
+#define ADC_DUALMODE_REGSIMULT ((uint32_t)( ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 )) /*!< ADC dual mode enabled: Regular simultaneous mode, on group regular */
+#define ADC_DUALMODE_INTERLFAST ((uint32_t)( ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0)) /*!< ADC dual mode enabled: Fast interleaved mode, on group regular (delay between ADC sampling phases: 7 ADC clock cycles (equivalent to parameter "TwoSamplingDelay" set to "ADC_TWOSAMPLINGDELAY_7CYCLES" on other STM32 devices)) */
+#define ADC_DUALMODE_INTERLSLOW ((uint32_t)(ADC_CR1_DUALMOD_3 )) /*!< ADC dual mode enabled: Slow interleaved mode, on group regular (delay between ADC sampling phases: 14 ADC clock cycles (equivalent to parameter "TwoSamplingDelay" set to "ADC_TWOSAMPLINGDELAY_7CYCLES" on other STM32 devices)) */
+#define ADC_DUALMODE_ALTERTRIG ((uint32_t)(ADC_CR1_DUALMOD_3 | ADC_CR1_DUALMOD_0)) /*!< ADC dual mode enabled: Alternate trigger mode, on group injected */
+/**
+ * @}
+ */
+#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
+
+/**
+ * @}
+ */
+
+
+/* Private constants ---------------------------------------------------------*/
+
+/** @addtogroup ADCEx_Private_Constants ADCEx Private Constants
+ * @{
+ */
+
+/** @defgroup ADCEx_Internal_HAL_driver_Ext_trig_src_Regular ADC Extended Internal HAL driver trigger selection for regular group
+ * @{
+ */
+/* List of external triggers of regular group for ADC1, ADC2, ADC3 (if ADC */
+/* instance is available on the selected device). */
+/* (used internally by HAL driver. To not use into HAL structure parameters) */
+
+/* External triggers of regular group for ADC1&ADC2 (if ADCx available) */
+#define ADC1_2_EXTERNALTRIG_T1_CC1 0x00000000U
+#define ADC1_2_EXTERNALTRIG_T1_CC2 ((uint32_t)( ADC_CR2_EXTSEL_0))
+#define ADC1_2_EXTERNALTRIG_T2_CC2 ((uint32_t)( ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0))
+#define ADC1_2_EXTERNALTRIG_T3_TRGO ((uint32_t)(ADC_CR2_EXTSEL_2 ))
+#define ADC1_2_EXTERNALTRIG_T4_CC4 ((uint32_t)(ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_0))
+#define ADC1_2_EXTERNALTRIG_EXT_IT11 ((uint32_t)(ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1 ))
+#if defined (STM32F101xE) || defined (STM32F103xE) || defined (STM32F103xG)
+/* Note: TIM8_TRGO is available on ADC1 and ADC2 only in high-density and */
+/* XL-density devices. */
+#define ADC1_2_EXTERNALTRIG_T8_TRGO ADC1_2_EXTERNALTRIG_EXT_IT11
+#endif
+
+#if defined (STM32F103xE) || defined (STM32F103xG)
+/* External triggers of regular group for ADC3 */
+#define ADC3_EXTERNALTRIG_T3_CC1 ADC1_2_EXTERNALTRIG_T1_CC1
+#define ADC3_EXTERNALTRIG_T2_CC3 ADC1_2_EXTERNALTRIG_T1_CC2
+#define ADC3_EXTERNALTRIG_T8_CC1 ADC1_2_EXTERNALTRIG_T2_CC2
+#define ADC3_EXTERNALTRIG_T8_TRGO ADC1_2_EXTERNALTRIG_T3_TRGO
+#define ADC3_EXTERNALTRIG_T5_CC1 ADC1_2_EXTERNALTRIG_T4_CC4
+#define ADC3_EXTERNALTRIG_T5_CC3 ADC1_2_EXTERNALTRIG_EXT_IT11
+#endif
+
+/* External triggers of regular group for ADC1&ADC2&ADC3 (if ADCx available) */
+#define ADC1_2_3_EXTERNALTRIG_T1_CC3 ((uint32_t)( ADC_CR2_EXTSEL_1 ))
+#define ADC1_2_3_SWSTART ((uint32_t)(ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0))
+/**
+ * @}
+ */
+
+/** @defgroup ADCEx_Internal_HAL_driver_Ext_trig_src_Injected ADC Extended Internal HAL driver trigger selection for injected group
+ * @{
+ */
+/* List of external triggers of injected group for ADC1, ADC2, ADC3 (if ADC */
+/* instance is available on the selected device). */
+/* (used internally by HAL driver. To not use into HAL structure parameters) */
+
+/* External triggers of injected group for ADC1&ADC2 (if ADCx available) */
+#define ADC1_2_EXTERNALTRIGINJEC_T2_TRGO ((uint32_t)( ADC_CR2_JEXTSEL_1 ))
+#define ADC1_2_EXTERNALTRIGINJEC_T2_CC1 ((uint32_t)( ADC_CR2_JEXTSEL_1 | ADC_CR2_JEXTSEL_0))
+#define ADC1_2_EXTERNALTRIGINJEC_T3_CC4 ((uint32_t)(ADC_CR2_JEXTSEL_2 ))
+#define ADC1_2_EXTERNALTRIGINJEC_T4_TRGO ((uint32_t)(ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_0))
+#define ADC1_2_EXTERNALTRIGINJEC_EXT_IT15 ((uint32_t)(ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_1 ))
+#if defined (STM32F101xE) || defined (STM32F103xE) || defined (STM32F103xG)
+/* Note: TIM8_CC4 is available on ADC1 and ADC2 only in high-density and */
+/* XL-density devices. */
+#define ADC1_2_EXTERNALTRIGINJEC_T8_CC4 ADC1_2_EXTERNALTRIGINJEC_EXT_IT15
+#endif
+
+#if defined (STM32F103xE) || defined (STM32F103xG)
+/* External triggers of injected group for ADC3 */
+#define ADC3_EXTERNALTRIGINJEC_T4_CC3 ADC1_2_EXTERNALTRIGINJEC_T2_TRGO
+#define ADC3_EXTERNALTRIGINJEC_T8_CC2 ADC1_2_EXTERNALTRIGINJEC_T2_CC1
+#define ADC3_EXTERNALTRIGINJEC_T8_CC4 ADC1_2_EXTERNALTRIGINJEC_T3_CC4
+#define ADC3_EXTERNALTRIGINJEC_T5_TRGO ADC1_2_EXTERNALTRIGINJEC_T4_TRGO
+#define ADC3_EXTERNALTRIGINJEC_T5_CC4 ADC1_2_EXTERNALTRIGINJEC_EXT_IT15
+#endif /* STM32F103xE || defined STM32F103xG */
+
+/* External triggers of injected group for ADC1&ADC2&ADC3 (if ADCx available) */
+#define ADC1_2_3_EXTERNALTRIGINJEC_T1_TRGO 0x00000000U
+#define ADC1_2_3_EXTERNALTRIGINJEC_T1_CC4 ((uint32_t)( ADC_CR2_JEXTSEL_0))
+#define ADC1_2_3_JSWSTART ((uint32_t)(ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_1 | ADC_CR2_JEXTSEL_0))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/* Exported macro ------------------------------------------------------------*/
+
+/* Private macro -------------------------------------------------------------*/
+
+/** @defgroup ADCEx_Private_Macro ADCEx Private Macro
+ * @{
+ */
+/* Macro reserved for internal HAL driver usage, not intended to be used in */
+/* code of final user. */
+
+
+/**
+ * @brief For devices with 3 ADCs: Defines the external trigger source
+ * for regular group according to ADC into common group ADC1&ADC2 or
+ * ADC3 (some triggers with same source have different value to
+ * be programmed into ADC EXTSEL bits of CR2 register).
+ * For devices with 2 ADCs or less: this macro makes no change.
+ * @param __HANDLE__: ADC handle
+ * @param __EXT_TRIG_CONV__: External trigger selected for regular group.
+ * @retval External trigger to be programmed into EXTSEL bits of CR2 register
+ */
+#if defined (STM32F103xE) || defined (STM32F103xG)
+#define ADC_CFGR_EXTSEL(__HANDLE__, __EXT_TRIG_CONV__) \
+ (( (((__HANDLE__)->Instance) == ADC3) \
+ )? \
+ ( ( (__EXT_TRIG_CONV__) == ADC_EXTERNALTRIGCONV_T8_TRGO \
+ )? \
+ (ADC3_EXTERNALTRIG_T8_TRGO) \
+ : \
+ (__EXT_TRIG_CONV__) \
+ ) \
+ : \
+ (__EXT_TRIG_CONV__) \
+ )
+#else
+#define ADC_CFGR_EXTSEL(__HANDLE__, __EXT_TRIG_CONV__) \
+ (__EXT_TRIG_CONV__)
+#endif /* STM32F103xE || STM32F103xG */
+
+/**
+ * @brief For devices with 3 ADCs: Defines the external trigger source
+ * for injected group according to ADC into common group ADC1&ADC2 or
+ * ADC3 (some triggers with same source have different value to
+ * be programmed into ADC JEXTSEL bits of CR2 register).
+ * For devices with 2 ADCs or less: this macro makes no change.
+ * @param __HANDLE__: ADC handle
+ * @param __EXT_TRIG_INJECTCONV__: External trigger selected for injected group.
+ * @retval External trigger to be programmed into JEXTSEL bits of CR2 register
+ */
+#if defined (STM32F103xE) || defined (STM32F103xG)
+#define ADC_CFGR_JEXTSEL(__HANDLE__, __EXT_TRIG_INJECTCONV__) \
+ (( (((__HANDLE__)->Instance) == ADC3) \
+ )? \
+ ( ( (__EXT_TRIG_INJECTCONV__) == ADC_EXTERNALTRIGINJECCONV_T8_CC4 \
+ )? \
+ (ADC3_EXTERNALTRIGINJEC_T8_CC4) \
+ : \
+ (__EXT_TRIG_INJECTCONV__) \
+ ) \
+ : \
+ (__EXT_TRIG_INJECTCONV__) \
+ )
+#else
+#define ADC_CFGR_JEXTSEL(__HANDLE__, __EXT_TRIG_INJECTCONV__) \
+ (__EXT_TRIG_INJECTCONV__)
+#endif /* STM32F103xE || STM32F103xG */
+
+
+/**
+ * @brief Verification if multimode is enabled for the selected ADC (multimode ADC master or ADC slave) (applicable for devices with several ADCs)
+ * @param __HANDLE__: ADC handle
+ * @retval Multimode state: RESET if multimode is disabled, other value if multimode is enabled
+ */
+#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
+#define ADC_MULTIMODE_IS_ENABLE(__HANDLE__) \
+ (( (((__HANDLE__)->Instance) == ADC1) || (((__HANDLE__)->Instance) == ADC2) \
+ )? \
+ (ADC1->CR1 & ADC_CR1_DUALMOD) \
+ : \
+ (RESET) \
+ )
+#else
+#define ADC_MULTIMODE_IS_ENABLE(__HANDLE__) \
+ (RESET)
+#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
+
+/**
+ * @brief Verification of condition for ADC start conversion: ADC must be in non-multimode, or multimode with handle of ADC master (applicable for devices with several ADCs)
+ * @param __HANDLE__: ADC handle
+ * @retval None
+ */
+#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
+#define ADC_NONMULTIMODE_OR_MULTIMODEMASTER(__HANDLE__) \
+ (( (((__HANDLE__)->Instance) == ADC2) \
+ )? \
+ ((ADC1->CR1 & ADC_CR1_DUALMOD) == RESET) \
+ : \
+ (!RESET) \
+ )
+#else
+#define ADC_NONMULTIMODE_OR_MULTIMODEMASTER(__HANDLE__) \
+ (!RESET)
+#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
+
+/**
+ * @brief Check ADC multimode setting: In case of multimode, check whether ADC master of the selected ADC has feature auto-injection enabled (applicable for devices with several ADCs)
+ * @param __HANDLE__: ADC handle
+ * @retval None
+ */
+#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
+#define ADC_MULTIMODE_AUTO_INJECTED(__HANDLE__) \
+ (( (((__HANDLE__)->Instance) == ADC1) || (((__HANDLE__)->Instance) == ADC2) \
+ )? \
+ (ADC1->CR1 & ADC_CR1_JAUTO) \
+ : \
+ (RESET) \
+ )
+#else
+#define ADC_MULTIMODE_AUTO_INJECTED(__HANDLE__) \
+ (RESET)
+#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
+
+#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
+/**
+ * @brief Set handle of the other ADC sharing the common multimode settings
+ * @param __HANDLE__: ADC handle
+ * @param __HANDLE_OTHER_ADC__: other ADC handle
+ * @retval None
+ */
+#define ADC_COMMON_ADC_OTHER(__HANDLE__, __HANDLE_OTHER_ADC__) \
+ ((__HANDLE_OTHER_ADC__)->Instance = ADC2)
+
+/**
+ * @brief Set handle of the ADC slave associated to the ADC master
+ * On STM32F1 devices, ADC slave is always ADC2 (this can be different
+ * on other STM32 devices)
+ * @param __HANDLE_MASTER__: ADC master handle
+ * @param __HANDLE_SLAVE__: ADC slave handle
+ * @retval None
+ */
+#define ADC_MULTI_SLAVE(__HANDLE_MASTER__, __HANDLE_SLAVE__) \
+ ((__HANDLE_SLAVE__)->Instance = ADC2)
+
+#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
+
+#define IS_ADC_INJECTED_RANK(CHANNEL) (((CHANNEL) == ADC_INJECTED_RANK_1) || \
+ ((CHANNEL) == ADC_INJECTED_RANK_2) || \
+ ((CHANNEL) == ADC_INJECTED_RANK_3) || \
+ ((CHANNEL) == ADC_INJECTED_RANK_4))
+
+#define IS_ADC_EXTTRIGINJEC_EDGE(EDGE) (((EDGE) == ADC_EXTERNALTRIGINJECCONV_EDGE_NONE) || \
+ ((EDGE) == ADC_EXTERNALTRIGINJECCONV_EDGE_RISING))
+
+/** @defgroup ADCEx_injected_nb_conv_verification ADCEx injected nb conv verification
+ * @{
+ */
+#define IS_ADC_INJECTED_NB_CONV(LENGTH) (((LENGTH) >= 1U) && ((LENGTH) <= 4U))
+/**
+ * @}
+ */
+
+#if defined (STM32F100xB) || defined (STM32F100xE) || defined (STM32F101x6) || defined (STM32F101xB) || defined (STM32F102x6) || defined (STM32F102xB) || defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC)
+#define IS_ADC_EXTTRIG(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC1) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC2) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC2) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_TRGO) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T4_CC4) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_EXT_IT11) || \
+ ((REGTRIG) == ADC_SOFTWARE_START))
+#endif
+#if defined (STM32F101xE)
+#define IS_ADC_EXTTRIG(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC1) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC2) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC2) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_TRGO) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T4_CC4) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_EXT_IT11) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T8_TRGO) || \
+ ((REGTRIG) == ADC_SOFTWARE_START))
+#endif
+#if defined (STM32F101xG)
+#define IS_ADC_EXTTRIG(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC1) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC2) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC2) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_TRGO) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T4_CC4) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_EXT_IT11) || \
+ ((REGTRIG) == ADC_SOFTWARE_START))
+#endif
+#if defined (STM32F103xE) || defined (STM32F103xG)
+#define IS_ADC_EXTTRIG(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC1) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC2) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC2) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_TRGO) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T4_CC4) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_EXT_IT11) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_CC1) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC3) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T8_CC1) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T5_CC1) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T5_CC3) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC3) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGCONV_T8_TRGO) || \
+ ((REGTRIG) == ADC_SOFTWARE_START))
+#endif
+
+#if defined (STM32F100xB) || defined (STM32F100xE) || defined (STM32F101x6) || defined (STM32F101xB) || defined (STM32F102x6) || defined (STM32F102xB) || defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC)
+#define IS_ADC_EXTTRIGINJEC(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_TRGO) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_CC1) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T3_CC4) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_TRGO) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_EXT_IT15) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_CC4) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_TRGO) || \
+ ((REGTRIG) == ADC_INJECTED_SOFTWARE_START))
+#endif
+#if defined (STM32F101xE)
+#define IS_ADC_EXTTRIGINJEC(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_TRGO) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_CC1) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T3_CC4) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_TRGO) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_EXT_IT15) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_CC4) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_TRGO) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T8_CC4) || \
+ ((REGTRIG) == ADC_INJECTED_SOFTWARE_START))
+#endif
+#if defined (STM32F101xG)
+#define IS_ADC_EXTTRIGINJEC(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_TRGO) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_CC1) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T3_CC4) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_TRGO) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_EXT_IT15) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_CC4) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_TRGO) || \
+ ((REGTRIG) == ADC_INJECTED_SOFTWARE_START))
+#endif
+#if defined (STM32F103xE) || defined (STM32F103xG)
+#define IS_ADC_EXTTRIGINJEC(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_TRGO) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_CC1) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T3_CC4) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_TRGO) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T5_CC4) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_EXT_IT15) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_CC3) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T8_CC2) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T5_TRGO) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T5_CC4) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_CC4) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_TRGO) || \
+ ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T8_CC4) || \
+ ((REGTRIG) == ADC_INJECTED_SOFTWARE_START))
+#endif
+
+#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
+#define IS_ADC_MODE(MODE) (((MODE) == ADC_MODE_INDEPENDENT) || \
+ ((MODE) == ADC_DUALMODE_REGSIMULT_INJECSIMULT) || \
+ ((MODE) == ADC_DUALMODE_REGSIMULT_ALTERTRIG) || \
+ ((MODE) == ADC_DUALMODE_INJECSIMULT_INTERLFAST) || \
+ ((MODE) == ADC_DUALMODE_INJECSIMULT_INTERLSLOW) || \
+ ((MODE) == ADC_DUALMODE_INJECSIMULT) || \
+ ((MODE) == ADC_DUALMODE_REGSIMULT) || \
+ ((MODE) == ADC_DUALMODE_INTERLFAST) || \
+ ((MODE) == ADC_DUALMODE_INTERLSLOW) || \
+ ((MODE) == ADC_DUALMODE_ALTERTRIG) )
+#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
+
+/**
+ * @}
+ */
+
+
+
+
+
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup ADCEx_Exported_Functions
+ * @{
+ */
+
+/* IO operation functions *****************************************************/
+/** @addtogroup ADCEx_Exported_Functions_Group1
+ * @{
+ */
+
+/* ADC calibration */
+HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc);
+
+/* Blocking mode: Polling */
+HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef* hadc);
+HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef* hadc);
+HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout);
+
+/* Non-blocking mode: Interruption */
+HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef* hadc);
+HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef* hadc);
+
+#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
+/* ADC multimode */
+HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, uint32_t Length);
+HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef *hadc);
+#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
+
+/* ADC retrieve conversion value intended to be used with polling or interruption */
+uint32_t HAL_ADCEx_InjectedGetValue(ADC_HandleTypeDef* hadc, uint32_t InjectedRank);
+#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
+uint32_t HAL_ADCEx_MultiModeGetValue(ADC_HandleTypeDef *hadc);
+#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
+
+/* ADC IRQHandler and Callbacks used in non-blocking modes (Interruption) */
+void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc);
+/**
+ * @}
+ */
+
+
+/* Peripheral Control functions ***********************************************/
+/** @addtogroup ADCEx_Exported_Functions_Group2
+ * @{
+ */
+HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc,ADC_InjectionConfTypeDef* sConfigInjected);
+#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
+HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef *hadc, ADC_MultiModeTypeDef *multimode);
+#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_ADC_EX_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_can.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_can.h
new file mode 100644
index 0000000..a33816c
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_can.h
@@ -0,0 +1,799 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_can.h
+ * @author MCD Application Team
+ * @brief Header file of CAN HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32F1xx_HAL_CAN_H
+#define STM32F1xx_HAL_CAN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#if defined (CAN1)
+/** @addtogroup CAN
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup CAN_Exported_Types CAN Exported Types
+ * @{
+ */
+/**
+ * @brief HAL State structures definition
+ */
+typedef enum
+{
+ HAL_CAN_STATE_RESET = 0x00U, /*!< CAN not yet initialized or disabled */
+ HAL_CAN_STATE_READY = 0x01U, /*!< CAN initialized and ready for use */
+ HAL_CAN_STATE_LISTENING = 0x02U, /*!< CAN receive process is ongoing */
+ HAL_CAN_STATE_SLEEP_PENDING = 0x03U, /*!< CAN sleep request is pending */
+ HAL_CAN_STATE_SLEEP_ACTIVE = 0x04U, /*!< CAN sleep mode is active */
+ HAL_CAN_STATE_ERROR = 0x05U /*!< CAN error state */
+
+} HAL_CAN_StateTypeDef;
+
+/**
+ * @brief CAN init structure definition
+ */
+typedef struct
+{
+ uint32_t Prescaler; /*!< Specifies the length of a time quantum.
+ This parameter must be a number between Min_Data = 1 and Max_Data = 1024. */
+
+ uint32_t Mode; /*!< Specifies the CAN operating mode.
+ This parameter can be a value of @ref CAN_operating_mode */
+
+ uint32_t SyncJumpWidth; /*!< Specifies the maximum number of time quanta the CAN hardware
+ is allowed to lengthen or shorten a bit to perform resynchronization.
+ This parameter can be a value of @ref CAN_synchronisation_jump_width */
+
+ uint32_t TimeSeg1; /*!< Specifies the number of time quanta in Bit Segment 1.
+ This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_1 */
+
+ uint32_t TimeSeg2; /*!< Specifies the number of time quanta in Bit Segment 2.
+ This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_2 */
+
+ FunctionalState TimeTriggeredMode; /*!< Enable or disable the time triggered communication mode.
+ This parameter can be set to ENABLE or DISABLE. */
+
+ FunctionalState AutoBusOff; /*!< Enable or disable the automatic bus-off management.
+ This parameter can be set to ENABLE or DISABLE. */
+
+ FunctionalState AutoWakeUp; /*!< Enable or disable the automatic wake-up mode.
+ This parameter can be set to ENABLE or DISABLE. */
+
+ FunctionalState AutoRetransmission; /*!< Enable or disable the non-automatic retransmission mode.
+ This parameter can be set to ENABLE or DISABLE. */
+
+ FunctionalState ReceiveFifoLocked; /*!< Enable or disable the Receive FIFO Locked mode.
+ This parameter can be set to ENABLE or DISABLE. */
+
+ FunctionalState TransmitFifoPriority;/*!< Enable or disable the transmit FIFO priority.
+ This parameter can be set to ENABLE or DISABLE. */
+
+} CAN_InitTypeDef;
+
+/**
+ * @brief CAN filter configuration structure definition
+ */
+typedef struct
+{
+ uint32_t FilterIdHigh; /*!< Specifies the filter identification number (MSBs for a 32-bit
+ configuration, first one for a 16-bit configuration).
+ This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
+
+ uint32_t FilterIdLow; /*!< Specifies the filter identification number (LSBs for a 32-bit
+ configuration, second one for a 16-bit configuration).
+ This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
+
+ uint32_t FilterMaskIdHigh; /*!< Specifies the filter mask number or identification number,
+ according to the mode (MSBs for a 32-bit configuration,
+ first one for a 16-bit configuration).
+ This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
+
+ uint32_t FilterMaskIdLow; /*!< Specifies the filter mask number or identification number,
+ according to the mode (LSBs for a 32-bit configuration,
+ second one for a 16-bit configuration).
+ This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
+
+ uint32_t FilterFIFOAssignment; /*!< Specifies the FIFO (0 or 1U) which will be assigned to the filter.
+ This parameter can be a value of @ref CAN_filter_FIFO */
+
+ uint32_t FilterBank; /*!< Specifies the filter bank which will be initialized.
+ For single CAN instance(14 dedicated filter banks),
+ this parameter must be a number between Min_Data = 0 and Max_Data = 13.
+ For dual CAN instances(28 filter banks shared),
+ this parameter must be a number between Min_Data = 0 and Max_Data = 27. */
+
+ uint32_t FilterMode; /*!< Specifies the filter mode to be initialized.
+ This parameter can be a value of @ref CAN_filter_mode */
+
+ uint32_t FilterScale; /*!< Specifies the filter scale.
+ This parameter can be a value of @ref CAN_filter_scale */
+
+ uint32_t FilterActivation; /*!< Enable or disable the filter.
+ This parameter can be a value of @ref CAN_filter_activation */
+
+ uint32_t SlaveStartFilterBank; /*!< Select the start filter bank for the slave CAN instance.
+ For single CAN instances, this parameter is meaningless.
+ For dual CAN instances, all filter banks with lower index are assigned to master
+ CAN instance, whereas all filter banks with greater index are assigned to slave
+ CAN instance.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 27. */
+
+} CAN_FilterTypeDef;
+
+/**
+ * @brief CAN Tx message header structure definition
+ */
+typedef struct
+{
+ uint32_t StdId; /*!< Specifies the standard identifier.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF. */
+
+ uint32_t ExtId; /*!< Specifies the extended identifier.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF. */
+
+ uint32_t IDE; /*!< Specifies the type of identifier for the message that will be transmitted.
+ This parameter can be a value of @ref CAN_identifier_type */
+
+ uint32_t RTR; /*!< Specifies the type of frame for the message that will be transmitted.
+ This parameter can be a value of @ref CAN_remote_transmission_request */
+
+ uint32_t DLC; /*!< Specifies the length of the frame that will be transmitted.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 8. */
+
+ FunctionalState TransmitGlobalTime; /*!< Specifies whether the timestamp counter value captured on start
+ of frame transmission, is sent in DATA6 and DATA7 replacing pData[6] and pData[7].
+ @note: Time Triggered Communication Mode must be enabled.
+ @note: DLC must be programmed as 8 bytes, in order these 2 bytes are sent.
+ This parameter can be set to ENABLE or DISABLE. */
+
+} CAN_TxHeaderTypeDef;
+
+/**
+ * @brief CAN Rx message header structure definition
+ */
+typedef struct
+{
+ uint32_t StdId; /*!< Specifies the standard identifier.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF. */
+
+ uint32_t ExtId; /*!< Specifies the extended identifier.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF. */
+
+ uint32_t IDE; /*!< Specifies the type of identifier for the message that will be transmitted.
+ This parameter can be a value of @ref CAN_identifier_type */
+
+ uint32_t RTR; /*!< Specifies the type of frame for the message that will be transmitted.
+ This parameter can be a value of @ref CAN_remote_transmission_request */
+
+ uint32_t DLC; /*!< Specifies the length of the frame that will be transmitted.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 8. */
+
+ uint32_t Timestamp; /*!< Specifies the timestamp counter value captured on start of frame reception.
+ @note: Time Triggered Communication Mode must be enabled.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 0xFFFF. */
+
+ uint32_t FilterMatchIndex; /*!< Specifies the index of matching acceptance filter element.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF. */
+
+} CAN_RxHeaderTypeDef;
+
+/**
+ * @brief CAN handle Structure definition
+ */
+typedef struct __CAN_HandleTypeDef
+{
+ CAN_TypeDef *Instance; /*!< Register base address */
+
+ CAN_InitTypeDef Init; /*!< CAN required parameters */
+
+ __IO HAL_CAN_StateTypeDef State; /*!< CAN communication state */
+
+ __IO uint32_t ErrorCode; /*!< CAN Error code.
+ This parameter can be a value of @ref CAN_Error_Code */
+
+} CAN_HandleTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup CAN_Exported_Constants CAN Exported Constants
+ * @{
+ */
+
+/** @defgroup CAN_Error_Code CAN Error Code
+ * @{
+ */
+#define HAL_CAN_ERROR_NONE (0x00000000U) /*!< No error */
+#define HAL_CAN_ERROR_EWG (0x00000001U) /*!< Protocol Error Warning */
+#define HAL_CAN_ERROR_EPV (0x00000002U) /*!< Error Passive */
+#define HAL_CAN_ERROR_BOF (0x00000004U) /*!< Bus-off error */
+#define HAL_CAN_ERROR_STF (0x00000008U) /*!< Stuff error */
+#define HAL_CAN_ERROR_FOR (0x00000010U) /*!< Form error */
+#define HAL_CAN_ERROR_ACK (0x00000020U) /*!< Acknowledgment error */
+#define HAL_CAN_ERROR_BR (0x00000040U) /*!< Bit recessive error */
+#define HAL_CAN_ERROR_BD (0x00000080U) /*!< Bit dominant error */
+#define HAL_CAN_ERROR_CRC (0x00000100U) /*!< CRC error */
+#define HAL_CAN_ERROR_RX_FOV0 (0x00000200U) /*!< Rx FIFO0 overrun error */
+#define HAL_CAN_ERROR_RX_FOV1 (0x00000400U) /*!< Rx FIFO1 overrun error */
+#define HAL_CAN_ERROR_TX_ALST0 (0x00000800U) /*!< TxMailbox 0 transmit failure due to arbitration lost */
+#define HAL_CAN_ERROR_TX_TERR0 (0x00001000U) /*!< TxMailbox 1 transmit failure due to tranmit error */
+#define HAL_CAN_ERROR_TX_ALST1 (0x00002000U) /*!< TxMailbox 0 transmit failure due to arbitration lost */
+#define HAL_CAN_ERROR_TX_TERR1 (0x00004000U) /*!< TxMailbox 1 transmit failure due to tranmit error */
+#define HAL_CAN_ERROR_TX_ALST2 (0x00008000U) /*!< TxMailbox 0 transmit failure due to arbitration lost */
+#define HAL_CAN_ERROR_TX_TERR2 (0x00010000U) /*!< TxMailbox 1 transmit failure due to tranmit error */
+#define HAL_CAN_ERROR_TIMEOUT (0x00020000U) /*!< Timeout error */
+#define HAL_CAN_ERROR_NOT_INITIALIZED (0x00040000U) /*!< Peripheral not initialized */
+#define HAL_CAN_ERROR_NOT_READY (0x00080000U) /*!< Peripheral not ready */
+#define HAL_CAN_ERROR_NOT_STARTED (0x00100000U) /*!< Peripheral not started */
+#define HAL_CAN_ERROR_PARAM (0x00200000U) /*!< Parameter error */
+
+#define HAL_CAN_ERROR_INTERNAL (0x00800000U) /*!< Internal error */
+
+/**
+ * @}
+ */
+
+/** @defgroup CAN_InitStatus CAN InitStatus
+ * @{
+ */
+#define CAN_INITSTATUS_FAILED (0x00000000U) /*!< CAN initialization failed */
+#define CAN_INITSTATUS_SUCCESS (0x00000001U) /*!< CAN initialization OK */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_operating_mode CAN Operating Mode
+ * @{
+ */
+#define CAN_MODE_NORMAL (0x00000000U) /*!< Normal mode */
+#define CAN_MODE_LOOPBACK ((uint32_t)CAN_BTR_LBKM) /*!< Loopback mode */
+#define CAN_MODE_SILENT ((uint32_t)CAN_BTR_SILM) /*!< Silent mode */
+#define CAN_MODE_SILENT_LOOPBACK ((uint32_t)(CAN_BTR_LBKM | CAN_BTR_SILM)) /*!< Loopback combined with silent mode */
+/**
+ * @}
+ */
+
+
+/** @defgroup CAN_synchronisation_jump_width CAN Synchronization Jump Width
+ * @{
+ */
+#define CAN_SJW_1TQ (0x00000000U) /*!< 1 time quantum */
+#define CAN_SJW_2TQ ((uint32_t)CAN_BTR_SJW_0) /*!< 2 time quantum */
+#define CAN_SJW_3TQ ((uint32_t)CAN_BTR_SJW_1) /*!< 3 time quantum */
+#define CAN_SJW_4TQ ((uint32_t)CAN_BTR_SJW) /*!< 4 time quantum */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_time_quantum_in_bit_segment_1 CAN Time Quantum in Bit Segment 1
+ * @{
+ */
+#define CAN_BS1_1TQ (0x00000000U) /*!< 1 time quantum */
+#define CAN_BS1_2TQ ((uint32_t)CAN_BTR_TS1_0) /*!< 2 time quantum */
+#define CAN_BS1_3TQ ((uint32_t)CAN_BTR_TS1_1) /*!< 3 time quantum */
+#define CAN_BS1_4TQ ((uint32_t)(CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 4 time quantum */
+#define CAN_BS1_5TQ ((uint32_t)CAN_BTR_TS1_2) /*!< 5 time quantum */
+#define CAN_BS1_6TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_0)) /*!< 6 time quantum */
+#define CAN_BS1_7TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_1)) /*!< 7 time quantum */
+#define CAN_BS1_8TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 8 time quantum */
+#define CAN_BS1_9TQ ((uint32_t)CAN_BTR_TS1_3) /*!< 9 time quantum */
+#define CAN_BS1_10TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_0)) /*!< 10 time quantum */
+#define CAN_BS1_11TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_1)) /*!< 11 time quantum */
+#define CAN_BS1_12TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 12 time quantum */
+#define CAN_BS1_13TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2)) /*!< 13 time quantum */
+#define CAN_BS1_14TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2 | CAN_BTR_TS1_0)) /*!< 14 time quantum */
+#define CAN_BS1_15TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2 | CAN_BTR_TS1_1)) /*!< 15 time quantum */
+#define CAN_BS1_16TQ ((uint32_t)CAN_BTR_TS1) /*!< 16 time quantum */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_time_quantum_in_bit_segment_2 CAN Time Quantum in Bit Segment 2
+ * @{
+ */
+#define CAN_BS2_1TQ (0x00000000U) /*!< 1 time quantum */
+#define CAN_BS2_2TQ ((uint32_t)CAN_BTR_TS2_0) /*!< 2 time quantum */
+#define CAN_BS2_3TQ ((uint32_t)CAN_BTR_TS2_1) /*!< 3 time quantum */
+#define CAN_BS2_4TQ ((uint32_t)(CAN_BTR_TS2_1 | CAN_BTR_TS2_0)) /*!< 4 time quantum */
+#define CAN_BS2_5TQ ((uint32_t)CAN_BTR_TS2_2) /*!< 5 time quantum */
+#define CAN_BS2_6TQ ((uint32_t)(CAN_BTR_TS2_2 | CAN_BTR_TS2_0)) /*!< 6 time quantum */
+#define CAN_BS2_7TQ ((uint32_t)(CAN_BTR_TS2_2 | CAN_BTR_TS2_1)) /*!< 7 time quantum */
+#define CAN_BS2_8TQ ((uint32_t)CAN_BTR_TS2) /*!< 8 time quantum */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_filter_mode CAN Filter Mode
+ * @{
+ */
+#define CAN_FILTERMODE_IDMASK (0x00000000U) /*!< Identifier mask mode */
+#define CAN_FILTERMODE_IDLIST (0x00000001U) /*!< Identifier list mode */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_filter_scale CAN Filter Scale
+ * @{
+ */
+#define CAN_FILTERSCALE_16BIT (0x00000000U) /*!< Two 16-bit filters */
+#define CAN_FILTERSCALE_32BIT (0x00000001U) /*!< One 32-bit filter */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_filter_activation CAN Filter Activation
+ * @{
+ */
+#define CAN_FILTER_DISABLE (0x00000000U) /*!< Disable filter */
+#define CAN_FILTER_ENABLE (0x00000001U) /*!< Enable filter */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_filter_FIFO CAN Filter FIFO
+ * @{
+ */
+#define CAN_FILTER_FIFO0 (0x00000000U) /*!< Filter FIFO 0 assignment for filter x */
+#define CAN_FILTER_FIFO1 (0x00000001U) /*!< Filter FIFO 1 assignment for filter x */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_identifier_type CAN Identifier Type
+ * @{
+ */
+#define CAN_ID_STD (0x00000000U) /*!< Standard Id */
+#define CAN_ID_EXT (0x00000004U) /*!< Extended Id */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_remote_transmission_request CAN Remote Transmission Request
+ * @{
+ */
+#define CAN_RTR_DATA (0x00000000U) /*!< Data frame */
+#define CAN_RTR_REMOTE (0x00000002U) /*!< Remote frame */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_receive_FIFO_number CAN Receive FIFO Number
+ * @{
+ */
+#define CAN_RX_FIFO0 (0x00000000U) /*!< CAN receive FIFO 0 */
+#define CAN_RX_FIFO1 (0x00000001U) /*!< CAN receive FIFO 1 */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_Tx_Mailboxes CAN Tx Mailboxes
+ * @{
+ */
+#define CAN_TX_MAILBOX0 (0x00000001U) /*!< Tx Mailbox 0 */
+#define CAN_TX_MAILBOX1 (0x00000002U) /*!< Tx Mailbox 1 */
+#define CAN_TX_MAILBOX2 (0x00000004U) /*!< Tx Mailbox 2 */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_flags CAN Flags
+ * @{
+ */
+/* Transmit Flags */
+#define CAN_FLAG_RQCP0 (0x00000500U) /*!< Request complete MailBox 0 flag */
+#define CAN_FLAG_TXOK0 (0x00000501U) /*!< Transmission OK MailBox 0 flag */
+#define CAN_FLAG_ALST0 (0x00000502U) /*!< Arbitration Lost MailBox 0 flag */
+#define CAN_FLAG_TERR0 (0x00000503U) /*!< Transmission error MailBox 0 flag */
+#define CAN_FLAG_RQCP1 (0x00000508U) /*!< Request complete MailBox1 flag */
+#define CAN_FLAG_TXOK1 (0x00000509U) /*!< Transmission OK MailBox 1 flag */
+#define CAN_FLAG_ALST1 (0x0000050AU) /*!< Arbitration Lost MailBox 1 flag */
+#define CAN_FLAG_TERR1 (0x0000050BU) /*!< Transmission error MailBox 1 flag */
+#define CAN_FLAG_RQCP2 (0x00000510U) /*!< Request complete MailBox2 flag */
+#define CAN_FLAG_TXOK2 (0x00000511U) /*!< Transmission OK MailBox 2 flag */
+#define CAN_FLAG_ALST2 (0x00000512U) /*!< Arbitration Lost MailBox 2 flag */
+#define CAN_FLAG_TERR2 (0x00000513U) /*!< Transmission error MailBox 2 flag */
+#define CAN_FLAG_TME0 (0x0000051AU) /*!< Transmit mailbox 0 empty flag */
+#define CAN_FLAG_TME1 (0x0000051BU) /*!< Transmit mailbox 1 empty flag */
+#define CAN_FLAG_TME2 (0x0000051CU) /*!< Transmit mailbox 2 empty flag */
+#define CAN_FLAG_LOW0 (0x0000051DU) /*!< Lowest priority mailbox 0 flag */
+#define CAN_FLAG_LOW1 (0x0000051EU) /*!< Lowest priority mailbox 1 flag */
+#define CAN_FLAG_LOW2 (0x0000051FU) /*!< Lowest priority mailbox 2 flag */
+
+/* Receive Flags */
+#define CAN_FLAG_FF0 (0x00000203U) /*!< RX FIFO 0 Full flag */
+#define CAN_FLAG_FOV0 (0x00000204U) /*!< RX FIFO 0 Overrun flag */
+#define CAN_FLAG_FF1 (0x00000403U) /*!< RX FIFO 1 Full flag */
+#define CAN_FLAG_FOV1 (0x00000404U) /*!< RX FIFO 1 Overrun flag */
+
+/* Operating Mode Flags */
+#define CAN_FLAG_INAK (0x00000100U) /*!< Initialization acknowledge flag */
+#define CAN_FLAG_SLAK (0x00000101U) /*!< Sleep acknowledge flag */
+#define CAN_FLAG_ERRI (0x00000102U) /*!< Error flag */
+#define CAN_FLAG_WKU (0x00000103U) /*!< Wake up interrupt flag */
+#define CAN_FLAG_SLAKI (0x00000104U) /*!< Sleep acknowledge interrupt flag */
+
+/* Error Flags */
+#define CAN_FLAG_EWG (0x00000300U) /*!< Error warning flag */
+#define CAN_FLAG_EPV (0x00000301U) /*!< Error passive flag */
+#define CAN_FLAG_BOF (0x00000302U) /*!< Bus-Off flag */
+/**
+ * @}
+ */
+
+
+/** @defgroup CAN_Interrupts CAN Interrupts
+ * @{
+ */
+/* Transmit Interrupt */
+#define CAN_IT_TX_MAILBOX_EMPTY ((uint32_t)CAN_IER_TMEIE) /*!< Transmit mailbox empty interrupt */
+
+/* Receive Interrupts */
+#define CAN_IT_RX_FIFO0_MSG_PENDING ((uint32_t)CAN_IER_FMPIE0) /*!< FIFO 0 message pending interrupt */
+#define CAN_IT_RX_FIFO0_FULL ((uint32_t)CAN_IER_FFIE0) /*!< FIFO 0 full interrupt */
+#define CAN_IT_RX_FIFO0_OVERRUN ((uint32_t)CAN_IER_FOVIE0) /*!< FIFO 0 overrun interrupt */
+#define CAN_IT_RX_FIFO1_MSG_PENDING ((uint32_t)CAN_IER_FMPIE1) /*!< FIFO 1 message pending interrupt */
+#define CAN_IT_RX_FIFO1_FULL ((uint32_t)CAN_IER_FFIE1) /*!< FIFO 1 full interrupt */
+#define CAN_IT_RX_FIFO1_OVERRUN ((uint32_t)CAN_IER_FOVIE1) /*!< FIFO 1 overrun interrupt */
+
+/* Operating Mode Interrupts */
+#define CAN_IT_WAKEUP ((uint32_t)CAN_IER_WKUIE) /*!< Wake-up interrupt */
+#define CAN_IT_SLEEP_ACK ((uint32_t)CAN_IER_SLKIE) /*!< Sleep acknowledge interrupt */
+
+/* Error Interrupts */
+#define CAN_IT_ERROR_WARNING ((uint32_t)CAN_IER_EWGIE) /*!< Error warning interrupt */
+#define CAN_IT_ERROR_PASSIVE ((uint32_t)CAN_IER_EPVIE) /*!< Error passive interrupt */
+#define CAN_IT_BUSOFF ((uint32_t)CAN_IER_BOFIE) /*!< Bus-off interrupt */
+#define CAN_IT_LAST_ERROR_CODE ((uint32_t)CAN_IER_LECIE) /*!< Last error code interrupt */
+#define CAN_IT_ERROR ((uint32_t)CAN_IER_ERRIE) /*!< Error Interrupt */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macros -----------------------------------------------------------*/
+/** @defgroup CAN_Exported_Macros CAN Exported Macros
+ * @{
+ */
+
+/** @brief Reset CAN handle state
+ * @param __HANDLE__ CAN handle.
+ * @retval None
+ */
+#define __HAL_CAN_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_CAN_STATE_RESET)
+
+/**
+ * @brief Enable the specified CAN interrupts.
+ * @param __HANDLE__ CAN handle.
+ * @param __INTERRUPT__ CAN Interrupt sources to enable.
+ * This parameter can be any combination of @arg CAN_Interrupts
+ * @retval None
+ */
+#define __HAL_CAN_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) |= (__INTERRUPT__))
+
+/**
+ * @brief Disable the specified CAN interrupts.
+ * @param __HANDLE__ CAN handle.
+ * @param __INTERRUPT__ CAN Interrupt sources to disable.
+ * This parameter can be any combination of @arg CAN_Interrupts
+ * @retval None
+ */
+#define __HAL_CAN_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) &= ~(__INTERRUPT__))
+
+/** @brief Check if the specified CAN interrupt source is enabled or disabled.
+ * @param __HANDLE__ specifies the CAN Handle.
+ * @param __INTERRUPT__ specifies the CAN interrupt source to check.
+ * This parameter can be a value of @arg CAN_Interrupts
+ * @retval The state of __IT__ (TRUE or FALSE).
+ */
+#define __HAL_CAN_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) & (__INTERRUPT__))
+
+/** @brief Check whether the specified CAN flag is set or not.
+ * @param __HANDLE__ specifies the CAN Handle.
+ * @param __FLAG__ specifies the flag to check.
+ * This parameter can be one of @arg CAN_flags
+ * @retval The state of __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_CAN_GET_FLAG(__HANDLE__, __FLAG__) \
+ ((((__FLAG__) >> 8U) == 5U)? ((((__HANDLE__)->Instance->TSR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
+ (((__FLAG__) >> 8U) == 2U)? ((((__HANDLE__)->Instance->RF0R) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
+ (((__FLAG__) >> 8U) == 4U)? ((((__HANDLE__)->Instance->RF1R) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
+ (((__FLAG__) >> 8U) == 1U)? ((((__HANDLE__)->Instance->MSR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
+ (((__FLAG__) >> 8U) == 3U)? ((((__HANDLE__)->Instance->ESR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): 0U)
+
+/** @brief Clear the specified CAN pending flag.
+ * @param __HANDLE__ specifies the CAN Handle.
+ * @param __FLAG__ specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg CAN_FLAG_RQCP0: Request complete MailBox 0 Flag
+ * @arg CAN_FLAG_TXOK0: Transmission OK MailBox 0 Flag
+ * @arg CAN_FLAG_ALST0: Arbitration Lost MailBox 0 Flag
+ * @arg CAN_FLAG_TERR0: Transmission error MailBox 0 Flag
+ * @arg CAN_FLAG_RQCP1: Request complete MailBox 1 Flag
+ * @arg CAN_FLAG_TXOK1: Transmission OK MailBox 1 Flag
+ * @arg CAN_FLAG_ALST1: Arbitration Lost MailBox 1 Flag
+ * @arg CAN_FLAG_TERR1: Transmission error MailBox 1 Flag
+ * @arg CAN_FLAG_RQCP2: Request complete MailBox 2 Flag
+ * @arg CAN_FLAG_TXOK2: Transmission OK MailBox 2 Flag
+ * @arg CAN_FLAG_ALST2: Arbitration Lost MailBox 2 Flag
+ * @arg CAN_FLAG_TERR2: Transmission error MailBox 2 Flag
+ * @arg CAN_FLAG_FF0: RX FIFO 0 Full Flag
+ * @arg CAN_FLAG_FOV0: RX FIFO 0 Overrun Flag
+ * @arg CAN_FLAG_FF1: RX FIFO 1 Full Flag
+ * @arg CAN_FLAG_FOV1: RX FIFO 1 Overrun Flag
+ * @arg CAN_FLAG_WKUI: Wake up Interrupt Flag
+ * @arg CAN_FLAG_SLAKI: Sleep acknowledge Interrupt Flag
+ * @retval None
+ */
+#define __HAL_CAN_CLEAR_FLAG(__HANDLE__, __FLAG__) \
+ ((((__FLAG__) >> 8U) == 5U)? (((__HANDLE__)->Instance->TSR) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
+ (((__FLAG__) >> 8U) == 2U)? (((__HANDLE__)->Instance->RF0R) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
+ (((__FLAG__) >> 8U) == 4U)? (((__HANDLE__)->Instance->RF1R) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
+ (((__FLAG__) >> 8U) == 1U)? (((__HANDLE__)->Instance->MSR) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): 0U)
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup CAN_Exported_Functions CAN Exported Functions
+ * @{
+ */
+
+/** @addtogroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ * @{
+ */
+
+/* Initialization and de-initialization functions *****************************/
+HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef *hcan);
+HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef *hcan);
+void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan);
+void HAL_CAN_MspDeInit(CAN_HandleTypeDef *hcan);
+
+/**
+ * @}
+ */
+
+/** @addtogroup CAN_Exported_Functions_Group2 Configuration functions
+ * @brief Configuration functions
+ * @{
+ */
+
+/* Configuration functions ****************************************************/
+HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan, CAN_FilterTypeDef *sFilterConfig);
+
+/**
+ * @}
+ */
+
+/** @addtogroup CAN_Exported_Functions_Group3 Control functions
+ * @brief Control functions
+ * @{
+ */
+
+/* Control functions **********************************************************/
+HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *hcan);
+HAL_StatusTypeDef HAL_CAN_Stop(CAN_HandleTypeDef *hcan);
+HAL_StatusTypeDef HAL_CAN_RequestSleep(CAN_HandleTypeDef *hcan);
+HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef *hcan);
+uint32_t HAL_CAN_IsSleepActive(CAN_HandleTypeDef *hcan);
+HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, CAN_TxHeaderTypeDef *pHeader, uint8_t aData[], uint32_t *pTxMailbox);
+HAL_StatusTypeDef HAL_CAN_AbortTxRequest(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes);
+uint32_t HAL_CAN_GetTxMailboxesFreeLevel(CAN_HandleTypeDef *hcan);
+uint32_t HAL_CAN_IsTxMessagePending(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes);
+uint32_t HAL_CAN_GetTxTimestamp(CAN_HandleTypeDef *hcan, uint32_t TxMailbox);
+HAL_StatusTypeDef HAL_CAN_GetRxMessage(CAN_HandleTypeDef *hcan, uint32_t RxFifo, CAN_RxHeaderTypeDef *pHeader, uint8_t aData[]);
+uint32_t HAL_CAN_GetRxFifoFillLevel(CAN_HandleTypeDef *hcan, uint32_t RxFifo);
+
+/**
+ * @}
+ */
+
+/** @addtogroup CAN_Exported_Functions_Group4 Interrupts management
+ * @brief Interrupts management
+ * @{
+ */
+/* Interrupts management ******************************************************/
+HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan, uint32_t ActiveITs);
+HAL_StatusTypeDef HAL_CAN_DeactivateNotification(CAN_HandleTypeDef *hcan, uint32_t InactiveITs);
+void HAL_CAN_IRQHandler(CAN_HandleTypeDef *hcan);
+
+/**
+ * @}
+ */
+
+/** @addtogroup CAN_Exported_Functions_Group5 Callback functions
+ * @brief Callback functions
+ * @{
+ */
+/* Callbacks functions ********************************************************/
+
+void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan);
+void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan);
+void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan);
+void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan);
+void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan);
+void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan);
+void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan);
+void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan);
+void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan);
+void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan);
+void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan);
+void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan);
+void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan);
+
+/**
+ * @}
+ */
+
+/** @addtogroup CAN_Exported_Functions_Group6 Peripheral State and Error functions
+ * @brief CAN Peripheral State functions
+ * @{
+ */
+/* Peripheral State and Error functions ***************************************/
+HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef *hcan);
+uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan);
+HAL_StatusTypeDef HAL_CAN_ResetError(CAN_HandleTypeDef *hcan);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private types -------------------------------------------------------------*/
+/** @defgroup CAN_Private_Types CAN Private Types
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/** @defgroup CAN_Private_Variables CAN Private Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup CAN_Private_Constants CAN Private Constants
+ * @{
+ */
+#define CAN_FLAG_MASK (0x000000FFU)
+/**
+ * @}
+ */
+
+/* Private Macros -----------------------------------------------------------*/
+/** @defgroup CAN_Private_Macros CAN Private Macros
+ * @{
+ */
+
+#define IS_CAN_MODE(MODE) (((MODE) == CAN_MODE_NORMAL) || \
+ ((MODE) == CAN_MODE_LOOPBACK)|| \
+ ((MODE) == CAN_MODE_SILENT) || \
+ ((MODE) == CAN_MODE_SILENT_LOOPBACK))
+#define IS_CAN_SJW(SJW) (((SJW) == CAN_SJW_1TQ) || ((SJW) == CAN_SJW_2TQ) || \
+ ((SJW) == CAN_SJW_3TQ) || ((SJW) == CAN_SJW_4TQ))
+#define IS_CAN_BS1(BS1) (((BS1) == CAN_BS1_1TQ) || ((BS1) == CAN_BS1_2TQ) || \
+ ((BS1) == CAN_BS1_3TQ) || ((BS1) == CAN_BS1_4TQ) || \
+ ((BS1) == CAN_BS1_5TQ) || ((BS1) == CAN_BS1_6TQ) || \
+ ((BS1) == CAN_BS1_7TQ) || ((BS1) == CAN_BS1_8TQ) || \
+ ((BS1) == CAN_BS1_9TQ) || ((BS1) == CAN_BS1_10TQ)|| \
+ ((BS1) == CAN_BS1_11TQ)|| ((BS1) == CAN_BS1_12TQ)|| \
+ ((BS1) == CAN_BS1_13TQ)|| ((BS1) == CAN_BS1_14TQ)|| \
+ ((BS1) == CAN_BS1_15TQ)|| ((BS1) == CAN_BS1_16TQ))
+#define IS_CAN_BS2(BS2) (((BS2) == CAN_BS2_1TQ) || ((BS2) == CAN_BS2_2TQ) || \
+ ((BS2) == CAN_BS2_3TQ) || ((BS2) == CAN_BS2_4TQ) || \
+ ((BS2) == CAN_BS2_5TQ) || ((BS2) == CAN_BS2_6TQ) || \
+ ((BS2) == CAN_BS2_7TQ) || ((BS2) == CAN_BS2_8TQ))
+#define IS_CAN_PRESCALER(PRESCALER) (((PRESCALER) >= 1U) && ((PRESCALER) <= 1024U))
+#define IS_CAN_FILTER_ID_HALFWORD(HALFWORD) ((HALFWORD) <= 0xFFFFU)
+#if defined(CAN2)
+#define IS_CAN_FILTER_BANK_DUAL(BANK) ((BANK) <= 27U)
+#endif
+#define IS_CAN_FILTER_BANK_SINGLE(BANK) ((BANK) <= 13U)
+#define IS_CAN_FILTER_MODE(MODE) (((MODE) == CAN_FILTERMODE_IDMASK) || \
+ ((MODE) == CAN_FILTERMODE_IDLIST))
+#define IS_CAN_FILTER_SCALE(SCALE) (((SCALE) == CAN_FILTERSCALE_16BIT) || \
+ ((SCALE) == CAN_FILTERSCALE_32BIT))
+#define IS_CAN_FILTER_ACTIVATION(ACTIVATION) (((ACTIVATION) == CAN_FILTER_DISABLE) || \
+ ((ACTIVATION) == CAN_FILTER_ENABLE))
+#define IS_CAN_FILTER_FIFO(FIFO) (((FIFO) == CAN_FILTER_FIFO0) || \
+ ((FIFO) == CAN_FILTER_FIFO1))
+#define IS_CAN_TX_MAILBOX(TRANSMITMAILBOX) (((TRANSMITMAILBOX) == CAN_TX_MAILBOX0 ) || \
+ ((TRANSMITMAILBOX) == CAN_TX_MAILBOX1 ) || \
+ ((TRANSMITMAILBOX) == CAN_TX_MAILBOX2 ))
+#define IS_CAN_TX_MAILBOX_LIST(TRANSMITMAILBOX) ((TRANSMITMAILBOX) <= (CAN_TX_MAILBOX0 | CAN_TX_MAILBOX1 | CAN_TX_MAILBOX2))
+#define IS_CAN_STDID(STDID) ((STDID) <= 0x7FFU)
+#define IS_CAN_EXTID(EXTID) ((EXTID) <= 0x1FFFFFFFU)
+#define IS_CAN_DLC(DLC) ((DLC) <= 8U)
+#define IS_CAN_IDTYPE(IDTYPE) (((IDTYPE) == CAN_ID_STD) || \
+ ((IDTYPE) == CAN_ID_EXT))
+#define IS_CAN_RTR(RTR) (((RTR) == CAN_RTR_DATA) || ((RTR) == CAN_RTR_REMOTE))
+#define IS_CAN_RX_FIFO(FIFO) (((FIFO) == CAN_RX_FIFO0) || ((FIFO) == CAN_RX_FIFO1))
+#define IS_CAN_IT(IT) ((IT) <= (CAN_IT_TX_MAILBOX_EMPTY | CAN_IT_RX_FIFO0_MSG_PENDING | \
+ CAN_IT_RX_FIFO0_FULL | CAN_IT_RX_FIFO0_OVERRUN | \
+ CAN_IT_RX_FIFO1_MSG_PENDING | CAN_IT_RX_FIFO1_FULL | \
+ CAN_IT_RX_FIFO1_OVERRUN | CAN_IT_WAKEUP | \
+ CAN_IT_SLEEP_ACK | CAN_IT_ERROR_WARNING | \
+ CAN_IT_ERROR_PASSIVE | CAN_IT_BUSOFF | \
+ CAN_IT_LAST_ERROR_CODE | CAN_IT_ERROR))
+
+/**
+ * @}
+ */
+/* End of private macros -----------------------------------------------------*/
+
+/**
+ * @}
+ */
+
+
+#endif /* CAN1 */
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32F1xx_HAL_CAN_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cec.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cec.h
new file mode 100644
index 0000000..dfd16da
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cec.h
@@ -0,0 +1,516 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_cec.h
+ * @author MCD Application Team
+ * @brief Header file of CEC HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_CEC_H
+#define __STM32F1xx_HAL_CEC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#if defined(STM32F100xB) || defined(STM32F100xE)
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup CEC
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup CEC_Exported_Types CEC Exported Types
+ * @{
+ */
+/**
+ * @brief CEC Init Structure definition
+ */
+typedef struct
+{
+ uint32_t TimingErrorFree; /*!< Configures the CEC Bit Timing Error Mode.
+ This parameter can be a value of @ref CEC_BitTimingErrorMode */
+ uint32_t PeriodErrorFree; /*!< Configures the CEC Bit Period Error Mode.
+ This parameter can be a value of @ref CEC_BitPeriodErrorMode */
+ uint16_t OwnAddress; /*!< Own addresses configuration
+ This parameter can be a value of @ref CEC_OWN_ADDRESS */
+ uint8_t *RxBuffer; /*!< CEC Rx buffer pointeur */
+}CEC_InitTypeDef;
+
+/**
+ * @brief HAL CEC State structures definition
+ * @note HAL CEC State value is a combination of 2 different substates: gState and RxState.
+ * - gState contains CEC state information related to global Handle management
+ * and also information related to Tx operations.
+ * gState value coding follow below described bitmap :
+ * b7 (not used)
+ * x : Should be set to 0
+ * b6 Error information
+ * 0 : No Error
+ * 1 : Error
+ * b5 IP initilisation status
+ * 0 : Reset (IP not initialized)
+ * 1 : Init done (IP initialized. HAL CEC Init function already called)
+ * b4-b3 (not used)
+ * xx : Should be set to 00
+ * b2 Intrinsic process state
+ * 0 : Ready
+ * 1 : Busy (IP busy with some configuration or internal operations)
+ * b1 (not used)
+ * x : Should be set to 0
+ * b0 Tx state
+ * 0 : Ready (no Tx operation ongoing)
+ * 1 : Busy (Tx operation ongoing)
+ * - RxState contains information related to Rx operations.
+ * RxState value coding follow below described bitmap :
+ * b7-b6 (not used)
+ * xx : Should be set to 00
+ * b5 IP initilisation status
+ * 0 : Reset (IP not initialized)
+ * 1 : Init done (IP initialized)
+ * b4-b2 (not used)
+ * xxx : Should be set to 000
+ * b1 Rx state
+ * 0 : Ready (no Rx operation ongoing)
+ * 1 : Busy (Rx operation ongoing)
+ * b0 (not used)
+ * x : Should be set to 0.
+ */
+typedef enum
+{
+ HAL_CEC_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized
+ Value is allowed for gState and RxState */
+ HAL_CEC_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use
+ Value is allowed for gState and RxState */
+ HAL_CEC_STATE_BUSY = 0x24U, /*!< an internal process is ongoing
+ Value is allowed for gState only */
+ HAL_CEC_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing
+ Value is allowed for RxState only */
+ HAL_CEC_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing
+ Value is allowed for gState only */
+ HAL_CEC_STATE_BUSY_RX_TX = 0x23U, /*!< an internal process is ongoing
+ Value is allowed for gState only */
+ HAL_CEC_STATE_ERROR = 0x60U /*!< Error Value is allowed for gState only */
+}HAL_CEC_StateTypeDef;
+
+/**
+ * @brief CEC handle Structure definition
+ */
+typedef struct
+{
+ CEC_TypeDef *Instance; /*!< CEC registers base address */
+
+ CEC_InitTypeDef Init; /*!< CEC communication parameters */
+
+ uint8_t *pTxBuffPtr; /*!< Pointer to CEC Tx transfer Buffer */
+
+ uint16_t TxXferCount; /*!< CEC Tx Transfer Counter */
+
+ uint16_t RxXferSize; /*!< CEC Rx Transfer size, 0: header received only */
+
+ HAL_LockTypeDef Lock; /*!< Locking object */
+
+ HAL_CEC_StateTypeDef gState; /*!< CEC state information related to global Handle management
+ and also related to Tx operations.
+ This parameter can be a value of @ref HAL_CEC_StateTypeDef */
+
+ HAL_CEC_StateTypeDef RxState; /*!< CEC state information related to Rx operations.
+ This parameter can be a value of @ref HAL_CEC_StateTypeDef */
+
+ uint32_t ErrorCode; /*!< For errors handling purposes, copy of ISR register
+ in case error is reported */
+}CEC_HandleTypeDef;
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup CEC_Exported_Constants CEC Exported Constants
+ * @{
+ */
+
+/** @defgroup CEC_Error_Code CEC Error Code
+ * @{
+ */
+#define HAL_CEC_ERROR_NONE 0x00000000U /*!< no error */
+#define HAL_CEC_ERROR_BTE CEC_ESR_BTE /*!< Bit Timing Error */
+#define HAL_CEC_ERROR_BPE CEC_ESR_BPE /*!< Bit Period Error */
+#define HAL_CEC_ERROR_RBTFE CEC_ESR_RBTFE /*!< Rx Block Transfer Finished Error */
+#define HAL_CEC_ERROR_SBE CEC_ESR_SBE /*!< Start Bit Error */
+#define HAL_CEC_ERROR_ACKE CEC_ESR_ACKE /*!< Block Acknowledge Error */
+#define HAL_CEC_ERROR_LINE CEC_ESR_LINE /*!< Line Error */
+#define HAL_CEC_ERROR_TBTFE CEC_ESR_TBTFE /*!< Tx Block Transfer Finished Error */
+/**
+ * @}
+ */
+
+/** @defgroup CEC_BitTimingErrorMode Bit Timing Error Mode
+ * @{
+ */
+#define CEC_BIT_TIMING_ERROR_MODE_STANDARD 0x00000000U /*!< Bit timing error Standard Mode */
+#define CEC_BIT_TIMING_ERROR_MODE_ERRORFREE CEC_CFGR_BTEM /*!< Bit timing error Free Mode */
+/**
+ * @}
+ */
+
+/** @defgroup CEC_BitPeriodErrorMode Bit Period Error Mode
+ * @{
+ */
+#define CEC_BIT_PERIOD_ERROR_MODE_STANDARD 0x00000000U /*!< Bit period error Standard Mode */
+#define CEC_BIT_PERIOD_ERROR_MODE_FLEXIBLE CEC_CFGR_BPEM /*!< Bit period error Flexible Mode */
+/**
+ * @}
+ */
+
+/** @defgroup CEC_Initiator_Position CEC Initiator logical address position in message header
+ * @{
+ */
+#define CEC_INITIATOR_LSB_POS 4U
+/**
+ * @}
+ */
+
+/** @defgroup CEC_OWN_ADDRESS CEC Own Address
+ * @{
+ */
+#define CEC_OWN_ADDRESS_NONE CEC_OWN_ADDRESS_0 /* Reset value */
+#define CEC_OWN_ADDRESS_0 ((uint16_t)0x0000U) /* Logical Address 0 */
+#define CEC_OWN_ADDRESS_1 ((uint16_t)0x0001U) /* Logical Address 1 */
+#define CEC_OWN_ADDRESS_2 ((uint16_t)0x0002U) /* Logical Address 2 */
+#define CEC_OWN_ADDRESS_3 ((uint16_t)0x0003U) /* Logical Address 3 */
+#define CEC_OWN_ADDRESS_4 ((uint16_t)0x0004U) /* Logical Address 4 */
+#define CEC_OWN_ADDRESS_5 ((uint16_t)0x0005U) /* Logical Address 5 */
+#define CEC_OWN_ADDRESS_6 ((uint16_t)0x0006U) /* Logical Address 6 */
+#define CEC_OWN_ADDRESS_7 ((uint16_t)0x0007U) /* Logical Address 7 */
+#define CEC_OWN_ADDRESS_8 ((uint16_t)0x0008U) /* Logical Address 8 */
+#define CEC_OWN_ADDRESS_9 ((uint16_t)0x0009U) /* Logical Address 9 */
+#define CEC_OWN_ADDRESS_10 ((uint16_t)0x000AU) /* Logical Address 10 */
+#define CEC_OWN_ADDRESS_11 ((uint16_t)0x000BU) /* Logical Address 11 */
+#define CEC_OWN_ADDRESS_12 ((uint16_t)0x000CU) /* Logical Address 12 */
+#define CEC_OWN_ADDRESS_13 ((uint16_t)0x000DU) /* Logical Address 13 */
+#define CEC_OWN_ADDRESS_14 ((uint16_t)0x000EU) /* Logical Address 14 */
+#define CEC_OWN_ADDRESS_15 ((uint16_t)0x000FU) /* Logical Address 15 */
+/**
+ * @}
+ */
+
+/** @defgroup CEC_Interrupts_Definitions Interrupts definition
+ * @{
+ */
+#define CEC_IT_IE CEC_CFGR_IE
+/**
+ * @}
+ */
+
+/** @defgroup CEC_Flags_Definitions Flags definition
+ * @{
+ */
+#define CEC_FLAG_TSOM CEC_CSR_TSOM
+#define CEC_FLAG_TEOM CEC_CSR_TEOM
+#define CEC_FLAG_TERR CEC_CSR_TERR
+#define CEC_FLAG_TBTRF CEC_CSR_TBTRF
+#define CEC_FLAG_RSOM CEC_CSR_RSOM
+#define CEC_FLAG_REOM CEC_CSR_REOM
+#define CEC_FLAG_RERR CEC_CSR_RERR
+#define CEC_FLAG_RBTF CEC_CSR_RBTF
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macros -----------------------------------------------------------*/
+/** @defgroup CEC_Exported_Macros CEC Exported Macros
+ * @{
+ */
+
+/** @brief Reset CEC handle gstate & RxState
+ * @param __HANDLE__: CEC handle.
+ * @retval None
+ */
+#define __HAL_CEC_RESET_HANDLE_STATE(__HANDLE__) do{ \
+ (__HANDLE__)->gState = HAL_CEC_STATE_RESET; \
+ (__HANDLE__)->RxState = HAL_CEC_STATE_RESET; \
+ } while(0U)
+
+/** @brief Checks whether or not the specified CEC interrupt flag is set.
+ * @param __HANDLE__: specifies the CEC Handle.
+ * @param __FLAG__: specifies the flag to check.
+ * @arg CEC_FLAG_TERR: Tx Error
+ * @arg CEC_FLAG_TBTRF:Tx Block Transfer Finished
+ * @arg CEC_FLAG_RERR: Rx Error
+ * @arg CEC_FLAG_RBTF: Rx Block Transfer Finished
+ * @retval ITStatus
+ */
+#define __HAL_CEC_GET_FLAG(__HANDLE__, __FLAG__) READ_BIT((__HANDLE__)->Instance->CSR,(__FLAG__))
+
+/** @brief Clears the CEC's pending flags.
+ * @param __HANDLE__: specifies the CEC Handle.
+ * @param __FLAG__: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg CEC_CSR_TERR: Tx Error
+ * @arg CEC_FLAG_TBTRF: Tx Block Transfer Finished
+ * @arg CEC_CSR_RERR: Rx Error
+ * @arg CEC_CSR_RBTF: Rx Block Transfer Finished
+ * @retval none
+ */
+#define __HAL_CEC_CLEAR_FLAG(__HANDLE__, __FLAG__) \
+ do { \
+ uint32_t tmp = 0x0U; \
+ tmp = (__HANDLE__)->Instance->CSR & 0x00000002U; \
+ (__HANDLE__)->Instance->CSR &= (uint32_t)(((~(uint32_t)(__FLAG__)) & 0xFFFFFFFCU) | tmp);\
+ } while(0U)
+
+/** @brief Enables the specified CEC interrupt.
+ * @param __HANDLE__: specifies the CEC Handle.
+ * @param __INTERRUPT__: specifies the CEC interrupt to enable.
+ * This parameter can be:
+ * @arg CEC_IT_IE : Interrupt Enable.
+ * @retval none
+ */
+#define __HAL_CEC_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->CFGR, (__INTERRUPT__))
+
+/** @brief Disables the specified CEC interrupt.
+ * @param __HANDLE__: specifies the CEC Handle.
+ * @param __INTERRUPT__: specifies the CEC interrupt to disable.
+ * This parameter can be:
+ * @arg CEC_IT_IE : Interrupt Enable
+ * @retval none
+ */
+#define __HAL_CEC_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT((__HANDLE__)->Instance->CFGR, (__INTERRUPT__))
+
+/** @brief Checks whether or not the specified CEC interrupt is enabled.
+ * @param __HANDLE__: specifies the CEC Handle.
+ * @param __INTERRUPT__: specifies the CEC interrupt to check.
+ * This parameter can be:
+ * @arg CEC_IT_IE : Interrupt Enable
+ * @retval FlagStatus
+ */
+#define __HAL_CEC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) READ_BIT((__HANDLE__)->Instance->CFGR, (__INTERRUPT__))
+
+/** @brief Enables the CEC device
+ * @param __HANDLE__: specifies the CEC Handle.
+ * @retval none
+ */
+#define __HAL_CEC_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CFGR, CEC_CFGR_PE)
+
+/** @brief Disables the CEC device
+ * @param __HANDLE__: specifies the CEC Handle.
+ * @retval none
+ */
+#define __HAL_CEC_DISABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CFGR, CEC_CFGR_PE)
+
+/** @brief Set Transmission Start flag
+ * @param __HANDLE__: specifies the CEC Handle.
+ * @retval none
+ */
+#define __HAL_CEC_FIRST_BYTE_TX_SET(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CSR, CEC_CSR_TSOM)
+
+/** @brief Set Transmission End flag
+ * @param __HANDLE__: specifies the CEC Handle.
+ * @retval none
+ */
+#define __HAL_CEC_LAST_BYTE_TX_SET(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CSR, CEC_CSR_TEOM)
+
+/** @brief Get Transmission Start flag
+ * @param __HANDLE__: specifies the CEC Handle.
+ * @retval FlagStatus
+ */
+#define __HAL_CEC_GET_TRANSMISSION_START_FLAG(__HANDLE__) READ_BIT((__HANDLE__)->Instance->CSR, CEC_CSR_TSOM)
+
+/** @brief Get Transmission End flag
+ * @param __HANDLE__: specifies the CEC Handle.
+ * @retval FlagStatus
+ */
+#define __HAL_CEC_GET_TRANSMISSION_END_FLAG(__HANDLE__) READ_BIT((__HANDLE__)->Instance->CSR, CEC_CSR_TEOM)
+
+/** @brief Clear OAR register
+ * @param __HANDLE__: specifies the CEC Handle.
+ * @retval none
+ */
+#define __HAL_CEC_CLEAR_OAR(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->OAR, CEC_OAR_OA)
+
+/** @brief Set OAR register
+ * @param __HANDLE__: specifies the CEC Handle.
+ * @param __ADDRESS__: Own Address value.
+ * @retval none
+ */
+#define __HAL_CEC_SET_OAR(__HANDLE__,__ADDRESS__) MODIFY_REG((__HANDLE__)->Instance->OAR, CEC_OAR_OA, (__ADDRESS__));
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup CEC_Exported_Functions CEC Exported Functions
+ * @{
+ */
+
+/** @addtogroup CEC_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ * @{
+ */
+/* Initialization and de-initialization functions ****************************/
+HAL_StatusTypeDef HAL_CEC_Init(CEC_HandleTypeDef *hcec);
+HAL_StatusTypeDef HAL_CEC_DeInit(CEC_HandleTypeDef *hcec);
+HAL_StatusTypeDef HAL_CEC_SetDeviceAddress(CEC_HandleTypeDef *hcec, uint16_t CEC_OwnAddress);
+void HAL_CEC_MspInit(CEC_HandleTypeDef *hcec);
+void HAL_CEC_MspDeInit(CEC_HandleTypeDef *hcec);
+/**
+ * @}
+ */
+
+/** @addtogroup CEC_Exported_Functions_Group2 Input and Output operation functions
+ * @brief CEC Transmit/Receive functions
+ * @{
+ */
+/* I/O operation functions ***************************************************/
+HAL_StatusTypeDef HAL_CEC_Transmit_IT(CEC_HandleTypeDef *hcec, uint8_t InitiatorAddress,uint8_t DestinationAddress, uint8_t *pData, uint32_t Size);
+uint32_t HAL_CEC_GetLastReceivedFrameSize(CEC_HandleTypeDef *hcec);
+void HAL_CEC_ChangeRxBuffer(CEC_HandleTypeDef *hcec, uint8_t* Rxbuffer);
+void HAL_CEC_IRQHandler(CEC_HandleTypeDef *hcec);
+void HAL_CEC_TxCpltCallback(CEC_HandleTypeDef *hcec);
+void HAL_CEC_RxCpltCallback(CEC_HandleTypeDef *hcec, uint32_t RxFrameSize);
+void HAL_CEC_ErrorCallback(CEC_HandleTypeDef *hcec);
+/**
+ * @}
+ */
+
+/** @defgroup CEC_Exported_Functions_Group3 Peripheral Control functions
+ * @brief CEC control functions
+ * @{
+ */
+/* Peripheral State and Error functions ***************************************/
+HAL_CEC_StateTypeDef HAL_CEC_GetState(CEC_HandleTypeDef *hcec);
+uint32_t HAL_CEC_GetError(CEC_HandleTypeDef *hcec);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private types -------------------------------------------------------------*/
+/** @defgroup CEC_Private_Types CEC Private Types
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/** @defgroup CEC_Private_Variables CEC Private Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup CEC_Private_Constants CEC Private Constants
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup CEC_Private_Macros CEC Private Macros
+ * @{
+ */
+#define IS_CEC_BIT_TIMING_ERROR_MODE(MODE) (((MODE) == CEC_BIT_TIMING_ERROR_MODE_STANDARD) || \
+ ((MODE) == CEC_BIT_TIMING_ERROR_MODE_ERRORFREE))
+
+#define IS_CEC_BIT_PERIOD_ERROR_MODE(MODE) (((MODE) == CEC_BIT_PERIOD_ERROR_MODE_STANDARD) || \
+ ((MODE) == CEC_BIT_PERIOD_ERROR_MODE_FLEXIBLE))
+
+/** @brief Check CEC message size.
+ * The message size is the payload size: without counting the header,
+ * it varies from 0 byte (ping operation, one header only, no payload) to
+ * 15 bytes (1 opcode and up to 14 operands following the header).
+ * @param __SIZE__: CEC message size.
+ * @retval Test result (TRUE or FALSE).
+ */
+#define IS_CEC_MSGSIZE(__SIZE__) ((__SIZE__) <= 0x10U)
+/** @brief Check CEC device Own Address Register (OAR) setting.
+ * @param __ADDRESS__: CEC own address.
+ * @retval Test result (TRUE or FALSE).
+ */
+#define IS_CEC_OWN_ADDRESS(__ADDRESS__) ((__ADDRESS__) <= 0x0000000FU)
+
+/** @brief Check CEC initiator or destination logical address setting.
+ * Initiator and destination addresses are coded over 4 bits.
+ * @param __ADDRESS__: CEC initiator or logical address.
+ * @retval Test result (TRUE or FALSE).
+ */
+#define IS_CEC_ADDRESS(__ADDRESS__) ((__ADDRESS__) <= 0x0000000FU)
+
+
+
+/**
+ * @}
+ */
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup CEC_Private_Functions CEC Private Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* defined(STM32F100xB) || defined(STM32F100xE) */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_CEC_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_conf_template.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_conf_template.h
new file mode 100644
index 0000000..ce39019
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_conf_template.h
@@ -0,0 +1,386 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_conf.h
+ * @author MCD Application Team
+ * @brief HAL configuration template file.
+ * This file should be copied to the application folder and renamed
+ * to stm32f1xx_hal_conf.h.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_CONF_H
+#define __STM32F1xx_HAL_CONF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* ########################## Module Selection ############################## */
+/**
+ * @brief This is the list of modules to be used in the HAL driver
+ */
+#define HAL_MODULE_ENABLED
+#define HAL_ADC_MODULE_ENABLED
+#define HAL_CAN_MODULE_ENABLED
+/* #define HAL_CAN_LEGACY_MODULE_ENABLED */
+#define HAL_CEC_MODULE_ENABLED
+#define HAL_CORTEX_MODULE_ENABLED
+#define HAL_CRC_MODULE_ENABLED
+#define HAL_DAC_MODULE_ENABLED
+#define HAL_DMA_MODULE_ENABLED
+#define HAL_ETH_MODULE_ENABLED
+#define HAL_FLASH_MODULE_ENABLED
+#define HAL_GPIO_MODULE_ENABLED
+#define HAL_HCD_MODULE_ENABLED
+#define HAL_I2C_MODULE_ENABLED
+#define HAL_I2S_MODULE_ENABLED
+#define HAL_IRDA_MODULE_ENABLED
+#define HAL_IWDG_MODULE_ENABLED
+#define HAL_NAND_MODULE_ENABLED
+#define HAL_NOR_MODULE_ENABLED
+#define HAL_PCCARD_MODULE_ENABLED
+#define HAL_PCD_MODULE_ENABLED
+#define HAL_PWR_MODULE_ENABLED
+#define HAL_RCC_MODULE_ENABLED
+#define HAL_RTC_MODULE_ENABLED
+#define HAL_SD_MODULE_ENABLED
+#define HAL_SMARTCARD_MODULE_ENABLED
+#define HAL_SPI_MODULE_ENABLED
+#define HAL_SRAM_MODULE_ENABLED
+#define HAL_TIM_MODULE_ENABLED
+#define HAL_UART_MODULE_ENABLED
+#define HAL_USART_MODULE_ENABLED
+#define HAL_WWDG_MODULE_ENABLED
+#define HAL_MMC_MODULE_ENABLED
+
+/* ########################## Oscillator Values adaptation ####################*/
+/**
+ * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSE is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSE_VALUE)
+#if defined(USE_STM3210C_EVAL)
+#define HSE_VALUE 25000000U /*!< Value of the External oscillator in Hz */
+#else
+#define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */
+#endif
+#endif /* HSE_VALUE */
+
+#if !defined (HSE_STARTUP_TIMEOUT)
+#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */
+#endif /* HSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief Internal High Speed oscillator (HSI) value.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSI is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSI_VALUE)
+#define HSI_VALUE 8000000U /*!< Value of the Internal oscillator in Hz */
+#endif /* HSI_VALUE */
+
+/**
+ * @brief Internal Low Speed oscillator (LSI) value.
+ */
+#if !defined (LSI_VALUE)
+#define LSI_VALUE 32000U /*!< LSI Typical Value in Hz */
+#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
+ The real value may vary depending on the variations
+ in voltage and temperature. */
+/**
+ * @brief External Low Speed oscillator (LSE) value.
+ * This value is used by the UART, RTC HAL module to compute the system frequency
+ */
+#if !defined (LSE_VALUE)
+#define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */
+#endif /* LSE_VALUE */
+
+#if !defined (LSE_STARTUP_TIMEOUT)
+#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */
+#endif /* LSE_STARTUP_TIMEOUT */
+
+/* Tip: To avoid modifying this file each time you need to use different HSE,
+ === you can define the HSE value in your toolchain compiler preprocessor. */
+
+/* ########################### System Configuration ######################### */
+/**
+ * @brief This is the HAL system configuration section
+ */
+#define VDD_VALUE 3300U /*!< Value of VDD in mv */
+#define TICK_INT_PRIORITY 0x0FU /*!< tick interrupt priority */
+#define USE_RTOS 0U
+#define PREFETCH_ENABLE 1U
+
+/* ########################## Assert Selection ############################## */
+/**
+ * @brief Uncomment the line below to expanse the "assert_param" macro in the
+ * HAL drivers code
+ */
+/* #define USE_FULL_ASSERT 1U */
+
+/* ################## Ethernet peripheral configuration ##################### */
+
+/* Section 1 : Ethernet peripheral configuration */
+
+/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
+#define MAC_ADDR0 2U
+#define MAC_ADDR1 0U
+#define MAC_ADDR2 0U
+#define MAC_ADDR3 0U
+#define MAC_ADDR4 0U
+#define MAC_ADDR5 0U
+
+/* Definition of the Ethernet driver buffers size and count */
+#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
+#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
+#define ETH_RXBUFNB 8U /* 8 Rx buffers of size ETH_RX_BUF_SIZE */
+#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
+
+/* Section 2: PHY configuration section */
+
+/* DP83848 PHY Address*/
+#define DP83848_PHY_ADDRESS 0x01U
+/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
+#define PHY_RESET_DELAY 0x000000FFU
+/* PHY Configuration delay */
+#define PHY_CONFIG_DELAY 0x00000FFFU
+
+#define PHY_READ_TO 0x0000FFFFU
+#define PHY_WRITE_TO 0x0000FFFFU
+
+/* Section 3: Common PHY Registers */
+
+#define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */
+#define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */
+
+#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */
+#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */
+#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */
+#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */
+#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */
+#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */
+#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */
+#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */
+#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */
+#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */
+
+#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */
+#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */
+#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */
+
+/* Section 4: Extended PHY Registers */
+
+#define PHY_SR ((uint16_t)0x0010) /*!< PHY status register Offset */
+#define PHY_MICR ((uint16_t)0x0011) /*!< MII Interrupt Control Register */
+#define PHY_MISR ((uint16_t)0x0012) /*!< MII Interrupt Status and Misc. Control Register */
+
+#define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */
+#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */
+#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */
+
+#define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */
+#define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */
+
+#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */
+#define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */
+
+/* ################## SPI peripheral configuration ########################## */
+
+/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
+* Activated: CRC code is present inside driver
+* Deactivated: CRC code cleaned from driver
+*/
+
+#define USE_SPI_CRC 1U
+
+/* Includes ------------------------------------------------------------------*/
+/**
+ * @brief Include module's header file
+ */
+
+#ifdef HAL_RCC_MODULE_ENABLED
+#include "stm32f1xx_hal_rcc.h"
+#endif /* HAL_RCC_MODULE_ENABLED */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+#include "stm32f1xx_hal_gpio.h"
+#endif /* HAL_GPIO_MODULE_ENABLED */
+
+#ifdef HAL_DMA_MODULE_ENABLED
+#include "stm32f1xx_hal_dma.h"
+#endif /* HAL_DMA_MODULE_ENABLED */
+
+#ifdef HAL_ETH_MODULE_ENABLED
+#include "stm32f1xx_hal_eth.h"
+#endif /* HAL_ETH_MODULE_ENABLED */
+
+#ifdef HAL_CAN_MODULE_ENABLED
+#include "stm32f1xx_hal_can.h"
+#endif /* HAL_CAN_MODULE_ENABLED */
+
+#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
+ #include "Legacy/stm32f1xx_hal_can_legacy.h"
+#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
+
+#ifdef HAL_CEC_MODULE_ENABLED
+#include "stm32f1xx_hal_cec.h"
+#endif /* HAL_CEC_MODULE_ENABLED */
+
+#ifdef HAL_CORTEX_MODULE_ENABLED
+#include "stm32f1xx_hal_cortex.h"
+#endif /* HAL_CORTEX_MODULE_ENABLED */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+#include "stm32f1xx_hal_adc.h"
+#endif /* HAL_ADC_MODULE_ENABLED */
+
+#ifdef HAL_CRC_MODULE_ENABLED
+#include "stm32f1xx_hal_crc.h"
+#endif /* HAL_CRC_MODULE_ENABLED */
+
+#ifdef HAL_DAC_MODULE_ENABLED
+#include "stm32f1xx_hal_dac.h"
+#endif /* HAL_DAC_MODULE_ENABLED */
+
+#ifdef HAL_FLASH_MODULE_ENABLED
+#include "stm32f1xx_hal_flash.h"
+#endif /* HAL_FLASH_MODULE_ENABLED */
+
+#ifdef HAL_SRAM_MODULE_ENABLED
+#include "stm32f1xx_hal_sram.h"
+#endif /* HAL_SRAM_MODULE_ENABLED */
+
+#ifdef HAL_NOR_MODULE_ENABLED
+#include "stm32f1xx_hal_nor.h"
+#endif /* HAL_NOR_MODULE_ENABLED */
+
+#ifdef HAL_I2C_MODULE_ENABLED
+#include "stm32f1xx_hal_i2c.h"
+#endif /* HAL_I2C_MODULE_ENABLED */
+
+#ifdef HAL_I2S_MODULE_ENABLED
+#include "stm32f1xx_hal_i2s.h"
+#endif /* HAL_I2S_MODULE_ENABLED */
+
+#ifdef HAL_IWDG_MODULE_ENABLED
+#include "stm32f1xx_hal_iwdg.h"
+#endif /* HAL_IWDG_MODULE_ENABLED */
+
+#ifdef HAL_PWR_MODULE_ENABLED
+#include "stm32f1xx_hal_pwr.h"
+#endif /* HAL_PWR_MODULE_ENABLED */
+
+#ifdef HAL_RTC_MODULE_ENABLED
+#include "stm32f1xx_hal_rtc.h"
+#endif /* HAL_RTC_MODULE_ENABLED */
+
+#ifdef HAL_PCCARD_MODULE_ENABLED
+#include "stm32f1xx_hal_pccard.h"
+#endif /* HAL_PCCARD_MODULE_ENABLED */
+
+#ifdef HAL_SD_MODULE_ENABLED
+#include "stm32f1xx_hal_sd.h"
+#endif /* HAL_SD_MODULE_ENABLED */
+
+#ifdef HAL_NAND_MODULE_ENABLED
+#include "stm32f1xx_hal_nand.h"
+#endif /* HAL_NAND_MODULE_ENABLED */
+
+#ifdef HAL_SPI_MODULE_ENABLED
+#include "stm32f1xx_hal_spi.h"
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+#ifdef HAL_TIM_MODULE_ENABLED
+#include "stm32f1xx_hal_tim.h"
+#endif /* HAL_TIM_MODULE_ENABLED */
+
+#ifdef HAL_UART_MODULE_ENABLED
+#include "stm32f1xx_hal_uart.h"
+#endif /* HAL_UART_MODULE_ENABLED */
+
+#ifdef HAL_USART_MODULE_ENABLED
+#include "stm32f1xx_hal_usart.h"
+#endif /* HAL_USART_MODULE_ENABLED */
+
+#ifdef HAL_IRDA_MODULE_ENABLED
+#include "stm32f1xx_hal_irda.h"
+#endif /* HAL_IRDA_MODULE_ENABLED */
+
+#ifdef HAL_SMARTCARD_MODULE_ENABLED
+#include "stm32f1xx_hal_smartcard.h"
+#endif /* HAL_SMARTCARD_MODULE_ENABLED */
+
+#ifdef HAL_WWDG_MODULE_ENABLED
+#include "stm32f1xx_hal_wwdg.h"
+#endif /* HAL_WWDG_MODULE_ENABLED */
+
+#ifdef HAL_PCD_MODULE_ENABLED
+#include "stm32f1xx_hal_pcd.h"
+#endif /* HAL_PCD_MODULE_ENABLED */
+
+#ifdef HAL_HCD_MODULE_ENABLED
+#include "stm32f1xx_hal_hcd.h"
+#endif /* HAL_HCD_MODULE_ENABLED */
+
+#ifdef HAL_MMC_MODULE_ENABLED
+#include "stm32f1xx_hal_mmc.h"
+#endif /* HAL_MMC_MODULE_ENABLED */
+
+/* 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)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+void assert_failed(uint8_t *file, uint32_t line);
+#else
+#define assert_param(expr) ((void)0U)
+#endif /* USE_FULL_ASSERT */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_CONF_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h
new file mode 100644
index 0000000..9cb0c83
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h
@@ -0,0 +1,426 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_cortex.h
+ * @author MCD Application Team
+ * @brief Header file of CORTEX HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_CORTEX_H
+#define __STM32F1xx_HAL_CORTEX_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup CORTEX
+ * @{
+ */
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup CORTEX_Exported_Types Cortex Exported Types
+ * @{
+ */
+
+#if (__MPU_PRESENT == 1U)
+/** @defgroup CORTEX_MPU_Region_Initialization_Structure_definition MPU Region Initialization Structure Definition
+ * @brief MPU Region initialization structure
+ * @{
+ */
+typedef struct
+{
+ uint8_t Enable; /*!< Specifies the status of the region.
+ This parameter can be a value of @ref CORTEX_MPU_Region_Enable */
+ uint8_t Number; /*!< Specifies the number of the region to protect.
+ This parameter can be a value of @ref CORTEX_MPU_Region_Number */
+ uint32_t BaseAddress; /*!< Specifies the base address of the region to protect. */
+ uint8_t Size; /*!< Specifies the size of the region to protect.
+ This parameter can be a value of @ref CORTEX_MPU_Region_Size */
+ uint8_t SubRegionDisable; /*!< Specifies the number of the subregion protection to disable.
+ This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF */
+ uint8_t TypeExtField; /*!< Specifies the TEX field level.
+ This parameter can be a value of @ref CORTEX_MPU_TEX_Levels */
+ uint8_t AccessPermission; /*!< Specifies the region access permission type.
+ This parameter can be a value of @ref CORTEX_MPU_Region_Permission_Attributes */
+ uint8_t DisableExec; /*!< Specifies the instruction access status.
+ This parameter can be a value of @ref CORTEX_MPU_Instruction_Access */
+ uint8_t IsShareable; /*!< Specifies the shareability status of the protected region.
+ This parameter can be a value of @ref CORTEX_MPU_Access_Shareable */
+ uint8_t IsCacheable; /*!< Specifies the cacheable status of the region protected.
+ This parameter can be a value of @ref CORTEX_MPU_Access_Cacheable */
+ uint8_t IsBufferable; /*!< Specifies the bufferable status of the protected region.
+ This parameter can be a value of @ref CORTEX_MPU_Access_Bufferable */
+}MPU_Region_InitTypeDef;
+/**
+ * @}
+ */
+#endif /* __MPU_PRESENT */
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup CORTEX_Exported_Constants CORTEX Exported Constants
+ * @{
+ */
+
+/** @defgroup CORTEX_Preemption_Priority_Group CORTEX Preemption Priority Group
+ * @{
+ */
+#define NVIC_PRIORITYGROUP_0 0x00000007U /*!< 0 bits for pre-emption priority
+ 4 bits for subpriority */
+#define NVIC_PRIORITYGROUP_1 0x00000006U /*!< 1 bits for pre-emption priority
+ 3 bits for subpriority */
+#define NVIC_PRIORITYGROUP_2 0x00000005U /*!< 2 bits for pre-emption priority
+ 2 bits for subpriority */
+#define NVIC_PRIORITYGROUP_3 0x00000004U /*!< 3 bits for pre-emption priority
+ 1 bits for subpriority */
+#define NVIC_PRIORITYGROUP_4 0x00000003U /*!< 4 bits for pre-emption priority
+ 0 bits for subpriority */
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_SysTick_clock_source CORTEX _SysTick clock source
+ * @{
+ */
+#define SYSTICK_CLKSOURCE_HCLK_DIV8 0x00000000U
+#define SYSTICK_CLKSOURCE_HCLK 0x00000004U
+
+/**
+ * @}
+ */
+
+#if (__MPU_PRESENT == 1)
+/** @defgroup CORTEX_MPU_HFNMI_PRIVDEF_Control MPU HFNMI and PRIVILEGED Access control
+ * @{
+ */
+#define MPU_HFNMI_PRIVDEF_NONE 0x00000000U
+#define MPU_HARDFAULT_NMI MPU_CTRL_HFNMIENA_Msk
+#define MPU_PRIVILEGED_DEFAULT MPU_CTRL_PRIVDEFENA_Msk
+#define MPU_HFNMI_PRIVDEF (MPU_CTRL_HFNMIENA_Msk | MPU_CTRL_PRIVDEFENA_Msk)
+
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_MPU_Region_Enable CORTEX MPU Region Enable
+ * @{
+ */
+#define MPU_REGION_ENABLE ((uint8_t)0x01)
+#define MPU_REGION_DISABLE ((uint8_t)0x00)
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_MPU_Instruction_Access CORTEX MPU Instruction Access
+ * @{
+ */
+#define MPU_INSTRUCTION_ACCESS_ENABLE ((uint8_t)0x00)
+#define MPU_INSTRUCTION_ACCESS_DISABLE ((uint8_t)0x01)
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_MPU_Access_Shareable CORTEX MPU Instruction Access Shareable
+ * @{
+ */
+#define MPU_ACCESS_SHAREABLE ((uint8_t)0x01)
+#define MPU_ACCESS_NOT_SHAREABLE ((uint8_t)0x00)
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_MPU_Access_Cacheable CORTEX MPU Instruction Access Cacheable
+ * @{
+ */
+#define MPU_ACCESS_CACHEABLE ((uint8_t)0x01)
+#define MPU_ACCESS_NOT_CACHEABLE ((uint8_t)0x00)
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_MPU_Access_Bufferable CORTEX MPU Instruction Access Bufferable
+ * @{
+ */
+#define MPU_ACCESS_BUFFERABLE ((uint8_t)0x01)
+#define MPU_ACCESS_NOT_BUFFERABLE ((uint8_t)0x00)
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_MPU_TEX_Levels MPU TEX Levels
+ * @{
+ */
+#define MPU_TEX_LEVEL0 ((uint8_t)0x00)
+#define MPU_TEX_LEVEL1 ((uint8_t)0x01)
+#define MPU_TEX_LEVEL2 ((uint8_t)0x02)
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_MPU_Region_Size CORTEX MPU Region Size
+ * @{
+ */
+#define MPU_REGION_SIZE_32B ((uint8_t)0x04)
+#define MPU_REGION_SIZE_64B ((uint8_t)0x05)
+#define MPU_REGION_SIZE_128B ((uint8_t)0x06)
+#define MPU_REGION_SIZE_256B ((uint8_t)0x07)
+#define MPU_REGION_SIZE_512B ((uint8_t)0x08)
+#define MPU_REGION_SIZE_1KB ((uint8_t)0x09)
+#define MPU_REGION_SIZE_2KB ((uint8_t)0x0A)
+#define MPU_REGION_SIZE_4KB ((uint8_t)0x0B)
+#define MPU_REGION_SIZE_8KB ((uint8_t)0x0C)
+#define MPU_REGION_SIZE_16KB ((uint8_t)0x0D)
+#define MPU_REGION_SIZE_32KB ((uint8_t)0x0E)
+#define MPU_REGION_SIZE_64KB ((uint8_t)0x0F)
+#define MPU_REGION_SIZE_128KB ((uint8_t)0x10)
+#define MPU_REGION_SIZE_256KB ((uint8_t)0x11)
+#define MPU_REGION_SIZE_512KB ((uint8_t)0x12)
+#define MPU_REGION_SIZE_1MB ((uint8_t)0x13)
+#define MPU_REGION_SIZE_2MB ((uint8_t)0x14)
+#define MPU_REGION_SIZE_4MB ((uint8_t)0x15)
+#define MPU_REGION_SIZE_8MB ((uint8_t)0x16)
+#define MPU_REGION_SIZE_16MB ((uint8_t)0x17)
+#define MPU_REGION_SIZE_32MB ((uint8_t)0x18)
+#define MPU_REGION_SIZE_64MB ((uint8_t)0x19)
+#define MPU_REGION_SIZE_128MB ((uint8_t)0x1A)
+#define MPU_REGION_SIZE_256MB ((uint8_t)0x1B)
+#define MPU_REGION_SIZE_512MB ((uint8_t)0x1C)
+#define MPU_REGION_SIZE_1GB ((uint8_t)0x1D)
+#define MPU_REGION_SIZE_2GB ((uint8_t)0x1E)
+#define MPU_REGION_SIZE_4GB ((uint8_t)0x1F)
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_MPU_Region_Permission_Attributes CORTEX MPU Region Permission Attributes
+ * @{
+ */
+#define MPU_REGION_NO_ACCESS ((uint8_t)0x00)
+#define MPU_REGION_PRIV_RW ((uint8_t)0x01)
+#define MPU_REGION_PRIV_RW_URO ((uint8_t)0x02)
+#define MPU_REGION_FULL_ACCESS ((uint8_t)0x03)
+#define MPU_REGION_PRIV_RO ((uint8_t)0x05)
+#define MPU_REGION_PRIV_RO_URO ((uint8_t)0x06)
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_MPU_Region_Number CORTEX MPU Region Number
+ * @{
+ */
+#define MPU_REGION_NUMBER0 ((uint8_t)0x00)
+#define MPU_REGION_NUMBER1 ((uint8_t)0x01)
+#define MPU_REGION_NUMBER2 ((uint8_t)0x02)
+#define MPU_REGION_NUMBER3 ((uint8_t)0x03)
+#define MPU_REGION_NUMBER4 ((uint8_t)0x04)
+#define MPU_REGION_NUMBER5 ((uint8_t)0x05)
+#define MPU_REGION_NUMBER6 ((uint8_t)0x06)
+#define MPU_REGION_NUMBER7 ((uint8_t)0x07)
+/**
+ * @}
+ */
+#endif /* __MPU_PRESENT */
+
+/**
+ * @}
+ */
+
+
+/* Exported Macros -----------------------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup CORTEX_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup CORTEX_Exported_Functions_Group1
+ * @{
+ */
+/* Initialization and de-initialization functions *****************************/
+void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup);
+void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority);
+void HAL_NVIC_EnableIRQ(IRQn_Type IRQn);
+void HAL_NVIC_DisableIRQ(IRQn_Type IRQn);
+void HAL_NVIC_SystemReset(void);
+uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb);
+/**
+ * @}
+ */
+
+/** @addtogroup CORTEX_Exported_Functions_Group2
+ * @{
+ */
+/* Peripheral Control functions ***********************************************/
+uint32_t HAL_NVIC_GetPriorityGrouping(void);
+void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority);
+uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn);
+void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn);
+void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn);
+uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn);
+void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource);
+void HAL_SYSTICK_IRQHandler(void);
+void HAL_SYSTICK_Callback(void);
+
+#if (__MPU_PRESENT == 1U)
+void HAL_MPU_Enable(uint32_t MPU_Control);
+void HAL_MPU_Disable(void);
+void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init);
+#endif /* __MPU_PRESENT */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup CORTEX_Private_Macros CORTEX Private Macros
+ * @{
+ */
+#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PRIORITYGROUP_0) || \
+ ((GROUP) == NVIC_PRIORITYGROUP_1) || \
+ ((GROUP) == NVIC_PRIORITYGROUP_2) || \
+ ((GROUP) == NVIC_PRIORITYGROUP_3) || \
+ ((GROUP) == NVIC_PRIORITYGROUP_4))
+
+#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10U)
+
+#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10U)
+
+#define IS_NVIC_DEVICE_IRQ(IRQ) ((IRQ) >= (IRQn_Type)0x00U)
+
+#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SYSTICK_CLKSOURCE_HCLK) || \
+ ((SOURCE) == SYSTICK_CLKSOURCE_HCLK_DIV8))
+
+#if (__MPU_PRESENT == 1U)
+#define IS_MPU_REGION_ENABLE(STATE) (((STATE) == MPU_REGION_ENABLE) || \
+ ((STATE) == MPU_REGION_DISABLE))
+
+#define IS_MPU_INSTRUCTION_ACCESS(STATE) (((STATE) == MPU_INSTRUCTION_ACCESS_ENABLE) || \
+ ((STATE) == MPU_INSTRUCTION_ACCESS_DISABLE))
+
+#define IS_MPU_ACCESS_SHAREABLE(STATE) (((STATE) == MPU_ACCESS_SHAREABLE) || \
+ ((STATE) == MPU_ACCESS_NOT_SHAREABLE))
+
+#define IS_MPU_ACCESS_CACHEABLE(STATE) (((STATE) == MPU_ACCESS_CACHEABLE) || \
+ ((STATE) == MPU_ACCESS_NOT_CACHEABLE))
+
+#define IS_MPU_ACCESS_BUFFERABLE(STATE) (((STATE) == MPU_ACCESS_BUFFERABLE) || \
+ ((STATE) == MPU_ACCESS_NOT_BUFFERABLE))
+
+#define IS_MPU_TEX_LEVEL(TYPE) (((TYPE) == MPU_TEX_LEVEL0) || \
+ ((TYPE) == MPU_TEX_LEVEL1) || \
+ ((TYPE) == MPU_TEX_LEVEL2))
+
+#define IS_MPU_REGION_PERMISSION_ATTRIBUTE(TYPE) (((TYPE) == MPU_REGION_NO_ACCESS) || \
+ ((TYPE) == MPU_REGION_PRIV_RW) || \
+ ((TYPE) == MPU_REGION_PRIV_RW_URO) || \
+ ((TYPE) == MPU_REGION_FULL_ACCESS) || \
+ ((TYPE) == MPU_REGION_PRIV_RO) || \
+ ((TYPE) == MPU_REGION_PRIV_RO_URO))
+
+#define IS_MPU_REGION_NUMBER(NUMBER) (((NUMBER) == MPU_REGION_NUMBER0) || \
+ ((NUMBER) == MPU_REGION_NUMBER1) || \
+ ((NUMBER) == MPU_REGION_NUMBER2) || \
+ ((NUMBER) == MPU_REGION_NUMBER3) || \
+ ((NUMBER) == MPU_REGION_NUMBER4) || \
+ ((NUMBER) == MPU_REGION_NUMBER5) || \
+ ((NUMBER) == MPU_REGION_NUMBER6) || \
+ ((NUMBER) == MPU_REGION_NUMBER7))
+
+#define IS_MPU_REGION_SIZE(SIZE) (((SIZE) == MPU_REGION_SIZE_32B) || \
+ ((SIZE) == MPU_REGION_SIZE_64B) || \
+ ((SIZE) == MPU_REGION_SIZE_128B) || \
+ ((SIZE) == MPU_REGION_SIZE_256B) || \
+ ((SIZE) == MPU_REGION_SIZE_512B) || \
+ ((SIZE) == MPU_REGION_SIZE_1KB) || \
+ ((SIZE) == MPU_REGION_SIZE_2KB) || \
+ ((SIZE) == MPU_REGION_SIZE_4KB) || \
+ ((SIZE) == MPU_REGION_SIZE_8KB) || \
+ ((SIZE) == MPU_REGION_SIZE_16KB) || \
+ ((SIZE) == MPU_REGION_SIZE_32KB) || \
+ ((SIZE) == MPU_REGION_SIZE_64KB) || \
+ ((SIZE) == MPU_REGION_SIZE_128KB) || \
+ ((SIZE) == MPU_REGION_SIZE_256KB) || \
+ ((SIZE) == MPU_REGION_SIZE_512KB) || \
+ ((SIZE) == MPU_REGION_SIZE_1MB) || \
+ ((SIZE) == MPU_REGION_SIZE_2MB) || \
+ ((SIZE) == MPU_REGION_SIZE_4MB) || \
+ ((SIZE) == MPU_REGION_SIZE_8MB) || \
+ ((SIZE) == MPU_REGION_SIZE_16MB) || \
+ ((SIZE) == MPU_REGION_SIZE_32MB) || \
+ ((SIZE) == MPU_REGION_SIZE_64MB) || \
+ ((SIZE) == MPU_REGION_SIZE_128MB) || \
+ ((SIZE) == MPU_REGION_SIZE_256MB) || \
+ ((SIZE) == MPU_REGION_SIZE_512MB) || \
+ ((SIZE) == MPU_REGION_SIZE_1GB) || \
+ ((SIZE) == MPU_REGION_SIZE_2GB) || \
+ ((SIZE) == MPU_REGION_SIZE_4GB))
+
+#define IS_MPU_SUB_REGION_DISABLE(SUBREGION) ((SUBREGION) < (uint16_t)0x00FF)
+#endif /* __MPU_PRESENT */
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_CORTEX_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_crc.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_crc.h
new file mode 100644
index 0000000..1430bf8
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_crc.h
@@ -0,0 +1,193 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_crc.h
+ * @author MCD Application Team
+ * @brief Header file of CRC HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_CRC_H
+#define __STM32F1xx_HAL_CRC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup CRC
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/** @defgroup CRC_Exported_Types CRC Exported Types
+ * @{
+ */
+
+/**
+ * @brief CRC HAL State Structure definition
+ */
+typedef enum
+{
+ HAL_CRC_STATE_RESET = 0x00U, /*!< CRC not yet initialized or disabled */
+ HAL_CRC_STATE_READY = 0x01U, /*!< CRC initialized and ready for use */
+ HAL_CRC_STATE_BUSY = 0x02U, /*!< CRC internal process is ongoing */
+ HAL_CRC_STATE_TIMEOUT = 0x03U, /*!< CRC timeout state */
+ HAL_CRC_STATE_ERROR = 0x04U /*!< CRC error state */
+
+}HAL_CRC_StateTypeDef;
+
+/**
+ * @brief CRC handle Structure definition
+ */
+typedef struct
+{
+ CRC_TypeDef *Instance; /*!< Register base address */
+
+ HAL_LockTypeDef Lock; /*!< CRC locking object */
+
+ __IO HAL_CRC_StateTypeDef State; /*!< CRC communication state */
+
+}CRC_HandleTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+
+/** @defgroup CRC_Exported_Macros CRC Exported Macros
+ * @{
+ */
+
+/** @brief Reset CRC handle state
+ * @param __HANDLE__: CRC handle
+ * @retval None
+ */
+#define __HAL_CRC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_CRC_STATE_RESET)
+
+/**
+ * @brief Resets CRC Data Register.
+ * @param __HANDLE__: CRC handle
+ * @retval None
+ */
+#define __HAL_CRC_DR_RESET(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR,CRC_CR_RESET))
+
+/**
+ * @brief Stores a 8-bit data in the Independent Data(ID) register.
+ * @param __HANDLE__: CRC handle
+ * @param __VALUE__: 8-bit value to be stored in the ID register
+ * @retval None
+ */
+#define __HAL_CRC_SET_IDR(__HANDLE__, __VALUE__) (WRITE_REG((__HANDLE__)->Instance->IDR, (__VALUE__)))
+
+/**
+ * @brief Returns the 8-bit data stored in the Independent Data(ID) register.
+ * @param __HANDLE__: CRC handle
+ * @retval 8-bit value of the ID register
+ */
+#define __HAL_CRC_GET_IDR(__HANDLE__) (((__HANDLE__)->Instance->IDR) & CRC_IDR_IDR)
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @addtogroup CRC_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup CRC_Exported_Functions_Group1
+ * @{
+ */
+
+/* Initialization/de-initialization functions **********************************/
+HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc);
+HAL_StatusTypeDef HAL_CRC_DeInit (CRC_HandleTypeDef *hcrc);
+void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc);
+void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc);
+
+/**
+ * @}
+ */
+
+/** @addtogroup CRC_Exported_Functions_Group2
+ * @{
+ */
+
+/* Peripheral Control functions ************************************************/
+uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength);
+uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength);
+
+
+/**
+ * @}
+ */
+
+/** @addtogroup CRC_Exported_Functions_Group3
+ ** @{
+ */
+
+/* Peripheral State functions **************************************************/
+HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc);
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_CRC_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dac.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dac.h
new file mode 100644
index 0000000..3ea0317
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dac.h
@@ -0,0 +1,322 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_dac.h
+ * @author MCD Application Team
+ * @brief Header file of DAC HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_DAC_H
+#define __STM32F1xx_HAL_DAC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#if defined (STM32F100xB) || defined (STM32F100xE) || defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup DAC
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/** @defgroup DAC_Exported_Types DAC Exported Types
+ * @{
+ */
+
+/**
+ * @brief HAL State structures definition
+ */
+typedef enum
+{
+ HAL_DAC_STATE_RESET = 0x00U, /*!< DAC not yet initialized or disabled */
+ HAL_DAC_STATE_READY = 0x01U, /*!< DAC initialized and ready for use */
+ HAL_DAC_STATE_BUSY = 0x02U, /*!< DAC internal processing is ongoing */
+ HAL_DAC_STATE_TIMEOUT = 0x03U, /*!< DAC timeout state */
+ HAL_DAC_STATE_ERROR = 0x04U /*!< DAC error state */
+
+}HAL_DAC_StateTypeDef;
+
+/**
+ * @brief DAC handle Structure definition
+ */
+typedef struct
+{
+ DAC_TypeDef *Instance; /*!< Register base address */
+
+ __IO HAL_DAC_StateTypeDef State; /*!< DAC communication state */
+
+ HAL_LockTypeDef Lock; /*!< DAC locking object */
+
+ DMA_HandleTypeDef *DMA_Handle1; /*!< Pointer DMA handler for channel 1 */
+
+ DMA_HandleTypeDef *DMA_Handle2; /*!< Pointer DMA handler for channel 2 */
+
+ __IO uint32_t ErrorCode; /*!< DAC Error code */
+
+}DAC_HandleTypeDef;
+
+/**
+ * @brief DAC Configuration regular Channel structure definition
+ */
+typedef struct
+{
+ uint32_t DAC_Trigger; /*!< Specifies the external trigger for the selected DAC channel.
+ This parameter can be a value of @ref DACEx_trigger_selection
+ Note: For STM32F100x high-density value line devices, additional trigger sources are available. */
+
+ uint32_t DAC_OutputBuffer; /*!< Specifies whether the DAC channel output buffer is enabled or disabled.
+ This parameter can be a value of @ref DAC_output_buffer */
+
+}DAC_ChannelConfTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup DAC_Exported_Constants DAC Exported Constants
+ * @{
+ */
+
+/** @defgroup DAC_Error_Code DAC Error Code
+ * @{
+ */
+#define HAL_DAC_ERROR_NONE 0x00000000U /*!< No error */
+#define HAL_DAC_ERROR_DMAUNDERRUNCH1 0x00000001U /*!< DAC channel1 DMA underrun error */
+#define HAL_DAC_ERROR_DMAUNDERRUNCH2 0x00000002U /*!< DAC channel2 DMA underrun error */
+#define HAL_DAC_ERROR_DMA 0x00000004U /*!< DMA error */
+/**
+ * @}
+ */
+
+/** @defgroup DAC_output_buffer DAC output buffer
+ * @{
+ */
+#define DAC_OUTPUTBUFFER_ENABLE 0x00000000U
+#define DAC_OUTPUTBUFFER_DISABLE ((uint32_t)DAC_CR_BOFF1)
+
+/**
+ * @}
+ */
+
+/** @defgroup DAC_Channel_selection DAC Channel selection
+ * @{
+ */
+#define DAC_CHANNEL_1 0x00000000U
+#define DAC_CHANNEL_2 0x00000010U
+
+/**
+ * @}
+ */
+
+/** @defgroup DAC_data_alignement DAC data alignement
+ * @{
+ */
+#define DAC_ALIGN_12B_R 0x00000000U
+#define DAC_ALIGN_12B_L 0x00000004U
+#define DAC_ALIGN_8B_R 0x00000008U
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+
+/** @defgroup DAC_Exported_Macros DAC Exported Macros
+ * @{
+ */
+
+/** @brief Reset DAC handle state
+ * @param __HANDLE__: specifies the DAC handle.
+ * @retval None
+ */
+#define __HAL_DAC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_DAC_STATE_RESET)
+
+/** @brief Enable the DAC channel
+ * @param __HANDLE__: specifies the DAC handle.
+ * @param __DAC_Channel__: specifies the DAC channel
+ * @retval None
+ */
+#define __HAL_DAC_ENABLE(__HANDLE__, __DAC_Channel__) \
+((__HANDLE__)->Instance->CR |= (DAC_CR_EN1 << (__DAC_Channel__)))
+
+/** @brief Disable the DAC channel
+ * @param __HANDLE__: specifies the DAC handle
+ * @param __DAC_Channel__: specifies the DAC channel.
+ * @retval None
+ */
+#define __HAL_DAC_DISABLE(__HANDLE__, __DAC_Channel__) \
+((__HANDLE__)->Instance->CR &= ~(DAC_CR_EN1 << (__DAC_Channel__)))
+
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+
+/** @defgroup DAC_Private_Macros DAC Private Macros
+ * @{
+ */
+#define IS_DAC_OUTPUT_BUFFER_STATE(STATE) (((STATE) == DAC_OUTPUTBUFFER_ENABLE) || \
+ ((STATE) == DAC_OUTPUTBUFFER_DISABLE))
+
+#define IS_DAC_CHANNEL(CHANNEL) (((CHANNEL) == DAC_CHANNEL_1) || \
+ ((CHANNEL) == DAC_CHANNEL_2))
+
+#define IS_DAC_ALIGN(ALIGN) (((ALIGN) == DAC_ALIGN_12B_R) || \
+ ((ALIGN) == DAC_ALIGN_12B_L) || \
+ ((ALIGN) == DAC_ALIGN_8B_R))
+
+#define IS_DAC_DATA(DATA) ((DATA) <= 0xFFF0U)
+
+#define DAC_DHR12R1_ALIGNMENT(__ALIGNMENT__) (0x00000008U + (__ALIGNMENT__))
+
+#define DAC_DHR12R2_ALIGNMENT(__ALIGNMENT__) (0x00000014U + (__ALIGNMENT__))
+
+#define DAC_DHR12RD_ALIGNMENT(__ALIGNMENT__) (0x00000020U + (__ALIGNMENT__))
+
+/**
+ * @}
+ */
+
+
+/* Include DAC HAL Extension module */
+#include "stm32f1xx_hal_dac_ex.h"
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @addtogroup DAC_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup DAC_Exported_Functions_Group1
+ * @{
+ */
+/* Initialization and de-initialization functions *****************************/
+HAL_StatusTypeDef HAL_DAC_Init(DAC_HandleTypeDef* hdac);
+HAL_StatusTypeDef HAL_DAC_DeInit(DAC_HandleTypeDef* hdac);
+void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac);
+void HAL_DAC_MspDeInit(DAC_HandleTypeDef* hdac);
+
+/**
+ * @}
+ */
+
+/** @addtogroup DAC_Exported_Functions_Group2
+ * @{
+ */
+/* IO operation functions *****************************************************/
+HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef* hdac, uint32_t Channel);
+HAL_StatusTypeDef HAL_DAC_Stop(DAC_HandleTypeDef* hdac, uint32_t Channel);
+HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t* pData, uint32_t Length, uint32_t Alignment);
+HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel);
+HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data);
+uint32_t HAL_DAC_GetValue(DAC_HandleTypeDef* hdac, uint32_t Channel);
+
+/**
+ * @}
+ */
+
+/** @addtogroup DAC_Exported_Functions_Group3
+ * @{
+ */
+/* Peripheral Control functions ***********************************************/
+HAL_StatusTypeDef HAL_DAC_ConfigChannel(DAC_HandleTypeDef* hdac, DAC_ChannelConfTypeDef* sConfig, uint32_t Channel);
+
+/**
+ * @}
+ */
+
+/** @addtogroup DAC_Exported_Functions_Group4
+ * @{
+ */
+/* Peripheral State functions *************************************************/
+HAL_DAC_StateTypeDef HAL_DAC_GetState(DAC_HandleTypeDef* hdac);
+uint32_t HAL_DAC_GetError(DAC_HandleTypeDef *hdac);
+
+void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef* hdac);
+void HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef* hdac);
+void HAL_DAC_ErrorCallbackCh1(DAC_HandleTypeDef *hdac);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup DAC_Private_Functions DAC Private Functions
+ * @{
+ */
+void DAC_DMAConvCpltCh1(DMA_HandleTypeDef *hdma);
+void DAC_DMAHalfConvCpltCh1(DMA_HandleTypeDef *hdma);
+void DAC_DMAErrorCh1(DMA_HandleTypeDef *hdma);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F100xB || STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /*__STM32F1xx_HAL_DAC_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dac_ex.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dac_ex.h
new file mode 100644
index 0000000..520b87b
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dac_ex.h
@@ -0,0 +1,370 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_dac_ex.h
+ * @author MCD Application Team
+ * @brief Header file of DAC HAL Extension module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_DAC_EX_H
+#define __STM32F1xx_HAL_DAC_EX_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#if defined (STM32F100xB) || defined (STM32F100xE) || defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup DACEx
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup DACEx_Exported_Constants DACEx Exported Constants
+ * @{
+ */
+
+/** @defgroup DACEx_lfsrunmask_triangleamplitude DACEx lfsrunmask triangleamplitude
+ * @{
+ */
+#define DAC_LFSRUNMASK_BIT0 0x00000000U /*!< Unmask DAC channel LFSR bit0 for noise wave generation */
+#define DAC_LFSRUNMASK_BITS1_0 ((uint32_t)DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[1:0] for noise wave generation */
+#define DAC_LFSRUNMASK_BITS2_0 ((uint32_t)DAC_CR_MAMP1_1) /*!< Unmask DAC channel LFSR bit[2:0] for noise wave generation */
+#define DAC_LFSRUNMASK_BITS3_0 ((uint32_t)DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0)/*!< Unmask DAC channel LFSR bit[3:0] for noise wave generation */
+#define DAC_LFSRUNMASK_BITS4_0 ((uint32_t)DAC_CR_MAMP1_2) /*!< Unmask DAC channel LFSR bit[4:0] for noise wave generation */
+#define DAC_LFSRUNMASK_BITS5_0 ((uint32_t)DAC_CR_MAMP1_2 | DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[5:0] for noise wave generation */
+#define DAC_LFSRUNMASK_BITS6_0 ((uint32_t)DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1) /*!< Unmask DAC channel LFSR bit[6:0] for noise wave generation */
+#define DAC_LFSRUNMASK_BITS7_0 ((uint32_t)DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[7:0] for noise wave generation */
+#define DAC_LFSRUNMASK_BITS8_0 ((uint32_t)DAC_CR_MAMP1_3) /*!< Unmask DAC channel LFSR bit[8:0] for noise wave generation */
+#define DAC_LFSRUNMASK_BITS9_0 ((uint32_t)DAC_CR_MAMP1_3 | DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[9:0] for noise wave generation */
+#define DAC_LFSRUNMASK_BITS10_0 ((uint32_t)DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1) /*!< Unmask DAC channel LFSR bit[10:0] for noise wave generation */
+#define DAC_LFSRUNMASK_BITS11_0 ((uint32_t)DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[11:0] for noise wave generation */
+#define DAC_TRIANGLEAMPLITUDE_1 0x00000000U /*!< Select max triangle amplitude of 1 */
+#define DAC_TRIANGLEAMPLITUDE_3 ((uint32_t)DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 3 */
+#define DAC_TRIANGLEAMPLITUDE_7 ((uint32_t)DAC_CR_MAMP1_1) /*!< Select max triangle amplitude of 7 */
+#define DAC_TRIANGLEAMPLITUDE_15 ((uint32_t)DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 15 */
+#define DAC_TRIANGLEAMPLITUDE_31 ((uint32_t)DAC_CR_MAMP1_2) /*!< Select max triangle amplitude of 31 */
+#define DAC_TRIANGLEAMPLITUDE_63 ((uint32_t)DAC_CR_MAMP1_2 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 63 */
+#define DAC_TRIANGLEAMPLITUDE_127 ((uint32_t)DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1) /*!< Select max triangle amplitude of 127 */
+#define DAC_TRIANGLEAMPLITUDE_255 ((uint32_t)DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 255 */
+#define DAC_TRIANGLEAMPLITUDE_511 ((uint32_t)DAC_CR_MAMP1_3) /*!< Select max triangle amplitude of 511 */
+#define DAC_TRIANGLEAMPLITUDE_1023 ((uint32_t)DAC_CR_MAMP1_3 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 1023 */
+#define DAC_TRIANGLEAMPLITUDE_2047 ((uint32_t)DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1) /*!< Select max triangle amplitude of 2047 */
+#define DAC_TRIANGLEAMPLITUDE_4095 ((uint32_t)DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 4095 */
+
+/**
+ * @}
+ */
+
+/** @defgroup DACEx_trigger_selection DAC trigger selection
+ * @{
+ */
+#define DAC_TRIGGER_NONE 0x00000000U /*!< Conversion is automatic once the DAC1_DHRxxxx register
+ has been loaded, and not by external trigger */
+#define DAC_TRIGGER_T6_TRGO ((uint32_t) DAC_CR_TEN1) /*!< TIM6 TRGO selected as external conversion trigger for DAC channel */
+#define DAC_TRIGGER_T7_TRGO ((uint32_t)( DAC_CR_TSEL1_1 | DAC_CR_TEN1)) /*!< TIM7 TRGO selected as external conversion trigger for DAC channel */
+#define DAC_TRIGGER_T2_TRGO ((uint32_t)(DAC_CR_TSEL1_2 | DAC_CR_TEN1)) /*!< TIM2 TRGO selected as external conversion trigger for DAC channel */
+#define DAC_TRIGGER_T4_TRGO ((uint32_t)(DAC_CR_TSEL1_2 | DAC_CR_TSEL1_0 | DAC_CR_TEN1)) /*!< TIM4 TRGO selected as external conversion trigger for DAC channel */
+#define DAC_TRIGGER_EXT_IT9 ((uint32_t)(DAC_CR_TSEL1_2 | DAC_CR_TSEL1_1 | DAC_CR_TEN1)) /*!< EXTI Line9 event selected as external conversion trigger for DAC channel */
+#define DAC_TRIGGER_SOFTWARE ((uint32_t)(DAC_CR_TSEL1 | DAC_CR_TEN1)) /*!< Conversion started by software trigger for DAC channel */
+
+#if defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG)
+/* For STM32F10x high-density and XL-density devices: TIM8 */
+#define DAC_TRIGGER_T8_TRGO ((uint32_t) DAC_CR_TSEL1_0 | DAC_CR_TEN1) /*!< TIM8 TRGO selected as external conversion trigger for DAC channel */
+#endif /* STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
+
+#if defined (STM32F100xB) || defined (STM32F100xE) || defined (STM32F105xC) || defined (STM32F107xC)
+/* For STM32F10x connectivity line devices and STM32F100x devices: TIM3 */
+#define DAC_TRIGGER_T3_TRGO ((uint32_t) DAC_CR_TSEL1_0 | DAC_CR_TEN1) /*!< TIM3 TRGO selected as external conversion trigger for DAC channel */
+#endif /* STM32F100xB || STM32F100xE || STM32F105xC || STM32F107xC */
+
+/* Availability of trigger from TIM5 and TIM15: */
+/* - For STM32F10x value line devices STM32F100xB: */
+/* trigger from TIM15 is available, TIM5 not available. */
+/* - For STM32F10x value line devices STM32F100xE: */
+/* trigger from TIM15 and TIM5 are both available, */
+/* selection depends on remap (with TIM5 as default configuration). */
+/* - Other STM32F1 devices: */
+/* trigger from TIM5 is available, TIM15 not available. */
+#if defined (STM32F100xB)
+#define DAC_TRIGGER_T15_TRGO ((uint32_t)( DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0 | DAC_CR_TEN1)) /*!< TIM15 TRGO selected as external conversion trigger for DAC channel */
+#else
+
+#define DAC_TRIGGER_T5_TRGO ((uint32_t)( DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0 | DAC_CR_TEN1)) /*!< TIM5 TRGO selected as external conversion trigger for DAC channel */
+
+#if defined (STM32F100xE)
+/*!< DAC trigger availability depending on STM32F1 devices:
+ For STM32F100x high-density value line devices, the TIM15 TRGO event can be selected
+ as replacement of TIM5 TRGO if the MISC_REMAP bit in the AFIO_MAPR2 register is set.
+ Refer to macro "__HAL_AFIO_REMAP_MISC_ENABLE()/__HAL_AFIO_REMAP_MISC_DISABLE()".
+ Otherwise, TIM5 TRGO is used and TIM15 TRGO is not used (default case).
+ For more details please refer to the AFIO section. */
+#define DAC_TRIGGER_T15_TRGO DAC_TRIGGER_T5_TRGO
+#endif /* STM32F100xE */
+
+#endif /* STM32F100xB */
+/**
+ * @}
+ */
+
+#if defined (STM32F100xB) || defined (STM32F100xE)
+/** @defgroup DAC_flags_definition DAC flags definition
+ * @{
+ */
+#define DAC_FLAG_DMAUDR1 ((uint32_t)DAC_SR_DMAUDR1)
+#define DAC_FLAG_DMAUDR2 ((uint32_t)DAC_SR_DMAUDR2)
+
+/**
+ * @}
+ */
+
+/** @defgroup DAC_IT_definition DAC IT definition
+ * @{
+ */
+#define DAC_IT_DMAUDR1 ((uint32_t)DAC_SR_DMAUDR1)
+#define DAC_IT_DMAUDR2 ((uint32_t)DAC_SR_DMAUDR2)
+
+/**
+ * @}
+ */
+#endif /* STM32F100xB || STM32F100xE */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+
+#if defined (STM32F100xB) || defined (STM32F100xE)
+/** @defgroup DACEx_Exported_Macros DACEx Exported Macros
+ * @{
+ */
+
+/** @brief Enable the DAC interrupt
+ * @param __HANDLE__: specifies the DAC handle
+ * @param __INTERRUPT__: specifies the DAC interrupt.
+ * This parameter can be any combination of the following values:
+ * @arg DAC_IT_DMAUDR1: DAC channel 1 DMA underrun interrupt
+ * @arg DAC_IT_DMAUDR2: DAC channel 2 DMA underrun interrupt
+ * @retval None
+ */
+#define __HAL_DAC_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CR) |= (__INTERRUPT__))
+
+/** @brief Disable the DAC interrupt
+ * @param __HANDLE__: specifies the DAC handle
+ * @param __INTERRUPT__: specifies the DAC interrupt.
+ * This parameter can be any combination of the following values:
+ * @arg DAC_IT_DMAUDR1: DAC channel 1 DMA underrun interrupt
+ * @arg DAC_IT_DMAUDR2: DAC channel 2 DMA underrun interrupt
+ * @retval None
+ */
+#define __HAL_DAC_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CR) &= ~(__INTERRUPT__))
+
+/** @brief Checks if the specified DAC interrupt source is enabled or disabled.
+ * @param __HANDLE__: DAC handle
+ * @param __INTERRUPT__: DAC interrupt source to check
+ * This parameter can be any combination of the following values:
+ * @arg DAC_IT_DMAUDR1: DAC channel 1 DMA underrun interrupt
+ * @arg DAC_IT_DMAUDR2: DAC channel 2 DMA underrun interrupt
+ * @retval State of interruption (SET or RESET)
+ */
+#define __HAL_DAC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CR & (__INTERRUPT__)) == (__INTERRUPT__))
+
+/** @brief Get the selected DAC's flag status.
+ * @param __HANDLE__: specifies the DAC handle.
+ * @param __FLAG__: specifies the DAC flag to get.
+ * This parameter can be any combination of the following values:
+ * @arg DAC_FLAG_DMAUDR1: DAC channel 1 DMA underrun flag
+ * @arg DAC_FLAG_DMAUDR2: DAC channel 2 DMA underrun flag
+ * @retval None
+ */
+#define __HAL_DAC_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__))
+
+/** @brief Clear the DAC's flag.
+ * @param __HANDLE__: specifies the DAC handle.
+ * @param __FLAG__: specifies the DAC flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg DAC_FLAG_DMAUDR1: DAC channel 1 DMA underrun flag
+ * @arg DAC_FLAG_DMAUDR2: DAC channel 2 DMA underrun flag
+ * @retval None
+ */
+#define __HAL_DAC_CLEAR_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR) = (__FLAG__))
+
+
+/**
+ * @}
+ */
+#endif /* STM32F100xB || STM32F100xE */
+
+/* Private macro -------------------------------------------------------------*/
+
+/** @defgroup DACEx_Private_Macros DACEx Private Macros
+ * @{
+ */
+#if defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG)
+#define IS_DAC_TRIGGER(TRIGGER) (((TRIGGER) == DAC_TRIGGER_NONE) || \
+ ((TRIGGER) == DAC_TRIGGER_T6_TRGO) || \
+ ((TRIGGER) == DAC_TRIGGER_T8_TRGO) || \
+ ((TRIGGER) == DAC_TRIGGER_T7_TRGO) || \
+ ((TRIGGER) == DAC_TRIGGER_T5_TRGO) || \
+ ((TRIGGER) == DAC_TRIGGER_T2_TRGO) || \
+ ((TRIGGER) == DAC_TRIGGER_T4_TRGO) || \
+ ((TRIGGER) == DAC_TRIGGER_EXT_IT9) || \
+ ((TRIGGER) == DAC_TRIGGER_SOFTWARE))
+#endif /* STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
+#if defined (STM32F100xE) || defined (STM32F105xC) || defined (STM32F107xC)
+#define IS_DAC_TRIGGER(TRIGGER) (((TRIGGER) == DAC_TRIGGER_NONE) || \
+ ((TRIGGER) == DAC_TRIGGER_T6_TRGO) || \
+ ((TRIGGER) == DAC_TRIGGER_T3_TRGO) || \
+ ((TRIGGER) == DAC_TRIGGER_T7_TRGO) || \
+ ((TRIGGER) == DAC_TRIGGER_T5_TRGO) || \
+ ((TRIGGER) == DAC_TRIGGER_T2_TRGO) || \
+ ((TRIGGER) == DAC_TRIGGER_T4_TRGO) || \
+ ((TRIGGER) == DAC_TRIGGER_EXT_IT9) || \
+ ((TRIGGER) == DAC_TRIGGER_SOFTWARE))
+#endif /* STM32F100xE || STM32F105xC || STM32F107xC */
+#if defined (STM32F100xB)
+#define IS_DAC_TRIGGER(TRIGGER) (((TRIGGER) == DAC_TRIGGER_NONE) || \
+ ((TRIGGER) == DAC_TRIGGER_T6_TRGO) || \
+ ((TRIGGER) == DAC_TRIGGER_T3_TRGO) || \
+ ((TRIGGER) == DAC_TRIGGER_T7_TRGO) || \
+ ((TRIGGER) == DAC_TRIGGER_T15_TRGO) || \
+ ((TRIGGER) == DAC_TRIGGER_T2_TRGO) || \
+ ((TRIGGER) == DAC_TRIGGER_T4_TRGO) || \
+ ((TRIGGER) == DAC_TRIGGER_EXT_IT9) || \
+ ((TRIGGER) == DAC_TRIGGER_SOFTWARE))
+#endif /* STM32F100xB */
+
+#define IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(VALUE) (((VALUE) == DAC_LFSRUNMASK_BIT0) || \
+ ((VALUE) == DAC_LFSRUNMASK_BITS1_0) || \
+ ((VALUE) == DAC_LFSRUNMASK_BITS2_0) || \
+ ((VALUE) == DAC_LFSRUNMASK_BITS3_0) || \
+ ((VALUE) == DAC_LFSRUNMASK_BITS4_0) || \
+ ((VALUE) == DAC_LFSRUNMASK_BITS5_0) || \
+ ((VALUE) == DAC_LFSRUNMASK_BITS6_0) || \
+ ((VALUE) == DAC_LFSRUNMASK_BITS7_0) || \
+ ((VALUE) == DAC_LFSRUNMASK_BITS8_0) || \
+ ((VALUE) == DAC_LFSRUNMASK_BITS9_0) || \
+ ((VALUE) == DAC_LFSRUNMASK_BITS10_0) || \
+ ((VALUE) == DAC_LFSRUNMASK_BITS11_0) || \
+ ((VALUE) == DAC_TRIANGLEAMPLITUDE_1) || \
+ ((VALUE) == DAC_TRIANGLEAMPLITUDE_3) || \
+ ((VALUE) == DAC_TRIANGLEAMPLITUDE_7) || \
+ ((VALUE) == DAC_TRIANGLEAMPLITUDE_15) || \
+ ((VALUE) == DAC_TRIANGLEAMPLITUDE_31) || \
+ ((VALUE) == DAC_TRIANGLEAMPLITUDE_63) || \
+ ((VALUE) == DAC_TRIANGLEAMPLITUDE_127) || \
+ ((VALUE) == DAC_TRIANGLEAMPLITUDE_255) || \
+ ((VALUE) == DAC_TRIANGLEAMPLITUDE_511) || \
+ ((VALUE) == DAC_TRIANGLEAMPLITUDE_1023) || \
+ ((VALUE) == DAC_TRIANGLEAMPLITUDE_2047) || \
+ ((VALUE) == DAC_TRIANGLEAMPLITUDE_4095))
+
+/**
+ * @}
+ */
+
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @addtogroup DACEx_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup DACEx_Exported_Functions_Group1
+ * @{
+ */
+/* Extension features functions ***********************************************/
+
+uint32_t HAL_DACEx_DualGetValue(DAC_HandleTypeDef* hdac);
+HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Amplitude);
+HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Amplitude);
+HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef* hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2);
+
+void HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef* hdac);
+void HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef* hdac);
+void HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef* hdac);
+
+#if defined (STM32F100xB) || defined (STM32F100xE)
+void HAL_DAC_IRQHandler(DAC_HandleTypeDef* hdac);
+void HAL_DAC_DMAUnderrunCallbackCh1(DAC_HandleTypeDef *hdac);
+void HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef* hdac);
+#endif /* STM32F100xB) || defined (STM32F100xE) */
+
+/**
+ * @}
+ */
+
+
+
+
+/**
+ * @}
+ */
+
+/** @addtogroup DACEx_Private_Functions
+ * @{
+ */
+void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma);
+void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma);
+void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F100xB || STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F1xx_HAL_DAC_EX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h
new file mode 100644
index 0000000..0a0e54f
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h
@@ -0,0 +1,214 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_def.h
+ * @author MCD Application Team
+ * @brief This file contains HAL common defines, enumeration, macros and
+ * structures definitions.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_DEF
+#define __STM32F1xx_HAL_DEF
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx.h"
+#if defined(USE_HAL_LEGACY)
+#include "Legacy/stm32_hal_legacy.h"
+#endif
+#include
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief HAL Status structures definition
+ */
+typedef enum
+{
+ HAL_OK = 0x00U,
+ HAL_ERROR = 0x01U,
+ HAL_BUSY = 0x02U,
+ HAL_TIMEOUT = 0x03U
+} HAL_StatusTypeDef;
+
+/**
+ * @brief HAL Lock structures definition
+ */
+typedef enum
+{
+ HAL_UNLOCKED = 0x00U,
+ HAL_LOCKED = 0x01U
+} HAL_LockTypeDef;
+
+/* Exported macro ------------------------------------------------------------*/
+#define HAL_MAX_DELAY 0xFFFFFFFFU
+
+#define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) != 0U)
+#define HAL_IS_BIT_CLR(REG, BIT) (((REG) & (BIT)) == 0U)
+
+#define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD__, __DMA_HANDLE__) \
+ do{ \
+ (__HANDLE__)->__PPP_DMA_FIELD__ = &(__DMA_HANDLE__); \
+ (__DMA_HANDLE__).Parent = (__HANDLE__); \
+ } while(0U)
+
+#define UNUSED(X) (void)X /* To avoid gcc/g++ warnings */
+
+/** @brief Reset the Handle's State field.
+ * @param __HANDLE__: specifies the Peripheral Handle.
+ * @note This macro can be used for the following purpose:
+ * - When the Handle is declared as local variable; before passing it as parameter
+ * to HAL_PPP_Init() for the first time, it is mandatory to use this macro
+ * to set to 0 the Handle's "State" field.
+ * Otherwise, "State" field may have any random value and the first time the function
+ * HAL_PPP_Init() is called, the low level hardware initialization will be missed
+ * (i.e. HAL_PPP_MspInit() will not be executed).
+ * - When there is a need to reconfigure the low level hardware: instead of calling
+ * HAL_PPP_DeInit() then HAL_PPP_Init(), user can make a call to this macro then HAL_PPP_Init().
+ * In this later function, when the Handle's "State" field is set to 0, it will execute the function
+ * HAL_PPP_MspInit() which will reconfigure the low level hardware.
+ * @retval None
+ */
+#define __HAL_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = 0U)
+
+#if (USE_RTOS == 1U)
+/* Reserved for future use */
+#error "USE_RTOS should be 0 in the current HAL release"
+#else
+#define __HAL_LOCK(__HANDLE__) \
+ do{ \
+ if((__HANDLE__)->Lock == HAL_LOCKED) \
+ { \
+ return HAL_BUSY; \
+ } \
+ else \
+ { \
+ (__HANDLE__)->Lock = HAL_LOCKED; \
+ } \
+ }while (0U)
+
+#define __HAL_UNLOCK(__HANDLE__) \
+ do{ \
+ (__HANDLE__)->Lock = HAL_UNLOCKED; \
+ }while (0U)
+#endif /* USE_RTOS */
+
+#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */
+#ifndef __weak
+#define __weak __attribute__((weak))
+#endif /* __weak */
+#ifndef __packed
+#define __packed __attribute__((__packed__))
+#endif /* __packed */
+#endif /* __GNUC__ */
+
+
+/* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma data_alignment=4" must be used instead */
+#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */
+#ifndef __ALIGN_END
+#define __ALIGN_END __attribute__ ((aligned (4)))
+#endif /* __ALIGN_END */
+#ifndef __ALIGN_BEGIN
+#define __ALIGN_BEGIN
+#endif /* __ALIGN_BEGIN */
+#else
+#ifndef __ALIGN_END
+#define __ALIGN_END
+#endif /* __ALIGN_END */
+#ifndef __ALIGN_BEGIN
+#if defined (__CC_ARM) /* ARM Compiler */
+#define __ALIGN_BEGIN __align(4)
+#elif defined (__ICCARM__) /* IAR Compiler */
+#define __ALIGN_BEGIN
+#endif /* __CC_ARM */
+#endif /* __ALIGN_BEGIN */
+#endif /* __GNUC__ */
+
+
+/**
+ * @brief __RAM_FUNC definition
+ */
+#if defined ( __CC_ARM )
+/* ARM Compiler
+ ------------
+ RAM functions are defined using the toolchain options.
+ Functions that are executed in RAM should reside in a separate source module.
+ Using the 'Options for File' dialog you can simply change the 'Code / Const'
+ area of a module to a memory space in physical RAM.
+ Available memory areas are declared in the 'Target' tab of the 'Options for Target'
+ dialog.
+*/
+#define __RAM_FUNC
+
+#elif defined ( __ICCARM__ )
+/* ICCARM Compiler
+ ---------------
+ RAM functions are defined using a specific toolchain keyword "__ramfunc".
+*/
+#define __RAM_FUNC __ramfunc
+
+#elif defined ( __GNUC__ )
+/* GNU Compiler
+ ------------
+ RAM functions are defined using a specific toolchain attribute
+ "__attribute__((section(".RamFunc")))".
+*/
+#define __RAM_FUNC __attribute__((section(".RamFunc")))
+
+#endif
+
+/**
+ * @brief __NOINLINE definition
+ */
+#if defined ( __CC_ARM ) || defined ( __GNUC__ )
+/* ARM & GNUCompiler
+ ----------------
+*/
+#define __NOINLINE __attribute__ ( (noinline) )
+
+#elif defined ( __ICCARM__ )
+/* ICCARM Compiler
+ ---------------
+*/
+#define __NOINLINE _Pragma("optimize = no_inline")
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ___STM32F1xx_HAL_DEF */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h
new file mode 100644
index 0000000..524f61f
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h
@@ -0,0 +1,473 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_dma.h
+ * @author MCD Application Team
+ * @brief Header file of DMA HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_DMA_H
+#define __STM32F1xx_HAL_DMA_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup DMA
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/** @defgroup DMA_Exported_Types DMA Exported Types
+ * @{
+ */
+
+/**
+ * @brief DMA Configuration Structure definition
+ */
+typedef struct
+{
+ uint32_t Direction; /*!< Specifies if the data will be transferred from memory to peripheral,
+ from memory to memory or from peripheral to memory.
+ This parameter can be a value of @ref DMA_Data_transfer_direction */
+
+ uint32_t PeriphInc; /*!< Specifies whether the Peripheral address register should be incremented or not.
+ This parameter can be a value of @ref DMA_Peripheral_incremented_mode */
+
+ uint32_t MemInc; /*!< Specifies whether the memory address register should be incremented or not.
+ This parameter can be a value of @ref DMA_Memory_incremented_mode */
+
+ uint32_t PeriphDataAlignment; /*!< Specifies the Peripheral data width.
+ This parameter can be a value of @ref DMA_Peripheral_data_size */
+
+ uint32_t MemDataAlignment; /*!< Specifies the Memory data width.
+ This parameter can be a value of @ref DMA_Memory_data_size */
+
+ uint32_t Mode; /*!< Specifies the operation mode of the DMAy Channelx.
+ This parameter can be a value of @ref DMA_mode
+ @note The circular buffer mode cannot be used if the memory-to-memory
+ data transfer is configured on the selected Channel */
+
+ uint32_t Priority; /*!< Specifies the software priority for the DMAy Channelx.
+ This parameter can be a value of @ref DMA_Priority_level */
+} DMA_InitTypeDef;
+
+/**
+ * @brief HAL DMA State structures definition
+ */
+typedef enum
+{
+ HAL_DMA_STATE_RESET = 0x00U, /*!< DMA not yet initialized or disabled */
+ HAL_DMA_STATE_READY = 0x01U, /*!< DMA initialized and ready for use */
+ HAL_DMA_STATE_BUSY = 0x02U, /*!< DMA process is ongoing */
+ HAL_DMA_STATE_TIMEOUT = 0x03U /*!< DMA timeout state */
+}HAL_DMA_StateTypeDef;
+
+/**
+ * @brief HAL DMA Error Code structure definition
+ */
+typedef enum
+{
+ HAL_DMA_FULL_TRANSFER = 0x00U, /*!< Full transfer */
+ HAL_DMA_HALF_TRANSFER = 0x01U /*!< Half Transfer */
+}HAL_DMA_LevelCompleteTypeDef;
+
+/**
+ * @brief HAL DMA Callback ID structure definition
+ */
+typedef enum
+{
+ HAL_DMA_XFER_CPLT_CB_ID = 0x00U, /*!< Full transfer */
+ HAL_DMA_XFER_HALFCPLT_CB_ID = 0x01U, /*!< Half transfer */
+ HAL_DMA_XFER_ERROR_CB_ID = 0x02U, /*!< Error */
+ HAL_DMA_XFER_ABORT_CB_ID = 0x03U, /*!< Abort */
+ HAL_DMA_XFER_ALL_CB_ID = 0x04U /*!< All */
+
+}HAL_DMA_CallbackIDTypeDef;
+
+/**
+ * @brief DMA handle Structure definition
+ */
+typedef struct __DMA_HandleTypeDef
+{
+ DMA_Channel_TypeDef *Instance; /*!< Register base address */
+
+ DMA_InitTypeDef Init; /*!< DMA communication parameters */
+
+ HAL_LockTypeDef Lock; /*!< DMA locking object */
+
+ HAL_DMA_StateTypeDef State; /*!< DMA transfer state */
+
+ void *Parent; /*!< Parent object state */
+
+ void (* XferCpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer complete callback */
+
+ void (* XferHalfCpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA Half transfer complete callback */
+
+ void (* XferErrorCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer error callback */
+
+ void (* XferAbortCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer abort callback */
+
+ __IO uint32_t ErrorCode; /*!< DMA Error code */
+
+ DMA_TypeDef *DmaBaseAddress; /*!< DMA Channel Base Address */
+
+ uint32_t ChannelIndex; /*!< DMA Channel Index */
+
+} DMA_HandleTypeDef;
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup DMA_Exported_Constants DMA Exported Constants
+ * @{
+ */
+
+/** @defgroup DMA_Error_Code DMA Error Code
+ * @{
+ */
+#define HAL_DMA_ERROR_NONE 0x00000000U /*!< No error */
+#define HAL_DMA_ERROR_TE 0x00000001U /*!< Transfer error */
+#define HAL_DMA_ERROR_NO_XFER 0x00000004U /*!< no ongoing transfer */
+#define HAL_DMA_ERROR_TIMEOUT 0x00000020U /*!< Timeout error */
+#define HAL_DMA_ERROR_NOT_SUPPORTED 0x00000100U /*!< Not supported mode */
+/**
+ * @}
+ */
+
+/** @defgroup DMA_Data_transfer_direction DMA Data transfer direction
+ * @{
+ */
+#define DMA_PERIPH_TO_MEMORY 0x00000000U /*!< Peripheral to memory direction */
+#define DMA_MEMORY_TO_PERIPH ((uint32_t)DMA_CCR_DIR) /*!< Memory to peripheral direction */
+#define DMA_MEMORY_TO_MEMORY ((uint32_t)DMA_CCR_MEM2MEM) /*!< Memory to memory direction */
+
+/**
+ * @}
+ */
+
+/** @defgroup DMA_Peripheral_incremented_mode DMA Peripheral incremented mode
+ * @{
+ */
+#define DMA_PINC_ENABLE ((uint32_t)DMA_CCR_PINC) /*!< Peripheral increment mode Enable */
+#define DMA_PINC_DISABLE 0x00000000U /*!< Peripheral increment mode Disable */
+/**
+ * @}
+ */
+
+/** @defgroup DMA_Memory_incremented_mode DMA Memory incremented mode
+ * @{
+ */
+#define DMA_MINC_ENABLE ((uint32_t)DMA_CCR_MINC) /*!< Memory increment mode Enable */
+#define DMA_MINC_DISABLE 0x00000000U /*!< Memory increment mode Disable */
+/**
+ * @}
+ */
+
+/** @defgroup DMA_Peripheral_data_size DMA Peripheral data size
+ * @{
+ */
+#define DMA_PDATAALIGN_BYTE 0x00000000U /*!< Peripheral data alignment: Byte */
+#define DMA_PDATAALIGN_HALFWORD ((uint32_t)DMA_CCR_PSIZE_0) /*!< Peripheral data alignment: HalfWord */
+#define DMA_PDATAALIGN_WORD ((uint32_t)DMA_CCR_PSIZE_1) /*!< Peripheral data alignment: Word */
+/**
+ * @}
+ */
+
+/** @defgroup DMA_Memory_data_size DMA Memory data size
+ * @{
+ */
+#define DMA_MDATAALIGN_BYTE 0x00000000U /*!< Memory data alignment: Byte */
+#define DMA_MDATAALIGN_HALFWORD ((uint32_t)DMA_CCR_MSIZE_0) /*!< Memory data alignment: HalfWord */
+#define DMA_MDATAALIGN_WORD ((uint32_t)DMA_CCR_MSIZE_1) /*!< Memory data alignment: Word */
+/**
+ * @}
+ */
+
+/** @defgroup DMA_mode DMA mode
+ * @{
+ */
+#define DMA_NORMAL 0x00000000U /*!< Normal mode */
+#define DMA_CIRCULAR ((uint32_t)DMA_CCR_CIRC) /*!< Circular mode */
+/**
+ * @}
+ */
+
+/** @defgroup DMA_Priority_level DMA Priority level
+ * @{
+ */
+#define DMA_PRIORITY_LOW 0x00000000U /*!< Priority level : Low */
+#define DMA_PRIORITY_MEDIUM ((uint32_t)DMA_CCR_PL_0) /*!< Priority level : Medium */
+#define DMA_PRIORITY_HIGH ((uint32_t)DMA_CCR_PL_1) /*!< Priority level : High */
+#define DMA_PRIORITY_VERY_HIGH ((uint32_t)DMA_CCR_PL) /*!< Priority level : Very_High */
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_interrupt_enable_definitions DMA interrupt enable definitions
+ * @{
+ */
+#define DMA_IT_TC ((uint32_t)DMA_CCR_TCIE)
+#define DMA_IT_HT ((uint32_t)DMA_CCR_HTIE)
+#define DMA_IT_TE ((uint32_t)DMA_CCR_TEIE)
+/**
+ * @}
+ */
+
+/** @defgroup DMA_flag_definitions DMA flag definitions
+ * @{
+ */
+#define DMA_FLAG_GL1 0x00000001U
+#define DMA_FLAG_TC1 0x00000002U
+#define DMA_FLAG_HT1 0x00000004U
+#define DMA_FLAG_TE1 0x00000008U
+#define DMA_FLAG_GL2 0x00000010U
+#define DMA_FLAG_TC2 0x00000020U
+#define DMA_FLAG_HT2 0x00000040U
+#define DMA_FLAG_TE2 0x00000080U
+#define DMA_FLAG_GL3 0x00000100U
+#define DMA_FLAG_TC3 0x00000200U
+#define DMA_FLAG_HT3 0x00000400U
+#define DMA_FLAG_TE3 0x00000800U
+#define DMA_FLAG_GL4 0x00001000U
+#define DMA_FLAG_TC4 0x00002000U
+#define DMA_FLAG_HT4 0x00004000U
+#define DMA_FLAG_TE4 0x00008000U
+#define DMA_FLAG_GL5 0x00010000U
+#define DMA_FLAG_TC5 0x00020000U
+#define DMA_FLAG_HT5 0x00040000U
+#define DMA_FLAG_TE5 0x00080000U
+#define DMA_FLAG_GL6 0x00100000U
+#define DMA_FLAG_TC6 0x00200000U
+#define DMA_FLAG_HT6 0x00400000U
+#define DMA_FLAG_TE6 0x00800000U
+#define DMA_FLAG_GL7 0x01000000U
+#define DMA_FLAG_TC7 0x02000000U
+#define DMA_FLAG_HT7 0x04000000U
+#define DMA_FLAG_TE7 0x08000000U
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/* Exported macros -----------------------------------------------------------*/
+/** @defgroup DMA_Exported_Macros DMA Exported Macros
+ * @{
+ */
+
+/** @brief Reset DMA handle state.
+ * @param __HANDLE__: DMA handle
+ * @retval None
+ */
+#define __HAL_DMA_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_DMA_STATE_RESET)
+
+/**
+ * @brief Enable the specified DMA Channel.
+ * @param __HANDLE__: DMA handle
+ * @retval None
+ */
+#define __HAL_DMA_ENABLE(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CCR, DMA_CCR_EN))
+
+/**
+ * @brief Disable the specified DMA Channel.
+ * @param __HANDLE__: DMA handle
+ * @retval None
+ */
+#define __HAL_DMA_DISABLE(__HANDLE__) (CLEAR_BIT((__HANDLE__)->Instance->CCR, DMA_CCR_EN))
+
+
+/* Interrupt & Flag management */
+
+/**
+ * @brief Enables the specified DMA Channel interrupts.
+ * @param __HANDLE__: DMA handle
+ * @param __INTERRUPT__: specifies the DMA interrupt sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg DMA_IT_TC: Transfer complete interrupt mask
+ * @arg DMA_IT_HT: Half transfer complete interrupt mask
+ * @arg DMA_IT_TE: Transfer error interrupt mask
+ * @retval None
+ */
+#define __HAL_DMA_ENABLE_IT(__HANDLE__, __INTERRUPT__) (SET_BIT((__HANDLE__)->Instance->CCR, (__INTERRUPT__)))
+
+/**
+ * @brief Disable the specified DMA Channel interrupts.
+ * @param __HANDLE__: DMA handle
+ * @param __INTERRUPT__: specifies the DMA interrupt sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg DMA_IT_TC: Transfer complete interrupt mask
+ * @arg DMA_IT_HT: Half transfer complete interrupt mask
+ * @arg DMA_IT_TE: Transfer error interrupt mask
+ * @retval None
+ */
+#define __HAL_DMA_DISABLE_IT(__HANDLE__, __INTERRUPT__) (CLEAR_BIT((__HANDLE__)->Instance->CCR , (__INTERRUPT__)))
+
+/**
+ * @brief Check whether the specified DMA Channel interrupt is enabled or not.
+ * @param __HANDLE__: DMA handle
+ * @param __INTERRUPT__: specifies the DMA interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg DMA_IT_TC: Transfer complete interrupt mask
+ * @arg DMA_IT_HT: Half transfer complete interrupt mask
+ * @arg DMA_IT_TE: Transfer error interrupt mask
+ * @retval The state of DMA_IT (SET or RESET).
+ */
+#define __HAL_DMA_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CCR & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
+
+/**
+ * @brief Return the number of remaining data units in the current DMA Channel transfer.
+ * @param __HANDLE__: DMA handle
+ * @retval The number of remaining data units in the current DMA Channel transfer.
+ */
+#define __HAL_DMA_GET_COUNTER(__HANDLE__) ((__HANDLE__)->Instance->CNDTR)
+
+/**
+ * @}
+ */
+
+/* Include DMA HAL Extension module */
+#include "stm32f1xx_hal_dma_ex.h"
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup DMA_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup DMA_Exported_Functions_Group1
+ * @{
+ */
+/* Initialization and de-initialization functions *****************************/
+HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma);
+HAL_StatusTypeDef HAL_DMA_DeInit (DMA_HandleTypeDef *hdma);
+/**
+ * @}
+ */
+
+/** @addtogroup DMA_Exported_Functions_Group2
+ * @{
+ */
+/* IO operation functions *****************************************************/
+HAL_StatusTypeDef HAL_DMA_Start (DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
+HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
+HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma);
+HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma);
+HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout);
+void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma);
+HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)( DMA_HandleTypeDef * _hdma));
+HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID);
+
+/**
+ * @}
+ */
+
+/** @addtogroup DMA_Exported_Functions_Group3
+ * @{
+ */
+/* Peripheral State and Error functions ***************************************/
+HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma);
+uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup DMA_Private_Macros DMA Private Macros
+ * @{
+ */
+
+#define IS_DMA_DIRECTION(DIRECTION) (((DIRECTION) == DMA_PERIPH_TO_MEMORY ) || \
+ ((DIRECTION) == DMA_MEMORY_TO_PERIPH) || \
+ ((DIRECTION) == DMA_MEMORY_TO_MEMORY))
+
+#define IS_DMA_BUFFER_SIZE(SIZE) (((SIZE) >= 0x1U) && ((SIZE) < 0x10000U))
+
+#define IS_DMA_PERIPHERAL_INC_STATE(STATE) (((STATE) == DMA_PINC_ENABLE) || \
+ ((STATE) == DMA_PINC_DISABLE))
+
+#define IS_DMA_MEMORY_INC_STATE(STATE) (((STATE) == DMA_MINC_ENABLE) || \
+ ((STATE) == DMA_MINC_DISABLE))
+
+#define IS_DMA_PERIPHERAL_DATA_SIZE(SIZE) (((SIZE) == DMA_PDATAALIGN_BYTE) || \
+ ((SIZE) == DMA_PDATAALIGN_HALFWORD) || \
+ ((SIZE) == DMA_PDATAALIGN_WORD))
+
+#define IS_DMA_MEMORY_DATA_SIZE(SIZE) (((SIZE) == DMA_MDATAALIGN_BYTE) || \
+ ((SIZE) == DMA_MDATAALIGN_HALFWORD) || \
+ ((SIZE) == DMA_MDATAALIGN_WORD ))
+
+#define IS_DMA_MODE(MODE) (((MODE) == DMA_NORMAL ) || \
+ ((MODE) == DMA_CIRCULAR))
+
+#define IS_DMA_PRIORITY(PRIORITY) (((PRIORITY) == DMA_PRIORITY_LOW ) || \
+ ((PRIORITY) == DMA_PRIORITY_MEDIUM) || \
+ ((PRIORITY) == DMA_PRIORITY_HIGH) || \
+ ((PRIORITY) == DMA_PRIORITY_VERY_HIGH))
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_DMA_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h
new file mode 100644
index 0000000..b5caf9f
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h
@@ -0,0 +1,293 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_dma_ex.h
+ * @author MCD Application Team
+ * @brief Header file of DMA HAL extension module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_DMA_EX_H
+#define __STM32F1xx_HAL_DMA_EX_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup DMAEx DMAEx
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup DMAEx_Exported_Macros DMA Extended Exported Macros
+ * @{
+ */
+/* Interrupt & Flag management */
+#if defined (STM32F100xE) || defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || \
+ defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC)
+/** @defgroup DMAEx_High_density_XL_density_Product_devices DMAEx High density and XL density product devices
+ * @{
+ */
+
+/**
+ * @brief Returns the current DMA Channel transfer complete flag.
+ * @param __HANDLE__: DMA handle
+ * @retval The specified transfer complete flag index.
+ */
+#define __HAL_DMA_GET_TC_FLAG_INDEX(__HANDLE__) \
+(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_TC1 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_TC2 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_TC3 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_TC4 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_TC5 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_TC6 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel7))? DMA_FLAG_TC7 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel1))? DMA_FLAG_TC1 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel2))? DMA_FLAG_TC2 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel3))? DMA_FLAG_TC3 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel4))? DMA_FLAG_TC4 :\
+ DMA_FLAG_TC5)
+
+/**
+ * @brief Returns the current DMA Channel half transfer complete flag.
+ * @param __HANDLE__: DMA handle
+ * @retval The specified half transfer complete flag index.
+ */
+#define __HAL_DMA_GET_HT_FLAG_INDEX(__HANDLE__)\
+(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_HT1 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_HT2 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_HT3 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_HT4 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_HT5 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_HT6 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel7))? DMA_FLAG_HT7 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel1))? DMA_FLAG_HT1 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel2))? DMA_FLAG_HT2 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel3))? DMA_FLAG_HT3 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel4))? DMA_FLAG_HT4 :\
+ DMA_FLAG_HT5)
+
+/**
+ * @brief Returns the current DMA Channel transfer error flag.
+ * @param __HANDLE__: DMA handle
+ * @retval The specified transfer error flag index.
+ */
+#define __HAL_DMA_GET_TE_FLAG_INDEX(__HANDLE__)\
+(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_TE1 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_TE2 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_TE3 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_TE4 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_TE5 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_TE6 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel7))? DMA_FLAG_TE7 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel1))? DMA_FLAG_TE1 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel2))? DMA_FLAG_TE2 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel3))? DMA_FLAG_TE3 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel4))? DMA_FLAG_TE4 :\
+ DMA_FLAG_TE5)
+
+/**
+ * @brief Return the current DMA Channel Global interrupt flag.
+ * @param __HANDLE__: DMA handle
+ * @retval The specified transfer error flag index.
+ */
+#define __HAL_DMA_GET_GI_FLAG_INDEX(__HANDLE__)\
+(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_GL1 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_GL2 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_GL3 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_GL4 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_GL5 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_GL6 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel7))? DMA_FLAG_GL7 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel1))? DMA_FLAG_GL1 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel2))? DMA_FLAG_GL2 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel3))? DMA_FLAG_GL3 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel4))? DMA_FLAG_GL4 :\
+ DMA_FLAG_GL5)
+
+/**
+ * @brief Get the DMA Channel pending flags.
+ * @param __HANDLE__: DMA handle
+ * @param __FLAG__: Get the specified flag.
+ * This parameter can be any combination of the following values:
+ * @arg DMA_FLAG_TCx: Transfer complete flag
+ * @arg DMA_FLAG_HTx: Half transfer complete flag
+ * @arg DMA_FLAG_TEx: Transfer error flag
+ * Where x can be 1_7 or 1_5 (depending on DMA1 or DMA2) to select the DMA Channel flag.
+ * @retval The state of FLAG (SET or RESET).
+ */
+#define __HAL_DMA_GET_FLAG(__HANDLE__, __FLAG__)\
+(((uint32_t)((__HANDLE__)->Instance) > (uint32_t)DMA1_Channel7)? (DMA2->ISR & (__FLAG__)) :\
+ (DMA1->ISR & (__FLAG__)))
+
+/**
+ * @brief Clears the DMA Channel pending flags.
+ * @param __HANDLE__: DMA handle
+ * @param __FLAG__: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg DMA_FLAG_TCx: Transfer complete flag
+ * @arg DMA_FLAG_HTx: Half transfer complete flag
+ * @arg DMA_FLAG_TEx: Transfer error flag
+ * Where x can be 1_7 or 1_5 (depending on DMA1 or DMA2) to select the DMA Channel flag.
+ * @retval None
+ */
+#define __HAL_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) \
+(((uint32_t)((__HANDLE__)->Instance) > (uint32_t)DMA1_Channel7)? (DMA2->IFCR = (__FLAG__)) :\
+ (DMA1->IFCR = (__FLAG__)))
+
+/**
+ * @}
+ */
+
+#else
+/** @defgroup DMA_Low_density_Medium_density_Product_devices DMA Low density and Medium density product devices
+ * @{
+ */
+
+/**
+ * @brief Returns the current DMA Channel transfer complete flag.
+ * @param __HANDLE__: DMA handle
+ * @retval The specified transfer complete flag index.
+ */
+#define __HAL_DMA_GET_TC_FLAG_INDEX(__HANDLE__) \
+(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_TC1 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_TC2 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_TC3 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_TC4 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_TC5 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_TC6 :\
+ DMA_FLAG_TC7)
+
+/**
+ * @brief Return the current DMA Channel half transfer complete flag.
+ * @param __HANDLE__: DMA handle
+ * @retval The specified half transfer complete flag index.
+ */
+#define __HAL_DMA_GET_HT_FLAG_INDEX(__HANDLE__)\
+(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_HT1 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_HT2 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_HT3 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_HT4 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_HT5 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_HT6 :\
+ DMA_FLAG_HT7)
+
+/**
+ * @brief Return the current DMA Channel transfer error flag.
+ * @param __HANDLE__: DMA handle
+ * @retval The specified transfer error flag index.
+ */
+#define __HAL_DMA_GET_TE_FLAG_INDEX(__HANDLE__)\
+(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_TE1 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_TE2 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_TE3 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_TE4 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_TE5 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_TE6 :\
+ DMA_FLAG_TE7)
+
+/**
+ * @brief Return the current DMA Channel Global interrupt flag.
+ * @param __HANDLE__: DMA handle
+ * @retval The specified transfer error flag index.
+ */
+#define __HAL_DMA_GET_GI_FLAG_INDEX(__HANDLE__)\
+(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_GL1 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_GL2 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_GL3 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_GL4 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_GL5 :\
+ ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_GL6 :\
+ DMA_FLAG_GL7)
+
+/**
+ * @brief Get the DMA Channel pending flags.
+ * @param __HANDLE__: DMA handle
+ * @param __FLAG__: Get the specified flag.
+ * This parameter can be any combination of the following values:
+ * @arg DMA_FLAG_TCx: Transfer complete flag
+ * @arg DMA_FLAG_HTx: Half transfer complete flag
+ * @arg DMA_FLAG_TEx: Transfer error flag
+ * @arg DMA_FLAG_GLx: Global interrupt flag
+ * Where x can be 1_7 to select the DMA Channel flag.
+ * @retval The state of FLAG (SET or RESET).
+ */
+
+#define __HAL_DMA_GET_FLAG(__HANDLE__, __FLAG__) (DMA1->ISR & (__FLAG__))
+
+/**
+ * @brief Clear the DMA Channel pending flags.
+ * @param __HANDLE__: DMA handle
+ * @param __FLAG__: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg DMA_FLAG_TCx: Transfer complete flag
+ * @arg DMA_FLAG_HTx: Half transfer complete flag
+ * @arg DMA_FLAG_TEx: Transfer error flag
+ * @arg DMA_FLAG_GLx: Global interrupt flag
+ * Where x can be 1_7 to select the DMA Channel flag.
+ * @retval None
+ */
+#define __HAL_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) (DMA1->IFCR = (__FLAG__))
+
+/**
+ * @}
+ */
+
+#endif
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || */
+ /* STM32F103xG || STM32F105xC || STM32F107xC */
+
+#endif /* __STM32F1xx_HAL_DMA_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_eth.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_eth.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_eth.h
rename to templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_eth.h
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h
new file mode 100644
index 0000000..399076d
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h
@@ -0,0 +1,344 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_flash.h
+ * @author MCD Application Team
+ * @brief Header file of Flash HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_FLASH_H
+#define __STM32F1xx_HAL_FLASH_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup FLASH
+ * @{
+ */
+
+/** @addtogroup FLASH_Private_Constants
+ * @{
+ */
+#define FLASH_TIMEOUT_VALUE 50000U /* 50 s */
+/**
+ * @}
+ */
+
+/** @addtogroup FLASH_Private_Macros
+ * @{
+ */
+
+#define IS_FLASH_TYPEPROGRAM(VALUE) (((VALUE) == FLASH_TYPEPROGRAM_HALFWORD) || \
+ ((VALUE) == FLASH_TYPEPROGRAM_WORD) || \
+ ((VALUE) == FLASH_TYPEPROGRAM_DOUBLEWORD))
+
+#if defined(FLASH_ACR_LATENCY)
+#define IS_FLASH_LATENCY(__LATENCY__) (((__LATENCY__) == FLASH_LATENCY_0) || \
+ ((__LATENCY__) == FLASH_LATENCY_1) || \
+ ((__LATENCY__) == FLASH_LATENCY_2))
+
+#else
+#define IS_FLASH_LATENCY(__LATENCY__) ((__LATENCY__) == FLASH_LATENCY_0)
+#endif /* FLASH_ACR_LATENCY */
+/**
+ * @}
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup FLASH_Exported_Types FLASH Exported Types
+ * @{
+ */
+
+/**
+ * @brief FLASH Procedure structure definition
+ */
+typedef enum
+{
+ FLASH_PROC_NONE = 0U,
+ FLASH_PROC_PAGEERASE = 1U,
+ FLASH_PROC_MASSERASE = 2U,
+ FLASH_PROC_PROGRAMHALFWORD = 3U,
+ FLASH_PROC_PROGRAMWORD = 4U,
+ FLASH_PROC_PROGRAMDOUBLEWORD = 5U
+} FLASH_ProcedureTypeDef;
+
+/**
+ * @brief FLASH handle Structure definition
+ */
+typedef struct
+{
+ __IO FLASH_ProcedureTypeDef ProcedureOnGoing; /*!< Internal variable to indicate which procedure is ongoing or not in IT context */
+
+ __IO uint32_t DataRemaining; /*!< Internal variable to save the remaining pages to erase or half-word to program in IT context */
+
+ __IO uint32_t Address; /*!< Internal variable to save address selected for program or erase */
+
+ __IO uint64_t Data; /*!< Internal variable to save data to be programmed */
+
+ HAL_LockTypeDef Lock; /*!< FLASH locking object */
+
+ __IO uint32_t ErrorCode; /*!< FLASH error code
+ This parameter can be a value of @ref FLASH_Error_Codes */
+} FLASH_ProcessTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup FLASH_Exported_Constants FLASH Exported Constants
+ * @{
+ */
+
+/** @defgroup FLASH_Error_Codes FLASH Error Codes
+ * @{
+ */
+
+#define HAL_FLASH_ERROR_NONE 0x00U /*!< No error */
+#define HAL_FLASH_ERROR_PROG 0x01U /*!< Programming error */
+#define HAL_FLASH_ERROR_WRP 0x02U /*!< Write protection error */
+#define HAL_FLASH_ERROR_OPTV 0x04U /*!< Option validity error */
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Type_Program FLASH Type Program
+ * @{
+ */
+#define FLASH_TYPEPROGRAM_HALFWORD 0x01U /*!ACR |= FLASH_ACR_HLFCYA)
+
+/**
+ * @brief Disable the FLASH half cycle access.
+ * @note half cycle access can only be used with a low-frequency clock of less than
+ 8 MHz that can be obtained with the use of HSI or HSE but not of PLL.
+ * @retval None
+ */
+#define __HAL_FLASH_HALF_CYCLE_ACCESS_DISABLE() (FLASH->ACR &= (~FLASH_ACR_HLFCYA))
+
+/**
+ * @}
+ */
+
+#if defined(FLASH_ACR_LATENCY)
+/** @defgroup FLASH_EM_Latency FLASH Latency
+ * @brief macros to handle FLASH Latency
+ * @{
+ */
+
+/**
+ * @brief Set the FLASH Latency.
+ * @param __LATENCY__ FLASH Latency
+ * The value of this parameter depend on device used within the same series
+ * @retval None
+ */
+#define __HAL_FLASH_SET_LATENCY(__LATENCY__) (FLASH->ACR = (FLASH->ACR&(~FLASH_ACR_LATENCY)) | (__LATENCY__))
+
+
+/**
+ * @brief Get the FLASH Latency.
+ * @retval FLASH Latency
+ * The value of this parameter depend on device used within the same series
+ */
+#define __HAL_FLASH_GET_LATENCY() (READ_BIT((FLASH->ACR), FLASH_ACR_LATENCY))
+
+/**
+ * @}
+ */
+
+#endif /* FLASH_ACR_LATENCY */
+/** @defgroup FLASH_Prefetch FLASH Prefetch
+ * @brief macros to handle FLASH Prefetch buffer
+ * @{
+ */
+/**
+ * @brief Enable the FLASH prefetch buffer.
+ * @retval None
+ */
+#define __HAL_FLASH_PREFETCH_BUFFER_ENABLE() (FLASH->ACR |= FLASH_ACR_PRFTBE)
+
+/**
+ * @brief Disable the FLASH prefetch buffer.
+ * @retval None
+ */
+#define __HAL_FLASH_PREFETCH_BUFFER_DISABLE() (FLASH->ACR &= (~FLASH_ACR_PRFTBE))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Include FLASH HAL Extended module */
+#include "stm32f1xx_hal_flash_ex.h"
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup FLASH_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup FLASH_Exported_Functions_Group1
+ * @{
+ */
+/* IO operation functions *****************************************************/
+HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data);
+HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data);
+
+/* FLASH IRQ handler function */
+void HAL_FLASH_IRQHandler(void);
+/* Callbacks in non blocking modes */
+void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue);
+void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue);
+
+/**
+ * @}
+ */
+
+/** @addtogroup FLASH_Exported_Functions_Group2
+ * @{
+ */
+/* Peripheral Control functions ***********************************************/
+HAL_StatusTypeDef HAL_FLASH_Unlock(void);
+HAL_StatusTypeDef HAL_FLASH_Lock(void);
+HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void);
+HAL_StatusTypeDef HAL_FLASH_OB_Lock(void);
+void HAL_FLASH_OB_Launch(void);
+
+/**
+ * @}
+ */
+
+/** @addtogroup FLASH_Exported_Functions_Group3
+ * @{
+ */
+/* Peripheral State and Error functions ***************************************/
+uint32_t HAL_FLASH_GetError(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private function -------------------------------------------------*/
+/** @addtogroup FLASH_Private_Functions
+ * @{
+ */
+HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout);
+#if defined(FLASH_BANK2_END)
+HAL_StatusTypeDef FLASH_WaitForLastOperationBank2(uint32_t Timeout);
+#endif /* FLASH_BANK2_END */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_FLASH_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h
new file mode 100644
index 0000000..5ec0163
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h
@@ -0,0 +1,802 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_flash_ex.h
+ * @author MCD Application Team
+ * @brief Header file of Flash HAL Extended module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_FLASH_EX_H
+#define __STM32F1xx_HAL_FLASH_EX_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup FLASHEx
+ * @{
+ */
+
+/** @addtogroup FLASHEx_Private_Constants
+ * @{
+ */
+
+#define FLASH_SIZE_DATA_REGISTER 0x1FFFF7E0U
+#define OBR_REG_INDEX 1U
+#define SR_FLAG_MASK ((uint32_t)(FLASH_SR_BSY | FLASH_SR_PGERR | FLASH_SR_WRPRTERR | FLASH_SR_EOP))
+
+/**
+ * @}
+ */
+
+/** @addtogroup FLASHEx_Private_Macros
+ * @{
+ */
+
+#define IS_FLASH_TYPEERASE(VALUE) (((VALUE) == FLASH_TYPEERASE_PAGES) || ((VALUE) == FLASH_TYPEERASE_MASSERASE))
+
+#define IS_OPTIONBYTE(VALUE) (((VALUE) <= (OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER | OPTIONBYTE_DATA)))
+
+#define IS_WRPSTATE(VALUE) (((VALUE) == OB_WRPSTATE_DISABLE) || ((VALUE) == OB_WRPSTATE_ENABLE))
+
+#define IS_OB_RDP_LEVEL(LEVEL) (((LEVEL) == OB_RDP_LEVEL_0) || ((LEVEL) == OB_RDP_LEVEL_1))
+
+#define IS_OB_DATA_ADDRESS(ADDRESS) (((ADDRESS) == OB_DATA_ADDRESS_DATA0) || ((ADDRESS) == OB_DATA_ADDRESS_DATA1))
+
+#define IS_OB_IWDG_SOURCE(SOURCE) (((SOURCE) == OB_IWDG_SW) || ((SOURCE) == OB_IWDG_HW))
+
+#define IS_OB_STOP_SOURCE(SOURCE) (((SOURCE) == OB_STOP_NO_RST) || ((SOURCE) == OB_STOP_RST))
+
+#define IS_OB_STDBY_SOURCE(SOURCE) (((SOURCE) == OB_STDBY_NO_RST) || ((SOURCE) == OB_STDBY_RST))
+
+#if defined(FLASH_BANK2_END)
+#define IS_OB_BOOT1(BOOT1) (((BOOT1) == OB_BOOT1_RESET) || ((BOOT1) == OB_BOOT1_SET))
+#endif /* FLASH_BANK2_END */
+
+/* Low Density */
+#if (defined(STM32F101x6) || defined(STM32F102x6) || defined(STM32F103x6))
+#define IS_FLASH_NB_PAGES(ADDRESS,NBPAGES) (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x20U) ? ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)- 1 <= 0x08007FFFU) : \
+ ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)- 1 <= 0x08003FFFU))
+#endif /* STM32F101x6 || STM32F102x6 || STM32F103x6 */
+
+/* Medium Density */
+#if (defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB))
+#define IS_FLASH_NB_PAGES(ADDRESS,NBPAGES) (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x80U) ? ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x0801FFFFU) : \
+ (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x40U) ? ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x0800FFFFU) : \
+ (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x20U) ? ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x08007FFFU) : \
+ ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x08003FFFU))))
+#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB*/
+
+/* High Density */
+#if (defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE))
+#define IS_FLASH_NB_PAGES(ADDRESS,NBPAGES) (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x200U) ? ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x0807FFFFU) : \
+ (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x180U) ? ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x0805FFFFU) : \
+ ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x0803FFFFU)))
+#endif /* STM32F100xE || STM32F101xE || STM32F103xE */
+
+/* XL Density */
+#if defined(FLASH_BANK2_END)
+#define IS_FLASH_NB_PAGES(ADDRESS,NBPAGES) (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x400U) ? ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x080FFFFFU) : \
+ ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x080BFFFFU))
+#endif /* FLASH_BANK2_END */
+
+/* Connectivity Line */
+#if (defined(STM32F105xC) || defined(STM32F107xC))
+#define IS_FLASH_NB_PAGES(ADDRESS,NBPAGES) (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x100U) ? ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x0803FFFFU) : \
+ (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x80U) ? ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x0801FFFFU) : \
+ ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= 0x0800FFFFU)))
+#endif /* STM32F105xC || STM32F107xC */
+
+#define IS_OB_WRP(PAGE) (((PAGE) != 0x0000000U))
+
+#if defined(FLASH_BANK2_END)
+#define IS_FLASH_BANK(BANK) (((BANK) == FLASH_BANK_1) || \
+ ((BANK) == FLASH_BANK_2) || \
+ ((BANK) == FLASH_BANK_BOTH))
+#else
+#define IS_FLASH_BANK(BANK) (((BANK) == FLASH_BANK_1))
+#endif /* FLASH_BANK2_END */
+
+/* Low Density */
+#if (defined(STM32F101x6) || defined(STM32F102x6) || defined(STM32F103x6))
+#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (((ADDRESS) >= FLASH_BASE) && (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x20U) ? \
+ ((ADDRESS) <= FLASH_BANK1_END) : ((ADDRESS) <= 0x08003FFFU)))
+
+#endif /* STM32F101x6 || STM32F102x6 || STM32F103x6 */
+
+/* Medium Density */
+#if (defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB))
+#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (((ADDRESS) >= FLASH_BASE) && (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x80U) ? \
+ ((ADDRESS) <= FLASH_BANK1_END) : (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x40U) ? \
+ ((ADDRESS) <= 0x0800FFFF) : (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x20U) ? \
+ ((ADDRESS) <= 0x08007FFF) : ((ADDRESS) <= 0x08003FFFU)))))
+
+#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB*/
+
+/* High Density */
+#if (defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE))
+#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (((ADDRESS) >= FLASH_BASE) && (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x200U) ? \
+ ((ADDRESS) <= FLASH_BANK1_END) : (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x180U) ? \
+ ((ADDRESS) <= 0x0805FFFFU) : ((ADDRESS) <= 0x0803FFFFU))))
+
+#endif /* STM32F100xE || STM32F101xE || STM32F103xE */
+
+/* XL Density */
+#if defined(FLASH_BANK2_END)
+#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (((ADDRESS) >= FLASH_BASE) && (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x400U) ? \
+ ((ADDRESS) <= FLASH_BANK2_END) : ((ADDRESS) <= 0x080BFFFFU)))
+
+#endif /* FLASH_BANK2_END */
+
+/* Connectivity Line */
+#if (defined(STM32F105xC) || defined(STM32F107xC))
+#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (((ADDRESS) >= FLASH_BASE) && (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x100U) ? \
+ ((ADDRESS) <= FLASH_BANK1_END) : (((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0x80U) ? \
+ ((ADDRESS) <= 0x0801FFFFU) : ((ADDRESS) <= 0x0800FFFFU))))
+
+#endif /* STM32F105xC || STM32F107xC */
+
+/**
+ * @}
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup FLASHEx_Exported_Types FLASHEx Exported Types
+ * @{
+ */
+
+/**
+ * @brief FLASH Erase structure definition
+ */
+typedef struct
+{
+ uint32_t TypeErase; /*!< TypeErase: Mass erase or page erase.
+ This parameter can be a value of @ref FLASHEx_Type_Erase */
+
+ uint32_t Banks; /*!< Select banks to erase when Mass erase is enabled.
+ This parameter must be a value of @ref FLASHEx_Banks */
+
+ uint32_t PageAddress; /*!< PageAdress: Initial FLASH page address to erase when mass erase is disabled
+ This parameter must be a number between Min_Data = 0x08000000 and Max_Data = FLASH_BANKx_END
+ (x = 1 or 2 depending on devices)*/
+
+ uint32_t NbPages; /*!< NbPages: Number of pagess to be erased.
+ This parameter must be a value between Min_Data = 1 and Max_Data = (max number of pages - value of initial page)*/
+
+} FLASH_EraseInitTypeDef;
+
+/**
+ * @brief FLASH Options bytes program structure definition
+ */
+typedef struct
+{
+ uint32_t OptionType; /*!< OptionType: Option byte to be configured.
+ This parameter can be a value of @ref FLASHEx_OB_Type */
+
+ uint32_t WRPState; /*!< WRPState: Write protection activation or deactivation.
+ This parameter can be a value of @ref FLASHEx_OB_WRP_State */
+
+ uint32_t WRPPage; /*!< WRPPage: specifies the page(s) to be write protected
+ This parameter can be a value of @ref FLASHEx_OB_Write_Protection */
+
+ uint32_t Banks; /*!< Select banks for WRP activation/deactivation of all sectors.
+ This parameter must be a value of @ref FLASHEx_Banks */
+
+ uint8_t RDPLevel; /*!< RDPLevel: Set the read protection level..
+ This parameter can be a value of @ref FLASHEx_OB_Read_Protection */
+
+#if defined(FLASH_BANK2_END)
+ uint8_t USERConfig; /*!< USERConfig: Program the FLASH User Option Byte:
+ IWDG / STOP / STDBY / BOOT1
+ This parameter can be a combination of @ref FLASHEx_OB_IWatchdog, @ref FLASHEx_OB_nRST_STOP,
+ @ref FLASHEx_OB_nRST_STDBY, @ref FLASHEx_OB_BOOT1 */
+#else
+ uint8_t USERConfig; /*!< USERConfig: Program the FLASH User Option Byte:
+ IWDG / STOP / STDBY
+ This parameter can be a combination of @ref FLASHEx_OB_IWatchdog, @ref FLASHEx_OB_nRST_STOP,
+ @ref FLASHEx_OB_nRST_STDBY */
+#endif /* FLASH_BANK2_END */
+
+ uint32_t DATAAddress; /*!< DATAAddress: Address of the option byte DATA to be programmed
+ This parameter can be a value of @ref FLASHEx_OB_Data_Address */
+
+ uint8_t DATAData; /*!< DATAData: Data to be stored in the option byte DATA
+ This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF */
+} FLASH_OBProgramInitTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup FLASHEx_Exported_Constants FLASHEx Exported Constants
+ * @{
+ */
+
+/** @defgroup FLASHEx_Constants FLASH Constants
+ * @{
+ */
+
+/** @defgroup FLASHEx_Page_Size Page Size
+ * @{
+ */
+#if (defined(STM32F101x6) || defined(STM32F102x6) || defined(STM32F103x6) || defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB))
+#define FLASH_PAGE_SIZE 0x400U
+#endif /* STM32F101x6 || STM32F102x6 || STM32F103x6 */
+ /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB */
+
+#if (defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC))
+#define FLASH_PAGE_SIZE 0x800U
+#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB */
+ /* STM32F101xG || STM32F103xG */
+ /* STM32F105xC || STM32F107xC */
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_Type_Erase Type Erase
+ * @{
+ */
+#define FLASH_TYPEERASE_PAGES 0x00U /*!CR, ((__INTERRUPT__) & 0x0000FFFFU)); \
+ /* Enable Bank2 IT */ \
+ SET_BIT(FLASH->CR2, ((__INTERRUPT__) >> 16U)); \
+ } while(0U)
+
+/**
+ * @brief Disable the specified FLASH interrupt.
+ * @param __INTERRUPT__ FLASH interrupt
+ * This parameter can be any combination of the following values:
+ * @arg @ref FLASH_IT_EOP_BANK1 End of FLASH Operation Interrupt on bank1
+ * @arg @ref FLASH_IT_ERR_BANK1 Error Interrupt on bank1
+ * @arg @ref FLASH_IT_EOP_BANK2 End of FLASH Operation Interrupt on bank2
+ * @arg @ref FLASH_IT_ERR_BANK2 Error Interrupt on bank2
+ * @retval none
+ */
+#define __HAL_FLASH_DISABLE_IT(__INTERRUPT__) do { \
+ /* Disable Bank1 IT */ \
+ CLEAR_BIT(FLASH->CR, ((__INTERRUPT__) & 0x0000FFFFU)); \
+ /* Disable Bank2 IT */ \
+ CLEAR_BIT(FLASH->CR2, ((__INTERRUPT__) >> 16U)); \
+ } while(0U)
+
+/**
+ * @brief Get the specified FLASH flag status.
+ * @param __FLAG__ specifies the FLASH flag to check.
+ * This parameter can be one of the following values:
+ * @arg @ref FLASH_FLAG_EOP_BANK1 FLASH End of Operation flag on bank1
+ * @arg @ref FLASH_FLAG_WRPERR_BANK1 FLASH Write protected error flag on bank1
+ * @arg @ref FLASH_FLAG_PGERR_BANK1 FLASH Programming error flag on bank1
+ * @arg @ref FLASH_FLAG_BSY_BANK1 FLASH Busy flag on bank1
+ * @arg @ref FLASH_FLAG_EOP_BANK2 FLASH End of Operation flag on bank2
+ * @arg @ref FLASH_FLAG_WRPERR_BANK2 FLASH Write protected error flag on bank2
+ * @arg @ref FLASH_FLAG_PGERR_BANK2 FLASH Programming error flag on bank2
+ * @arg @ref FLASH_FLAG_BSY_BANK2 FLASH Busy flag on bank2
+ * @arg @ref FLASH_FLAG_OPTVERR Loaded OB and its complement do not match
+ * @retval The new state of __FLAG__ (SET or RESET).
+ */
+#define __HAL_FLASH_GET_FLAG(__FLAG__) (((__FLAG__) == FLASH_FLAG_OPTVERR) ? \
+ (FLASH->OBR & FLASH_OBR_OPTERR) : \
+ ((((__FLAG__) & SR_FLAG_MASK) != RESET)? \
+ (FLASH->SR & ((__FLAG__) & SR_FLAG_MASK)) : \
+ (FLASH->SR2 & ((__FLAG__) >> 16U))))
+
+/**
+ * @brief Clear the specified FLASH flag.
+ * @param __FLAG__ specifies the FLASH flags to clear.
+ * This parameter can be any combination of the following values:
+ * @arg @ref FLASH_FLAG_EOP_BANK1 FLASH End of Operation flag on bank1
+ * @arg @ref FLASH_FLAG_WRPERR_BANK1 FLASH Write protected error flag on bank1
+ * @arg @ref FLASH_FLAG_PGERR_BANK1 FLASH Programming error flag on bank1
+ * @arg @ref FLASH_FLAG_BSY_BANK1 FLASH Busy flag on bank1
+ * @arg @ref FLASH_FLAG_EOP_BANK2 FLASH End of Operation flag on bank2
+ * @arg @ref FLASH_FLAG_WRPERR_BANK2 FLASH Write protected error flag on bank2
+ * @arg @ref FLASH_FLAG_PGERR_BANK2 FLASH Programming error flag on bank2
+ * @arg @ref FLASH_FLAG_BSY_BANK2 FLASH Busy flag on bank2
+ * @arg @ref FLASH_FLAG_OPTVERR Loaded OB and its complement do not match
+ * @retval none
+ */
+#define __HAL_FLASH_CLEAR_FLAG(__FLAG__) do { \
+ /* Clear FLASH_FLAG_OPTVERR flag */ \
+ if ((__FLAG__) == FLASH_FLAG_OPTVERR) \
+ { \
+ CLEAR_BIT(FLASH->OBR, FLASH_OBR_OPTERR); \
+ } \
+ else { \
+ /* Clear Flag in Bank1 */ \
+ if (((__FLAG__) & SR_FLAG_MASK) != RESET) \
+ { \
+ FLASH->SR = ((__FLAG__) & SR_FLAG_MASK); \
+ } \
+ /* Clear Flag in Bank2 */ \
+ if (((__FLAG__) >> 16U) != RESET) \
+ { \
+ FLASH->SR2 = ((__FLAG__) >> 16U); \
+ } \
+ } \
+ } while(0U)
+#else
+/**
+ * @brief Enable the specified FLASH interrupt.
+ * @param __INTERRUPT__ FLASH interrupt
+ * This parameter can be any combination of the following values:
+ * @arg @ref FLASH_IT_EOP End of FLASH Operation Interrupt
+ * @arg @ref FLASH_IT_ERR Error Interrupt
+ * @retval none
+ */
+#define __HAL_FLASH_ENABLE_IT(__INTERRUPT__) (FLASH->CR |= (__INTERRUPT__))
+
+/**
+ * @brief Disable the specified FLASH interrupt.
+ * @param __INTERRUPT__ FLASH interrupt
+ * This parameter can be any combination of the following values:
+ * @arg @ref FLASH_IT_EOP End of FLASH Operation Interrupt
+ * @arg @ref FLASH_IT_ERR Error Interrupt
+ * @retval none
+ */
+#define __HAL_FLASH_DISABLE_IT(__INTERRUPT__) (FLASH->CR &= ~(__INTERRUPT__))
+
+/**
+ * @brief Get the specified FLASH flag status.
+ * @param __FLAG__ specifies the FLASH flag to check.
+ * This parameter can be one of the following values:
+ * @arg @ref FLASH_FLAG_EOP FLASH End of Operation flag
+ * @arg @ref FLASH_FLAG_WRPERR FLASH Write protected error flag
+ * @arg @ref FLASH_FLAG_PGERR FLASH Programming error flag
+ * @arg @ref FLASH_FLAG_BSY FLASH Busy flag
+ * @arg @ref FLASH_FLAG_OPTVERR Loaded OB and its complement do not match
+ * @retval The new state of __FLAG__ (SET or RESET).
+ */
+#define __HAL_FLASH_GET_FLAG(__FLAG__) (((__FLAG__) == FLASH_FLAG_OPTVERR) ? \
+ (FLASH->OBR & FLASH_OBR_OPTERR) : \
+ (FLASH->SR & (__FLAG__)))
+/**
+ * @brief Clear the specified FLASH flag.
+ * @param __FLAG__ specifies the FLASH flags to clear.
+ * This parameter can be any combination of the following values:
+ * @arg @ref FLASH_FLAG_EOP FLASH End of Operation flag
+ * @arg @ref FLASH_FLAG_WRPERR FLASH Write protected error flag
+ * @arg @ref FLASH_FLAG_PGERR FLASH Programming error flag
+ * @arg @ref FLASH_FLAG_OPTVERR Loaded OB and its complement do not match
+ * @retval none
+ */
+#define __HAL_FLASH_CLEAR_FLAG(__FLAG__) do { \
+ /* Clear FLASH_FLAG_OPTVERR flag */ \
+ if ((__FLAG__) == FLASH_FLAG_OPTVERR) \
+ { \
+ CLEAR_BIT(FLASH->OBR, FLASH_OBR_OPTERR); \
+ } \
+ else { \
+ /* Clear Flag in Bank1 */ \
+ FLASH->SR = (__FLAG__); \
+ } \
+ } while(0U)
+
+#endif
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup FLASHEx_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup FLASHEx_Exported_Functions_Group1
+ * @{
+ */
+/* IO operation functions *****************************************************/
+HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError);
+HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit);
+
+/**
+ * @}
+ */
+
+/** @addtogroup FLASHEx_Exported_Functions_Group2
+ * @{
+ */
+/* Peripheral Control functions ***********************************************/
+HAL_StatusTypeDef HAL_FLASHEx_OBErase(void);
+HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit);
+void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit);
+uint32_t HAL_FLASHEx_OBGetUserData(uint32_t DATAAdress);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_FLASH_EX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h
new file mode 100644
index 0000000..2594a19
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h
@@ -0,0 +1,324 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_gpio.h
+ * @author MCD Application Team
+ * @brief Header file of GPIO HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_GPIO_H
+#define __STM32F1xx_HAL_GPIO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup GPIO
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup GPIO_Exported_Types GPIO Exported Types
+ * @{
+ */
+
+/**
+ * @brief GPIO Init structure definition
+ */
+typedef struct
+{
+ uint32_t Pin; /*!< Specifies the GPIO pins to be configured.
+ This parameter can be any value of @ref GPIO_pins_define */
+
+ uint32_t Mode; /*!< Specifies the operating mode for the selected pins.
+ This parameter can be a value of @ref GPIO_mode_define */
+
+ uint32_t Pull; /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.
+ This parameter can be a value of @ref GPIO_pull_define */
+
+ uint32_t Speed; /*!< Specifies the speed for the selected pins.
+ This parameter can be a value of @ref GPIO_speed_define */
+} GPIO_InitTypeDef;
+
+/**
+ * @brief GPIO Bit SET and Bit RESET enumeration
+ */
+typedef enum
+{
+ GPIO_PIN_RESET = 0U,
+ GPIO_PIN_SET
+} GPIO_PinState;
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup GPIO_Exported_Constants GPIO Exported Constants
+ * @{
+ */
+
+/** @defgroup GPIO_pins_define GPIO pins define
+ * @{
+ */
+#define GPIO_PIN_0 ((uint16_t)0x0001) /* Pin 0 selected */
+#define GPIO_PIN_1 ((uint16_t)0x0002) /* Pin 1 selected */
+#define GPIO_PIN_2 ((uint16_t)0x0004) /* Pin 2 selected */
+#define GPIO_PIN_3 ((uint16_t)0x0008) /* Pin 3 selected */
+#define GPIO_PIN_4 ((uint16_t)0x0010) /* Pin 4 selected */
+#define GPIO_PIN_5 ((uint16_t)0x0020) /* Pin 5 selected */
+#define GPIO_PIN_6 ((uint16_t)0x0040) /* Pin 6 selected */
+#define GPIO_PIN_7 ((uint16_t)0x0080) /* Pin 7 selected */
+#define GPIO_PIN_8 ((uint16_t)0x0100) /* Pin 8 selected */
+#define GPIO_PIN_9 ((uint16_t)0x0200) /* Pin 9 selected */
+#define GPIO_PIN_10 ((uint16_t)0x0400) /* Pin 10 selected */
+#define GPIO_PIN_11 ((uint16_t)0x0800) /* Pin 11 selected */
+#define GPIO_PIN_12 ((uint16_t)0x1000) /* Pin 12 selected */
+#define GPIO_PIN_13 ((uint16_t)0x2000) /* Pin 13 selected */
+#define GPIO_PIN_14 ((uint16_t)0x4000) /* Pin 14 selected */
+#define GPIO_PIN_15 ((uint16_t)0x8000) /* Pin 15 selected */
+#define GPIO_PIN_All ((uint16_t)0xFFFF) /* All pins selected */
+
+#define GPIO_PIN_MASK 0x0000FFFFU /* PIN mask for assert test */
+/**
+ * @}
+ */
+
+/** @defgroup GPIO_mode_define GPIO mode define
+ * @brief GPIO Configuration Mode
+ * Elements values convention: 0xX0yz00YZ
+ * - X : GPIO mode or EXTI Mode
+ * - y : External IT or Event trigger detection
+ * - z : IO configuration on External IT or Event
+ * - Y : Output type (Push Pull or Open Drain)
+ * - Z : IO Direction mode (Input, Output, Alternate or Analog)
+ * @{
+ */
+#define GPIO_MODE_INPUT 0x00000000U /*!< Input Floating Mode */
+#define GPIO_MODE_OUTPUT_PP 0x00000001U /*!< Output Push Pull Mode */
+#define GPIO_MODE_OUTPUT_OD 0x00000011U /*!< Output Open Drain Mode */
+#define GPIO_MODE_AF_PP 0x00000002U /*!< Alternate Function Push Pull Mode */
+#define GPIO_MODE_AF_OD 0x00000012U /*!< Alternate Function Open Drain Mode */
+#define GPIO_MODE_AF_INPUT GPIO_MODE_INPUT /*!< Alternate Function Input Mode */
+
+#define GPIO_MODE_ANALOG 0x00000003U /*!< Analog Mode */
+
+#define GPIO_MODE_IT_RISING 0x10110000U /*!< External Interrupt Mode with Rising edge trigger detection */
+#define GPIO_MODE_IT_FALLING 0x10210000U /*!< External Interrupt Mode with Falling edge trigger detection */
+#define GPIO_MODE_IT_RISING_FALLING 0x10310000U /*!< External Interrupt Mode with Rising/Falling edge trigger detection */
+
+#define GPIO_MODE_EVT_RISING 0x10120000U /*!< External Event Mode with Rising edge trigger detection */
+#define GPIO_MODE_EVT_FALLING 0x10220000U /*!< External Event Mode with Falling edge trigger detection */
+#define GPIO_MODE_EVT_RISING_FALLING 0x10320000U /*!< External Event Mode with Rising/Falling edge trigger detection */
+
+/**
+ * @}
+ */
+
+/** @defgroup GPIO_speed_define GPIO speed define
+ * @brief GPIO Output Maximum frequency
+ * @{
+ */
+#define GPIO_SPEED_FREQ_LOW (GPIO_CRL_MODE0_1) /*!< Low speed */
+#define GPIO_SPEED_FREQ_MEDIUM (GPIO_CRL_MODE0_0) /*!< Medium speed */
+#define GPIO_SPEED_FREQ_HIGH (GPIO_CRL_MODE0) /*!< High speed */
+
+/**
+ * @}
+ */
+
+/** @defgroup GPIO_pull_define GPIO pull define
+ * @brief GPIO Pull-Up or Pull-Down Activation
+ * @{
+ */
+#define GPIO_NOPULL 0x00000000U /*!< No Pull-up or Pull-down activation */
+#define GPIO_PULLUP 0x00000001U /*!< Pull-up activation */
+#define GPIO_PULLDOWN 0x00000002U /*!< Pull-down activation */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup GPIO_Exported_Macros GPIO Exported Macros
+ * @{
+ */
+
+/**
+ * @brief Checks whether the specified EXTI line flag is set or not.
+ * @param __EXTI_LINE__: specifies the EXTI line flag to check.
+ * This parameter can be GPIO_PIN_x where x can be(0..15)
+ * @retval The new state of __EXTI_LINE__ (SET or RESET).
+ */
+#define __HAL_GPIO_EXTI_GET_FLAG(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__))
+
+/**
+ * @brief Clears the EXTI's line pending flags.
+ * @param __EXTI_LINE__: specifies the EXTI lines flags to clear.
+ * This parameter can be any combination of GPIO_PIN_x where x can be (0..15)
+ * @retval None
+ */
+#define __HAL_GPIO_EXTI_CLEAR_FLAG(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__))
+
+/**
+ * @brief Checks whether the specified EXTI line is asserted or not.
+ * @param __EXTI_LINE__: specifies the EXTI line to check.
+ * This parameter can be GPIO_PIN_x where x can be(0..15)
+ * @retval The new state of __EXTI_LINE__ (SET or RESET).
+ */
+#define __HAL_GPIO_EXTI_GET_IT(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__))
+
+/**
+ * @brief Clears the EXTI's line pending bits.
+ * @param __EXTI_LINE__: specifies the EXTI lines to clear.
+ * This parameter can be any combination of GPIO_PIN_x where x can be (0..15)
+ * @retval None
+ */
+#define __HAL_GPIO_EXTI_CLEAR_IT(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__))
+
+/**
+ * @brief Generates a Software interrupt on selected EXTI line.
+ * @param __EXTI_LINE__: specifies the EXTI line to check.
+ * This parameter can be GPIO_PIN_x where x can be(0..15)
+ * @retval None
+ */
+#define __HAL_GPIO_EXTI_GENERATE_SWIT(__EXTI_LINE__) (EXTI->SWIER |= (__EXTI_LINE__))
+/**
+ * @}
+ */
+
+/* Include GPIO HAL Extension module */
+#include "stm32f1xx_hal_gpio_ex.h"
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup GPIO_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup GPIO_Exported_Functions_Group1
+ * @{
+ */
+/* Initialization and de-initialization functions *****************************/
+void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
+void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);
+/**
+ * @}
+ */
+
+/** @addtogroup GPIO_Exported_Functions_Group2
+ * @{
+ */
+/* IO operation functions *****************************************************/
+GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
+void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
+void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
+HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
+void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
+void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup GPIO_Private_Constants GPIO Private Constants
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup GPIO_Private_Macros GPIO Private Macros
+ * @{
+ */
+#define IS_GPIO_PIN_ACTION(ACTION) (((ACTION) == GPIO_PIN_RESET) || ((ACTION) == GPIO_PIN_SET))
+#define IS_GPIO_PIN(PIN) ((((PIN) & GPIO_PIN_MASK ) != 0x00U) && (((PIN) & ~GPIO_PIN_MASK) == 0x00U))
+#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_MODE_INPUT) ||\
+ ((MODE) == GPIO_MODE_OUTPUT_PP) ||\
+ ((MODE) == GPIO_MODE_OUTPUT_OD) ||\
+ ((MODE) == GPIO_MODE_AF_PP) ||\
+ ((MODE) == GPIO_MODE_AF_OD) ||\
+ ((MODE) == GPIO_MODE_IT_RISING) ||\
+ ((MODE) == GPIO_MODE_IT_FALLING) ||\
+ ((MODE) == GPIO_MODE_IT_RISING_FALLING) ||\
+ ((MODE) == GPIO_MODE_EVT_RISING) ||\
+ ((MODE) == GPIO_MODE_EVT_FALLING) ||\
+ ((MODE) == GPIO_MODE_EVT_RISING_FALLING) ||\
+ ((MODE) == GPIO_MODE_ANALOG))
+#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_SPEED_FREQ_LOW) || \
+ ((SPEED) == GPIO_SPEED_FREQ_MEDIUM) || ((SPEED) == GPIO_SPEED_FREQ_HIGH))
+#define IS_GPIO_PULL(PULL) (((PULL) == GPIO_NOPULL) || ((PULL) == GPIO_PULLUP) || \
+ ((PULL) == GPIO_PULLDOWN))
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup GPIO_Private_Functions GPIO Private Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_GPIO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h
new file mode 100644
index 0000000..ff4b96a
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h
@@ -0,0 +1,910 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_gpio_ex.h
+ * @author MCD Application Team
+ * @brief Header file of GPIO HAL Extension module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_GPIO_EX_H
+#define __STM32F1xx_HAL_GPIO_EX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup GPIOEx GPIOEx
+ * @{
+ */
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup GPIOEx_Exported_Constants GPIOEx Exported Constants
+ * @{
+ */
+
+/** @defgroup GPIOEx_EVENTOUT EVENTOUT Cortex Configuration
+ * @brief This section propose definition to use the Cortex EVENTOUT signal.
+ * @{
+ */
+
+/** @defgroup GPIOEx_EVENTOUT_PIN EVENTOUT Pin
+ * @{
+ */
+
+#define AFIO_EVENTOUT_PIN_0 AFIO_EVCR_PIN_PX0 /*!< EVENTOUT on pin 0 */
+#define AFIO_EVENTOUT_PIN_1 AFIO_EVCR_PIN_PX1 /*!< EVENTOUT on pin 1 */
+#define AFIO_EVENTOUT_PIN_2 AFIO_EVCR_PIN_PX2 /*!< EVENTOUT on pin 2 */
+#define AFIO_EVENTOUT_PIN_3 AFIO_EVCR_PIN_PX3 /*!< EVENTOUT on pin 3 */
+#define AFIO_EVENTOUT_PIN_4 AFIO_EVCR_PIN_PX4 /*!< EVENTOUT on pin 4 */
+#define AFIO_EVENTOUT_PIN_5 AFIO_EVCR_PIN_PX5 /*!< EVENTOUT on pin 5 */
+#define AFIO_EVENTOUT_PIN_6 AFIO_EVCR_PIN_PX6 /*!< EVENTOUT on pin 6 */
+#define AFIO_EVENTOUT_PIN_7 AFIO_EVCR_PIN_PX7 /*!< EVENTOUT on pin 7 */
+#define AFIO_EVENTOUT_PIN_8 AFIO_EVCR_PIN_PX8 /*!< EVENTOUT on pin 8 */
+#define AFIO_EVENTOUT_PIN_9 AFIO_EVCR_PIN_PX9 /*!< EVENTOUT on pin 9 */
+#define AFIO_EVENTOUT_PIN_10 AFIO_EVCR_PIN_PX10 /*!< EVENTOUT on pin 10 */
+#define AFIO_EVENTOUT_PIN_11 AFIO_EVCR_PIN_PX11 /*!< EVENTOUT on pin 11 */
+#define AFIO_EVENTOUT_PIN_12 AFIO_EVCR_PIN_PX12 /*!< EVENTOUT on pin 12 */
+#define AFIO_EVENTOUT_PIN_13 AFIO_EVCR_PIN_PX13 /*!< EVENTOUT on pin 13 */
+#define AFIO_EVENTOUT_PIN_14 AFIO_EVCR_PIN_PX14 /*!< EVENTOUT on pin 14 */
+#define AFIO_EVENTOUT_PIN_15 AFIO_EVCR_PIN_PX15 /*!< EVENTOUT on pin 15 */
+
+#define IS_AFIO_EVENTOUT_PIN(__PIN__) (((__PIN__) == AFIO_EVENTOUT_PIN_0) || \
+ ((__PIN__) == AFIO_EVENTOUT_PIN_1) || \
+ ((__PIN__) == AFIO_EVENTOUT_PIN_2) || \
+ ((__PIN__) == AFIO_EVENTOUT_PIN_3) || \
+ ((__PIN__) == AFIO_EVENTOUT_PIN_4) || \
+ ((__PIN__) == AFIO_EVENTOUT_PIN_5) || \
+ ((__PIN__) == AFIO_EVENTOUT_PIN_6) || \
+ ((__PIN__) == AFIO_EVENTOUT_PIN_7) || \
+ ((__PIN__) == AFIO_EVENTOUT_PIN_8) || \
+ ((__PIN__) == AFIO_EVENTOUT_PIN_9) || \
+ ((__PIN__) == AFIO_EVENTOUT_PIN_10) || \
+ ((__PIN__) == AFIO_EVENTOUT_PIN_11) || \
+ ((__PIN__) == AFIO_EVENTOUT_PIN_12) || \
+ ((__PIN__) == AFIO_EVENTOUT_PIN_13) || \
+ ((__PIN__) == AFIO_EVENTOUT_PIN_14) || \
+ ((__PIN__) == AFIO_EVENTOUT_PIN_15))
+/**
+ * @}
+ */
+
+/** @defgroup GPIOEx_EVENTOUT_PORT EVENTOUT Port
+ * @{
+ */
+
+#define AFIO_EVENTOUT_PORT_A AFIO_EVCR_PORT_PA /*!< EVENTOUT on port A */
+#define AFIO_EVENTOUT_PORT_B AFIO_EVCR_PORT_PB /*!< EVENTOUT on port B */
+#define AFIO_EVENTOUT_PORT_C AFIO_EVCR_PORT_PC /*!< EVENTOUT on port C */
+#define AFIO_EVENTOUT_PORT_D AFIO_EVCR_PORT_PD /*!< EVENTOUT on port D */
+#define AFIO_EVENTOUT_PORT_E AFIO_EVCR_PORT_PE /*!< EVENTOUT on port E */
+
+#define IS_AFIO_EVENTOUT_PORT(__PORT__) (((__PORT__) == AFIO_EVENTOUT_PORT_A) || \
+ ((__PORT__) == AFIO_EVENTOUT_PORT_B) || \
+ ((__PORT__) == AFIO_EVENTOUT_PORT_C) || \
+ ((__PORT__) == AFIO_EVENTOUT_PORT_D) || \
+ ((__PORT__) == AFIO_EVENTOUT_PORT_E))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup GPIOEx_AFIO_AF_REMAPPING Alternate Function Remapping
+ * @brief This section propose definition to remap the alternate function to some other port/pins.
+ * @{
+ */
+
+/**
+ * @brief Enable the remapping of SPI1 alternate function NSS, SCK, MISO and MOSI.
+ * @note ENABLE: Remap (NSS/PA15, SCK/PB3, MISO/PB4, MOSI/PB5)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_SPI1_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_SPI1_REMAP)
+
+/**
+ * @brief Disable the remapping of SPI1 alternate function NSS, SCK, MISO and MOSI.
+ * @note DISABLE: No remap (NSS/PA4, SCK/PA5, MISO/PA6, MOSI/PA7)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_SPI1_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_SPI1_REMAP)
+
+/**
+ * @brief Enable the remapping of I2C1 alternate function SCL and SDA.
+ * @note ENABLE: Remap (SCL/PB8, SDA/PB9)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_I2C1_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_I2C1_REMAP)
+
+/**
+ * @brief Disable the remapping of I2C1 alternate function SCL and SDA.
+ * @note DISABLE: No remap (SCL/PB6, SDA/PB7)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_I2C1_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_I2C1_REMAP)
+
+/**
+ * @brief Enable the remapping of USART1 alternate function TX and RX.
+ * @note ENABLE: Remap (TX/PB6, RX/PB7)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_USART1_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_USART1_REMAP)
+
+/**
+ * @brief Disable the remapping of USART1 alternate function TX and RX.
+ * @note DISABLE: No remap (TX/PA9, RX/PA10)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_USART1_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_USART1_REMAP)
+
+/**
+ * @brief Enable the remapping of USART2 alternate function CTS, RTS, CK, TX and RX.
+ * @note ENABLE: Remap (CTS/PD3, RTS/PD4, TX/PD5, RX/PD6, CK/PD7)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_USART2_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_USART2_REMAP)
+
+/**
+ * @brief Disable the remapping of USART2 alternate function CTS, RTS, CK, TX and RX.
+ * @note DISABLE: No remap (CTS/PA0, RTS/PA1, TX/PA2, RX/PA3, CK/PA4)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_USART2_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_USART2_REMAP)
+
+/**
+ * @brief Enable the remapping of USART3 alternate function CTS, RTS, CK, TX and RX.
+ * @note ENABLE: Full remap (TX/PD8, RX/PD9, CK/PD10, CTS/PD11, RTS/PD12)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_USART3_ENABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_USART3_REMAP_FULLREMAP, AFIO_MAPR_USART3_REMAP_FULLREMAP)
+
+/**
+ * @brief Enable the remapping of USART3 alternate function CTS, RTS, CK, TX and RX.
+ * @note PARTIAL: Partial remap (TX/PC10, RX/PC11, CK/PC12, CTS/PB13, RTS/PB14)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_USART3_PARTIAL() AFIO_REMAP_PARTIAL(AFIO_MAPR_USART3_REMAP_PARTIALREMAP, AFIO_MAPR_USART3_REMAP_FULLREMAP)
+
+/**
+ * @brief Disable the remapping of USART3 alternate function CTS, RTS, CK, TX and RX.
+ * @note DISABLE: No remap (TX/PB10, RX/PB11, CK/PB12, CTS/PB13, RTS/PB14)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_USART3_DISABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_USART3_REMAP_NOREMAP, AFIO_MAPR_USART3_REMAP_FULLREMAP)
+
+/**
+ * @brief Enable the remapping of TIM1 alternate function channels 1 to 4, 1N to 3N, external trigger (ETR) and Break input (BKIN)
+ * @note ENABLE: Full remap (ETR/PE7, CH1/PE9, CH2/PE11, CH3/PE13, CH4/PE14, BKIN/PE15, CH1N/PE8, CH2N/PE10, CH3N/PE12)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM1_ENABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM1_REMAP_FULLREMAP, AFIO_MAPR_TIM1_REMAP_FULLREMAP)
+
+/**
+ * @brief Enable the remapping of TIM1 alternate function channels 1 to 4, 1N to 3N, external trigger (ETR) and Break input (BKIN)
+ * @note PARTIAL: Partial remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PA6, CH1N/PA7, CH2N/PB0, CH3N/PB1)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM1_PARTIAL() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM1_REMAP_PARTIALREMAP, AFIO_MAPR_TIM1_REMAP_FULLREMAP)
+
+/**
+ * @brief Disable the remapping of TIM1 alternate function channels 1 to 4, 1N to 3N, external trigger (ETR) and Break input (BKIN)
+ * @note DISABLE: No remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PB12, CH1N/PB13, CH2N/PB14, CH3N/PB15)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM1_DISABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM1_REMAP_NOREMAP, AFIO_MAPR_TIM1_REMAP_FULLREMAP)
+
+/**
+ * @brief Enable the remapping of TIM2 alternate function channels 1 to 4 and external trigger (ETR)
+ * @note ENABLE: Full remap (CH1/ETR/PA15, CH2/PB3, CH3/PB10, CH4/PB11)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM2_ENABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM2_REMAP_FULLREMAP, AFIO_MAPR_TIM2_REMAP_FULLREMAP)
+
+/**
+ * @brief Enable the remapping of TIM2 alternate function channels 1 to 4 and external trigger (ETR)
+ * @note PARTIAL_2: Partial remap (CH1/ETR/PA0, CH2/PA1, CH3/PB10, CH4/PB11)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM2_PARTIAL_2() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM2_REMAP_PARTIALREMAP2, AFIO_MAPR_TIM2_REMAP_FULLREMAP)
+
+/**
+ * @brief Enable the remapping of TIM2 alternate function channels 1 to 4 and external trigger (ETR)
+ * @note PARTIAL_1: Partial remap (CH1/ETR/PA15, CH2/PB3, CH3/PA2, CH4/PA3)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM2_PARTIAL_1() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM2_REMAP_PARTIALREMAP1, AFIO_MAPR_TIM2_REMAP_FULLREMAP)
+
+/**
+ * @brief Disable the remapping of TIM2 alternate function channels 1 to 4 and external trigger (ETR)
+ * @note DISABLE: No remap (CH1/ETR/PA0, CH2/PA1, CH3/PA2, CH4/PA3)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM2_DISABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM2_REMAP_NOREMAP, AFIO_MAPR_TIM2_REMAP_FULLREMAP)
+
+/**
+ * @brief Enable the remapping of TIM3 alternate function channels 1 to 4
+ * @note ENABLE: Full remap (CH1/PC6, CH2/PC7, CH3/PC8, CH4/PC9)
+ * @note TIM3_ETR on PE0 is not re-mapped.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM3_ENABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM3_REMAP_FULLREMAP, AFIO_MAPR_TIM3_REMAP_FULLREMAP)
+
+/**
+ * @brief Enable the remapping of TIM3 alternate function channels 1 to 4
+ * @note PARTIAL: Partial remap (CH1/PB4, CH2/PB5, CH3/PB0, CH4/PB1)
+ * @note TIM3_ETR on PE0 is not re-mapped.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM3_PARTIAL() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM3_REMAP_PARTIALREMAP, AFIO_MAPR_TIM3_REMAP_FULLREMAP)
+
+/**
+ * @brief Disable the remapping of TIM3 alternate function channels 1 to 4
+ * @note DISABLE: No remap (CH1/PA6, CH2/PA7, CH3/PB0, CH4/PB1)
+ * @note TIM3_ETR on PE0 is not re-mapped.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM3_DISABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM3_REMAP_NOREMAP, AFIO_MAPR_TIM3_REMAP_FULLREMAP)
+
+/**
+ * @brief Enable the remapping of TIM4 alternate function channels 1 to 4.
+ * @note ENABLE: Full remap (TIM4_CH1/PD12, TIM4_CH2/PD13, TIM4_CH3/PD14, TIM4_CH4/PD15)
+ * @note TIM4_ETR on PE0 is not re-mapped.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM4_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_TIM4_REMAP)
+
+/**
+ * @brief Disable the remapping of TIM4 alternate function channels 1 to 4.
+ * @note DISABLE: No remap (TIM4_CH1/PB6, TIM4_CH2/PB7, TIM4_CH3/PB8, TIM4_CH4/PB9)
+ * @note TIM4_ETR on PE0 is not re-mapped.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM4_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_TIM4_REMAP)
+
+#if defined(AFIO_MAPR_CAN_REMAP_REMAP1)
+
+/**
+ * @brief Enable or disable the remapping of CAN alternate function CAN_RX and CAN_TX in devices with a single CAN interface.
+ * @note CASE 1: CAN_RX mapped to PA11, CAN_TX mapped to PA12
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_CAN1_1() AFIO_REMAP_PARTIAL(AFIO_MAPR_CAN_REMAP_REMAP1, AFIO_MAPR_CAN_REMAP)
+
+/**
+ * @brief Enable or disable the remapping of CAN alternate function CAN_RX and CAN_TX in devices with a single CAN interface.
+ * @note CASE 2: CAN_RX mapped to PB8, CAN_TX mapped to PB9 (not available on 36-pin package)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_CAN1_2() AFIO_REMAP_PARTIAL(AFIO_MAPR_CAN_REMAP_REMAP2, AFIO_MAPR_CAN_REMAP)
+
+/**
+ * @brief Enable or disable the remapping of CAN alternate function CAN_RX and CAN_TX in devices with a single CAN interface.
+ * @note CASE 3: CAN_RX mapped to PD0, CAN_TX mapped to PD1
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_CAN1_3() AFIO_REMAP_PARTIAL(AFIO_MAPR_CAN_REMAP_REMAP3, AFIO_MAPR_CAN_REMAP)
+
+#endif
+
+/**
+ * @brief Enable the remapping of PD0 and PD1. When the HSE oscillator is not used
+ * (application running on internal 8 MHz RC) PD0 and PD1 can be mapped on OSC_IN and
+ * OSC_OUT. This is available only on 36, 48 and 64 pins packages (PD0 and PD1 are available
+ * on 100-pin and 144-pin packages, no need for remapping).
+ * @note ENABLE: PD0 remapped on OSC_IN, PD1 remapped on OSC_OUT.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_PD01_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_PD01_REMAP)
+
+/**
+ * @brief Disable the remapping of PD0 and PD1. When the HSE oscillator is not used
+ * (application running on internal 8 MHz RC) PD0 and PD1 can be mapped on OSC_IN and
+ * OSC_OUT. This is available only on 36, 48 and 64 pins packages (PD0 and PD1 are available
+ * on 100-pin and 144-pin packages, no need for remapping).
+ * @note DISABLE: No remapping of PD0 and PD1
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_PD01_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_PD01_REMAP)
+
+#if defined(AFIO_MAPR_TIM5CH4_IREMAP)
+/**
+ * @brief Enable the remapping of TIM5CH4.
+ * @note ENABLE: LSI internal clock is connected to TIM5_CH4 input for calibration purpose.
+ * @note This function is available only in high density value line devices.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM5CH4_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_TIM5CH4_IREMAP)
+
+/**
+ * @brief Disable the remapping of TIM5CH4.
+ * @note DISABLE: TIM5_CH4 is connected to PA3
+ * @note This function is available only in high density value line devices.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM5CH4_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_TIM5CH4_IREMAP)
+#endif
+
+#if defined(AFIO_MAPR_ETH_REMAP)
+/**
+ * @brief Enable the remapping of Ethernet MAC connections with the PHY.
+ * @note ENABLE: Remap (RX_DV-CRS_DV/PD8, RXD0/PD9, RXD1/PD10, RXD2/PD11, RXD3/PD12)
+ * @note This bit is available only in connectivity line devices and is reserved otherwise.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_ETH_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_ETH_REMAP)
+
+/**
+ * @brief Disable the remapping of Ethernet MAC connections with the PHY.
+ * @note DISABLE: No remap (RX_DV-CRS_DV/PA7, RXD0/PC4, RXD1/PC5, RXD2/PB0, RXD3/PB1)
+ * @note This bit is available only in connectivity line devices and is reserved otherwise.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_ETH_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_ETH_REMAP)
+#endif
+
+#if defined(AFIO_MAPR_CAN2_REMAP)
+
+/**
+ * @brief Enable the remapping of CAN2 alternate function CAN2_RX and CAN2_TX.
+ * @note ENABLE: Remap (CAN2_RX/PB5, CAN2_TX/PB6)
+ * @note This bit is available only in connectivity line devices and is reserved otherwise.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_CAN2_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_CAN2_REMAP)
+
+/**
+ * @brief Disable the remapping of CAN2 alternate function CAN2_RX and CAN2_TX.
+ * @note DISABLE: No remap (CAN2_RX/PB12, CAN2_TX/PB13)
+ * @note This bit is available only in connectivity line devices and is reserved otherwise.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_CAN2_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_CAN2_REMAP)
+#endif
+
+#if defined(AFIO_MAPR_MII_RMII_SEL)
+/**
+ * @brief Configures the Ethernet MAC internally for use with an external MII or RMII PHY.
+ * @note ETH_RMII: Configure Ethernet MAC for connection with an RMII PHY
+ * @note This bit is available only in connectivity line devices and is reserved otherwise.
+ * @retval None
+ */
+#define __HAL_AFIO_ETH_RMII() AFIO_REMAP_ENABLE(AFIO_MAPR_MII_RMII_SEL)
+
+/**
+ * @brief Configures the Ethernet MAC internally for use with an external MII or RMII PHY.
+ * @note ETH_MII: Configure Ethernet MAC for connection with an MII PHY
+ * @note This bit is available only in connectivity line devices and is reserved otherwise.
+ * @retval None
+ */
+#define __HAL_AFIO_ETH_MII() AFIO_REMAP_DISABLE(AFIO_MAPR_MII_RMII_SEL)
+#endif
+
+/**
+ * @brief Enable the remapping of ADC1_ETRGINJ (ADC 1 External trigger injected conversion).
+ * @note ENABLE: ADC1 External Event injected conversion is connected to TIM8 Channel4.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_ADC1_ETRGINJ_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_ADC1_ETRGINJ_REMAP)
+
+/**
+ * @brief Disable the remapping of ADC1_ETRGINJ (ADC 1 External trigger injected conversion).
+ * @note DISABLE: ADC1 External trigger injected conversion is connected to EXTI15
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_ADC1_ETRGINJ_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_ADC1_ETRGINJ_REMAP)
+
+/**
+ * @brief Enable the remapping of ADC1_ETRGREG (ADC 1 External trigger regular conversion).
+ * @note ENABLE: ADC1 External Event regular conversion is connected to TIM8 TRG0.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_ADC1_ETRGREG_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_ADC1_ETRGREG_REMAP)
+
+/**
+ * @brief Disable the remapping of ADC1_ETRGREG (ADC 1 External trigger regular conversion).
+ * @note DISABLE: ADC1 External trigger regular conversion is connected to EXTI11
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_ADC1_ETRGREG_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_ADC1_ETRGREG_REMAP)
+
+#if defined(AFIO_MAPR_ADC2_ETRGINJ_REMAP)
+
+/**
+ * @brief Enable the remapping of ADC2_ETRGREG (ADC 2 External trigger injected conversion).
+ * @note ENABLE: ADC2 External Event injected conversion is connected to TIM8 Channel4.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_ADC2_ETRGINJ_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_ADC2_ETRGINJ_REMAP)
+
+/**
+ * @brief Disable the remapping of ADC2_ETRGREG (ADC 2 External trigger injected conversion).
+ * @note DISABLE: ADC2 External trigger injected conversion is connected to EXTI15
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_ADC2_ETRGINJ_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_ADC2_ETRGINJ_REMAP)
+#endif
+
+#if defined (AFIO_MAPR_ADC2_ETRGREG_REMAP)
+
+/**
+ * @brief Enable the remapping of ADC2_ETRGREG (ADC 2 External trigger regular conversion).
+ * @note ENABLE: ADC2 External Event regular conversion is connected to TIM8 TRG0.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_ADC2_ETRGREG_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_ADC2_ETRGREG_REMAP)
+
+/**
+ * @brief Disable the remapping of ADC2_ETRGREG (ADC 2 External trigger regular conversion).
+ * @note DISABLE: ADC2 External trigger regular conversion is connected to EXTI11
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_ADC2_ETRGREG_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_ADC2_ETRGREG_REMAP)
+#endif
+
+/**
+ * @brief Enable the Serial wire JTAG configuration
+ * @note ENABLE: Full SWJ (JTAG-DP + SW-DP): Reset State
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_SWJ_ENABLE() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_RESET)
+
+/**
+ * @brief Enable the Serial wire JTAG configuration
+ * @note NONJTRST: Full SWJ (JTAG-DP + SW-DP) but without NJTRST
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_SWJ_NONJTRST() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_NOJNTRST)
+
+/**
+ * @brief Enable the Serial wire JTAG configuration
+ * @note NOJTAG: JTAG-DP Disabled and SW-DP Enabled
+ * @retval None
+ */
+
+#define __HAL_AFIO_REMAP_SWJ_NOJTAG() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_JTAGDISABLE)
+
+/**
+ * @brief Disable the Serial wire JTAG configuration
+ * @note DISABLE: JTAG-DP Disabled and SW-DP Disabled
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_SWJ_DISABLE() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_DISABLE)
+
+#if defined(AFIO_MAPR_SPI3_REMAP)
+
+/**
+ * @brief Enable the remapping of SPI3 alternate functions SPI3_NSS/I2S3_WS, SPI3_SCK/I2S3_CK, SPI3_MISO, SPI3_MOSI/I2S3_SD.
+ * @note ENABLE: Remap (SPI3_NSS-I2S3_WS/PA4, SPI3_SCK-I2S3_CK/PC10, SPI3_MISO/PC11, SPI3_MOSI-I2S3_SD/PC12)
+ * @note This bit is available only in connectivity line devices and is reserved otherwise.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_SPI3_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_SPI3_REMAP)
+
+/**
+ * @brief Disable the remapping of SPI3 alternate functions SPI3_NSS/I2S3_WS, SPI3_SCK/I2S3_CK, SPI3_MISO, SPI3_MOSI/I2S3_SD.
+ * @note DISABLE: No remap (SPI3_NSS-I2S3_WS/PA15, SPI3_SCK-I2S3_CK/PB3, SPI3_MISO/PB4, SPI3_MOSI-I2S3_SD/PB5).
+ * @note This bit is available only in connectivity line devices and is reserved otherwise.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_SPI3_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_SPI3_REMAP)
+#endif
+
+#if defined(AFIO_MAPR_TIM2ITR1_IREMAP)
+
+/**
+ * @brief Control of TIM2_ITR1 internal mapping.
+ * @note TO_USB: Connect USB OTG SOF (Start of Frame) output to TIM2_ITR1 for calibration purposes.
+ * @note This bit is available only in connectivity line devices and is reserved otherwise.
+ * @retval None
+ */
+#define __HAL_AFIO_TIM2ITR1_TO_USB() AFIO_REMAP_ENABLE(AFIO_MAPR_TIM2ITR1_IREMAP)
+
+/**
+ * @brief Control of TIM2_ITR1 internal mapping.
+ * @note TO_ETH: Connect TIM2_ITR1 internally to the Ethernet PTP output for calibration purposes.
+ * @note This bit is available only in connectivity line devices and is reserved otherwise.
+ * @retval None
+ */
+#define __HAL_AFIO_TIM2ITR1_TO_ETH() AFIO_REMAP_DISABLE(AFIO_MAPR_TIM2ITR1_IREMAP)
+#endif
+
+#if defined(AFIO_MAPR_PTP_PPS_REMAP)
+
+/**
+ * @brief Enable the remapping of ADC2_ETRGREG (ADC 2 External trigger regular conversion).
+ * @note ENABLE: PTP_PPS is output on PB5 pin.
+ * @note This bit is available only in connectivity line devices and is reserved otherwise.
+ * @retval None
+ */
+#define __HAL_AFIO_ETH_PTP_PPS_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_PTP_PPS_REMAP)
+
+/**
+ * @brief Disable the remapping of ADC2_ETRGREG (ADC 2 External trigger regular conversion).
+ * @note DISABLE: PTP_PPS not output on PB5 pin.
+ * @note This bit is available only in connectivity line devices and is reserved otherwise.
+ * @retval None
+ */
+#define __HAL_AFIO_ETH_PTP_PPS_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_PTP_PPS_REMAP)
+#endif
+
+#if defined(AFIO_MAPR2_TIM9_REMAP)
+
+/**
+ * @brief Enable the remapping of TIM9_CH1 and TIM9_CH2.
+ * @note ENABLE: Remap (TIM9_CH1 on PE5 and TIM9_CH2 on PE6).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM9_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM9_REMAP)
+
+/**
+ * @brief Disable the remapping of TIM9_CH1 and TIM9_CH2.
+ * @note DISABLE: No remap (TIM9_CH1 on PA2 and TIM9_CH2 on PA3).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM9_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM9_REMAP)
+#endif
+
+#if defined(AFIO_MAPR2_TIM10_REMAP)
+
+/**
+ * @brief Enable the remapping of TIM10_CH1.
+ * @note ENABLE: Remap (TIM10_CH1 on PF6).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM10_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM10_REMAP)
+
+/**
+ * @brief Disable the remapping of TIM10_CH1.
+ * @note DISABLE: No remap (TIM10_CH1 on PB8).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM10_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM10_REMAP)
+#endif
+
+#if defined(AFIO_MAPR2_TIM11_REMAP)
+/**
+ * @brief Enable the remapping of TIM11_CH1.
+ * @note ENABLE: Remap (TIM11_CH1 on PF7).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM11_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM11_REMAP)
+
+/**
+ * @brief Disable the remapping of TIM11_CH1.
+ * @note DISABLE: No remap (TIM11_CH1 on PB9).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM11_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM11_REMAP)
+#endif
+
+#if defined(AFIO_MAPR2_TIM13_REMAP)
+
+/**
+ * @brief Enable the remapping of TIM13_CH1.
+ * @note ENABLE: Remap STM32F100:(TIM13_CH1 on PF8). Others:(TIM13_CH1 on PB0).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM13_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM13_REMAP)
+
+/**
+ * @brief Disable the remapping of TIM13_CH1.
+ * @note DISABLE: No remap STM32F100:(TIM13_CH1 on PA6). Others:(TIM13_CH1 on PC8).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM13_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM13_REMAP)
+#endif
+
+#if defined(AFIO_MAPR2_TIM14_REMAP)
+
+/**
+ * @brief Enable the remapping of TIM14_CH1.
+ * @note ENABLE: Remap STM32F100:(TIM14_CH1 on PB1). Others:(TIM14_CH1 on PF9).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM14_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM14_REMAP)
+
+/**
+ * @brief Disable the remapping of TIM14_CH1.
+ * @note DISABLE: No remap STM32F100:(TIM14_CH1 on PC9). Others:(TIM14_CH1 on PA7).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM14_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM14_REMAP)
+#endif
+
+#if defined(AFIO_MAPR2_FSMC_NADV_REMAP)
+
+/**
+ * @brief Controls the use of the optional FSMC_NADV signal.
+ * @note DISCONNECTED: The NADV signal is not connected. The I/O pin can be used by another peripheral.
+ * @retval None
+ */
+#define __HAL_AFIO_FSMCNADV_DISCONNECTED() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_FSMC_NADV_REMAP)
+
+/**
+ * @brief Controls the use of the optional FSMC_NADV signal.
+ * @note CONNECTED: The NADV signal is connected to the output (default).
+ * @retval None
+ */
+#define __HAL_AFIO_FSMCNADV_CONNECTED() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_FSMC_NADV_REMAP)
+#endif
+
+#if defined(AFIO_MAPR2_TIM15_REMAP)
+
+/**
+ * @brief Enable the remapping of TIM15_CH1 and TIM15_CH2.
+ * @note ENABLE: Remap (TIM15_CH1 on PB14 and TIM15_CH2 on PB15).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM15_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM15_REMAP)
+
+/**
+ * @brief Disable the remapping of TIM15_CH1 and TIM15_CH2.
+ * @note DISABLE: No remap (TIM15_CH1 on PA2 and TIM15_CH2 on PA3).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM15_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM15_REMAP)
+#endif
+
+#if defined(AFIO_MAPR2_TIM16_REMAP)
+
+/**
+ * @brief Enable the remapping of TIM16_CH1.
+ * @note ENABLE: Remap (TIM16_CH1 on PA6).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM16_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM16_REMAP)
+
+/**
+ * @brief Disable the remapping of TIM16_CH1.
+ * @note DISABLE: No remap (TIM16_CH1 on PB8).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM16_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM16_REMAP)
+#endif
+
+#if defined(AFIO_MAPR2_TIM17_REMAP)
+
+/**
+ * @brief Enable the remapping of TIM17_CH1.
+ * @note ENABLE: Remap (TIM17_CH1 on PA7).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM17_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM17_REMAP)
+
+/**
+ * @brief Disable the remapping of TIM17_CH1.
+ * @note DISABLE: No remap (TIM17_CH1 on PB9).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM17_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM17_REMAP)
+#endif
+
+#if defined(AFIO_MAPR2_CEC_REMAP)
+
+/**
+ * @brief Enable the remapping of CEC.
+ * @note ENABLE: Remap (CEC on PB10).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_CEC_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_CEC_REMAP)
+
+/**
+ * @brief Disable the remapping of CEC.
+ * @note DISABLE: No remap (CEC on PB8).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_CEC_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_CEC_REMAP)
+#endif
+
+#if defined(AFIO_MAPR2_TIM1_DMA_REMAP)
+
+/**
+ * @brief Controls the mapping of the TIM1_CH1 TIM1_CH2 DMA requests onto the DMA1 channels.
+ * @note ENABLE: Remap (TIM1_CH1 DMA request/DMA1 Channel6, TIM1_CH2 DMA request/DMA1 Channel6)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM1DMA_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM1_DMA_REMAP)
+
+/**
+ * @brief Controls the mapping of the TIM1_CH1 TIM1_CH2 DMA requests onto the DMA1 channels.
+ * @note DISABLE: No remap (TIM1_CH1 DMA request/DMA1 Channel2, TIM1_CH2 DMA request/DMA1 Channel3).
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM1DMA_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM1_DMA_REMAP)
+#endif
+
+#if defined(AFIO_MAPR2_TIM67_DAC_DMA_REMAP)
+
+/**
+ * @brief Controls the mapping of the TIM6_DAC1 and TIM7_DAC2 DMA requests onto the DMA1 channels.
+ * @note ENABLE: Remap (TIM6_DAC1 DMA request/DMA1 Channel3, TIM7_DAC2 DMA request/DMA1 Channel4)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM67DACDMA_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM67_DAC_DMA_REMAP)
+
+/**
+ * @brief Controls the mapping of the TIM6_DAC1 and TIM7_DAC2 DMA requests onto the DMA1 channels.
+ * @note DISABLE: No remap (TIM6_DAC1 DMA request/DMA2 Channel3, TIM7_DAC2 DMA request/DMA2 Channel4)
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM67DACDMA_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM67_DAC_DMA_REMAP)
+#endif
+
+#if defined(AFIO_MAPR2_TIM12_REMAP)
+
+/**
+ * @brief Enable the remapping of TIM12_CH1 and TIM12_CH2.
+ * @note ENABLE: Remap (TIM12_CH1 on PB12 and TIM12_CH2 on PB13).
+ * @note This bit is available only in high density value line devices.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM12_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM12_REMAP)
+
+/**
+ * @brief Disable the remapping of TIM12_CH1 and TIM12_CH2.
+ * @note DISABLE: No remap (TIM12_CH1 on PC4 and TIM12_CH2 on PC5).
+ * @note This bit is available only in high density value line devices.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_TIM12_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_TIM12_REMAP)
+#endif
+
+#if defined(AFIO_MAPR2_MISC_REMAP)
+
+/**
+ * @brief Miscellaneous features remapping.
+ * This bit is set and cleared by software. It controls miscellaneous features.
+ * The DMA2 channel 5 interrupt position in the vector table.
+ * The timer selection for DAC trigger 3 (TSEL[2:0] = 011, for more details refer to the DAC_CR register).
+ * @note ENABLE: DMA2 channel 5 interrupt is mapped separately at position 60 and TIM15 TRGO event is
+ * selected as DAC Trigger 3, TIM15 triggers TIM1/3.
+ * @note This bit is available only in high density value line devices.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_MISC_ENABLE() SET_BIT(AFIO->MAPR2, AFIO_MAPR2_MISC_REMAP)
+
+/**
+ * @brief Miscellaneous features remapping.
+ * This bit is set and cleared by software. It controls miscellaneous features.
+ * The DMA2 channel 5 interrupt position in the vector table.
+ * The timer selection for DAC trigger 3 (TSEL[2:0] = 011, for more details refer to the DAC_CR register).
+ * @note DISABLE: DMA2 channel 5 interrupt is mapped with DMA2 channel 4 at position 59, TIM5 TRGO
+ * event is selected as DAC Trigger 3, TIM5 triggers TIM1/3.
+ * @note This bit is available only in high density value line devices.
+ * @retval None
+ */
+#define __HAL_AFIO_REMAP_MISC_DISABLE() CLEAR_BIT(AFIO->MAPR2, AFIO_MAPR2_MISC_REMAP)
+#endif
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup GPIOEx_Private_Macros GPIOEx Private Macros
+ * @{
+ */
+#if defined(STM32F101x6) || defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)
+#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0U :\
+ ((__GPIOx__) == (GPIOB))? 1U :\
+ ((__GPIOx__) == (GPIOC))? 2U :3U)
+#elif defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F103xB) || defined(STM32F105xC) || defined(STM32F107xC)
+#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0U :\
+ ((__GPIOx__) == (GPIOB))? 1U :\
+ ((__GPIOx__) == (GPIOC))? 2U :\
+ ((__GPIOx__) == (GPIOD))? 3U :4U)
+#elif defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
+#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0U :\
+ ((__GPIOx__) == (GPIOB))? 1U :\
+ ((__GPIOx__) == (GPIOC))? 2U :\
+ ((__GPIOx__) == (GPIOD))? 3U :\
+ ((__GPIOx__) == (GPIOE))? 4U :\
+ ((__GPIOx__) == (GPIOF))? 5U :6U)
+#endif
+
+#define AFIO_REMAP_ENABLE(REMAP_PIN) do{ uint32_t tmpreg = AFIO->MAPR; \
+ tmpreg |= AFIO_MAPR_SWJ_CFG; \
+ tmpreg |= REMAP_PIN; \
+ AFIO->MAPR = tmpreg; \
+ }while(0U)
+
+#define AFIO_REMAP_DISABLE(REMAP_PIN) do{ uint32_t tmpreg = AFIO->MAPR; \
+ tmpreg |= AFIO_MAPR_SWJ_CFG; \
+ tmpreg &= ~REMAP_PIN; \
+ AFIO->MAPR = tmpreg; \
+ }while(0U)
+
+#define AFIO_REMAP_PARTIAL(REMAP_PIN, REMAP_PIN_MASK) do{ uint32_t tmpreg = AFIO->MAPR; \
+ tmpreg &= ~REMAP_PIN_MASK; \
+ tmpreg |= AFIO_MAPR_SWJ_CFG; \
+ tmpreg |= REMAP_PIN; \
+ AFIO->MAPR = tmpreg; \
+ }while(0U)
+
+#define AFIO_DBGAFR_CONFIG(DBGAFR_SWJCFG) do{ uint32_t tmpreg = AFIO->MAPR; \
+ tmpreg &= ~AFIO_MAPR_SWJ_CFG_Msk; \
+ tmpreg |= DBGAFR_SWJCFG; \
+ AFIO->MAPR = tmpreg; \
+ }while(0U)
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/** @addtogroup GPIOEx_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup GPIOEx_Exported_Functions_Group1
+ * @{
+ */
+void HAL_GPIOEx_ConfigEventout(uint32_t GPIO_PortSource, uint32_t GPIO_PinSource);
+void HAL_GPIOEx_EnableEventout(void);
+void HAL_GPIOEx_DisableEventout(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_GPIO_EX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_hcd.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_hcd.h
new file mode 100644
index 0000000..f635e14
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_hcd.h
@@ -0,0 +1,252 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_hcd.h
+ * @author MCD Application Team
+ * @brief Header file of HCD HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_HCD_H
+#define __STM32F1xx_HAL_HCD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#if defined(STM32F105xC) || defined(STM32F107xC)
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_usb.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup HCD
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup HCD_Exported_Types HCD Exported Types
+ * @{
+ */
+
+/**
+ * @brief HCD Status structure definition
+ */
+typedef enum
+{
+ HAL_HCD_STATE_RESET = 0x00U,
+ HAL_HCD_STATE_READY = 0x01U,
+ HAL_HCD_STATE_ERROR = 0x02U,
+ HAL_HCD_STATE_BUSY = 0x03U,
+ HAL_HCD_STATE_TIMEOUT = 0x04U
+} HCD_StateTypeDef;
+
+typedef USB_OTG_GlobalTypeDef HCD_TypeDef;
+typedef USB_OTG_CfgTypeDef HCD_InitTypeDef;
+typedef USB_OTG_HCTypeDef HCD_HCTypeDef;
+typedef USB_OTG_URBStateTypeDef HCD_URBStateTypeDef;
+typedef USB_OTG_HCStateTypeDef HCD_HCStateTypeDef;
+
+/**
+ * @brief HCD Handle Structure definition
+ */
+typedef struct
+{
+ HCD_TypeDef *Instance; /*!< Register base address */
+ HCD_InitTypeDef Init; /*!< HCD required parameters */
+ HCD_HCTypeDef hc[15U]; /*!< Host channels parameters */
+ HAL_LockTypeDef Lock; /*!< HCD peripheral status */
+ __IO HCD_StateTypeDef State; /*!< HCD communication state */
+ void *pData; /*!< Pointer Stack Handler */
+} HCD_HandleTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup HCD_Exported_Constants HCD Exported Constants
+ * @{
+ */
+/** @defgroup HCD_Speed HCD Speed
+ * @{
+ */
+#define HCD_SPEED_LOW 2U
+#define HCD_SPEED_FULL 3U
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup HCD_Exported_Macros HCD Exported Macros
+ * @brief macros to handle interrupts and specific clock configurations
+ * @{
+ */
+#define __HAL_HCD_ENABLE(__HANDLE__) USB_EnableGlobalInt ((__HANDLE__)->Instance)
+#define __HAL_HCD_DISABLE(__HANDLE__) USB_DisableGlobalInt ((__HANDLE__)->Instance)
+
+
+#define __HAL_HCD_GET_FLAG(__HANDLE__, __INTERRUPT__) ((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__))
+#define __HAL_HCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->GINTSTS) = (__INTERRUPT__))
+#define __HAL_HCD_IS_INVALID_INTERRUPT(__HANDLE__) (USB_ReadInterrupts((__HANDLE__)->Instance) == 0U)
+
+
+#define __HAL_HCD_CLEAR_HC_INT(chnum, __INTERRUPT__) (USBx_HC(chnum)->HCINT = (__INTERRUPT__))
+#define __HAL_HCD_MASK_HALT_HC_INT(chnum) (USBx_HC(chnum)->HCINTMSK &= ~USB_OTG_HCINTMSK_CHHM)
+#define __HAL_HCD_UNMASK_HALT_HC_INT(chnum) (USBx_HC(chnum)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM)
+#define __HAL_HCD_MASK_ACK_HC_INT(chnum) (USBx_HC(chnum)->HCINTMSK &= ~USB_OTG_HCINTMSK_ACKM)
+#define __HAL_HCD_UNMASK_ACK_HC_INT(chnum) (USBx_HC(chnum)->HCINTMSK |= USB_OTG_HCINTMSK_ACKM)
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup HCD_Exported_Functions HCD Exported Functions
+ * @{
+ */
+
+/* Initialization/de-initialization functions ********************************/
+/** @addtogroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @{
+ */
+HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd);
+HAL_StatusTypeDef HAL_HCD_DeInit (HCD_HandleTypeDef *hhcd);
+HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd,
+ uint8_t ch_num,
+ uint8_t epnum,
+ uint8_t dev_address,
+ uint8_t speed,
+ uint8_t ep_type,
+ uint16_t mps);
+
+HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd,
+ uint8_t ch_num);
+
+void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd);
+void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd);
+/**
+ * @}
+ */
+
+/* I/O operation functions ***************************************************/
+/** @addtogroup HCD_Exported_Functions_Group2 IO operation functions
+ * @{
+ */
+HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
+ uint8_t pipe,
+ uint8_t direction,
+ uint8_t ep_type,
+ uint8_t token,
+ uint8_t* pbuff,
+ uint16_t length,
+ uint8_t do_ping);
+
+ /* Non-Blocking mode: Interrupt */
+void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd);
+void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd);
+void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd);
+void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd);
+void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd,
+ uint8_t chnum,
+ HCD_URBStateTypeDef urb_state);
+/**
+ * @}
+ */
+/* Peripheral Control functions **********************************************/
+/** @addtogroup HCD_Exported_Functions_Group3 Peripheral Control functions
+ * @{
+ */
+HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd);
+HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd);
+HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd);
+/**
+ * @}
+ */
+/* Peripheral State functions ************************************************/
+/** @addtogroup HCD_Exported_Functions_Group4 Peripheral State functions
+ * @{
+ */
+HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd);
+HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum);
+uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum);
+HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum);
+uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd);
+uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup HCD_Private_Macros HCD Private Macros
+ * @{
+ */
+/** @defgroup HCD_Instance_definition HCD Instance definition
+ * @{
+ */
+ #define IS_HCD_ALL_INSTANCE(INSTANCE) (((INSTANCE) == USB_OTG_FS))
+/**
+ * @}
+ */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F105xC || STM32F107xC */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_HCD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h
new file mode 100644
index 0000000..f8a6839
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h
@@ -0,0 +1,650 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_i2c.h
+ * @author MCD Application Team
+ * @brief Header file of I2C HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_I2C_H
+#define __STM32F1xx_HAL_I2C_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup I2C
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup I2C_Exported_Types I2C Exported Types
+ * @{
+ */
+
+/**
+ * @brief I2C Configuration Structure definition
+ */
+typedef struct
+{
+ uint32_t ClockSpeed; /*!< Specifies the clock frequency.
+ This parameter must be set to a value lower than 400kHz */
+
+ uint32_t DutyCycle; /*!< Specifies the I2C fast mode duty cycle.
+ This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */
+
+ uint32_t OwnAddress1; /*!< Specifies the first device own address.
+ This parameter can be a 7-bit or 10-bit address. */
+
+ uint32_t AddressingMode; /*!< Specifies if 7-bit or 10-bit addressing mode is selected.
+ This parameter can be a value of @ref I2C_addressing_mode */
+
+ uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected.
+ This parameter can be a value of @ref I2C_dual_addressing_mode */
+
+ uint32_t OwnAddress2; /*!< Specifies the second device own address if dual addressing mode is selected
+ This parameter can be a 7-bit address. */
+
+ uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected.
+ This parameter can be a value of @ref I2C_general_call_addressing_mode */
+
+ uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected.
+ This parameter can be a value of @ref I2C_nostretch_mode */
+
+}I2C_InitTypeDef;
+
+/**
+ * @brief HAL State structure definition
+ * @note HAL I2C State value coding follow below described bitmap :
+ * b7-b6 Error information
+ * 00 : No Error
+ * 01 : Abort (Abort user request on going)
+ * 10 : Timeout
+ * 11 : Error
+ * b5 IP initilisation status
+ * 0 : Reset (IP not initialized)
+ * 1 : Init done (IP initialized and ready to use. HAL I2C Init function called)
+ * b4 (not used)
+ * x : Should be set to 0
+ * b3
+ * 0 : Ready or Busy (No Listen mode ongoing)
+ * 1 : Listen (IP in Address Listen Mode)
+ * b2 Intrinsic process state
+ * 0 : Ready
+ * 1 : Busy (IP busy with some configuration or internal operations)
+ * b1 Rx state
+ * 0 : Ready (no Rx operation ongoing)
+ * 1 : Busy (Rx operation ongoing)
+ * b0 Tx state
+ * 0 : Ready (no Tx operation ongoing)
+ * 1 : Busy (Tx operation ongoing)
+ */
+typedef enum
+{
+ HAL_I2C_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */
+ HAL_I2C_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use */
+ HAL_I2C_STATE_BUSY = 0x24U, /*!< An internal process is ongoing */
+ HAL_I2C_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing */
+ HAL_I2C_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */
+ HAL_I2C_STATE_LISTEN = 0x28U, /*!< Address Listen Mode is ongoing */
+ HAL_I2C_STATE_BUSY_TX_LISTEN = 0x29U, /*!< Address Listen Mode and Data Transmission
+ process is ongoing */
+ HAL_I2C_STATE_BUSY_RX_LISTEN = 0x2AU, /*!< Address Listen Mode and Data Reception
+ process is ongoing */
+ HAL_I2C_STATE_ABORT = 0x60U, /*!< Abort user request ongoing */
+ HAL_I2C_STATE_TIMEOUT = 0xA0U, /*!< Timeout state */
+ HAL_I2C_STATE_ERROR = 0xE0U /*!< Error */
+
+}HAL_I2C_StateTypeDef;
+
+/**
+ * @brief HAL Mode structure definition
+ * @note HAL I2C Mode value coding follow below described bitmap :
+ * b7 (not used)
+ * x : Should be set to 0
+ * b6
+ * 0 : None
+ * 1 : Memory (HAL I2C communication is in Memory Mode)
+ * b5
+ * 0 : None
+ * 1 : Slave (HAL I2C communication is in Slave Mode)
+ * b4
+ * 0 : None
+ * 1 : Master (HAL I2C communication is in Master Mode)
+ * b3-b2-b1-b0 (not used)
+ * xxxx : Should be set to 0000
+ */
+typedef enum
+{
+ HAL_I2C_MODE_NONE = 0x00U, /*!< No I2C communication on going */
+ HAL_I2C_MODE_MASTER = 0x10U, /*!< I2C communication is in Master Mode */
+ HAL_I2C_MODE_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */
+ HAL_I2C_MODE_MEM = 0x40U /*!< I2C communication is in Memory Mode */
+
+}HAL_I2C_ModeTypeDef;
+
+/**
+ * @brief I2C handle Structure definition
+ */
+typedef struct
+{
+ I2C_TypeDef *Instance; /*!< I2C registers base address */
+
+ I2C_InitTypeDef Init; /*!< I2C communication parameters */
+
+ uint8_t *pBuffPtr; /*!< Pointer to I2C transfer buffer */
+
+ uint16_t XferSize; /*!< I2C transfer size */
+
+ __IO uint16_t XferCount; /*!< I2C transfer counter */
+
+ __IO uint32_t XferOptions; /*!< I2C transfer options */
+
+ __IO uint32_t PreviousState; /*!< I2C communication Previous state and mode
+ context for internal usage */
+
+ DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */
+
+ DMA_HandleTypeDef *hdmarx; /*!< I2C Rx DMA handle parameters */
+
+ HAL_LockTypeDef Lock; /*!< I2C locking object */
+
+ __IO HAL_I2C_StateTypeDef State; /*!< I2C communication state */
+
+ __IO HAL_I2C_ModeTypeDef Mode; /*!< I2C communication mode */
+
+ __IO uint32_t ErrorCode; /*!< I2C Error code */
+
+ __IO uint32_t Devaddress; /*!< I2C Target device address */
+
+ __IO uint32_t Memaddress; /*!< I2C Target memory address */
+
+ __IO uint32_t MemaddSize; /*!< I2C Target memory address size */
+
+ __IO uint32_t EventCount; /*!< I2C Event counter */
+
+}I2C_HandleTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup I2C_Exported_Constants I2C Exported Constants
+ * @{
+ */
+
+/** @defgroup I2C_Error_Code I2C Error Code
+ * @brief I2C Error Code
+ * @{
+ */
+#define HAL_I2C_ERROR_NONE 0x00000000U /*!< No error */
+#define HAL_I2C_ERROR_BERR 0x00000001U /*!< BERR error */
+#define HAL_I2C_ERROR_ARLO 0x00000002U /*!< ARLO error */
+#define HAL_I2C_ERROR_AF 0x00000004U /*!< AF error */
+#define HAL_I2C_ERROR_OVR 0x00000008U /*!< OVR error */
+#define HAL_I2C_ERROR_DMA 0x00000010U /*!< DMA transfer error */
+#define HAL_I2C_ERROR_TIMEOUT 0x00000020U /*!< Timeout Error */
+/**
+ * @}
+ */
+
+/** @defgroup I2C_duty_cycle_in_fast_mode I2C duty cycle in fast mode
+ * @{
+ */
+#define I2C_DUTYCYCLE_2 0x00000000U
+#define I2C_DUTYCYCLE_16_9 I2C_CCR_DUTY
+/**
+ * @}
+ */
+
+/** @defgroup I2C_addressing_mode I2C addressing mode
+ * @{
+ */
+#define I2C_ADDRESSINGMODE_7BIT 0x00004000U
+#define I2C_ADDRESSINGMODE_10BIT (I2C_OAR1_ADDMODE | 0x00004000U)
+/**
+ * @}
+ */
+
+/** @defgroup I2C_dual_addressing_mode I2C dual addressing mode
+ * @{
+ */
+#define I2C_DUALADDRESS_DISABLE 0x00000000U
+#define I2C_DUALADDRESS_ENABLE I2C_OAR2_ENDUAL
+/**
+ * @}
+ */
+
+/** @defgroup I2C_general_call_addressing_mode I2C general call addressing mode
+ * @{
+ */
+#define I2C_GENERALCALL_DISABLE 0x00000000U
+#define I2C_GENERALCALL_ENABLE I2C_CR1_ENGC
+/**
+ * @}
+ */
+
+/** @defgroup I2C_nostretch_mode I2C nostretch mode
+ * @{
+ */
+#define I2C_NOSTRETCH_DISABLE 0x00000000U
+#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Memory_Address_Size I2C Memory Address Size
+ * @{
+ */
+#define I2C_MEMADD_SIZE_8BIT 0x00000001U
+#define I2C_MEMADD_SIZE_16BIT 0x00000010U
+/**
+ * @}
+ */
+
+/** @defgroup I2C_XferDirection_definition I2C XferDirection definition
+ * @{
+ */
+#define I2C_DIRECTION_RECEIVE 0x00000000U
+#define I2C_DIRECTION_TRANSMIT 0x00000001U
+/**
+ * @}
+ */
+
+/** @defgroup I2C_XferOptions_definition I2C XferOptions definition
+ * @{
+ */
+#define I2C_FIRST_FRAME 0x00000001U
+#define I2C_NEXT_FRAME 0x00000002U
+#define I2C_FIRST_AND_LAST_FRAME 0x00000004U
+#define I2C_LAST_FRAME 0x00000008U
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Interrupt_configuration_definition I2C Interrupt configuration definition
+ * @{
+ */
+#define I2C_IT_BUF I2C_CR2_ITBUFEN
+#define I2C_IT_EVT I2C_CR2_ITEVTEN
+#define I2C_IT_ERR I2C_CR2_ITERREN
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Flag_definition I2C Flag definition
+ * @{
+ */
+#define I2C_FLAG_SMBALERT 0x00018000U
+#define I2C_FLAG_TIMEOUT 0x00014000U
+#define I2C_FLAG_PECERR 0x00011000U
+#define I2C_FLAG_OVR 0x00010800U
+#define I2C_FLAG_AF 0x00010400U
+#define I2C_FLAG_ARLO 0x00010200U
+#define I2C_FLAG_BERR 0x00010100U
+#define I2C_FLAG_TXE 0x00010080U
+#define I2C_FLAG_RXNE 0x00010040U
+#define I2C_FLAG_STOPF 0x00010010U
+#define I2C_FLAG_ADD10 0x00010008U
+#define I2C_FLAG_BTF 0x00010004U
+#define I2C_FLAG_ADDR 0x00010002U
+#define I2C_FLAG_SB 0x00010001U
+#define I2C_FLAG_DUALF 0x00100080U
+#define I2C_FLAG_SMBHOST 0x00100040U
+#define I2C_FLAG_SMBDEFAULT 0x00100020U
+#define I2C_FLAG_GENCALL 0x00100010U
+#define I2C_FLAG_TRA 0x00100004U
+#define I2C_FLAG_BUSY 0x00100002U
+#define I2C_FLAG_MSL 0x00100001U
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup I2C_Exported_Macros I2C Exported Macros
+ * @{
+ */
+
+/** @brief Reset I2C handle state
+ * @param __HANDLE__: specifies the I2C Handle.
+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
+ * @retval None
+ */
+#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2C_STATE_RESET)
+
+/** @brief Enable or disable the specified I2C interrupts.
+ * @param __HANDLE__: specifies the I2C Handle.
+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
+ * @param __INTERRUPT__: specifies the interrupt source to enable or disable.
+ * This parameter can be one of the following values:
+ * @arg I2C_IT_BUF: Buffer interrupt enable
+ * @arg I2C_IT_EVT: Event interrupt enable
+ * @arg I2C_IT_ERR: Error interrupt enable
+ * @retval None
+ */
+#define __HAL_I2C_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 |= (__INTERRUPT__))
+#define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 &= (~(__INTERRUPT__)))
+
+/** @brief Checks if the specified I2C interrupt source is enabled or disabled.
+ * @param __HANDLE__: specifies the I2C Handle.
+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
+ * @param __INTERRUPT__: specifies the I2C interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg I2C_IT_BUF: Buffer interrupt enable
+ * @arg I2C_IT_EVT: Event interrupt enable
+ * @arg I2C_IT_ERR: Error interrupt enable
+ * @retval The new state of __INTERRUPT__ (TRUE or FALSE).
+ */
+#define __HAL_I2C_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
+
+/** @brief Checks whether the specified I2C flag is set or not.
+ * @param __HANDLE__: specifies the I2C Handle.
+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be one 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
+ * @arg I2C_FLAG_AF: Acknowledge failure flag
+ * @arg I2C_FLAG_ARLO: Arbitration lost flag
+ * @arg I2C_FLAG_BERR: Bus error flag
+ * @arg I2C_FLAG_TXE: Data register empty flag
+ * @arg I2C_FLAG_RXNE: Data register not empty flag
+ * @arg I2C_FLAG_STOPF: Stop detection flag
+ * @arg I2C_FLAG_ADD10: 10-bit header sent flag
+ * @arg I2C_FLAG_BTF: Byte transfer finished flag
+ * @arg I2C_FLAG_ADDR: Address sent flag
+ * Address matched flag
+ * @arg I2C_FLAG_SB: Start bit flag
+ * @arg I2C_FLAG_DUALF: Dual flag
+ * @arg I2C_FLAG_SMBHOST: SMBus host header
+ * @arg I2C_FLAG_SMBDEFAULT: SMBus default header
+ * @arg I2C_FLAG_GENCALL: General call header flag
+ * @arg I2C_FLAG_TRA: Transmitter/Receiver flag
+ * @arg I2C_FLAG_BUSY: Bus busy flag
+ * @arg I2C_FLAG_MSL: Master/Slave flag
+ * @retval The new state of __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_I2C_GET_FLAG(__HANDLE__, __FLAG__) ((((uint8_t)((__FLAG__) >> 16U)) == 0x01U)?((((__HANDLE__)->Instance->SR1) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)): \
+ ((((__HANDLE__)->Instance->SR2) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)))
+
+/** @brief Clears the I2C pending flags which are cleared by writing 0 in a specific bit.
+ * @param __HANDLE__: specifies the I2C Handle.
+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
+ * @param __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
+ * @retval None
+ */
+#define __HAL_I2C_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR1 = ~((__FLAG__) & I2C_FLAG_MASK))
+
+/** @brief Clears the I2C ADDR pending flag.
+ * @param __HANDLE__: specifies the I2C Handle.
+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
+ * @retval None
+ */
+#define __HAL_I2C_CLEAR_ADDRFLAG(__HANDLE__) \
+ do{ \
+ __IO uint32_t tmpreg = 0x00U; \
+ tmpreg = (__HANDLE__)->Instance->SR1; \
+ tmpreg = (__HANDLE__)->Instance->SR2; \
+ UNUSED(tmpreg); \
+ } while(0U)
+
+/** @brief Clears the I2C STOPF pending flag.
+ * @param __HANDLE__: specifies the I2C Handle.
+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
+ * @retval None
+ */
+#define __HAL_I2C_CLEAR_STOPFLAG(__HANDLE__) \
+ do{ \
+ __IO uint32_t tmpreg = 0x00U; \
+ tmpreg = (__HANDLE__)->Instance->SR1; \
+ (__HANDLE__)->Instance->CR1 |= I2C_CR1_PE; \
+ UNUSED(tmpreg); \
+ } while(0U)
+
+/** @brief Enable the I2C peripheral.
+ * @param __HANDLE__: specifies the I2C Handle.
+ * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral.
+ * @retval None
+ */
+#define __HAL_I2C_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= I2C_CR1_PE)
+
+/** @brief Disable the I2C peripheral.
+ * @param __HANDLE__: specifies the I2C Handle.
+ * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral.
+ * @retval None
+ */
+#define __HAL_I2C_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~I2C_CR1_PE)
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup I2C_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup I2C_Exported_Functions_Group1
+ * @{
+ */
+/* Initialization/de-initialization functions **********************************/
+HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c);
+HAL_StatusTypeDef HAL_I2C_DeInit (I2C_HandleTypeDef *hi2c);
+void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c);
+/**
+ * @}
+ */
+
+/** @addtogroup I2C_Exported_Functions_Group2
+ * @{
+ */
+/* I/O operation functions *****************************************************/
+/******* Blocking mode: Polling */
+HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout);
+
+/******* Non-Blocking mode: Interrupt */
+HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
+
+HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress);
+HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c);
+HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c);
+
+/******* Non-Blocking mode: DMA */
+HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
+
+/******* I2C IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */
+void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode);
+void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c);
+/**
+ * @}
+ */
+
+/** @addtogroup I2C_Exported_Functions_Group3
+ * @{
+ */
+/* Peripheral State, Mode and Errors functions *********************************/
+HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c);
+HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c);
+uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup I2C_Private_Constants I2C Private Constants
+ * @{
+ */
+#define I2C_FLAG_MASK 0x0000FFFFU
+#define I2C_MIN_PCLK_FREQ_STANDARD 2000000U /*!< 2 MHz */
+#define I2C_MIN_PCLK_FREQ_FAST 4000000U /*!< 4 MHz */
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup I2C_Private_Macros I2C Private Macros
+ * @{
+ */
+
+#define I2C_MIN_PCLK_FREQ(__PCLK__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__PCLK__) < I2C_MIN_PCLK_FREQ_STANDARD) : ((__PCLK__) < I2C_MIN_PCLK_FREQ_FAST))
+#define I2C_CCR_CALCULATION(__PCLK__, __SPEED__, __COEFF__) (((((__PCLK__) - 1U)/((__SPEED__) * (__COEFF__))) + 1U) & I2C_CCR_CCR)
+#define I2C_FREQRANGE(__PCLK__) ((__PCLK__)/1000000U)
+#define I2C_RISE_TIME(__FREQRANGE__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__FREQRANGE__) + 1U) : ((((__FREQRANGE__) * 300U) / 1000U) + 1U))
+#define I2C_SPEED_STANDARD(__PCLK__, __SPEED__) ((I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 2U) < 4U)? 4U:I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 2U))
+#define I2C_SPEED_FAST(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__DUTYCYCLE__) == I2C_DUTYCYCLE_2)? I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 3U) : (I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 25U) | I2C_DUTYCYCLE_16_9))
+#define I2C_SPEED(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__SPEED__) <= 100000U)? (I2C_SPEED_STANDARD((__PCLK__), (__SPEED__))) : \
+ ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__)) & I2C_CCR_CCR) == 0U)? 1U : \
+ ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__))) | I2C_CCR_FS))
+
+#define I2C_7BIT_ADD_WRITE(__ADDRESS__) ((uint8_t)((__ADDRESS__) & (~I2C_OAR1_ADD0)))
+#define I2C_7BIT_ADD_READ(__ADDRESS__) ((uint8_t)((__ADDRESS__) | I2C_OAR1_ADD0))
+
+#define I2C_10BIT_ADDRESS(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FFU))))
+#define I2C_10BIT_HEADER_WRITE(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0x0300U))) >> 7U) | (uint16_t)(0x00F0U))))
+#define I2C_10BIT_HEADER_READ(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0x0300U))) >> 7U) | (uint16_t)(0x00F1U))))
+
+#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0xFF00U))) >> 8U)))
+#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FFU))))
+
+/** @defgroup I2C_IS_RTC_Definitions I2C Private macros to check input parameters
+ * @{
+ */
+#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DUTYCYCLE_2) || \
+ ((CYCLE) == I2C_DUTYCYCLE_16_9))
+#define IS_I2C_ADDRESSING_MODE(ADDRESS) (((ADDRESS) == I2C_ADDRESSINGMODE_7BIT) || \
+ ((ADDRESS) == I2C_ADDRESSINGMODE_10BIT))
+#define IS_I2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == I2C_DUALADDRESS_DISABLE) || \
+ ((ADDRESS) == I2C_DUALADDRESS_ENABLE))
+#define IS_I2C_GENERAL_CALL(CALL) (((CALL) == I2C_GENERALCALL_DISABLE) || \
+ ((CALL) == I2C_GENERALCALL_ENABLE))
+#define IS_I2C_NO_STRETCH(STRETCH) (((STRETCH) == I2C_NOSTRETCH_DISABLE) || \
+ ((STRETCH) == I2C_NOSTRETCH_ENABLE))
+#define IS_I2C_MEMADD_SIZE(SIZE) (((SIZE) == I2C_MEMADD_SIZE_8BIT) || \
+ ((SIZE) == I2C_MEMADD_SIZE_16BIT))
+#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) > 0) && ((SPEED) <= 400000U))
+#define IS_I2C_OWN_ADDRESS1(ADDRESS1) (((ADDRESS1) & (uint32_t)(0xFFFFFC00U)) == 0U)
+#define IS_I2C_OWN_ADDRESS2(ADDRESS2) (((ADDRESS2) & (uint32_t)(0xFFFFFF01U)) == 0U)
+#define IS_I2C_TRANSFER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_FIRST_FRAME) || \
+ ((REQUEST) == I2C_NEXT_FRAME) || \
+ ((REQUEST) == I2C_FIRST_AND_LAST_FRAME) || \
+ ((REQUEST) == I2C_LAST_FRAME))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup I2C_Private_Functions I2C Private Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __STM32F1xx_HAL_I2C_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2s.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2s.h
new file mode 100644
index 0000000..787d4ca
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2s.h
@@ -0,0 +1,491 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_i2s.h
+ * @author MCD Application Team
+ * @brief Header file of I2S HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_I2S_H
+#define __STM32F1xx_HAL_I2S_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#if defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup I2S
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup I2S_Exported_Types I2S Exported Types
+ * @{
+ */
+
+/**
+ * @brief I2S Init structure definition
+ */
+typedef struct
+{
+ uint32_t Mode; /*!< Specifies the I2S operating mode.
+ This parameter can be a value of @ref I2S_Mode */
+
+ uint32_t Standard; /*!< Specifies the standard used for the I2S communication.
+ This parameter can be a value of @ref I2S_Standard */
+
+ uint32_t DataFormat; /*!< Specifies the data format for the I2S communication.
+ This parameter can be a value of @ref I2S_Data_Format */
+
+ uint32_t MCLKOutput; /*!< Specifies whether the I2S MCLK output is enabled or not.
+ This parameter can be a value of @ref I2S_MCLK_Output */
+
+ uint32_t AudioFreq; /*!< Specifies the frequency selected for the I2S communication.
+ This parameter can be a value of @ref I2S_Audio_Frequency */
+
+ uint32_t CPOL; /*!< Specifies the idle state of the I2S clock.
+ This parameter can be a value of @ref I2S_Clock_Polarity */
+}I2S_InitTypeDef;
+
+/**
+ * @brief HAL State structures definition
+ */
+typedef enum
+{
+ HAL_I2S_STATE_RESET = 0x00U, /*!< I2S not yet initialized or disabled */
+ HAL_I2S_STATE_READY = 0x01U, /*!< I2S initialized and ready for use */
+ HAL_I2S_STATE_BUSY = 0x02U, /*!< I2S internal process is ongoing */
+ HAL_I2S_STATE_BUSY_TX = 0x03U, /*!< Data Transmission process is ongoing */
+ HAL_I2S_STATE_BUSY_RX = 0x04U, /*!< Data Reception process is ongoing */
+ HAL_I2S_STATE_BUSY_TX_RX = 0x05U, /*!< Data Transmission and Reception process is ongoing */
+ HAL_I2S_STATE_TIMEOUT = 0x06U, /*!< I2S timeout state */
+ HAL_I2S_STATE_ERROR = 0x07U /*!< I2S error state */
+
+}HAL_I2S_StateTypeDef;
+
+/**
+ * @brief I2S handle Structure definition
+ */
+typedef struct __I2S_HandleTypeDef
+{
+ SPI_TypeDef *Instance; /*!< I2S registers base address */
+
+ I2S_InitTypeDef Init; /*!< I2S communication parameters */
+
+ uint16_t *pTxBuffPtr; /*!< Pointer to I2S Tx transfer buffer */
+
+ __IO uint16_t TxXferSize; /*!< I2S Tx transfer size */
+
+ __IO uint16_t TxXferCount; /*!< I2S Tx transfer Counter */
+
+ uint16_t *pRxBuffPtr; /*!< Pointer to I2S Rx transfer buffer */
+
+ __IO uint16_t RxXferSize; /*!< I2S Rx transfer size */
+
+ __IO uint16_t RxXferCount; /*!< I2S Rx transfer counter
+ (This field is initialized at the
+ same value as transfer size at the
+ beginning of the transfer and
+ decremented when a sample is received
+ NbSamplesReceived = RxBufferSize-RxBufferCount) */
+
+ void (*IrqHandlerISR) (struct __I2S_HandleTypeDef *hi2s); /*!< I2S function pointer on IrqHandler */
+
+ DMA_HandleTypeDef *hdmatx; /*!< I2S Tx DMA handle parameters */
+
+ DMA_HandleTypeDef *hdmarx; /*!< I2S Rx DMA handle parameters */
+
+ __IO HAL_LockTypeDef Lock; /*!< I2S locking object */
+
+ __IO HAL_I2S_StateTypeDef State; /*!< I2S communication state */
+
+ __IO uint32_t ErrorCode; /*!< I2S Error code
+ This parameter can be a value of @ref I2S_ErrorCode */
+
+}I2S_HandleTypeDef;
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup I2S_Exported_Constants I2S Exported Constants
+ * @{
+ */
+/**
+ * @defgroup I2S_ErrorCode I2S Error Code
+ * @{
+ */
+#define HAL_I2S_ERROR_NONE 0x00000000U /*!< No error */
+#define HAL_I2S_ERROR_TIMEOUT 0x00000001U /*!< Timeout error */
+#define HAL_I2S_ERROR_OVR 0x00000002U /*!< OVR error */
+#define HAL_I2S_ERROR_UDR 0x00000004U /*!< UDR error */
+#define HAL_I2S_ERROR_DMA 0x00000008U /*!< DMA transfer error */
+#define HAL_I2S_ERROR_PRESCALER 0x00000010U /*!< Prescaler Calculation error */
+/**
+ * @}
+ */
+
+/** @defgroup I2S_Mode I2S Mode
+ * @{
+ */
+#define I2S_MODE_SLAVE_TX 0x00000000U
+#define I2S_MODE_SLAVE_RX ((uint32_t)SPI_I2SCFGR_I2SCFG_0)
+#define I2S_MODE_MASTER_TX ((uint32_t)SPI_I2SCFGR_I2SCFG_1)
+#define I2S_MODE_MASTER_RX ((uint32_t)(SPI_I2SCFGR_I2SCFG_0 | SPI_I2SCFGR_I2SCFG_1))
+/**
+ * @}
+ */
+
+/** @defgroup I2S_Standard I2S Standard
+ * @{
+ */
+#define I2S_STANDARD_PHILIPS 0x00000000U
+#define I2S_STANDARD_MSB ((uint32_t)SPI_I2SCFGR_I2SSTD_0)
+#define I2S_STANDARD_LSB ((uint32_t)SPI_I2SCFGR_I2SSTD_1)
+#define I2S_STANDARD_PCM_SHORT ((uint32_t)(SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1))
+#define I2S_STANDARD_PCM_LONG ((uint32_t)(SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1 | SPI_I2SCFGR_PCMSYNC))
+/**
+ * @}
+ */
+
+/** @defgroup I2S_Data_Format I2S Data Format
+ * @{
+ */
+#define I2S_DATAFORMAT_16B 0x00000000U
+#define I2S_DATAFORMAT_16B_EXTENDED ((uint32_t)SPI_I2SCFGR_CHLEN)
+#define I2S_DATAFORMAT_24B ((uint32_t)(SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN_0))
+#define I2S_DATAFORMAT_32B ((uint32_t)(SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN_1))
+/**
+ * @}
+ */
+
+/** @defgroup I2S_MCLK_Output I2S Mclk Output
+ * @{
+ */
+#define I2S_MCLKOUTPUT_ENABLE ((uint32_t)SPI_I2SPR_MCKOE)
+#define I2S_MCLKOUTPUT_DISABLE 0x00000000U
+/**
+ * @}
+ */
+
+/** @defgroup I2S_Audio_Frequency I2S Audio Frequency
+ * @{
+ */
+#define I2S_AUDIOFREQ_192K 192000U
+#define I2S_AUDIOFREQ_96K 96000U
+#define I2S_AUDIOFREQ_48K 48000U
+#define I2S_AUDIOFREQ_44K 44100U
+#define I2S_AUDIOFREQ_32K 32000U
+#define I2S_AUDIOFREQ_22K 22050U
+#define I2S_AUDIOFREQ_16K 16000U
+#define I2S_AUDIOFREQ_11K 11025U
+#define I2S_AUDIOFREQ_8K 8000U
+#define I2S_AUDIOFREQ_DEFAULT 2U
+/**
+ * @}
+ */
+
+/** @defgroup I2S_Clock_Polarity I2S Clock Polarity
+ * @{
+ */
+#define I2S_CPOL_LOW 0x00000000U
+#define I2S_CPOL_HIGH ((uint32_t)SPI_I2SCFGR_CKPOL)
+/**
+ * @}
+ */
+
+/** @defgroup I2S_Interrupts_Definition I2S Interrupts Definition
+ * @{
+ */
+#define I2S_IT_TXE SPI_CR2_TXEIE
+#define I2S_IT_RXNE SPI_CR2_RXNEIE
+#define I2S_IT_ERR SPI_CR2_ERRIE
+/**
+ * @}
+ */
+
+/** @defgroup I2S_Flags_Definition I2S Flags Definition
+ * @{
+ */
+#define I2S_FLAG_TXE SPI_SR_TXE
+#define I2S_FLAG_RXNE SPI_SR_RXNE
+
+#define I2S_FLAG_UDR SPI_SR_UDR
+#define I2S_FLAG_OVR SPI_SR_OVR
+#define I2S_FLAG_FRE SPI_SR_FRE
+
+#define I2S_FLAG_CHSIDE SPI_SR_CHSIDE
+#define I2S_FLAG_BSY SPI_SR_BSY
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup I2S_Exported_Macros I2S Exported Macros
+ * @{
+ */
+
+/** @brief Reset I2S handle state
+ * @param __HANDLE__: specifies the I2S Handle.
+ * @retval None
+ */
+#define __HAL_I2S_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2S_STATE_RESET)
+
+/** @brief Enable the specified SPI peripheral (in I2S mode).
+ * @param __HANDLE__: specifies the I2S Handle.
+ * @retval None
+ */
+#define __HAL_I2S_ENABLE(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
+
+/** @brief Disable the specified SPI peripheral (in I2S mode).
+ * @param __HANDLE__: specifies the I2S Handle.
+ * @retval None
+ */
+#define __HAL_I2S_DISABLE(__HANDLE__) (CLEAR_BIT((__HANDLE__)->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
+
+/** @brief Enable the specified I2S interrupts.
+ * @param __HANDLE__: specifies the I2S Handle.
+ * @param __INTERRUPT__: specifies the interrupt source to enable or disable.
+ * This parameter can be one of the following values:
+ * @arg I2S_IT_TXE: Tx buffer empty interrupt enable
+ * @arg I2S_IT_RXNE: RX buffer not empty interrupt enable
+ * @arg I2S_IT_ERR: Error interrupt enable
+ * @retval None
+ */
+#define __HAL_I2S_ENABLE_IT(__HANDLE__, __INTERRUPT__) (SET_BIT((__HANDLE__)->Instance->CR2,(__INTERRUPT__)))
+
+/** @brief Disable the specified I2S interrupts.
+ * @param __HANDLE__: specifies the I2S Handle.
+ * @param __INTERRUPT__: specifies the interrupt source to enable or disable.
+ * This parameter can be one of the following values:
+ * @arg I2S_IT_TXE: Tx buffer empty interrupt enable
+ * @arg I2S_IT_RXNE: RX buffer not empty interrupt enable
+ * @arg I2S_IT_ERR: Error interrupt enable
+ * @retval None
+ */
+#define __HAL_I2S_DISABLE_IT(__HANDLE__, __INTERRUPT__) (CLEAR_BIT((__HANDLE__)->Instance->CR2,(__INTERRUPT__)))
+
+/** @brief Checks if the specified I2S interrupt source is enabled or disabled.
+ * @param __HANDLE__: specifies the I2S Handle.
+ * This parameter can be I2S where x: 1, 2, or 3 to select the I2S peripheral.
+ * @param __INTERRUPT__: specifies the I2S interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg I2S_IT_TXE: Tx buffer empty interrupt enable
+ * @arg I2S_IT_RXNE: RX buffer not empty interrupt enable
+ * @arg I2S_IT_ERR: Error interrupt enable
+ * @retval The new state of __IT__ (TRUE or FALSE).
+ */
+#define __HAL_I2S_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
+
+/** @brief Checks whether the specified I2S flag is set or not.
+ * @param __HANDLE__: specifies the I2S Handle.
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg I2S_FLAG_RXNE: Receive buffer not empty flag
+ * @arg I2S_FLAG_TXE: Transmit buffer empty flag
+ * @arg I2S_FLAG_UDR: Underrun flag
+ * @arg I2S_FLAG_OVR: Overrun flag
+ * @arg I2S_FLAG_FRE: Frame error flag
+ * @arg I2S_FLAG_CHSIDE: Channel Side flag
+ * @arg I2S_FLAG_BSY: Busy flag
+ * @retval The new state of __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_I2S_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__))
+
+/** @brief Clears the I2S OVR pending flag.
+ * @param __HANDLE__: specifies the I2S Handle.
+ * @retval None
+ */
+#define __HAL_I2S_CLEAR_OVRFLAG(__HANDLE__) \
+ do{ \
+ __IO uint32_t tmpreg = 0x00U; \
+ tmpreg = (__HANDLE__)->Instance->DR; \
+ tmpreg = (__HANDLE__)->Instance->SR; \
+ UNUSED(tmpreg); \
+ } while(0U)
+
+/** @brief Clears the I2S UDR pending flag.
+ * @param __HANDLE__: specifies the I2S Handle.
+ * @retval None
+ */
+#define __HAL_I2S_CLEAR_UDRFLAG(__HANDLE__) \
+ do{ \
+ __IO uint32_t tmpreg = 0x00U; \
+ tmpreg = (__HANDLE__)->Instance->SR; \
+ UNUSED(tmpreg); \
+ } while(0U)
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup I2S_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup I2S_Exported_Functions_Group1
+ * @{
+ */
+/* Initialization/de-initialization functions ********************************/
+HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s);
+HAL_StatusTypeDef HAL_I2S_DeInit (I2S_HandleTypeDef *hi2s);
+void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s);
+void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s);
+/**
+ * @}
+ */
+
+/** @addtogroup I2S_Exported_Functions_Group2
+ * @{
+ */
+/* I/O operation functions ***************************************************/
+/* Blocking mode: Polling */
+HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout);
+
+ /* Non-Blocking mode: Interrupt */
+HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size);
+void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s);
+
+/* Non-Blocking mode: DMA */
+HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size);
+
+HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s);
+HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s);
+HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s);
+
+/* Callbacks used in non blocking modes (Interrupt and DMA) *******************/
+void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s);
+void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s);
+void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s);
+void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s);
+void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s);
+/**
+ * @}
+ */
+
+/** @addtogroup I2S_Exported_Functions_Group3
+ * @{
+ */
+/* Peripheral Control and State functions ************************************/
+HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s);
+uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup I2S_Private_Constants I2S Private Constants
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup I2S_Private_Macros I2S Private Macros
+ * @{
+ */
+#define IS_I2S_MODE(MODE) (((MODE) == I2S_MODE_SLAVE_TX) || \
+ ((MODE) == I2S_MODE_SLAVE_RX) || \
+ ((MODE) == I2S_MODE_MASTER_TX) || \
+ ((MODE) == I2S_MODE_MASTER_RX))
+
+#define IS_I2S_STANDARD(STANDARD) (((STANDARD) == I2S_STANDARD_PHILIPS) || \
+ ((STANDARD) == I2S_STANDARD_MSB) || \
+ ((STANDARD) == I2S_STANDARD_LSB) || \
+ ((STANDARD) == I2S_STANDARD_PCM_SHORT) || \
+ ((STANDARD) == I2S_STANDARD_PCM_LONG))
+
+#define IS_I2S_DATA_FORMAT(FORMAT) (((FORMAT) == I2S_DATAFORMAT_16B) || \
+ ((FORMAT) == I2S_DATAFORMAT_16B_EXTENDED) || \
+ ((FORMAT) == I2S_DATAFORMAT_24B) || \
+ ((FORMAT) == I2S_DATAFORMAT_32B))
+
+#define IS_I2S_MCLK_OUTPUT(OUTPUT) (((OUTPUT) == I2S_MCLKOUTPUT_ENABLE) || \
+ ((OUTPUT) == I2S_MCLKOUTPUT_DISABLE))
+
+#define IS_I2S_AUDIO_FREQ(FREQ) ((((FREQ) >= I2S_AUDIOFREQ_8K) && \
+ ((FREQ) <= I2S_AUDIOFREQ_192K)) || \
+ ((FREQ) == I2S_AUDIOFREQ_DEFAULT))
+
+#define IS_I2S_CPOL(CPOL) (((CPOL) == I2S_CPOL_LOW) || \
+ ((CPOL) == I2S_CPOL_HIGH))
+/**
+ * @}
+ */
+
+/* Private Fonctions ---------------------------------------------------------*/
+/** @defgroup I2S_Private_Functions I2S Private Functions
+ * @{
+ */
+/* Private functions are defined in stm32f1xx_hal_i2s.c file */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_I2S_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_irda.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_irda.h
new file mode 100644
index 0000000..7c64c1e
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_irda.h
@@ -0,0 +1,597 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_irda.h
+ * @author MCD Application Team
+ * @brief Header file of IRDA HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_IRDA_H
+#define __STM32F1xx_HAL_IRDA_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup IRDA
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup IRDA_Exported_Types IRDA Exported Types
+ * @{
+ */
+
+/**
+ * @brief IRDA Init Structure definition
+ */
+typedef struct
+{
+ uint32_t BaudRate; /*!< This member configures the IRDA communication baud rate.
+ The baud rate is computed using the following formula:
+ - IntegerDivider = ((PCLKx) / (16 * (hirda->Init.BaudRate)))
+ - FractionalDivider = ((IntegerDivider - ((uint32_t) IntegerDivider)) * 16) + 0.5 */
+
+ uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame.
+ This parameter can be a value of @ref IRDA_Word_Length */
+
+
+ uint32_t Parity; /*!< Specifies the parity mode.
+ This parameter can be a value of @ref IRDA_Parity
+ @note When parity is enabled, the computed parity is inserted
+ at the MSB position of the transmitted data (9th bit when
+ the word length is set to 9 data bits; 8th bit when the
+ word length is set to 8 data bits). */
+
+ uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.
+ This parameter can be a value of @ref IRDA_Transfer_Mode */
+
+ uint8_t Prescaler; /*!< Specifies the Prescaler value prescaler value to be programmed
+ in the IrDA low-power Baud Register, for defining pulse width on which
+ burst acceptance/rejection will be decided. This value is used as divisor
+ of system clock to achieve required pulse width. */
+
+ uint32_t IrDAMode; /*!< Specifies the IrDA mode
+ This parameter can be a value of @ref IRDA_Low_Power */
+}IRDA_InitTypeDef;
+
+/**
+ * @brief HAL IRDA State structures definition
+ * @note HAL IRDA State value is a combination of 2 different substates: gState and RxState.
+ * - gState contains IRDA state information related to global Handle management
+ * and also information related to Tx operations.
+ * gState value coding follow below described bitmap :
+ * b7-b6 Error information
+ * 00 : No Error
+ * 01 : (Not Used)
+ * 10 : Timeout
+ * 11 : Error
+ * b5 IP initilisation status
+ * 0 : Reset (IP not initialized)
+ * 1 : Init done (IP not initialized. HAL IRDA Init function already called)
+ * b4-b3 (not used)
+ * xx : Should be set to 00
+ * b2 Intrinsic process state
+ * 0 : Ready
+ * 1 : Busy (IP busy with some configuration or internal operations)
+ * b1 (not used)
+ * x : Should be set to 0
+ * b0 Tx state
+ * 0 : Ready (no Tx operation ongoing)
+ * 1 : Busy (Tx operation ongoing)
+ * - RxState contains information related to Rx operations.
+ * RxState value coding follow below described bitmap :
+ * b7-b6 (not used)
+ * xx : Should be set to 00
+ * b5 IP initilisation status
+ * 0 : Reset (IP not initialized)
+ * 1 : Init done (IP not initialized)
+ * b4-b2 (not used)
+ * xxx : Should be set to 000
+ * b1 Rx state
+ * 0 : Ready (no Rx operation ongoing)
+ * 1 : Busy (Rx operation ongoing)
+ * b0 (not used)
+ * x : Should be set to 0.
+ */
+typedef enum
+{
+ HAL_IRDA_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized
+ Value is allowed for gState and RxState */
+ HAL_IRDA_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use
+ Value is allowed for gState and RxState */
+ HAL_IRDA_STATE_BUSY = 0x24U, /*!< An internal process is ongoing
+ Value is allowed for gState only */
+ HAL_IRDA_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing
+ Value is allowed for gState only */
+ HAL_IRDA_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing
+ Value is allowed for RxState only */
+ HAL_IRDA_STATE_BUSY_TX_RX = 0x23U, /*!< Data Transmission and Reception process is ongoing
+ Not to be used for neither gState nor RxState.
+ Value is result of combination (Or) between gState and RxState values */
+ HAL_IRDA_STATE_TIMEOUT = 0xA0U, /*!< Timeout state
+ Value is allowed for gState only */
+ HAL_IRDA_STATE_ERROR = 0xE0U /*!< Error
+ Value is allowed for gState only */
+}HAL_IRDA_StateTypeDef;
+
+/**
+ * @brief IRDA handle Structure definition
+ */
+typedef struct
+{
+ USART_TypeDef *Instance; /*!< USART registers base address */
+
+ IRDA_InitTypeDef Init; /*!< IRDA communication parameters */
+
+ uint8_t *pTxBuffPtr; /*!< Pointer to IRDA Tx transfer Buffer */
+
+ uint16_t TxXferSize; /*!< IRDA Tx Transfer size */
+
+ __IO uint16_t TxXferCount; /*!< IRDA Tx Transfer Counter */
+
+ uint8_t *pRxBuffPtr; /*!< Pointer to IRDA Rx transfer Buffer */
+
+ uint16_t RxXferSize; /*!< IRDA Rx Transfer size */
+
+ __IO uint16_t RxXferCount; /*!< IRDA Rx Transfer Counter */
+
+ DMA_HandleTypeDef *hdmatx; /*!< IRDA Tx DMA Handle parameters */
+
+ DMA_HandleTypeDef *hdmarx; /*!< IRDA Rx DMA Handle parameters */
+
+ HAL_LockTypeDef Lock; /*!< Locking object */
+
+ __IO HAL_IRDA_StateTypeDef gState; /*!< IRDA state information related to global Handle management
+ and also related to Tx operations.
+ This parameter can be a value of @ref HAL_IRDA_StateTypeDef */
+
+ __IO HAL_IRDA_StateTypeDef RxState; /*!< IRDA state information related to Rx operations.
+ This parameter can be a value of @ref HAL_IRDA_StateTypeDef */
+
+ __IO uint32_t ErrorCode; /*!< IRDA Error code */
+}IRDA_HandleTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup IRDA_Exported_Constants IRDA Exported constants
+ * @{
+ */
+/** @defgroup IRDA_Error_Code IRDA Error Code
+ * @{
+ */
+#define HAL_IRDA_ERROR_NONE 0x00000000U /*!< No error */
+#define HAL_IRDA_ERROR_PE 0x00000001U /*!< Parity error */
+#define HAL_IRDA_ERROR_NE 0x00000002U /*!< Noise error */
+#define HAL_IRDA_ERROR_FE 0x00000004U /*!< Frame error */
+#define HAL_IRDA_ERROR_ORE 0x00000008U /*!< Overrun error */
+#define HAL_IRDA_ERROR_DMA 0x00000010U /*!< DMA transfer error */
+/**
+ * @}
+ */
+
+/** @defgroup IRDA_Word_Length IRDA Word Length
+ * @{
+ */
+#define IRDA_WORDLENGTH_8B 0x00000000U
+#define IRDA_WORDLENGTH_9B ((uint32_t)USART_CR1_M)
+/**
+ * @}
+ */
+
+/** @defgroup IRDA_Parity IRDA Parity
+ * @{
+ */
+#define IRDA_PARITY_NONE 0x00000000U
+#define IRDA_PARITY_EVEN ((uint32_t)USART_CR1_PCE)
+#define IRDA_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS))
+/**
+ * @}
+ */
+
+/** @defgroup IRDA_Transfer_Mode IRDA Transfer Mode
+ * @{
+ */
+#define IRDA_MODE_RX ((uint32_t)USART_CR1_RE)
+#define IRDA_MODE_TX ((uint32_t)USART_CR1_TE)
+#define IRDA_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE))
+/**
+ * @}
+ */
+
+/** @defgroup IRDA_Low_Power IRDA Low Power
+ * @{
+ */
+#define IRDA_POWERMODE_LOWPOWER ((uint32_t)USART_CR3_IRLP)
+#define IRDA_POWERMODE_NORMAL 0x00000000U
+/**
+ * @}
+ */
+
+/** @defgroup IRDA_Flags IRDA Flags
+ * Elements values convention: 0xXXXX
+ * - 0xXXXX : Flag mask in the SR register
+ * @{
+ */
+#define IRDA_FLAG_TXE ((uint32_t)USART_SR_TXE)
+#define IRDA_FLAG_TC ((uint32_t)USART_SR_TC)
+#define IRDA_FLAG_RXNE ((uint32_t)USART_SR_RXNE)
+#define IRDA_FLAG_IDLE ((uint32_t)USART_SR_IDLE)
+#define IRDA_FLAG_ORE ((uint32_t)USART_SR_ORE)
+#define IRDA_FLAG_NE ((uint32_t)USART_SR_NE)
+#define IRDA_FLAG_FE ((uint32_t)USART_SR_FE)
+#define IRDA_FLAG_PE ((uint32_t)USART_SR_PE)
+/**
+ * @}
+ */
+
+/** @defgroup IRDA_Interrupt_definition IRDA Interrupt Definitions
+ * Elements values convention: 0xY000XXXX
+ * - XXXX : Interrupt mask in the XX register
+ * - Y : Interrupt source register (2bits)
+ * - 01: CR1 register
+ * - 10: CR2 register
+ * - 11: CR3 register
+ * @{
+ */
+#define IRDA_IT_PE ((uint32_t)(IRDA_CR1_REG_INDEX << 28U | USART_CR1_PEIE))
+#define IRDA_IT_TXE ((uint32_t)(IRDA_CR1_REG_INDEX << 28U | USART_CR1_TXEIE))
+#define IRDA_IT_TC ((uint32_t)(IRDA_CR1_REG_INDEX << 28U | USART_CR1_TCIE))
+#define IRDA_IT_RXNE ((uint32_t)(IRDA_CR1_REG_INDEX << 28U | USART_CR1_RXNEIE))
+#define IRDA_IT_IDLE ((uint32_t)(IRDA_CR1_REG_INDEX << 28U | USART_CR1_IDLEIE))
+
+#define IRDA_IT_LBD ((uint32_t)(IRDA_CR2_REG_INDEX << 28U | USART_CR2_LBDIE))
+
+#define IRDA_IT_CTS ((uint32_t)(IRDA_CR3_REG_INDEX << 28U | USART_CR3_CTSIE))
+#define IRDA_IT_ERR ((uint32_t)(IRDA_CR3_REG_INDEX << 28U | USART_CR3_EIE))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup IRDA_Exported_Macros IRDA Exported Macros
+ * @{
+ */
+
+/** @brief Reset IRDA handle gstate & RxState
+ * @param __HANDLE__: specifies the IRDA Handle.
+ * IRDA Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ */
+#define __HAL_IRDA_RESET_HANDLE_STATE(__HANDLE__) do{ \
+ (__HANDLE__)->gState = HAL_IRDA_STATE_RESET; \
+ (__HANDLE__)->RxState = HAL_IRDA_STATE_RESET; \
+ } while(0U)
+
+/** @brief Flush the IRDA DR register
+ * @param __HANDLE__: specifies the USART Handle.
+ * IRDA Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ */
+#define __HAL_IRDA_FLUSH_DRREGISTER(__HANDLE__) ((__HANDLE__)->Instance->DR)
+
+/** @brief Check whether the specified IRDA flag is set or not.
+ * @param __HANDLE__: specifies the IRDA Handle.
+ * IRDA Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg IRDA_FLAG_TXE: Transmit data register empty flag
+ * @arg IRDA_FLAG_TC: Transmission Complete flag
+ * @arg IRDA_FLAG_RXNE: Receive data register not empty flag
+ * @arg IRDA_FLAG_IDLE: Idle Line detection flag
+ * @arg IRDA_FLAG_ORE: OverRun Error flag
+ * @arg IRDA_FLAG_NE: Noise Error flag
+ * @arg IRDA_FLAG_FE: Framing Error flag
+ * @arg IRDA_FLAG_PE: Parity Error flag
+ * @retval The new state of __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_IRDA_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__))
+
+/** @brief Clear the specified IRDA pending flag.
+ * @param __HANDLE__: specifies the IRDA Handle.
+ * IRDA Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be any combination of the following values:
+ * @arg IRDA_FLAG_TC: Transmission Complete flag.
+ * @arg IRDA_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 followed by a read
+ * operation to USART_DR register.
+ * @note RXNE flag can be also cleared by a read to the USART_DR register.
+ * @note TC flag can be also cleared by software sequence: a read operation to
+ * USART_SR register followed by a write operation to USART_DR register.
+ * @note TXE flag is cleared only by a write to the USART_DR register.
+ *
+ */
+#define __HAL_IRDA_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__))
+
+/** @brief Clear the IRDA PE pending flag.
+ * @param __HANDLE__: specifies the IRDA Handle.
+ * IRDA Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ */
+#define __HAL_IRDA_CLEAR_PEFLAG(__HANDLE__) \
+do{ \
+ __IO uint32_t tmpreg = 0x00U; \
+ tmpreg = (__HANDLE__)->Instance->SR; \
+ tmpreg = (__HANDLE__)->Instance->DR; \
+ UNUSED(tmpreg); \
+ } while(0U)
+
+/** @brief Clear the IRDA FE pending flag.
+ * @param __HANDLE__: specifies the IRDA Handle.
+ * IRDA Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ */
+#define __HAL_IRDA_CLEAR_FEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Clear the IRDA NE pending flag.
+ * @param __HANDLE__: specifies the IRDA Handle.
+ * IRDA Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ */
+#define __HAL_IRDA_CLEAR_NEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Clear the IRDA ORE pending flag.
+ * @param __HANDLE__: specifies the IRDA Handle.
+ * IRDA Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ */
+#define __HAL_IRDA_CLEAR_OREFLAG(__HANDLE__) __HAL_IRDA_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Clear the IRDA IDLE pending flag.
+ * @param __HANDLE__: specifies the IRDA Handle.
+ * IRDA Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ */
+#define __HAL_IRDA_CLEAR_IDLEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Enable the specified IRDA interrupt.
+ * @param __HANDLE__: specifies the IRDA Handle.
+ * IRDA Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __INTERRUPT__: specifies the IRDA interrupt source to enable.
+ * This parameter can be one of the following values:
+ * @arg IRDA_IT_TXE: Transmit Data Register empty interrupt
+ * @arg IRDA_IT_TC: Transmission complete interrupt
+ * @arg IRDA_IT_RXNE: Receive Data register not empty interrupt
+ * @arg IRDA_IT_IDLE: Idle line detection interrupt
+ * @arg IRDA_IT_PE: Parity Error interrupt
+ * @arg IRDA_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
+ */
+#define __HAL_IRDA_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == IRDA_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & IRDA_IT_MASK)): \
+ (((__INTERRUPT__) >> 28U) == IRDA_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 |= ((__INTERRUPT__) & IRDA_IT_MASK)): \
+ ((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & IRDA_IT_MASK)))
+/** @brief Disable the specified IRDA interrupt.
+ * @param __HANDLE__: specifies the IRDA Handle.
+ * IRDA Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __INTERRUPT__: specifies the IRDA interrupt source to disable.
+ * This parameter can be one of the following values:
+ * @arg IRDA_IT_TXE: Transmit Data Register empty interrupt
+ * @arg IRDA_IT_TC: Transmission complete interrupt
+ * @arg IRDA_IT_RXNE: Receive Data register not empty interrupt
+ * @arg IRDA_IT_IDLE: Idle line detection interrupt
+ * @arg IRDA_IT_PE: Parity Error interrupt
+ * @arg IRDA_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
+ */
+#define __HAL_IRDA_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == IRDA_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 &= ~((__INTERRUPT__) & IRDA_IT_MASK)): \
+ (((__INTERRUPT__) >> 28U) == IRDA_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 &= ~((__INTERRUPT__) & IRDA_IT_MASK)): \
+ ((__HANDLE__)->Instance->CR3 &= ~ ((__INTERRUPT__) & IRDA_IT_MASK)))
+
+/** @brief Check whether the specified IRDA interrupt has occurred or not.
+ * @param __HANDLE__: specifies the IRDA Handle.
+ * IRDA Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __IT__: specifies the IRDA interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg IRDA_IT_TXE: Transmit Data Register empty interrupt
+ * @arg IRDA_IT_TC: Transmission complete interrupt
+ * @arg IRDA_IT_RXNE: Receive Data register not empty interrupt
+ * @arg IRDA_IT_IDLE: Idle line detection interrupt
+ * @arg IRDA_IT_ERR: Error interrupt
+ * @arg IRDA_IT_PE: Parity Error interrupt
+ * @retval The new state of __IT__ (TRUE or FALSE).
+ */
+#define __HAL_IRDA_GET_IT_SOURCE(__HANDLE__, __IT__) (((((__IT__) >> 28U) == IRDA_CR1_REG_INDEX)? (__HANDLE__)->Instance->CR1:(((((uint32_t)(__IT__)) >> 28U) == IRDA_CR2_REG_INDEX)? \
+ (__HANDLE__)->Instance->CR2 : (__HANDLE__)->Instance->CR3)) & (((uint32_t)(__IT__)) & IRDA_IT_MASK))
+
+/** @brief Enable UART/USART associated to IRDA Handle
+ * @param __HANDLE__: specifies the IRDA Handle.
+ * IRDA Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ */
+#define __HAL_IRDA_ENABLE(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR1, USART_CR1_UE))
+
+/** @brief Disable UART/USART associated to IRDA Handle
+ * @param __HANDLE__: specifies the IRDA Handle.
+ * IRDA Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ */
+#define __HAL_IRDA_DISABLE(__HANDLE__) (CLEAR_BIT((__HANDLE__)->Instance->CR1, USART_CR1_UE))
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup IRDA_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup IRDA_Exported_Functions_Group1
+ * @{
+ */
+/* Initialization/de-initialization functions **********************************/
+HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda);
+HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda);
+void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda);
+void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda);
+/**
+ * @}
+ */
+
+/** @addtogroup IRDA_Exported_Functions_Group2
+ * @{
+ */
+/* IO operation functions *******************************************************/
+HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda);
+HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda);
+HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda);
+/* Transfer Abort functions */
+HAL_StatusTypeDef HAL_IRDA_Abort(IRDA_HandleTypeDef *hirda);
+HAL_StatusTypeDef HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef *hirda);
+HAL_StatusTypeDef HAL_IRDA_AbortReceive(IRDA_HandleTypeDef *hirda);
+HAL_StatusTypeDef HAL_IRDA_Abort_IT(IRDA_HandleTypeDef *hirda);
+HAL_StatusTypeDef HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef *hirda);
+HAL_StatusTypeDef HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef *hirda);
+
+void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda);
+void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda);
+void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda);
+void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda);
+void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda);
+void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda);
+void HAL_IRDA_AbortCpltCallback(IRDA_HandleTypeDef *hirda);
+void HAL_IRDA_AbortTransmitCpltCallback(IRDA_HandleTypeDef *hirda);
+void HAL_IRDA_AbortReceiveCpltCallback(IRDA_HandleTypeDef *hirda);
+/**
+ * @}
+ */
+
+/** @addtogroup IRDA_Exported_Functions_Group3
+ * @{
+ */
+/* Peripheral State functions **************************************************/
+HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda);
+uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup IRDA_Private_Constants IRDA Private Constants
+ * @{
+ */
+
+/** @brief IRDA interruptions flag mask
+ *
+ */
+#define IRDA_IT_MASK 0x0000FFFFU
+
+#define IRDA_CR1_REG_INDEX 1U
+#define IRDA_CR2_REG_INDEX 2U
+#define IRDA_CR3_REG_INDEX 3U
+/**
+ * @}
+ */
+
+/* Private macros --------------------------------------------------------*/
+/** @defgroup IRDA_Private_Macros IRDA Private Macros
+ * @{
+ */
+#define IS_IRDA_WORD_LENGTH(LENGTH) (((LENGTH) == IRDA_WORDLENGTH_8B) || \
+ ((LENGTH) == IRDA_WORDLENGTH_9B))
+#define IS_IRDA_PARITY(PARITY) (((PARITY) == IRDA_PARITY_NONE) || \
+ ((PARITY) == IRDA_PARITY_EVEN) || \
+ ((PARITY) == IRDA_PARITY_ODD))
+#define IS_IRDA_MODE(MODE) ((((MODE) & 0x0000FFF3U) == 0x00U) && ((MODE) != 0x00000000U))
+#define IS_IRDA_POWERMODE(MODE) (((MODE) == IRDA_POWERMODE_LOWPOWER) || \
+ ((MODE) == IRDA_POWERMODE_NORMAL))
+#define IS_IRDA_BAUDRATE(BAUDRATE) ((BAUDRATE) < 115201U)
+
+#define IRDA_DIV(_PCLK_, _BAUD_) (((_PCLK_)*25U)/(4U*(_BAUD_)))
+#define IRDA_DIVMANT(_PCLK_, _BAUD_) (IRDA_DIV((_PCLK_), (_BAUD_))/100U)
+#define IRDA_DIVFRAQ(_PCLK_, _BAUD_) (((IRDA_DIV((_PCLK_), (_BAUD_)) - (IRDA_DIVMANT((_PCLK_), (_BAUD_)) * 100U)) * 16U + 50U) / 100U)
+/* UART BRR = mantissa + overflow + fraction
+ = (UART DIVMANT << 4) + (UART DIVFRAQ & 0xF0) + (UART DIVFRAQ & 0x0FU) */
+#define IRDA_BRR(_PCLK_, _BAUD_) (((IRDA_DIVMANT((_PCLK_), (_BAUD_)) << 4U) + \
+ (IRDA_DIVFRAQ((_PCLK_), (_BAUD_)) & 0xF0U)) + \
+ (IRDA_DIVFRAQ((_PCLK_), (_BAUD_)) & 0x0FU))
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup IRDA_Private_Functions IRDA Private Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_IRDA_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_iwdg.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_iwdg.h
new file mode 100644
index 0000000..5a6f395
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_iwdg.h
@@ -0,0 +1,238 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_iwdg.h
+ * @author MCD Application Team
+ * @brief Header file of IWDG HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_IWDG_H
+#define __STM32F1xx_HAL_IWDG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup IWDG
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup IWDG_Exported_Types IWDG Exported Types
+ * @{
+ */
+
+/**
+ * @brief IWDG Init structure definition
+ */
+typedef struct
+{
+ uint32_t Prescaler; /*!< Select the prescaler of the IWDG.
+ This parameter can be a value of @ref IWDG_Prescaler */
+
+ uint32_t Reload; /*!< Specifies the IWDG down-counter reload value.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 0x0FFF */
+
+} IWDG_InitTypeDef;
+
+/**
+ * @brief IWDG Handle Structure definition
+ */
+typedef struct
+{
+ IWDG_TypeDef *Instance; /*!< Register base address */
+
+ IWDG_InitTypeDef Init; /*!< IWDG required parameters */
+
+} IWDG_HandleTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup IWDG_Exported_Constants IWDG Exported Constants
+ * @{
+ */
+
+/** @defgroup IWDG_Prescaler IWDG Prescaler
+ * @{
+ */
+#define IWDG_PRESCALER_4 0x00000000U /*!< IWDG prescaler set to 4 */
+#define IWDG_PRESCALER_8 IWDG_PR_PR_0 /*!< IWDG prescaler set to 8 */
+#define IWDG_PRESCALER_16 IWDG_PR_PR_1 /*!< IWDG prescaler set to 16 */
+#define IWDG_PRESCALER_32 (IWDG_PR_PR_1 | IWDG_PR_PR_0) /*!< IWDG prescaler set to 32 */
+#define IWDG_PRESCALER_64 IWDG_PR_PR_2 /*!< IWDG prescaler set to 64 */
+#define IWDG_PRESCALER_128 (IWDG_PR_PR_2 | IWDG_PR_PR_0) /*!< IWDG prescaler set to 128 */
+#define IWDG_PRESCALER_256 (IWDG_PR_PR_2 | IWDG_PR_PR_1) /*!< IWDG prescaler set to 256 */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/* Exported macros -----------------------------------------------------------*/
+/** @defgroup IWDG_Exported_Macros IWDG Exported Macros
+ * @{
+ */
+
+/**
+ * @brief Enable the IWDG peripheral.
+ * @param __HANDLE__ IWDG handle
+ * @retval None
+ */
+#define __HAL_IWDG_START(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_ENABLE)
+
+/**
+ * @brief Reload IWDG counter with value defined in the reload register
+ * (write access to IWDG_PR & IWDG_RLR registers disabled).
+ * @param __HANDLE__ IWDG handle
+ * @retval None
+ */
+#define __HAL_IWDG_RELOAD_COUNTER(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_RELOAD)
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup IWDG_Exported_Functions IWDG Exported Functions
+ * @{
+ */
+
+/** @defgroup IWDG_Exported_Functions_Group1 Initialization and Start functions
+ * @{
+ */
+/* Initialization/Start functions ********************************************/
+HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg);
+/**
+ * @}
+ */
+
+/** @defgroup IWDG_Exported_Functions_Group2 IO operation functions
+ * @{
+ */
+/* I/O operation functions ****************************************************/
+HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup IWDG_Private_Constants IWDG Private Constants
+ * @{
+ */
+
+/**
+ * @brief IWDG Key Register BitMask
+ */
+#define IWDG_KEY_RELOAD 0x0000AAAAU /*!< IWDG Reload Counter Enable */
+#define IWDG_KEY_ENABLE 0x0000CCCCU /*!< IWDG Peripheral Enable */
+#define IWDG_KEY_WRITE_ACCESS_ENABLE 0x00005555U /*!< IWDG KR Write Access Enable */
+#define IWDG_KEY_WRITE_ACCESS_DISABLE 0x00000000U /*!< IWDG KR Write Access Disable */
+
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup IWDG_Private_Macros IWDG Private Macros
+ * @{
+ */
+
+/**
+ * @brief Enable write access to IWDG_PR and IWDG_RLR registers.
+ * @param __HANDLE__ IWDG handle
+ * @retval None
+ */
+#define IWDG_ENABLE_WRITE_ACCESS(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_WRITE_ACCESS_ENABLE)
+
+/**
+ * @brief Disable write access to IWDG_PR and IWDG_RLR registers.
+ * @param __HANDLE__ IWDG handle
+ * @retval None
+ */
+#define IWDG_DISABLE_WRITE_ACCESS(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_WRITE_ACCESS_DISABLE)
+
+/**
+ * @brief Check IWDG prescaler value.
+ * @param __PRESCALER__ IWDG prescaler value
+ * @retval None
+ */
+#define IS_IWDG_PRESCALER(__PRESCALER__) (((__PRESCALER__) == IWDG_PRESCALER_4) || \
+ ((__PRESCALER__) == IWDG_PRESCALER_8) || \
+ ((__PRESCALER__) == IWDG_PRESCALER_16) || \
+ ((__PRESCALER__) == IWDG_PRESCALER_32) || \
+ ((__PRESCALER__) == IWDG_PRESCALER_64) || \
+ ((__PRESCALER__) == IWDG_PRESCALER_128)|| \
+ ((__PRESCALER__) == IWDG_PRESCALER_256))
+
+/**
+ * @brief Check IWDG reload value.
+ * @param __RELOAD__ IWDG reload value
+ * @retval None
+ */
+#define IS_IWDG_RELOAD(__RELOAD__) ((__RELOAD__) <= IWDG_RLR_RL)
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_IWDG_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_mmc.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_mmc.h
new file mode 100644
index 0000000..fe4b8b7
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_mmc.h
@@ -0,0 +1,716 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_mmc.h
+ * @author MCD Application Team
+ * @brief Header file of MMC HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_MMC_H
+#define __STM32F1xx_HAL_MMC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#if defined(STM32F103xE) || defined(STM32F103xG)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_sdmmc.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup MMC MMC
+ * @brief MMC HAL module driver
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup MMC_Exported_Types MMC Exported Types
+ * @{
+ */
+
+/** @defgroup MMC_Exported_Types_Group1 MMC State enumeration structure
+ * @{
+ */
+typedef enum
+{
+ HAL_MMC_STATE_RESET = 0x00000000U, /*!< MMC not yet initialized or disabled */
+ HAL_MMC_STATE_READY = 0x00000001U, /*!< MMC initialized and ready for use */
+ HAL_MMC_STATE_TIMEOUT = 0x00000002U, /*!< MMC Timeout state */
+ HAL_MMC_STATE_BUSY = 0x00000003U, /*!< MMC process ongoing */
+ HAL_MMC_STATE_PROGRAMMING = 0x00000004U, /*!< MMC Programming State */
+ HAL_MMC_STATE_RECEIVING = 0x00000005U, /*!< MMC Receinving State */
+ HAL_MMC_STATE_TRANSFER = 0x00000006U, /*!< MMC Transfert State */
+ HAL_MMC_STATE_ERROR = 0x0000000FU /*!< MMC is in error state */
+}HAL_MMC_StateTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup MMC_Exported_Types_Group2 MMC Card State enumeration structure
+ * @{
+ */
+typedef enum
+{
+ HAL_MMC_CARD_READY = 0x00000001U, /*!< Card state is ready */
+ HAL_MMC_CARD_IDENTIFICATION = 0x00000002U, /*!< Card is in identification state */
+ HAL_MMC_CARD_STANDBY = 0x00000003U, /*!< Card is in standby state */
+ HAL_MMC_CARD_TRANSFER = 0x00000004U, /*!< Card is in transfer state */
+ HAL_MMC_CARD_SENDING = 0x00000005U, /*!< Card is sending an operation */
+ HAL_MMC_CARD_RECEIVING = 0x00000006U, /*!< Card is receiving operation information */
+ HAL_MMC_CARD_PROGRAMMING = 0x00000007U, /*!< Card is in programming state */
+ HAL_MMC_CARD_DISCONNECTED = 0x00000008U, /*!< Card is disconnected */
+ HAL_MMC_CARD_ERROR = 0x000000FFU /*!< Card response Error */
+}HAL_MMC_CardStateTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup MMC_Exported_Types_Group3 MMC Handle Structure definition
+ * @{
+ */
+#define MMC_InitTypeDef SDIO_InitTypeDef
+#define MMC_TypeDef SDIO_TypeDef
+
+/**
+ * @brief MMC Card Information Structure definition
+ */
+typedef struct
+{
+ uint32_t CardType; /*!< Specifies the card Type */
+
+ uint32_t Class; /*!< Specifies the class of the card class */
+
+ uint32_t RelCardAdd; /*!< Specifies the Relative Card Address */
+
+ uint32_t BlockNbr; /*!< Specifies the Card Capacity in blocks */
+
+ uint32_t BlockSize; /*!< Specifies one block size in bytes */
+
+ uint32_t LogBlockNbr; /*!< Specifies the Card logical Capacity in blocks */
+
+ uint32_t LogBlockSize; /*!< Specifies logical block size in bytes */
+
+}HAL_MMC_CardInfoTypeDef;
+
+/**
+ * @brief MMC handle Structure definition
+ */
+typedef struct
+{
+ MMC_TypeDef *Instance; /*!< MMC registers base address */
+
+ MMC_InitTypeDef Init; /*!< MMC required parameters */
+
+ HAL_LockTypeDef Lock; /*!< MMC locking object */
+
+ uint32_t *pTxBuffPtr; /*!< Pointer to MMC Tx transfer Buffer */
+
+ uint32_t TxXferSize; /*!< MMC Tx Transfer size */
+
+ uint32_t *pRxBuffPtr; /*!< Pointer to MMC Rx transfer Buffer */
+
+ uint32_t RxXferSize; /*!< MMC Rx Transfer size */
+
+ __IO uint32_t Context; /*!< MMC transfer context */
+
+ __IO HAL_MMC_StateTypeDef State; /*!< MMC card State */
+
+ __IO uint32_t ErrorCode; /*!< MMC Card Error codes */
+
+ DMA_HandleTypeDef *hdmarx; /*!< MMC Rx DMA handle parameters */
+
+ DMA_HandleTypeDef *hdmatx; /*!< MMC Tx DMA handle parameters */
+
+ HAL_MMC_CardInfoTypeDef MmcCard; /*!< MMC Card information */
+
+ uint32_t CSD[4U]; /*!< MMC card specific data table */
+
+ uint32_t CID[4U]; /*!< MMC card identification number table */
+
+}MMC_HandleTypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup MMC_Exported_Types_Group4 Card Specific Data: CSD Register
+ * @{
+ */
+typedef struct
+{
+ __IO uint8_t CSDStruct; /*!< CSD structure */
+ __IO uint8_t SysSpecVersion; /*!< System specification version */
+ __IO uint8_t Reserved1; /*!< Reserved */
+ __IO uint8_t TAAC; /*!< Data read access time 1 */
+ __IO uint8_t NSAC; /*!< Data read access time 2 in CLK cycles */
+ __IO uint8_t MaxBusClkFrec; /*!< Max. bus clock frequency */
+ __IO uint16_t CardComdClasses; /*!< Card command classes */
+ __IO uint8_t RdBlockLen; /*!< Max. read data block length */
+ __IO uint8_t PartBlockRead; /*!< Partial blocks for read allowed */
+ __IO uint8_t WrBlockMisalign; /*!< Write block misalignment */
+ __IO uint8_t RdBlockMisalign; /*!< Read block misalignment */
+ __IO uint8_t DSRImpl; /*!< DSR implemented */
+ __IO uint8_t Reserved2; /*!< Reserved */
+ __IO uint32_t DeviceSize; /*!< Device Size */
+ __IO uint8_t MaxRdCurrentVDDMin; /*!< Max. read current @ VDD min */
+ __IO uint8_t MaxRdCurrentVDDMax; /*!< Max. read current @ VDD max */
+ __IO uint8_t MaxWrCurrentVDDMin; /*!< Max. write current @ VDD min */
+ __IO uint8_t MaxWrCurrentVDDMax; /*!< Max. write current @ VDD max */
+ __IO uint8_t DeviceSizeMul; /*!< Device size multiplier */
+ __IO uint8_t EraseGrSize; /*!< Erase group size */
+ __IO uint8_t EraseGrMul; /*!< Erase group size multiplier */
+ __IO uint8_t WrProtectGrSize; /*!< Write protect group size */
+ __IO uint8_t WrProtectGrEnable; /*!< Write protect group enable */
+ __IO uint8_t ManDeflECC; /*!< Manufacturer default ECC */
+ __IO uint8_t WrSpeedFact; /*!< Write speed factor */
+ __IO uint8_t MaxWrBlockLen; /*!< Max. write data block length */
+ __IO uint8_t WriteBlockPaPartial; /*!< Partial blocks for write allowed */
+ __IO uint8_t Reserved3; /*!< Reserved */
+ __IO uint8_t ContentProtectAppli; /*!< Content protection application */
+ __IO uint8_t FileFormatGrouop; /*!< File format group */
+ __IO uint8_t CopyFlag; /*!< Copy flag (OTP) */
+ __IO uint8_t PermWrProtect; /*!< Permanent write protection */
+ __IO uint8_t TempWrProtect; /*!< Temporary write protection */
+ __IO uint8_t FileFormat; /*!< File format */
+ __IO uint8_t ECC; /*!< ECC code */
+ __IO uint8_t CSD_CRC; /*!< CSD CRC */
+ __IO uint8_t Reserved4; /*!< Always 1 */
+
+}HAL_MMC_CardCSDTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup MMC_Exported_Types_Group5 Card Identification Data: CID Register
+ * @{
+ */
+typedef struct
+{
+ __IO uint8_t ManufacturerID; /*!< Manufacturer ID */
+ __IO uint16_t OEM_AppliID; /*!< OEM/Application ID */
+ __IO uint32_t ProdName1; /*!< Product Name part1 */
+ __IO uint8_t ProdName2; /*!< Product Name part2 */
+ __IO uint8_t ProdRev; /*!< Product Revision */
+ __IO uint32_t ProdSN; /*!< Product Serial Number */
+ __IO uint8_t Reserved1; /*!< Reserved1 */
+ __IO uint16_t ManufactDate; /*!< Manufacturing Date */
+ __IO uint8_t CID_CRC; /*!< CID CRC */
+ __IO uint8_t Reserved2; /*!< Always 1 */
+
+}HAL_MMC_CardCIDTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup MMC_Exported_Types_Group6 MMC Card Status returned by ACMD13
+ * @{
+ */
+typedef struct
+{
+ __IO uint8_t DataBusWidth; /*!< Shows the currently defined data bus width */
+ __IO uint8_t SecuredMode; /*!< Card is in secured mode of operation */
+ __IO uint16_t CardType; /*!< Carries information about card type */
+ __IO uint32_t ProtectedAreaSize; /*!< Carries information about the capacity of protected area */
+ __IO uint8_t SpeedClass; /*!< Carries information about the speed class of the card */
+ __IO uint8_t PerformanceMove; /*!< Carries information about the card's performance move */
+ __IO uint8_t AllocationUnitSize; /*!< Carries information about the card's allocation unit size */
+ __IO uint16_t EraseSize; /*!< Determines the number of AUs to be erased in one operation */
+ __IO uint8_t EraseTimeout; /*!< Determines the timeout for any number of AU erase */
+ __IO uint8_t EraseOffset; /*!< Carries information about the erase offset */
+
+}HAL_MMC_CardStatusTypeDef;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup MMC_Exported_Constants Exported Constants
+ * @{
+ */
+
+#define BLOCKSIZE 512U /*!< Block size is 512 bytes */
+
+#define CAPACITY 0x400000U /*!< Log Block Nuumber for 2 G bytes Cards */
+
+/** @defgroup MMC_Exported_Constansts_Group1 MMC Error status enumeration Structure definition
+ * @{
+ */
+#define HAL_MMC_ERROR_NONE SDMMC_ERROR_NONE /*!< No error */
+#define HAL_MMC_ERROR_CMD_CRC_FAIL SDMMC_ERROR_CMD_CRC_FAIL /*!< Command response received (but CRC check failed) */
+#define HAL_MMC_ERROR_DATA_CRC_FAIL SDMMC_ERROR_DATA_CRC_FAIL /*!< Data block sent/received (CRC check failed) */
+#define HAL_MMC_ERROR_CMD_RSP_TIMEOUT SDMMC_ERROR_CMD_RSP_TIMEOUT /*!< Command response timeout */
+#define HAL_MMC_ERROR_DATA_TIMEOUT SDMMC_ERROR_DATA_TIMEOUT /*!< Data timeout */
+#define HAL_MMC_ERROR_TX_UNDERRUN SDMMC_ERROR_TX_UNDERRUN /*!< Transmit FIFO underrun */
+#define HAL_MMC_ERROR_RX_OVERRUN SDMMC_ERROR_RX_OVERRUN /*!< Receive FIFO overrun */
+#define HAL_MMC_ERROR_ADDR_MISALIGNED SDMMC_ERROR_ADDR_MISALIGNED /*!< Misaligned address */
+#define HAL_MMC_ERROR_BLOCK_LEN_ERR SDMMC_ERROR_BLOCK_LEN_ERR /*!< Transferred block length is not allowed for the card or the
+ number of transferred bytes does not match the block length */
+#define HAL_MMC_ERROR_ERASE_SEQ_ERR SDMMC_ERROR_ERASE_SEQ_ERR /*!< An error in the sequence of erase command occurs */
+#define HAL_MMC_ERROR_BAD_ERASE_PARAM SDMMC_ERROR_BAD_ERASE_PARAM /*!< An invalid selection for erase groups */
+#define HAL_MMC_ERROR_WRITE_PROT_VIOLATION SDMMC_ERROR_WRITE_PROT_VIOLATION /*!< Attempt to program a write protect block */
+#define HAL_MMC_ERROR_LOCK_UNLOCK_FAILED SDMMC_ERROR_LOCK_UNLOCK_FAILED /*!< Sequence or password error has been detected in unlock
+ command or if there was an attempt to access a locked card */
+#define HAL_MMC_ERROR_COM_CRC_FAILED SDMMC_ERROR_COM_CRC_FAILED /*!< CRC check of the previous command failed */
+#define HAL_MMC_ERROR_ILLEGAL_CMD SDMMC_ERROR_ILLEGAL_CMD /*!< Command is not legal for the card state */
+#define HAL_MMC_ERROR_CARD_ECC_FAILED SDMMC_ERROR_CARD_ECC_FAILED /*!< Card internal ECC was applied but failed to correct the data */
+#define HAL_MMC_ERROR_CC_ERR SDMMC_ERROR_CC_ERR /*!< Internal card controller error */
+#define HAL_MMC_ERROR_GENERAL_UNKNOWN_ERR SDMMC_ERROR_GENERAL_UNKNOWN_ERR /*!< General or unknown error */
+#define HAL_MMC_ERROR_STREAM_READ_UNDERRUN SDMMC_ERROR_STREAM_READ_UNDERRUN /*!< The card could not sustain data reading in stream rmode */
+#define HAL_MMC_ERROR_STREAM_WRITE_OVERRUN SDMMC_ERROR_STREAM_WRITE_OVERRUN /*!< The card could not sustain data programming in stream mode */
+#define HAL_MMC_ERROR_CID_CSD_OVERWRITE SDMMC_ERROR_CID_CSD_OVERWRITE /*!< CID/CSD overwrite error */
+#define HAL_MMC_ERROR_WP_ERASE_SKIP SDMMC_ERROR_WP_ERASE_SKIP /*!< Only partial address space was erased */
+#define HAL_MMC_ERROR_CARD_ECC_DISABLED SDMMC_ERROR_CARD_ECC_DISABLED /*!< Command has been executed without using internal ECC */
+#define HAL_MMC_ERROR_ERASE_RESET SDMMC_ERROR_ERASE_RESET /*!< Erase sequence was cleared before executing because an out
+ of erase sequence command was received */
+#define HAL_MMC_ERROR_AKE_SEQ_ERR SDMMC_ERROR_AKE_SEQ_ERR /*!< Error in sequence of authentication */
+#define HAL_MMC_ERROR_INVALID_VOLTRANGE SDMMC_ERROR_INVALID_VOLTRANGE /*!< Error in case of invalid voltage range */
+#define HAL_MMC_ERROR_ADDR_OUT_OF_RANGE SDMMC_ERROR_ADDR_OUT_OF_RANGE /*!< Error when addressed block is out of range */
+#define HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE SDMMC_ERROR_REQUEST_NOT_APPLICABLE /*!< Error when command request is not applicable */
+#define HAL_MMC_ERROR_PARAM SDMMC_ERROR_INVALID_PARAMETER /*!< the used parameter is not valid */
+#define HAL_MMC_ERROR_UNSUPPORTED_FEATURE SDMMC_ERROR_UNSUPPORTED_FEATURE /*!< Error when feature is not insupported */
+#define HAL_MMC_ERROR_BUSY SDMMC_ERROR_BUSY /*!< Error when transfer process is busy */
+#define HAL_MMC_ERROR_DMA SDMMC_ERROR_DMA /*!< Error while DMA transfer */
+#define HAL_MMC_ERROR_TIMEOUT SDMMC_ERROR_TIMEOUT /*!< Timeout error */
+/**
+ * @}
+ */
+
+/** @defgroup MMC_Exported_Constansts_Group2 MMC context enumeration structure
+ * @{
+ */
+#define MMC_CONTEXT_NONE 0x00000000U /*!< None */
+#define MMC_CONTEXT_READ_SINGLE_BLOCK 0x00000001U /*!< Read single block operation */
+#define MMC_CONTEXT_READ_MULTIPLE_BLOCK 0x00000002U /*!< Read multiple blocks operation */
+#define MMC_CONTEXT_WRITE_SINGLE_BLOCK 0x00000010U /*!< Write single block operation */
+#define MMC_CONTEXT_WRITE_MULTIPLE_BLOCK 0x00000020U /*!< Write multiple blocks operation */
+#define MMC_CONTEXT_IT 0x00000008U /*!< Process in Interrupt mode */
+#define MMC_CONTEXT_DMA 0x00000080U /*!< Process in DMA mode */
+/**
+ * @}
+ */
+
+/** @defgroup MMC_Exported_Constansts_Group3 MMC Voltage mode
+ * @{
+ */
+/**
+ * @brief
+ */
+#define MMC_HIGH_VOLTAGE_RANGE 0x80FF8000U /*!< VALUE OF ARGUMENT */
+#define MMC_DUAL_VOLTAGE_RANGE 0x80FF8080U /*!< VALUE OF ARGUMENT */
+#define eMMC_HIGH_VOLTAGE_RANGE 0xC0FF8000U /*!< for eMMC > 2Gb sector mode */
+#define eMMC_DUAL_VOLTAGE_RANGE 0xC0FF8080U /*!< for eMMC > 2Gb sector mode */
+#define MMC_INVALID_VOLTAGE_RANGE 0x0001FF01U
+/**
+ * @}
+ */
+
+/** @defgroup MMC_Exported_Constansts_Group4 MMC Memory Cards
+ * @{
+ */
+#define MMC_HIGH_VOLTAGE_CARD 0x00000000U
+#define MMC_DUAL_VOLTAGE_CARD 0x00000001U
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup MMC_Exported_macros MMC Exported Macros
+ * @brief macros to handle interrupts and specific clock configurations
+ * @{
+ */
+
+/**
+ * @brief Enable the MMC device.
+ * @retval None
+ */
+#define __HAL_MMC_ENABLE(__HANDLE__) __SDIO_ENABLE((__HANDLE__)->Instance)
+
+/**
+ * @brief Disable the MMC device.
+ * @retval None
+ */
+#define __HAL_MMC_DISABLE(__HANDLE__) __SDIO_DISABLE((__HANDLE__)->Instance)
+
+/**
+ * @brief Enable the SDMMC DMA transfer.
+ * @retval None
+ */
+#define __HAL_MMC_DMA_ENABLE(__HANDLE__) __SDIO_DMA_ENABLE((__HANDLE__)->Instance)
+
+/**
+ * @brief Disable the SDMMC DMA transfer.
+ * @retval None
+ */
+#define __HAL_MMC_DMA_DISABLE(__HANDLE__) __SDIO_DMA_DISABLE((__HANDLE__)->Instance)
+
+/**
+ * @brief Enable the MMC device interrupt.
+ * @param __HANDLE__: MMC Handle
+ * @param __INTERRUPT__: specifies the SDMMC interrupt sources to be enabled.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
+ * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
+ * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
+ * @arg SDIO_IT_RXACT: Data receive in progress interrupt
+ * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
+ * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
+ * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
+ * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
+ * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
+ * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
+ * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
+ * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @retval None
+ */
+#define __HAL_MMC_ENABLE_IT(__HANDLE__, __INTERRUPT__) __SDIO_ENABLE_IT((__HANDLE__)->Instance, (__INTERRUPT__))
+
+/**
+ * @brief Disable the MMC device interrupt.
+ * @param __HANDLE__: MMC Handle
+ * @param __INTERRUPT__: specifies the SDMMC interrupt sources to be disabled.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
+ * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
+ * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
+ * @arg SDIO_IT_RXACT: Data receive in progress interrupt
+ * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
+ * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
+ * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
+ * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
+ * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
+ * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
+ * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
+ * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @retval None
+ */
+#define __HAL_MMC_DISABLE_IT(__HANDLE__, __INTERRUPT__) __SDIO_DISABLE_IT((__HANDLE__)->Instance, (__INTERRUPT__))
+
+/**
+ * @brief Check whether the specified MMC flag is set or not.
+ * @param __HANDLE__: MMC Handle
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed)
+ * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed)
+ * @arg SDIO_FLAG_CTIMEOUT: Command response timeout
+ * @arg SDIO_FLAG_DTIMEOUT: Data timeout
+ * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error
+ * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error
+ * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed)
+ * @arg SDIO_FLAG_CMDSENT: Command sent (no response required)
+ * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero)
+ * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed)
+ * @arg SDIO_FLAG_CMDACT: Command transfer in progress
+ * @arg SDIO_FLAG_TXACT: Data transmit in progress
+ * @arg SDIO_FLAG_RXACT: Data receive in progress
+ * @arg SDIO_FLAG_TXFIFOHE: Transmit FIFO Half Empty
+ * @arg SDIO_FLAG_RXFIFOHF: Receive FIFO Half Full
+ * @arg SDIO_FLAG_TXFIFOF: Transmit FIFO full
+ * @arg SDIO_FLAG_RXFIFOF: Receive FIFO full
+ * @arg SDIO_FLAG_TXFIFOE: Transmit FIFO empty
+ * @arg SDIO_FLAG_RXFIFOE: Receive FIFO empty
+ * @arg SDIO_FLAG_TXDAVL: Data available in transmit FIFO
+ * @arg SDIO_FLAG_RXDAVL: Data available in receive FIFO
+ * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received
+ * @retval The new state of MMC FLAG (SET or RESET).
+ */
+#define __HAL_MMC_GET_FLAG(__HANDLE__, __FLAG__) __SDIO_GET_FLAG((__HANDLE__)->Instance, (__FLAG__))
+
+/**
+ * @brief Clear the MMC's pending flags.
+ * @param __HANDLE__: MMC Handle
+ * @param __FLAG__: specifies the flag to clear.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed)
+ * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed)
+ * @arg SDIO_FLAG_CTIMEOUT: Command response timeout
+ * @arg SDIO_FLAG_DTIMEOUT: Data timeout
+ * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error
+ * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error
+ * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed)
+ * @arg SDIO_FLAG_CMDSENT: Command sent (no response required)
+ * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero)
+ * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed)
+ * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received
+ * @retval None
+ */
+#define __HAL_MMC_CLEAR_FLAG(__HANDLE__, __FLAG__) __SDIO_CLEAR_FLAG((__HANDLE__)->Instance, (__FLAG__))
+
+/**
+ * @brief Check whether the specified MMC interrupt has occurred or not.
+ * @param __HANDLE__: MMC Handle
+ * @param __INTERRUPT__: specifies the SDMMC interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
+ * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
+ * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
+ * @arg SDIO_IT_RXACT: Data receive in progress interrupt
+ * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
+ * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
+ * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
+ * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
+ * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
+ * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
+ * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
+ * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @retval The new state of MMC IT (SET or RESET).
+ */
+#define __HAL_MMC_GET_IT(__HANDLE__, __INTERRUPT__) __SDIO_GET_IT((__HANDLE__)->Instance, (__INTERRUPT__))
+
+/**
+ * @brief Clear the MMC's interrupt pending bits.
+ * @param __HANDLE__: MMC Handle
+ * @param __INTERRUPT__: specifies the interrupt pending bit to clear.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDMMC_DCOUNT, is zero) interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @retval None
+ */
+#define __HAL_MMC_CLEAR_IT(__HANDLE__, __INTERRUPT__) __SDIO_CLEAR_IT((__HANDLE__)->Instance, (__INTERRUPT__))
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup MMC_Exported_Functions MMC Exported Functions
+ * @{
+ */
+
+/** @defgroup MMC_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @{
+ */
+HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc);
+HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc);
+HAL_StatusTypeDef HAL_MMC_DeInit (MMC_HandleTypeDef *hmmc);
+void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc);
+void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc);
+/**
+ * @}
+ */
+
+/** @defgroup MMC_Exported_Functions_Group2 Input and Output operation functions
+ * @{
+ */
+/* Blocking mode: Polling */
+HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout);
+HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout);
+HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd);
+/* Non-Blocking mode: IT */
+HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks);
+HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks);
+/* Non-Blocking mode: DMA */
+HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks);
+HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks);
+
+void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc);
+
+/* Callback in non blocking modes (DMA) */
+void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc);
+void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc);
+void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc);
+void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc);
+/**
+ * @}
+ */
+
+/** @defgroup MMC_Exported_Functions_Group3 Peripheral Control functions
+ * @{
+ */
+HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode);
+/**
+ * @}
+ */
+
+/** @defgroup MMC_Exported_Functions_Group4 MMC card related functions
+ * @{
+ */
+HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc);
+HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID);
+HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD);
+HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo);
+/**
+ * @}
+ */
+
+/** @defgroup MMC_Exported_Functions_Group5 Peripheral State and Errors functions
+ * @{
+ */
+HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc);
+uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc);
+/**
+ * @}
+ */
+
+/** @defgroup MMC_Exported_Functions_Group6 Perioheral Abort management
+ * @{
+ */
+HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc);
+HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc);
+/**
+ * @}
+ */
+
+/* Private types -------------------------------------------------------------*/
+/** @defgroup MMC_Private_Types MMC Private Types
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private defines -----------------------------------------------------------*/
+/** @defgroup MMC_Private_Defines MMC Private Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/** @defgroup MMC_Private_Variables MMC Private Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup MMC_Private_Constants MMC Private Constants
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup MMC_Private_Macros MMC Private Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private functions prototypes ----------------------------------------------*/
+/** @defgroup MMC_Private_Functions_Prototypes MMC Private Functions Prototypes
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup MMC_Private_Functions MMC Private Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F103xE || STM32F103xG */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __STM32F1xx_HAL_MMC_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_nand.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_nand.h
new file mode 100644
index 0000000..0a49689
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_nand.h
@@ -0,0 +1,345 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_nand.h
+ * @author MCD Application Team
+ * @brief Header file of NAND HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_NAND_H
+#define __STM32F1xx_HAL_NAND_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_fsmc.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG)
+/** @addtogroup NAND
+ * @{
+ */
+
+
+/* Exported typedef ----------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup NAND_Exported_Types NAND Exported Types
+ * @{
+ */
+
+/**
+ * @brief HAL NAND State structures definition
+ */
+typedef enum
+{
+ HAL_NAND_STATE_RESET = 0x00U, /*!< NAND not yet initialized or disabled */
+ HAL_NAND_STATE_READY = 0x01U, /*!< NAND initialized and ready for use */
+ HAL_NAND_STATE_BUSY = 0x02U, /*!< NAND internal process is ongoing */
+ HAL_NAND_STATE_ERROR = 0x03U /*!< NAND error state */
+}HAL_NAND_StateTypeDef;
+
+/**
+ * @brief NAND Memory electronic signature Structure definition
+ */
+typedef struct
+{
+ /*State = HAL_NAND_STATE_RESET)
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup NAND_Exported_Functions NAND Exported Functions
+ * @{
+ */
+
+/** @addtogroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @{
+ */
+
+/* Initialization/de-initialization functions ********************************/
+HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FSMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FSMC_NAND_PCC_TimingTypeDef *AttSpace_Timing);
+HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand);
+
+HAL_StatusTypeDef HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig);
+
+HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID);
+
+void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand);
+void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand);
+void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand);
+void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand);
+
+/**
+ * @}
+ */
+
+/** @addtogroup NAND_Exported_Functions_Group2 Input and Output functions
+ * @{
+ */
+
+/* IO operation functions ****************************************************/
+
+HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand);
+
+HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead);
+HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite);
+HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead);
+HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite);
+
+HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToRead);
+HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToWrite);
+HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaToRead);
+HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaTowrite);
+
+HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress);
+uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand);
+uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress);
+
+/**
+ * @}
+ */
+
+/** @addtogroup NAND_Exported_Functions_Group3 Peripheral Control functions
+ * @{
+ */
+
+/* NAND Control functions ****************************************************/
+HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand);
+HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand);
+HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout);
+
+/**
+ * @}
+ */
+
+/** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
+ * @{
+ */
+
+/* NAND State functions *******************************************************/
+HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand);
+uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @addtogroup NAND_Private_Constants
+ * @{
+ */
+
+#define NAND_DEVICE1 FSMC_BANK2
+#define NAND_DEVICE2 FSMC_BANK3
+#define NAND_WRITE_TIMEOUT 1000U
+
+#define CMD_AREA (1U<<16U) /* A16 = CLE high */
+#define ADDR_AREA (1U<<17U) /* A17 = ALE high */
+
+#define NAND_CMD_AREA_A ((uint8_t)0x00)
+#define NAND_CMD_AREA_B ((uint8_t)0x01)
+#define NAND_CMD_AREA_C ((uint8_t)0x50)
+#define NAND_CMD_AREA_TRUE1 ((uint8_t)0x30)
+
+#define NAND_CMD_WRITE0 ((uint8_t)0x80)
+#define NAND_CMD_WRITE_TRUE1 ((uint8_t)0x10)
+#define NAND_CMD_ERASE0 ((uint8_t)0x60)
+#define NAND_CMD_ERASE1 ((uint8_t)0xD0)
+#define NAND_CMD_READID ((uint8_t)0x90)
+#define NAND_CMD_STATUS ((uint8_t)0x70)
+#define NAND_CMD_LOCK_STATUS ((uint8_t)0x7A)
+#define NAND_CMD_RESET ((uint8_t)0xFF)
+
+/* NAND memory status */
+#define NAND_VALID_ADDRESS 0x00000100U
+#define NAND_INVALID_ADDRESS 0x00000200U
+#define NAND_TIMEOUT_ERROR 0x00000400U
+#define NAND_BUSY 0x00000000U
+#define NAND_ERROR 0x00000001U
+#define NAND_READY 0x00000040U
+
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @addtogroup NAND_Private_Macros
+ * @{
+ */
+
+/**
+ * @brief NAND memory address computation.
+ * @param __ADDRESS__: NAND memory address.
+ * @param __HANDLE__ : NAND handle.
+ * @retval NAND Raw address value
+ */
+#define ARRAY_ADDRESS(__ADDRESS__ , __HANDLE__) ((__ADDRESS__)->Page + \
+ (((__ADDRESS__)->Block + (((__ADDRESS__)->Plane) * ((__HANDLE__)->Config.PlaneSize)))* ((__HANDLE__)->Config.BlockSize)))
+
+/**
+ * @brief NAND memory Column address computation.
+ * @param __HANDLE__: NAND handle.
+ * @retval NAND Raw address value
+ */
+#define COLUMN_ADDRESS( __HANDLE__) ((__HANDLE__)->Config.PageSize)
+
+/**
+ * @brief NAND memory address cycling.
+ * @param __ADDRESS__: NAND memory address.
+ * @retval NAND address cycling value.
+ */
+#define ADDR_1ST_CYCLE(__ADDRESS__) (uint8_t)(__ADDRESS__) /* 1st addressing cycle */
+#define ADDR_2ND_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 8U) /* 2nd addressing cycle */
+#define ADDR_3RD_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 16U) /* 3rd addressing cycle */
+#define ADDR_4TH_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 24U) /* 4th addressing cycle */
+
+/**
+ * @brief NAND memory Columns cycling.
+ * @param __ADDRESS__: NAND memory address.
+ * @retval NAND Column address cycling value.
+ */
+#define COLUMN_1ST_CYCLE(__ADDRESS__) (uint8_t)(__ADDRESS__) /* 1st Column addressing cycle */
+#define COLUMN_2ND_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 8U) /* 2nd Column addressing cycle */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_NAND_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_nor.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_nor.h
new file mode 100644
index 0000000..97b492a
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_nor.h
@@ -0,0 +1,304 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_nor.h
+ * @author MCD Application Team
+ * @brief Header file of NOR HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_NOR_H
+#define __STM32F1xx_HAL_NOR_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_fsmc.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG) || defined(STM32F100xE)
+/** @addtogroup NOR
+ * @{
+ */
+
+/** @addtogroup NOR_Private_Constants
+ * @{
+ */
+
+/* NOR device IDs addresses */
+#define MC_ADDRESS ((uint16_t)0x0000)
+#define DEVICE_CODE1_ADDR ((uint16_t)0x0001)
+#define DEVICE_CODE2_ADDR ((uint16_t)0x000E)
+#define DEVICE_CODE3_ADDR ((uint16_t)0x000F)
+
+/* NOR CFI IDs addresses */
+#define CFI1_ADDRESS ((uint16_t)0x10)
+#define CFI2_ADDRESS ((uint16_t)0x11)
+#define CFI3_ADDRESS ((uint16_t)0x12)
+#define CFI4_ADDRESS ((uint16_t)0x13)
+
+/* NOR operation wait timeout */
+#define NOR_TMEOUT ((uint16_t)0xFFFF)
+
+/* NOR memory data width */
+#define NOR_MEMORY_8B ((uint8_t)0x0)
+#define NOR_MEMORY_16B ((uint8_t)0x1)
+
+/* NOR memory device read/write start address */
+#define NOR_MEMORY_ADRESS1 FSMC_BANK1_1
+#define NOR_MEMORY_ADRESS2 FSMC_BANK1_2
+#define NOR_MEMORY_ADRESS3 FSMC_BANK1_3
+#define NOR_MEMORY_ADRESS4 FSMC_BANK1_4
+
+/**
+ * @}
+ */
+
+/** @addtogroup NOR_Private_Macros
+ * @{
+ */
+
+/**
+ * @brief NOR memory address shifting.
+ * @param __NOR_ADDRESS: NOR base address
+ * @param __NOR_MEMORY_WIDTH_: NOR memory width
+ * @param __ADDRESS__: NOR memory address
+ * @retval NOR shifted address value
+ */
+#define NOR_ADDR_SHIFT(__NOR_ADDRESS, __NOR_MEMORY_WIDTH_, __ADDRESS__) \
+ ((uint32_t)(((__NOR_MEMORY_WIDTH_) == NOR_MEMORY_16B)? \
+ ((uint32_t)((__NOR_ADDRESS) + (2U * (__ADDRESS__)))): \
+ ((uint32_t)((__NOR_ADDRESS) + (__ADDRESS__)))))
+
+/**
+ * @brief NOR memory write data to specified address.
+ * @param __ADDRESS__: NOR memory address
+ * @param __DATA__: Data to write
+ * @retval None
+ */
+#define NOR_WRITE(__ADDRESS__, __DATA__) (*(__IO uint16_t *)((uint32_t)(__ADDRESS__)) = (__DATA__))
+
+/**
+ * @}
+ */
+
+/* Exported typedef ----------------------------------------------------------*/
+/** @defgroup NOR_Exported_Types NOR Exported Types
+ * @{
+ */
+
+/**
+ * @brief HAL SRAM State structures definition
+ */
+typedef enum
+{
+ HAL_NOR_STATE_RESET = 0x00U, /*!< NOR not yet initialized or disabled */
+ HAL_NOR_STATE_READY = 0x01U, /*!< NOR initialized and ready for use */
+ HAL_NOR_STATE_BUSY = 0x02U, /*!< NOR internal processing is ongoing */
+ HAL_NOR_STATE_ERROR = 0x03U, /*!< NOR error state */
+ HAL_NOR_STATE_PROTECTED = 0x04U /*!< NOR NORSRAM device write protected */
+}HAL_NOR_StateTypeDef;
+
+/**
+ * @brief FSMC NOR Status typedef
+ */
+typedef enum
+{
+ HAL_NOR_STATUS_SUCCESS = 0U,
+ HAL_NOR_STATUS_ONGOING,
+ HAL_NOR_STATUS_ERROR,
+ HAL_NOR_STATUS_TIMEOUT
+}HAL_NOR_StatusTypeDef;
+
+/**
+ * @brief FSMC NOR ID typedef
+ */
+typedef struct
+{
+ uint16_t Manufacturer_Code; /*!< Defines the device's manufacturer code used to identify the memory */
+
+ uint16_t Device_Code1;
+
+ uint16_t Device_Code2;
+
+ uint16_t Device_Code3; /*!< Defines the device's codes used to identify the memory.
+ These codes can be accessed by performing read operations with specific
+ control signals and addresses set.They can also be accessed by issuing
+ an Auto Select command */
+}NOR_IDTypeDef;
+
+/**
+ * @brief FSMC NOR CFI typedef
+ */
+typedef struct
+{
+ /*!< Defines the information stored in the memory's Common flash interface
+ which contains a description of various electrical and timing parameters,
+ density information and functions supported by the memory */
+
+ uint16_t CFI_1;
+
+ uint16_t CFI_2;
+
+ uint16_t CFI_3;
+
+ uint16_t CFI_4;
+}NOR_CFITypeDef;
+
+/**
+ * @brief NOR handle Structure definition
+ */
+typedef struct
+{
+ FSMC_NORSRAM_TypeDef *Instance; /*!< Register base address */
+
+ FSMC_NORSRAM_EXTENDED_TypeDef *Extended; /*!< Extended mode register base address */
+
+ FSMC_NORSRAM_InitTypeDef Init; /*!< NOR device control configuration parameters */
+
+ HAL_LockTypeDef Lock; /*!< NOR locking object */
+
+ __IO HAL_NOR_StateTypeDef State; /*!< NOR device access state */
+
+}NOR_HandleTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+
+/** @defgroup NOR_Exported_macro NOR Exported Macros
+ * @{
+ */
+
+/** @brief Reset NOR handle state
+ * @param __HANDLE__: NOR handle
+ * @retval None
+ */
+#define __HAL_NOR_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_NOR_STATE_RESET)
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup NOR_Exported_Functions NOR Exported Functions
+ * @{
+ */
+
+/** @addtogroup NOR_Exported_Functions_Group1
+ * @{
+ */
+
+/* Initialization/de-initialization functions **********************************/
+HAL_StatusTypeDef HAL_NOR_Init(NOR_HandleTypeDef *hnor, FSMC_NORSRAM_TimingTypeDef *Timing, FSMC_NORSRAM_TimingTypeDef *ExtTiming);
+HAL_StatusTypeDef HAL_NOR_DeInit(NOR_HandleTypeDef *hnor);
+void HAL_NOR_MspInit(NOR_HandleTypeDef *hnor);
+void HAL_NOR_MspDeInit(NOR_HandleTypeDef *hnor);
+void HAL_NOR_MspWait(NOR_HandleTypeDef *hnor, uint32_t Timeout);
+
+/**
+ * @}
+ */
+
+/** @addtogroup NOR_Exported_Functions_Group2
+ * @{
+ */
+
+/* I/O operation functions ***************************************************/
+HAL_StatusTypeDef HAL_NOR_Read_ID(NOR_HandleTypeDef *hnor, NOR_IDTypeDef *pNOR_ID);
+HAL_StatusTypeDef HAL_NOR_ReturnToReadMode(NOR_HandleTypeDef *hnor);
+HAL_StatusTypeDef HAL_NOR_Read(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData);
+HAL_StatusTypeDef HAL_NOR_Program(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData);
+
+HAL_StatusTypeDef HAL_NOR_ReadBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize);
+HAL_StatusTypeDef HAL_NOR_ProgramBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize);
+
+HAL_StatusTypeDef HAL_NOR_Erase_Block(NOR_HandleTypeDef *hnor, uint32_t BlockAddress, uint32_t Address);
+HAL_StatusTypeDef HAL_NOR_Erase_Chip(NOR_HandleTypeDef *hnor, uint32_t Address);
+HAL_StatusTypeDef HAL_NOR_Read_CFI(NOR_HandleTypeDef *hnor, NOR_CFITypeDef *pNOR_CFI);
+
+/**
+ * @}
+ */
+
+/** @addtogroup NOR_Exported_Functions_Group3
+ * @{
+ */
+
+/* NOR Control functions *****************************************************/
+HAL_StatusTypeDef HAL_NOR_WriteOperation_Enable(NOR_HandleTypeDef *hnor);
+HAL_StatusTypeDef HAL_NOR_WriteOperation_Disable(NOR_HandleTypeDef *hnor);
+
+/**
+ * @}
+ */
+
+/** @addtogroup NOR_Exported_Functions_Group4
+ * @{
+ */
+
+/* NOR State functions ********************************************************/
+HAL_NOR_StateTypeDef HAL_NOR_GetState(NOR_HandleTypeDef *hnor);
+HAL_NOR_StatusTypeDef HAL_NOR_GetStatus(NOR_HandleTypeDef *hnor, uint32_t Address, uint32_t Timeout);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG || STM32F100xE */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_NOR_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pccard.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pccard.h
new file mode 100644
index 0000000..7429fb6
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pccard.h
@@ -0,0 +1,246 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_pccard.h
+ * @author MCD Application Team
+ * @brief Header file of PCCARD HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_PCCARD_H
+#define __STM32F1xx_HAL_PCCARD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_fsmc.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG)
+/** @addtogroup PCCARD
+ * @{
+ */
+
+/** @addtogroup PCCARD_Private_Constants
+ * @{
+ */
+
+#define PCCARD_DEVICE_ADDRESS FSMC_BANK4
+#define PCCARD_ATTRIBUTE_SPACE_ADDRESS ((uint32_t)(FSMC_BANK4 + 0x08000000U)) /* Attribute space size to @0x9BFF FFFF */
+#define PCCARD_COMMON_SPACE_ADDRESS PCCARD_DEVICE_ADDRESS /* Common space size to @0x93FF FFFF */
+#define PCCARD_IO_SPACE_ADDRESS ((uint32_t)(FSMC_BANK4 + 0x0C000000U)) /* IO space size to @0x9FFF FFFF */
+#define PCCARD_IO_SPACE_PRIMARY_ADDR ((uint32_t)(FSMC_BANK4 + 0x0C0001F0U)) /* IO space size to @0x9FFF FFFF */
+
+/* Compact Flash-ATA registers description */
+#define ATA_DATA ((uint8_t)0x00) /* Data register */
+#define ATA_SECTOR_COUNT ((uint8_t)0x02) /* Sector Count register */
+#define ATA_SECTOR_NUMBER ((uint8_t)0x03) /* Sector Number register */
+#define ATA_CYLINDER_LOW ((uint8_t)0x04) /* Cylinder low register */
+#define ATA_CYLINDER_HIGH ((uint8_t)0x05) /* Cylinder high register */
+#define ATA_CARD_HEAD ((uint8_t)0x06) /* Card/Head register */
+#define ATA_STATUS_CMD ((uint8_t)0x07) /* Status(read)/Command(write) register */
+#define ATA_STATUS_CMD_ALTERNATE ((uint8_t)0x0E) /* Alternate Status(read)/Command(write) register */
+#define ATA_COMMON_DATA_AREA ((uint16_t)0x0400) /* Start of data area (for Common access only!) */
+#define ATA_CARD_CONFIGURATION ((uint16_t)0x0202) /* Card Configuration and Status Register */
+
+/* Compact Flash-ATA commands */
+#define ATA_READ_SECTOR_CMD ((uint8_t)0x20)
+#define ATA_WRITE_SECTOR_CMD ((uint8_t)0x30)
+#define ATA_ERASE_SECTOR_CMD ((uint8_t)0xC0)
+#define ATA_IDENTIFY_CMD ((uint8_t)0xEC)
+
+/* Compact Flash status */
+#define PCCARD_TIMEOUT_ERROR ((uint8_t)0x60)
+#define PCCARD_BUSY ((uint8_t)0x80)
+#define PCCARD_PROGR ((uint8_t)0x01)
+#define PCCARD_READY ((uint8_t)0x40)
+
+#define PCCARD_SECTOR_SIZE 255U /* In half words */
+
+
+/* Compact Flash redefinition */
+#define HAL_CF_Read_ID HAL_PCCARD_Read_ID
+#define HAL_CF_Write_Sector HAL_PCCARD_Write_Sector
+#define HAL_CF_Read_Sector HAL_PCCARD_Read_Sector
+#define HAL_CF_Erase_Sector HAL_PCCARD_Erase_Sector
+#define HAL_CF_Reset HAL_PCCARD_Reset
+
+#define HAL_CF_GetStatus HAL_PCCARD_GetStatus
+#define HAL_CF_ReadStatus HAL_PCCARD_ReadStatus
+
+#define CF_SUCCESS HAL_PCCARD_STATUS_SUCCESS
+#define CF_ONGOING HAL_PCCARD_STATUS_ONGOING
+#define CF_ERROR HAL_PCCARD_STATUS_ERROR
+#define CF_TIMEOUT HAL_PCCARD_STATUS_TIMEOUT
+#define CF_StatusTypedef HAL_PCCARD_StatusTypeDef
+
+#define CF_DEVICE_ADDRESS PCCARD_DEVICE_ADDRESS
+#define CF_ATTRIBUTE_SPACE_ADDRESS PCCARD_ATTRIBUTE_SPACE_ADDRESS
+#define CF_COMMON_SPACE_ADDRESS PCCARD_COMMON_SPACE_ADDRESS
+#define CF_IO_SPACE_ADDRESS PCCARD_IO_SPACE_ADDRESS
+#define CF_IO_SPACE_PRIMARY_ADDR PCCARD_IO_SPACE_PRIMARY_ADDR
+
+#define CF_TIMEOUT_ERROR PCCARD_TIMEOUT_ERROR
+#define CF_BUSY PCCARD_BUSY
+#define CF_PROGR PCCARD_PROGR
+#define CF_READY PCCARD_READY
+
+#define CF_SECTOR_SIZE PCCARD_SECTOR_SIZE
+
+/**
+ * @}
+ */
+
+/* Exported typedef ----------------------------------------------------------*/
+/** @defgroup PCCARD_Exported_Types PCCARD Exported Types
+ * @{
+ */
+
+/**
+ * @brief HAL PCCARD State structures definition
+ */
+typedef enum
+{
+ HAL_PCCARD_STATE_RESET = 0x00U, /*!< PCCARD peripheral not yet initialized or disabled */
+ HAL_PCCARD_STATE_READY = 0x01U, /*!< PCCARD peripheral ready */
+ HAL_PCCARD_STATE_BUSY = 0x02U, /*!< PCCARD peripheral busy */
+ HAL_PCCARD_STATE_ERROR = 0x04U /*!< PCCARD peripheral error */
+}HAL_PCCARD_StateTypeDef;
+
+typedef enum
+{
+ HAL_PCCARD_STATUS_SUCCESS = 0U,
+ HAL_PCCARD_STATUS_ONGOING,
+ HAL_PCCARD_STATUS_ERROR,
+ HAL_PCCARD_STATUS_TIMEOUT
+}HAL_PCCARD_StatusTypeDef;
+
+/**
+ * @brief FSMC_PCCARD handle Structure definition
+ */
+typedef struct
+{
+ FSMC_PCCARD_TypeDef *Instance; /*!< Register base address for PCCARD device */
+
+ FSMC_PCCARD_InitTypeDef Init; /*!< PCCARD device control configuration parameters */
+
+ __IO HAL_PCCARD_StateTypeDef State; /*!< PCCARD device access state */
+
+ HAL_LockTypeDef Lock; /*!< PCCARD Lock */
+
+}PCCARD_HandleTypeDef;
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup PCCARD_Exported_Macros PCCARD Exported Macros
+ * @{
+ */
+
+/** @brief Reset PCCARD handle state
+ * @param __HANDLE__: specifies the PCCARD handle.
+ * @retval None
+ */
+#define __HAL_PCCARD_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_PCCARD_STATE_RESET)
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup PCCARD_Exported_Functions PCCARD Exported Functions
+ * @{
+ */
+
+/** @addtogroup PCCARD_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @{
+ */
+/* Initialization/de-initialization functions **********************************/
+HAL_StatusTypeDef HAL_PCCARD_Init(PCCARD_HandleTypeDef *hpccard, FSMC_NAND_PCC_TimingTypeDef *ComSpaceTiming, FSMC_NAND_PCC_TimingTypeDef *AttSpaceTiming, FSMC_NAND_PCC_TimingTypeDef *IOSpaceTiming);
+HAL_StatusTypeDef HAL_PCCARD_DeInit(PCCARD_HandleTypeDef *hpccard);
+void HAL_PCCARD_MspInit(PCCARD_HandleTypeDef *hpccard);
+void HAL_PCCARD_MspDeInit(PCCARD_HandleTypeDef *hpccard);
+/**
+ * @}
+ */
+
+/** @addtogroup PCCARD_Exported_Functions_Group2 Input Output and memory functions
+ * @{
+ */
+/* IO operation functions *****************************************************/
+HAL_StatusTypeDef HAL_PCCARD_Read_ID(PCCARD_HandleTypeDef *hpccard, uint8_t CompactFlash_ID[], uint8_t *pStatus);
+HAL_StatusTypeDef HAL_PCCARD_Write_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress, uint8_t *pStatus);
+HAL_StatusTypeDef HAL_PCCARD_Read_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress, uint8_t *pStatus);
+HAL_StatusTypeDef HAL_PCCARD_Erase_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t SectorAddress, uint8_t *pStatus);
+HAL_StatusTypeDef HAL_PCCARD_Reset(PCCARD_HandleTypeDef *hpccard);
+void HAL_PCCARD_IRQHandler(PCCARD_HandleTypeDef *hpccard);
+void HAL_PCCARD_ITCallback(PCCARD_HandleTypeDef *hpccard);
+
+/**
+ * @}
+ */
+
+/** @defgroup PCCARD_Exported_Functions_Group3 Peripheral State functions
+ * @{
+ */
+/* PCCARD State functions *******************************************************/
+HAL_PCCARD_StateTypeDef HAL_PCCARD_GetState(PCCARD_HandleTypeDef *hpccard);
+HAL_PCCARD_StatusTypeDef HAL_PCCARD_GetStatus(PCCARD_HandleTypeDef *hpccard);
+HAL_PCCARD_StatusTypeDef HAL_PCCARD_ReadStatus(PCCARD_HandleTypeDef *hpccard);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_PCCARD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd.h
new file mode 100644
index 0000000..1c8c0b2
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd.h
@@ -0,0 +1,851 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_pcd.h
+ * @author MCD Application Team
+ * @brief Header file of PCD HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_PCD_H
+#define __STM32F1xx_HAL_PCD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#if defined(STM32F102x6) || defined(STM32F102xB) || \
+ defined(STM32F103x6) || defined(STM32F103xB) || \
+ defined(STM32F103xE) || defined(STM32F103xG) || \
+ defined(STM32F105xC) || defined(STM32F107xC)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_usb.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup PCD
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup PCD_Exported_Types PCD Exported Types
+ * @{
+ */
+
+/**
+ * @brief PCD State structure definition
+ */
+typedef enum
+{
+ HAL_PCD_STATE_RESET = 0x00U,
+ HAL_PCD_STATE_READY = 0x01U,
+ HAL_PCD_STATE_ERROR = 0x02U,
+ HAL_PCD_STATE_BUSY = 0x03U,
+ HAL_PCD_STATE_TIMEOUT = 0x04U
+} PCD_StateTypeDef;
+
+#if defined (USB)
+/**
+ * @brief PCD double buffered endpoint direction
+ */
+typedef enum
+{
+ PCD_EP_DBUF_OUT,
+ PCD_EP_DBUF_IN,
+ PCD_EP_DBUF_ERR,
+}PCD_EP_DBUF_DIR;
+
+/**
+ * @brief PCD endpoint buffer number
+ */
+typedef enum
+{
+ PCD_EP_NOBUF,
+ PCD_EP_BUF0,
+ PCD_EP_BUF1
+}PCD_EP_BUF_NUM;
+#endif /* USB */
+
+#if defined (USB_OTG_FS)
+typedef USB_OTG_GlobalTypeDef PCD_TypeDef;
+typedef USB_OTG_CfgTypeDef PCD_InitTypeDef;
+typedef USB_OTG_EPTypeDef PCD_EPTypeDef;
+#endif /* USB_OTG_FS */
+
+#if defined (USB)
+typedef USB_TypeDef PCD_TypeDef;
+typedef USB_CfgTypeDef PCD_InitTypeDef;
+typedef USB_EPTypeDef PCD_EPTypeDef;
+#endif /* USB */
+
+/**
+ * @brief PCD Handle Structure definition
+ */
+typedef struct
+{
+ PCD_TypeDef *Instance; /*!< Register base address */
+ PCD_InitTypeDef Init; /*!< PCD required parameters */
+ __IO uint8_t USB_Address; /*!< USB Address: not used by USB OTG FS */
+ PCD_EPTypeDef IN_ep[16]; /*!< IN endpoint parameters */
+ PCD_EPTypeDef OUT_ep[16]; /*!< OUT endpoint parameters */
+ HAL_LockTypeDef Lock; /*!< PCD peripheral status */
+ __IO PCD_StateTypeDef State; /*!< PCD communication state */
+ uint32_t Setup[12U]; /*!< Setup packet buffer */
+ void *pData; /*!< Pointer to upper stack Handler */
+} PCD_HandleTypeDef;
+
+/**
+ * @}
+ */
+
+/* Include PCD HAL Extension module */
+#include "stm32f1xx_hal_pcd_ex.h"
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup PCD_Exported_Constants PCD Exported Constants
+ * @{
+ */
+
+/** @defgroup PCD_Speed PCD Speed
+ * @{
+ */
+#define PCD_SPEED_HIGH 0U /* Not Supported */
+#define PCD_SPEED_HIGH_IN_FULL 1U /* Not Supported */
+#define PCD_SPEED_FULL 2U
+/**
+ * @}
+ */
+
+/** @defgroup PCD_PHY_Module PCD PHY Module
+ * @{
+ */
+#define PCD_PHY_EMBEDDED 2U
+/**
+ * @}
+ */
+
+/** @defgroup PCD_Turnaround_Timeout Turnaround Timeout Value
+ * @{
+ */
+#ifndef USBD_FS_TRDT_VALUE
+ #define USBD_FS_TRDT_VALUE 5U
+#endif /* USBD_FS_TRDT_VALUE */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macros -----------------------------------------------------------*/
+/** @defgroup PCD_Exported_Macros PCD Exported Macros
+ * @brief macros to handle interrupts and specific clock configurations
+ * @{
+ */
+#if defined (USB_OTG_FS)
+
+#define __HAL_PCD_ENABLE(__HANDLE__) USB_EnableGlobalInt ((__HANDLE__)->Instance)
+#define __HAL_PCD_DISABLE(__HANDLE__) USB_DisableGlobalInt ((__HANDLE__)->Instance)
+
+#define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__) ((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__))
+#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->GINTSTS) = (__INTERRUPT__))
+#define __HAL_PCD_IS_INVALID_INTERRUPT(__HANDLE__) (USB_ReadInterrupts((__HANDLE__)->Instance) == 0U)
+
+#define __HAL_PCD_UNGATE_PHYCLOCK(__HANDLE__) *(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) &= \
+ ~(USB_OTG_PCGCCTL_STOPCLK)
+
+#define __HAL_PCD_GATE_PHYCLOCK(__HANDLE__) *(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) |= USB_OTG_PCGCCTL_STOPCLK
+
+#define __HAL_PCD_IS_PHY_SUSPENDED(__HANDLE__) ((*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE)) & 0x10U)
+
+#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= USB_OTG_FS_WAKEUP_EXTI_LINE
+#define __HAL_USB_OTG_FS_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE)
+#define __HAL_USB_OTG_FS_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (USB_OTG_FS_WAKEUP_EXTI_LINE)
+#define __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = USB_OTG_FS_WAKEUP_EXTI_LINE
+
+#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE() \
+ do{ \
+ EXTI->FTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE); \
+ EXTI->RTSR |= USB_OTG_FS_WAKEUP_EXTI_LINE; \
+ } while(0U)
+
+#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_FALLING_EDGE() \
+ do{ \
+ EXTI->FTSR |= (USB_OTG_FS_WAKEUP_EXTI_LINE); \
+ EXTI->RTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE); \
+ } while(0U)
+
+#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE() \
+ do{ \
+ EXTI->RTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE); \
+ EXTI->FTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE); \
+ EXTI->RTSR |= USB_OTG_FS_WAKEUP_EXTI_LINE; \
+ EXTI->FTSR |= USB_OTG_FS_WAKEUP_EXTI_LINE; \
+ } while(0U)
+
+#define __HAL_USB_OTG_FS_WAKEUP_EXTI_GENERATE_SWIT() (EXTI->SWIER |= USB_OTG_FS_WAKEUP_EXTI_LINE)
+#endif /* USB_OTG_FS */
+
+#if defined (USB)
+#define __HAL_PCD_ENABLE(__HANDLE__) USB_EnableGlobalInt ((__HANDLE__)->Instance)
+#define __HAL_PCD_DISABLE(__HANDLE__) USB_DisableGlobalInt ((__HANDLE__)->Instance)
+#define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__) ((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__))
+#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->ISTR) &= ~(__INTERRUPT__))
+
+#define __HAL_USB_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= USB_WAKEUP_EXTI_LINE
+#define __HAL_USB_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(USB_WAKEUP_EXTI_LINE)
+#define __HAL_USB_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (USB_WAKEUP_EXTI_LINE)
+#define __HAL_USB_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = USB_WAKEUP_EXTI_LINE
+
+#define __HAL_USB_WAKEUP_EXTI_ENABLE_RISING_EDGE() \
+ do{ \
+ EXTI->FTSR &= ~(USB_WAKEUP_EXTI_LINE); \
+ EXTI->RTSR |= USB_WAKEUP_EXTI_LINE; \
+ } while(0U)
+
+#define __HAL_USB_WAKEUP_EXTI_ENABLE_FALLING_EDGE() \
+ do{ \
+ EXTI->FTSR |= (USB_WAKEUP_EXTI_LINE); \
+ EXTI->RTSR &= ~(USB_WAKEUP_EXTI_LINE); \
+ } while(0U)
+
+#define __HAL_USB_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE() \
+ do{ \
+ EXTI->RTSR &= ~(USB_WAKEUP_EXTI_LINE); \
+ EXTI->FTSR &= ~(USB_WAKEUP_EXTI_LINE); \
+ EXTI->RTSR |= USB_WAKEUP_EXTI_LINE; \
+ EXTI->FTSR |= USB_WAKEUP_EXTI_LINE; \
+ } while(0U)
+#endif /* USB */
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup PCD_Exported_Functions PCD Exported Functions
+ * @{
+ */
+
+/* Initialization/de-initialization functions ********************************/
+/** @addtogroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @{
+ */
+HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd);
+HAL_StatusTypeDef HAL_PCD_DeInit (PCD_HandleTypeDef *hpcd);
+void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd);
+void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd);
+/**
+ * @}
+ */
+
+/* I/O operation functions ***************************************************/
+/* Non-Blocking mode: Interrupt */
+/** @addtogroup PCD_Exported_Functions_Group2 IO operation functions
+ * @{
+ */
+HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd);
+HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd);
+void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd);
+
+void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
+void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
+void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd);
+void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd);
+void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd);
+void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd);
+void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd);
+void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
+void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
+void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd);
+void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd);
+/**
+ * @}
+ */
+
+/* Peripheral Control functions **********************************************/
+/** @addtogroup PCD_Exported_Functions_Group3 Peripheral Control functions
+ * @{
+ */
+HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd);
+HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd);
+HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address);
+HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type);
+HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
+HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len);
+HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len);
+uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
+HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
+HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
+HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
+HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
+HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
+/**
+ * @}
+ */
+
+/* Peripheral State functions ************************************************/
+/** @addtogroup PCD_Exported_Functions_Group4 Peripheral State functions
+ * @{
+ */
+PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup PCD_Private_Constants PCD Private Constants
+ * @{
+ */
+/** @defgroup USB_EXTI_Line_Interrupt USB EXTI line interrupt
+ * @{
+ */
+#if defined (USB_OTG_FS)
+#define USB_OTG_FS_WAKEUP_EXTI_RISING_EDGE 0x08U
+#define USB_OTG_FS_WAKEUP_EXTI_FALLING_EDGE 0x0CU
+#define USB_OTG_FS_WAKEUP_EXTI_RISING_FALLING_EDGE 0x10U
+
+#define USB_OTG_FS_WAKEUP_EXTI_LINE 0x00040000U /*!< External interrupt line 18 Connected to the USB EXTI Line */
+#endif /* USB_OTG_FS */
+
+#if defined (USB)
+#define USB_WAKEUP_EXTI_LINE 0x00040000U /*!< External interrupt line 18 Connected to the USB EXTI Line */
+#endif /* USB */
+/**
+ * @}
+ */
+
+#if defined (USB)
+/** @defgroup PCD_EP0_MPS PCD EP0 MPS
+ * @{
+ */
+#define PCD_EP0MPS_64 DEP0CTL_MPS_64
+#define PCD_EP0MPS_32 DEP0CTL_MPS_32
+#define PCD_EP0MPS_16 DEP0CTL_MPS_16
+#define PCD_EP0MPS_08 DEP0CTL_MPS_8
+/**
+ * @}
+ */
+
+/** @defgroup PCD_ENDP PCD ENDP
+ * @{
+ */
+#define PCD_ENDP0 ((uint8_t)0)
+#define PCD_ENDP1 ((uint8_t)1)
+#define PCD_ENDP2 ((uint8_t)2)
+#define PCD_ENDP3 ((uint8_t)3)
+#define PCD_ENDP4 ((uint8_t)4)
+#define PCD_ENDP5 ((uint8_t)5)
+#define PCD_ENDP6 ((uint8_t)6)
+#define PCD_ENDP7 ((uint8_t)7)
+/**
+ * @}
+ */
+
+/** @defgroup PCD_ENDP_Kind PCD Endpoint Kind
+ * @{
+ */
+#define PCD_SNG_BUF 0U
+#define PCD_DBL_BUF 1U
+/**
+ * @}
+ */
+#endif /* USB */
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @addtogroup PCD_Private_Macros PCD Private Macros
+ * @{
+ */
+#if defined (USB)
+/* SetENDPOINT */
+#define PCD_SET_ENDPOINT(USBx, bEpNum,wRegValue) (*(&(USBx)->EP0R + (bEpNum) * 2U)= (uint16_t)(wRegValue))
+
+/* GetENDPOINT */
+#define PCD_GET_ENDPOINT(USBx, bEpNum) (*(&(USBx)->EP0R + (bEpNum) * 2U))
+
+/* ENDPOINT transfer */
+#define USB_EP0StartXfer USB_EPStartXfer
+
+/**
+ * @brief sets the type in the endpoint register(bits EP_TYPE[1:0])
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @param wType: Endpoint Type.
+ * @retval None
+ */
+#define PCD_SET_EPTYPE(USBx, bEpNum,wType) (PCD_SET_ENDPOINT((USBx), (bEpNum),\
+ ((PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_T_MASK) | (wType) )))
+
+/**
+ * @brief gets the type in the endpoint register(bits EP_TYPE[1:0])
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @retval Endpoint Type
+ */
+#define PCD_GET_EPTYPE(USBx, bEpNum) (PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_T_FIELD)
+
+/**
+ * @brief free buffer used from the application realizing it to the line
+ toggles bit SW_BUF in the double buffered endpoint register
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @param bDir: Direction
+ * @retval None
+ */
+#define PCD_FreeUserBuffer(USBx, bEpNum, bDir)\
+{\
+ if ((bDir) == PCD_EP_DBUF_OUT)\
+ { /* OUT double buffered endpoint */\
+ PCD_TX_DTOG((USBx), (bEpNum));\
+ }\
+ else if ((bDir) == PCD_EP_DBUF_IN)\
+ { /* IN double buffered endpoint */\
+ PCD_RX_DTOG((USBx), (bEpNum));\
+ }\
+}
+
+/**
+ * @brief gets direction of the double buffered endpoint
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @retval EP_DBUF_OUT, EP_DBUF_IN,
+ * EP_DBUF_ERR if the endpoint counter not yet programmed.
+ */
+#define PCD_GET_DB_DIR(USBx, bEpNum)\
+{\
+ if ((uint16_t)(*PCD_EP_RX_CNT((USBx), (bEpNum)) & 0xFC00) != 0)\
+ return(PCD_EP_DBUF_OUT);\
+ else if (((uint16_t)(*PCD_EP_TX_CNT((USBx), (bEpNum))) & 0x03FF) != 0)\
+ return(PCD_EP_DBUF_IN);\
+ else\
+ return(PCD_EP_DBUF_ERR);\
+}
+
+/**
+ * @brief sets the status for tx transfer (bits STAT_TX[1:0]).
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @param wState: new state
+ * @retval None
+ */
+#define PCD_SET_EP_TX_STATUS(USBx, bEpNum, wState) { register uint16_t _wRegVal;\
+ \
+ _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPTX_DTOGMASK;\
+ /* toggle first bit ? */ \
+ if((USB_EPTX_DTOG1 & (wState))!= 0U)\
+ { \
+ _wRegVal ^= USB_EPTX_DTOG1; \
+ } \
+ /* toggle second bit ? */ \
+ if((USB_EPTX_DTOG2 & (wState))!= 0U) \
+ { \
+ _wRegVal ^= USB_EPTX_DTOG2; \
+ } \
+ PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX|USB_EP_CTR_TX));\
+ } /* PCD_SET_EP_TX_STATUS */
+
+/**
+ * @brief sets the status for rx transfer (bits STAT_TX[1:0])
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @param wState: new state
+ * @retval None
+ */
+#define PCD_SET_EP_RX_STATUS(USBx, bEpNum,wState) {\
+ register uint16_t _wRegVal; \
+ \
+ _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPRX_DTOGMASK;\
+ /* toggle first bit ? */ \
+ if((USB_EPRX_DTOG1 & (wState))!= 0U) \
+ { \
+ _wRegVal ^= USB_EPRX_DTOG1; \
+ } \
+ /* toggle second bit ? */ \
+ if((USB_EPRX_DTOG2 & (wState))!= 0U) \
+ { \
+ _wRegVal ^= USB_EPRX_DTOG2; \
+ } \
+ PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX|USB_EP_CTR_TX)); \
+ } /* PCD_SET_EP_RX_STATUS */
+
+/**
+ * @brief sets the status for rx & tx (bits STAT_TX[1:0] & STAT_RX[1:0])
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @param wStaterx: new state.
+ * @param wStatetx: new state.
+ * @retval None
+ */
+#define PCD_SET_EP_TXRX_STATUS(USBx,bEpNum,wStaterx,wStatetx) {\
+ register uint32_t _wRegVal; \
+ \
+ _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (USB_EPRX_DTOGMASK |USB_EPTX_STAT) ;\
+ /* toggle first bit ? */ \
+ if((USB_EPRX_DTOG1 & ((wStaterx)))!= 0U) \
+ { \
+ _wRegVal ^= USB_EPRX_DTOG1; \
+ } \
+ /* toggle second bit ? */ \
+ if((USB_EPRX_DTOG2 & (wStaterx))!= 0U) \
+ { \
+ _wRegVal ^= USB_EPRX_DTOG2; \
+ } \
+ /* toggle first bit ? */ \
+ if((USB_EPTX_DTOG1 & (wStatetx))!= 0U) \
+ { \
+ _wRegVal ^= USB_EPTX_DTOG1; \
+ } \
+ /* toggle second bit ? */ \
+ if((USB_EPTX_DTOG2 & (wStatetx))!= 0U) \
+ { \
+ _wRegVal ^= USB_EPTX_DTOG2; \
+ } \
+ PCD_SET_ENDPOINT((USBx), (bEpNum), _wRegVal | USB_EP_CTR_RX|USB_EP_CTR_TX); \
+ } /* PCD_SET_EP_TXRX_STATUS */
+
+/**
+ * @brief gets the status for tx/rx transfer (bits STAT_TX[1:0]
+ * /STAT_RX[1:0])
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @retval status
+ */
+#define PCD_GET_EP_TX_STATUS(USBx, bEpNum) ((uint16_t)PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPTX_STAT)
+#define PCD_GET_EP_RX_STATUS(USBx, bEpNum) ((uint16_t)PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPRX_STAT)
+
+/**
+ * @brief sets directly the VALID tx/rx-status into the endpoint register
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @retval None
+ */
+#define PCD_SET_EP_TX_VALID(USBx, bEpNum) (PCD_SET_EP_TX_STATUS((USBx), (bEpNum), USB_EP_TX_VALID))
+#define PCD_SET_EP_RX_VALID(USBx, bEpNum) (PCD_SET_EP_RX_STATUS((USBx), (bEpNum), USB_EP_RX_VALID))
+
+/**
+ * @brief checks stall condition in an endpoint.
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @retval TRUE = endpoint in stall condition.
+ */
+#define PCD_GET_EP_TX_STALL_STATUS(USBx, bEpNum) (PCD_GET_EP_TX_STATUS((USBx), (bEpNum)) \
+ == USB_EP_TX_STALL)
+#define PCD_GET_EP_RX_STALL_STATUS(USBx, bEpNum) (PCD_GET_EP_RX_STATUS((USBx), (bEpNum)) \
+ == USB_EP_RX_STALL)
+
+/**
+ * @brief set & clear EP_KIND bit.
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @retval None
+ */
+#define PCD_SET_EP_KIND(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum), \
+ (USB_EP_CTR_RX|USB_EP_CTR_TX|((PCD_GET_ENDPOINT((USBx), (bEpNum)) | USB_EP_KIND) & USB_EPREG_MASK))))
+#define PCD_CLEAR_EP_KIND(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum), \
+ (USB_EP_CTR_RX|USB_EP_CTR_TX|(PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPKIND_MASK))))
+
+/**
+ * @brief Sets/clears directly STATUS_OUT bit in the endpoint register.
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @retval None
+ */
+#define PCD_SET_OUT_STATUS(USBx, bEpNum) PCD_SET_EP_KIND((USBx), (bEpNum))
+#define PCD_CLEAR_OUT_STATUS(USBx, bEpNum) PCD_CLEAR_EP_KIND((USBx), (bEpNum))
+
+/**
+ * @brief Sets/clears directly EP_KIND bit in the endpoint register.
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @retval None
+ */
+#define PCD_SET_EP_DBUF(USBx, bEpNum) PCD_SET_EP_KIND((USBx), (bEpNum))
+#define PCD_CLEAR_EP_DBUF(USBx, bEpNum) PCD_CLEAR_EP_KIND((USBx), (bEpNum))
+
+/**
+ * @brief Clears bit CTR_RX / CTR_TX in the endpoint register.
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @retval None
+ */
+#define PCD_CLEAR_RX_EP_CTR(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum),\
+ PCD_GET_ENDPOINT((USBx), (bEpNum)) & 0x7FFFU & USB_EPREG_MASK))
+#define PCD_CLEAR_TX_EP_CTR(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum),\
+ PCD_GET_ENDPOINT((USBx), (bEpNum)) & 0xFF7FU & USB_EPREG_MASK))
+
+/**
+ * @brief Toggles DTOG_RX / DTOG_TX bit in the endpoint register.
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @retval None
+ */
+#define PCD_RX_DTOG(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum), \
+ USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX | (PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK)))
+#define PCD_TX_DTOG(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum), \
+ USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX | (PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK)))
+
+/**
+ * @brief Clears DTOG_RX / DTOG_TX bit in the endpoint register.
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @retval None
+ */
+#define PCD_CLEAR_RX_DTOG(USBx, bEpNum) if((PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_DTOG_RX) != 0U)\
+ { \
+ PCD_RX_DTOG((USBx), (bEpNum)); \
+ }
+#define PCD_CLEAR_TX_DTOG(USBx, bEpNum) if((PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_DTOG_TX) != 0U)\
+ { \
+ PCD_TX_DTOG((USBx), (bEpNum)); \
+ }
+
+/**
+ * @brief Sets address in an endpoint register.
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @param bAddr: Address.
+ * @retval None
+ */
+#define PCD_SET_EP_ADDRESS(USBx, bEpNum,bAddr) PCD_SET_ENDPOINT((USBx), (bEpNum),\
+ USB_EP_CTR_RX|USB_EP_CTR_TX|(PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK) | (bAddr))
+
+#define PCD_GET_EP_ADDRESS(USBx, bEpNum) ((uint8_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPADDR_FIELD))
+
+#define PCD_EP_TX_ADDRESS(USBx, bEpNum) ((uint32_t *)(((USBx)->BTABLE+(bEpNum)*8U)*2U+ ((uint32_t)(USBx) + 0x400U)))
+#define PCD_EP_TX_CNT(USBx, bEpNum) ((uint32_t *)(((USBx)->BTABLE+(bEpNum)*8U+2U)*2U+ ((uint32_t)(USBx) + 0x400U)))
+#define PCD_EP_RX_ADDRESS(USBx, bEpNum) ((uint32_t *)(((USBx)->BTABLE+(bEpNum)*8U+4U)*2U+ ((uint32_t)(USBx) + 0x400U)))
+#define PCD_EP_RX_CNT(USBx, bEpNum) ((uint32_t *)(((USBx)->BTABLE+(bEpNum)*8U+6U)*2U+ ((uint32_t)(USBx) + 0x400U)))
+
+#define PCD_SET_EP_RX_CNT(USBx, bEpNum,wCount) {\
+ uint32_t *pdwReg = PCD_EP_RX_CNT((USBx), (bEpNum)); \
+ PCD_SET_EP_CNT_RX_REG(pdwReg, (wCount));\
+ }
+
+/**
+ * @brief sets address of the tx/rx buffer.
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @param wAddr: address to be set (must be word aligned).
+ * @retval None
+ */
+#define PCD_SET_EP_TX_ADDRESS(USBx, bEpNum,wAddr) (*PCD_EP_TX_ADDRESS((USBx), (bEpNum)) = (((wAddr) >> 1U) << 1U))
+#define PCD_SET_EP_RX_ADDRESS(USBx, bEpNum,wAddr) (*PCD_EP_RX_ADDRESS((USBx), (bEpNum)) = (((wAddr) >> 1U) << 1U))
+
+/**
+ * @brief Gets address of the tx/rx buffer.
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @retval address of the buffer.
+ */
+#define PCD_GET_EP_TX_ADDRESS(USBx, bEpNum) ((uint16_t)*PCD_EP_TX_ADDRESS((USBx), (bEpNum)))
+#define PCD_GET_EP_RX_ADDRESS(USBx, bEpNum) ((uint16_t)*PCD_EP_RX_ADDRESS((USBx), (bEpNum)))
+
+/**
+ * @brief Sets counter of rx buffer with no. of blocks.
+ * @param dwReg: Register
+ * @param wCount: Counter.
+ * @param wNBlocks: no. of Blocks.
+ * @retval None
+ */
+#define PCD_CALC_BLK32(dwReg,wCount,wNBlocks) {\
+ (wNBlocks) = (wCount) >> 5U;\
+ if(((wCount) & 0x1FU) == 0U)\
+ { \
+ (wNBlocks)--;\
+ } \
+ *pdwReg = (uint16_t)((uint16_t)((wNBlocks) << 10U) | 0x8000U); \
+ }/* PCD_CALC_BLK32 */
+
+#define PCD_CALC_BLK2(dwReg,wCount,wNBlocks) {\
+ (wNBlocks) = (wCount) >> 1U;\
+ if(((wCount) & 0x01U) != 0U)\
+ { \
+ (wNBlocks)++;\
+ } \
+ *pdwReg = (uint16_t)((wNBlocks) << 10U);\
+ }/* PCD_CALC_BLK2 */
+
+#define PCD_SET_EP_CNT_RX_REG(dwReg,wCount) {\
+ uint16_t wNBlocks;\
+ if((wCount) > 62U) \
+ { \
+ PCD_CALC_BLK32((dwReg),(wCount),wNBlocks); \
+ } \
+ else \
+ { \
+ PCD_CALC_BLK2((dwReg),(wCount),wNBlocks); \
+ } \
+ }/* PCD_SET_EP_CNT_RX_REG */
+
+#define PCD_SET_EP_RX_DBUF0_CNT(USBx, bEpNum,wCount) {\
+ uint32_t *pdwReg = PCD_EP_TX_CNT((USBx), (bEpNum)); \
+ PCD_SET_EP_CNT_RX_REG(pdwReg, (wCount));\
+ }
+
+/**
+ * @brief sets counter for the tx/rx buffer.
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @param wCount: Counter value.
+ * @retval None
+ */
+#define PCD_SET_EP_TX_CNT(USBx, bEpNum,wCount) (*PCD_EP_TX_CNT((USBx), (bEpNum)) = (wCount))
+
+
+/**
+ * @brief gets counter of the tx buffer.
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @retval Counter value
+ */
+#define PCD_GET_EP_TX_CNT(USBx, bEpNum) ((uint16_t)(*PCD_EP_TX_CNT((USBx), (bEpNum))) & 0x3FFU)
+#define PCD_GET_EP_RX_CNT(USBx, bEpNum) ((uint16_t)(*PCD_EP_RX_CNT((USBx), (bEpNum))) & 0x3FFU)
+
+/**
+ * @brief Sets buffer 0/1 address in a double buffer endpoint.
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @param wBuf0Addr: buffer 0 address.
+ * @retval Counter value
+ */
+#define PCD_SET_EP_DBUF0_ADDR(USBx, bEpNum,wBuf0Addr) {PCD_SET_EP_TX_ADDRESS((USBx), (bEpNum), (wBuf0Addr));}
+#define PCD_SET_EP_DBUF1_ADDR(USBx, bEpNum,wBuf1Addr) {PCD_SET_EP_RX_ADDRESS((USBx), (bEpNum), (wBuf1Addr));}
+
+/**
+ * @brief Sets addresses in a double buffer endpoint.
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @param wBuf0Addr: buffer 0 address.
+ * @param wBuf1Addr = buffer 1 address.
+ * @retval None
+ */
+#define PCD_SET_EP_DBUF_ADDR(USBx, bEpNum,wBuf0Addr,wBuf1Addr) { \
+ PCD_SET_EP_DBUF0_ADDR((USBx), (bEpNum), (wBuf0Addr));\
+ PCD_SET_EP_DBUF1_ADDR((USBx), (bEpNum), (wBuf1Addr));\
+ } /* PCD_SET_EP_DBUF_ADDR */
+
+/**
+ * @brief Gets buffer 0/1 address of a double buffer endpoint.
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @retval None
+ */
+#define PCD_GET_EP_DBUF0_ADDR(USBx, bEpNum) (PCD_GET_EP_TX_ADDRESS((USBx), (bEpNum)))
+#define PCD_GET_EP_DBUF1_ADDR(USBx, bEpNum) (PCD_GET_EP_RX_ADDRESS((USBx), (bEpNum)))
+
+/**
+ * @brief Gets buffer 0/1 address of a double buffer endpoint.
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @param bDir: endpoint dir EP_DBUF_OUT = OUT
+ * EP_DBUF_IN = IN
+ * @param wCount: Counter value
+ * @retval None
+ */
+#define PCD_SET_EP_DBUF0_CNT(USBx, bEpNum, bDir, wCount) { \
+ if((bDir) == PCD_EP_DBUF_OUT)\
+ /* OUT endpoint */ \
+ {PCD_SET_EP_RX_DBUF0_CNT((USBx), (bEpNum),(wCount));} \
+ else if((bDir) == PCD_EP_DBUF_IN)\
+ /* IN endpoint */ \
+ *PCD_EP_TX_CNT((USBx), (bEpNum)) = (uint32_t)(wCount); \
+ } /* SetEPDblBuf0Count*/
+
+#define PCD_SET_EP_DBUF1_CNT(USBx, bEpNum, bDir, wCount) { \
+ if((bDir) == PCD_EP_DBUF_OUT)\
+ {/* OUT endpoint */ \
+ PCD_SET_EP_RX_CNT((USBx), (bEpNum),(wCount)); \
+ } \
+ else if((bDir) == PCD_EP_DBUF_IN)\
+ {/* IN endpoint */ \
+ *PCD_EP_TX_CNT((USBx), (bEpNum)) = (uint32_t)(wCount); \
+ } \
+ } /* SetEPDblBuf1Count */
+
+#define PCD_SET_EP_DBUF_CNT(USBx, bEpNum, bDir, wCount) {\
+ PCD_SET_EP_DBUF0_CNT((USBx), (bEpNum), (bDir), (wCount)); \
+ PCD_SET_EP_DBUF1_CNT((USBx), (bEpNum), (bDir), (wCount)); \
+ } /* PCD_SET_EP_DBUF_CNT */
+
+/**
+ * @brief Gets buffer 0/1 rx/tx counter for double buffering.
+ * @param USBx: USB peripheral instance register address.
+ * @param bEpNum: Endpoint Number.
+ * @retval None
+ */
+#define PCD_GET_EP_DBUF0_CNT(USBx, bEpNum) (PCD_GET_EP_TX_CNT((USBx), (bEpNum)))
+#define PCD_GET_EP_DBUF1_CNT(USBx, bEpNum) (PCD_GET_EP_RX_CNT((USBx), (bEpNum)))
+
+#endif /* USB */
+
+/** @defgroup PCD_Instance_definition PCD Instance definition
+ * @{
+ */
+#define IS_PCD_ALL_INSTANCE IS_USB_ALL_INSTANCE
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F102x6 || STM32F102xB || */
+ /* STM32F103x6 || STM32F103xB || */
+ /* STM32F103xE || STM32F103xG || */
+ /* STM32F105xC || STM32F107xC */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __STM32F1xx_HAL_PCD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd_ex.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd_ex.h
new file mode 100644
index 0000000..f2ca4b8
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pcd_ex.h
@@ -0,0 +1,114 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_pcd_ex.h
+ * @author MCD Application Team
+ * @brief Header file of Extended PCD HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_PCD_EX_H
+#define __STM32F1xx_HAL_PCD_EX_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#if defined(STM32F102x6) || defined(STM32F102xB) || \
+ defined(STM32F103x6) || defined(STM32F103xB) || \
+ defined(STM32F103xE) || defined(STM32F103xG) || \
+ defined(STM32F105xC) || defined(STM32F107xC)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup PCDEx
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macros -----------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup PCDEx_Exported_Functions PCDEx Exported Functions
+ * @{
+ */
+/** @addtogroup PCDEx_Exported_Functions_Group1 Peripheral Control functions
+ * @{
+ */
+#if defined (USB_OTG_FS)
+HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size);
+HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size);
+#endif /* USB_OTG_FS */
+
+#if defined (USB)
+HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd,
+ uint16_t ep_addr,
+ uint16_t ep_kind,
+ uint32_t pmaadress);
+#endif /* USB */
+/**
+ * @}
+ */
+
+/** @addtogroup PCDEx_Exported_Functions_Group2 Peripheral State functions
+ * @{
+ */
+void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state);
+/**
+ * @}
+ */
+/**
+ * @}
+ */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* STM32F102x6 || STM32F102xB || */
+ /* STM32F103x6 || STM32F103xB || */
+ /* STM32F103xE || STM32F103xG || */
+ /* STM32F105xC || STM32F107xC */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __STM32F1xx_HAL_PCD_EX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h
new file mode 100644
index 0000000..8499c7f
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h
@@ -0,0 +1,404 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_pwr.h
+ * @author MCD Application Team
+ * @brief Header file of PWR HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_PWR_H
+#define __STM32F1xx_HAL_PWR_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup PWR
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/** @defgroup PWR_Exported_Types PWR Exported Types
+ * @{
+ */
+
+/**
+ * @brief PWR PVD configuration structure definition
+ */
+typedef struct
+{
+ uint32_t PVDLevel; /*!< PVDLevel: Specifies the PVD detection level.
+ This parameter can be a value of @ref PWR_PVD_detection_level */
+
+ uint32_t Mode; /*!< Mode: Specifies the operating mode for the selected pins.
+ This parameter can be a value of @ref PWR_PVD_Mode */
+}PWR_PVDTypeDef;
+
+
+/**
+ * @}
+ */
+
+
+/* Internal constants --------------------------------------------------------*/
+
+/** @addtogroup PWR_Private_Constants
+ * @{
+ */
+
+#define PWR_EXTI_LINE_PVD ((uint32_t)0x00010000) /*!< External interrupt line 16 Connected to the PVD EXTI Line */
+
+/**
+ * @}
+ */
+
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup PWR_Exported_Constants PWR Exported Constants
+ * @{
+ */
+
+/** @defgroup PWR_PVD_detection_level PWR PVD detection level
+ * @{
+ */
+#define PWR_PVDLEVEL_0 PWR_CR_PLS_2V2
+#define PWR_PVDLEVEL_1 PWR_CR_PLS_2V3
+#define PWR_PVDLEVEL_2 PWR_CR_PLS_2V4
+#define PWR_PVDLEVEL_3 PWR_CR_PLS_2V5
+#define PWR_PVDLEVEL_4 PWR_CR_PLS_2V6
+#define PWR_PVDLEVEL_5 PWR_CR_PLS_2V7
+#define PWR_PVDLEVEL_6 PWR_CR_PLS_2V8
+#define PWR_PVDLEVEL_7 PWR_CR_PLS_2V9
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_PVD_Mode PWR PVD Mode
+ * @{
+ */
+#define PWR_PVD_MODE_NORMAL 0x00000000U /*!< basic mode is used */
+#define PWR_PVD_MODE_IT_RISING 0x00010001U /*!< External Interrupt Mode with Rising edge trigger detection */
+#define PWR_PVD_MODE_IT_FALLING 0x00010002U /*!< External Interrupt Mode with Falling edge trigger detection */
+#define PWR_PVD_MODE_IT_RISING_FALLING 0x00010003U /*!< External Interrupt Mode with Rising/Falling edge trigger detection */
+#define PWR_PVD_MODE_EVENT_RISING 0x00020001U /*!< Event Mode with Rising edge trigger detection */
+#define PWR_PVD_MODE_EVENT_FALLING 0x00020002U /*!< Event Mode with Falling edge trigger detection */
+#define PWR_PVD_MODE_EVENT_RISING_FALLING 0x00020003U /*!< Event Mode with Rising/Falling edge trigger detection */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup PWR_WakeUp_Pins PWR WakeUp Pins
+ * @{
+ */
+
+#define PWR_WAKEUP_PIN1 PWR_CSR_EWUP
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_Regulator_state_in_SLEEP_STOP_mode PWR Regulator state in SLEEP/STOP mode
+ * @{
+ */
+#define PWR_MAINREGULATOR_ON 0x00000000U
+#define PWR_LOWPOWERREGULATOR_ON PWR_CR_LPDS
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_SLEEP_mode_entry PWR SLEEP mode entry
+ * @{
+ */
+#define PWR_SLEEPENTRY_WFI ((uint8_t)0x01)
+#define PWR_SLEEPENTRY_WFE ((uint8_t)0x02)
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_STOP_mode_entry PWR STOP mode entry
+ * @{
+ */
+#define PWR_STOPENTRY_WFI ((uint8_t)0x01)
+#define PWR_STOPENTRY_WFE ((uint8_t)0x02)
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_Flag PWR Flag
+ * @{
+ */
+#define PWR_FLAG_WU PWR_CSR_WUF
+#define PWR_FLAG_SB PWR_CSR_SBF
+#define PWR_FLAG_PVDO PWR_CSR_PVDO
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup PWR_Exported_Macros PWR Exported Macros
+ * @{
+ */
+
+/** @brief Check PWR flag is set or not.
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg PWR_FLAG_WU: Wake Up flag. This flag indicates that a wakeup event
+ * was received from the WKUP pin or from the RTC alarm
+ * An additional wakeup event is detected if the WKUP pin is enabled
+ * (by setting the EWUP bit) when the WKUP pin level is already high.
+ * @arg PWR_FLAG_SB: StandBy flag. This flag indicates that the system was
+ * resumed from StandBy mode.
+ * @arg PWR_FLAG_PVDO: PVD Output. This flag is valid only if PVD is enabled
+ * by the HAL_PWR_EnablePVD() function. The PVD is stopped by Standby mode
+ * For this reason, this bit is equal to 0 after Standby or reset
+ * until the PVDE bit is set.
+ * @retval The new state of __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_PWR_GET_FLAG(__FLAG__) ((PWR->CSR & (__FLAG__)) == (__FLAG__))
+
+/** @brief Clear the PWR's pending flags.
+ * @param __FLAG__: specifies the flag to clear.
+ * This parameter can be one of the following values:
+ * @arg PWR_FLAG_WU: Wake Up flag
+ * @arg PWR_FLAG_SB: StandBy flag
+ */
+#define __HAL_PWR_CLEAR_FLAG(__FLAG__) SET_BIT(PWR->CR, ((__FLAG__) << 2))
+
+/**
+ * @brief Enable interrupt on PVD Exti Line 16.
+ * @retval None.
+ */
+#define __HAL_PWR_PVD_EXTI_ENABLE_IT() SET_BIT(EXTI->IMR, PWR_EXTI_LINE_PVD)
+
+/**
+ * @brief Disable interrupt on PVD Exti Line 16.
+ * @retval None.
+ */
+#define __HAL_PWR_PVD_EXTI_DISABLE_IT() CLEAR_BIT(EXTI->IMR, PWR_EXTI_LINE_PVD)
+
+/**
+ * @brief Enable event on PVD Exti Line 16.
+ * @retval None.
+ */
+#define __HAL_PWR_PVD_EXTI_ENABLE_EVENT() SET_BIT(EXTI->EMR, PWR_EXTI_LINE_PVD)
+
+/**
+ * @brief Disable event on PVD Exti Line 16.
+ * @retval None.
+ */
+#define __HAL_PWR_PVD_EXTI_DISABLE_EVENT() CLEAR_BIT(EXTI->EMR, PWR_EXTI_LINE_PVD)
+
+
+/**
+ * @brief PVD EXTI line configuration: set falling edge trigger.
+ * @retval None.
+ */
+#define __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE() SET_BIT(EXTI->FTSR, PWR_EXTI_LINE_PVD)
+
+
+/**
+ * @brief Disable the PVD Extended Interrupt Falling Trigger.
+ * @retval None.
+ */
+#define __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE() CLEAR_BIT(EXTI->FTSR, PWR_EXTI_LINE_PVD)
+
+
+/**
+ * @brief PVD EXTI line configuration: set rising edge trigger.
+ * @retval None.
+ */
+#define __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE() SET_BIT(EXTI->RTSR, PWR_EXTI_LINE_PVD)
+
+/**
+ * @brief Disable the PVD Extended Interrupt Rising Trigger.
+ * This parameter can be:
+ * @retval None.
+ */
+#define __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE() CLEAR_BIT(EXTI->RTSR, PWR_EXTI_LINE_PVD)
+
+/**
+ * @brief PVD EXTI line configuration: set rising & falling edge trigger.
+ * @retval None.
+ */
+#define __HAL_PWR_PVD_EXTI_ENABLE_RISING_FALLING_EDGE() __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE();__HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE();
+
+/**
+ * @brief Disable the PVD Extended Interrupt Rising & Falling Trigger.
+ * This parameter can be:
+ * @retval None.
+ */
+#define __HAL_PWR_PVD_EXTI_DISABLE_RISING_FALLING_EDGE() __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();__HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE();
+
+
+
+/**
+ * @brief Check whether the specified PVD EXTI interrupt flag is set or not.
+ * @retval EXTI PVD Line Status.
+ */
+#define __HAL_PWR_PVD_EXTI_GET_FLAG() (EXTI->PR & (PWR_EXTI_LINE_PVD))
+
+/**
+ * @brief Clear the PVD EXTI flag.
+ * @retval None.
+ */
+#define __HAL_PWR_PVD_EXTI_CLEAR_FLAG() (EXTI->PR = (PWR_EXTI_LINE_PVD))
+
+/**
+ * @brief Generate a Software interrupt on selected EXTI line.
+ * @retval None.
+ */
+#define __HAL_PWR_PVD_EXTI_GENERATE_SWIT() SET_BIT(EXTI->SWIER, PWR_EXTI_LINE_PVD)
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/** @defgroup PWR_Private_Macros PWR Private Macros
+ * @{
+ */
+#define IS_PWR_PVD_LEVEL(LEVEL) (((LEVEL) == PWR_PVDLEVEL_0) || ((LEVEL) == PWR_PVDLEVEL_1)|| \
+ ((LEVEL) == PWR_PVDLEVEL_2) || ((LEVEL) == PWR_PVDLEVEL_3)|| \
+ ((LEVEL) == PWR_PVDLEVEL_4) || ((LEVEL) == PWR_PVDLEVEL_5)|| \
+ ((LEVEL) == PWR_PVDLEVEL_6) || ((LEVEL) == PWR_PVDLEVEL_7))
+
+
+#define IS_PWR_PVD_MODE(MODE) (((MODE) == PWR_PVD_MODE_IT_RISING)|| ((MODE) == PWR_PVD_MODE_IT_FALLING) || \
+ ((MODE) == PWR_PVD_MODE_IT_RISING_FALLING) || ((MODE) == PWR_PVD_MODE_EVENT_RISING) || \
+ ((MODE) == PWR_PVD_MODE_EVENT_FALLING) || ((MODE) == PWR_PVD_MODE_EVENT_RISING_FALLING) || \
+ ((MODE) == PWR_PVD_MODE_NORMAL))
+
+#define IS_PWR_WAKEUP_PIN(PIN) (((PIN) == PWR_WAKEUP_PIN1))
+
+#define IS_PWR_REGULATOR(REGULATOR) (((REGULATOR) == PWR_MAINREGULATOR_ON) || \
+ ((REGULATOR) == PWR_LOWPOWERREGULATOR_ON))
+
+#define IS_PWR_SLEEP_ENTRY(ENTRY) (((ENTRY) == PWR_SLEEPENTRY_WFI) || ((ENTRY) == PWR_SLEEPENTRY_WFE))
+
+#define IS_PWR_STOP_ENTRY(ENTRY) (((ENTRY) == PWR_STOPENTRY_WFI) || ((ENTRY) == PWR_STOPENTRY_WFE))
+
+/**
+ * @}
+ */
+
+
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @addtogroup PWR_Exported_Functions PWR Exported Functions
+ * @{
+ */
+
+/** @addtogroup PWR_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @{
+ */
+
+/* Initialization and de-initialization functions *******************************/
+void HAL_PWR_DeInit(void);
+void HAL_PWR_EnableBkUpAccess(void);
+void HAL_PWR_DisableBkUpAccess(void);
+
+/**
+ * @}
+ */
+
+/** @addtogroup PWR_Exported_Functions_Group2 Peripheral Control functions
+ * @{
+ */
+
+/* Peripheral Control functions ************************************************/
+void HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD);
+/* #define HAL_PWR_ConfigPVD 12*/
+void HAL_PWR_EnablePVD(void);
+void HAL_PWR_DisablePVD(void);
+
+/* WakeUp pins configuration functions ****************************************/
+void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinx);
+void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx);
+
+/* Low Power modes configuration functions ************************************/
+void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry);
+void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry);
+void HAL_PWR_EnterSTANDBYMode(void);
+
+void HAL_PWR_EnableSleepOnExit(void);
+void HAL_PWR_DisableSleepOnExit(void);
+void HAL_PWR_EnableSEVOnPend(void);
+void HAL_PWR_DisableSEVOnPend(void);
+
+
+
+void HAL_PWR_PVD_IRQHandler(void);
+void HAL_PWR_PVDCallback(void);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __STM32F1xx_HAL_PWR_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h
new file mode 100644
index 0000000..0e3bdfc
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h
@@ -0,0 +1,1393 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_rcc.h
+ * @author MCD Application Team
+ * @brief Header file of RCC HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_RCC_H
+#define __STM32F1xx_HAL_RCC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup RCC
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/** @defgroup RCC_Exported_Types RCC Exported Types
+ * @{
+ */
+
+/**
+ * @brief RCC PLL configuration structure definition
+ */
+typedef struct
+{
+ uint32_t PLLState; /*!< PLLState: The new state of the PLL.
+ This parameter can be a value of @ref RCC_PLL_Config */
+
+ uint32_t PLLSource; /*!< PLLSource: PLL entry clock source.
+ This parameter must be a value of @ref RCC_PLL_Clock_Source */
+
+ uint32_t PLLMUL; /*!< PLLMUL: Multiplication factor for PLL VCO input clock
+ This parameter must be a value of @ref RCCEx_PLL_Multiplication_Factor */
+} RCC_PLLInitTypeDef;
+
+/**
+ * @brief RCC System, AHB and APB busses clock configuration structure definition
+ */
+typedef struct
+{
+ uint32_t ClockType; /*!< The clock to be configured.
+ This parameter can be a value of @ref RCC_System_Clock_Type */
+
+ uint32_t SYSCLKSource; /*!< The clock source (SYSCLKS) used as system clock.
+ This parameter can be a value of @ref RCC_System_Clock_Source */
+
+ uint32_t AHBCLKDivider; /*!< The AHB clock (HCLK) divider. This clock is derived from the system clock (SYSCLK).
+ This parameter can be a value of @ref RCC_AHB_Clock_Source */
+
+ uint32_t APB1CLKDivider; /*!< The APB1 clock (PCLK1) divider. This clock is derived from the AHB clock (HCLK).
+ This parameter can be a value of @ref RCC_APB1_APB2_Clock_Source */
+
+ uint32_t APB2CLKDivider; /*!< The APB2 clock (PCLK2) divider. This clock is derived from the AHB clock (HCLK).
+ This parameter can be a value of @ref RCC_APB1_APB2_Clock_Source */
+} RCC_ClkInitTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup RCC_Exported_Constants RCC Exported Constants
+ * @{
+ */
+
+/** @defgroup RCC_PLL_Clock_Source PLL Clock Source
+ * @{
+ */
+
+#define RCC_PLLSOURCE_HSI_DIV2 0x00000000U /*!< HSI clock divided by 2 selected as PLL entry clock source */
+#define RCC_PLLSOURCE_HSE RCC_CFGR_PLLSRC /*!< HSE clock selected as PLL entry clock source */
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_Oscillator_Type Oscillator Type
+ * @{
+ */
+#define RCC_OSCILLATORTYPE_NONE 0x00000000U
+#define RCC_OSCILLATORTYPE_HSE 0x00000001U
+#define RCC_OSCILLATORTYPE_HSI 0x00000002U
+#define RCC_OSCILLATORTYPE_LSE 0x00000004U
+#define RCC_OSCILLATORTYPE_LSI 0x00000008U
+/**
+ * @}
+ */
+
+/** @defgroup RCC_HSE_Config HSE Config
+ * @{
+ */
+#define RCC_HSE_OFF 0x00000000U /*!< HSE clock deactivation */
+#define RCC_HSE_ON RCC_CR_HSEON /*!< HSE clock activation */
+#define RCC_HSE_BYPASS ((uint32_t)(RCC_CR_HSEBYP | RCC_CR_HSEON)) /*!< External clock source for HSE clock */
+/**
+ * @}
+ */
+
+/** @defgroup RCC_LSE_Config LSE Config
+ * @{
+ */
+#define RCC_LSE_OFF 0x00000000U /*!< LSE clock deactivation */
+#define RCC_LSE_ON RCC_BDCR_LSEON /*!< LSE clock activation */
+#define RCC_LSE_BYPASS ((uint32_t)(RCC_BDCR_LSEBYP | RCC_BDCR_LSEON)) /*!< External clock source for LSE clock */
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_HSI_Config HSI Config
+ * @{
+ */
+#define RCC_HSI_OFF 0x00000000U /*!< HSI clock deactivation */
+#define RCC_HSI_ON RCC_CR_HSION /*!< HSI clock activation */
+
+#define RCC_HSICALIBRATION_DEFAULT 0x10U /* Default HSI calibration trimming value */
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_LSI_Config LSI Config
+ * @{
+ */
+#define RCC_LSI_OFF 0x00000000U /*!< LSI clock deactivation */
+#define RCC_LSI_ON RCC_CSR_LSION /*!< LSI clock activation */
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_PLL_Config PLL Config
+ * @{
+ */
+#define RCC_PLL_NONE 0x00000000U /*!< PLL is not configured */
+#define RCC_PLL_OFF 0x00000001U /*!< PLL deactivation */
+#define RCC_PLL_ON 0x00000002U /*!< PLL activation */
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_System_Clock_Type System Clock Type
+ * @{
+ */
+#define RCC_CLOCKTYPE_SYSCLK 0x00000001U /*!< SYSCLK to configure */
+#define RCC_CLOCKTYPE_HCLK 0x00000002U /*!< HCLK to configure */
+#define RCC_CLOCKTYPE_PCLK1 0x00000004U /*!< PCLK1 to configure */
+#define RCC_CLOCKTYPE_PCLK2 0x00000008U /*!< PCLK2 to configure */
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_System_Clock_Source System Clock Source
+ * @{
+ */
+#define RCC_SYSCLKSOURCE_HSI RCC_CFGR_SW_HSI /*!< HSI selected as system clock */
+#define RCC_SYSCLKSOURCE_HSE RCC_CFGR_SW_HSE /*!< HSE selected as system clock */
+#define RCC_SYSCLKSOURCE_PLLCLK RCC_CFGR_SW_PLL /*!< PLL selected as system clock */
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_System_Clock_Source_Status System Clock Source Status
+ * @{
+ */
+#define RCC_SYSCLKSOURCE_STATUS_HSI RCC_CFGR_SWS_HSI /*!< HSI used as system clock */
+#define RCC_SYSCLKSOURCE_STATUS_HSE RCC_CFGR_SWS_HSE /*!< HSE used as system clock */
+#define RCC_SYSCLKSOURCE_STATUS_PLLCLK RCC_CFGR_SWS_PLL /*!< PLL used as system clock */
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_AHB_Clock_Source AHB Clock Source
+ * @{
+ */
+#define RCC_SYSCLK_DIV1 RCC_CFGR_HPRE_DIV1 /*!< SYSCLK not divided */
+#define RCC_SYSCLK_DIV2 RCC_CFGR_HPRE_DIV2 /*!< SYSCLK divided by 2 */
+#define RCC_SYSCLK_DIV4 RCC_CFGR_HPRE_DIV4 /*!< SYSCLK divided by 4 */
+#define RCC_SYSCLK_DIV8 RCC_CFGR_HPRE_DIV8 /*!< SYSCLK divided by 8 */
+#define RCC_SYSCLK_DIV16 RCC_CFGR_HPRE_DIV16 /*!< SYSCLK divided by 16 */
+#define RCC_SYSCLK_DIV64 RCC_CFGR_HPRE_DIV64 /*!< SYSCLK divided by 64 */
+#define RCC_SYSCLK_DIV128 RCC_CFGR_HPRE_DIV128 /*!< SYSCLK divided by 128 */
+#define RCC_SYSCLK_DIV256 RCC_CFGR_HPRE_DIV256 /*!< SYSCLK divided by 256 */
+#define RCC_SYSCLK_DIV512 RCC_CFGR_HPRE_DIV512 /*!< SYSCLK divided by 512 */
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_APB1_APB2_Clock_Source APB1 APB2 Clock Source
+ * @{
+ */
+#define RCC_HCLK_DIV1 RCC_CFGR_PPRE1_DIV1 /*!< HCLK not divided */
+#define RCC_HCLK_DIV2 RCC_CFGR_PPRE1_DIV2 /*!< HCLK divided by 2 */
+#define RCC_HCLK_DIV4 RCC_CFGR_PPRE1_DIV4 /*!< HCLK divided by 4 */
+#define RCC_HCLK_DIV8 RCC_CFGR_PPRE1_DIV8 /*!< HCLK divided by 8 */
+#define RCC_HCLK_DIV16 RCC_CFGR_PPRE1_DIV16 /*!< HCLK divided by 16 */
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_RTC_Clock_Source RTC Clock Source
+ * @{
+ */
+#define RCC_RTCCLKSOURCE_NO_CLK 0x00000000U /*!< No clock */
+#define RCC_RTCCLKSOURCE_LSE RCC_BDCR_RTCSEL_LSE /*!< LSE oscillator clock used as RTC clock */
+#define RCC_RTCCLKSOURCE_LSI RCC_BDCR_RTCSEL_LSI /*!< LSI oscillator clock used as RTC clock */
+#define RCC_RTCCLKSOURCE_HSE_DIV128 RCC_BDCR_RTCSEL_HSE /*!< HSE oscillator clock divided by 128 used as RTC clock */
+/**
+ * @}
+ */
+
+
+/** @defgroup RCC_MCO_Index MCO Index
+ * @{
+ */
+#define RCC_MCO1 0x00000000U
+#define RCC_MCO RCC_MCO1 /*!< MCO1 to be compliant with other families with 2 MCOs*/
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_MCOx_Clock_Prescaler MCO Clock Prescaler
+ * @{
+ */
+#define RCC_MCODIV_1 0x00000000U
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_Interrupt Interrupts
+ * @{
+ */
+#define RCC_IT_LSIRDY ((uint8_t)RCC_CIR_LSIRDYF) /*!< LSI Ready Interrupt flag */
+#define RCC_IT_LSERDY ((uint8_t)RCC_CIR_LSERDYF) /*!< LSE Ready Interrupt flag */
+#define RCC_IT_HSIRDY ((uint8_t)RCC_CIR_HSIRDYF) /*!< HSI Ready Interrupt flag */
+#define RCC_IT_HSERDY ((uint8_t)RCC_CIR_HSERDYF) /*!< HSE Ready Interrupt flag */
+#define RCC_IT_PLLRDY ((uint8_t)RCC_CIR_PLLRDYF) /*!< PLL Ready Interrupt flag */
+#define RCC_IT_CSS ((uint8_t)RCC_CIR_CSSF) /*!< Clock Security System Interrupt flag */
+/**
+ * @}
+ */
+
+/** @defgroup RCC_Flag Flags
+ * Elements values convention: XXXYYYYYb
+ * - YYYYY : Flag position in the register
+ * - XXX : Register index
+ * - 001: CR register
+ * - 010: BDCR register
+ * - 011: CSR register
+ * @{
+ */
+/* Flags in the CR register */
+#define RCC_FLAG_HSIRDY ((uint8_t)((CR_REG_INDEX << 5U) | RCC_CR_HSIRDY_Pos)) /*!< Internal High Speed clock ready flag */
+#define RCC_FLAG_HSERDY ((uint8_t)((CR_REG_INDEX << 5U) | RCC_CR_HSERDY_Pos)) /*!< External High Speed clock ready flag */
+#define RCC_FLAG_PLLRDY ((uint8_t)((CR_REG_INDEX << 5U) | RCC_CR_PLLRDY_Pos)) /*!< PLL clock ready flag */
+
+/* Flags in the CSR register */
+#define RCC_FLAG_LSIRDY ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_LSIRDY_Pos)) /*!< Internal Low Speed oscillator Ready */
+#define RCC_FLAG_PINRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_PINRSTF_Pos)) /*!< PIN reset flag */
+#define RCC_FLAG_PORRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_PORRSTF_Pos)) /*!< POR/PDR reset flag */
+#define RCC_FLAG_SFTRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_SFTRSTF_Pos)) /*!< Software Reset flag */
+#define RCC_FLAG_IWDGRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_IWDGRSTF_Pos)) /*!< Independent Watchdog reset flag */
+#define RCC_FLAG_WWDGRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_WWDGRSTF_Pos)) /*!< Window watchdog reset flag */
+#define RCC_FLAG_LPWRRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_LPWRRSTF_Pos)) /*!< Low-Power reset flag */
+
+/* Flags in the BDCR register */
+#define RCC_FLAG_LSERDY ((uint8_t)((BDCR_REG_INDEX << 5U) | RCC_BDCR_LSERDY_Pos)) /*!< External Low Speed oscillator Ready */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+
+/** @defgroup RCC_Exported_Macros RCC Exported Macros
+ * @{
+ */
+
+/** @defgroup RCC_Peripheral_Clock_Enable_Disable Peripheral Clock Enable Disable
+ * @brief Enable or disable the AHB1 peripheral clock.
+ * @note After reset, the peripheral clock (used for registers read/write access)
+ * is disabled and the application software has to enable this clock before
+ * using it.
+ * @{
+ */
+#define __HAL_RCC_DMA1_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->AHBENR, RCC_AHBENR_DMA1EN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_DMA1EN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_SRAM_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->AHBENR, RCC_AHBENR_SRAMEN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_SRAMEN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_FLITF_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->AHBENR, RCC_AHBENR_FLITFEN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FLITFEN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_CRC_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->AHBENR, RCC_AHBENR_CRCEN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_CRCEN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_DMA1_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_DMA1EN))
+#define __HAL_RCC_SRAM_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_SRAMEN))
+#define __HAL_RCC_FLITF_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_FLITFEN))
+#define __HAL_RCC_CRC_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_CRCEN))
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_AHB_Peripheral_Clock_Enable_Disable_Status AHB Peripheral Clock Enable Disable Status
+ * @brief Get the enable or disable status of the AHB peripheral clock.
+ * @note After reset, the peripheral clock (used for registers read/write access)
+ * is disabled and the application software has to enable this clock before
+ * using it.
+ * @{
+ */
+
+#define __HAL_RCC_DMA1_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_DMA1EN)) != RESET)
+#define __HAL_RCC_DMA1_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_DMA1EN)) == RESET)
+#define __HAL_RCC_SRAM_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_SRAMEN)) != RESET)
+#define __HAL_RCC_SRAM_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_SRAMEN)) == RESET)
+#define __HAL_RCC_FLITF_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_FLITFEN)) != RESET)
+#define __HAL_RCC_FLITF_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_FLITFEN)) == RESET)
+#define __HAL_RCC_CRC_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_CRCEN)) != RESET)
+#define __HAL_RCC_CRC_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_CRCEN)) == RESET)
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_APB1_Clock_Enable_Disable APB1 Clock Enable Disable
+ * @brief Enable or disable the Low Speed APB (APB1) peripheral clock.
+ * @note After reset, the peripheral clock (used for registers read/write access)
+ * is disabled and the application software has to enable this clock before
+ * using it.
+ * @{
+ */
+#define __HAL_RCC_TIM2_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_TIM3_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM3EN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM3EN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_WWDG_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->APB1ENR, RCC_APB1ENR_WWDGEN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_WWDGEN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_USART2_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_I2C1_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_BKP_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->APB1ENR, RCC_APB1ENR_BKPEN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_BKPEN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_PWR_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_TIM2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM2EN))
+#define __HAL_RCC_TIM3_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM3EN))
+#define __HAL_RCC_WWDG_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_WWDGEN))
+#define __HAL_RCC_USART2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_USART2EN))
+#define __HAL_RCC_I2C1_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_I2C1EN))
+
+#define __HAL_RCC_BKP_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_BKPEN))
+#define __HAL_RCC_PWR_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_PWREN))
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_APB1_Peripheral_Clock_Enable_Disable_Status APB1 Peripheral Clock Enable Disable Status
+ * @brief Get the enable or disable status of the APB1 peripheral clock.
+ * @note After reset, the peripheral clock (used for registers read/write access)
+ * is disabled and the application software has to enable this clock before
+ * using it.
+ * @{
+ */
+
+#define __HAL_RCC_TIM2_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM2EN)) != RESET)
+#define __HAL_RCC_TIM2_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM2EN)) == RESET)
+#define __HAL_RCC_TIM3_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM3EN)) != RESET)
+#define __HAL_RCC_TIM3_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM3EN)) == RESET)
+#define __HAL_RCC_WWDG_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_WWDGEN)) != RESET)
+#define __HAL_RCC_WWDG_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_WWDGEN)) == RESET)
+#define __HAL_RCC_USART2_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_USART2EN)) != RESET)
+#define __HAL_RCC_USART2_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_USART2EN)) == RESET)
+#define __HAL_RCC_I2C1_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_I2C1EN)) != RESET)
+#define __HAL_RCC_I2C1_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_I2C1EN)) == RESET)
+#define __HAL_RCC_BKP_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_BKPEN)) != RESET)
+#define __HAL_RCC_BKP_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_BKPEN)) == RESET)
+#define __HAL_RCC_PWR_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_PWREN)) != RESET)
+#define __HAL_RCC_PWR_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_PWREN)) == RESET)
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_APB2_Clock_Enable_Disable APB2 Clock Enable Disable
+ * @brief Enable or disable the High Speed APB (APB2) peripheral clock.
+ * @note After reset, the peripheral clock (used for registers read/write access)
+ * is disabled and the application software has to enable this clock before
+ * using it.
+ * @{
+ */
+#define __HAL_RCC_AFIO_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->APB2ENR, RCC_APB2ENR_AFIOEN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_AFIOEN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_GPIOA_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_GPIOB_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPBEN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPBEN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_GPIOC_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPCEN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPCEN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_GPIOD_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_ADC1_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_TIM1_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_SPI1_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_USART1_CLK_ENABLE() do { \
+ __IO uint32_t tmpreg; \
+ SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN);\
+ /* Delay after an RCC peripheral clock enabling */\
+ tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN);\
+ UNUSED(tmpreg); \
+ } while(0U)
+
+#define __HAL_RCC_AFIO_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_AFIOEN))
+#define __HAL_RCC_GPIOA_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_IOPAEN))
+#define __HAL_RCC_GPIOB_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_IOPBEN))
+#define __HAL_RCC_GPIOC_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_IOPCEN))
+#define __HAL_RCC_GPIOD_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_IOPDEN))
+#define __HAL_RCC_ADC1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN))
+
+#define __HAL_RCC_TIM1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_TIM1EN))
+#define __HAL_RCC_SPI1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_SPI1EN))
+#define __HAL_RCC_USART1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_USART1EN))
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_APB2_Peripheral_Clock_Enable_Disable_Status APB2 Peripheral Clock Enable Disable Status
+ * @brief Get the enable or disable status of the APB2 peripheral clock.
+ * @note After reset, the peripheral clock (used for registers read/write access)
+ * is disabled and the application software has to enable this clock before
+ * using it.
+ * @{
+ */
+
+#define __HAL_RCC_AFIO_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_AFIOEN)) != RESET)
+#define __HAL_RCC_AFIO_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_AFIOEN)) == RESET)
+#define __HAL_RCC_GPIOA_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_IOPAEN)) != RESET)
+#define __HAL_RCC_GPIOA_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_IOPAEN)) == RESET)
+#define __HAL_RCC_GPIOB_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_IOPBEN)) != RESET)
+#define __HAL_RCC_GPIOB_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_IOPBEN)) == RESET)
+#define __HAL_RCC_GPIOC_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_IOPCEN)) != RESET)
+#define __HAL_RCC_GPIOC_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_IOPCEN)) == RESET)
+#define __HAL_RCC_GPIOD_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_IOPDEN)) != RESET)
+#define __HAL_RCC_GPIOD_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_IOPDEN)) == RESET)
+#define __HAL_RCC_ADC1_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_ADC1EN)) != RESET)
+#define __HAL_RCC_ADC1_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_ADC1EN)) == RESET)
+#define __HAL_RCC_TIM1_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_TIM1EN)) != RESET)
+#define __HAL_RCC_TIM1_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_TIM1EN)) == RESET)
+#define __HAL_RCC_SPI1_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_SPI1EN)) != RESET)
+#define __HAL_RCC_SPI1_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_SPI1EN)) == RESET)
+#define __HAL_RCC_USART1_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_USART1EN)) != RESET)
+#define __HAL_RCC_USART1_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_USART1EN)) == RESET)
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_APB1_Force_Release_Reset APB1 Force Release Reset
+ * @brief Force or release APB1 peripheral reset.
+ * @{
+ */
+#define __HAL_RCC_APB1_FORCE_RESET() (RCC->APB2RSTR = 0xFFFFFFFFU)
+#define __HAL_RCC_TIM2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM2RST))
+#define __HAL_RCC_TIM3_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM3RST))
+#define __HAL_RCC_WWDG_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_WWDGRST))
+#define __HAL_RCC_USART2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_USART2RST))
+#define __HAL_RCC_I2C1_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_I2C1RST))
+
+#define __HAL_RCC_BKP_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_BKPRST))
+#define __HAL_RCC_PWR_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_PWRRST))
+
+#define __HAL_RCC_APB1_RELEASE_RESET() (RCC->APB1RSTR = 0x00)
+#define __HAL_RCC_TIM2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM2RST))
+#define __HAL_RCC_TIM3_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM3RST))
+#define __HAL_RCC_WWDG_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_WWDGRST))
+#define __HAL_RCC_USART2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_USART2RST))
+#define __HAL_RCC_I2C1_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_I2C1RST))
+
+#define __HAL_RCC_BKP_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_BKPRST))
+#define __HAL_RCC_PWR_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_PWRRST))
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_APB2_Force_Release_Reset APB2 Force Release Reset
+ * @brief Force or release APB2 peripheral reset.
+ * @{
+ */
+#define __HAL_RCC_APB2_FORCE_RESET() (RCC->APB2RSTR = 0xFFFFFFFFU)
+#define __HAL_RCC_AFIO_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_AFIORST))
+#define __HAL_RCC_GPIOA_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_IOPARST))
+#define __HAL_RCC_GPIOB_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_IOPBRST))
+#define __HAL_RCC_GPIOC_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_IOPCRST))
+#define __HAL_RCC_GPIOD_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_IOPDRST))
+#define __HAL_RCC_ADC1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_ADC1RST))
+
+#define __HAL_RCC_TIM1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_TIM1RST))
+#define __HAL_RCC_SPI1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_SPI1RST))
+#define __HAL_RCC_USART1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_USART1RST))
+
+#define __HAL_RCC_APB2_RELEASE_RESET() (RCC->APB2RSTR = 0x00)
+#define __HAL_RCC_AFIO_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_AFIORST))
+#define __HAL_RCC_GPIOA_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_IOPARST))
+#define __HAL_RCC_GPIOB_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_IOPBRST))
+#define __HAL_RCC_GPIOC_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_IOPCRST))
+#define __HAL_RCC_GPIOD_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_IOPDRST))
+#define __HAL_RCC_ADC1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_ADC1RST))
+
+#define __HAL_RCC_TIM1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_TIM1RST))
+#define __HAL_RCC_SPI1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_SPI1RST))
+#define __HAL_RCC_USART1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_USART1RST))
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_HSI_Configuration HSI Configuration
+ * @{
+ */
+
+/** @brief Macros to enable or disable the Internal High Speed oscillator (HSI).
+ * @note The HSI is stopped by hardware when entering STOP and STANDBY modes.
+ * @note HSI can not be stopped if it is used as system clock source. In this case,
+ * you have to select another source of the system clock then stop the HSI.
+ * @note After enabling the HSI, the application software should wait on HSIRDY
+ * flag to be set indicating that HSI clock is stable and can be used as
+ * system clock source.
+ * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator
+ * clock cycles.
+ */
+#define __HAL_RCC_HSI_ENABLE() (*(__IO uint32_t *) RCC_CR_HSION_BB = ENABLE)
+#define __HAL_RCC_HSI_DISABLE() (*(__IO uint32_t *) RCC_CR_HSION_BB = DISABLE)
+
+/** @brief Macro to adjust the Internal High Speed oscillator (HSI) calibration value.
+ * @note The calibration is used to compensate for the variations in voltage
+ * and temperature that influence the frequency of the internal HSI RC.
+ * @param _HSICALIBRATIONVALUE_ specifies the calibration trimming value.
+ * (default is RCC_HSICALIBRATION_DEFAULT).
+ * This parameter must be a number between 0 and 0x1F.
+ */
+#define __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(_HSICALIBRATIONVALUE_) \
+ (MODIFY_REG(RCC->CR, RCC_CR_HSITRIM, (uint32_t)(_HSICALIBRATIONVALUE_) << RCC_CR_HSITRIM_Pos))
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_LSI_Configuration LSI Configuration
+ * @{
+ */
+
+/** @brief Macro to enable the Internal Low Speed oscillator (LSI).
+ * @note After enabling the LSI, the application software should wait on
+ * LSIRDY flag to be set indicating that LSI clock is stable and can
+ * be used to clock the IWDG and/or the RTC.
+ */
+#define __HAL_RCC_LSI_ENABLE() (*(__IO uint32_t *) RCC_CSR_LSION_BB = ENABLE)
+
+/** @brief Macro to disable the Internal Low Speed oscillator (LSI).
+ * @note LSI can not be disabled if the IWDG is running.
+ * @note When the LSI is stopped, LSIRDY flag goes low after 6 LSI oscillator
+ * clock cycles.
+ */
+#define __HAL_RCC_LSI_DISABLE() (*(__IO uint32_t *) RCC_CSR_LSION_BB = DISABLE)
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_HSE_Configuration HSE Configuration
+ * @{
+ */
+
+/**
+ * @brief Macro to configure the External High Speed oscillator (HSE).
+ * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
+ * supported by this macro. User should request a transition to HSE Off
+ * first and then HSE On or HSE Bypass.
+ * @note After enabling the HSE (RCC_HSE_ON or RCC_HSE_Bypass), the application
+ * software should wait on HSERDY flag to be set indicating that HSE clock
+ * is stable and can be used to clock the PLL and/or system clock.
+ * @note HSE state can not be changed if it is used directly or through the
+ * PLL as system clock. In this case, you have to select another source
+ * of the system clock then change the HSE state (ex. disable it).
+ * @note The HSE is stopped by hardware when entering STOP and STANDBY modes.
+ * @note This function reset the CSSON bit, so if the clock security system(CSS)
+ * was previously enabled you have to enable it again after calling this
+ * function.
+ * @param __STATE__ specifies the new state of the HSE.
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_HSE_OFF turn OFF the HSE oscillator, HSERDY flag goes low after
+ * 6 HSE oscillator clock cycles.
+ * @arg @ref RCC_HSE_ON turn ON the HSE oscillator
+ * @arg @ref RCC_HSE_BYPASS HSE oscillator bypassed with external clock
+ */
+#define __HAL_RCC_HSE_CONFIG(__STATE__) \
+ do{ \
+ if ((__STATE__) == RCC_HSE_ON) \
+ { \
+ SET_BIT(RCC->CR, RCC_CR_HSEON); \
+ } \
+ else if ((__STATE__) == RCC_HSE_OFF) \
+ { \
+ CLEAR_BIT(RCC->CR, RCC_CR_HSEON); \
+ CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); \
+ } \
+ else if ((__STATE__) == RCC_HSE_BYPASS) \
+ { \
+ SET_BIT(RCC->CR, RCC_CR_HSEBYP); \
+ SET_BIT(RCC->CR, RCC_CR_HSEON); \
+ } \
+ else \
+ { \
+ CLEAR_BIT(RCC->CR, RCC_CR_HSEON); \
+ CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); \
+ } \
+ }while(0U)
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_LSE_Configuration LSE Configuration
+ * @{
+ */
+
+/**
+ * @brief Macro to configure the External Low Speed oscillator (LSE).
+ * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not supported by this macro.
+ * @note As the LSE is in the Backup domain and write access is denied to
+ * this domain after reset, you have to enable write access using
+ * @ref HAL_PWR_EnableBkUpAccess() function before to configure the LSE
+ * (to be done once after reset).
+ * @note After enabling the LSE (RCC_LSE_ON or RCC_LSE_BYPASS), the application
+ * software should wait on LSERDY flag to be set indicating that LSE clock
+ * is stable and can be used to clock the RTC.
+ * @param __STATE__ specifies the new state of the LSE.
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_LSE_OFF turn OFF the LSE oscillator, LSERDY flag goes low after
+ * 6 LSE oscillator clock cycles.
+ * @arg @ref RCC_LSE_ON turn ON the LSE oscillator.
+ * @arg @ref RCC_LSE_BYPASS LSE oscillator bypassed with external clock.
+ */
+#define __HAL_RCC_LSE_CONFIG(__STATE__) \
+ do{ \
+ if ((__STATE__) == RCC_LSE_ON) \
+ { \
+ SET_BIT(RCC->BDCR, RCC_BDCR_LSEON); \
+ } \
+ else if ((__STATE__) == RCC_LSE_OFF) \
+ { \
+ CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON); \
+ CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); \
+ } \
+ else if ((__STATE__) == RCC_LSE_BYPASS) \
+ { \
+ SET_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); \
+ SET_BIT(RCC->BDCR, RCC_BDCR_LSEON); \
+ } \
+ else \
+ { \
+ CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON); \
+ CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); \
+ } \
+ }while(0U)
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_PLL_Configuration PLL Configuration
+ * @{
+ */
+
+/** @brief Macro to enable the main PLL.
+ * @note After enabling the main PLL, the application software should wait on
+ * PLLRDY flag to be set indicating that PLL clock is stable and can
+ * be used as system clock source.
+ * @note The main PLL is disabled by hardware when entering STOP and STANDBY modes.
+ */
+#define __HAL_RCC_PLL_ENABLE() (*(__IO uint32_t *) RCC_CR_PLLON_BB = ENABLE)
+
+/** @brief Macro to disable the main PLL.
+ * @note The main PLL can not be disabled if it is used as system clock source
+ */
+#define __HAL_RCC_PLL_DISABLE() (*(__IO uint32_t *) RCC_CR_PLLON_BB = DISABLE)
+
+/** @brief Macro to configure the main PLL clock source and multiplication factors.
+ * @note This function must be used only when the main PLL is disabled.
+ *
+ * @param __RCC_PLLSOURCE__ specifies the PLL entry clock source.
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_PLLSOURCE_HSI_DIV2 HSI oscillator clock selected as PLL clock entry
+ * @arg @ref RCC_PLLSOURCE_HSE HSE oscillator clock selected as PLL clock entry
+ * @param __PLLMUL__ specifies the multiplication factor for PLL VCO output clock
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_PLL_MUL4 PLLVCO = PLL clock entry x 4
+ * @arg @ref RCC_PLL_MUL6 PLLVCO = PLL clock entry x 6
+ @if STM32F105xC
+ * @arg @ref RCC_PLL_MUL6_5 PLLVCO = PLL clock entry x 6.5
+ @elseif STM32F107xC
+ * @arg @ref RCC_PLL_MUL6_5 PLLVCO = PLL clock entry x 6.5
+ @else
+ * @arg @ref RCC_PLL_MUL2 PLLVCO = PLL clock entry x 2
+ * @arg @ref RCC_PLL_MUL3 PLLVCO = PLL clock entry x 3
+ * @arg @ref RCC_PLL_MUL10 PLLVCO = PLL clock entry x 10
+ * @arg @ref RCC_PLL_MUL11 PLLVCO = PLL clock entry x 11
+ * @arg @ref RCC_PLL_MUL12 PLLVCO = PLL clock entry x 12
+ * @arg @ref RCC_PLL_MUL13 PLLVCO = PLL clock entry x 13
+ * @arg @ref RCC_PLL_MUL14 PLLVCO = PLL clock entry x 14
+ * @arg @ref RCC_PLL_MUL15 PLLVCO = PLL clock entry x 15
+ * @arg @ref RCC_PLL_MUL16 PLLVCO = PLL clock entry x 16
+ @endif
+ * @arg @ref RCC_PLL_MUL8 PLLVCO = PLL clock entry x 8
+ * @arg @ref RCC_PLL_MUL9 PLLVCO = PLL clock entry x 9
+ *
+ */
+#define __HAL_RCC_PLL_CONFIG(__RCC_PLLSOURCE__, __PLLMUL__)\
+ MODIFY_REG(RCC->CFGR, (RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL),((__RCC_PLLSOURCE__) | (__PLLMUL__) ))
+
+/** @brief Get oscillator clock selected as PLL input clock
+ * @retval The clock source used for PLL entry. The returned value can be one
+ * of the following:
+ * @arg @ref RCC_PLLSOURCE_HSI_DIV2 HSI oscillator clock selected as PLL input clock
+ * @arg @ref RCC_PLLSOURCE_HSE HSE oscillator clock selected as PLL input clock
+ */
+#define __HAL_RCC_GET_PLL_OSCSOURCE() ((uint32_t)(READ_BIT(RCC->CFGR, RCC_CFGR_PLLSRC)))
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_Get_Clock_source Get Clock source
+ * @{
+ */
+
+/**
+ * @brief Macro to configure the system clock source.
+ * @param __SYSCLKSOURCE__ specifies the system clock source.
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_SYSCLKSOURCE_HSI HSI oscillator is used as system clock source.
+ * @arg @ref RCC_SYSCLKSOURCE_HSE HSE oscillator is used as system clock source.
+ * @arg @ref RCC_SYSCLKSOURCE_PLLCLK PLL output is used as system clock source.
+ */
+#define __HAL_RCC_SYSCLK_CONFIG(__SYSCLKSOURCE__) \
+ MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, (__SYSCLKSOURCE__))
+
+/** @brief Macro to get the clock source used as system clock.
+ * @retval The clock source used as system clock. The returned value can be one
+ * of the following:
+ * @arg @ref RCC_SYSCLKSOURCE_STATUS_HSI HSI used as system clock
+ * @arg @ref RCC_SYSCLKSOURCE_STATUS_HSE HSE used as system clock
+ * @arg @ref RCC_SYSCLKSOURCE_STATUS_PLLCLK PLL used as system clock
+ */
+#define __HAL_RCC_GET_SYSCLK_SOURCE() ((uint32_t)(READ_BIT(RCC->CFGR,RCC_CFGR_SWS)))
+
+/**
+ * @}
+ */
+
+/** @defgroup RCCEx_MCOx_Clock_Config RCC Extended MCOx Clock Config
+ * @{
+ */
+
+#if defined(RCC_CFGR_MCO_3)
+/** @brief Macro to configure the MCO clock.
+ * @param __MCOCLKSOURCE__ specifies the MCO clock source.
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected as MCO clock
+ * @arg @ref RCC_MCO1SOURCE_SYSCLK System clock (SYSCLK) selected as MCO clock
+ * @arg @ref RCC_MCO1SOURCE_HSI HSI selected as MCO clock
+ * @arg @ref RCC_MCO1SOURCE_HSE HSE selected as MCO clock
+ * @arg @ref RCC_MCO1SOURCE_PLLCLK PLL clock divided by 2 selected as MCO clock
+ * @arg @ref RCC_MCO1SOURCE_PLL2CLK PLL2 clock selected by 2 selected as MCO clock
+ * @arg @ref RCC_MCO1SOURCE_PLL3CLK_DIV2 PLL3 clock divided by 2 selected as MCO clock
+ * @arg @ref RCC_MCO1SOURCE_EXT_HSE XT1 external 3-25 MHz oscillator clock selected (for Ethernet) as MCO clock
+ * @arg @ref RCC_MCO1SOURCE_PLL3CLK PLL3 clock selected (for Ethernet) as MCO clock
+ * @param __MCODIV__ specifies the MCO clock prescaler.
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_MCODIV_1 No division applied on MCO clock source
+ */
+#else
+/** @brief Macro to configure the MCO clock.
+ * @param __MCOCLKSOURCE__ specifies the MCO clock source.
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected as MCO clock
+ * @arg @ref RCC_MCO1SOURCE_SYSCLK System clock (SYSCLK) selected as MCO clock
+ * @arg @ref RCC_MCO1SOURCE_HSI HSI selected as MCO clock
+ * @arg @ref RCC_MCO1SOURCE_HSE HSE selected as MCO clock
+ * @arg @ref RCC_MCO1SOURCE_PLLCLK PLL clock divided by 2 selected as MCO clock
+ * @param __MCODIV__ specifies the MCO clock prescaler.
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_MCODIV_1 No division applied on MCO clock source
+ */
+#endif
+
+#define __HAL_RCC_MCO1_CONFIG(__MCOCLKSOURCE__, __MCODIV__) \
+ MODIFY_REG(RCC->CFGR, RCC_CFGR_MCO, (__MCOCLKSOURCE__))
+
+
+/**
+ * @}
+ */
+
+ /** @defgroup RCC_RTC_Clock_Configuration RCC RTC Clock Configuration
+ * @{
+ */
+
+/** @brief Macro to configure the RTC clock (RTCCLK).
+ * @note As the RTC clock configuration bits are in the Backup domain and write
+ * access is denied to this domain after reset, you have to enable write
+ * access using the Power Backup Access macro before to configure
+ * the RTC clock source (to be done once after reset).
+ * @note Once the RTC clock is configured it can't be changed unless the
+ * Backup domain is reset using @ref __HAL_RCC_BACKUPRESET_FORCE() macro, or by
+ * a Power On Reset (POR).
+ *
+ * @param __RTC_CLKSOURCE__ specifies the RTC clock source.
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_RTCCLKSOURCE_NO_CLK No clock selected as RTC clock
+ * @arg @ref RCC_RTCCLKSOURCE_LSE LSE selected as RTC clock
+ * @arg @ref RCC_RTCCLKSOURCE_LSI LSI selected as RTC clock
+ * @arg @ref RCC_RTCCLKSOURCE_HSE_DIV128 HSE divided by 128 selected as RTC clock
+ * @note If the LSE or LSI is used as RTC clock source, the RTC continues to
+ * work in STOP and STANDBY modes, and can be used as wakeup source.
+ * However, when the HSE clock is used as RTC clock source, the RTC
+ * cannot be used in STOP and STANDBY modes.
+ * @note The maximum input clock frequency for RTC is 1MHz (when using HSE as
+ * RTC clock source).
+ */
+#define __HAL_RCC_RTC_CONFIG(__RTC_CLKSOURCE__) MODIFY_REG(RCC->BDCR, RCC_BDCR_RTCSEL, (__RTC_CLKSOURCE__))
+
+/** @brief Macro to get the RTC clock source.
+ * @retval The clock source can be one of the following values:
+ * @arg @ref RCC_RTCCLKSOURCE_NO_CLK No clock selected as RTC clock
+ * @arg @ref RCC_RTCCLKSOURCE_LSE LSE selected as RTC clock
+ * @arg @ref RCC_RTCCLKSOURCE_LSI LSI selected as RTC clock
+ * @arg @ref RCC_RTCCLKSOURCE_HSE_DIV128 HSE divided by 128 selected as RTC clock
+ */
+#define __HAL_RCC_GET_RTC_SOURCE() (READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL))
+
+/** @brief Macro to enable the the RTC clock.
+ * @note These macros must be used only after the RTC clock source was selected.
+ */
+#define __HAL_RCC_RTC_ENABLE() (*(__IO uint32_t *) RCC_BDCR_RTCEN_BB = ENABLE)
+
+/** @brief Macro to disable the the RTC clock.
+ * @note These macros must be used only after the RTC clock source was selected.
+ */
+#define __HAL_RCC_RTC_DISABLE() (*(__IO uint32_t *) RCC_BDCR_RTCEN_BB = DISABLE)
+
+/** @brief Macro to force the Backup domain reset.
+ * @note This function resets the RTC peripheral (including the backup registers)
+ * and the RTC clock source selection in RCC_BDCR register.
+ */
+#define __HAL_RCC_BACKUPRESET_FORCE() (*(__IO uint32_t *) RCC_BDCR_BDRST_BB = ENABLE)
+
+/** @brief Macros to release the Backup domain reset.
+ */
+#define __HAL_RCC_BACKUPRESET_RELEASE() (*(__IO uint32_t *) RCC_BDCR_BDRST_BB = DISABLE)
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_Flags_Interrupts_Management Flags Interrupts Management
+ * @brief macros to manage the specified RCC Flags and interrupts.
+ * @{
+ */
+
+/** @brief Enable RCC interrupt.
+ * @param __INTERRUPT__ specifies the RCC interrupt sources to be enabled.
+ * This parameter can be any combination of the following values:
+ * @arg @ref RCC_IT_LSIRDY LSI ready interrupt
+ * @arg @ref RCC_IT_LSERDY LSE ready interrupt
+ * @arg @ref RCC_IT_HSIRDY HSI ready interrupt
+ * @arg @ref RCC_IT_HSERDY HSE ready interrupt
+ * @arg @ref RCC_IT_PLLRDY main PLL ready interrupt
+ @if STM32F105xx
+ * @arg @ref RCC_IT_PLL2RDY Main PLL2 ready interrupt.
+ * @arg @ref RCC_IT_PLLI2S2RDY Main PLLI2S ready interrupt.
+ @elsif STM32F107xx
+ * @arg @ref RCC_IT_PLL2RDY Main PLL2 ready interrupt.
+ * @arg @ref RCC_IT_PLLI2S2RDY Main PLLI2S ready interrupt.
+ @endif
+ */
+#define __HAL_RCC_ENABLE_IT(__INTERRUPT__) (*(__IO uint8_t *) RCC_CIR_BYTE1_ADDRESS |= (__INTERRUPT__))
+
+/** @brief Disable RCC interrupt.
+ * @param __INTERRUPT__ specifies the RCC interrupt sources to be disabled.
+ * This parameter can be any combination of the following values:
+ * @arg @ref RCC_IT_LSIRDY LSI ready interrupt
+ * @arg @ref RCC_IT_LSERDY LSE ready interrupt
+ * @arg @ref RCC_IT_HSIRDY HSI ready interrupt
+ * @arg @ref RCC_IT_HSERDY HSE ready interrupt
+ * @arg @ref RCC_IT_PLLRDY main PLL ready interrupt
+ @if STM32F105xx
+ * @arg @ref RCC_IT_PLL2RDY Main PLL2 ready interrupt.
+ * @arg @ref RCC_IT_PLLI2S2RDY Main PLLI2S ready interrupt.
+ @elsif STM32F107xx
+ * @arg @ref RCC_IT_PLL2RDY Main PLL2 ready interrupt.
+ * @arg @ref RCC_IT_PLLI2S2RDY Main PLLI2S ready interrupt.
+ @endif
+ */
+#define __HAL_RCC_DISABLE_IT(__INTERRUPT__) (*(__IO uint8_t *) RCC_CIR_BYTE1_ADDRESS &= (uint8_t)(~(__INTERRUPT__)))
+
+/** @brief Clear the RCC's interrupt pending bits.
+ * @param __INTERRUPT__ specifies the interrupt pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg @ref RCC_IT_LSIRDY LSI ready interrupt.
+ * @arg @ref RCC_IT_LSERDY LSE ready interrupt.
+ * @arg @ref RCC_IT_HSIRDY HSI ready interrupt.
+ * @arg @ref RCC_IT_HSERDY HSE ready interrupt.
+ * @arg @ref RCC_IT_PLLRDY Main PLL ready interrupt.
+ @if STM32F105xx
+ * @arg @ref RCC_IT_PLL2RDY Main PLL2 ready interrupt.
+ * @arg @ref RCC_IT_PLLI2S2RDY Main PLLI2S ready interrupt.
+ @elsif STM32F107xx
+ * @arg @ref RCC_IT_PLL2RDY Main PLL2 ready interrupt.
+ * @arg @ref RCC_IT_PLLI2S2RDY Main PLLI2S ready interrupt.
+ @endif
+ * @arg @ref RCC_IT_CSS Clock Security System interrupt
+ */
+#define __HAL_RCC_CLEAR_IT(__INTERRUPT__) (*(__IO uint8_t *) RCC_CIR_BYTE2_ADDRESS = (__INTERRUPT__))
+
+/** @brief Check the RCC's interrupt has occurred or not.
+ * @param __INTERRUPT__ specifies the RCC interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_IT_LSIRDY LSI ready interrupt.
+ * @arg @ref RCC_IT_LSERDY LSE ready interrupt.
+ * @arg @ref RCC_IT_HSIRDY HSI ready interrupt.
+ * @arg @ref RCC_IT_HSERDY HSE ready interrupt.
+ * @arg @ref RCC_IT_PLLRDY Main PLL ready interrupt.
+ @if STM32F105xx
+ * @arg @ref RCC_IT_PLL2RDY Main PLL2 ready interrupt.
+ * @arg @ref RCC_IT_PLLI2S2RDY Main PLLI2S ready interrupt.
+ @elsif STM32F107xx
+ * @arg @ref RCC_IT_PLL2RDY Main PLL2 ready interrupt.
+ * @arg @ref RCC_IT_PLLI2S2RDY Main PLLI2S ready interrupt.
+ @endif
+ * @arg @ref RCC_IT_CSS Clock Security System interrupt
+ * @retval The new state of __INTERRUPT__ (TRUE or FALSE).
+ */
+#define __HAL_RCC_GET_IT(__INTERRUPT__) ((RCC->CIR & (__INTERRUPT__)) == (__INTERRUPT__))
+
+/** @brief Set RMVF bit to clear the reset flags.
+ * The reset flags are RCC_FLAG_PINRST, RCC_FLAG_PORRST, RCC_FLAG_SFTRST,
+ * RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST, RCC_FLAG_LPWRRST
+ */
+#define __HAL_RCC_CLEAR_RESET_FLAGS() (*(__IO uint32_t *)RCC_CSR_RMVF_BB = ENABLE)
+
+/** @brief Check RCC flag is set or not.
+ * @param __FLAG__ specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_FLAG_HSIRDY HSI oscillator clock ready.
+ * @arg @ref RCC_FLAG_HSERDY HSE oscillator clock ready.
+ * @arg @ref RCC_FLAG_PLLRDY Main PLL clock ready.
+ @if STM32F105xx
+ * @arg @ref RCC_FLAG_PLL2RDY Main PLL2 clock ready.
+ * @arg @ref RCC_FLAG_PLLI2SRDY Main PLLI2S clock ready.
+ @elsif STM32F107xx
+ * @arg @ref RCC_FLAG_PLL2RDY Main PLL2 clock ready.
+ * @arg @ref RCC_FLAG_PLLI2SRDY Main PLLI2S clock ready.
+ @endif
+ * @arg @ref RCC_FLAG_LSERDY LSE oscillator clock ready.
+ * @arg @ref RCC_FLAG_LSIRDY LSI oscillator clock ready.
+ * @arg @ref RCC_FLAG_PINRST Pin reset.
+ * @arg @ref RCC_FLAG_PORRST POR/PDR reset.
+ * @arg @ref RCC_FLAG_SFTRST Software reset.
+ * @arg @ref RCC_FLAG_IWDGRST Independent Watchdog reset.
+ * @arg @ref RCC_FLAG_WWDGRST Window Watchdog reset.
+ * @arg @ref RCC_FLAG_LPWRRST Low Power reset.
+ * @retval The new state of __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_RCC_GET_FLAG(__FLAG__) (((((__FLAG__) >> 5U) == CR_REG_INDEX)? RCC->CR : \
+ ((((__FLAG__) >> 5U) == BDCR_REG_INDEX)? RCC->BDCR : \
+ RCC->CSR)) & (1U << ((__FLAG__) & RCC_FLAG_MASK)))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Include RCC HAL Extension module */
+#include "stm32f1xx_hal_rcc_ex.h"
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup RCC_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup RCC_Exported_Functions_Group1
+ * @{
+ */
+
+/* Initialization and de-initialization functions ******************************/
+HAL_StatusTypeDef HAL_RCC_DeInit(void);
+HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct);
+HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency);
+
+/**
+ * @}
+ */
+
+/** @addtogroup RCC_Exported_Functions_Group2
+ * @{
+ */
+
+/* Peripheral Control functions ************************************************/
+void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv);
+void HAL_RCC_EnableCSS(void);
+void HAL_RCC_DisableCSS(void);
+uint32_t HAL_RCC_GetSysClockFreq(void);
+uint32_t HAL_RCC_GetHCLKFreq(void);
+uint32_t HAL_RCC_GetPCLK1Freq(void);
+uint32_t HAL_RCC_GetPCLK2Freq(void);
+void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct);
+void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency);
+
+/* CSS NMI IRQ handler */
+void HAL_RCC_NMI_IRQHandler(void);
+
+/* User Callbacks in non blocking mode (IT mode) */
+void HAL_RCC_CSSCallback(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup RCC_Private_Constants
+ * @{
+ */
+
+/** @defgroup RCC_Timeout RCC Timeout
+ * @{
+ */
+
+/* Disable Backup domain write protection state change timeout */
+#define RCC_DBP_TIMEOUT_VALUE 100U /* 100 ms */
+/* LSE state change timeout */
+#define RCC_LSE_TIMEOUT_VALUE LSE_STARTUP_TIMEOUT
+#define CLOCKSWITCH_TIMEOUT_VALUE 5000 /* 5 s */
+#define HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT
+#define HSI_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
+#define LSI_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
+#define PLL_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_Register_Offset Register offsets
+ * @{
+ */
+#define RCC_OFFSET (RCC_BASE - PERIPH_BASE)
+#define RCC_CR_OFFSET 0x00U
+#define RCC_CFGR_OFFSET 0x04U
+#define RCC_CIR_OFFSET 0x08U
+#define RCC_BDCR_OFFSET 0x20U
+#define RCC_CSR_OFFSET 0x24U
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_BitAddress_AliasRegion BitAddress AliasRegion
+ * @brief RCC registers bit address in the alias region
+ * @{
+ */
+#define RCC_CR_OFFSET_BB (RCC_OFFSET + RCC_CR_OFFSET)
+#define RCC_CFGR_OFFSET_BB (RCC_OFFSET + RCC_CFGR_OFFSET)
+#define RCC_CIR_OFFSET_BB (RCC_OFFSET + RCC_CIR_OFFSET)
+#define RCC_BDCR_OFFSET_BB (RCC_OFFSET + RCC_BDCR_OFFSET)
+#define RCC_CSR_OFFSET_BB (RCC_OFFSET + RCC_CSR_OFFSET)
+
+/* --- CR Register ---*/
+/* Alias word address of HSION bit */
+#define RCC_HSION_BIT_NUMBER RCC_CR_HSION_Pos
+#define RCC_CR_HSION_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_CR_OFFSET_BB * 32U) + (RCC_HSION_BIT_NUMBER * 4U)))
+/* Alias word address of HSEON bit */
+#define RCC_HSEON_BIT_NUMBER RCC_CR_HSEON_Pos
+#define RCC_CR_HSEON_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_CR_OFFSET_BB * 32U) + (RCC_HSEON_BIT_NUMBER * 4U)))
+/* Alias word address of CSSON bit */
+#define RCC_CSSON_BIT_NUMBER RCC_CR_CSSON_Pos
+#define RCC_CR_CSSON_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_CR_OFFSET_BB * 32U) + (RCC_CSSON_BIT_NUMBER * 4U)))
+/* Alias word address of PLLON bit */
+#define RCC_PLLON_BIT_NUMBER RCC_CR_PLLON_Pos
+#define RCC_CR_PLLON_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_CR_OFFSET_BB * 32U) + (RCC_PLLON_BIT_NUMBER * 4U)))
+
+/* --- CSR Register ---*/
+/* Alias word address of LSION bit */
+#define RCC_LSION_BIT_NUMBER RCC_CSR_LSION_Pos
+#define RCC_CSR_LSION_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_CSR_OFFSET_BB * 32U) + (RCC_LSION_BIT_NUMBER * 4U)))
+
+/* Alias word address of RMVF bit */
+#define RCC_RMVF_BIT_NUMBER RCC_CSR_RMVF_Pos
+#define RCC_CSR_RMVF_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_CSR_OFFSET_BB * 32U) + (RCC_RMVF_BIT_NUMBER * 4U)))
+
+/* --- BDCR Registers ---*/
+/* Alias word address of LSEON bit */
+#define RCC_LSEON_BIT_NUMBER RCC_BDCR_LSEON_Pos
+#define RCC_BDCR_LSEON_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_BDCR_OFFSET_BB * 32U) + (RCC_LSEON_BIT_NUMBER * 4U)))
+
+/* Alias word address of LSEON bit */
+#define RCC_LSEBYP_BIT_NUMBER RCC_BDCR_LSEBYP_Pos
+#define RCC_BDCR_LSEBYP_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_BDCR_OFFSET_BB * 32U) + (RCC_LSEBYP_BIT_NUMBER * 4U)))
+
+/* Alias word address of RTCEN bit */
+#define RCC_RTCEN_BIT_NUMBER RCC_BDCR_RTCEN_Pos
+#define RCC_BDCR_RTCEN_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_BDCR_OFFSET_BB * 32U) + (RCC_RTCEN_BIT_NUMBER * 4U)))
+
+/* Alias word address of BDRST bit */
+#define RCC_BDRST_BIT_NUMBER RCC_BDCR_BDRST_Pos
+#define RCC_BDCR_BDRST_BB ((uint32_t)(PERIPH_BB_BASE + (RCC_BDCR_OFFSET_BB * 32U) + (RCC_BDRST_BIT_NUMBER * 4U)))
+
+/**
+ * @}
+ */
+
+/* CR register byte 2 (Bits[23:16]) base address */
+#define RCC_CR_BYTE2_ADDRESS ((uint32_t)(RCC_BASE + RCC_CR_OFFSET + 0x02U))
+
+/* CIR register byte 1 (Bits[15:8]) base address */
+#define RCC_CIR_BYTE1_ADDRESS ((uint32_t)(RCC_BASE + RCC_CIR_OFFSET + 0x01U))
+
+/* CIR register byte 2 (Bits[23:16]) base address */
+#define RCC_CIR_BYTE2_ADDRESS ((uint32_t)(RCC_BASE + RCC_CIR_OFFSET + 0x02U))
+
+/* Defines used for Flags */
+#define CR_REG_INDEX ((uint8_t)1)
+#define BDCR_REG_INDEX ((uint8_t)2)
+#define CSR_REG_INDEX ((uint8_t)3)
+
+#define RCC_FLAG_MASK ((uint8_t)0x1F)
+
+/**
+ * @}
+ */
+
+/** @addtogroup RCC_Private_Macros
+ * @{
+ */
+/** @defgroup RCC_Alias_For_Legacy Alias define maintained for legacy
+ * @{
+ */
+#define __HAL_RCC_SYSCFG_CLK_DISABLE __HAL_RCC_AFIO_CLK_DISABLE
+#define __HAL_RCC_SYSCFG_CLK_ENABLE __HAL_RCC_AFIO_CLK_ENABLE
+#define __HAL_RCC_SYSCFG_FORCE_RESET __HAL_RCC_AFIO_FORCE_RESET
+#define __HAL_RCC_SYSCFG_RELEASE_RESET __HAL_RCC_AFIO_RELEASE_RESET
+/**
+ * @}
+ */
+
+#define IS_RCC_PLLSOURCE(__SOURCE__) (((__SOURCE__) == RCC_PLLSOURCE_HSI_DIV2) || \
+ ((__SOURCE__) == RCC_PLLSOURCE_HSE))
+#define IS_RCC_OSCILLATORTYPE(__OSCILLATOR__) (((__OSCILLATOR__) == RCC_OSCILLATORTYPE_NONE) || \
+ (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) || \
+ (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) || \
+ (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) || \
+ (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE))
+#define IS_RCC_HSE(__HSE__) (((__HSE__) == RCC_HSE_OFF) || ((__HSE__) == RCC_HSE_ON) || \
+ ((__HSE__) == RCC_HSE_BYPASS))
+#define IS_RCC_LSE(__LSE__) (((__LSE__) == RCC_LSE_OFF) || ((__LSE__) == RCC_LSE_ON) || \
+ ((__LSE__) == RCC_LSE_BYPASS))
+#define IS_RCC_HSI(__HSI__) (((__HSI__) == RCC_HSI_OFF) || ((__HSI__) == RCC_HSI_ON))
+#define IS_RCC_CALIBRATION_VALUE(__VALUE__) ((__VALUE__) <= 0x1FU)
+#define IS_RCC_LSI(__LSI__) (((__LSI__) == RCC_LSI_OFF) || ((__LSI__) == RCC_LSI_ON))
+#define IS_RCC_PLL(__PLL__) (((__PLL__) == RCC_PLL_NONE) || ((__PLL__) == RCC_PLL_OFF) || \
+ ((__PLL__) == RCC_PLL_ON))
+
+#define IS_RCC_CLOCKTYPE(CLK) ((((CLK) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK) || \
+ (((CLK) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) || \
+ (((CLK) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) || \
+ (((CLK) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2))
+#define IS_RCC_SYSCLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_SYSCLKSOURCE_HSI) || \
+ ((__SOURCE__) == RCC_SYSCLKSOURCE_HSE) || \
+ ((__SOURCE__) == RCC_SYSCLKSOURCE_PLLCLK))
+#define IS_RCC_SYSCLKSOURCE_STATUS(__SOURCE__) (((__SOURCE__) == RCC_SYSCLKSOURCE_STATUS_HSI) || \
+ ((__SOURCE__) == RCC_SYSCLKSOURCE_STATUS_HSE) || \
+ ((__SOURCE__) == RCC_SYSCLKSOURCE_STATUS_PLLCLK))
+#define IS_RCC_HCLK(__HCLK__) (((__HCLK__) == RCC_SYSCLK_DIV1) || ((__HCLK__) == RCC_SYSCLK_DIV2) || \
+ ((__HCLK__) == RCC_SYSCLK_DIV4) || ((__HCLK__) == RCC_SYSCLK_DIV8) || \
+ ((__HCLK__) == RCC_SYSCLK_DIV16) || ((__HCLK__) == RCC_SYSCLK_DIV64) || \
+ ((__HCLK__) == RCC_SYSCLK_DIV128) || ((__HCLK__) == RCC_SYSCLK_DIV256) || \
+ ((__HCLK__) == RCC_SYSCLK_DIV512))
+#define IS_RCC_PCLK(__PCLK__) (((__PCLK__) == RCC_HCLK_DIV1) || ((__PCLK__) == RCC_HCLK_DIV2) || \
+ ((__PCLK__) == RCC_HCLK_DIV4) || ((__PCLK__) == RCC_HCLK_DIV8) || \
+ ((__PCLK__) == RCC_HCLK_DIV16))
+#define IS_RCC_MCO(__MCO__) ((__MCO__) == RCC_MCO)
+#define IS_RCC_MCODIV(__DIV__) (((__DIV__) == RCC_MCODIV_1))
+#define IS_RCC_RTCCLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_RTCCLKSOURCE_NO_CLK) || \
+ ((__SOURCE__) == RCC_RTCCLKSOURCE_LSE) || \
+ ((__SOURCE__) == RCC_RTCCLKSOURCE_LSI) || \
+ ((__SOURCE__) == RCC_RTCCLKSOURCE_HSE_DIV128))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_RCC_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h
rename to templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc.h
new file mode 100644
index 0000000..11e1793
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc.h
@@ -0,0 +1,576 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_rtc.h
+ * @author MCD Application Team
+ * @brief Header file of RTC HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_RTC_H
+#define __STM32F1xx_HAL_RTC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup RTC
+ * @{
+ */
+
+/** @addtogroup RTC_Private_Macros
+ * @{
+ */
+
+#define IS_RTC_ASYNCH_PREDIV(PREDIV) (((PREDIV) <= 0xFFFFFU) || ((PREDIV) == RTC_AUTO_1_SECOND))
+#define IS_RTC_HOUR24(HOUR) ((HOUR) <= 23U)
+#define IS_RTC_MINUTES(MINUTES) ((MINUTES) <= 59U)
+#define IS_RTC_SECONDS(SECONDS) ((SECONDS) <= 59U)
+#define IS_RTC_FORMAT(FORMAT) (((FORMAT) == RTC_FORMAT_BIN) || ((FORMAT) == RTC_FORMAT_BCD))
+#define IS_RTC_YEAR(YEAR) ((YEAR) <= 99U)
+#define IS_RTC_MONTH(MONTH) (((MONTH) >= 1U) && ((MONTH) <= 12U))
+#define IS_RTC_DATE(DATE) (((DATE) >= 1U) && ((DATE) <= 31U))
+#define IS_RTC_ALARM(ALARM) ((ALARM) == RTC_ALARM_A)
+#define IS_RTC_CALIB_OUTPUT(__OUTPUT__) (((__OUTPUT__) == RTC_OUTPUTSOURCE_NONE) || \
+ ((__OUTPUT__) == RTC_OUTPUTSOURCE_CALIBCLOCK) || \
+ ((__OUTPUT__) == RTC_OUTPUTSOURCE_ALARM) || \
+ ((__OUTPUT__) == RTC_OUTPUTSOURCE_SECOND))
+
+
+/**
+ * @}
+ */
+
+/** @addtogroup RTC_Private_Constants
+ * @{
+ */
+/** @defgroup RTC_Timeout_Value Default Timeout Value
+ * @{
+ */
+#define RTC_TIMEOUT_VALUE 1000U
+/**
+ * @}
+ */
+
+/** @defgroup RTC_EXTI_Line_Event RTC EXTI Line event
+ * @{
+ */
+#define RTC_EXTI_LINE_ALARM_EVENT ((uint32_t)EXTI_IMR_MR17) /*!< External interrupt line 17 Connected to the RTC Alarm event */
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup RTC_Exported_Types RTC Exported Types
+ * @{
+ */
+/**
+ * @brief RTC Time structure definition
+ */
+typedef struct
+{
+ uint8_t Hours; /*!< Specifies the RTC Time Hour.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 23 */
+
+ uint8_t Minutes; /*!< Specifies the RTC Time Minutes.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 59 */
+
+ uint8_t Seconds; /*!< Specifies the RTC Time Seconds.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 59 */
+
+}RTC_TimeTypeDef;
+
+/**
+ * @brief RTC Alarm structure definition
+ */
+typedef struct
+{
+ RTC_TimeTypeDef AlarmTime; /*!< Specifies the RTC Alarm Time members */
+
+ uint32_t Alarm; /*!< Specifies the alarm ID (only 1 alarm ID for STM32F1).
+ This parameter can be a value of @ref RTC_Alarms_Definitions */
+}RTC_AlarmTypeDef;
+
+/**
+ * @brief HAL State structures definition
+ */
+typedef enum
+{
+ HAL_RTC_STATE_RESET = 0x00U, /*!< RTC not yet initialized or disabled */
+ HAL_RTC_STATE_READY = 0x01U, /*!< RTC initialized and ready for use */
+ HAL_RTC_STATE_BUSY = 0x02U, /*!< RTC process is ongoing */
+ HAL_RTC_STATE_TIMEOUT = 0x03U, /*!< RTC timeout state */
+ HAL_RTC_STATE_ERROR = 0x04U /*!< RTC error state */
+
+}HAL_RTCStateTypeDef;
+
+/**
+ * @brief RTC Configuration Structure definition
+ */
+typedef struct
+{
+ uint32_t AsynchPrediv; /*!< Specifies the RTC Asynchronous Predivider value.
+ This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFFFFF or RTC_AUTO_1_SECOND
+ If RTC_AUTO_1_SECOND is selected, AsynchPrediv will be set automatically to get 1sec timebase */
+
+ uint32_t OutPut; /*!< Specifies which signal will be routed to the RTC Tamper pin.
+ This parameter can be a value of @ref RTC_output_source_to_output_on_the_Tamper_pin */
+
+}RTC_InitTypeDef;
+
+/**
+ * @brief RTC Date structure definition
+ */
+typedef struct
+{
+ uint8_t WeekDay; /*!< Specifies the RTC Date WeekDay (not necessary for HAL_RTC_SetDate).
+ This parameter can be a value of @ref RTC_WeekDay_Definitions */
+
+ uint8_t Month; /*!< Specifies the RTC Date Month (in BCD format).
+ This parameter can be a value of @ref RTC_Month_Date_Definitions */
+
+ uint8_t Date; /*!< Specifies the RTC Date.
+ This parameter must be a number between Min_Data = 1 and Max_Data = 31 */
+
+ uint8_t Year; /*!< Specifies the RTC Date Year.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 99 */
+
+}RTC_DateTypeDef;
+
+/**
+ * @brief Time Handle Structure definition
+ */
+typedef struct
+{
+ RTC_TypeDef *Instance; /*!< Register base address */
+
+ RTC_InitTypeDef Init; /*!< RTC required parameters */
+
+ RTC_DateTypeDef DateToUpdate; /*!< Current date set by user and updated automatically */
+
+ HAL_LockTypeDef Lock; /*!< RTC locking object */
+
+ __IO HAL_RTCStateTypeDef State; /*!< Time communication state */
+
+}RTC_HandleTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup RTC_Exported_Constants RTC Exported Constants
+ * @{
+ */
+
+/** @defgroup RTC_Automatic_Prediv_1_Second Automatic calculation of prediv for 1sec timebase
+ * @{
+ */
+#define RTC_AUTO_1_SECOND 0xFFFFFFFFU
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Input_parameter_format_definitions Input Parameter Format
+ * @{
+ */
+#define RTC_FORMAT_BIN 0x000000000U
+#define RTC_FORMAT_BCD 0x000000001U
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Month_Date_Definitions Month Definitions
+ * @{
+ */
+
+/* Coded in BCD format */
+#define RTC_MONTH_JANUARY ((uint8_t)0x01)
+#define RTC_MONTH_FEBRUARY ((uint8_t)0x02)
+#define RTC_MONTH_MARCH ((uint8_t)0x03)
+#define RTC_MONTH_APRIL ((uint8_t)0x04)
+#define RTC_MONTH_MAY ((uint8_t)0x05)
+#define RTC_MONTH_JUNE ((uint8_t)0x06)
+#define RTC_MONTH_JULY ((uint8_t)0x07)
+#define RTC_MONTH_AUGUST ((uint8_t)0x08)
+#define RTC_MONTH_SEPTEMBER ((uint8_t)0x09)
+#define RTC_MONTH_OCTOBER ((uint8_t)0x10)
+#define RTC_MONTH_NOVEMBER ((uint8_t)0x11)
+#define RTC_MONTH_DECEMBER ((uint8_t)0x12)
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_WeekDay_Definitions WeekDay Definitions
+ * @{
+ */
+#define RTC_WEEKDAY_MONDAY ((uint8_t)0x01)
+#define RTC_WEEKDAY_TUESDAY ((uint8_t)0x02)
+#define RTC_WEEKDAY_WEDNESDAY ((uint8_t)0x03)
+#define RTC_WEEKDAY_THURSDAY ((uint8_t)0x04)
+#define RTC_WEEKDAY_FRIDAY ((uint8_t)0x05)
+#define RTC_WEEKDAY_SATURDAY ((uint8_t)0x06)
+#define RTC_WEEKDAY_SUNDAY ((uint8_t)0x00)
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Alarms_Definitions Alarms Definitions
+ * @{
+ */
+#define RTC_ALARM_A 0U /*!< Specify alarm ID (mainly for legacy purposes) */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup RTC_output_source_to_output_on_the_Tamper_pin Output source to output on the Tamper pin
+ * @{
+ */
+
+#define RTC_OUTPUTSOURCE_NONE 0x00000000U /*!< No output on the TAMPER pin */
+#define RTC_OUTPUTSOURCE_CALIBCLOCK BKP_RTCCR_CCO /*!< RTC clock with a frequency divided by 64 on the TAMPER pin */
+#define RTC_OUTPUTSOURCE_ALARM BKP_RTCCR_ASOE /*!< Alarm pulse signal on the TAMPER pin */
+#define RTC_OUTPUTSOURCE_SECOND (BKP_RTCCR_ASOS | BKP_RTCCR_ASOE) /*!< Second pulse signal on the TAMPER pin */
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Interrupts_Definitions Interrupts Definitions
+ * @{
+ */
+#define RTC_IT_OW RTC_CRH_OWIE /*!< Overflow interrupt */
+#define RTC_IT_ALRA RTC_CRH_ALRIE /*!< Alarm interrupt */
+#define RTC_IT_SEC RTC_CRH_SECIE /*!< Second interrupt */
+#define RTC_IT_TAMP1 BKP_CSR_TPIE /*!< TAMPER Pin interrupt enable */
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Flags_Definitions Flags Definitions
+ * @{
+ */
+#define RTC_FLAG_RTOFF RTC_CRL_RTOFF /*!< RTC Operation OFF flag */
+#define RTC_FLAG_RSF RTC_CRL_RSF /*!< Registers Synchronized flag */
+#define RTC_FLAG_OW RTC_CRL_OWF /*!< Overflow flag */
+#define RTC_FLAG_ALRAF RTC_CRL_ALRF /*!< Alarm flag */
+#define RTC_FLAG_SEC RTC_CRL_SECF /*!< Second flag */
+#define RTC_FLAG_TAMP1F BKP_CSR_TEF /*!< Tamper Interrupt Flag */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup RTC_Exported_macros RTC Exported Macros
+ * @{
+ */
+
+/** @brief Reset RTC handle state
+ * @param __HANDLE__: RTC handle.
+ * @retval None
+ */
+#define __HAL_RTC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_RTC_STATE_RESET)
+
+/**
+ * @brief Disable the write protection for RTC registers.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @retval None
+ */
+#define __HAL_RTC_WRITEPROTECTION_DISABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CRL, RTC_CRL_CNF)
+
+/**
+ * @brief Enable the write protection for RTC registers.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @retval None
+ */
+#define __HAL_RTC_WRITEPROTECTION_ENABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CRL, RTC_CRL_CNF)
+
+/**
+ * @brief Enable the RTC Alarm interrupt.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __INTERRUPT__: specifies the RTC Alarm interrupt sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg RTC_IT_ALRA: Alarm A interrupt
+ * @retval None
+ */
+#define __HAL_RTC_ALARM_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->CRH, (__INTERRUPT__))
+
+/**
+ * @brief Disable the RTC Alarm interrupt.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __INTERRUPT__: specifies the RTC Alarm interrupt sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg RTC_IT_ALRA: Alarm A interrupt
+ * @retval None
+ */
+#define __HAL_RTC_ALARM_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT((__HANDLE__)->Instance->CRH, (__INTERRUPT__))
+
+/**
+ * @brief Check whether the specified RTC Alarm interrupt has been enabled or not.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __INTERRUPT__: specifies the RTC Alarm interrupt sources to be checked
+ * This parameter can be:
+ * @arg RTC_IT_ALRA: Alarm A interrupt
+ * @retval None
+ */
+#define __HAL_RTC_ALARM_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((((__HANDLE__)->Instance->CRH)& ((__INTERRUPT__)))) != RESET)? SET : RESET)
+
+/**
+ * @brief Get the selected RTC Alarm's flag status.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __FLAG__: specifies the RTC Alarm Flag sources to be enabled or disabled.
+ * This parameter can be:
+ * @arg RTC_FLAG_ALRAF
+ * @retval None
+ */
+#define __HAL_RTC_ALARM_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->CRL) & (__FLAG__)) != RESET)? SET : RESET)
+
+/**
+ * @brief Check whether the specified RTC Alarm interrupt has occurred or not.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __INTERRUPT__: specifies the RTC Alarm interrupt sources to check.
+ * This parameter can be:
+ * @arg RTC_IT_ALRA: Alarm A interrupt
+ * @retval None
+ */
+#define __HAL_RTC_ALARM_GET_IT(__HANDLE__, __INTERRUPT__) (((((__HANDLE__)->Instance->CRL) & (__INTERRUPT__)) != RESET)? SET : RESET)
+
+/**
+ * @brief Clear the RTC Alarm's pending flags.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __FLAG__: specifies the RTC Alarm Flag sources to be enabled or disabled.
+ * This parameter can be:
+ * @arg RTC_FLAG_ALRAF
+ * @retval None
+ */
+#define __HAL_RTC_ALARM_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->CRL) = ~(__FLAG__)
+
+/**
+ * @brief Enable interrupt on ALARM Exti Line 17.
+ * @retval None.
+ */
+#define __HAL_RTC_ALARM_EXTI_ENABLE_IT() SET_BIT(EXTI->IMR, RTC_EXTI_LINE_ALARM_EVENT)
+
+/**
+ * @brief Disable interrupt on ALARM Exti Line 17.
+ * @retval None.
+ */
+#define __HAL_RTC_ALARM_EXTI_DISABLE_IT() CLEAR_BIT(EXTI->IMR, RTC_EXTI_LINE_ALARM_EVENT)
+
+/**
+ * @brief Enable event on ALARM Exti Line 17.
+ * @retval None.
+ */
+#define __HAL_RTC_ALARM_EXTI_ENABLE_EVENT() SET_BIT(EXTI->EMR, RTC_EXTI_LINE_ALARM_EVENT)
+
+/**
+ * @brief Disable event on ALARM Exti Line 17.
+ * @retval None.
+ */
+#define __HAL_RTC_ALARM_EXTI_DISABLE_EVENT() CLEAR_BIT(EXTI->EMR, RTC_EXTI_LINE_ALARM_EVENT)
+
+
+/**
+ * @brief ALARM EXTI line configuration: set falling edge trigger.
+ * @retval None.
+ */
+#define __HAL_RTC_ALARM_EXTI_ENABLE_FALLING_EDGE() SET_BIT(EXTI->FTSR, RTC_EXTI_LINE_ALARM_EVENT)
+
+
+/**
+ * @brief Disable the ALARM Extended Interrupt Falling Trigger.
+ * @retval None.
+ */
+#define __HAL_RTC_ALARM_EXTI_DISABLE_FALLING_EDGE() CLEAR_BIT(EXTI->FTSR, RTC_EXTI_LINE_ALARM_EVENT)
+
+
+/**
+ * @brief ALARM EXTI line configuration: set rising edge trigger.
+ * @retval None.
+ */
+#define __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE() SET_BIT(EXTI->RTSR, RTC_EXTI_LINE_ALARM_EVENT)
+
+/**
+ * @brief Disable the ALARM Extended Interrupt Rising Trigger.
+ * This parameter can be:
+ * @retval None.
+ */
+#define __HAL_RTC_ALARM_EXTI_DISABLE_RISING_EDGE() CLEAR_BIT(EXTI->RTSR, RTC_EXTI_LINE_ALARM_EVENT)
+
+/**
+ * @brief ALARM EXTI line configuration: set rising & falling edge trigger.
+ * @retval None.
+ */
+#define __HAL_RTC_ALARM_EXTI_ENABLE_RISING_FALLING_EDGE() \
+do{ \
+ __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE(); \
+ __HAL_RTC_ALARM_EXTI_ENABLE_FALLING_EDGE(); \
+ } while(0U)
+
+/**
+ * @brief Disable the ALARM Extended Interrupt Rising & Falling Trigger.
+ * This parameter can be:
+ * @retval None.
+ */
+#define __HAL_RTC_ALARM_EXTI_DISABLE_RISING_FALLING_EDGE() \
+do{ \
+ __HAL_RTC_ALARM_EXTI_DISABLE_RISING_EDGE(); \
+ __HAL_RTC_ALARM_EXTI_DISABLE_FALLING_EDGE(); \
+ } while(0U)
+
+/**
+ * @brief Check whether the specified ALARM EXTI interrupt flag is set or not.
+ * @retval EXTI ALARM Line Status.
+ */
+#define __HAL_RTC_ALARM_EXTI_GET_FLAG() (EXTI->PR & (RTC_EXTI_LINE_ALARM_EVENT))
+
+/**
+ * @brief Clear the ALARM EXTI flag.
+ * @retval None.
+ */
+#define __HAL_RTC_ALARM_EXTI_CLEAR_FLAG() (EXTI->PR = (RTC_EXTI_LINE_ALARM_EVENT))
+
+/**
+ * @brief Generate a Software interrupt on selected EXTI line.
+ * @retval None.
+ */
+#define __HAL_RTC_ALARM_EXTI_GENERATE_SWIT() SET_BIT(EXTI->SWIER, RTC_EXTI_LINE_ALARM_EVENT)
+/**
+ * @}
+ */
+
+/* Include RTC HAL Extension module */
+#include "stm32f1xx_hal_rtc_ex.h"
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup RTC_Exported_Functions
+ * @{
+ */
+
+
+/* Initialization and de-initialization functions ****************************/
+/** @addtogroup RTC_Exported_Functions_Group1
+ * @{
+ */
+HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc);
+HAL_StatusTypeDef HAL_RTC_DeInit(RTC_HandleTypeDef *hrtc);
+void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc);
+void HAL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc);
+/**
+ * @}
+ */
+
+/* RTC Time and Date functions ************************************************/
+/** @addtogroup RTC_Exported_Functions_Group2
+ * @{
+ */
+HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format);
+HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format);
+HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format);
+HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format);
+/**
+ * @}
+ */
+
+/* RTC Alarm functions ********************************************************/
+/** @addtogroup RTC_Exported_Functions_Group3
+ * @{
+ */
+HAL_StatusTypeDef HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format);
+HAL_StatusTypeDef HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format);
+HAL_StatusTypeDef HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef *hrtc, uint32_t Alarm);
+HAL_StatusTypeDef HAL_RTC_GetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Alarm, uint32_t Format);
+void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef *hrtc);
+HAL_StatusTypeDef HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout);
+void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc);
+/**
+ * @}
+ */
+
+/* Peripheral State functions *************************************************/
+/** @addtogroup RTC_Exported_Functions_Group4
+ * @{
+ */
+HAL_RTCStateTypeDef HAL_RTC_GetState(RTC_HandleTypeDef *hrtc);
+/**
+ * @}
+ */
+
+/* Peripheral Control functions ***********************************************/
+/** @addtogroup RTC_Exported_Functions_Group5
+ * @{
+ */
+HAL_StatusTypeDef HAL_RTC_WaitForSynchro(RTC_HandleTypeDef* hrtc);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_RTC_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc_ex.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc_ex.h
new file mode 100644
index 0000000..e02f47e
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc_ex.h
@@ -0,0 +1,428 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_rtc_ex.h
+ * @author MCD Application Team
+ * @brief Header file of RTC HAL Extension module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_RTC_EX_H
+#define __STM32F1xx_HAL_RTC_EX_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup RTCEx
+ * @{
+ */
+
+/** @addtogroup RTCEx_Private_Macros
+ * @{
+ */
+
+/** @defgroup RTCEx_Alias_For_Legacy Alias define maintained for legacy
+ * @{
+ */
+#define HAL_RTCEx_TamperTimeStampIRQHandler HAL_RTCEx_TamperIRQHandler
+
+/**
+ * @}
+ */
+
+/** @defgroup RTCEx_IS_RTC_Definitions Private macros to check input parameters
+ * @{
+ */
+#define IS_RTC_TAMPER(__TAMPER__) ((__TAMPER__) == RTC_TAMPER_1)
+
+#define IS_RTC_TAMPER_TRIGGER(__TRIGGER__) (((__TRIGGER__) == RTC_TAMPERTRIGGER_LOWLEVEL) || \
+ ((__TRIGGER__) == RTC_TAMPERTRIGGER_HIGHLEVEL))
+
+#if RTC_BKP_NUMBER > 10U
+#define IS_RTC_BKP(BKP) (((BKP) <= (uint32_t)RTC_BKP_DR10) || (((BKP) >= (uint32_t)RTC_BKP_DR11) && ((BKP) <= (uint32_t)RTC_BKP_DR42)))
+#else
+#define IS_RTC_BKP(BKP) ((BKP) <= (uint32_t)RTC_BKP_NUMBER)
+#endif
+#define IS_RTC_SMOOTH_CALIB_MINUS(__VALUE__) ((__VALUE__) <= 0x0000007FU)
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup RTCEx_Exported_Types RTCEx Exported Types
+ * @{
+ */
+/**
+ * @brief RTC Tamper structure definition
+ */
+typedef struct
+{
+ uint32_t Tamper; /*!< Specifies the Tamper Pin.
+ This parameter can be a value of @ref RTCEx_Tamper_Pins_Definitions */
+
+ uint32_t Trigger; /*!< Specifies the Tamper Trigger.
+ This parameter can be a value of @ref RTCEx_Tamper_Trigger_Definitions */
+
+}RTC_TamperTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup RTCEx_Exported_Constants RTCEx Exported Constants
+ * @{
+ */
+
+/** @defgroup RTCEx_Tamper_Pins_Definitions Tamper Pins Definitions
+ * @{
+ */
+#define RTC_TAMPER_1 BKP_CR_TPE /*!< Select tamper to be enabled (mainly for legacy purposes) */
+
+/**
+ * @}
+ */
+
+/** @defgroup RTCEx_Tamper_Trigger_Definitions Tamper Trigger Definitions
+ * @{
+ */
+#define RTC_TAMPERTRIGGER_LOWLEVEL BKP_CR_TPAL /*!< A high level on the TAMPER pin resets all data backup registers (if TPE bit is set) */
+#define RTC_TAMPERTRIGGER_HIGHLEVEL 0x00000000U /*!< A low level on the TAMPER pin resets all data backup registers (if TPE bit is set) */
+
+/**
+ * @}
+ */
+
+/** @defgroup RTCEx_Backup_Registers_Definitions Backup Registers Definitions
+ * @{
+ */
+#if RTC_BKP_NUMBER > 0U
+#define RTC_BKP_DR1 0x00000001U
+#define RTC_BKP_DR2 0x00000002U
+#define RTC_BKP_DR3 0x00000003U
+#define RTC_BKP_DR4 0x00000004U
+#define RTC_BKP_DR5 0x00000005U
+#define RTC_BKP_DR6 0x00000006U
+#define RTC_BKP_DR7 0x00000007U
+#define RTC_BKP_DR8 0x00000008U
+#define RTC_BKP_DR9 0x00000009U
+#define RTC_BKP_DR10 0x0000000AU
+#endif /* RTC_BKP_NUMBER > 0 */
+
+#if RTC_BKP_NUMBER > 10U
+#define RTC_BKP_DR11 0x00000010U
+#define RTC_BKP_DR12 0x00000011U
+#define RTC_BKP_DR13 0x00000012U
+#define RTC_BKP_DR14 0x00000013U
+#define RTC_BKP_DR15 0x00000014U
+#define RTC_BKP_DR16 0x00000015U
+#define RTC_BKP_DR17 0x00000016U
+#define RTC_BKP_DR18 0x00000017U
+#define RTC_BKP_DR19 0x00000018U
+#define RTC_BKP_DR20 0x00000019U
+#define RTC_BKP_DR21 0x0000001AU
+#define RTC_BKP_DR22 0x0000001BU
+#define RTC_BKP_DR23 0x0000001CU
+#define RTC_BKP_DR24 0x0000001DU
+#define RTC_BKP_DR25 0x0000001EU
+#define RTC_BKP_DR26 0x0000001FU
+#define RTC_BKP_DR27 0x00000020U
+#define RTC_BKP_DR28 0x00000021U
+#define RTC_BKP_DR29 0x00000022U
+#define RTC_BKP_DR30 0x00000023U
+#define RTC_BKP_DR31 0x00000024U
+#define RTC_BKP_DR32 0x00000025U
+#define RTC_BKP_DR33 0x00000026U
+#define RTC_BKP_DR34 0x00000027U
+#define RTC_BKP_DR35 0x00000028U
+#define RTC_BKP_DR36 0x00000029U
+#define RTC_BKP_DR37 0x0000002AU
+#define RTC_BKP_DR38 0x0000002BU
+#define RTC_BKP_DR39 0x0000002CU
+#define RTC_BKP_DR40 0x0000002DU
+#define RTC_BKP_DR41 0x0000002EU
+#define RTC_BKP_DR42 0x0000002FU
+#endif /* RTC_BKP_NUMBER > 10 */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup RTCEx_Exported_Macros RTCEx Exported Macros
+ * @{
+ */
+
+/**
+ * @brief Enable the RTC Tamper interrupt.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __INTERRUPT__: specifies the RTC Tamper interrupt sources to be enabled
+ * This parameter can be any combination of the following values:
+ * @arg RTC_IT_TAMP1: Tamper A interrupt
+ * @retval None
+ */
+#define __HAL_RTC_TAMPER_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT(BKP->CSR, (__INTERRUPT__))
+
+/**
+ * @brief Disable the RTC Tamper interrupt.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __INTERRUPT__: specifies the RTC Tamper interrupt sources to be disabled.
+ * This parameter can be any combination of the following values:
+ * @arg RTC_IT_TAMP1: Tamper A interrupt
+ * @retval None
+ */
+#define __HAL_RTC_TAMPER_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT(BKP->CSR, (__INTERRUPT__))
+
+/**
+ * @brief Check whether the specified RTC Tamper interrupt has been enabled or not.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __INTERRUPT__: specifies the RTC Tamper interrupt sources to be checked.
+ * This parameter can be:
+ * @arg RTC_IT_TAMP1
+ * @retval None
+ */
+#define __HAL_RTC_TAMPER_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((BKP->CSR) & ((__INTERRUPT__))) != RESET)? SET : RESET)
+
+/**
+ * @brief Get the selected RTC Tamper's flag status.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __FLAG__: specifies the RTC Tamper Flag sources to be enabled or disabled.
+ * This parameter can be:
+ * @arg RTC_FLAG_TAMP1F
+ * @retval None
+ */
+#define __HAL_RTC_TAMPER_GET_FLAG(__HANDLE__, __FLAG__) ((((BKP->CSR) & (__FLAG__)) != RESET)? SET : RESET)
+
+/**
+ * @brief Get the selected RTC Tamper's flag status.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __INTERRUPT__: specifies the RTC Tamper interrupt sources to be checked.
+ * This parameter can be:
+ * @arg RTC_IT_TAMP1
+ * @retval None
+ */
+#define __HAL_RTC_TAMPER_GET_IT(__HANDLE__, __INTERRUPT__) ((((BKP->CSR) & (BKP_CSR_TEF)) != RESET)? SET : RESET)
+
+/**
+ * @brief Clear the RTC Tamper's pending flags.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __FLAG__: specifies the RTC Tamper Flag sources to be enabled or disabled.
+ * This parameter can be:
+ * @arg RTC_FLAG_TAMP1F
+ * @retval None
+ */
+#define __HAL_RTC_TAMPER_CLEAR_FLAG(__HANDLE__, __FLAG__) SET_BIT(BKP->CSR, BKP_CSR_CTE | BKP_CSR_CTI)
+
+/**
+ * @brief Enable the RTC Second interrupt.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __INTERRUPT__: specifies the RTC Second interrupt sources to be enabled
+ * This parameter can be any combination of the following values:
+ * @arg RTC_IT_SEC: Second A interrupt
+ * @retval None
+ */
+#define __HAL_RTC_SECOND_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->CRH, (__INTERRUPT__))
+
+/**
+ * @brief Disable the RTC Second interrupt.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __INTERRUPT__: specifies the RTC Second interrupt sources to be disabled.
+ * This parameter can be any combination of the following values:
+ * @arg RTC_IT_SEC: Second A interrupt
+ * @retval None
+ */
+#define __HAL_RTC_SECOND_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT((__HANDLE__)->Instance->CRH, (__INTERRUPT__))
+
+/**
+ * @brief Check whether the specified RTC Second interrupt has occurred or not.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __INTERRUPT__: specifies the RTC Second interrupt sources to be enabled or disabled.
+ * This parameter can be:
+ * @arg RTC_IT_SEC: Second A interrupt
+ * @retval None
+ */
+#define __HAL_RTC_SECOND_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((((__HANDLE__)->Instance->CRH)& ((__INTERRUPT__)))) != RESET)? SET : RESET)
+
+/**
+ * @brief Get the selected RTC Second's flag status.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __FLAG__: specifies the RTC Second Flag sources to be enabled or disabled.
+ * This parameter can be:
+ * @arg RTC_FLAG_SEC
+ * @retval None
+ */
+#define __HAL_RTC_SECOND_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->CRL) & (__FLAG__)) != RESET)? SET : RESET)
+
+/**
+ * @brief Clear the RTC Second's pending flags.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __FLAG__: specifies the RTC Second Flag sources to be enabled or disabled.
+ * This parameter can be:
+ * @arg RTC_FLAG_SEC
+ * @retval None
+ */
+#define __HAL_RTC_SECOND_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->CRL) = ~(__FLAG__)
+
+/**
+ * @brief Enable the RTC Overflow interrupt.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __INTERRUPT__: specifies the RTC Overflow interrupt sources to be enabled
+ * This parameter can be any combination of the following values:
+ * @arg RTC_IT_OW: Overflow A interrupt
+ * @retval None
+ */
+#define __HAL_RTC_OVERFLOW_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->CRH, (__INTERRUPT__))
+
+/**
+ * @brief Disable the RTC Overflow interrupt.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __INTERRUPT__: specifies the RTC Overflow interrupt sources to be disabled.
+ * This parameter can be any combination of the following values:
+ * @arg RTC_IT_OW: Overflow A interrupt
+ * @retval None
+ */
+#define __HAL_RTC_OVERFLOW_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT((__HANDLE__)->Instance->CRH, (__INTERRUPT__))
+
+/**
+ * @brief Check whether the specified RTC Overflow interrupt has occurred or not.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __INTERRUPT__: specifies the RTC Overflow interrupt sources to be enabled or disabled.
+ * This parameter can be:
+ * @arg RTC_IT_OW: Overflow A interrupt
+ * @retval None
+ */
+#define __HAL_RTC_OVERFLOW_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((((__HANDLE__)->Instance->CRH)& ((__INTERRUPT__))) ) != RESET)? SET : RESET)
+
+/**
+ * @brief Get the selected RTC Overflow's flag status.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __FLAG__: specifies the RTC Overflow Flag sources to be enabled or disabled.
+ * This parameter can be:
+ * @arg RTC_FLAG_OW
+ * @retval None
+ */
+#define __HAL_RTC_OVERFLOW_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->CRL) & (__FLAG__)) != RESET)? SET : RESET)
+
+/**
+ * @brief Clear the RTC Overflow's pending flags.
+ * @param __HANDLE__: specifies the RTC handle.
+ * @param __FLAG__: specifies the RTC Overflow Flag sources to be enabled or disabled.
+ * This parameter can be:
+ * @arg RTC_FLAG_OW
+ * @retval None
+ */
+#define __HAL_RTC_OVERFLOW_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->CRL) = ~(__FLAG__)
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup RTCEx_Exported_Functions
+ * @{
+ */
+
+/* RTC Tamper functions *****************************************/
+/** @addtogroup RTCEx_Exported_Functions_Group1
+ * @{
+ */
+HAL_StatusTypeDef HAL_RTCEx_SetTamper(RTC_HandleTypeDef *hrtc, RTC_TamperTypeDef* sTamper);
+HAL_StatusTypeDef HAL_RTCEx_SetTamper_IT(RTC_HandleTypeDef *hrtc, RTC_TamperTypeDef* sTamper);
+HAL_StatusTypeDef HAL_RTCEx_DeactivateTamper(RTC_HandleTypeDef *hrtc, uint32_t Tamper);
+void HAL_RTCEx_TamperIRQHandler(RTC_HandleTypeDef *hrtc);
+void HAL_RTCEx_Tamper1EventCallback(RTC_HandleTypeDef *hrtc);
+HAL_StatusTypeDef HAL_RTCEx_PollForTamper1Event(RTC_HandleTypeDef *hrtc, uint32_t Timeout);
+
+/**
+ * @}
+ */
+
+/* RTC Second functions *****************************************/
+/** @addtogroup RTCEx_Exported_Functions_Group2
+ * @{
+ */
+HAL_StatusTypeDef HAL_RTCEx_SetSecond_IT(RTC_HandleTypeDef *hrtc);
+HAL_StatusTypeDef HAL_RTCEx_DeactivateSecond(RTC_HandleTypeDef *hrtc);
+void HAL_RTCEx_RTCIRQHandler(RTC_HandleTypeDef* hrtc);
+void HAL_RTCEx_RTCEventCallback(RTC_HandleTypeDef *hrtc);
+void HAL_RTCEx_RTCEventErrorCallback(RTC_HandleTypeDef *hrtc);
+
+/**
+ * @}
+ */
+
+/* Extension Control functions ************************************************/
+/** @addtogroup RTCEx_Exported_Functions_Group3
+ * @{
+ */
+void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data);
+uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister);
+
+HAL_StatusTypeDef HAL_RTCEx_SetSmoothCalib(RTC_HandleTypeDef* hrtc, uint32_t SmoothCalibPeriod, uint32_t SmoothCalibPlusPulses, uint32_t SmouthCalibMinusPulsesValue);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_RTC_EX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sd.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sd.h
new file mode 100644
index 0000000..770ec0c
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sd.h
@@ -0,0 +1,715 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_sd.h
+ * @author MCD Application Team
+ * @brief Header file of SD HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_SD_H
+#define __STM32F1xx_HAL_SD_H
+
+#if defined(STM32F103xE) || defined(STM32F103xG)
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_sdmmc.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup SD SD
+ * @brief SD HAL module driver
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup SD_Exported_Types SD Exported Types
+ * @{
+ */
+
+/** @defgroup SD_Exported_Types_Group1 SD State enumeration structure
+ * @{
+ */
+typedef enum
+{
+ HAL_SD_STATE_RESET = 0x00000000U, /*!< SD not yet initialized or disabled */
+ HAL_SD_STATE_READY = 0x00000001U, /*!< SD initialized and ready for use */
+ HAL_SD_STATE_TIMEOUT = 0x00000002U, /*!< SD Timeout state */
+ HAL_SD_STATE_BUSY = 0x00000003U, /*!< SD process ongoing */
+ HAL_SD_STATE_PROGRAMMING = 0x00000004U, /*!< SD Programming State */
+ HAL_SD_STATE_RECEIVING = 0x00000005U, /*!< SD Receinving State */
+ HAL_SD_STATE_TRANSFER = 0x00000006U, /*!< SD Transfert State */
+ HAL_SD_STATE_ERROR = 0x0000000FU /*!< SD is in error state */
+}HAL_SD_StateTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup SD_Exported_Types_Group2 SD Card State enumeration structure
+ * @{
+ */
+typedef enum
+{
+ HAL_SD_CARD_READY = 0x00000001U, /*!< Card state is ready */
+ HAL_SD_CARD_IDENTIFICATION = 0x00000002U, /*!< Card is in identification state */
+ HAL_SD_CARD_STANDBY = 0x00000003U, /*!< Card is in standby state */
+ HAL_SD_CARD_TRANSFER = 0x00000004U, /*!< Card is in transfer state */
+ HAL_SD_CARD_SENDING = 0x00000005U, /*!< Card is sending an operation */
+ HAL_SD_CARD_RECEIVING = 0x00000006U, /*!< Card is receiving operation information */
+ HAL_SD_CARD_PROGRAMMING = 0x00000007U, /*!< Card is in programming state */
+ HAL_SD_CARD_DISCONNECTED = 0x00000008U, /*!< Card is disconnected */
+ HAL_SD_CARD_ERROR = 0x000000FFU /*!< Card response Error */
+}HAL_SD_CardStateTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup SD_Exported_Types_Group3 SD Handle Structure definition
+ * @{
+ */
+#define SD_InitTypeDef SDIO_InitTypeDef
+#define SD_TypeDef SDIO_TypeDef
+
+/**
+ * @brief SD Card Information Structure definition
+ */
+typedef struct
+{
+ uint32_t CardType; /*!< Specifies the card Type */
+
+ uint32_t CardVersion; /*!< Specifies the card version */
+
+ uint32_t Class; /*!< Specifies the class of the card class */
+
+ uint32_t RelCardAdd; /*!< Specifies the Relative Card Address */
+
+ uint32_t BlockNbr; /*!< Specifies the Card Capacity in blocks */
+
+ uint32_t BlockSize; /*!< Specifies one block size in bytes */
+
+ uint32_t LogBlockNbr; /*!< Specifies the Card logical Capacity in blocks */
+
+ uint32_t LogBlockSize; /*!< Specifies logical block size in bytes */
+
+}HAL_SD_CardInfoTypeDef;
+
+/**
+ * @brief SD handle Structure definition
+ */
+typedef struct
+{
+ SD_TypeDef *Instance; /*!< SD registers base address */
+
+ SD_InitTypeDef Init; /*!< SD required parameters */
+
+ HAL_LockTypeDef Lock; /*!< SD locking object */
+
+ uint32_t *pTxBuffPtr; /*!< Pointer to SD Tx transfer Buffer */
+
+ uint32_t TxXferSize; /*!< SD Tx Transfer size */
+
+ uint32_t *pRxBuffPtr; /*!< Pointer to SD Rx transfer Buffer */
+
+ uint32_t RxXferSize; /*!< SD Rx Transfer size */
+
+ __IO uint32_t Context; /*!< SD transfer context */
+
+ __IO HAL_SD_StateTypeDef State; /*!< SD card State */
+
+ __IO uint32_t ErrorCode; /*!< SD Card Error codes */
+
+ DMA_HandleTypeDef *hdmarx; /*!< SD Rx DMA handle parameters */
+
+ DMA_HandleTypeDef *hdmatx; /*!< SD Tx DMA handle parameters */
+
+ HAL_SD_CardInfoTypeDef SdCard; /*!< SD Card information */
+
+ uint32_t CSD[4]; /*!< SD card specific data table */
+
+ uint32_t CID[4]; /*!< SD card identification number table */
+
+}SD_HandleTypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup SD_Exported_Types_Group4 Card Specific Data: CSD Register
+ * @{
+ */
+typedef struct
+{
+ __IO uint8_t CSDStruct; /*!< CSD structure */
+ __IO uint8_t SysSpecVersion; /*!< System specification version */
+ __IO uint8_t Reserved1; /*!< Reserved */
+ __IO uint8_t TAAC; /*!< Data read access time 1 */
+ __IO uint8_t NSAC; /*!< Data read access time 2 in CLK cycles */
+ __IO uint8_t MaxBusClkFrec; /*!< Max. bus clock frequency */
+ __IO uint16_t CardComdClasses; /*!< Card command classes */
+ __IO uint8_t RdBlockLen; /*!< Max. read data block length */
+ __IO uint8_t PartBlockRead; /*!< Partial blocks for read allowed */
+ __IO uint8_t WrBlockMisalign; /*!< Write block misalignment */
+ __IO uint8_t RdBlockMisalign; /*!< Read block misalignment */
+ __IO uint8_t DSRImpl; /*!< DSR implemented */
+ __IO uint8_t Reserved2; /*!< Reserved */
+ __IO uint32_t DeviceSize; /*!< Device Size */
+ __IO uint8_t MaxRdCurrentVDDMin; /*!< Max. read current @ VDD min */
+ __IO uint8_t MaxRdCurrentVDDMax; /*!< Max. read current @ VDD max */
+ __IO uint8_t MaxWrCurrentVDDMin; /*!< Max. write current @ VDD min */
+ __IO uint8_t MaxWrCurrentVDDMax; /*!< Max. write current @ VDD max */
+ __IO uint8_t DeviceSizeMul; /*!< Device size multiplier */
+ __IO uint8_t EraseGrSize; /*!< Erase group size */
+ __IO uint8_t EraseGrMul; /*!< Erase group size multiplier */
+ __IO uint8_t WrProtectGrSize; /*!< Write protect group size */
+ __IO uint8_t WrProtectGrEnable; /*!< Write protect group enable */
+ __IO uint8_t ManDeflECC; /*!< Manufacturer default ECC */
+ __IO uint8_t WrSpeedFact; /*!< Write speed factor */
+ __IO uint8_t MaxWrBlockLen; /*!< Max. write data block length */
+ __IO uint8_t WriteBlockPaPartial; /*!< Partial blocks for write allowed */
+ __IO uint8_t Reserved3; /*!< Reserved */
+ __IO uint8_t ContentProtectAppli; /*!< Content protection application */
+ __IO uint8_t FileFormatGrouop; /*!< File format group */
+ __IO uint8_t CopyFlag; /*!< Copy flag (OTP) */
+ __IO uint8_t PermWrProtect; /*!< Permanent write protection */
+ __IO uint8_t TempWrProtect; /*!< Temporary write protection */
+ __IO uint8_t FileFormat; /*!< File format */
+ __IO uint8_t ECC; /*!< ECC code */
+ __IO uint8_t CSD_CRC; /*!< CSD CRC */
+ __IO uint8_t Reserved4; /*!< Always 1 */
+
+}HAL_SD_CardCSDTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup SD_Exported_Types_Group5 Card Identification Data: CID Register
+ * @{
+ */
+typedef struct
+{
+ __IO uint8_t ManufacturerID; /*!< Manufacturer ID */
+ __IO uint16_t OEM_AppliID; /*!< OEM/Application ID */
+ __IO uint32_t ProdName1; /*!< Product Name part1 */
+ __IO uint8_t ProdName2; /*!< Product Name part2 */
+ __IO uint8_t ProdRev; /*!< Product Revision */
+ __IO uint32_t ProdSN; /*!< Product Serial Number */
+ __IO uint8_t Reserved1; /*!< Reserved1 */
+ __IO uint16_t ManufactDate; /*!< Manufacturing Date */
+ __IO uint8_t CID_CRC; /*!< CID CRC */
+ __IO uint8_t Reserved2; /*!< Always 1 */
+
+}HAL_SD_CardCIDTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup SD_Exported_Types_Group6 SD Card Status returned by ACMD13
+ * @{
+ */
+typedef struct
+{
+ __IO uint8_t DataBusWidth; /*!< Shows the currently defined data bus width */
+ __IO uint8_t SecuredMode; /*!< Card is in secured mode of operation */
+ __IO uint16_t CardType; /*!< Carries information about card type */
+ __IO uint32_t ProtectedAreaSize; /*!< Carries information about the capacity of protected area */
+ __IO uint8_t SpeedClass; /*!< Carries information about the speed class of the card */
+ __IO uint8_t PerformanceMove; /*!< Carries information about the card's performance move */
+ __IO uint8_t AllocationUnitSize; /*!< Carries information about the card's allocation unit size */
+ __IO uint16_t EraseSize; /*!< Determines the number of AUs to be erased in one operation */
+ __IO uint8_t EraseTimeout; /*!< Determines the timeout for any number of AU erase */
+ __IO uint8_t EraseOffset; /*!< Carries information about the erase offset */
+
+}HAL_SD_CardStatusTypeDef;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup SD_Exported_Constants Exported Constants
+ * @{
+ */
+
+#define BLOCKSIZE 512U /*!< Block size is 512 bytes */
+
+/** @defgroup SD_Exported_Constansts_Group1 SD Error status enumeration Structure definition
+ * @{
+ */
+#define HAL_SD_ERROR_NONE SDMMC_ERROR_NONE /*!< No error */
+#define HAL_SD_ERROR_CMD_CRC_FAIL SDMMC_ERROR_CMD_CRC_FAIL /*!< Command response received (but CRC check failed) */
+#define HAL_SD_ERROR_DATA_CRC_FAIL SDMMC_ERROR_DATA_CRC_FAIL /*!< Data block sent/received (CRC check failed) */
+#define HAL_SD_ERROR_CMD_RSP_TIMEOUT SDMMC_ERROR_CMD_RSP_TIMEOUT /*!< Command response timeout */
+#define HAL_SD_ERROR_DATA_TIMEOUT SDMMC_ERROR_DATA_TIMEOUT /*!< Data timeout */
+#define HAL_SD_ERROR_TX_UNDERRUN SDMMC_ERROR_TX_UNDERRUN /*!< Transmit FIFO underrun */
+#define HAL_SD_ERROR_RX_OVERRUN SDMMC_ERROR_RX_OVERRUN /*!< Receive FIFO overrun */
+#define HAL_SD_ERROR_ADDR_MISALIGNED SDMMC_ERROR_ADDR_MISALIGNED /*!< Misaligned address */
+#define HAL_SD_ERROR_BLOCK_LEN_ERR SDMMC_ERROR_BLOCK_LEN_ERR /*!< Transferred block length is not allowed for the card or the
+ number of transferred bytes does not match the block length */
+#define HAL_SD_ERROR_ERASE_SEQ_ERR SDMMC_ERROR_ERASE_SEQ_ERR /*!< An error in the sequence of erase command occurs */
+#define HAL_SD_ERROR_BAD_ERASE_PARAM SDMMC_ERROR_BAD_ERASE_PARAM /*!< An invalid selection for erase groups */
+#define HAL_SD_ERROR_WRITE_PROT_VIOLATION SDMMC_ERROR_WRITE_PROT_VIOLATION /*!< Attempt to program a write protect block */
+#define HAL_SD_ERROR_LOCK_UNLOCK_FAILED SDMMC_ERROR_LOCK_UNLOCK_FAILED /*!< Sequence or password error has been detected in unlock
+ command or if there was an attempt to access a locked card */
+#define HAL_SD_ERROR_COM_CRC_FAILED SDMMC_ERROR_COM_CRC_FAILED /*!< CRC check of the previous command failed */
+#define HAL_SD_ERROR_ILLEGAL_CMD SDMMC_ERROR_ILLEGAL_CMD /*!< Command is not legal for the card state */
+#define HAL_SD_ERROR_CARD_ECC_FAILED SDMMC_ERROR_CARD_ECC_FAILED /*!< Card internal ECC was applied but failed to correct the data */
+#define HAL_SD_ERROR_CC_ERR SDMMC_ERROR_CC_ERR /*!< Internal card controller error */
+#define HAL_SD_ERROR_GENERAL_UNKNOWN_ERR SDMMC_ERROR_GENERAL_UNKNOWN_ERR /*!< General or unknown error */
+#define HAL_SD_ERROR_STREAM_READ_UNDERRUN SDMMC_ERROR_STREAM_READ_UNDERRUN /*!< The card could not sustain data reading in stream rmode */
+#define HAL_SD_ERROR_STREAM_WRITE_OVERRUN SDMMC_ERROR_STREAM_WRITE_OVERRUN /*!< The card could not sustain data programming in stream mode */
+#define HAL_SD_ERROR_CID_CSD_OVERWRITE SDMMC_ERROR_CID_CSD_OVERWRITE /*!< CID/CSD overwrite error */
+#define HAL_SD_ERROR_WP_ERASE_SKIP SDMMC_ERROR_WP_ERASE_SKIP /*!< Only partial address space was erased */
+#define HAL_SD_ERROR_CARD_ECC_DISABLED SDMMC_ERROR_CARD_ECC_DISABLED /*!< Command has been executed without using internal ECC */
+#define HAL_SD_ERROR_ERASE_RESET SDMMC_ERROR_ERASE_RESET /*!< Erase sequence was cleared before executing because an out
+ of erase sequence command was received */
+#define HAL_SD_ERROR_AKE_SEQ_ERR SDMMC_ERROR_AKE_SEQ_ERR /*!< Error in sequence of authentication */
+#define HAL_SD_ERROR_INVALID_VOLTRANGE SDMMC_ERROR_INVALID_VOLTRANGE /*!< Error in case of invalid voltage range */
+#define HAL_SD_ERROR_ADDR_OUT_OF_RANGE SDMMC_ERROR_ADDR_OUT_OF_RANGE /*!< Error when addressed block is out of range */
+#define HAL_SD_ERROR_REQUEST_NOT_APPLICABLE SDMMC_ERROR_REQUEST_NOT_APPLICABLE /*!< Error when command request is not applicable */
+#define HAL_SD_ERROR_PARAM SDMMC_ERROR_INVALID_PARAMETER /*!< the used parameter is not valid */
+#define HAL_SD_ERROR_UNSUPPORTED_FEATURE SDMMC_ERROR_UNSUPPORTED_FEATURE /*!< Error when feature is not insupported */
+#define HAL_SD_ERROR_BUSY SDMMC_ERROR_BUSY /*!< Error when transfer process is busy */
+#define HAL_SD_ERROR_DMA SDMMC_ERROR_DMA /*!< Error while DMA transfer */
+#define HAL_SD_ERROR_TIMEOUT SDMMC_ERROR_TIMEOUT /*!< Timeout error */
+
+/**
+ * @}
+ */
+
+/** @defgroup SD_Exported_Constansts_Group2 SD context enumeration
+ * @{
+ */
+#define SD_CONTEXT_NONE 0x00000000U /*!< None */
+#define SD_CONTEXT_READ_SINGLE_BLOCK 0x00000001U /*!< Read single block operation */
+#define SD_CONTEXT_READ_MULTIPLE_BLOCK 0x00000002U /*!< Read multiple blocks operation */
+#define SD_CONTEXT_WRITE_SINGLE_BLOCK 0x00000010U /*!< Write single block operation */
+#define SD_CONTEXT_WRITE_MULTIPLE_BLOCK 0x00000020U /*!< Write multiple blocks operation */
+#define SD_CONTEXT_IT 0x00000008U /*!< Process in Interrupt mode */
+#define SD_CONTEXT_DMA 0x00000080U /*!< Process in DMA mode */
+
+/**
+ * @}
+ */
+
+/** @defgroup SD_Exported_Constansts_Group3 SD Supported Memory Cards
+ * @{
+ */
+#define CARD_SDSC 0x00000000U
+#define CARD_SDHC_SDXC 0x00000001U
+#define CARD_SECURED 0x00000003U
+
+/**
+ * @}
+ */
+
+/** @defgroup SD_Exported_Constansts_Group4 SD Supported Version
+ * @{
+ */
+#define CARD_V1_X 0x00000000U
+#define CARD_V2_X 0x00000001U
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup SD_Exported_macros SD Exported Macros
+ * @brief macros to handle interrupts and specific clock configurations
+ * @{
+ */
+
+/**
+ * @brief Enable the SD device.
+ * @retval None
+ */
+#define __HAL_SD_ENABLE(__HANDLE__) __SDIO_ENABLE((__HANDLE__)->Instance)
+
+/**
+ * @brief Disable the SD device.
+ * @retval None
+ */
+#define __HAL_SD_DISABLE(__HANDLE__) __SDIO_DISABLE((__HANDLE__)->Instance)
+
+/**
+ * @brief Enable the SDMMC DMA transfer.
+ * @retval None
+ */
+#define __HAL_SD_DMA_ENABLE(__HANDLE__) __SDIO_DMA_ENABLE((__HANDLE__)->Instance)
+
+/**
+ * @brief Disable the SDMMC DMA transfer.
+ * @retval None
+ */
+#define __HAL_SD_DMA_DISABLE(__HANDLE__) __SDIO_DMA_DISABLE((__HANDLE__)->Instance)
+
+/**
+ * @brief Enable the SD device interrupt.
+ * @param __HANDLE__: SD Handle
+ * @param __INTERRUPT__: specifies the SDMMC interrupt sources to be enabled.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
+ * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
+ * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
+ * @arg SDIO_IT_RXACT: Data receive in progress interrupt
+ * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
+ * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
+ * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
+ * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
+ * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
+ * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
+ * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
+ * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @retval None
+ */
+#define __HAL_SD_ENABLE_IT(__HANDLE__, __INTERRUPT__) __SDIO_ENABLE_IT((__HANDLE__)->Instance, (__INTERRUPT__))
+
+/**
+ * @brief Disable the SD device interrupt.
+ * @param __HANDLE__: SD Handle
+ * @param __INTERRUPT__: specifies the SDMMC interrupt sources to be disabled.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
+ * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
+ * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
+ * @arg SDIO_IT_RXACT: Data receive in progress interrupt
+ * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
+ * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
+ * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
+ * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
+ * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
+ * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
+ * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
+ * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @retval None
+ */
+#define __HAL_SD_DISABLE_IT(__HANDLE__, __INTERRUPT__) __SDIO_DISABLE_IT((__HANDLE__)->Instance, (__INTERRUPT__))
+
+/**
+ * @brief Check whether the specified SD flag is set or not.
+ * @param __HANDLE__: SD Handle
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed)
+ * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed)
+ * @arg SDIO_FLAG_CTIMEOUT: Command response timeout
+ * @arg SDIO_FLAG_DTIMEOUT: Data timeout
+ * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error
+ * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error
+ * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed)
+ * @arg SDIO_FLAG_CMDSENT: Command sent (no response required)
+ * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero)
+ * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed)
+ * @arg SDIO_FLAG_CMDACT: Command transfer in progress
+ * @arg SDIO_FLAG_TXACT: Data transmit in progress
+ * @arg SDIO_FLAG_RXACT: Data receive in progress
+ * @arg SDIO_FLAG_TXFIFOHE: Transmit FIFO Half Empty
+ * @arg SDIO_FLAG_RXFIFOHF: Receive FIFO Half Full
+ * @arg SDIO_FLAG_TXFIFOF: Transmit FIFO full
+ * @arg SDIO_FLAG_RXFIFOF: Receive FIFO full
+ * @arg SDIO_FLAG_TXFIFOE: Transmit FIFO empty
+ * @arg SDIO_FLAG_RXFIFOE: Receive FIFO empty
+ * @arg SDIO_FLAG_TXDAVL: Data available in transmit FIFO
+ * @arg SDIO_FLAG_RXDAVL: Data available in receive FIFO
+ * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received
+ * @retval The new state of SD FLAG (SET or RESET).
+ */
+#define __HAL_SD_GET_FLAG(__HANDLE__, __FLAG__) __SDIO_GET_FLAG((__HANDLE__)->Instance, (__FLAG__))
+
+/**
+ * @brief Clear the SD's pending flags.
+ * @param __HANDLE__: SD Handle
+ * @param __FLAG__: specifies the flag to clear.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed)
+ * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed)
+ * @arg SDIO_FLAG_CTIMEOUT: Command response timeout
+ * @arg SDIO_FLAG_DTIMEOUT: Data timeout
+ * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error
+ * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error
+ * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed)
+ * @arg SDIO_FLAG_CMDSENT: Command sent (no response required)
+ * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero)
+ * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed)
+ * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received
+ * @retval None
+ */
+#define __HAL_SD_CLEAR_FLAG(__HANDLE__, __FLAG__) __SDIO_CLEAR_FLAG((__HANDLE__)->Instance, (__FLAG__))
+
+/**
+ * @brief Check whether the specified SD interrupt has occurred or not.
+ * @param __HANDLE__: SD Handle
+ * @param __INTERRUPT__: specifies the SDMMC interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
+ * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
+ * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
+ * @arg SDIO_IT_RXACT: Data receive in progress interrupt
+ * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
+ * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
+ * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
+ * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
+ * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
+ * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
+ * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
+ * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @retval The new state of SD IT (SET or RESET).
+ */
+#define __HAL_SD_GET_IT(__HANDLE__, __INTERRUPT__) __SDIO_GET_IT((__HANDLE__)->Instance, (__INTERRUPT__))
+
+/**
+ * @brief Clear the SD's interrupt pending bits.
+ * @param __HANDLE__: SD Handle
+ * @param __INTERRUPT__: specifies the interrupt pending bit to clear.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDMMC_DCOUNT, is zero) interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @retval None
+ */
+#define __HAL_SD_CLEAR_IT(__HANDLE__, __INTERRUPT__) __SDIO_CLEAR_IT((__HANDLE__)->Instance, (__INTERRUPT__))
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup SD_Exported_Functions SD Exported Functions
+ * @{
+ */
+
+/** @defgroup SD_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @{
+ */
+HAL_StatusTypeDef HAL_SD_Init(SD_HandleTypeDef *hsd);
+HAL_StatusTypeDef HAL_SD_InitCard(SD_HandleTypeDef *hsd);
+HAL_StatusTypeDef HAL_SD_DeInit (SD_HandleTypeDef *hsd);
+void HAL_SD_MspInit(SD_HandleTypeDef *hsd);
+void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd);
+/**
+ * @}
+ */
+
+/** @defgroup SD_Exported_Functions_Group2 Input and Output operation functions
+ * @{
+ */
+/* Blocking mode: Polling */
+HAL_StatusTypeDef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout);
+HAL_StatusTypeDef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout);
+HAL_StatusTypeDef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint32_t BlockStartAdd, uint32_t BlockEndAdd);
+/* Non-Blocking mode: IT */
+HAL_StatusTypeDef HAL_SD_ReadBlocks_IT(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks);
+HAL_StatusTypeDef HAL_SD_WriteBlocks_IT(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks);
+/* Non-Blocking mode: DMA */
+HAL_StatusTypeDef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks);
+HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks);
+
+void HAL_SD_IRQHandler(SD_HandleTypeDef *hsd);
+
+/* Callback in non blocking modes (DMA) */
+void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd);
+void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd);
+void HAL_SD_ErrorCallback(SD_HandleTypeDef *hsd);
+void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd);
+/**
+ * @}
+ */
+
+/** @defgroup SD_Exported_Functions_Group3 Peripheral Control functions
+ * @{
+ */
+HAL_StatusTypeDef HAL_SD_ConfigWideBusOperation(SD_HandleTypeDef *hsd, uint32_t WideMode);
+/**
+ * @}
+ */
+
+/** @defgroup SD_Exported_Functions_Group4 SD card related functions
+ * @{
+ */
+HAL_StatusTypeDef HAL_SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus);
+HAL_SD_CardStateTypeDef HAL_SD_GetCardState(SD_HandleTypeDef *hsd);
+HAL_StatusTypeDef HAL_SD_GetCardCID(SD_HandleTypeDef *hsd, HAL_SD_CardCIDTypeDef *pCID);
+HAL_StatusTypeDef HAL_SD_GetCardCSD(SD_HandleTypeDef *hsd, HAL_SD_CardCSDTypeDef *pCSD);
+HAL_StatusTypeDef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypeDef *pStatus);
+HAL_StatusTypeDef HAL_SD_GetCardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypeDef *pCardInfo);
+/**
+ * @}
+ */
+
+/** @defgroup SD_Exported_Functions_Group5 Peripheral State and Errors functions
+ * @{
+ */
+HAL_SD_StateTypeDef HAL_SD_GetState(SD_HandleTypeDef *hsd);
+uint32_t HAL_SD_GetError(SD_HandleTypeDef *hsd);
+/**
+ * @}
+ */
+
+/** @defgroup SD_Exported_Functions_Group6 Perioheral Abort management
+ * @{
+ */
+HAL_StatusTypeDef HAL_SD_Abort(SD_HandleTypeDef *hsd);
+HAL_StatusTypeDef HAL_SD_Abort_IT(SD_HandleTypeDef *hsd);
+/**
+ * @}
+ */
+
+/* Private types -------------------------------------------------------------*/
+/** @defgroup SD_Private_Types SD Private Types
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private defines -----------------------------------------------------------*/
+/** @defgroup SD_Private_Defines SD Private Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/** @defgroup SD_Private_Variables SD Private Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup SD_Private_Constants SD Private Constants
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup SD_Private_Macros SD Private Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private functions prototypes ----------------------------------------------*/
+/** @defgroup SD_Private_Functions_Prototypes SD Private Functions Prototypes
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup SD_Private_Functions SD Private Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32F103xE || STM32F103xG */
+
+#endif /* __STM32F1xx_HAL_SD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_smartcard.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_smartcard.h
new file mode 100644
index 0000000..44e3133
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_smartcard.h
@@ -0,0 +1,683 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_smartcard.h
+ * @author MCD Application Team
+ * @brief Header file of SMARTCARD HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_SMARTCARD_H
+#define __STM32F1xx_HAL_SMARTCARD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup SMARTCARD
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup SMARTCARD_Exported_Types SMARTCARD Exported Types
+ * @{
+ */
+
+/**
+ * @brief SMARTCARD Init Structure definition
+ */
+typedef struct
+{
+ uint32_t BaudRate; /*!< This member configures the SmartCard communication baud rate.
+ The baud rate is computed using the following formula:
+ - IntegerDivider = ((PCLKx) / (16 * (hsmartcard->Init.BaudRate)))
+ - FractionalDivider = ((IntegerDivider - ((uint32_t) IntegerDivider)) * 16) + 0.5 */
+
+ uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame.
+ This parameter can be a value of @ref SMARTCARD_Word_Length */
+
+ uint32_t StopBits; /*!< Specifies the number of stop bits transmitted.
+ This parameter can be a value of @ref SMARTCARD_Stop_Bits */
+
+ uint32_t Parity; /*!< Specifies the parity mode.
+ This parameter can be a value of @ref SMARTCARD_Parity
+ @note When parity is enabled, the computed parity is inserted
+ at the MSB position of the transmitted data (9th bit when
+ the word length is set to 9 data bits; 8th bit when the
+ word length is set to 8 data bits).*/
+
+ uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.
+ This parameter can be a value of @ref SMARTCARD_Mode */
+
+ uint32_t CLKPolarity; /*!< Specifies the steady state of the serial clock.
+ This parameter can be a value of @ref SMARTCARD_Clock_Polarity */
+
+ uint32_t CLKPhase; /*!< Specifies the clock transition on which the bit capture is made.
+ This parameter can be a value of @ref SMARTCARD_Clock_Phase */
+
+ uint32_t CLKLastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted
+ data bit (MSB) has to be output on the SCLK pin in synchronous mode.
+ This parameter can be a value of @ref SMARTCARD_Last_Bit */
+
+ uint32_t Prescaler; /*!< Specifies the SmartCard Prescaler value used for dividing the system clock
+ to provide the smartcard clock. The value given in the register (5 significant bits)
+ is multiplied by 2 to give the division factor of the source clock frequency.
+ This parameter can be a value of @ref SMARTCARD_Prescaler */
+
+ uint32_t GuardTime; /*!< Specifies the SmartCard Guard Time value in terms of number of baud clocks */
+
+ uint32_t NACKState; /*!< Specifies the SmartCard NACK Transmission state
+ This parameter can be a value of @ref SMARTCARD_NACK_State */
+} SMARTCARD_InitTypeDef;
+
+/**
+ * @brief HAL SMARTCARD State structures definition
+ * @note HAL SMARTCARD State value is a combination of 2 different substates: gState and RxState.
+ * - gState contains SMARTCARD state information related to global Handle management
+ * and also information related to Tx operations.
+ * gState value coding follow below described bitmap :
+ * b7-b6 Error information
+ * 00 : No Error
+ * 01 : (Not Used)
+ * 10 : Timeout
+ * 11 : Error
+ * b5 IP initilisation status
+ * 0 : Reset (IP not initialized)
+ * 1 : Init done (IP not initialized. HAL SMARTCARD Init function already called)
+ * b4-b3 (not used)
+ * xx : Should be set to 00
+ * b2 Intrinsic process state
+ * 0 : Ready
+ * 1 : Busy (IP busy with some configuration or internal operations)
+ * b1 (not used)
+ * x : Should be set to 0
+ * b0 Tx state
+ * 0 : Ready (no Tx operation ongoing)
+ * 1 : Busy (Tx operation ongoing)
+ * - RxState contains information related to Rx operations.
+ * RxState value coding follow below described bitmap :
+ * b7-b6 (not used)
+ * xx : Should be set to 00
+ * b5 IP initilisation status
+ * 0 : Reset (IP not initialized)
+ * 1 : Init done (IP not initialized)
+ * b4-b2 (not used)
+ * xxx : Should be set to 000
+ * b1 Rx state
+ * 0 : Ready (no Rx operation ongoing)
+ * 1 : Busy (Rx operation ongoing)
+ * b0 (not used)
+ * x : Should be set to 0.
+ */
+typedef enum
+{
+ HAL_SMARTCARD_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized
+ Value is allowed for gState and RxState */
+ HAL_SMARTCARD_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use
+ Value is allowed for gState and RxState */
+ HAL_SMARTCARD_STATE_BUSY = 0x24U, /*!< an internal process is ongoing
+ Value is allowed for gState only */
+ HAL_SMARTCARD_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing
+ Value is allowed for gState only */
+ HAL_SMARTCARD_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing
+ Value is allowed for RxState only */
+ HAL_SMARTCARD_STATE_BUSY_TX_RX = 0x23U, /*!< Data Transmission and Reception process is ongoing
+ Not to be used for neither gState nor RxState.
+ Value is result of combination (Or) between gState and RxState values */
+ HAL_SMARTCARD_STATE_TIMEOUT = 0xA0U, /*!< Timeout state
+ Value is allowed for gState only */
+ HAL_SMARTCARD_STATE_ERROR = 0xE0U /*!< Error
+ Value is allowed for gState only */
+} HAL_SMARTCARD_StateTypeDef;
+
+/**
+ * @brief SMARTCARD handle Structure definition
+ */
+typedef struct
+{
+ USART_TypeDef *Instance; /*!< USART registers base address */
+
+ SMARTCARD_InitTypeDef Init; /*!< SmartCard communication parameters */
+
+ uint8_t *pTxBuffPtr; /*!< Pointer to SmartCard Tx transfer Buffer */
+
+ uint16_t TxXferSize; /*!< SmartCard Tx Transfer size */
+
+ __IO uint16_t TxXferCount; /*!< SmartCard Tx Transfer Counter */
+
+ uint8_t *pRxBuffPtr; /*!< Pointer to SmartCard Rx transfer Buffer */
+
+ uint16_t RxXferSize; /*!< SmartCard Rx Transfer size */
+
+ __IO uint16_t RxXferCount; /*!< SmartCard Rx Transfer Counter */
+
+ DMA_HandleTypeDef *hdmatx; /*!< SmartCard Tx DMA Handle parameters */
+
+ DMA_HandleTypeDef *hdmarx; /*!< SmartCard Rx DMA Handle parameters */
+
+ HAL_LockTypeDef Lock; /*!< Locking object */
+
+ __IO HAL_SMARTCARD_StateTypeDef gState; /*!< SmartCard state information related to global Handle management
+ and also related to Tx operations.
+ This parameter can be a value of @ref HAL_SMARTCARD_StateTypeDef */
+
+ __IO HAL_SMARTCARD_StateTypeDef RxState; /*!< SmartCard state information related to Rx operations.
+ This parameter can be a value of @ref HAL_SMARTCARD_StateTypeDef */
+
+ __IO uint32_t ErrorCode; /*!< SmartCard Error code */
+} SMARTCARD_HandleTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup SMARTCARD_Exported_Constants SMARTCARD Exported constants
+ * @{
+ */
+
+/** @defgroup SMARTCARD_Error_Code SMARTCARD Error Code
+ * @{
+ */
+#define HAL_SMARTCARD_ERROR_NONE 0x00000000U /*!< No error */
+#define HAL_SMARTCARD_ERROR_PE 0x00000001U /*!< Parity error */
+#define HAL_SMARTCARD_ERROR_NE 0x00000002U /*!< Noise error */
+#define HAL_SMARTCARD_ERROR_FE 0x00000004U /*!< Frame error */
+#define HAL_SMARTCARD_ERROR_ORE 0x00000008U /*!< OverRun error */
+#define HAL_SMARTCARD_ERROR_DMA 0x00000010U /*!< DMA transfer error */
+/**
+ * @}
+ */
+
+/** @defgroup SMARTCARD_Word_Length SMARTCARD Word Length
+ * @{
+ */
+#define SMARTCARD_WORDLENGTH_9B ((uint32_t)USART_CR1_M)
+/**
+ * @}
+ */
+
+/** @defgroup SMARTCARD_Stop_Bits SMARTCARD Number of Stop Bits
+ * @{
+ */
+#define SMARTCARD_STOPBITS_0_5 ((uint32_t)USART_CR2_STOP_0)
+#define SMARTCARD_STOPBITS_1_5 ((uint32_t)(USART_CR2_STOP_0 | USART_CR2_STOP_1))
+/**
+ * @}
+ */
+
+/** @defgroup SMARTCARD_Parity SMARTCARD Parity
+ * @{
+ */
+#define SMARTCARD_PARITY_EVEN ((uint32_t)USART_CR1_PCE)
+#define SMARTCARD_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS))
+/**
+ * @}
+ */
+
+/** @defgroup SMARTCARD_Mode SMARTCARD Mode
+ * @{
+ */
+#define SMARTCARD_MODE_RX ((uint32_t)USART_CR1_RE)
+#define SMARTCARD_MODE_TX ((uint32_t)USART_CR1_TE)
+#define SMARTCARD_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE))
+/**
+ * @}
+ */
+
+/** @defgroup SMARTCARD_Clock_Polarity SMARTCARD Clock Polarity
+ * @{
+ */
+#define SMARTCARD_POLARITY_LOW 0x00000000U
+#define SMARTCARD_POLARITY_HIGH ((uint32_t)USART_CR2_CPOL)
+/**
+ * @}
+ */
+
+/** @defgroup SMARTCARD_Clock_Phase SMARTCARD Clock Phase
+ * @{
+ */
+#define SMARTCARD_PHASE_1EDGE 0x00000000U
+#define SMARTCARD_PHASE_2EDGE ((uint32_t)USART_CR2_CPHA)
+/**
+ * @}
+ */
+
+/** @defgroup SMARTCARD_Last_Bit SMARTCARD Last Bit
+ * @{
+ */
+#define SMARTCARD_LASTBIT_DISABLE 0x00000000U
+#define SMARTCARD_LASTBIT_ENABLE ((uint32_t)USART_CR2_LBCL)
+/**
+ * @}
+ */
+
+/** @defgroup SMARTCARD_NACK_State SMARTCARD NACK State
+ * @{
+ */
+#define SMARTCARD_NACK_ENABLE ((uint32_t)USART_CR3_NACK)
+#define SMARTCARD_NACK_DISABLE 0x00000000U
+/**
+ * @}
+ */
+
+/** @defgroup SMARTCARD_DMA_Requests SMARTCARD DMA requests
+ * @{
+ */
+#define SMARTCARD_DMAREQ_TX ((uint32_t)USART_CR3_DMAT)
+#define SMARTCARD_DMAREQ_RX ((uint32_t)USART_CR3_DMAR)
+/**
+ * @}
+ */
+
+/** @defgroup SMARTCARD_Prescaler SMARTCARD Prescaler
+ * @{
+ */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV2 0x00000001U /*!< SYSCLK divided by 2 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV4 0x00000002U /*!< SYSCLK divided by 4 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV6 0x00000003U /*!< SYSCLK divided by 6 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV8 0x00000004U /*!< SYSCLK divided by 8 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV10 0x00000005U /*!< SYSCLK divided by 10 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV12 0x00000006U /*!< SYSCLK divided by 12 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV14 0x00000007U /*!< SYSCLK divided by 14 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV16 0x00000008U /*!< SYSCLK divided by 16 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV18 0x00000009U /*!< SYSCLK divided by 18 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV20 0x0000000AU /*!< SYSCLK divided by 20 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV22 0x0000000BU /*!< SYSCLK divided by 22 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV24 0x0000000CU /*!< SYSCLK divided by 24 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV26 0x0000000DU /*!< SYSCLK divided by 26 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV28 0x0000000EU /*!< SYSCLK divided by 28 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV30 0x0000000FU /*!< SYSCLK divided by 30 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV32 0x00000010U /*!< SYSCLK divided by 32 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV34 0x00000011U /*!< SYSCLK divided by 34 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV36 0x00000012U /*!< SYSCLK divided by 36 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV38 0x00000013U /*!< SYSCLK divided by 38 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV40 0x00000014U /*!< SYSCLK divided by 40 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV42 0x00000015U /*!< SYSCLK divided by 42 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV44 0x00000016U /*!< SYSCLK divided by 44 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV46 0x00000017U /*!< SYSCLK divided by 46 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV48 0x00000018U /*!< SYSCLK divided by 48 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV50 0x00000019U /*!< SYSCLK divided by 50 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV52 0x0000001AU /*!< SYSCLK divided by 52 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV54 0x0000001BU /*!< SYSCLK divided by 54 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV56 0x0000001CU /*!< SYSCLK divided by 56 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV58 0x0000001DU /*!< SYSCLK divided by 58 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV60 0x0000001EU /*!< SYSCLK divided by 60 */
+#define SMARTCARD_PRESCALER_SYSCLK_DIV62 0x0000001FU /*!< SYSCLK divided by 62 */
+/**
+ * @}
+ */
+
+/** @defgroup SmartCard_Flags SMARTCARD Flags
+ * Elements values convention: 0xXXXX
+ * - 0xXXXX : Flag mask in the SR register
+ * @{
+ */
+#define SMARTCARD_FLAG_TXE ((uint32_t)USART_SR_TXE)
+#define SMARTCARD_FLAG_TC ((uint32_t)USART_SR_TC)
+#define SMARTCARD_FLAG_RXNE ((uint32_t)USART_SR_RXNE)
+#define SMARTCARD_FLAG_IDLE ((uint32_t)USART_SR_IDLE)
+#define SMARTCARD_FLAG_ORE ((uint32_t)USART_SR_ORE)
+#define SMARTCARD_FLAG_NE ((uint32_t)USART_SR_NE)
+#define SMARTCARD_FLAG_FE ((uint32_t)USART_SR_FE)
+#define SMARTCARD_FLAG_PE ((uint32_t)USART_SR_PE)
+/**
+ * @}
+ */
+
+/** @defgroup SmartCard_Interrupt_definition SMARTCARD Interrupts Definition
+ * Elements values convention: 0xY000XXXX
+ * - XXXX : Interrupt mask in the XX register
+ * - Y : Interrupt source register (2bits)
+ * - 01: CR1 register
+ * - 11: CR3 register
+ * @{
+ */
+#define SMARTCARD_IT_PE ((uint32_t)(SMARTCARD_CR1_REG_INDEX << 28U | USART_CR1_PEIE))
+#define SMARTCARD_IT_TXE ((uint32_t)(SMARTCARD_CR1_REG_INDEX << 28U | USART_CR1_TXEIE))
+#define SMARTCARD_IT_TC ((uint32_t)(SMARTCARD_CR1_REG_INDEX << 28U | USART_CR1_TCIE))
+#define SMARTCARD_IT_RXNE ((uint32_t)(SMARTCARD_CR1_REG_INDEX << 28U | USART_CR1_RXNEIE))
+#define SMARTCARD_IT_IDLE ((uint32_t)(SMARTCARD_CR1_REG_INDEX << 28U | USART_CR1_IDLEIE))
+#define SMARTCARD_IT_ERR ((uint32_t)(SMARTCARD_CR3_REG_INDEX << 28U | USART_CR3_EIE))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup SMARTCARD_Exported_Macros SMARTCARD Exported Macros
+ * @{
+ */
+
+/** @brief Reset SMARTCARD handle gstate & RxState
+ * @param __HANDLE__: specifies the SMARTCARD Handle.
+ * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_SMARTCARD_RESET_HANDLE_STATE(__HANDLE__) do{ \
+ (__HANDLE__)->gState = HAL_SMARTCARD_STATE_RESET; \
+ (__HANDLE__)->RxState = HAL_SMARTCARD_STATE_RESET; \
+ } while(0U)
+
+/** @brief Flush the Smartcard DR register
+ * @param __HANDLE__: specifies the SMARTCARD Handle.
+ * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_SMARTCARD_FLUSH_DRREGISTER(__HANDLE__) ((__HANDLE__)->Instance->DR)
+
+/** @brief Check whether the specified Smartcard flag is set or not.
+ * @param __HANDLE__: specifies the SMARTCARD Handle.
+ * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg SMARTCARD_FLAG_TXE: Transmit data register empty flag
+ * @arg SMARTCARD_FLAG_TC: Transmission Complete flag
+ * @arg SMARTCARD_FLAG_RXNE: Receive data register not empty flag
+ * @arg SMARTCARD_FLAG_IDLE: Idle Line detection flag
+ * @arg SMARTCARD_FLAG_ORE: OverRun Error flag
+ * @arg SMARTCARD_FLAG_NE: Noise Error flag
+ * @arg SMARTCARD_FLAG_FE: Framing Error flag
+ * @arg SMARTCARD_FLAG_PE: Parity Error flag
+ * @retval The new state of __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_SMARTCARD_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__))
+
+/** @brief Clear the specified Smartcard pending flags.
+ * @param __HANDLE__: specifies the SMARTCARD Handle.
+ * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be any combination of the following values:
+ * @arg SMARTCARD_FLAG_TC: Transmission Complete flag.
+ * @arg SMARTCARD_FLAG_RXNE: Receive data register not empty flag.
+ *
+ * @note PE (Parity error), FE (Framing error), NE (Noise error) and ORE (OverRun
+ * error) flags are cleared by software sequence: a read operation to
+ * USART_SR register followed by a read operation to USART_DR register.
+ * @note RXNE flag can be also cleared by a read to the USART_DR register.
+ * @note TC flag can be also cleared by software sequence: a read operation to
+ * USART_SR register followed by a write operation to USART_DR register.
+ * @note TXE flag is cleared only by a write to the USART_DR register.
+ */
+#define __HAL_SMARTCARD_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__))
+
+/** @brief Clear the SMARTCARD PE pending flag.
+ * @param __HANDLE__: specifies the USART Handle.
+ * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_SMARTCARD_CLEAR_PEFLAG(__HANDLE__) \
+ do{ \
+ __IO uint32_t tmpreg = 0x00U; \
+ tmpreg = (__HANDLE__)->Instance->SR; \
+ tmpreg = (__HANDLE__)->Instance->DR; \
+ UNUSED(tmpreg); \
+ } while(0U)
+
+/** @brief Clear the SMARTCARD FE pending flag.
+ * @param __HANDLE__: specifies the USART Handle.
+ * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_SMARTCARD_CLEAR_FEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Clear the SMARTCARD NE pending flag.
+ * @param __HANDLE__: specifies the USART Handle.
+ * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_SMARTCARD_CLEAR_NEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Clear the SMARTCARD ORE pending flag.
+ * @param __HANDLE__: specifies the USART Handle.
+ * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_SMARTCARD_CLEAR_OREFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Clear the SMARTCARD IDLE pending flag.
+ * @param __HANDLE__: specifies the USART Handle.
+ * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_SMARTCARD_CLEAR_IDLEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Enable the specified SmartCard interrupt.
+ * @param __HANDLE__: specifies the SMARTCARD Handle.
+ * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ * @param __INTERRUPT__: specifies the SMARTCARD interrupt to enable.
+ * This parameter can be one of the following values:
+ * @arg SMARTCARD_IT_TXE: Transmit Data Register empty interrupt
+ * @arg SMARTCARD_IT_TC: Transmission complete interrupt
+ * @arg SMARTCARD_IT_RXNE: Receive Data register not empty interrupt
+ * @arg SMARTCARD_IT_IDLE: Idle line detection interrupt
+ * @arg SMARTCARD_IT_PE: Parity Error interrupt
+ * @arg SMARTCARD_IT_ERR: Error interrupt(Frame error, noise error, overRun error)
+ */
+#define __HAL_SMARTCARD_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == SMARTCARD_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & SMARTCARD_IT_MASK)): \
+ ((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & SMARTCARD_IT_MASK)))
+
+/** @brief Disable the specified SmartCard interrupt.
+ * @param __HANDLE__: specifies the SMARTCARD Handle.
+ * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ * @param __INTERRUPT__: specifies the SMARTCARD interrupt to disable.
+ * This parameter can be one of the following values:
+ * @arg SMARTCARD_IT_TXE: Transmit Data Register empty interrupt
+ * @arg SMARTCARD_IT_TC: Transmission complete interrupt
+ * @arg SMARTCARD_IT_RXNE: Receive Data register not empty interrupt
+ * @arg SMARTCARD_IT_IDLE: Idle line detection interrupt
+ * @arg SMARTCARD_IT_PE: Parity Error interrupt
+ * @arg SMARTCARD_IT_ERR: Error interrupt(Frame error, noise error, overRun error)
+ */
+#define __HAL_SMARTCARD_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == SMARTCARD_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 &= ~((__INTERRUPT__) & SMARTCARD_IT_MASK)): \
+ ((__HANDLE__)->Instance->CR3 &= ~ ((__INTERRUPT__) & SMARTCARD_IT_MASK)))
+
+/** @brief Checks whether the specified SmartCard interrupt has occurred or not.
+ * @param __HANDLE__: specifies the SmartCard Handle.
+ * @param __IT__: specifies the SMARTCARD interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg SMARTCARD_IT_TXE: Transmit Data Register empty interrupt
+ * @arg SMARTCARD_IT_TC: Transmission complete interrupt
+ * @arg SMARTCARD_IT_RXNE: Receive Data register not empty interrupt
+ * @arg SMARTCARD_IT_IDLE: Idle line detection interrupt
+ * @arg SMARTCARD_IT_ERR: Error interrupt
+ * @arg SMARTCARD_IT_PE: Parity Error interrupt
+ * @retval The new state of __IT__ (TRUE or FALSE).
+ */
+#define __HAL_SMARTCARD_GET_IT_SOURCE(__HANDLE__, __IT__) (((((__IT__) >> 28U) == SMARTCARD_CR1_REG_INDEX)? (__HANDLE__)->Instance->CR1: (__HANDLE__)->Instance->CR3) & (((uint32_t)(__IT__)) & SMARTCARD_IT_MASK))
+
+/** @brief Enable the USART associated to the SMARTCARD Handle
+ * @param __HANDLE__: specifies the SMARTCARD Handle.
+ * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_SMARTCARD_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE)
+
+/** @brief Disable the USART associated to the SMARTCARD Handle
+ * @param __HANDLE__: specifies the SMARTCARD Handle.
+ * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_SMARTCARD_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE)
+
+/** @brief Macros to enable the SmartCard DMA request.
+ * @param __HANDLE__: specifies the SmartCard Handle.
+ * @param __REQUEST__: specifies the SmartCard DMA request.
+ * This parameter can be one of the following values:
+ * @arg SMARTCARD_DMAREQ_TX: SmartCard DMA transmit request
+ * @arg SMARTCARD_DMAREQ_RX: SmartCard DMA receive request
+ */
+#define __HAL_SMARTCARD_DMA_REQUEST_ENABLE(__HANDLE__, __REQUEST__) ((__HANDLE__)->Instance->CR3 |= (__REQUEST__))
+
+/** @brief Macros to disable the SmartCard DMA request.
+ * @param __HANDLE__: specifies the SmartCard Handle.
+ * @param __REQUEST__: specifies the SmartCard DMA request.
+ * This parameter can be one of the following values:
+ * @arg SMARTCARD_DMAREQ_TX: SmartCard DMA transmit request
+ * @arg SMARTCARD_DMAREQ_RX: SmartCard DMA receive request
+ */
+#define __HAL_SMARTCARD_DMA_REQUEST_DISABLE(__HANDLE__, __REQUEST__) ((__HANDLE__)->Instance->CR3 &= ~(__REQUEST__))
+
+/**
+ * @}
+ */
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup SMARTCARD_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup SMARTCARD_Exported_Functions_Group1
+ * @{
+ */
+/* Initialization/de-initialization functions **********************************/
+HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc);
+HAL_StatusTypeDef HAL_SMARTCARD_ReInit(SMARTCARD_HandleTypeDef *hsc);
+HAL_StatusTypeDef HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef *hsc);
+void HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef *hsc);
+void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsc);
+/**
+ * @}
+ */
+
+/** @addtogroup SMARTCARD_Exported_Functions_Group2
+ * @{
+ */
+/* IO operation functions *******************************************************/
+HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size);
+/* Transfer Abort functions */
+HAL_StatusTypeDef HAL_SMARTCARD_Abort(SMARTCARD_HandleTypeDef *hsc);
+HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit(SMARTCARD_HandleTypeDef *hsc);
+HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive(SMARTCARD_HandleTypeDef *hsc);
+HAL_StatusTypeDef HAL_SMARTCARD_Abort_IT(SMARTCARD_HandleTypeDef *hsc);
+HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit_IT(SMARTCARD_HandleTypeDef *hsc);
+HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive_IT(SMARTCARD_HandleTypeDef *hsc);
+
+void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc);
+void HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef *hsc);
+void HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef *hsc);
+void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsc);
+void HAL_SMARTCARD_AbortCpltCallback(SMARTCARD_HandleTypeDef *hsc);
+void HAL_SMARTCARD_AbortTransmitCpltCallback(SMARTCARD_HandleTypeDef *hsc);
+void HAL_SMARTCARD_AbortReceiveCpltCallback(SMARTCARD_HandleTypeDef *hsc);
+/**
+ * @}
+ */
+
+/** @addtogroup SMARTCARD_Exported_Functions_Group3
+ * @{
+ */
+/* Peripheral State functions **************************************************/
+HAL_SMARTCARD_StateTypeDef HAL_SMARTCARD_GetState(SMARTCARD_HandleTypeDef *hsc);
+uint32_t HAL_SMARTCARD_GetError(SMARTCARD_HandleTypeDef *hsc);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup SMARTCARD_Private_Constants SMARTCARD Private Constants
+ * @{
+ */
+
+/** @brief SMARTCARD interruptions flag mask
+ *
+ */
+#define SMARTCARD_IT_MASK 0x0000FFFFU
+
+#define SMARTCARD_CR1_REG_INDEX 1U
+#define SMARTCARD_CR3_REG_INDEX 3U
+/**
+ * @}
+ */
+
+/* Private macros --------------------------------------------------------*/
+/** @defgroup SMARTCARD_Private_Macros SMARTCARD Private Macros
+ * @{
+ */
+#define IS_SMARTCARD_WORD_LENGTH(LENGTH) ((LENGTH) == SMARTCARD_WORDLENGTH_9B)
+#define IS_SMARTCARD_STOPBITS(STOPBITS) (((STOPBITS) == SMARTCARD_STOPBITS_0_5) || \
+ ((STOPBITS) == SMARTCARD_STOPBITS_1_5))
+#define IS_SMARTCARD_PARITY(PARITY) (((PARITY) == SMARTCARD_PARITY_EVEN) || \
+ ((PARITY) == SMARTCARD_PARITY_ODD))
+#define IS_SMARTCARD_MODE(MODE) ((((MODE) & 0x0000FFF3U) == 0x00U) && ((MODE) != 0x000000U))
+#define IS_SMARTCARD_POLARITY(CPOL) (((CPOL) == SMARTCARD_POLARITY_LOW) || ((CPOL) == SMARTCARD_POLARITY_HIGH))
+#define IS_SMARTCARD_PHASE(CPHA) (((CPHA) == SMARTCARD_PHASE_1EDGE) || ((CPHA) == SMARTCARD_PHASE_2EDGE))
+#define IS_SMARTCARD_LASTBIT(LASTBIT) (((LASTBIT) == SMARTCARD_LASTBIT_DISABLE) || \
+ ((LASTBIT) == SMARTCARD_LASTBIT_ENABLE))
+#define IS_SMARTCARD_NACK_STATE(NACK) (((NACK) == SMARTCARD_NACK_ENABLE) || \
+ ((NACK) == SMARTCARD_NACK_DISABLE))
+#define IS_SMARTCARD_BAUDRATE(BAUDRATE) ((BAUDRATE) < 4500001U)
+
+#define SMARTCARD_DIV(_PCLK_, _BAUD_) (((_PCLK_)*25U)/(4U*(_BAUD_)))
+#define SMARTCARD_DIVMANT(_PCLK_, _BAUD_) (SMARTCARD_DIV((_PCLK_), (_BAUD_))/100U)
+#define SMARTCARD_DIVFRAQ(_PCLK_, _BAUD_) (((SMARTCARD_DIV((_PCLK_), (_BAUD_)) - (SMARTCARD_DIVMANT((_PCLK_), (_BAUD_)) * 100U)) * 16U + 50U) / 100U)
+/* SMARTCARD BRR = mantissa + overflow + fraction
+ = (SMARTCARD DIVMANT << 4) + (SMARTCARD DIVFRAQ & 0xF0) + (SMARTCARD DIVFRAQ & 0x0FU) */
+#define SMARTCARD_BRR(_PCLK_, _BAUD_) (((SMARTCARD_DIVMANT((_PCLK_), (_BAUD_)) << 4U) + \
+ (SMARTCARD_DIVFRAQ((_PCLK_), (_BAUD_)) & 0xF0U)) + \
+ (SMARTCARD_DIVFRAQ((_PCLK_), (_BAUD_)) & 0x0FU))
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup SMARTCARD_Private_Functions SMARTCARD Private Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_SMARTCARD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h
new file mode 100644
index 0000000..668d573
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h
@@ -0,0 +1,587 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_spi.h
+ * @author MCD Application Team
+ * @brief Header file of SPI HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_SPI_H
+#define __STM32F1xx_HAL_SPI_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup SPI
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup SPI_Exported_Types SPI Exported Types
+ * @{
+ */
+
+/**
+ * @brief SPI Configuration Structure definition
+ */
+typedef struct
+{
+ uint32_t Mode; /*!< Specifies the SPI operating mode.
+ This parameter can be a value of @ref SPI_Mode */
+
+ uint32_t Direction; /*!< Specifies the SPI Directional mode state.
+ This parameter can be a value of @ref SPI_Direction */
+
+ uint32_t DataSize; /*!< Specifies the SPI data size.
+ This parameter can be a value of @ref SPI_Data_Size */
+
+ uint32_t CLKPolarity; /*!< Specifies the serial clock steady state.
+ This parameter can be a value of @ref SPI_Clock_Polarity */
+
+ uint32_t CLKPhase; /*!< Specifies the clock active edge for the bit capture.
+ This parameter can be a value of @ref SPI_Clock_Phase */
+
+ uint32_t NSS; /*!< Specifies whether the NSS signal is managed by
+ hardware (NSS pin) or by software using the SSI bit.
+ This parameter can be a value of @ref SPI_Slave_Select_management */
+
+ uint32_t BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be
+ used to configure the transmit and receive SCK clock.
+ This parameter can be a value of @ref SPI_BaudRate_Prescaler
+ @note The communication clock is derived from the master
+ clock. The slave clock does not need to be set. */
+
+ uint32_t FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit.
+ This parameter can be a value of @ref SPI_MSB_LSB_transmission */
+
+ uint32_t TIMode; /*!< Specifies if the TI mode is enabled or not.
+ This parameter can be a value of @ref SPI_TI_mode */
+
+ uint32_t CRCCalculation; /*!< Specifies if the CRC calculation is enabled or not.
+ This parameter can be a value of @ref SPI_CRC_Calculation */
+
+ uint32_t CRCPolynomial; /*!< Specifies the polynomial used for the CRC calculation.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 65535 */
+}SPI_InitTypeDef;
+
+/**
+ * @brief HAL SPI State structure definition
+ */
+typedef enum
+{
+ HAL_SPI_STATE_RESET = 0x00U, /*!< Peripheral not Initialized */
+ HAL_SPI_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */
+ HAL_SPI_STATE_BUSY = 0x02U, /*!< an internal process is ongoing */
+ HAL_SPI_STATE_BUSY_TX = 0x03U, /*!< Data Transmission process is ongoing */
+ HAL_SPI_STATE_BUSY_RX = 0x04U, /*!< Data Reception process is ongoing */
+ HAL_SPI_STATE_BUSY_TX_RX = 0x05U, /*!< Data Transmission and Reception process is ongoing */
+ HAL_SPI_STATE_ERROR = 0x06U /*!< SPI error state */
+}HAL_SPI_StateTypeDef;
+
+/**
+ * @brief SPI handle Structure definition
+ */
+typedef struct __SPI_HandleTypeDef
+{
+ SPI_TypeDef *Instance; /*!< SPI registers base address */
+
+ SPI_InitTypeDef Init; /*!< SPI communication parameters */
+
+ uint8_t *pTxBuffPtr; /*!< Pointer to SPI Tx transfer Buffer */
+
+ uint16_t TxXferSize; /*!< SPI Tx Transfer size */
+
+ __IO uint16_t TxXferCount; /*!< SPI Tx Transfer Counter */
+
+ uint8_t *pRxBuffPtr; /*!< Pointer to SPI Rx transfer Buffer */
+
+ uint16_t RxXferSize; /*!< SPI Rx Transfer size */
+
+ __IO uint16_t RxXferCount; /*!< SPI Rx Transfer Counter */
+
+ void (*RxISR)(struct __SPI_HandleTypeDef * hspi); /*!< function pointer on Rx ISR */
+
+ void (*TxISR)(struct __SPI_HandleTypeDef * hspi); /*!< function pointer on Tx ISR */
+
+ DMA_HandleTypeDef *hdmatx; /*!< SPI Tx DMA Handle parameters */
+
+ DMA_HandleTypeDef *hdmarx; /*!< SPI Rx DMA Handle parameters */
+
+ HAL_LockTypeDef Lock; /*!< Locking object */
+
+ __IO HAL_SPI_StateTypeDef State; /*!< SPI communication state */
+
+ __IO uint32_t ErrorCode; /*!< SPI Error code */
+
+}SPI_HandleTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup SPI_Exported_Constants SPI Exported Constants
+ * @{
+ */
+
+/** @defgroup SPI_Error_Code SPI Error Code
+ * @{
+ */
+#define HAL_SPI_ERROR_NONE 0x00000000U /*!< No error */
+#define HAL_SPI_ERROR_MODF 0x00000001U /*!< MODF error */
+#define HAL_SPI_ERROR_CRC 0x00000002U /*!< CRC error */
+#define HAL_SPI_ERROR_OVR 0x00000004U /*!< OVR error */
+#define HAL_SPI_ERROR_FRE 0x00000008U /*!< FRE error */
+#define HAL_SPI_ERROR_DMA 0x00000010U /*!< DMA transfer error */
+#define HAL_SPI_ERROR_FLAG 0x00000020U /*!< Flag: RXNE,TXE, BSY */
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Mode SPI Mode
+ * @{
+ */
+#define SPI_MODE_SLAVE 0x00000000U
+#define SPI_MODE_MASTER (SPI_CR1_MSTR | SPI_CR1_SSI)
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Direction SPI Direction Mode
+ * @{
+ */
+#define SPI_DIRECTION_2LINES 0x00000000U
+#define SPI_DIRECTION_2LINES_RXONLY SPI_CR1_RXONLY
+#define SPI_DIRECTION_1LINE SPI_CR1_BIDIMODE
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Data_Size SPI Data Size
+ * @{
+ */
+#define SPI_DATASIZE_8BIT 0x00000000U
+#define SPI_DATASIZE_16BIT SPI_CR1_DFF
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Clock_Polarity SPI Clock Polarity
+ * @{
+ */
+#define SPI_POLARITY_LOW 0x00000000U
+#define SPI_POLARITY_HIGH SPI_CR1_CPOL
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Clock_Phase SPI Clock Phase
+ * @{
+ */
+#define SPI_PHASE_1EDGE 0x00000000U
+#define SPI_PHASE_2EDGE SPI_CR1_CPHA
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Slave_Select_management SPI Slave Select Management
+ * @{
+ */
+#define SPI_NSS_SOFT SPI_CR1_SSM
+#define SPI_NSS_HARD_INPUT 0x00000000U
+#define SPI_NSS_HARD_OUTPUT ((uint32_t)(SPI_CR2_SSOE << 16))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_BaudRate_Prescaler SPI BaudRate Prescaler
+ * @{
+ */
+#define SPI_BAUDRATEPRESCALER_2 0x00000000U
+#define SPI_BAUDRATEPRESCALER_4 SPI_CR1_BR_0
+#define SPI_BAUDRATEPRESCALER_8 SPI_CR1_BR_1
+#define SPI_BAUDRATEPRESCALER_16 (uint32_t)(SPI_CR1_BR_1 | SPI_CR1_BR_0)
+#define SPI_BAUDRATEPRESCALER_32 SPI_CR1_BR_2
+#define SPI_BAUDRATEPRESCALER_64 (uint32_t)(SPI_CR1_BR_2 | SPI_CR1_BR_0)
+#define SPI_BAUDRATEPRESCALER_128 (uint32_t)(SPI_CR1_BR_2 | SPI_CR1_BR_1)
+#define SPI_BAUDRATEPRESCALER_256 (uint32_t)(SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0)
+
+/**
+ * @}
+ */
+
+/** @defgroup SPI_MSB_LSB_transmission SPI MSB LSB Transmission
+ * @{
+ */
+#define SPI_FIRSTBIT_MSB 0x00000000U
+#define SPI_FIRSTBIT_LSB SPI_CR1_LSBFIRST
+/**
+ * @}
+ */
+
+/** @defgroup SPI_TI_mode SPI TI Mode
+ * @{
+ */
+#define SPI_TIMODE_DISABLE 0x00000000U
+/**
+ * @}
+ */
+
+/** @defgroup SPI_CRC_Calculation SPI CRC Calculation
+ * @{
+ */
+#define SPI_CRCCALCULATION_DISABLE 0x00000000U
+#define SPI_CRCCALCULATION_ENABLE SPI_CR1_CRCEN
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Interrupt_definition SPI Interrupt Definition
+ * @{
+ */
+#define SPI_IT_TXE SPI_CR2_TXEIE
+#define SPI_IT_RXNE SPI_CR2_RXNEIE
+#define SPI_IT_ERR SPI_CR2_ERRIE
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Flags_definition SPI Flags Definition
+ * @{
+ */
+#define SPI_FLAG_RXNE SPI_SR_RXNE /* SPI status flag: Rx buffer not empty flag */
+#define SPI_FLAG_TXE SPI_SR_TXE /* SPI status flag: Tx buffer empty flag */
+#define SPI_FLAG_BSY SPI_SR_BSY /* SPI status flag: Busy flag */
+#define SPI_FLAG_CRCERR SPI_SR_CRCERR /* SPI Error flag: CRC error flag */
+#define SPI_FLAG_MODF SPI_SR_MODF /* SPI Error flag: Mode fault flag */
+#define SPI_FLAG_OVR SPI_SR_OVR /* SPI Error flag: Overrun flag */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup SPI_Exported_Macros SPI Exported Macros
+ * @{
+ */
+
+/** @brief Reset SPI handle state.
+ * @param __HANDLE__: specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @retval None
+ */
+#define __HAL_SPI_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SPI_STATE_RESET)
+
+/** @brief Enable the specified SPI interrupts.
+ * @param __HANDLE__: specifies the SPI handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @param __INTERRUPT__: specifies the interrupt source to enable.
+ * This parameter can be one of the following values:
+ * @arg SPI_IT_TXE: Tx buffer empty interrupt enable
+ * @arg SPI_IT_RXNE: RX buffer not empty interrupt enable
+ * @arg SPI_IT_ERR: Error interrupt enable
+ * @retval None
+ */
+#define __HAL_SPI_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 |= (__INTERRUPT__))
+
+/** @brief Disable the specified SPI interrupts.
+ * @param __HANDLE__: specifies the SPI handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @param __INTERRUPT__: specifies the interrupt source to disable.
+ * This parameter can be one of the following values:
+ * @arg SPI_IT_TXE: Tx buffer empty interrupt enable
+ * @arg SPI_IT_RXNE: RX buffer not empty interrupt enable
+ * @arg SPI_IT_ERR: Error interrupt enable
+ * @retval None
+ */
+#define __HAL_SPI_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 &= (~(__INTERRUPT__)))
+
+/** @brief Check whether the specified SPI interrupt source is enabled or not.
+ * @param __HANDLE__: specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @param __INTERRUPT__: specifies the SPI interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg SPI_IT_TXE: Tx buffer empty interrupt enable
+ * @arg SPI_IT_RXNE: RX buffer not empty interrupt enable
+ * @arg SPI_IT_ERR: Error interrupt enable
+ * @retval The new state of __IT__ (TRUE or FALSE).
+ */
+#define __HAL_SPI_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
+
+/** @brief Check whether the specified SPI flag is set or not.
+ * @param __HANDLE__: specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg SPI_FLAG_RXNE: Receive buffer not empty flag
+ * @arg SPI_FLAG_TXE: Transmit buffer empty flag
+ * @arg SPI_FLAG_CRCERR: CRC error flag
+ * @arg SPI_FLAG_MODF: Mode fault flag
+ * @arg SPI_FLAG_OVR: Overrun flag
+ * @arg SPI_FLAG_BSY: Busy flag
+ * @retval The new state of __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_SPI_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__))
+
+/** @brief Clear the SPI CRCERR pending flag.
+ * @param __HANDLE__: specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @retval None
+ */
+#define __HAL_SPI_CLEAR_CRCERRFLAG(__HANDLE__) ((__HANDLE__)->Instance->SR = (uint16_t)(~SPI_FLAG_CRCERR))
+
+/** @brief Clear the SPI MODF pending flag.
+ * @param __HANDLE__: specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @retval None
+ */
+#define __HAL_SPI_CLEAR_MODFFLAG(__HANDLE__) \
+do{ \
+ __IO uint32_t tmpreg_modf = 0x00U; \
+ tmpreg_modf = (__HANDLE__)->Instance->SR; \
+ (__HANDLE__)->Instance->CR1 &= (~SPI_CR1_SPE); \
+ UNUSED(tmpreg_modf); \
+ } while(0U)
+
+/** @brief Clear the SPI OVR pending flag.
+ * @param __HANDLE__: specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @retval None
+ */
+#define __HAL_SPI_CLEAR_OVRFLAG(__HANDLE__) \
+do{ \
+ __IO uint32_t tmpreg_ovr = 0x00U; \
+ tmpreg_ovr = (__HANDLE__)->Instance->DR; \
+ tmpreg_ovr = (__HANDLE__)->Instance->SR; \
+ UNUSED(tmpreg_ovr); \
+ } while(0U)
+
+
+/** @brief Enable the SPI peripheral.
+ * @param __HANDLE__: specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @retval None
+ */
+#define __HAL_SPI_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= SPI_CR1_SPE)
+
+/** @brief Disable the SPI peripheral.
+ * @param __HANDLE__: specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @retval None
+ */
+#define __HAL_SPI_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= (~SPI_CR1_SPE))
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup SPI_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup SPI_Exported_Functions_Group1
+ * @{
+ */
+/* Initialization/de-initialization functions **********************************/
+HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi);
+HAL_StatusTypeDef HAL_SPI_DeInit (SPI_HandleTypeDef *hspi);
+void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi);
+void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi);
+/**
+ * @}
+ */
+
+/** @addtogroup SPI_Exported_Functions_Group2
+ * @{
+ */
+/* I/O operation functions *****************************************************/
+HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size);
+HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size);
+HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi);
+HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi);
+HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi);
+/* Transfer Abort functions */
+HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi);
+HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi);
+
+void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi);
+void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi);
+/**
+ * @}
+ */
+
+/** @addtogroup SPI_Exported_Functions_Group3
+ * @{
+ */
+/* Peripheral State and Error functions ***************************************/
+HAL_SPI_StateTypeDef HAL_SPI_GetState(SPI_HandleTypeDef *hspi);
+uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup SPI_Private_Constants SPI Private Constants
+ * @{
+ */
+#define SPI_INVALID_CRC_ERROR 0U /* CRC error wrongly detected */
+#define SPI_VALID_CRC_ERROR 1U /* CRC error is true */
+/**
+ * @}
+ */
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup SPI_Private_Macros SPI Private Macros
+ * @{
+ */
+
+/** @brief Set the SPI transmit-only mode.
+ * @param __HANDLE__: specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @retval None
+ */
+#define SPI_1LINE_TX(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= SPI_CR1_BIDIOE)
+
+/** @brief Set the SPI receive-only mode.
+ * @param __HANDLE__: specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @retval None
+ */
+#define SPI_1LINE_RX(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= (~SPI_CR1_BIDIOE))
+
+/** @brief Reset the CRC calculation of the SPI.
+ * @param __HANDLE__: specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @retval None
+ */
+#define SPI_RESET_CRC(__HANDLE__) do{(__HANDLE__)->Instance->CR1 &= (uint16_t)(~SPI_CR1_CRCEN);\
+ (__HANDLE__)->Instance->CR1 |= SPI_CR1_CRCEN;}while(0U)
+
+#define IS_SPI_MODE(MODE) (((MODE) == SPI_MODE_SLAVE) || \
+ ((MODE) == SPI_MODE_MASTER))
+
+#define IS_SPI_DIRECTION(MODE) (((MODE) == SPI_DIRECTION_2LINES) || \
+ ((MODE) == SPI_DIRECTION_2LINES_RXONLY) || \
+ ((MODE) == SPI_DIRECTION_1LINE))
+
+#define IS_SPI_DIRECTION_2LINES(MODE) ((MODE) == SPI_DIRECTION_2LINES)
+
+#define IS_SPI_DIRECTION_2LINES_OR_1LINE(MODE) (((MODE) == SPI_DIRECTION_2LINES) || \
+ ((MODE) == SPI_DIRECTION_1LINE))
+
+#define IS_SPI_DATASIZE(DATASIZE) (((DATASIZE) == SPI_DATASIZE_16BIT) || \
+ ((DATASIZE) == SPI_DATASIZE_8BIT))
+
+#define IS_SPI_CPOL(CPOL) (((CPOL) == SPI_POLARITY_LOW) || \
+ ((CPOL) == SPI_POLARITY_HIGH))
+
+#define IS_SPI_CPHA(CPHA) (((CPHA) == SPI_PHASE_1EDGE) || \
+ ((CPHA) == SPI_PHASE_2EDGE))
+
+#define IS_SPI_NSS(NSS) (((NSS) == SPI_NSS_SOFT) || \
+ ((NSS) == SPI_NSS_HARD_INPUT) || \
+ ((NSS) == SPI_NSS_HARD_OUTPUT))
+
+#define IS_SPI_BAUDRATE_PRESCALER(PRESCALER) (((PRESCALER) == SPI_BAUDRATEPRESCALER_2) || \
+ ((PRESCALER) == SPI_BAUDRATEPRESCALER_4) || \
+ ((PRESCALER) == SPI_BAUDRATEPRESCALER_8) || \
+ ((PRESCALER) == SPI_BAUDRATEPRESCALER_16) || \
+ ((PRESCALER) == SPI_BAUDRATEPRESCALER_32) || \
+ ((PRESCALER) == SPI_BAUDRATEPRESCALER_64) || \
+ ((PRESCALER) == SPI_BAUDRATEPRESCALER_128) || \
+ ((PRESCALER) == SPI_BAUDRATEPRESCALER_256))
+
+#define IS_SPI_FIRST_BIT(BIT) (((BIT) == SPI_FIRSTBIT_MSB) || \
+ ((BIT) == SPI_FIRSTBIT_LSB))
+
+#define IS_SPI_CRC_CALCULATION(CALCULATION) (((CALCULATION) == SPI_CRCCALCULATION_DISABLE) || \
+ ((CALCULATION) == SPI_CRCCALCULATION_ENABLE))
+
+#define IS_SPI_CRC_POLYNOMIAL(POLYNOMIAL) (((POLYNOMIAL) >= 0x01U) && ((POLYNOMIAL) <= 0xFFFFU))
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup SPI_Private_Functions SPI Private Functions
+ * @{
+ */
+uint8_t SPI_ISCRCErrorValid(SPI_HandleTypeDef *hspi);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_SPI_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sram.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sram.h
new file mode 100644
index 0000000..6c8d489
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sram.h
@@ -0,0 +1,199 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_sram.h
+ * @author MCD Application Team
+ * @brief Header file of SRAM HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_SRAM_H
+#define __STM32F1xx_HAL_SRAM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_fsmc.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG) || defined(STM32F100xE)
+
+/** @addtogroup SRAM
+ * @{
+ */
+
+/* Exported typedef ----------------------------------------------------------*/
+
+/** @defgroup SRAM_Exported_Types SRAM Exported Types
+ * @{
+ */
+/**
+ * @brief HAL SRAM State structures definition
+ */
+typedef enum
+{
+ HAL_SRAM_STATE_RESET = 0x00U, /*!< SRAM not yet initialized or disabled */
+ HAL_SRAM_STATE_READY = 0x01U, /*!< SRAM initialized and ready for use */
+ HAL_SRAM_STATE_BUSY = 0x02U, /*!< SRAM internal process is ongoing */
+ HAL_SRAM_STATE_ERROR = 0x03U, /*!< SRAM error state */
+ HAL_SRAM_STATE_PROTECTED = 0x04U /*!< SRAM peripheral NORSRAM device write protected */
+
+}HAL_SRAM_StateTypeDef;
+
+/**
+ * @brief SRAM handle Structure definition
+ */
+typedef struct
+{
+ FSMC_NORSRAM_TypeDef *Instance; /*!< Register base address */
+
+ FSMC_NORSRAM_EXTENDED_TypeDef *Extended; /*!< Extended mode register base address */
+
+ FSMC_NORSRAM_InitTypeDef Init; /*!< SRAM device control configuration parameters */
+
+ HAL_LockTypeDef Lock; /*!< SRAM locking object */
+
+ __IO HAL_SRAM_StateTypeDef State; /*!< SRAM device access state */
+
+ DMA_HandleTypeDef *hdma; /*!< Pointer DMA handler */
+
+}SRAM_HandleTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+
+/** @defgroup SRAM_Exported_Macros SRAM Exported Macros
+ * @{
+ */
+
+/** @brief Reset SRAM handle state
+ * @param __HANDLE__: SRAM handle
+ * @retval None
+ */
+#define __HAL_SRAM_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SRAM_STATE_RESET)
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @addtogroup SRAM_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup SRAM_Exported_Functions_Group1
+ * @{
+ */
+
+/* Initialization/de-initialization functions **********************************/
+HAL_StatusTypeDef HAL_SRAM_Init(SRAM_HandleTypeDef *hsram, FSMC_NORSRAM_TimingTypeDef *Timing, FSMC_NORSRAM_TimingTypeDef *ExtTiming);
+HAL_StatusTypeDef HAL_SRAM_DeInit(SRAM_HandleTypeDef *hsram);
+void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram);
+void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef *hsram);
+
+void HAL_SRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma);
+void HAL_SRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma);
+
+/**
+ * @}
+ */
+
+/** @addtogroup SRAM_Exported_Functions_Group2
+ * @{
+ */
+
+/* I/O operation functions *****************************************************/
+HAL_StatusTypeDef HAL_SRAM_Read_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pDstBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Write_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pSrcBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Read_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pDstBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Write_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pSrcBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Read_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Write_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Read_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef HAL_SRAM_Write_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize);
+
+/**
+ * @}
+ */
+
+/** @addtogroup SRAM_Exported_Functions_Group3
+ * @{
+ */
+
+/* SRAM Control functions ******************************************************/
+HAL_StatusTypeDef HAL_SRAM_WriteOperation_Enable(SRAM_HandleTypeDef *hsram);
+HAL_StatusTypeDef HAL_SRAM_WriteOperation_Disable(SRAM_HandleTypeDef *hsram);
+
+/**
+ * @}
+ */
+
+/** @addtogroup SRAM_Exported_Functions_Group4
+ * @{
+ */
+
+/* SRAM State functions *********************************************************/
+HAL_SRAM_StateTypeDef HAL_SRAM_GetState(SRAM_HandleTypeDef *hsram);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG || STM32F100xE */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_SRAM_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h
rename to templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h
new file mode 100644
index 0000000..3ad03bf
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h
@@ -0,0 +1,343 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_tim_ex.h
+ * @author MCD Application Team
+ * @brief Header file of TIM HAL Extension module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_TIM_EX_H
+#define __STM32F1xx_HAL_TIM_EX_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup TIMEx
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup TIMEx_Exported_Types TIMEx Exported Types
+ * @{
+ */
+
+
+/**
+ * @brief TIM Hall sensor Configuration Structure definition
+ */
+
+typedef struct
+{
+
+ uint32_t IC1Polarity; /*!< Specifies the active edge of the input signal.
+ This parameter can be a value of @ref TIM_Input_Capture_Polarity */
+
+ uint32_t IC1Prescaler; /*!< Specifies the Input Capture Prescaler.
+ This parameter can be a value of @ref TIM_Input_Capture_Prescaler */
+
+ uint32_t IC1Filter; /*!< Specifies the input capture filter.
+ This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
+ uint32_t Commutation_Delay; /*!< Specifies the pulse value to be loaded into the Capture Compare Register.
+ This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */
+} TIM_HallSensor_InitTypeDef;
+
+
+#if defined (STM32F100xB) || defined (STM32F100xE) || \
+ defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
+ defined (STM32F105xC) || defined (STM32F107xC)
+
+/**
+ * @brief TIM Break and Dead time configuration Structure definition
+ */
+typedef struct
+{
+ uint32_t OffStateRunMode; /*!< TIM off state in run mode
+ This parameter can be a value of @ref TIM_OSSR_Off_State_Selection_for_Run_mode_state */
+ uint32_t OffStateIDLEMode; /*!< TIM off state in IDLE mode
+ This parameter can be a value of @ref TIM_OSSI_Off_State_Selection_for_Idle_mode_state */
+ uint32_t LockLevel; /*!< TIM Lock level
+ This parameter can be a value of @ref TIM_Lock_level */
+ uint32_t DeadTime; /*!< TIM dead Time
+ This parameter can be a number between Min_Data = 0x00 and Max_Data = 0xFF */
+ uint32_t BreakState; /*!< TIM Break State
+ This parameter can be a value of @ref TIM_Break_Input_enable_disable */
+ uint32_t BreakPolarity; /*!< TIM Break input polarity
+ This parameter can be a value of @ref TIM_Break_Polarity */
+ uint32_t AutomaticOutput; /*!< TIM Automatic Output Enable state
+ This parameter can be a value of @ref TIM_AOE_Bit_Set_Reset */
+} TIM_BreakDeadTimeConfigTypeDef;
+
+#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
+ /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
+ /* defined(STM32F105xC) || defined(STM32F107xC) */
+
+/**
+ * @brief TIM Master configuration Structure definition
+ */
+typedef struct {
+ uint32_t MasterOutputTrigger; /*!< Trigger output (TRGO) selection
+ This parameter can be a value of @ref TIM_Master_Mode_Selection */
+ uint32_t MasterSlaveMode; /*!< Master/slave mode selection
+ This parameter can be a value of @ref TIM_Master_Slave_Mode */
+}TIM_MasterConfigTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+#if defined (STM32F100xB) || defined (STM32F100xE) || \
+ defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
+ defined (STM32F105xC) || defined (STM32F107xC)
+/** @defgroup TIMEx_Exported_Constants TIMEx Exported Constants
+ * @{
+ */
+
+/** @defgroup TIMEx_Clock_Filter TIMEx Clock Filter
+ * @{
+ */
+#define IS_TIM_DEADTIME(DEADTIME) ((DEADTIME) <= 0xFFU) /*!< BreakDead Time */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
+ /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
+ /* defined(STM32F105xC) || defined(STM32F107xC) */
+
+/* Exported macro ------------------------------------------------------------*/
+/**
+ * @brief Sets the TIM Output compare preload.
+ * @param __HANDLE__: TIM handle.
+ * @param __CHANNEL__: TIM Channels to be configured.
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval None
+ */
+#define __HAL_TIM_ENABLE_OCxPRELOAD(__HANDLE__, __CHANNEL__) \
+ (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC1PE) :\
+ ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC2PE) :\
+ ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC3PE) :\
+ ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC4PE))
+
+/**
+ * @brief Resets the TIM Output compare preload.
+ * @param __HANDLE__: TIM handle.
+ * @param __CHANNEL__: TIM Channels to be configured.
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval None
+ */
+#define __HAL_TIM_DISABLE_OCxPRELOAD(__HANDLE__, __CHANNEL__) \
+ (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 &= (uint16_t)~TIM_CCMR1_OC1PE) :\
+ ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 &= (uint16_t)~TIM_CCMR1_OC2PE) :\
+ ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 &= (uint16_t)~TIM_CCMR2_OC3PE) :\
+ ((__HANDLE__)->Instance->CCMR2 &= (uint16_t)~TIM_CCMR2_OC4PE))
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup TIMEx_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup TIMEx_Exported_Functions_Group1
+ * @{
+ */
+/* Timer Hall Sensor functions **********************************************/
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, TIM_HallSensor_InitTypeDef* sConfig);
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim);
+
+void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim);
+void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim);
+
+ /* Blocking mode: Polling */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim);
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim);
+/* Non-Blocking mode: Interrupt */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim);
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim);
+/* Non-Blocking mode: DMA */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length);
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim);
+/**
+ * @}
+ */
+
+#if defined (STM32F100xB) || defined (STM32F100xE) || \
+ defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
+ defined (STM32F105xC) || defined (STM32F107xC)
+
+/** @addtogroup TIMEx_Exported_Functions_Group2
+ * @{
+ */
+/* Timer Complementary Output Compare functions *****************************/
+/* Blocking mode: Polling */
+HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
+HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
+
+/* Non-Blocking mode: Interrupt */
+HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
+HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
+
+/* Non-Blocking mode: DMA */
+HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length);
+HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel);
+/**
+ * @}
+ */
+
+/** @addtogroup TIMEx_Exported_Functions_Group3
+ * @{
+ */
+/* Timer Complementary PWM functions ****************************************/
+/* Blocking mode: Polling */
+HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
+HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
+
+/* Non-Blocking mode: Interrupt */
+HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
+HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
+/* Non-Blocking mode: DMA */
+HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length);
+HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel);
+/**
+ * @}
+ */
+
+/** @addtogroup TIMEx_Exported_Functions_Group4
+ * @{
+ */
+/* Timer Complementary One Pulse functions **********************************/
+/* Blocking mode: Polling */
+HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
+HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
+
+/* Non-Blocking mode: Interrupt */
+HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
+HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
+/**
+ * @}
+ */
+#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
+ /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
+ /* defined(STM32F105xC) || defined(STM32F107xC) */
+
+/** @addtogroup TIMEx_Exported_Functions_Group5
+ * @{
+ */
+/* Extended Control functions ************************************************/
+#if defined (STM32F100xB) || defined (STM32F100xE) || \
+ defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
+ defined (STM32F105xC) || defined (STM32F107xC)
+HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource);
+HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent_IT(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource);
+HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent_DMA(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource);
+HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim, TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig);
+#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
+ /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
+ /* defined(STM32F105xC) || defined(STM32F107xC) */
+HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim, TIM_MasterConfigTypeDef * sMasterConfig);
+/**
+ * @}
+ */
+
+/** @addtogroup TIMEx_Exported_Functions_Group6
+ * @{
+ */
+/* Extension Callback *********************************************************/
+void HAL_TIMEx_CommutationCallback(TIM_HandleTypeDef *htim);
+void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim);
+/**
+ * @}
+ */
+
+#if defined (STM32F100xB) || defined (STM32F100xE) || \
+ defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
+ defined (STM32F105xC) || defined (STM32F107xC)
+/** @addtogroup TIMEx_Exported_Functions_Group7
+ * @{
+ */
+/* Extension Peripheral State functions **************************************/
+HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(TIM_HandleTypeDef *htim);
+/**
+ * @}
+ */
+#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
+ /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
+ /* defined(STM32F105xC) || defined(STM32F107xC) */
+
+/**
+ * @}
+ */
+/* End of exported functions -------------------------------------------------*/
+
+/* Private functions----------------------------------------------------------*/
+/** @defgroup TIMEx_Private_Functions TIMEx Private Functions
+* @{
+*/
+void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma);
+/**
+* @}
+*/
+/* End of private functions --------------------------------------------------*/
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __STM32F1xx_HAL_TIM_EX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h
new file mode 100644
index 0000000..8e2b2ed
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h
@@ -0,0 +1,785 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_uart.h
+ * @author MCD Application Team
+ * @brief Header file of UART HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_UART_H
+#define __STM32F1xx_HAL_UART_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup UART
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup UART_Exported_Types UART Exported Types
+ * @{
+ */
+
+/**
+ * @brief UART Init Structure definition
+ */
+typedef struct
+{
+ uint32_t BaudRate; /*!< This member configures the UART communication baud rate.
+ The baud rate is computed using the following formula:
+ - IntegerDivider = ((PCLKx) / (16 * (huart->Init.BaudRate)))
+ - FractionalDivider = ((IntegerDivider - ((uint32_t) IntegerDivider)) * 16) + 0.5 */
+
+ uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame.
+ This parameter can be a value of @ref UART_Word_Length */
+
+ uint32_t StopBits; /*!< Specifies the number of stop bits transmitted.
+ This parameter can be a value of @ref UART_Stop_Bits */
+
+ uint32_t Parity; /*!< Specifies the parity mode.
+ This parameter can be a value of @ref UART_Parity
+ @note When parity is enabled, the computed parity is inserted
+ at the MSB position of the transmitted data (9th bit when
+ the word length is set to 9 data bits; 8th bit when the
+ word length is set to 8 data bits). */
+
+ uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.
+ This parameter can be a value of @ref UART_Mode */
+
+ uint32_t HwFlowCtl; /*!< Specifies whether the hardware flow control mode is enabled or disabled.
+ This parameter can be a value of @ref UART_Hardware_Flow_Control */
+
+ uint32_t OverSampling; /*!< Specifies whether the Over sampling 8 is enabled or disabled, to achieve higher speed (up to fPCLK/8).
+ This parameter can be a value of @ref UART_Over_Sampling. This feature is only available
+ on STM32F100xx family, so OverSampling parameter should always be set to 16. */
+}UART_InitTypeDef;
+
+/**
+ * @brief HAL UART State structures definition
+ * @note HAL UART State value is a combination of 2 different substates: gState and RxState.
+ * - gState contains UART state information related to global Handle management
+ * and also information related to Tx operations.
+ * gState value coding follow below described bitmap :
+ * b7-b6 Error information
+ * 00 : No Error
+ * 01 : (Not Used)
+ * 10 : Timeout
+ * 11 : Error
+ * b5 IP initilisation status
+ * 0 : Reset (IP not initialized)
+ * 1 : Init done (IP not initialized. HAL UART Init function already called)
+ * b4-b3 (not used)
+ * xx : Should be set to 00
+ * b2 Intrinsic process state
+ * 0 : Ready
+ * 1 : Busy (IP busy with some configuration or internal operations)
+ * b1 (not used)
+ * x : Should be set to 0
+ * b0 Tx state
+ * 0 : Ready (no Tx operation ongoing)
+ * 1 : Busy (Tx operation ongoing)
+ * - RxState contains information related to Rx operations.
+ * RxState value coding follow below described bitmap :
+ * b7-b6 (not used)
+ * xx : Should be set to 00
+ * b5 IP initilisation status
+ * 0 : Reset (IP not initialized)
+ * 1 : Init done (IP not initialized)
+ * b4-b2 (not used)
+ * xxx : Should be set to 000
+ * b1 Rx state
+ * 0 : Ready (no Rx operation ongoing)
+ * 1 : Busy (Rx operation ongoing)
+ * b0 (not used)
+ * x : Should be set to 0.
+ */
+typedef enum
+{
+ HAL_UART_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized
+ Value is allowed for gState and RxState */
+ HAL_UART_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use
+ Value is allowed for gState and RxState */
+ HAL_UART_STATE_BUSY = 0x24U, /*!< an internal process is ongoing
+ Value is allowed for gState only */
+ HAL_UART_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing
+ Value is allowed for gState only */
+ HAL_UART_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing
+ Value is allowed for RxState only */
+ HAL_UART_STATE_BUSY_TX_RX = 0x23U, /*!< Data Transmission and Reception process is ongoing
+ Not to be used for neither gState nor RxState.
+ Value is result of combination (Or) between gState and RxState values */
+ HAL_UART_STATE_TIMEOUT = 0xA0U, /*!< Timeout state
+ Value is allowed for gState only */
+ HAL_UART_STATE_ERROR = 0xE0U /*!< Error
+ Value is allowed for gState only */
+}HAL_UART_StateTypeDef;
+
+/**
+ * @brief UART handle Structure definition
+ */
+typedef struct
+{
+ USART_TypeDef *Instance; /*!< UART registers base address */
+
+ UART_InitTypeDef Init; /*!< UART communication parameters */
+
+ uint8_t *pTxBuffPtr; /*!< Pointer to UART Tx transfer Buffer */
+
+ uint16_t TxXferSize; /*!< UART Tx Transfer size */
+
+ __IO uint16_t TxXferCount; /*!< UART Tx Transfer Counter */
+
+ uint8_t *pRxBuffPtr; /*!< Pointer to UART Rx transfer Buffer */
+
+ uint16_t RxXferSize; /*!< UART Rx Transfer size */
+
+ __IO uint16_t RxXferCount; /*!< UART Rx Transfer Counter */
+
+ DMA_HandleTypeDef *hdmatx; /*!< UART Tx DMA Handle parameters */
+
+ DMA_HandleTypeDef *hdmarx; /*!< UART Rx DMA Handle parameters */
+
+ HAL_LockTypeDef Lock; /*!< Locking object */
+
+ __IO HAL_UART_StateTypeDef gState; /*!< UART state information related to global Handle management
+ and also related to Tx operations.
+ This parameter can be a value of @ref HAL_UART_StateTypeDef */
+
+ __IO HAL_UART_StateTypeDef RxState; /*!< UART state information related to Rx operations.
+ This parameter can be a value of @ref HAL_UART_StateTypeDef */
+
+ __IO uint32_t ErrorCode; /*!< UART Error code */
+}UART_HandleTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup UART_Exported_Constants UART Exported constants
+ * @{
+ */
+
+/** @defgroup UART_Error_Code UART Error Code
+ * @{
+ */
+#define HAL_UART_ERROR_NONE 0x00000000U /*!< No error */
+#define HAL_UART_ERROR_PE 0x00000001U /*!< Parity error */
+#define HAL_UART_ERROR_NE 0x00000002U /*!< Noise error */
+#define HAL_UART_ERROR_FE 0x00000004U /*!< Frame error */
+#define HAL_UART_ERROR_ORE 0x00000008U /*!< Overrun error */
+#define HAL_UART_ERROR_DMA 0x00000010U /*!< DMA transfer error */
+/**
+ * @}
+ */
+
+/** @defgroup UART_Word_Length UART Word Length
+ * @{
+ */
+#define UART_WORDLENGTH_8B 0x00000000U
+#define UART_WORDLENGTH_9B ((uint32_t)USART_CR1_M)
+/**
+ * @}
+ */
+
+/** @defgroup UART_Stop_Bits UART Number of Stop Bits
+ * @{
+ */
+#define UART_STOPBITS_1 0x00000000U
+#define UART_STOPBITS_2 ((uint32_t)USART_CR2_STOP_1)
+/**
+ * @}
+ */
+
+/** @defgroup UART_Parity UART Parity
+ * @{
+ */
+#define UART_PARITY_NONE 0x00000000U
+#define UART_PARITY_EVEN ((uint32_t)USART_CR1_PCE)
+#define UART_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS))
+/**
+ * @}
+ */
+
+/** @defgroup UART_Hardware_Flow_Control UART Hardware Flow Control
+ * @{
+ */
+#define UART_HWCONTROL_NONE 0x00000000U
+#define UART_HWCONTROL_RTS ((uint32_t)USART_CR3_RTSE)
+#define UART_HWCONTROL_CTS ((uint32_t)USART_CR3_CTSE)
+#define UART_HWCONTROL_RTS_CTS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE))
+/**
+ * @}
+ */
+
+/** @defgroup UART_Mode UART Transfer Mode
+ * @{
+ */
+#define UART_MODE_RX ((uint32_t)USART_CR1_RE)
+#define UART_MODE_TX ((uint32_t)USART_CR1_TE)
+#define UART_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE))
+/**
+ * @}
+ */
+
+/** @defgroup UART_State UART State
+ * @{
+ */
+#define UART_STATE_DISABLE 0x00000000U
+#define UART_STATE_ENABLE ((uint32_t)USART_CR1_UE)
+/**
+ * @}
+ */
+
+
+/** @defgroup UART_Over_Sampling UART Over Sampling
+ * @{
+ */
+#define UART_OVERSAMPLING_16 0x00000000U
+#if defined(USART_CR1_OVER8)
+#define UART_OVERSAMPLING_8 ((uint32_t)USART_CR1_OVER8)
+#endif /* USART_CR1_OVER8 */
+/**
+ * @}
+ */
+
+
+/** @defgroup UART_LIN_Break_Detection_Length UART LIN Break Detection Length
+ * @{
+ */
+#define UART_LINBREAKDETECTLENGTH_10B 0x00000000U
+#define UART_LINBREAKDETECTLENGTH_11B ((uint32_t)USART_CR2_LBDL)
+/**
+ * @}
+ */
+/** @defgroup UART_WakeUp_functions UART Wakeup Functions
+ * @{
+ */
+#define UART_WAKEUPMETHOD_IDLELINE 0x00000000U
+#define UART_WAKEUPMETHOD_ADDRESSMARK ((uint32_t)USART_CR1_WAKE)
+/**
+ * @}
+ */
+
+/** @defgroup UART_Flags UART FLags
+ * Elements values convention: 0xXXXX
+ * - 0xXXXX : Flag mask in the SR register
+ * @{
+ */
+#define UART_FLAG_CTS ((uint32_t)USART_SR_CTS)
+#define UART_FLAG_LBD ((uint32_t)USART_SR_LBD)
+#define UART_FLAG_TXE ((uint32_t)USART_SR_TXE)
+#define UART_FLAG_TC ((uint32_t)USART_SR_TC)
+#define UART_FLAG_RXNE ((uint32_t)USART_SR_RXNE)
+#define UART_FLAG_IDLE ((uint32_t)USART_SR_IDLE)
+#define UART_FLAG_ORE ((uint32_t)USART_SR_ORE)
+#define UART_FLAG_NE ((uint32_t)USART_SR_NE)
+#define UART_FLAG_FE ((uint32_t)USART_SR_FE)
+#define UART_FLAG_PE ((uint32_t)USART_SR_PE)
+/**
+ * @}
+ */
+
+/** @defgroup UART_Interrupt_definition UART Interrupt Definitions
+ * Elements values convention: 0xY000XXXX
+ * - XXXX : Interrupt mask (16 bits) in the Y register
+ * - Y : Interrupt source register (2bits)
+ * - 01: CR1 register
+ * - 10: CR2 register
+ * - 11: CR3 register
+ * @{
+ */
+
+#define UART_IT_PE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_PEIE))
+#define UART_IT_TXE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_TXEIE))
+#define UART_IT_TC ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_TCIE))
+#define UART_IT_RXNE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_RXNEIE))
+#define UART_IT_IDLE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_IDLEIE))
+
+#define UART_IT_LBD ((uint32_t)(UART_CR2_REG_INDEX << 28U | USART_CR2_LBDIE))
+
+#define UART_IT_CTS ((uint32_t)(UART_CR3_REG_INDEX << 28U | USART_CR3_CTSIE))
+#define UART_IT_ERR ((uint32_t)(UART_CR3_REG_INDEX << 28U | USART_CR3_EIE))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup UART_Exported_Macros UART Exported Macros
+ * @{
+ */
+
+/** @brief Reset UART handle gstate & RxState
+ * @param __HANDLE__: specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ */
+#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__) do{ \
+ (__HANDLE__)->gState = HAL_UART_STATE_RESET; \
+ (__HANDLE__)->RxState = HAL_UART_STATE_RESET; \
+ } while(0U)
+
+/** @brief Flushs the UART DR register
+ * @param __HANDLE__: specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ */
+#define __HAL_UART_FLUSH_DRREGISTER(__HANDLE__) ((__HANDLE__)->Instance->DR)
+
+/** @brief Checks whether the specified UART flag is set or not.
+ * @param __HANDLE__: specifies the UART Handle.
+ * This parameter can be UARTx where x: 1, 2, 3, 4 or 5 to select the USART or
+ * UART peripheral.
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg UART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5)
+ * @arg UART_FLAG_LBD: LIN Break detection flag
+ * @arg UART_FLAG_TXE: Transmit data register empty flag
+ * @arg UART_FLAG_TC: Transmission Complete flag
+ * @arg UART_FLAG_RXNE: Receive data register not empty flag
+ * @arg UART_FLAG_IDLE: Idle Line detection flag
+ * @arg UART_FLAG_ORE: OverRun Error flag
+ * @arg UART_FLAG_NE: Noise Error flag
+ * @arg UART_FLAG_FE: Framing Error flag
+ * @arg UART_FLAG_PE: Parity Error flag
+ * @retval The new state of __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_UART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__))
+
+/** @brief Clears the specified UART pending flag.
+ * @param __HANDLE__: specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be any combination of the following values:
+ * @arg UART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5).
+ * @arg UART_FLAG_LBD: LIN Break detection flag.
+ * @arg UART_FLAG_TC: Transmission Complete flag.
+ * @arg UART_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 followed by a read
+ * operation to USART_DR register.
+ * @note RXNE flag can be also cleared by a read to the USART_DR register.
+ * @note TC flag can be also cleared by software sequence: a read operation to
+ * USART_SR register followed by a write operation to USART_DR register.
+ * @note TXE flag is cleared only by a write to the USART_DR register.
+ *
+ */
+#define __HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__))
+
+/** @brief Clears the UART PE pending flag.
+ * @param __HANDLE__: specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ */
+#define __HAL_UART_CLEAR_PEFLAG(__HANDLE__) \
+ do{ \
+ __IO uint32_t tmpreg = 0x00U; \
+ tmpreg = (__HANDLE__)->Instance->SR; \
+ tmpreg = (__HANDLE__)->Instance->DR; \
+ UNUSED(tmpreg); \
+ } while(0U)
+
+/** @brief Clears the UART FE pending flag.
+ * @param __HANDLE__: specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ */
+#define __HAL_UART_CLEAR_FEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Clears the UART NE pending flag.
+ * @param __HANDLE__: specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ */
+#define __HAL_UART_CLEAR_NEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Clears the UART ORE pending flag.
+ * @param __HANDLE__: specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ */
+#define __HAL_UART_CLEAR_OREFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Clears the UART IDLE pending flag.
+ * @param __HANDLE__: specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ */
+#define __HAL_UART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Enable the specified UART interrupt.
+ * @param __HANDLE__: specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __INTERRUPT__: specifies the UART interrupt source to enable.
+ * This parameter can be one of the following values:
+ * @arg UART_IT_CTS: CTS change interrupt
+ * @arg UART_IT_LBD: LIN Break detection interrupt
+ * @arg UART_IT_TXE: Transmit Data Register empty interrupt
+ * @arg UART_IT_TC: Transmission complete interrupt
+ * @arg UART_IT_RXNE: Receive Data register not empty interrupt
+ * @arg UART_IT_IDLE: Idle line detection interrupt
+ * @arg UART_IT_PE: Parity Error interrupt
+ * @arg UART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
+ */
+#define __HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == UART_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & UART_IT_MASK)): \
+ (((__INTERRUPT__) >> 28U) == UART_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 |= ((__INTERRUPT__) & UART_IT_MASK)): \
+ ((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & UART_IT_MASK)))
+
+/** @brief Disable the specified UART interrupt.
+ * @param __HANDLE__: specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __INTERRUPT__: specifies the UART interrupt source to disable.
+ * This parameter can be one of the following values:
+ * @arg UART_IT_CTS: CTS change interrupt
+ * @arg UART_IT_LBD: LIN Break detection interrupt
+ * @arg UART_IT_TXE: Transmit Data Register empty interrupt
+ * @arg UART_IT_TC: Transmission complete interrupt
+ * @arg UART_IT_RXNE: Receive Data register not empty interrupt
+ * @arg UART_IT_IDLE: Idle line detection interrupt
+ * @arg UART_IT_PE: Parity Error interrupt
+ * @arg UART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
+ */
+#define __HAL_UART_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == UART_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 &= ~((__INTERRUPT__) & UART_IT_MASK)): \
+ (((__INTERRUPT__) >> 28U) == UART_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 &= ~((__INTERRUPT__) & UART_IT_MASK)): \
+ ((__HANDLE__)->Instance->CR3 &= ~ ((__INTERRUPT__) & UART_IT_MASK)))
+
+/** @brief Checks whether the specified UART interrupt has occurred or not.
+ * @param __HANDLE__: specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __IT__: specifies the UART interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg UART_IT_CTS: CTS change interrupt (not available for UART4 and UART5)
+ * @arg UART_IT_LBD: LIN Break detection interrupt
+ * @arg UART_IT_TXE: Transmit Data Register empty interrupt
+ * @arg UART_IT_TC: Transmission complete interrupt
+ * @arg UART_IT_RXNE: Receive Data register not empty interrupt
+ * @arg UART_IT_IDLE: Idle line detection interrupt
+ * @arg UART_IT_ERR: Error interrupt
+ * @retval The new state of __IT__ (TRUE or FALSE).
+ */
+#define __HAL_UART_GET_IT_SOURCE(__HANDLE__, __IT__) (((((__IT__) >> 28U) == UART_CR1_REG_INDEX)? (__HANDLE__)->Instance->CR1:(((((uint32_t)(__IT__)) >> 28U) == UART_CR2_REG_INDEX)? \
+ (__HANDLE__)->Instance->CR2 : (__HANDLE__)->Instance->CR3)) & (((uint32_t)(__IT__)) & UART_IT_MASK))
+
+/** @brief Enable CTS flow control
+ * This macro allows to enable CTS hardware flow control for a given UART instance,
+ * without need to call HAL_UART_Init() function.
+ * As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
+ * @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need
+ * for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
+ * - UART instance should have already been initialised (through call of HAL_UART_Init() )
+ * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
+ * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
+ * @param __HANDLE__: specifies the UART Handle.
+ * The Handle Instance can be any USARTx (supporting the HW Flow control feature).
+ * It is used to select the USART peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_UART_HWCONTROL_CTS_ENABLE(__HANDLE__) \
+ do{ \
+ SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \
+ (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_CTSE; \
+ } while(0U)
+
+/** @brief Disable CTS flow control
+ * This macro allows to disable CTS hardware flow control for a given UART instance,
+ * without need to call HAL_UART_Init() function.
+ * As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
+ * @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need
+ * for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
+ * - UART instance should have already been initialised (through call of HAL_UART_Init() )
+ * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
+ * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
+ * @param __HANDLE__: specifies the UART Handle.
+ * The Handle Instance can be any USARTx (supporting the HW Flow control feature).
+ * It is used to select the USART peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_UART_HWCONTROL_CTS_DISABLE(__HANDLE__) \
+ do{ \
+ CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \
+ (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_CTSE); \
+ } while(0U)
+
+/** @brief Enable RTS flow control
+ * This macro allows to enable RTS hardware flow control for a given UART instance,
+ * without need to call HAL_UART_Init() function.
+ * As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
+ * @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need
+ * for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
+ * - UART instance should have already been initialised (through call of HAL_UART_Init() )
+ * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
+ * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
+ * @param __HANDLE__: specifies the UART Handle.
+ * The Handle Instance can be any USARTx (supporting the HW Flow control feature).
+ * It is used to select the USART peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_UART_HWCONTROL_RTS_ENABLE(__HANDLE__) \
+ do{ \
+ SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE); \
+ (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_RTSE; \
+ } while(0U)
+
+/** @brief Disable RTS flow control
+ * This macro allows to disable RTS hardware flow control for a given UART instance,
+ * without need to call HAL_UART_Init() function.
+ * As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
+ * @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need
+ * for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
+ * - UART instance should have already been initialised (through call of HAL_UART_Init() )
+ * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
+ * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
+ * @param __HANDLE__: specifies the UART Handle.
+ * The Handle Instance can be any USARTx (supporting the HW Flow control feature).
+ * It is used to select the USART peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_UART_HWCONTROL_RTS_DISABLE(__HANDLE__) \
+ do{ \
+ CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE);\
+ (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_RTSE); \
+ } while(0U)
+
+#if defined(USART_CR3_ONEBIT)
+/** @brief macros to enables the UART's one bit sample method
+ * @param __HANDLE__: specifies the UART Handle.
+ */
+#define __HAL_UART_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT)
+
+/** @brief macros to disables the UART's one bit sample method
+ * @param __HANDLE__: specifies the UART Handle.
+ * @retval None
+ */
+#define __HAL_UART_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_ONEBIT))
+#endif /* USART_CR3_ONEBIT */
+
+/** @brief Enable UART
+ * @param __HANDLE__: specifies the UART Handle.
+ */
+#define __HAL_UART_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE)
+
+/** @brief Disable UART
+ * @param __HANDLE__: specifies the UART Handle.
+ */
+#define __HAL_UART_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE)
+/**
+ * @}
+ */
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup UART_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup UART_Exported_Functions_Group1
+ * @{
+ */
+/* Initialization/de-initialization functions **********************************/
+HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength);
+HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod);
+HAL_StatusTypeDef HAL_UART_DeInit (UART_HandleTypeDef *huart);
+void HAL_UART_MspInit(UART_HandleTypeDef *huart);
+void HAL_UART_MspDeInit(UART_HandleTypeDef *huart);
+/**
+ * @}
+ */
+
+/** @addtogroup UART_Exported_Functions_Group2
+ * @{
+ */
+/* IO operation functions *******************************************************/
+HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart);
+/* Transfer Abort functions */
+HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart);
+
+void HAL_UART_IRQHandler(UART_HandleTypeDef *huart);
+void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart);
+void HAL_UART_AbortCpltCallback (UART_HandleTypeDef *huart);
+void HAL_UART_AbortTransmitCpltCallback (UART_HandleTypeDef *huart);
+void HAL_UART_AbortReceiveCpltCallback (UART_HandleTypeDef *huart);
+/**
+ * @}
+ */
+
+/** @addtogroup UART_Exported_Functions_Group3
+ * @{
+ */
+/* Peripheral Control functions ************************************************/
+HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart);
+/**
+ * @}
+ */
+
+/** @addtogroup UART_Exported_Functions_Group4
+ * @{
+ */
+/* Peripheral State functions **************************************************/
+HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart);
+uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup UART_Private_Constants UART Private Constants
+ * @{
+ */
+/** @brief UART interruptions flag mask
+ *
+ */
+#define UART_IT_MASK 0x0000FFFFU
+
+#define UART_CR1_REG_INDEX 1U
+#define UART_CR2_REG_INDEX 2U
+#define UART_CR3_REG_INDEX 3U
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup UART_Private_Macros UART Private Macros
+ * @{
+ */
+#define IS_UART_WORD_LENGTH(LENGTH) (((LENGTH) == UART_WORDLENGTH_8B) || \
+ ((LENGTH) == UART_WORDLENGTH_9B))
+#define IS_UART_LIN_WORD_LENGTH(LENGTH) (((LENGTH) == UART_WORDLENGTH_8B))
+#define IS_UART_STOPBITS(STOPBITS) (((STOPBITS) == UART_STOPBITS_1) || \
+ ((STOPBITS) == UART_STOPBITS_2))
+#define IS_UART_PARITY(PARITY) (((PARITY) == UART_PARITY_NONE) || \
+ ((PARITY) == UART_PARITY_EVEN) || \
+ ((PARITY) == UART_PARITY_ODD))
+#define IS_UART_HARDWARE_FLOW_CONTROL(CONTROL)\
+ (((CONTROL) == UART_HWCONTROL_NONE) || \
+ ((CONTROL) == UART_HWCONTROL_RTS) || \
+ ((CONTROL) == UART_HWCONTROL_CTS) || \
+ ((CONTROL) == UART_HWCONTROL_RTS_CTS))
+#define IS_UART_MODE(MODE) ((((MODE) & 0x0000FFF3U) == 0x00U) && ((MODE) != 0x00U))
+#define IS_UART_STATE(STATE) (((STATE) == UART_STATE_DISABLE) || \
+ ((STATE) == UART_STATE_ENABLE))
+#if defined(USART_CR1_OVER8)
+#define IS_UART_OVERSAMPLING(SAMPLING) (((SAMPLING) == UART_OVERSAMPLING_16) || \
+ ((SAMPLING) == UART_OVERSAMPLING_8))
+#endif /* USART_CR1_OVER8 */
+#define IS_UART_LIN_OVERSAMPLING(SAMPLING) (((SAMPLING) == UART_OVERSAMPLING_16))
+#define IS_UART_LIN_BREAK_DETECT_LENGTH(LENGTH) (((LENGTH) == UART_LINBREAKDETECTLENGTH_10B) || \
+ ((LENGTH) == UART_LINBREAKDETECTLENGTH_11B))
+#define IS_UART_WAKEUPMETHOD(WAKEUP) (((WAKEUP) == UART_WAKEUPMETHOD_IDLELINE) || \
+ ((WAKEUP) == UART_WAKEUPMETHOD_ADDRESSMARK))
+#define IS_UART_BAUDRATE(BAUDRATE) ((BAUDRATE) < 4500001U)
+#define IS_UART_ADDRESS(ADDRESS) ((ADDRESS) <= 0x0FU)
+
+#define UART_DIV_SAMPLING16(_PCLK_, _BAUD_) (((_PCLK_)*25U)/(4U*(_BAUD_)))
+#define UART_DIVMANT_SAMPLING16(_PCLK_, _BAUD_) (UART_DIV_SAMPLING16((_PCLK_), (_BAUD_))/100U)
+#define UART_DIVFRAQ_SAMPLING16(_PCLK_, _BAUD_) (((UART_DIV_SAMPLING16((_PCLK_), (_BAUD_)) - (UART_DIVMANT_SAMPLING16((_PCLK_), (_BAUD_)) * 100U)) * 16U + 50U) / 100U)
+/* UART BRR = mantissa + overflow + fraction
+ = (UART DIVMANT << 4) + (UART DIVFRAQ & 0xF0) + (UART DIVFRAQ & 0x0FU) */
+#define UART_BRR_SAMPLING16(_PCLK_, _BAUD_) (((UART_DIVMANT_SAMPLING16((_PCLK_), (_BAUD_)) << 4U) + \
+ (UART_DIVFRAQ_SAMPLING16((_PCLK_), (_BAUD_)) & 0xF0U)) + \
+ (UART_DIVFRAQ_SAMPLING16((_PCLK_), (_BAUD_)) & 0x0FU))
+
+#define UART_DIV_SAMPLING8(_PCLK_, _BAUD_) (((_PCLK_)*25U)/(2U*(_BAUD_)))
+#define UART_DIVMANT_SAMPLING8(_PCLK_, _BAUD_) (UART_DIV_SAMPLING8((_PCLK_), (_BAUD_))/100U)
+#define UART_DIVFRAQ_SAMPLING8(_PCLK_, _BAUD_) (((UART_DIV_SAMPLING8((_PCLK_), (_BAUD_)) - (UART_DIVMANT_SAMPLING8((_PCLK_), (_BAUD_)) * 100U)) * 8U + 50U) / 100U)
+/* UART BRR = mantissa + overflow + fraction
+ = (UART DIVMANT << 4) + ((UART DIVFRAQ & 0xF8) << 1) + (UART DIVFRAQ & 0x07U) */
+#define UART_BRR_SAMPLING8(_PCLK_, _BAUD_) (((UART_DIVMANT_SAMPLING8((_PCLK_), (_BAUD_)) << 4U) + \
+ ((UART_DIVFRAQ_SAMPLING8((_PCLK_), (_BAUD_)) & 0xF8U) << 1U)) + \
+ (UART_DIVFRAQ_SAMPLING8((_PCLK_), (_BAUD_)) & 0x07U))
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup UART_Private_Functions UART Private Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_UART_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_usart.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_usart.h
new file mode 100644
index 0000000..2aed913
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_usart.h
@@ -0,0 +1,593 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_usart.h
+ * @author MCD Application Team
+ * @brief Header file of USART HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_USART_H
+#define __STM32F1xx_HAL_USART_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup USART
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup USART_Exported_Types USART Exported Types
+ * @{
+ */
+
+/**
+ * @brief USART Init Structure definition
+ */
+typedef struct
+{
+ uint32_t BaudRate; /*!< This member configures the Usart communication baud rate.
+ The baud rate is computed using the following formula:
+ - IntegerDivider = ((PCLKx) / (16 * (husart->Init.BaudRate)))
+ - FractionalDivider = ((IntegerDivider - ((uint32_t) IntegerDivider)) * 16) + 0.5 */
+
+ uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame.
+ This parameter can be a value of @ref USART_Word_Length */
+
+ uint32_t StopBits; /*!< Specifies the number of stop bits transmitted.
+ This parameter can be a value of @ref USART_Stop_Bits */
+
+ uint32_t Parity; /*!< Specifies the parity mode.
+ This parameter can be a value of @ref USART_Parity
+ @note When parity is enabled, the computed parity is inserted
+ at the MSB position of the transmitted data (9th bit when
+ the word length is set to 9 data bits; 8th bit when the
+ word length is set to 8 data bits). */
+
+ uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.
+ This parameter can be a value of @ref USART_Mode */
+
+ uint32_t CLKPolarity; /*!< Specifies the steady state of the serial clock.
+ This parameter can be a value of @ref USART_Clock_Polarity */
+
+ uint32_t CLKPhase; /*!< Specifies the clock transition on which the bit capture is made.
+ This parameter can be a value of @ref USART_Clock_Phase */
+
+ uint32_t CLKLastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted
+ data bit (MSB) has to be output on the SCLK pin in synchronous mode.
+ This parameter can be a value of @ref USART_Last_Bit */
+}USART_InitTypeDef;
+
+/**
+ * @brief HAL State structures definition
+ */
+typedef enum
+{
+ HAL_USART_STATE_RESET = 0x00U, /*!< Peripheral is not yet initialized */
+ HAL_USART_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */
+ HAL_USART_STATE_BUSY = 0x02U, /*!< an internal process is ongoing */
+ HAL_USART_STATE_BUSY_TX = 0x12U, /*!< Data Transmission process is ongoing */
+ HAL_USART_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */
+ HAL_USART_STATE_BUSY_TX_RX = 0x32U, /*!< Data Transmission Reception process is ongoing */
+ HAL_USART_STATE_TIMEOUT = 0x03U, /*!< Timeout state */
+ HAL_USART_STATE_ERROR = 0x04U /*!< Error */
+}HAL_USART_StateTypeDef;
+
+/**
+ * @brief USART handle Structure definition
+ */
+typedef struct
+{
+ USART_TypeDef *Instance; /*!< USART registers base address */
+
+ USART_InitTypeDef Init; /*!< Usart communication parameters */
+
+ uint8_t *pTxBuffPtr; /*!< Pointer to Usart Tx transfer Buffer */
+
+ uint16_t TxXferSize; /*!< Usart Tx Transfer size */
+
+ __IO uint16_t TxXferCount; /*!< Usart Tx Transfer Counter */
+
+ uint8_t *pRxBuffPtr; /*!< Pointer to Usart Rx transfer Buffer */
+
+ uint16_t RxXferSize; /*!< Usart Rx Transfer size */
+
+ __IO uint16_t RxXferCount; /*!< Usart Rx Transfer Counter */
+
+ DMA_HandleTypeDef *hdmatx; /*!< Usart Tx DMA Handle parameters */
+
+ DMA_HandleTypeDef *hdmarx; /*!< Usart Rx DMA Handle parameters */
+
+ HAL_LockTypeDef Lock; /*!< Locking object */
+
+ __IO HAL_USART_StateTypeDef State; /*!< Usart communication state */
+
+ __IO uint32_t ErrorCode; /*!< USART Error code */
+}USART_HandleTypeDef;
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup USART_Exported_Constants USART Exported Constants
+ * @{
+ */
+
+/** @defgroup USART_Error_Code USART Error Code
+ * @brief USART Error Code
+ * @{
+ */
+#define HAL_USART_ERROR_NONE 0x00000000U /*!< No error */
+#define HAL_USART_ERROR_PE 0x00000001U /*!< Parity error */
+#define HAL_USART_ERROR_NE 0x00000002U /*!< Noise error */
+#define HAL_USART_ERROR_FE 0x00000004U /*!< Frame error */
+#define HAL_USART_ERROR_ORE 0x00000008U /*!< Overrun error */
+#define HAL_USART_ERROR_DMA 0x00000010U /*!< DMA transfer error */
+/**
+ * @}
+ */
+
+/** @defgroup USART_Word_Length USART Word Length
+ * @{
+ */
+#define USART_WORDLENGTH_8B 0x00000000U
+#define USART_WORDLENGTH_9B ((uint32_t)USART_CR1_M)
+/**
+ * @}
+ */
+
+/** @defgroup USART_Stop_Bits USART Number of Stop Bits
+ * @{
+ */
+#define USART_STOPBITS_1 0x00000000U
+#define USART_STOPBITS_0_5 ((uint32_t)USART_CR2_STOP_0)
+#define USART_STOPBITS_2 ((uint32_t)USART_CR2_STOP_1)
+#define USART_STOPBITS_1_5 ((uint32_t)(USART_CR2_STOP_0 | USART_CR2_STOP_1))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Parity USART Parity
+ * @{
+ */
+#define USART_PARITY_NONE 0x00000000U
+#define USART_PARITY_EVEN ((uint32_t)USART_CR1_PCE)
+#define USART_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Mode USART Mode
+ * @{
+ */
+#define USART_MODE_RX ((uint32_t)USART_CR1_RE)
+#define USART_MODE_TX ((uint32_t)USART_CR1_TE)
+#define USART_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Clock USART Clock
+ * @{
+ */
+#define USART_CLOCK_DISABLE 0x00000000U
+#define USART_CLOCK_ENABLE ((uint32_t)USART_CR2_CLKEN)
+/**
+ * @}
+ */
+
+/** @defgroup USART_Clock_Polarity USART Clock Polarity
+ * @{
+ */
+#define USART_POLARITY_LOW 0x00000000U
+#define USART_POLARITY_HIGH ((uint32_t)USART_CR2_CPOL)
+/**
+ * @}
+ */
+
+/** @defgroup USART_Clock_Phase USART Clock Phase
+ * @{
+ */
+#define USART_PHASE_1EDGE 0x00000000U
+#define USART_PHASE_2EDGE ((uint32_t)USART_CR2_CPHA)
+/**
+ * @}
+ */
+
+/** @defgroup USART_Last_Bit USART Last Bit
+ * @{
+ */
+#define USART_LASTBIT_DISABLE 0x00000000U
+#define USART_LASTBIT_ENABLE ((uint32_t)USART_CR2_LBCL)
+/**
+ * @}
+ */
+
+/** @defgroup USART_NACK_State USART NACK State
+ * @{
+ */
+#define USART_NACK_ENABLE ((uint32_t)USART_CR3_NACK)
+#define USART_NACK_DISABLE 0x00000000U
+/**
+ * @}
+ */
+
+/** @defgroup USART_Flags USART Flags
+ * Elements values convention: 0xXXXX
+ * - 0xXXXX : Flag mask in the SR register
+ * @{
+ */
+#define USART_FLAG_TXE ((uint32_t)USART_SR_TXE)
+#define USART_FLAG_TC ((uint32_t)USART_SR_TC)
+#define USART_FLAG_RXNE ((uint32_t)USART_SR_RXNE)
+#define USART_FLAG_IDLE ((uint32_t)USART_SR_IDLE)
+#define USART_FLAG_ORE ((uint32_t)USART_SR_ORE)
+#define USART_FLAG_NE ((uint32_t)USART_SR_NE)
+#define USART_FLAG_FE ((uint32_t)USART_SR_FE)
+#define USART_FLAG_PE ((uint32_t)USART_SR_PE)
+/**
+ * @}
+ */
+
+/** @defgroup USART_Interrupt_definition USART Interrupts Definition
+ * Elements values convention: 0xY000XXXX
+ * - XXXX : Interrupt mask in the XX register
+ * - Y : Interrupt source register (2bits)
+ * - 01: CR1 register
+ * - 10: CR2 register
+ * - 11: CR3 register
+ *
+ * @{
+ */
+
+#define USART_IT_PE ((uint32_t)(USART_CR1_REG_INDEX << 28U | USART_CR1_PEIE))
+#define USART_IT_TXE ((uint32_t)(USART_CR1_REG_INDEX << 28U | USART_CR1_TXEIE))
+#define USART_IT_TC ((uint32_t)(USART_CR1_REG_INDEX << 28U | USART_CR1_TCIE))
+#define USART_IT_RXNE ((uint32_t)(USART_CR1_REG_INDEX << 28U | USART_CR1_RXNEIE))
+#define USART_IT_IDLE ((uint32_t)(USART_CR1_REG_INDEX << 28U | USART_CR1_IDLEIE))
+
+#define USART_IT_LBD ((uint32_t)(USART_CR2_REG_INDEX << 28U | USART_CR2_LBDIE))
+
+#define USART_IT_CTS ((uint32_t)(USART_CR3_REG_INDEX << 28U | USART_CR3_CTSIE))
+#define USART_IT_ERR ((uint32_t)(USART_CR3_REG_INDEX << 28U | USART_CR3_EIE))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup USART_Exported_Macros USART Exported Macros
+ * @{
+ */
+
+/** @brief Reset USART handle state
+ * @param __HANDLE__: specifies the USART Handle.
+ * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_USART_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_USART_STATE_RESET)
+
+/** @brief Checks whether the specified USART flag is set or not.
+ * @param __HANDLE__: specifies the USART Handle.
+ * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @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 __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_USART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__))
+
+/** @brief Clears the specified USART pending flags.
+ * @param __HANDLE__: specifies the USART Handle.
+ * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be any combination of the following values:
+ * @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 followed by a read
+ * operation to USART_DR register.
+ * @note RXNE flag can be also cleared by a read to the USART_DR register.
+ * @note TC flag can be also cleared by software sequence: a read operation to
+ * USART_SR register followed by a write operation to USART_DR register
+ * @note TXE flag is cleared only by a write to the USART_DR register
+ *
+ */
+#define __HAL_USART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__))
+
+/** @brief Clear the USART PE pending flag.
+ * @param __HANDLE__: specifies the USART Handle.
+ * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_USART_CLEAR_PEFLAG(__HANDLE__) \
+ do{ \
+ __IO uint32_t tmpreg = 0x00U; \
+ tmpreg = (__HANDLE__)->Instance->SR; \
+ tmpreg = (__HANDLE__)->Instance->DR; \
+ UNUSED(tmpreg); \
+ } while(0U)
+
+/** @brief Clear the USART FE pending flag.
+ * @param __HANDLE__: specifies the USART Handle.
+ * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_USART_CLEAR_FEFLAG(__HANDLE__) __HAL_USART_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Clear the USART NE pending flag.
+ * @param __HANDLE__: specifies the USART Handle.
+ * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_USART_CLEAR_NEFLAG(__HANDLE__) __HAL_USART_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Clear the USART ORE pending flag.
+ * @param __HANDLE__: specifies the USART Handle.
+ * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
+
+ */
+#define __HAL_USART_CLEAR_OREFLAG(__HANDLE__) __HAL_USART_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Clear the USART IDLE pending flag.
+ * @param __HANDLE__: specifies the USART Handle.
+ * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_USART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_USART_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Enable the specified USART interrupts.
+ * @param __HANDLE__: specifies the USART Handle.
+ * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ * @param __INTERRUPT__: specifies the USART interrupt source to enable.
+ * This parameter can be one of the following values:
+ * @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)
+ * This parameter can be: ENABLE or DISABLE.
+ */
+#define __HAL_USART_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == USART_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & USART_IT_MASK)): \
+ (((__INTERRUPT__) >> 28U) == USART_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 |= ((__INTERRUPT__) & USART_IT_MASK)): \
+ ((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & USART_IT_MASK)))
+
+/** @brief Disable the specified USART interrupts.
+ * @param __HANDLE__: specifies the USART Handle.
+ * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ * @param __INTERRUPT__: specifies the USART interrupt source to disable.
+ * This parameter can be one of the following values:
+ * @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)
+ * This parameter can be: ENABLE or DISABLE.
+ */
+#define __HAL_USART_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == USART_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 &= ~((__INTERRUPT__) & USART_IT_MASK)): \
+ (((__INTERRUPT__) >> 28U) == USART_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 &= ~((__INTERRUPT__) & USART_IT_MASK)): \
+ ((__HANDLE__)->Instance->CR3 &= ~ ((__INTERRUPT__) & USART_IT_MASK)))
+
+/** @brief Checks whether the specified USART interrupt has occurred or not.
+ * @param __HANDLE__: specifies the USART Handle.
+ * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ * @param __IT__: specifies the USART interrupt source to check.
+ * This parameter can be one of the following values:
+ * @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_ERR: Error interrupt
+ * @arg USART_IT_PE: Parity Error interrupt
+ * @retval The new state of __IT__ (TRUE or FALSE).
+ */
+#define __HAL_USART_GET_IT_SOURCE(__HANDLE__, __IT__) (((((__IT__) >> 28U) == USART_CR1_REG_INDEX)? (__HANDLE__)->Instance->CR1:(((((uint32_t)(__IT__)) >> 28U) == USART_CR2_REG_INDEX)? \
+ (__HANDLE__)->Instance->CR2 : (__HANDLE__)->Instance->CR3)) & (((uint32_t)(__IT__)) & USART_IT_MASK))
+
+/** @brief Enable USART
+ * @param __HANDLE__: specifies the USART Handle.
+ * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_USART_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR1,(USART_CR1_UE))
+
+/** @brief Disable USART
+ * @param __HANDLE__: specifies the USART Handle.
+ * USART Handle selects the USARTx peripheral (USART availability and x value depending on device).
+ */
+#define __HAL_USART_DISABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CR1,(USART_CR1_UE))
+/**
+ * @}
+ */
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup USART_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup USART_Exported_Functions_Group1
+ * @{
+ */
+/* Initialization/de-initialization functions **********************************/
+HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart);
+HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart);
+void HAL_USART_MspInit(USART_HandleTypeDef *husart);
+void HAL_USART_MspDeInit(USART_HandleTypeDef *husart);
+/**
+ * @}
+ */
+
+/** @addtogroup USART_Exported_Functions_Group2
+ * @{
+ */
+/* IO operation functions *******************************************************/
+HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size);
+HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size);
+HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size);
+HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size);
+HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size);
+HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size);
+HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart);
+HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart);
+HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart);
+/* Transfer Abort functions */
+HAL_StatusTypeDef HAL_USART_Abort(USART_HandleTypeDef *husart);
+HAL_StatusTypeDef HAL_USART_Abort_IT(USART_HandleTypeDef *husart);
+
+void HAL_USART_IRQHandler(USART_HandleTypeDef *husart);
+void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart);
+void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart);
+void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart);
+void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart);
+void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart);
+void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart);
+void HAL_USART_AbortCpltCallback (USART_HandleTypeDef *husart);
+/**
+ * @}
+ */
+
+/** @addtogroup USART_Exported_Functions_Group3
+ * @{
+ */
+/* Peripheral State functions ************************************************/
+HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart);
+uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup USART_Private_Constants USART Private Constants
+ * @{
+ */
+/** @brief USART interruptions flag mask
+ *
+ */
+#define USART_IT_MASK 0x0000FFFFU
+
+#define USART_CR1_REG_INDEX 1U
+#define USART_CR2_REG_INDEX 2U
+#define USART_CR3_REG_INDEX 3U
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup USART_Private_Macros USART Private Macros
+ * @{
+ */
+#define IS_USART_NACK_STATE(NACK) (((NACK) == USART_NACK_ENABLE) || \
+ ((NACK) == USART_NACK_DISABLE))
+
+#define IS_USART_LASTBIT(LASTBIT) (((LASTBIT) == USART_LASTBIT_DISABLE) || \
+ ((LASTBIT) == USART_LASTBIT_ENABLE))
+
+#define IS_USART_PHASE(CPHA) (((CPHA) == USART_PHASE_1EDGE) || ((CPHA) == USART_PHASE_2EDGE))
+
+#define IS_USART_POLARITY(CPOL) (((CPOL) == USART_POLARITY_LOW) || ((CPOL) == USART_POLARITY_HIGH))
+
+#define IS_USART_CLOCK(CLOCK) (((CLOCK) == USART_CLOCK_DISABLE) || \
+ ((CLOCK) == USART_CLOCK_ENABLE))
+
+#define IS_USART_WORD_LENGTH(LENGTH) (((LENGTH) == USART_WORDLENGTH_8B) || \
+ ((LENGTH) == USART_WORDLENGTH_9B))
+
+#define IS_USART_STOPBITS(STOPBITS) (((STOPBITS) == USART_STOPBITS_1) || \
+ ((STOPBITS) == USART_STOPBITS_0_5) || \
+ ((STOPBITS) == USART_STOPBITS_1_5) || \
+ ((STOPBITS) == USART_STOPBITS_2))
+
+#define IS_USART_PARITY(PARITY) (((PARITY) == USART_PARITY_NONE) || \
+ ((PARITY) == USART_PARITY_EVEN) || \
+ ((PARITY) == USART_PARITY_ODD))
+
+#define IS_USART_MODE(MODE) ((((MODE) & 0xFFF3U) == 0x00U) && ((MODE) != 0x00U))
+
+#define IS_USART_BAUDRATE(BAUDRATE) ((BAUDRATE) < 4500001U)
+
+#define USART_DIV(_PCLK_, _BAUD_) (((_PCLK_)*25U)/(2U*(_BAUD_)))
+
+#define USART_DIVMANT(_PCLK_, _BAUD_) (USART_DIV((_PCLK_), (_BAUD_))/100U)
+
+#define USART_DIVFRAQ(_PCLK_, _BAUD_) (((USART_DIV((_PCLK_), (_BAUD_)) - (USART_DIVMANT((_PCLK_), (_BAUD_)) * 100U)) * 16U + 50U) / 100U)
+
+#define USART_BRR(_PCLK_, _BAUD_) ((USART_DIVMANT((_PCLK_), (_BAUD_)) << 4U)|(USART_DIVFRAQ((_PCLK_), (_BAUD_)) & 0x0FU))
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup USART_Private_Functions USART Private Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_USART_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_wwdg.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_wwdg.h
new file mode 100644
index 0000000..70f3ca1
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_wwdg.h
@@ -0,0 +1,281 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_wwdg.h
+ * @author MCD Application Team
+ * @brief Header file of WWDG HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_WWDG_H
+#define __STM32F1xx_HAL_WWDG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup WWDG
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup WWDG_Exported_Types WWDG Exported Types
+ * @{
+ */
+
+/**
+ * @brief WWDG Init structure definition
+ */
+typedef struct
+{
+ uint32_t Prescaler; /*!< Specifies the prescaler value of the WWDG.
+ This parameter can be a value of @ref WWDG_Prescaler */
+
+ uint32_t Window; /*!< Specifies the WWDG window value to be compared to the downcounter.
+ This parameter must be a number Min_Data = 0x40 and Max_Data = 0x7F */
+
+ uint32_t Counter; /*!< Specifies the WWDG free-running downcounter value.
+ This parameter must be a number between Min_Data = 0x40 and Max_Data = 0x7F */
+
+ uint32_t EWIMode ; /*!< Specifies if WWDG Early Wakeup Interupt is enable or not.
+ This parameter can be a value of @ref WWDG_EWI_Mode */
+
+} WWDG_InitTypeDef;
+
+/**
+ * @brief WWDG handle Structure definition
+ */
+typedef struct
+{
+ WWDG_TypeDef *Instance; /*!< Register base address */
+
+ WWDG_InitTypeDef Init; /*!< WWDG required parameters */
+
+} WWDG_HandleTypeDef;
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup WWDG_Exported_Constants WWDG Exported Constants
+ * @{
+ */
+
+/** @defgroup WWDG_Interrupt_definition WWDG Interrupt definition
+ * @{
+ */
+#define WWDG_IT_EWI WWDG_CFR_EWI /*!< Early wakeup interrupt */
+/**
+ * @}
+ */
+
+/** @defgroup WWDG_Flag_definition WWDG Flag definition
+ * @brief WWDG Flag definition
+ * @{
+ */
+#define WWDG_FLAG_EWIF WWDG_SR_EWIF /*!< Early wakeup interrupt flag */
+/**
+ * @}
+ */
+
+/** @defgroup WWDG_Prescaler WWDG Prescaler
+ * @{
+ */
+#define WWDG_PRESCALER_1 0x00000000U /*!< WWDG counter clock = (PCLK1/4096)/1 */
+#define WWDG_PRESCALER_2 WWDG_CFR_WDGTB0 /*!< WWDG counter clock = (PCLK1/4096)/2 */
+#define WWDG_PRESCALER_4 WWDG_CFR_WDGTB1 /*!< WWDG counter clock = (PCLK1/4096)/4 */
+#define WWDG_PRESCALER_8 WWDG_CFR_WDGTB /*!< WWDG counter clock = (PCLK1/4096)/8 */
+/**
+ * @}
+ */
+
+/** @defgroup WWDG_EWI_Mode WWDG Early Wakeup Interrupt Mode
+ * @{
+ */
+#define WWDG_EWI_DISABLE 0x00000000U /*!< EWI Disable */
+#define WWDG_EWI_ENABLE WWDG_CFR_EWI /*!< EWI Enable */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+
+/** @defgroup WWDG_Private_Macros WWDG Private Macros
+ * @{
+ */
+#define IS_WWDG_PRESCALER(__PRESCALER__) (((__PRESCALER__) == WWDG_PRESCALER_1) || \
+ ((__PRESCALER__) == WWDG_PRESCALER_2) || \
+ ((__PRESCALER__) == WWDG_PRESCALER_4) || \
+ ((__PRESCALER__) == WWDG_PRESCALER_8))
+
+#define IS_WWDG_WINDOW(__WINDOW__) (((__WINDOW__) >= WWDG_CFR_W_6) && ((__WINDOW__) <= WWDG_CFR_W))
+
+#define IS_WWDG_COUNTER(__COUNTER__) (((__COUNTER__) >= WWDG_CR_T_6) && ((__COUNTER__) <= WWDG_CR_T))
+
+#define IS_WWDG_EWI_MODE(__MODE__) (((__MODE__) == WWDG_EWI_ENABLE) || \
+ ((__MODE__) == WWDG_EWI_DISABLE))
+/**
+ * @}
+ */
+
+
+/* Exported macros ------------------------------------------------------------*/
+
+/** @defgroup WWDG_Exported_Macros WWDG Exported Macros
+ * @{
+ */
+
+/**
+ * @brief Enables the WWDG peripheral.
+ * @param __HANDLE__: WWDG handle
+ * @retval None
+ */
+#define __HAL_WWDG_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR, WWDG_CR_WDGA)
+
+/**
+ * @brief Enables the WWDG early wakeup interrupt.
+ * @param __HANDLE__: WWDG handle
+ * @param __INTERRUPT__ specifies the interrupt to enable.
+ * This parameter can be one of the following values:
+ * @arg WWDG_IT_EWI: Early wakeup interrupt
+ * @note Once enabled this interrupt cannot be disabled except by a system reset.
+ * @retval None
+ */
+#define __HAL_WWDG_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->CFR, (__INTERRUPT__))
+
+/**
+ * @brief Checks whether the selected WWDG interrupt has occurred or not.
+ * @param __HANDLE__ WWDG handle
+ * @param __INTERRUPT__ specifies the it to check.
+ * This parameter can be one of the following values:
+ * @arg WWDG_FLAG_EWIF: Early wakeup interrupt IT
+ * @retval The new state of WWDG_FLAG (SET or RESET).
+ */
+#define __HAL_WWDG_GET_IT(__HANDLE__, __INTERRUPT__) __HAL_WWDG_GET_FLAG((__HANDLE__),(__INTERRUPT__))
+
+/** @brief Clear the WWDG's interrupt pending bits
+ * bits to clear the selected interrupt pending bits.
+ * @param __HANDLE__: WWDG handle
+ * @param __INTERRUPT__: specifies the interrupt pending bit to clear.
+ * This parameter can be one of the following values:
+ * @arg WWDG_FLAG_EWIF: Early wakeup interrupt flag
+ */
+#define __HAL_WWDG_CLEAR_IT(__HANDLE__, __INTERRUPT__) __HAL_WWDG_CLEAR_FLAG((__HANDLE__), (__INTERRUPT__))
+
+/**
+ * @brief Check whether the specified WWDG flag is set or not.
+ * @param __HANDLE__ WWDG handle
+ * @param __FLAG__ specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg WWDG_FLAG_EWIF: Early wakeup interrupt flag
+ * @retval The new state of WWDG_FLAG (SET or RESET).
+ */
+#define __HAL_WWDG_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__))
+
+/**
+ * @brief Clears the WWDG's pending flags.
+ * @param __HANDLE__: WWDG handle
+ * @param __FLAG__: specifies the flag to clear.
+ * This parameter can be one of the following values:
+ * @arg WWDG_FLAG_EWIF: Early wakeup interrupt flag
+ * @retval None
+ */
+#define __HAL_WWDG_CLEAR_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR) = ~(__FLAG__))
+
+/** @brief Checks if the specified WWDG interrupt source is enabled or disabled.
+ * @param __HANDLE__: WWDG Handle.
+ * @param __INTERRUPT__: specifies the WWDG interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg WWDG_IT_EWI: Early Wakeup Interrupt
+ * @retval state of __INTERRUPT__ (TRUE or FALSE).
+ */
+#define __HAL_WWDG_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CFR & (__INTERRUPT__)) == (__INTERRUPT__))
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup WWDG_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup WWDG_Exported_Functions_Group1
+ * @{
+ */
+/* Initialization/de-initialization functions **********************************/
+HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg);
+void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg);
+/**
+ * @}
+ */
+
+/** @addtogroup WWDG_Exported_Functions_Group2
+ * @{
+ */
+/* I/O operation functions ******************************************************/
+HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg);
+void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg);
+void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_WWDG_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_adc.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_adc.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_adc.h
rename to templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_adc.h
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_bus.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_bus.h
new file mode 100644
index 0000000..e5b054a
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_bus.h
@@ -0,0 +1,1031 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_bus.h
+ * @author MCD Application Team
+ * @brief Header file of BUS LL module.
+
+ @verbatim
+ ##### RCC Limitations #####
+ ==============================================================================
+ [..]
+ A delay between an RCC peripheral clock enable and the effective peripheral
+ enabling should be taken into account in order to manage the peripheral read/write
+ from/to registers.
+ (+) This delay depends on the peripheral mapping.
+ (++) AHB & APB peripherals, 1 dummy read is necessary
+
+ [..]
+ Workarounds:
+ (#) For AHB & APB peripherals, a dummy read to the peripheral register has been
+ inserted in each LL_{BUS}_GRP{x}_EnableClock() function.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_BUS_H
+#define __STM32F1xx_LL_BUS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx.h"
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined(RCC)
+
+/** @defgroup BUS_LL BUS
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/* Private constants ---------------------------------------------------------*/
+#if defined(RCC_AHBRSTR_OTGFSRST) || defined(RCC_AHBRSTR_ETHMACRST)
+#define RCC_AHBRSTR_SUPPORT
+#endif /* RCC_AHBRSTR_OTGFSRST || RCC_AHBRSTR_ETHMACRST */
+
+/* Private macros ------------------------------------------------------------*/
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup BUS_LL_Exported_Constants BUS Exported Constants
+ * @{
+ */
+
+/** @defgroup BUS_LL_EC_AHB1_GRP1_PERIPH AHB1 GRP1 PERIPH
+ * @{
+ */
+#define LL_AHB1_GRP1_PERIPH_ALL (uint32_t)0xFFFFFFFFU
+#define LL_AHB1_GRP1_PERIPH_CRC RCC_AHBENR_CRCEN
+#define LL_AHB1_GRP1_PERIPH_DMA1 RCC_AHBENR_DMA1EN
+#if defined(DMA2)
+#define LL_AHB1_GRP1_PERIPH_DMA2 RCC_AHBENR_DMA2EN
+#endif /*DMA2*/
+#if defined(ETH)
+#define LL_AHB1_GRP1_PERIPH_ETHMAC RCC_AHBENR_ETHMACEN
+#define LL_AHB1_GRP1_PERIPH_ETHMACRX RCC_AHBENR_ETHMACRXEN
+#define LL_AHB1_GRP1_PERIPH_ETHMACTX RCC_AHBENR_ETHMACTXEN
+#endif /*ETH*/
+#define LL_AHB1_GRP1_PERIPH_FLASH RCC_AHBENR_FLITFEN
+#if defined(FSMC_Bank1)
+#define LL_AHB1_GRP1_PERIPH_FSMC RCC_AHBENR_FSMCEN
+#endif /*FSMC_Bank1*/
+#if defined(USB_OTG_FS)
+#define LL_AHB1_GRP1_PERIPH_OTGFS RCC_AHBENR_OTGFSEN
+#endif /*USB_OTG_FS*/
+#if defined(SDIO)
+#define LL_AHB1_GRP1_PERIPH_SDIO RCC_AHBENR_SDIOEN
+#endif /*SDIO*/
+#define LL_AHB1_GRP1_PERIPH_SRAM RCC_AHBENR_SRAMEN
+/**
+ * @}
+ */
+
+/** @defgroup BUS_LL_EC_APB1_GRP1_PERIPH APB1 GRP1 PERIPH
+ * @{
+ */
+#define LL_APB1_GRP1_PERIPH_ALL (uint32_t)0xFFFFFFFFU
+#define LL_APB1_GRP1_PERIPH_BKP RCC_APB1ENR_BKPEN
+#if defined(CAN1)
+#define LL_APB1_GRP1_PERIPH_CAN1 RCC_APB1ENR_CAN1EN
+#endif /*CAN1*/
+#if defined(CAN2)
+#define LL_APB1_GRP1_PERIPH_CAN2 RCC_APB1ENR_CAN2EN
+#endif /*CAN2*/
+#if defined(CEC)
+#define LL_APB1_GRP1_PERIPH_CEC RCC_APB1ENR_CECEN
+#endif /*CEC*/
+#if defined(DAC)
+#define LL_APB1_GRP1_PERIPH_DAC1 RCC_APB1ENR_DACEN
+#endif /*DAC*/
+#define LL_APB1_GRP1_PERIPH_I2C1 RCC_APB1ENR_I2C1EN
+#if defined(I2C2)
+#define LL_APB1_GRP1_PERIPH_I2C2 RCC_APB1ENR_I2C2EN
+#endif /*I2C2*/
+#define LL_APB1_GRP1_PERIPH_PWR RCC_APB1ENR_PWREN
+#if defined(SPI2)
+#define LL_APB1_GRP1_PERIPH_SPI2 RCC_APB1ENR_SPI2EN
+#endif /*SPI2*/
+#if defined(SPI3)
+#define LL_APB1_GRP1_PERIPH_SPI3 RCC_APB1ENR_SPI3EN
+#endif /*SPI3*/
+#if defined(TIM12)
+#define LL_APB1_GRP1_PERIPH_TIM12 RCC_APB1ENR_TIM12EN
+#endif /*TIM12*/
+#if defined(TIM13)
+#define LL_APB1_GRP1_PERIPH_TIM13 RCC_APB1ENR_TIM13EN
+#endif /*TIM13*/
+#if defined(TIM14)
+#define LL_APB1_GRP1_PERIPH_TIM14 RCC_APB1ENR_TIM14EN
+#endif /*TIM14*/
+#define LL_APB1_GRP1_PERIPH_TIM2 RCC_APB1ENR_TIM2EN
+#define LL_APB1_GRP1_PERIPH_TIM3 RCC_APB1ENR_TIM3EN
+#if defined(TIM4)
+#define LL_APB1_GRP1_PERIPH_TIM4 RCC_APB1ENR_TIM4EN
+#endif /*TIM4*/
+#if defined(TIM5)
+#define LL_APB1_GRP1_PERIPH_TIM5 RCC_APB1ENR_TIM5EN
+#endif /*TIM5*/
+#if defined(TIM6)
+#define LL_APB1_GRP1_PERIPH_TIM6 RCC_APB1ENR_TIM6EN
+#endif /*TIM6*/
+#if defined(TIM7)
+#define LL_APB1_GRP1_PERIPH_TIM7 RCC_APB1ENR_TIM7EN
+#endif /*TIM7*/
+#if defined(UART4)
+#define LL_APB1_GRP1_PERIPH_UART4 RCC_APB1ENR_UART4EN
+#endif /*UART4*/
+#if defined(UART5)
+#define LL_APB1_GRP1_PERIPH_UART5 RCC_APB1ENR_UART5EN
+#endif /*UART5*/
+#define LL_APB1_GRP1_PERIPH_USART2 RCC_APB1ENR_USART2EN
+#if defined(USART3)
+#define LL_APB1_GRP1_PERIPH_USART3 RCC_APB1ENR_USART3EN
+#endif /*USART3*/
+#if defined(USB)
+#define LL_APB1_GRP1_PERIPH_USB RCC_APB1ENR_USBEN
+#endif /*USB*/
+#define LL_APB1_GRP1_PERIPH_WWDG RCC_APB1ENR_WWDGEN
+/**
+ * @}
+ */
+
+/** @defgroup BUS_LL_EC_APB2_GRP1_PERIPH APB2 GRP1 PERIPH
+ * @{
+ */
+#define LL_APB2_GRP1_PERIPH_ALL (uint32_t)0xFFFFFFFFU
+#define LL_APB2_GRP1_PERIPH_ADC1 RCC_APB2ENR_ADC1EN
+#if defined(ADC2)
+#define LL_APB2_GRP1_PERIPH_ADC2 RCC_APB2ENR_ADC2EN
+#endif /*ADC2*/
+#if defined(ADC3)
+#define LL_APB2_GRP1_PERIPH_ADC3 RCC_APB2ENR_ADC3EN
+#endif /*ADC3*/
+#define LL_APB2_GRP1_PERIPH_AFIO RCC_APB2ENR_AFIOEN
+#define LL_APB2_GRP1_PERIPH_GPIOA RCC_APB2ENR_IOPAEN
+#define LL_APB2_GRP1_PERIPH_GPIOB RCC_APB2ENR_IOPBEN
+#define LL_APB2_GRP1_PERIPH_GPIOC RCC_APB2ENR_IOPCEN
+#define LL_APB2_GRP1_PERIPH_GPIOD RCC_APB2ENR_IOPDEN
+#if defined(GPIOE)
+#define LL_APB2_GRP1_PERIPH_GPIOE RCC_APB2ENR_IOPEEN
+#endif /*GPIOE*/
+#if defined(GPIOF)
+#define LL_APB2_GRP1_PERIPH_GPIOF RCC_APB2ENR_IOPFEN
+#endif /*GPIOF*/
+#if defined(GPIOG)
+#define LL_APB2_GRP1_PERIPH_GPIOG RCC_APB2ENR_IOPGEN
+#endif /*GPIOG*/
+#define LL_APB2_GRP1_PERIPH_SPI1 RCC_APB2ENR_SPI1EN
+#if defined(TIM10)
+#define LL_APB2_GRP1_PERIPH_TIM10 RCC_APB2ENR_TIM10EN
+#endif /*TIM10*/
+#if defined(TIM11)
+#define LL_APB2_GRP1_PERIPH_TIM11 RCC_APB2ENR_TIM11EN
+#endif /*TIM11*/
+#if defined(TIM15)
+#define LL_APB2_GRP1_PERIPH_TIM15 RCC_APB2ENR_TIM15EN
+#endif /*TIM15*/
+#if defined(TIM16)
+#define LL_APB2_GRP1_PERIPH_TIM16 RCC_APB2ENR_TIM16EN
+#endif /*TIM16*/
+#if defined(TIM17)
+#define LL_APB2_GRP1_PERIPH_TIM17 RCC_APB2ENR_TIM17EN
+#endif /*TIM17*/
+#define LL_APB2_GRP1_PERIPH_TIM1 RCC_APB2ENR_TIM1EN
+#if defined(TIM8)
+#define LL_APB2_GRP1_PERIPH_TIM8 RCC_APB2ENR_TIM8EN
+#endif /*TIM8*/
+#if defined(TIM9)
+#define LL_APB2_GRP1_PERIPH_TIM9 RCC_APB2ENR_TIM9EN
+#endif /*TIM9*/
+#define LL_APB2_GRP1_PERIPH_USART1 RCC_APB2ENR_USART1EN
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup BUS_LL_Exported_Functions BUS Exported Functions
+ * @{
+ */
+
+/** @defgroup BUS_LL_EF_AHB1 AHB1
+ * @{
+ */
+
+/**
+ * @brief Enable AHB1 peripherals clock.
+ * @rmtoll AHBENR CRCEN LL_AHB1_GRP1_EnableClock\n
+ * AHBENR DMA1EN LL_AHB1_GRP1_EnableClock\n
+ * AHBENR DMA2EN LL_AHB1_GRP1_EnableClock\n
+ * AHBENR ETHMACEN LL_AHB1_GRP1_EnableClock\n
+ * AHBENR ETHMACRXEN LL_AHB1_GRP1_EnableClock\n
+ * AHBENR ETHMACTXEN LL_AHB1_GRP1_EnableClock\n
+ * AHBENR FLITFEN LL_AHB1_GRP1_EnableClock\n
+ * AHBENR FSMCEN LL_AHB1_GRP1_EnableClock\n
+ * AHBENR OTGFSEN LL_AHB1_GRP1_EnableClock\n
+ * AHBENR SDIOEN LL_AHB1_GRP1_EnableClock\n
+ * AHBENR SRAMEN LL_AHB1_GRP1_EnableClock
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_AHB1_GRP1_PERIPH_CRC
+ * @arg @ref LL_AHB1_GRP1_PERIPH_DMA1
+ * @arg @ref LL_AHB1_GRP1_PERIPH_DMA2 (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMAC (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMACRX (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMACTX (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_FLASH
+ * @arg @ref LL_AHB1_GRP1_PERIPH_FSMC (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_OTGFS (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_SDIO (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_SRAM
+ *
+ * (*) value not defined in all devices.
+ * @retval None
+*/
+__STATIC_INLINE void LL_AHB1_GRP1_EnableClock(uint32_t Periphs)
+{
+ __IO uint32_t tmpreg;
+ SET_BIT(RCC->AHBENR, Periphs);
+ /* Delay after an RCC peripheral clock enabling */
+ tmpreg = READ_BIT(RCC->AHBENR, Periphs);
+ (void)tmpreg;
+}
+
+/**
+ * @brief Check if AHB1 peripheral clock is enabled or not
+ * @rmtoll AHBENR CRCEN LL_AHB1_GRP1_IsEnabledClock\n
+ * AHBENR DMA1EN LL_AHB1_GRP1_IsEnabledClock\n
+ * AHBENR DMA2EN LL_AHB1_GRP1_IsEnabledClock\n
+ * AHBENR ETHMACEN LL_AHB1_GRP1_IsEnabledClock\n
+ * AHBENR ETHMACRXEN LL_AHB1_GRP1_IsEnabledClock\n
+ * AHBENR ETHMACTXEN LL_AHB1_GRP1_IsEnabledClock\n
+ * AHBENR FLITFEN LL_AHB1_GRP1_IsEnabledClock\n
+ * AHBENR FSMCEN LL_AHB1_GRP1_IsEnabledClock\n
+ * AHBENR OTGFSEN LL_AHB1_GRP1_IsEnabledClock\n
+ * AHBENR SDIOEN LL_AHB1_GRP1_IsEnabledClock\n
+ * AHBENR SRAMEN LL_AHB1_GRP1_IsEnabledClock
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_AHB1_GRP1_PERIPH_CRC
+ * @arg @ref LL_AHB1_GRP1_PERIPH_DMA1
+ * @arg @ref LL_AHB1_GRP1_PERIPH_DMA2 (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMAC (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMACRX (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMACTX (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_FLASH
+ * @arg @ref LL_AHB1_GRP1_PERIPH_FSMC (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_OTGFS (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_SDIO (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_SRAM
+ *
+ * (*) value not defined in all devices.
+ * @retval State of Periphs (1 or 0).
+*/
+__STATIC_INLINE uint32_t LL_AHB1_GRP1_IsEnabledClock(uint32_t Periphs)
+{
+ return (READ_BIT(RCC->AHBENR, Periphs) == Periphs);
+}
+
+/**
+ * @brief Disable AHB1 peripherals clock.
+ * @rmtoll AHBENR CRCEN LL_AHB1_GRP1_DisableClock\n
+ * AHBENR DMA1EN LL_AHB1_GRP1_DisableClock\n
+ * AHBENR DMA2EN LL_AHB1_GRP1_DisableClock\n
+ * AHBENR ETHMACEN LL_AHB1_GRP1_DisableClock\n
+ * AHBENR ETHMACRXEN LL_AHB1_GRP1_DisableClock\n
+ * AHBENR ETHMACTXEN LL_AHB1_GRP1_DisableClock\n
+ * AHBENR FLITFEN LL_AHB1_GRP1_DisableClock\n
+ * AHBENR FSMCEN LL_AHB1_GRP1_DisableClock\n
+ * AHBENR OTGFSEN LL_AHB1_GRP1_DisableClock\n
+ * AHBENR SDIOEN LL_AHB1_GRP1_DisableClock\n
+ * AHBENR SRAMEN LL_AHB1_GRP1_DisableClock
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_AHB1_GRP1_PERIPH_CRC
+ * @arg @ref LL_AHB1_GRP1_PERIPH_DMA1
+ * @arg @ref LL_AHB1_GRP1_PERIPH_DMA2 (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMAC (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMACRX (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMACTX (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_FLASH
+ * @arg @ref LL_AHB1_GRP1_PERIPH_FSMC (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_OTGFS (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_SDIO (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_SRAM
+ *
+ * (*) value not defined in all devices.
+ * @retval None
+*/
+__STATIC_INLINE void LL_AHB1_GRP1_DisableClock(uint32_t Periphs)
+{
+ CLEAR_BIT(RCC->AHBENR, Periphs);
+}
+
+#if defined(RCC_AHBRSTR_SUPPORT)
+/**
+ * @brief Force AHB1 peripherals reset.
+ * @rmtoll AHBRSTR ETHMACRST LL_AHB1_GRP1_ForceReset\n
+ * AHBRSTR OTGFSRST LL_AHB1_GRP1_ForceReset
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_AHB1_GRP1_PERIPH_ALL
+ * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMAC (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_OTGFS (*)
+ *
+ * (*) value not defined in all devices.
+ * @retval None
+*/
+__STATIC_INLINE void LL_AHB1_GRP1_ForceReset(uint32_t Periphs)
+{
+ SET_BIT(RCC->AHBRSTR, Periphs);
+}
+
+/**
+ * @brief Release AHB1 peripherals reset.
+ * @rmtoll AHBRSTR ETHMACRST LL_AHB1_GRP1_ReleaseReset\n
+ * AHBRSTR OTGFSRST LL_AHB1_GRP1_ReleaseReset
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_AHB1_GRP1_PERIPH_ALL
+ * @arg @ref LL_AHB1_GRP1_PERIPH_ETHMAC (*)
+ * @arg @ref LL_AHB1_GRP1_PERIPH_OTGFS (*)
+ *
+ * (*) value not defined in all devices.
+ * @retval None
+*/
+__STATIC_INLINE void LL_AHB1_GRP1_ReleaseReset(uint32_t Periphs)
+{
+ CLEAR_BIT(RCC->AHBRSTR, Periphs);
+}
+#endif /* RCC_AHBRSTR_SUPPORT */
+
+/**
+ * @}
+ */
+
+/** @defgroup BUS_LL_EF_APB1 APB1
+ * @{
+ */
+
+/**
+ * @brief Enable APB1 peripherals clock.
+ * @rmtoll APB1ENR BKPEN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR CAN1EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR CAN2EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR CECEN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR DACEN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR I2C1EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR I2C2EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR PWREN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR SPI2EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR SPI3EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR TIM12EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR TIM13EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR TIM14EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR TIM2EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR TIM3EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR TIM4EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR TIM5EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR TIM6EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR TIM7EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR UART4EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR UART5EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR USART2EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR USART3EN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR USBEN LL_APB1_GRP1_EnableClock\n
+ * APB1ENR WWDGEN LL_APB1_GRP1_EnableClock
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_APB1_GRP1_PERIPH_BKP
+ * @arg @ref LL_APB1_GRP1_PERIPH_CAN1 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_CAN2 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_DAC1 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_I2C1
+ * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_PWR
+ * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM12 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM13 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM2
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM3
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM4 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM5 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_UART4 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_UART5 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_USART2
+ * @arg @ref LL_APB1_GRP1_PERIPH_USART3 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_USB (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_WWDG
+ *
+ * (*) value not defined in all devices.
+ * @retval None
+*/
+__STATIC_INLINE void LL_APB1_GRP1_EnableClock(uint32_t Periphs)
+{
+ __IO uint32_t tmpreg;
+ SET_BIT(RCC->APB1ENR, Periphs);
+ /* Delay after an RCC peripheral clock enabling */
+ tmpreg = READ_BIT(RCC->APB1ENR, Periphs);
+ (void)tmpreg;
+}
+
+/**
+ * @brief Check if APB1 peripheral clock is enabled or not
+ * @rmtoll APB1ENR BKPEN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR CAN1EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR CAN2EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR CECEN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR DACEN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR I2C1EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR I2C2EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR PWREN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR SPI2EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR SPI3EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR TIM12EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR TIM13EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR TIM14EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR TIM2EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR TIM3EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR TIM4EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR TIM5EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR TIM6EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR TIM7EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR UART4EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR UART5EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR USART2EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR USART3EN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR USBEN LL_APB1_GRP1_IsEnabledClock\n
+ * APB1ENR WWDGEN LL_APB1_GRP1_IsEnabledClock
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_APB1_GRP1_PERIPH_BKP
+ * @arg @ref LL_APB1_GRP1_PERIPH_CAN1 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_CAN2 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_DAC1 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_I2C1
+ * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_PWR
+ * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM12 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM13 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM2
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM3
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM4 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM5 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_UART4 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_UART5 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_USART2
+ * @arg @ref LL_APB1_GRP1_PERIPH_USART3 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_USB (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_WWDG
+ *
+ * (*) value not defined in all devices.
+ * @retval State of Periphs (1 or 0).
+*/
+__STATIC_INLINE uint32_t LL_APB1_GRP1_IsEnabledClock(uint32_t Periphs)
+{
+ return (READ_BIT(RCC->APB1ENR, Periphs) == Periphs);
+}
+
+/**
+ * @brief Disable APB1 peripherals clock.
+ * @rmtoll APB1ENR BKPEN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR CAN1EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR CAN2EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR CECEN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR DACEN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR I2C1EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR I2C2EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR PWREN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR SPI2EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR SPI3EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR TIM12EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR TIM13EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR TIM14EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR TIM2EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR TIM3EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR TIM4EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR TIM5EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR TIM6EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR TIM7EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR UART4EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR UART5EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR USART2EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR USART3EN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR USBEN LL_APB1_GRP1_DisableClock\n
+ * APB1ENR WWDGEN LL_APB1_GRP1_DisableClock
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_APB1_GRP1_PERIPH_BKP
+ * @arg @ref LL_APB1_GRP1_PERIPH_CAN1 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_CAN2 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_DAC1 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_I2C1
+ * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_PWR
+ * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM12 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM13 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM2
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM3
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM4 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM5 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_UART4 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_UART5 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_USART2
+ * @arg @ref LL_APB1_GRP1_PERIPH_USART3 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_USB (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_WWDG
+ *
+ * (*) value not defined in all devices.
+ * @retval None
+*/
+__STATIC_INLINE void LL_APB1_GRP1_DisableClock(uint32_t Periphs)
+{
+ CLEAR_BIT(RCC->APB1ENR, Periphs);
+}
+
+/**
+ * @brief Force APB1 peripherals reset.
+ * @rmtoll APB1RSTR BKPRST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR CAN1RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR CAN2RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR CECRST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR DACRST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR I2C1RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR I2C2RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR PWRRST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR SPI2RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR SPI3RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR TIM12RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR TIM13RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR TIM14RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR TIM2RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR TIM3RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR TIM4RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR TIM5RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR TIM6RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR TIM7RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR UART4RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR UART5RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR USART2RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR USART3RST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR USBRST LL_APB1_GRP1_ForceReset\n
+ * APB1RSTR WWDGRST LL_APB1_GRP1_ForceReset
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_APB1_GRP1_PERIPH_ALL
+ * @arg @ref LL_APB1_GRP1_PERIPH_BKP
+ * @arg @ref LL_APB1_GRP1_PERIPH_CAN1 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_CAN2 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_DAC1 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_I2C1
+ * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_PWR
+ * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM12 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM13 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM2
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM3
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM4 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM5 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_UART4 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_UART5 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_USART2
+ * @arg @ref LL_APB1_GRP1_PERIPH_USART3 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_USB (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_WWDG
+ *
+ * (*) value not defined in all devices.
+ * @retval None
+*/
+__STATIC_INLINE void LL_APB1_GRP1_ForceReset(uint32_t Periphs)
+{
+ SET_BIT(RCC->APB1RSTR, Periphs);
+}
+
+/**
+ * @brief Release APB1 peripherals reset.
+ * @rmtoll APB1RSTR BKPRST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR CAN1RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR CAN2RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR CECRST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR DACRST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR I2C1RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR I2C2RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR PWRRST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR SPI2RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR SPI3RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR TIM12RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR TIM13RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR TIM14RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR TIM2RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR TIM3RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR TIM4RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR TIM5RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR TIM6RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR TIM7RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR UART4RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR UART5RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR USART2RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR USART3RST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR USBRST LL_APB1_GRP1_ReleaseReset\n
+ * APB1RSTR WWDGRST LL_APB1_GRP1_ReleaseReset
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_APB1_GRP1_PERIPH_ALL
+ * @arg @ref LL_APB1_GRP1_PERIPH_BKP
+ * @arg @ref LL_APB1_GRP1_PERIPH_CAN1 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_CAN2 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_DAC1 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_I2C1
+ * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_PWR
+ * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM12 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM13 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM2
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM3
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM4 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM5 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_UART4 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_UART5 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_USART2
+ * @arg @ref LL_APB1_GRP1_PERIPH_USART3 (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_USB (*)
+ * @arg @ref LL_APB1_GRP1_PERIPH_WWDG
+ *
+ * (*) value not defined in all devices.
+ * @retval None
+*/
+__STATIC_INLINE void LL_APB1_GRP1_ReleaseReset(uint32_t Periphs)
+{
+ CLEAR_BIT(RCC->APB1RSTR, Periphs);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup BUS_LL_EF_APB2 APB2
+ * @{
+ */
+
+/**
+ * @brief Enable APB2 peripherals clock.
+ * @rmtoll APB2ENR ADC1EN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR ADC2EN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR ADC3EN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR AFIOEN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR IOPAEN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR IOPBEN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR IOPCEN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR IOPDEN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR IOPEEN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR IOPFEN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR IOPGEN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR SPI1EN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR TIM10EN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR TIM11EN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR TIM15EN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR TIM16EN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR TIM17EN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR TIM1EN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR TIM8EN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR TIM9EN LL_APB2_GRP1_EnableClock\n
+ * APB2ENR USART1EN LL_APB2_GRP1_EnableClock
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_APB2_GRP1_PERIPH_ADC1
+ * @arg @ref LL_APB2_GRP1_PERIPH_ADC2 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_ADC3 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_AFIO
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOA
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOB
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOC
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOD
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOE (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOF (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOG (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_SPI1
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM10 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM11 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM15 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM16 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM17 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM1
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM8 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM9 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_USART1
+ *
+ * (*) value not defined in all devices.
+ * @retval None
+*/
+__STATIC_INLINE void LL_APB2_GRP1_EnableClock(uint32_t Periphs)
+{
+ __IO uint32_t tmpreg;
+ SET_BIT(RCC->APB2ENR, Periphs);
+ /* Delay after an RCC peripheral clock enabling */
+ tmpreg = READ_BIT(RCC->APB2ENR, Periphs);
+ (void)tmpreg;
+}
+
+/**
+ * @brief Check if APB2 peripheral clock is enabled or not
+ * @rmtoll APB2ENR ADC1EN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR ADC2EN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR ADC3EN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR AFIOEN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR IOPAEN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR IOPBEN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR IOPCEN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR IOPDEN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR IOPEEN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR IOPFEN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR IOPGEN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR SPI1EN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR TIM10EN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR TIM11EN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR TIM15EN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR TIM16EN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR TIM17EN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR TIM1EN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR TIM8EN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR TIM9EN LL_APB2_GRP1_IsEnabledClock\n
+ * APB2ENR USART1EN LL_APB2_GRP1_IsEnabledClock
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_APB2_GRP1_PERIPH_ADC1
+ * @arg @ref LL_APB2_GRP1_PERIPH_ADC2 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_ADC3 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_AFIO
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOA
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOB
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOC
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOD
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOE (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOF (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOG (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_SPI1
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM10 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM11 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM15 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM16 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM17 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM1
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM8 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM9 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_USART1
+ *
+ * (*) value not defined in all devices.
+ * @retval State of Periphs (1 or 0).
+*/
+__STATIC_INLINE uint32_t LL_APB2_GRP1_IsEnabledClock(uint32_t Periphs)
+{
+ return (READ_BIT(RCC->APB2ENR, Periphs) == Periphs);
+}
+
+/**
+ * @brief Disable APB2 peripherals clock.
+ * @rmtoll APB2ENR ADC1EN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR ADC2EN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR ADC3EN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR AFIOEN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR IOPAEN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR IOPBEN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR IOPCEN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR IOPDEN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR IOPEEN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR IOPFEN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR IOPGEN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR SPI1EN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR TIM10EN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR TIM11EN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR TIM15EN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR TIM16EN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR TIM17EN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR TIM1EN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR TIM8EN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR TIM9EN LL_APB2_GRP1_DisableClock\n
+ * APB2ENR USART1EN LL_APB2_GRP1_DisableClock
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_APB2_GRP1_PERIPH_ADC1
+ * @arg @ref LL_APB2_GRP1_PERIPH_ADC2 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_ADC3 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_AFIO
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOA
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOB
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOC
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOD
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOE (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOF (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOG (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_SPI1
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM10 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM11 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM15 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM16 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM17 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM1
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM8 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM9 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_USART1
+ *
+ * (*) value not defined in all devices.
+ * @retval None
+*/
+__STATIC_INLINE void LL_APB2_GRP1_DisableClock(uint32_t Periphs)
+{
+ CLEAR_BIT(RCC->APB2ENR, Periphs);
+}
+
+/**
+ * @brief Force APB2 peripherals reset.
+ * @rmtoll APB2RSTR ADC1RST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR ADC2RST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR ADC3RST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR AFIORST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR IOPARST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR IOPBRST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR IOPCRST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR IOPDRST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR IOPERST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR IOPFRST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR IOPGRST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR SPI1RST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR TIM10RST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR TIM11RST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR TIM15RST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR TIM16RST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR TIM17RST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR TIM1RST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR TIM8RST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR TIM9RST LL_APB2_GRP1_ForceReset\n
+ * APB2RSTR USART1RST LL_APB2_GRP1_ForceReset
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_APB2_GRP1_PERIPH_ALL
+ * @arg @ref LL_APB2_GRP1_PERIPH_ADC1
+ * @arg @ref LL_APB2_GRP1_PERIPH_ADC2 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_ADC3 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_AFIO
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOA
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOB
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOC
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOD
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOE (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOF (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOG (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_SPI1
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM10 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM11 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM15 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM16 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM17 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM1
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM8 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM9 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_USART1
+ *
+ * (*) value not defined in all devices.
+ * @retval None
+*/
+__STATIC_INLINE void LL_APB2_GRP1_ForceReset(uint32_t Periphs)
+{
+ SET_BIT(RCC->APB2RSTR, Periphs);
+}
+
+/**
+ * @brief Release APB2 peripherals reset.
+ * @rmtoll APB2RSTR ADC1RST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR ADC2RST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR ADC3RST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR AFIORST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR IOPARST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR IOPBRST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR IOPCRST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR IOPDRST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR IOPERST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR IOPFRST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR IOPGRST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR SPI1RST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR TIM10RST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR TIM11RST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR TIM15RST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR TIM16RST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR TIM17RST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR TIM1RST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR TIM8RST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR TIM9RST LL_APB2_GRP1_ReleaseReset\n
+ * APB2RSTR USART1RST LL_APB2_GRP1_ReleaseReset
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_APB2_GRP1_PERIPH_ALL
+ * @arg @ref LL_APB2_GRP1_PERIPH_ADC1
+ * @arg @ref LL_APB2_GRP1_PERIPH_ADC2 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_ADC3 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_AFIO
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOA
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOB
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOC
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOD
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOE (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOF (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_GPIOG (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_SPI1
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM10 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM11 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM15 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM16 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM17 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM1
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM8 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_TIM9 (*)
+ * @arg @ref LL_APB2_GRP1_PERIPH_USART1
+ *
+ * (*) value not defined in all devices.
+ * @retval None
+*/
+__STATIC_INLINE void LL_APB2_GRP1_ReleaseReset(uint32_t Periphs)
+{
+ CLEAR_BIT(RCC->APB2RSTR, Periphs);
+}
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* defined(RCC) */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_LL_BUS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_cortex.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_cortex.h
new file mode 100644
index 0000000..50604aa
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_cortex.h
@@ -0,0 +1,656 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_cortex.h
+ * @author MCD Application Team
+ * @brief Header file of CORTEX LL module.
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The LL CORTEX driver contains a set of generic APIs that can be
+ used by user:
+ (+) SYSTICK configuration used by @ref LL_mDelay and @ref LL_Init1msTick
+ functions
+ (+) Low power mode configuration (SCB register of Cortex-MCU)
+ (+) MPU API to configure and enable regions
+ (MPU services provided only on some devices)
+ (+) API to access to MCU info (CPUID register)
+ (+) API to enable fault handler (SHCSR accesses)
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_CORTEX_H
+#define __STM32F1xx_LL_CORTEX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx.h"
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+/** @defgroup CORTEX_LL CORTEX
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/* Private constants ---------------------------------------------------------*/
+
+/* Private macros ------------------------------------------------------------*/
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup CORTEX_LL_Exported_Constants CORTEX Exported Constants
+ * @{
+ */
+
+/** @defgroup CORTEX_LL_EC_CLKSOURCE_HCLK SYSTICK Clock Source
+ * @{
+ */
+#define LL_SYSTICK_CLKSOURCE_HCLK_DIV8 0x00000000U /*!< AHB clock divided by 8 selected as SysTick clock source.*/
+#define LL_SYSTICK_CLKSOURCE_HCLK SysTick_CTRL_CLKSOURCE_Msk /*!< AHB clock selected as SysTick clock source. */
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_LL_EC_FAULT Handler Fault type
+ * @{
+ */
+#define LL_HANDLER_FAULT_USG SCB_SHCSR_USGFAULTENA_Msk /*!< Usage fault */
+#define LL_HANDLER_FAULT_BUS SCB_SHCSR_BUSFAULTENA_Msk /*!< Bus fault */
+#define LL_HANDLER_FAULT_MEM SCB_SHCSR_MEMFAULTENA_Msk /*!< Memory management fault */
+/**
+ * @}
+ */
+
+#if __MPU_PRESENT
+
+/** @defgroup CORTEX_LL_EC_CTRL_HFNMI_PRIVDEF MPU Control
+ * @{
+ */
+#define LL_MPU_CTRL_HFNMI_PRIVDEF_NONE 0x00000000U /*!< Disable NMI and privileged SW access */
+#define LL_MPU_CTRL_HARDFAULT_NMI MPU_CTRL_HFNMIENA_Msk /*!< Enables the operation of MPU during hard fault, NMI, and FAULTMASK handlers */
+#define LL_MPU_CTRL_PRIVILEGED_DEFAULT MPU_CTRL_PRIVDEFENA_Msk /*!< Enable privileged software access to default memory map */
+#define LL_MPU_CTRL_HFNMI_PRIVDEF (MPU_CTRL_HFNMIENA_Msk | MPU_CTRL_PRIVDEFENA_Msk) /*!< Enable NMI and privileged SW access */
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_LL_EC_REGION MPU Region Number
+ * @{
+ */
+#define LL_MPU_REGION_NUMBER0 0x00U /*!< REGION Number 0 */
+#define LL_MPU_REGION_NUMBER1 0x01U /*!< REGION Number 1 */
+#define LL_MPU_REGION_NUMBER2 0x02U /*!< REGION Number 2 */
+#define LL_MPU_REGION_NUMBER3 0x03U /*!< REGION Number 3 */
+#define LL_MPU_REGION_NUMBER4 0x04U /*!< REGION Number 4 */
+#define LL_MPU_REGION_NUMBER5 0x05U /*!< REGION Number 5 */
+#define LL_MPU_REGION_NUMBER6 0x06U /*!< REGION Number 6 */
+#define LL_MPU_REGION_NUMBER7 0x07U /*!< REGION Number 7 */
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_LL_EC_REGION_SIZE MPU Region Size
+ * @{
+ */
+#define LL_MPU_REGION_SIZE_32B (0x04U << MPU_RASR_SIZE_Pos) /*!< 32B Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_64B (0x05U << MPU_RASR_SIZE_Pos) /*!< 64B Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_128B (0x06U << MPU_RASR_SIZE_Pos) /*!< 128B Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_256B (0x07U << MPU_RASR_SIZE_Pos) /*!< 256B Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_512B (0x08U << MPU_RASR_SIZE_Pos) /*!< 512B Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_1KB (0x09U << MPU_RASR_SIZE_Pos) /*!< 1KB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_2KB (0x0AU << MPU_RASR_SIZE_Pos) /*!< 2KB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_4KB (0x0BU << MPU_RASR_SIZE_Pos) /*!< 4KB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_8KB (0x0CU << MPU_RASR_SIZE_Pos) /*!< 8KB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_16KB (0x0DU << MPU_RASR_SIZE_Pos) /*!< 16KB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_32KB (0x0EU << MPU_RASR_SIZE_Pos) /*!< 32KB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_64KB (0x0FU << MPU_RASR_SIZE_Pos) /*!< 64KB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_128KB (0x10U << MPU_RASR_SIZE_Pos) /*!< 128KB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_256KB (0x11U << MPU_RASR_SIZE_Pos) /*!< 256KB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_512KB (0x12U << MPU_RASR_SIZE_Pos) /*!< 512KB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_1MB (0x13U << MPU_RASR_SIZE_Pos) /*!< 1MB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_2MB (0x14U << MPU_RASR_SIZE_Pos) /*!< 2MB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_4MB (0x15U << MPU_RASR_SIZE_Pos) /*!< 4MB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_8MB (0x16U << MPU_RASR_SIZE_Pos) /*!< 8MB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_16MB (0x17U << MPU_RASR_SIZE_Pos) /*!< 16MB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_32MB (0x18U << MPU_RASR_SIZE_Pos) /*!< 32MB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_64MB (0x19U << MPU_RASR_SIZE_Pos) /*!< 64MB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_128MB (0x1AU << MPU_RASR_SIZE_Pos) /*!< 128MB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_256MB (0x1BU << MPU_RASR_SIZE_Pos) /*!< 256MB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_512MB (0x1CU << MPU_RASR_SIZE_Pos) /*!< 512MB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_1GB (0x1DU << MPU_RASR_SIZE_Pos) /*!< 1GB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_2GB (0x1EU << MPU_RASR_SIZE_Pos) /*!< 2GB Size of the MPU protection region */
+#define LL_MPU_REGION_SIZE_4GB (0x1FU << MPU_RASR_SIZE_Pos) /*!< 4GB Size of the MPU protection region */
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_LL_EC_REGION_PRIVILEDGES MPU Region Privileges
+ * @{
+ */
+#define LL_MPU_REGION_NO_ACCESS (0x00U << MPU_RASR_AP_Pos) /*!< No access*/
+#define LL_MPU_REGION_PRIV_RW (0x01U << MPU_RASR_AP_Pos) /*!< RW privileged (privileged access only)*/
+#define LL_MPU_REGION_PRIV_RW_URO (0x02U << MPU_RASR_AP_Pos) /*!< RW privileged - RO user (Write in a user program generates a fault) */
+#define LL_MPU_REGION_FULL_ACCESS (0x03U << MPU_RASR_AP_Pos) /*!< RW privileged & user (Full access) */
+#define LL_MPU_REGION_PRIV_RO (0x05U << MPU_RASR_AP_Pos) /*!< RO privileged (privileged read only)*/
+#define LL_MPU_REGION_PRIV_RO_URO (0x06U << MPU_RASR_AP_Pos) /*!< RO privileged & user (read only) */
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_LL_EC_TEX MPU TEX Level
+ * @{
+ */
+#define LL_MPU_TEX_LEVEL0 (0x00U << MPU_RASR_TEX_Pos) /*!< b000 for TEX bits */
+#define LL_MPU_TEX_LEVEL1 (0x01U << MPU_RASR_TEX_Pos) /*!< b001 for TEX bits */
+#define LL_MPU_TEX_LEVEL2 (0x02U << MPU_RASR_TEX_Pos) /*!< b010 for TEX bits */
+#define LL_MPU_TEX_LEVEL4 (0x04U << MPU_RASR_TEX_Pos) /*!< b100 for TEX bits */
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_LL_EC_INSTRUCTION_ACCESS MPU Instruction Access
+ * @{
+ */
+#define LL_MPU_INSTRUCTION_ACCESS_ENABLE 0x00U /*!< Instruction fetches enabled */
+#define LL_MPU_INSTRUCTION_ACCESS_DISABLE MPU_RASR_XN_Msk /*!< Instruction fetches disabled*/
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_LL_EC_SHAREABLE_ACCESS MPU Shareable Access
+ * @{
+ */
+#define LL_MPU_ACCESS_SHAREABLE MPU_RASR_S_Msk /*!< Shareable memory attribute */
+#define LL_MPU_ACCESS_NOT_SHAREABLE 0x00U /*!< Not Shareable memory attribute */
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_LL_EC_CACHEABLE_ACCESS MPU Cacheable Access
+ * @{
+ */
+#define LL_MPU_ACCESS_CACHEABLE MPU_RASR_C_Msk /*!< Cacheable memory attribute */
+#define LL_MPU_ACCESS_NOT_CACHEABLE 0x00U /*!< Not Cacheable memory attribute */
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_LL_EC_BUFFERABLE_ACCESS MPU Bufferable Access
+ * @{
+ */
+#define LL_MPU_ACCESS_BUFFERABLE MPU_RASR_B_Msk /*!< Bufferable memory attribute */
+#define LL_MPU_ACCESS_NOT_BUFFERABLE 0x00U /*!< Not Bufferable memory attribute */
+/**
+ * @}
+ */
+#endif /* __MPU_PRESENT */
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup CORTEX_LL_Exported_Functions CORTEX Exported Functions
+ * @{
+ */
+
+/** @defgroup CORTEX_LL_EF_SYSTICK SYSTICK
+ * @{
+ */
+
+/**
+ * @brief This function checks if the Systick counter flag is active or not.
+ * @note It can be used in timeout function on application side.
+ * @rmtoll STK_CTRL COUNTFLAG LL_SYSTICK_IsActiveCounterFlag
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_SYSTICK_IsActiveCounterFlag(void)
+{
+ return ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == (SysTick_CTRL_COUNTFLAG_Msk));
+}
+
+/**
+ * @brief Configures the SysTick clock source
+ * @rmtoll STK_CTRL CLKSOURCE LL_SYSTICK_SetClkSource
+ * @param Source This parameter can be one of the following values:
+ * @arg @ref LL_SYSTICK_CLKSOURCE_HCLK_DIV8
+ * @arg @ref LL_SYSTICK_CLKSOURCE_HCLK
+ * @retval None
+ */
+__STATIC_INLINE void LL_SYSTICK_SetClkSource(uint32_t Source)
+{
+ if (Source == LL_SYSTICK_CLKSOURCE_HCLK)
+ {
+ SET_BIT(SysTick->CTRL, LL_SYSTICK_CLKSOURCE_HCLK);
+ }
+ else
+ {
+ CLEAR_BIT(SysTick->CTRL, LL_SYSTICK_CLKSOURCE_HCLK);
+ }
+}
+
+/**
+ * @brief Get the SysTick clock source
+ * @rmtoll STK_CTRL CLKSOURCE LL_SYSTICK_GetClkSource
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_SYSTICK_CLKSOURCE_HCLK_DIV8
+ * @arg @ref LL_SYSTICK_CLKSOURCE_HCLK
+ */
+__STATIC_INLINE uint32_t LL_SYSTICK_GetClkSource(void)
+{
+ return READ_BIT(SysTick->CTRL, LL_SYSTICK_CLKSOURCE_HCLK);
+}
+
+/**
+ * @brief Enable SysTick exception request
+ * @rmtoll STK_CTRL TICKINT LL_SYSTICK_EnableIT
+ * @retval None
+ */
+__STATIC_INLINE void LL_SYSTICK_EnableIT(void)
+{
+ SET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
+}
+
+/**
+ * @brief Disable SysTick exception request
+ * @rmtoll STK_CTRL TICKINT LL_SYSTICK_DisableIT
+ * @retval None
+ */
+__STATIC_INLINE void LL_SYSTICK_DisableIT(void)
+{
+ CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
+}
+
+/**
+ * @brief Checks if the SYSTICK interrupt is enabled or disabled.
+ * @rmtoll STK_CTRL TICKINT LL_SYSTICK_IsEnabledIT
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_SYSTICK_IsEnabledIT(void)
+{
+ return (READ_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk) == (SysTick_CTRL_TICKINT_Msk));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_LL_EF_LOW_POWER_MODE LOW POWER MODE
+ * @{
+ */
+
+/**
+ * @brief Processor uses sleep as its low power mode
+ * @rmtoll SCB_SCR SLEEPDEEP LL_LPM_EnableSleep
+ * @retval None
+ */
+__STATIC_INLINE void LL_LPM_EnableSleep(void)
+{
+ /* Clear SLEEPDEEP bit of Cortex System Control Register */
+ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
+}
+
+/**
+ * @brief Processor uses deep sleep as its low power mode
+ * @rmtoll SCB_SCR SLEEPDEEP LL_LPM_EnableDeepSleep
+ * @retval None
+ */
+__STATIC_INLINE void LL_LPM_EnableDeepSleep(void)
+{
+ /* Set SLEEPDEEP bit of Cortex System Control Register */
+ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
+}
+
+/**
+ * @brief Configures sleep-on-exit when returning from Handler mode to Thread mode.
+ * @note Setting this bit to 1 enables an interrupt-driven application to avoid returning to an
+ * empty main application.
+ * @rmtoll SCB_SCR SLEEPONEXIT LL_LPM_EnableSleepOnExit
+ * @retval None
+ */
+__STATIC_INLINE void LL_LPM_EnableSleepOnExit(void)
+{
+ /* Set SLEEPONEXIT bit of Cortex System Control Register */
+ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
+}
+
+/**
+ * @brief Do not sleep when returning to Thread mode.
+ * @rmtoll SCB_SCR SLEEPONEXIT LL_LPM_DisableSleepOnExit
+ * @retval None
+ */
+__STATIC_INLINE void LL_LPM_DisableSleepOnExit(void)
+{
+ /* Clear SLEEPONEXIT bit of Cortex System Control Register */
+ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
+}
+
+/**
+ * @brief Enabled events and all interrupts, including disabled interrupts, can wakeup the
+ * processor.
+ * @rmtoll SCB_SCR SEVEONPEND LL_LPM_EnableEventOnPend
+ * @retval None
+ */
+__STATIC_INLINE void LL_LPM_EnableEventOnPend(void)
+{
+ /* Set SEVEONPEND bit of Cortex System Control Register */
+ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
+}
+
+/**
+ * @brief Only enabled interrupts or events can wakeup the processor, disabled interrupts are
+ * excluded
+ * @rmtoll SCB_SCR SEVEONPEND LL_LPM_DisableEventOnPend
+ * @retval None
+ */
+__STATIC_INLINE void LL_LPM_DisableEventOnPend(void)
+{
+ /* Clear SEVEONPEND bit of Cortex System Control Register */
+ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_LL_EF_HANDLER HANDLER
+ * @{
+ */
+
+/**
+ * @brief Enable a fault in System handler control register (SHCSR)
+ * @rmtoll SCB_SHCSR MEMFAULTENA LL_HANDLER_EnableFault
+ * @param Fault This parameter can be a combination of the following values:
+ * @arg @ref LL_HANDLER_FAULT_USG
+ * @arg @ref LL_HANDLER_FAULT_BUS
+ * @arg @ref LL_HANDLER_FAULT_MEM
+ * @retval None
+ */
+__STATIC_INLINE void LL_HANDLER_EnableFault(uint32_t Fault)
+{
+ /* Enable the system handler fault */
+ SET_BIT(SCB->SHCSR, Fault);
+}
+
+/**
+ * @brief Disable a fault in System handler control register (SHCSR)
+ * @rmtoll SCB_SHCSR MEMFAULTENA LL_HANDLER_DisableFault
+ * @param Fault This parameter can be a combination of the following values:
+ * @arg @ref LL_HANDLER_FAULT_USG
+ * @arg @ref LL_HANDLER_FAULT_BUS
+ * @arg @ref LL_HANDLER_FAULT_MEM
+ * @retval None
+ */
+__STATIC_INLINE void LL_HANDLER_DisableFault(uint32_t Fault)
+{
+ /* Disable the system handler fault */
+ CLEAR_BIT(SCB->SHCSR, Fault);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_LL_EF_MCU_INFO MCU INFO
+ * @{
+ */
+
+/**
+ * @brief Get Implementer code
+ * @rmtoll SCB_CPUID IMPLEMENTER LL_CPUID_GetImplementer
+ * @retval Value should be equal to 0x41 for ARM
+ */
+__STATIC_INLINE uint32_t LL_CPUID_GetImplementer(void)
+{
+ return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_IMPLEMENTER_Msk) >> SCB_CPUID_IMPLEMENTER_Pos);
+}
+
+/**
+ * @brief Get Variant number (The r value in the rnpn product revision identifier)
+ * @rmtoll SCB_CPUID VARIANT LL_CPUID_GetVariant
+ * @retval Value between 0 and 255 (0x1: revision 1, 0x2: revision 2)
+ */
+__STATIC_INLINE uint32_t LL_CPUID_GetVariant(void)
+{
+ return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_VARIANT_Msk) >> SCB_CPUID_VARIANT_Pos);
+}
+
+/**
+ * @brief Get Constant number
+ * @rmtoll SCB_CPUID ARCHITECTURE LL_CPUID_GetConstant
+ * @retval Value should be equal to 0xF for Cortex-M3 devices
+ */
+__STATIC_INLINE uint32_t LL_CPUID_GetConstant(void)
+{
+ return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_ARCHITECTURE_Msk) >> SCB_CPUID_ARCHITECTURE_Pos);
+}
+
+/**
+ * @brief Get Part number
+ * @rmtoll SCB_CPUID PARTNO LL_CPUID_GetParNo
+ * @retval Value should be equal to 0xC23 for Cortex-M3
+ */
+__STATIC_INLINE uint32_t LL_CPUID_GetParNo(void)
+{
+ return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_PARTNO_Msk) >> SCB_CPUID_PARTNO_Pos);
+}
+
+/**
+ * @brief Get Revision number (The p value in the rnpn product revision identifier, indicates patch release)
+ * @rmtoll SCB_CPUID REVISION LL_CPUID_GetRevision
+ * @retval Value between 0 and 255 (0x0: patch 0, 0x1: patch 1)
+ */
+__STATIC_INLINE uint32_t LL_CPUID_GetRevision(void)
+{
+ return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_REVISION_Msk) >> SCB_CPUID_REVISION_Pos);
+}
+
+/**
+ * @}
+ */
+
+#if __MPU_PRESENT
+/** @defgroup CORTEX_LL_EF_MPU MPU
+ * @{
+ */
+
+/**
+ * @brief Enable MPU with input options
+ * @rmtoll MPU_CTRL ENABLE LL_MPU_Enable
+ * @param Options This parameter can be one of the following values:
+ * @arg @ref LL_MPU_CTRL_HFNMI_PRIVDEF_NONE
+ * @arg @ref LL_MPU_CTRL_HARDFAULT_NMI
+ * @arg @ref LL_MPU_CTRL_PRIVILEGED_DEFAULT
+ * @arg @ref LL_MPU_CTRL_HFNMI_PRIVDEF
+ * @retval None
+ */
+__STATIC_INLINE void LL_MPU_Enable(uint32_t Options)
+{
+ /* Enable the MPU*/
+ WRITE_REG(MPU->CTRL, (MPU_CTRL_ENABLE_Msk | Options));
+ /* Ensure MPU settings take effects */
+ __DSB();
+ /* Sequence instruction fetches using update settings */
+ __ISB();
+}
+
+/**
+ * @brief Disable MPU
+ * @rmtoll MPU_CTRL ENABLE LL_MPU_Disable
+ * @retval None
+ */
+__STATIC_INLINE void LL_MPU_Disable(void)
+{
+ /* Make sure outstanding transfers are done */
+ __DMB();
+ /* Disable MPU*/
+ WRITE_REG(MPU->CTRL, 0U);
+}
+
+/**
+ * @brief Check if MPU is enabled or not
+ * @rmtoll MPU_CTRL ENABLE LL_MPU_IsEnabled
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_MPU_IsEnabled(void)
+{
+ return (READ_BIT(MPU->CTRL, MPU_CTRL_ENABLE_Msk) == (MPU_CTRL_ENABLE_Msk));
+}
+
+/**
+ * @brief Enable a MPU region
+ * @rmtoll MPU_RASR ENABLE LL_MPU_EnableRegion
+ * @param Region This parameter can be one of the following values:
+ * @arg @ref LL_MPU_REGION_NUMBER0
+ * @arg @ref LL_MPU_REGION_NUMBER1
+ * @arg @ref LL_MPU_REGION_NUMBER2
+ * @arg @ref LL_MPU_REGION_NUMBER3
+ * @arg @ref LL_MPU_REGION_NUMBER4
+ * @arg @ref LL_MPU_REGION_NUMBER5
+ * @arg @ref LL_MPU_REGION_NUMBER6
+ * @arg @ref LL_MPU_REGION_NUMBER7
+ * @retval None
+ */
+__STATIC_INLINE void LL_MPU_EnableRegion(uint32_t Region)
+{
+ /* Set Region number */
+ WRITE_REG(MPU->RNR, Region);
+ /* Enable the MPU region */
+ SET_BIT(MPU->RASR, MPU_RASR_ENABLE_Msk);
+}
+
+/**
+ * @brief Configure and enable a region
+ * @rmtoll MPU_RNR REGION LL_MPU_ConfigRegion\n
+ * MPU_RBAR REGION LL_MPU_ConfigRegion\n
+ * MPU_RBAR ADDR LL_MPU_ConfigRegion\n
+ * MPU_RASR XN LL_MPU_ConfigRegion\n
+ * MPU_RASR AP LL_MPU_ConfigRegion\n
+ * MPU_RASR S LL_MPU_ConfigRegion\n
+ * MPU_RASR C LL_MPU_ConfigRegion\n
+ * MPU_RASR B LL_MPU_ConfigRegion\n
+ * MPU_RASR SIZE LL_MPU_ConfigRegion
+ * @param Region This parameter can be one of the following values:
+ * @arg @ref LL_MPU_REGION_NUMBER0
+ * @arg @ref LL_MPU_REGION_NUMBER1
+ * @arg @ref LL_MPU_REGION_NUMBER2
+ * @arg @ref LL_MPU_REGION_NUMBER3
+ * @arg @ref LL_MPU_REGION_NUMBER4
+ * @arg @ref LL_MPU_REGION_NUMBER5
+ * @arg @ref LL_MPU_REGION_NUMBER6
+ * @arg @ref LL_MPU_REGION_NUMBER7
+ * @param Address Value of region base address
+ * @param SubRegionDisable Sub-region disable value between Min_Data = 0x00 and Max_Data = 0xFF
+ * @param Attributes This parameter can be a combination of the following values:
+ * @arg @ref LL_MPU_REGION_SIZE_32B or @ref LL_MPU_REGION_SIZE_64B or @ref LL_MPU_REGION_SIZE_128B or @ref LL_MPU_REGION_SIZE_256B or @ref LL_MPU_REGION_SIZE_512B
+ * or @ref LL_MPU_REGION_SIZE_1KB or @ref LL_MPU_REGION_SIZE_2KB or @ref LL_MPU_REGION_SIZE_4KB or @ref LL_MPU_REGION_SIZE_8KB or @ref LL_MPU_REGION_SIZE_16KB
+ * or @ref LL_MPU_REGION_SIZE_32KB or @ref LL_MPU_REGION_SIZE_64KB or @ref LL_MPU_REGION_SIZE_128KB or @ref LL_MPU_REGION_SIZE_256KB or @ref LL_MPU_REGION_SIZE_512KB
+ * or @ref LL_MPU_REGION_SIZE_1MB or @ref LL_MPU_REGION_SIZE_2MB or @ref LL_MPU_REGION_SIZE_4MB or @ref LL_MPU_REGION_SIZE_8MB or @ref LL_MPU_REGION_SIZE_16MB
+ * or @ref LL_MPU_REGION_SIZE_32MB or @ref LL_MPU_REGION_SIZE_64MB or @ref LL_MPU_REGION_SIZE_128MB or @ref LL_MPU_REGION_SIZE_256MB or @ref LL_MPU_REGION_SIZE_512MB
+ * or @ref LL_MPU_REGION_SIZE_1GB or @ref LL_MPU_REGION_SIZE_2GB or @ref LL_MPU_REGION_SIZE_4GB
+ * @arg @ref LL_MPU_REGION_NO_ACCESS or @ref LL_MPU_REGION_PRIV_RW or @ref LL_MPU_REGION_PRIV_RW_URO or @ref LL_MPU_REGION_FULL_ACCESS
+ * or @ref LL_MPU_REGION_PRIV_RO or @ref LL_MPU_REGION_PRIV_RO_URO
+ * @arg @ref LL_MPU_TEX_LEVEL0 or @ref LL_MPU_TEX_LEVEL1 or @ref LL_MPU_TEX_LEVEL2 or @ref LL_MPU_TEX_LEVEL4
+ * @arg @ref LL_MPU_INSTRUCTION_ACCESS_ENABLE or @ref LL_MPU_INSTRUCTION_ACCESS_DISABLE
+ * @arg @ref LL_MPU_ACCESS_SHAREABLE or @ref LL_MPU_ACCESS_NOT_SHAREABLE
+ * @arg @ref LL_MPU_ACCESS_CACHEABLE or @ref LL_MPU_ACCESS_NOT_CACHEABLE
+ * @arg @ref LL_MPU_ACCESS_BUFFERABLE or @ref LL_MPU_ACCESS_NOT_BUFFERABLE
+ * @retval None
+ */
+__STATIC_INLINE void LL_MPU_ConfigRegion(uint32_t Region, uint32_t SubRegionDisable, uint32_t Address, uint32_t Attributes)
+{
+ /* Set Region number */
+ WRITE_REG(MPU->RNR, Region);
+ /* Set base address */
+ WRITE_REG(MPU->RBAR, (Address & 0xFFFFFFE0U));
+ /* Configure MPU */
+ WRITE_REG(MPU->RASR, (MPU_RASR_ENABLE_Msk | Attributes | SubRegionDisable << MPU_RASR_SRD_Pos));
+}
+
+/**
+ * @brief Disable a region
+ * @rmtoll MPU_RNR REGION LL_MPU_DisableRegion\n
+ * MPU_RASR ENABLE LL_MPU_DisableRegion
+ * @param Region This parameter can be one of the following values:
+ * @arg @ref LL_MPU_REGION_NUMBER0
+ * @arg @ref LL_MPU_REGION_NUMBER1
+ * @arg @ref LL_MPU_REGION_NUMBER2
+ * @arg @ref LL_MPU_REGION_NUMBER3
+ * @arg @ref LL_MPU_REGION_NUMBER4
+ * @arg @ref LL_MPU_REGION_NUMBER5
+ * @arg @ref LL_MPU_REGION_NUMBER6
+ * @arg @ref LL_MPU_REGION_NUMBER7
+ * @retval None
+ */
+__STATIC_INLINE void LL_MPU_DisableRegion(uint32_t Region)
+{
+ /* Set Region number */
+ WRITE_REG(MPU->RNR, Region);
+ /* Disable the MPU region */
+ CLEAR_BIT(MPU->RASR, MPU_RASR_ENABLE_Msk);
+}
+
+/**
+ * @}
+ */
+
+#endif /* __MPU_PRESENT */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_LL_CORTEX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_crc.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_crc.h
new file mode 100644
index 0000000..dafbe9d
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_crc.h
@@ -0,0 +1,210 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_crc.h
+ * @author MCD Application Team
+ * @brief Header file of CRC LL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_CRC_H
+#define __STM32F1xx_LL_CRC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx.h"
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined(CRC)
+
+/** @defgroup CRC_LL CRC
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup CRC_LL_Exported_Macros CRC Exported Macros
+ * @{
+ */
+
+/** @defgroup CRC_LL_EM_WRITE_READ Common Write and read registers Macros
+ * @{
+ */
+
+/**
+ * @brief Write a value in CRC register
+ * @param __INSTANCE__ CRC Instance
+ * @param __REG__ Register to be written
+ * @param __VALUE__ Value to be written in the register
+ * @retval None
+ */
+#define LL_CRC_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
+
+/**
+ * @brief Read a value in CRC register
+ * @param __INSTANCE__ CRC Instance
+ * @param __REG__ Register to be read
+ * @retval Register value
+ */
+#define LL_CRC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup CRC_LL_Exported_Functions CRC Exported Functions
+ * @{
+ */
+
+/** @defgroup CRC_LL_EF_Configuration CRC Configuration functions
+ * @{
+ */
+
+/**
+ * @brief Reset the CRC calculation unit.
+ * @rmtoll CR RESET LL_CRC_ResetCRCCalculationUnit
+ * @param CRCx CRC Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_CRC_ResetCRCCalculationUnit(CRC_TypeDef *CRCx)
+{
+ WRITE_REG(CRCx->CR, CRC_CR_RESET);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup CRC_LL_EF_Data_Management Data_Management
+ * @{
+ */
+
+/**
+ * @brief Write given 32-bit data to the CRC calculator
+ * @rmtoll DR DR LL_CRC_FeedData32
+ * @param CRCx CRC Instance
+ * @param InData value to be provided to CRC calculator between between Min_Data=0 and Max_Data=0xFFFFFFFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_CRC_FeedData32(CRC_TypeDef *CRCx, uint32_t InData)
+{
+ WRITE_REG(CRCx->DR, InData);
+}
+
+/**
+ * @brief Return current CRC calculation result. 32 bits value is returned.
+ * @rmtoll DR DR LL_CRC_ReadData32
+ * @param CRCx CRC Instance
+ * @retval Current CRC calculation result as stored in CRC_DR register (32 bits).
+ */
+__STATIC_INLINE uint32_t LL_CRC_ReadData32(CRC_TypeDef *CRCx)
+{
+ return (uint32_t)(READ_REG(CRCx->DR));
+}
+
+/**
+ * @brief Return data stored in the Independent Data(IDR) register.
+ * @note This register can be used as a temporary storage location for one byte.
+ * @rmtoll IDR IDR LL_CRC_Read_IDR
+ * @param CRCx CRC Instance
+ * @retval Value stored in CRC_IDR register (General-purpose 8-bit data register).
+ */
+__STATIC_INLINE uint32_t LL_CRC_Read_IDR(CRC_TypeDef *CRCx)
+{
+ return (uint32_t)(READ_REG(CRCx->IDR));
+}
+
+/**
+ * @brief Store data in the Independent Data(IDR) register.
+ * @note This register can be used as a temporary storage location for one byte.
+ * @rmtoll IDR IDR LL_CRC_Write_IDR
+ * @param CRCx CRC Instance
+ * @param InData value to be stored in CRC_IDR register (8-bit) between between Min_Data=0 and Max_Data=0xFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_CRC_Write_IDR(CRC_TypeDef *CRCx, uint32_t InData)
+{
+ *((uint8_t __IO *)(&CRCx->IDR)) = (uint8_t) InData;
+}
+/**
+ * @}
+ */
+
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup CRC_LL_EF_Init Initialization and de-initialization functions
+ * @{
+ */
+
+ErrorStatus LL_CRC_DeInit(CRC_TypeDef *CRCx);
+
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* defined(CRC) */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_LL_CRC_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_dac.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_dac.h
new file mode 100644
index 0000000..1008ab1
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_dac.h
@@ -0,0 +1,1347 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_dac.h
+ * @author MCD Application Team
+ * @brief Header file of DAC LL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_DAC_H
+#define __STM32F1xx_LL_DAC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx.h"
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (DAC)
+
+/** @defgroup DAC_LL DAC
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup DAC_LL_Private_Constants DAC Private Constants
+ * @{
+ */
+
+/* Internal masks for DAC channels definition */
+/* To select into literal LL_DAC_CHANNEL_x the relevant bits for: */
+/* - channel bits position into register CR */
+/* - channel bits position into register SWTRIG */
+/* - channel register offset of data holding register DHRx */
+/* - channel register offset of data output register DORx */
+#define DAC_CR_CH1_BITOFFSET 0U /* Position of channel bits into registers CR, MCR, CCR, SHHR, SHRR of channel 1 */
+#define DAC_CR_CH2_BITOFFSET 16U /* Position of channel bits into registers CR, MCR, CCR, SHHR, SHRR of channel 2 */
+#define DAC_CR_CHX_BITOFFSET_MASK (DAC_CR_CH1_BITOFFSET | DAC_CR_CH2_BITOFFSET)
+
+#define DAC_SWTR_CH1 (DAC_SWTRIGR_SWTRIG1) /* Channel bit into register SWTRIGR of channel 1. This bit is into area of LL_DAC_CR_CHx_BITOFFSET but excluded by mask DAC_CR_CHX_BITOFFSET_MASK (done to be enable to trig SW start of both DAC channels simultaneously). */
+#define DAC_SWTR_CH2 (DAC_SWTRIGR_SWTRIG2) /* Channel bit into register SWTRIGR of channel 2. This bit is into area of LL_DAC_CR_CHx_BITOFFSET but excluded by mask DAC_CR_CHX_BITOFFSET_MASK (done to be enable to trig SW start of both DAC channels simultaneously). */
+#define DAC_SWTR_CHX_MASK (DAC_SWTR_CH1 | DAC_SWTR_CH2)
+
+#define DAC_REG_DHR12R1_REGOFFSET 0x00000000U /* Register DHR12Rx channel 1 taken as reference */
+#define DAC_REG_DHR12L1_REGOFFSET 0x00100000U /* Register offset of DHR12Lx channel 1 versus DHR12Rx channel 1 (shifted left of 20 bits) */
+#define DAC_REG_DHR8R1_REGOFFSET 0x02000000U /* Register offset of DHR8Rx channel 1 versus DHR12Rx channel 1 (shifted left of 24 bits) */
+#define DAC_REG_DHR12R2_REGOFFSET 0x00030000U /* Register offset of DHR12Rx channel 2 versus DHR12Rx channel 1 (shifted left of 16 bits) */
+#define DAC_REG_DHR12L2_REGOFFSET 0x00400000U /* Register offset of DHR12Lx channel 2 versus DHR12Rx channel 1 (shifted left of 20 bits) */
+#define DAC_REG_DHR8R2_REGOFFSET 0x05000000U /* Register offset of DHR8Rx channel 2 versus DHR12Rx channel 1 (shifted left of 24 bits) */
+#define DAC_REG_DHR12RX_REGOFFSET_MASK 0x000F0000U
+#define DAC_REG_DHR12LX_REGOFFSET_MASK 0x00F00000U
+#define DAC_REG_DHR8RX_REGOFFSET_MASK 0x0F000000U
+#define DAC_REG_DHRX_REGOFFSET_MASK (DAC_REG_DHR12RX_REGOFFSET_MASK | DAC_REG_DHR12LX_REGOFFSET_MASK | DAC_REG_DHR8RX_REGOFFSET_MASK)
+
+#define DAC_REG_DOR1_REGOFFSET 0x00000000U /* Register DORx channel 1 taken as reference */
+#define DAC_REG_DOR2_REGOFFSET 0x10000000U /* Register offset of DORx channel 1 versus DORx channel 2 (shifted left of 28 bits) */
+#define DAC_REG_DORX_REGOFFSET_MASK (DAC_REG_DOR1_REGOFFSET | DAC_REG_DOR2_REGOFFSET)
+
+/* DAC registers bits positions */
+#define DAC_DHR12RD_DACC2DHR_BITOFFSET_POS 16U /* Value equivalent to POSITION_VAL(DAC_DHR12RD_DACC2DHR) */
+#define DAC_DHR12LD_DACC2DHR_BITOFFSET_POS 20U /* Value equivalent to POSITION_VAL(DAC_DHR12LD_DACC2DHR) */
+#define DAC_DHR8RD_DACC2DHR_BITOFFSET_POS 8U /* Value equivalent to POSITION_VAL(DAC_DHR8RD_DACC2DHR) */
+
+/* Miscellaneous data */
+#define DAC_DIGITAL_SCALE_12BITS 4095U /* Full-scale digital value with a resolution of 12 bits (voltage range determined by analog voltage references Vref+ and Vref-, refer to reference manual) */
+
+/**
+ * @}
+ */
+
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup DAC_LL_Private_Macros DAC Private Macros
+ * @{
+ */
+
+/**
+ * @brief Driver macro reserved for internal use: isolate bits with the
+ * selected mask and shift them to the register LSB
+ * (shift mask on register position bit 0).
+ * @param __BITS__ Bits in register 32 bits
+ * @param __MASK__ Mask in register 32 bits
+ * @retval Bits in register 32 bits
+*/
+#define __DAC_MASK_SHIFT(__BITS__, __MASK__) \
+ (((__BITS__) & (__MASK__)) >> POSITION_VAL((__MASK__)))
+
+/**
+ * @brief Driver macro reserved for internal use: set a pointer to
+ * a register from a register basis from which an offset
+ * is applied.
+ * @param __REG__ Register basis from which the offset is applied.
+ * @param __REG_OFFFSET__ Offset to be applied (unit: number of registers).
+ * @retval Pointer to register address
+*/
+#define __DAC_PTR_REG_OFFSET(__REG__, __REG_OFFFSET__) \
+ ((uint32_t *)((uint32_t) ((uint32_t)(&(__REG__)) + ((__REG_OFFFSET__) << 2U))))
+
+/**
+ * @}
+ */
+
+
+/* Exported types ------------------------------------------------------------*/
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup DAC_LL_ES_INIT DAC Exported Init structure
+ * @{
+ */
+
+/**
+ * @brief Structure definition of some features of DAC instance.
+ */
+typedef struct
+{
+ uint32_t TriggerSource; /*!< Set the conversion trigger source for the selected DAC channel: internal (SW start) or from external IP (timer event, external interrupt line).
+ This parameter can be a value of @ref DAC_LL_EC_TRIGGER_SOURCE
+
+ This feature can be modified afterwards using unitary function @ref LL_DAC_SetTriggerSource(). */
+
+ uint32_t WaveAutoGeneration; /*!< Set the waveform automatic generation mode for the selected DAC channel.
+ This parameter can be a value of @ref DAC_LL_EC_WAVE_AUTO_GENERATION_MODE
+
+ This feature can be modified afterwards using unitary function @ref LL_DAC_SetWaveAutoGeneration(). */
+
+ uint32_t WaveAutoGenerationConfig; /*!< Set the waveform automatic generation mode for the selected DAC channel.
+ If waveform automatic generation mode is set to noise, this parameter can be a value of @ref DAC_LL_EC_WAVE_NOISE_LFSR_UNMASK_BITS
+ If waveform automatic generation mode is set to triangle, this parameter can be a value of @ref DAC_LL_EC_WAVE_TRIANGLE_AMPLITUDE
+ @note If waveform automatic generation mode is disabled, this parameter is discarded.
+
+ This feature can be modified afterwards using unitary function @ref LL_DAC_SetWaveNoiseLFSR() or @ref LL_DAC_SetWaveTriangleAmplitude(), depending on the wave automatic generation selected. */
+
+ uint32_t OutputBuffer; /*!< Set the output buffer for the selected DAC channel.
+ This parameter can be a value of @ref DAC_LL_EC_OUTPUT_BUFFER
+
+ This feature can be modified afterwards using unitary function @ref LL_DAC_SetOutputBuffer(). */
+
+} LL_DAC_InitTypeDef;
+
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup DAC_LL_Exported_Constants DAC Exported Constants
+ * @{
+ */
+
+/** @defgroup DAC_LL_EC_GET_FLAG DAC flags
+ * @brief Flags defines which can be used with LL_DAC_ReadReg function
+ * @{
+ */
+/* DAC channel 1 flags */
+#if defined(DAC_SR_DMAUDR1)
+#define LL_DAC_FLAG_DMAUDR1 (DAC_SR_DMAUDR1) /*!< DAC channel 1 flag DMA underrun */
+#endif /* DAC_SR_DMAUDR1 */
+
+/* DAC channel 2 flags */
+#if defined(DAC_SR_DMAUDR2)
+#define LL_DAC_FLAG_DMAUDR2 (DAC_SR_DMAUDR2) /*!< DAC channel 2 flag DMA underrun */
+#endif /* DAC_SR_DMAUDR2 */
+/**
+ * @}
+ */
+
+/** @defgroup DAC_LL_EC_IT DAC interruptions
+ * @brief IT defines which can be used with LL_DAC_ReadReg and LL_DAC_WriteReg functions
+ * @{
+ */
+#if defined(DAC_CR_DMAUDRIE1)
+#define LL_DAC_IT_DMAUDRIE1 (DAC_CR_DMAUDRIE1) /*!< DAC channel 1 interruption DMA underrun */
+#endif /* DAC_CR_DMAUDRIE1 */
+#if defined(DAC_CR_DMAUDRIE2)
+#define LL_DAC_IT_DMAUDRIE2 (DAC_CR_DMAUDRIE2) /*!< DAC channel 2 interruption DMA underrun */
+#endif /* DAC_CR_DMAUDRIE2 */
+/**
+ * @}
+ */
+
+/** @defgroup DAC_LL_EC_CHANNEL DAC channels
+ * @{
+ */
+#define LL_DAC_CHANNEL_1 (DAC_REG_DOR1_REGOFFSET | DAC_REG_DHR12R1_REGOFFSET | DAC_REG_DHR12L1_REGOFFSET | DAC_REG_DHR8R1_REGOFFSET | DAC_CR_CH1_BITOFFSET | DAC_SWTR_CH1) /*!< DAC channel 1 */
+#define LL_DAC_CHANNEL_2 (DAC_REG_DOR2_REGOFFSET | DAC_REG_DHR12R2_REGOFFSET | DAC_REG_DHR12L2_REGOFFSET | DAC_REG_DHR8R2_REGOFFSET | DAC_CR_CH2_BITOFFSET | DAC_SWTR_CH2) /*!< DAC channel 2 */
+/**
+ * @}
+ */
+
+/** @defgroup DAC_LL_EC_TRIGGER_SOURCE DAC trigger source
+ * @{
+ */
+#define LL_DAC_TRIG_SOFTWARE (DAC_CR_TSEL1_2 | DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger internal (SW start) */
+#define LL_DAC_TRIG_EXT_TIM3_TRGO ( DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external IP: TIM3 TRGO. */
+#define LL_DAC_TRIG_EXT_TIM15_TRGO ( DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external IP: TIM15 TRGO. */
+#define LL_DAC_TRIG_EXT_TIM2_TRGO (DAC_CR_TSEL1_2 ) /*!< DAC channel conversion trigger from external IP: TIM2 TRGO. */
+#define LL_DAC_TRIG_EXT_TIM8_TRGO ( DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external IP: TIM8 TRGO. */
+#define LL_DAC_TRIG_EXT_TIM4_TRGO (DAC_CR_TSEL1_2 | DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external IP: TIM4 TRGO. */
+#define LL_DAC_TRIG_EXT_TIM6_TRGO 0x00000000U /*!< DAC channel conversion trigger from external IP: TIM6 TRGO. */
+#define LL_DAC_TRIG_EXT_TIM7_TRGO ( DAC_CR_TSEL1_1 ) /*!< DAC channel conversion trigger from external IP: TIM7 TRGO. */
+#define LL_DAC_TRIG_EXT_TIM5_TRGO ( DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external IP: TIM5 TRGO. */
+#define LL_DAC_TRIG_EXT_EXTI_LINE9 (DAC_CR_TSEL1_2 | DAC_CR_TSEL1_1 ) /*!< DAC channel conversion trigger from external IP: external interrupt line 9. */
+/**
+ * @}
+ */
+
+/** @defgroup DAC_LL_EC_WAVE_AUTO_GENERATION_MODE DAC waveform automatic generation mode
+ * @{
+ */
+#define LL_DAC_WAVE_AUTO_GENERATION_NONE 0x00000000U /*!< DAC channel wave auto generation mode disabled. */
+#define LL_DAC_WAVE_AUTO_GENERATION_NOISE (DAC_CR_WAVE1_0) /*!< DAC channel wave auto generation mode enabled, set generated noise waveform. */
+#define LL_DAC_WAVE_AUTO_GENERATION_TRIANGLE (DAC_CR_WAVE1_1) /*!< DAC channel wave auto generation mode enabled, set generated triangle waveform. */
+/**
+ * @}
+ */
+
+/** @defgroup DAC_LL_EC_WAVE_NOISE_LFSR_UNMASK_BITS DAC wave generation - Noise LFSR unmask bits
+ * @{
+ */
+#define LL_DAC_NOISE_LFSR_UNMASK_BIT0 0x00000000U /*!< Noise wave generation, unmask LFSR bit0, for the selected DAC channel */
+#define LL_DAC_NOISE_LFSR_UNMASK_BITS1_0 ( DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[1:0], for the selected DAC channel */
+#define LL_DAC_NOISE_LFSR_UNMASK_BITS2_0 ( DAC_CR_MAMP1_1 ) /*!< Noise wave generation, unmask LFSR bits[2:0], for the selected DAC channel */
+#define LL_DAC_NOISE_LFSR_UNMASK_BITS3_0 ( DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[3:0], for the selected DAC channel */
+#define LL_DAC_NOISE_LFSR_UNMASK_BITS4_0 ( DAC_CR_MAMP1_2 ) /*!< Noise wave generation, unmask LFSR bits[4:0], for the selected DAC channel */
+#define LL_DAC_NOISE_LFSR_UNMASK_BITS5_0 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[5:0], for the selected DAC channel */
+#define LL_DAC_NOISE_LFSR_UNMASK_BITS6_0 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 ) /*!< Noise wave generation, unmask LFSR bits[6:0], for the selected DAC channel */
+#define LL_DAC_NOISE_LFSR_UNMASK_BITS7_0 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[7:0], for the selected DAC channel */
+#define LL_DAC_NOISE_LFSR_UNMASK_BITS8_0 (DAC_CR_MAMP1_3 ) /*!< Noise wave generation, unmask LFSR bits[8:0], for the selected DAC channel */
+#define LL_DAC_NOISE_LFSR_UNMASK_BITS9_0 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[9:0], for the selected DAC channel */
+#define LL_DAC_NOISE_LFSR_UNMASK_BITS10_0 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 ) /*!< Noise wave generation, unmask LFSR bits[10:0], for the selected DAC channel */
+#define LL_DAC_NOISE_LFSR_UNMASK_BITS11_0 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[11:0], for the selected DAC channel */
+/**
+ * @}
+ */
+
+/** @defgroup DAC_LL_EC_WAVE_TRIANGLE_AMPLITUDE DAC wave generation - Triangle amplitude
+ * @{
+ */
+#define LL_DAC_TRIANGLE_AMPLITUDE_1 0x00000000U /*!< Triangle wave generation, amplitude of 1 LSB of DAC output range, for the selected DAC channel */
+#define LL_DAC_TRIANGLE_AMPLITUDE_3 ( DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 3 LSB of DAC output range, for the selected DAC channel */
+#define LL_DAC_TRIANGLE_AMPLITUDE_7 ( DAC_CR_MAMP1_1 ) /*!< Triangle wave generation, amplitude of 7 LSB of DAC output range, for the selected DAC channel */
+#define LL_DAC_TRIANGLE_AMPLITUDE_15 ( DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 15 LSB of DAC output range, for the selected DAC channel */
+#define LL_DAC_TRIANGLE_AMPLITUDE_31 ( DAC_CR_MAMP1_2 ) /*!< Triangle wave generation, amplitude of 31 LSB of DAC output range, for the selected DAC channel */
+#define LL_DAC_TRIANGLE_AMPLITUDE_63 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 63 LSB of DAC output range, for the selected DAC channel */
+#define LL_DAC_TRIANGLE_AMPLITUDE_127 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 ) /*!< Triangle wave generation, amplitude of 127 LSB of DAC output range, for the selected DAC channel */
+#define LL_DAC_TRIANGLE_AMPLITUDE_255 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 255 LSB of DAC output range, for the selected DAC channel */
+#define LL_DAC_TRIANGLE_AMPLITUDE_511 (DAC_CR_MAMP1_3 ) /*!< Triangle wave generation, amplitude of 512 LSB of DAC output range, for the selected DAC channel */
+#define LL_DAC_TRIANGLE_AMPLITUDE_1023 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 1023 LSB of DAC output range, for the selected DAC channel */
+#define LL_DAC_TRIANGLE_AMPLITUDE_2047 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 ) /*!< Triangle wave generation, amplitude of 2047 LSB of DAC output range, for the selected DAC channel */
+#define LL_DAC_TRIANGLE_AMPLITUDE_4095 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 4095 LSB of DAC output range, for the selected DAC channel */
+/**
+ * @}
+ */
+
+/** @defgroup DAC_LL_EC_OUTPUT_BUFFER DAC channel output buffer
+ * @{
+ */
+#define LL_DAC_OUTPUT_BUFFER_ENABLE 0x00000000U /*!< The selected DAC channel output is buffered: higher drive current capability, but also higher current consumption */
+#define LL_DAC_OUTPUT_BUFFER_DISABLE (DAC_CR_BOFF1) /*!< The selected DAC channel output is not buffered: lower drive current capability, but also lower current consumption */
+/**
+ * @}
+ */
+
+
+/** @defgroup DAC_LL_EC_RESOLUTION DAC channel output resolution
+ * @{
+ */
+#define LL_DAC_RESOLUTION_12B 0x00000000U /*!< DAC channel resolution 12 bits */
+#define LL_DAC_RESOLUTION_8B 0x00000002U /*!< DAC channel resolution 8 bits */
+/**
+ * @}
+ */
+
+/** @defgroup DAC_LL_EC_REGISTERS DAC registers compliant with specific purpose
+ * @{
+ */
+/* List of DAC registers intended to be used (most commonly) with */
+/* DMA transfer. */
+/* Refer to function @ref LL_DAC_DMA_GetRegAddr(). */
+#define LL_DAC_DMA_REG_DATA_12BITS_RIGHT_ALIGNED DAC_REG_DHR12RX_REGOFFSET_MASK /*!< DAC channel data holding register 12 bits right aligned */
+#define LL_DAC_DMA_REG_DATA_12BITS_LEFT_ALIGNED DAC_REG_DHR12LX_REGOFFSET_MASK /*!< DAC channel data holding register 12 bits left aligned */
+#define LL_DAC_DMA_REG_DATA_8BITS_RIGHT_ALIGNED DAC_REG_DHR8RX_REGOFFSET_MASK /*!< DAC channel data holding register 8 bits right aligned */
+/**
+ * @}
+ */
+
+/** @defgroup DAC_LL_EC_HW_DELAYS Definitions of DAC hardware constraints delays
+ * @note Only DAC IP HW delays are defined in DAC LL driver driver,
+ * not timeout values.
+ * For details on delays values, refer to descriptions in source code
+ * above each literal definition.
+ * @{
+ */
+
+/* Delay for DAC channel voltage settling time from DAC channel startup */
+/* (transition from disable to enable). */
+/* Note: DAC channel startup time depends on board application environment: */
+/* impedance connected to DAC channel output. */
+/* The delay below is specified under conditions: */
+/* - voltage maximum transition (lowest to highest value) */
+/* - until voltage reaches final value +-1LSB */
+/* - DAC channel output buffer enabled */
+/* - load impedance of 5kOhm (min), 50pF (max) */
+/* Literal set to maximum value (refer to device datasheet, */
+/* parameter "tWAKEUP"). */
+/* Unit: us */
+#define LL_DAC_DELAY_STARTUP_VOLTAGE_SETTLING_US 15U /*!< Delay for DAC channel voltage settling time from DAC channel startup (transition from disable to enable) */
+
+/* Delay for DAC channel voltage settling time. */
+/* Note: DAC channel startup time depends on board application environment: */
+/* impedance connected to DAC channel output. */
+/* The delay below is specified under conditions: */
+/* - voltage maximum transition (lowest to highest value) */
+/* - until voltage reaches final value +-1LSB */
+/* - DAC channel output buffer enabled */
+/* - load impedance of 5kOhm min, 50pF max */
+/* Literal set to maximum value (refer to device datasheet, */
+/* parameter "tSETTLING"). */
+/* Unit: us */
+#define LL_DAC_DELAY_VOLTAGE_SETTLING_US 12U /*!< Delay for DAC channel voltage settling time */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup DAC_LL_Exported_Macros DAC Exported Macros
+ * @{
+ */
+
+/** @defgroup DAC_LL_EM_WRITE_READ Common write and read registers macros
+ * @{
+ */
+
+/**
+ * @brief Write a value in DAC register
+ * @param __INSTANCE__ DAC Instance
+ * @param __REG__ Register to be written
+ * @param __VALUE__ Value to be written in the register
+ * @retval None
+ */
+#define LL_DAC_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
+
+/**
+ * @brief Read a value in DAC register
+ * @param __INSTANCE__ DAC Instance
+ * @param __REG__ Register to be read
+ * @retval Register value
+ */
+#define LL_DAC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
+
+/**
+ * @}
+ */
+
+/** @defgroup DAC_LL_EM_HELPER_MACRO DAC helper macro
+ * @{
+ */
+
+/**
+ * @brief Helper macro to get DAC channel number in decimal format
+ * from literals LL_DAC_CHANNEL_x.
+ * Example:
+ * __LL_DAC_CHANNEL_TO_DECIMAL_NB(LL_DAC_CHANNEL_1)
+ * will return decimal number "1".
+ * @note The input can be a value from functions where a channel
+ * number is returned.
+ * @param __CHANNEL__ This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @retval 1...2
+ */
+#define __LL_DAC_CHANNEL_TO_DECIMAL_NB(__CHANNEL__) \
+ ((__CHANNEL__) & DAC_SWTR_CHX_MASK)
+
+/**
+ * @brief Helper macro to get DAC channel in literal format LL_DAC_CHANNEL_x
+ * from number in decimal format.
+ * Example:
+ * __LL_DAC_DECIMAL_NB_TO_CHANNEL(1)
+ * will return a data equivalent to "LL_DAC_CHANNEL_1".
+ * @note If the input parameter does not correspond to a DAC channel,
+ * this macro returns value '0'.
+ * @param __DECIMAL_NB__ 1...2
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ */
+#define __LL_DAC_DECIMAL_NB_TO_CHANNEL(__DECIMAL_NB__) \
+ (((__DECIMAL_NB__) == 1U) \
+ ? ( \
+ LL_DAC_CHANNEL_1 \
+ ) \
+ : \
+ (((__DECIMAL_NB__) == 2U) \
+ ? ( \
+ LL_DAC_CHANNEL_2 \
+ ) \
+ : \
+ ( \
+ 0 \
+ ) \
+ ) \
+ )
+
+/**
+ * @brief Helper macro to define the DAC conversion data full-scale digital
+ * value corresponding to the selected DAC resolution.
+ * @note DAC conversion data full-scale corresponds to voltage range
+ * determined by analog voltage references Vref+ and Vref-
+ * (refer to reference manual).
+ * @param __DAC_RESOLUTION__ This parameter can be one of the following values:
+ * @arg @ref LL_DAC_RESOLUTION_12B
+ * @arg @ref LL_DAC_RESOLUTION_8B
+ * @retval ADC conversion data equivalent voltage value (unit: mVolt)
+ */
+#define __LL_DAC_DIGITAL_SCALE(__DAC_RESOLUTION__) \
+ ((0x00000FFFU) >> ((__DAC_RESOLUTION__) << 1U))
+
+/**
+ * @brief Helper macro to calculate the DAC conversion data (unit: digital
+ * value) corresponding to a voltage (unit: mVolt).
+ * @note This helper macro is intended to provide input data in voltage
+ * rather than digital value,
+ * to be used with LL DAC functions such as
+ * @ref LL_DAC_ConvertData12RightAligned().
+ * @note Analog reference voltage (Vref+) must be either known from
+ * user board environment or can be calculated using ADC measurement
+ * and ADC helper macro @ref __LL_ADC_CALC_VREFANALOG_VOLTAGE().
+ * @param __VREFANALOG_VOLTAGE__ Analog reference voltage (unit: mV)
+ * @param __DAC_VOLTAGE__ Voltage to be generated by DAC channel
+ * (unit: mVolt).
+ * @param __DAC_RESOLUTION__ This parameter can be one of the following values:
+ * @arg @ref LL_DAC_RESOLUTION_12B
+ * @arg @ref LL_DAC_RESOLUTION_8B
+ * @retval DAC conversion data (unit: digital value)
+ */
+#define __LL_DAC_CALC_VOLTAGE_TO_DATA(__VREFANALOG_VOLTAGE__,\
+ __DAC_VOLTAGE__,\
+ __DAC_RESOLUTION__) \
+ ((__DAC_VOLTAGE__) * __LL_DAC_DIGITAL_SCALE(__DAC_RESOLUTION__) \
+ / (__VREFANALOG_VOLTAGE__) \
+ )
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup DAC_LL_Exported_Functions DAC Exported Functions
+ * @{
+ */
+/** @defgroup DAC_LL_EF_Configuration Configuration of DAC channels
+ * @{
+ */
+
+/**
+ * @brief Set the conversion trigger source for the selected DAC channel.
+ * @note For conversion trigger source to be effective, DAC trigger
+ * must be enabled using function @ref LL_DAC_EnableTrigger().
+ * @note To set conversion trigger source, DAC channel must be disabled.
+ * Otherwise, the setting is discarded.
+ * @note Availability of parameters of trigger sources from timer
+ * depends on timers availability on the selected device.
+ * @rmtoll CR TSEL1 LL_DAC_SetTriggerSource\n
+ * CR TSEL2 LL_DAC_SetTriggerSource
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @param TriggerSource This parameter can be one of the following values:
+ * @arg @ref LL_DAC_TRIG_SOFTWARE
+ * @arg @ref LL_DAC_TRIG_EXT_TIM3_TRGO
+ * @arg @ref LL_DAC_TRIG_EXT_TIM15_TRGO
+ * @arg @ref LL_DAC_TRIG_EXT_TIM8_TRGO
+ * @arg @ref LL_DAC_TRIG_EXT_TIM7_TRGO
+ * @arg @ref LL_DAC_TRIG_EXT_TIM6_TRGO
+ * @arg @ref LL_DAC_TRIG_EXT_TIM5_TRGO
+ * @arg @ref LL_DAC_TRIG_EXT_TIM4_TRGO
+ * @arg @ref LL_DAC_TRIG_EXT_TIM2_TRGO
+ * @arg @ref LL_DAC_TRIG_EXT_EXTI_LINE9
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_SetTriggerSource(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t TriggerSource)
+{
+ MODIFY_REG(DACx->CR,
+ DAC_CR_TSEL1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK),
+ TriggerSource << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
+}
+
+/**
+ * @brief Get the conversion trigger source for the selected DAC channel.
+ * @note For conversion trigger source to be effective, DAC trigger
+ * must be enabled using function @ref LL_DAC_EnableTrigger().
+ * @note Availability of parameters of trigger sources from timer
+ * depends on timers availability on the selected device.
+ * @rmtoll CR TSEL1 LL_DAC_GetTriggerSource\n
+ * CR TSEL2 LL_DAC_GetTriggerSource
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_DAC_TRIG_SOFTWARE
+ * @arg @ref LL_DAC_TRIG_EXT_TIM3_TRGO
+ * @arg @ref LL_DAC_TRIG_EXT_TIM15_TRGO
+ * @arg @ref LL_DAC_TRIG_EXT_TIM8_TRGO
+ * @arg @ref LL_DAC_TRIG_EXT_TIM7_TRGO
+ * @arg @ref LL_DAC_TRIG_EXT_TIM6_TRGO
+ * @arg @ref LL_DAC_TRIG_EXT_TIM5_TRGO
+ * @arg @ref LL_DAC_TRIG_EXT_TIM4_TRGO
+ * @arg @ref LL_DAC_TRIG_EXT_TIM2_TRGO
+ * @arg @ref LL_DAC_TRIG_EXT_EXTI_LINE9
+ */
+__STATIC_INLINE uint32_t LL_DAC_GetTriggerSource(DAC_TypeDef *DACx, uint32_t DAC_Channel)
+{
+ return (uint32_t)(READ_BIT(DACx->CR, DAC_CR_TSEL1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))
+ >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)
+ );
+}
+
+/**
+ * @brief Set the waveform automatic generation mode
+ * for the selected DAC channel.
+ * @rmtoll CR WAVE1 LL_DAC_SetWaveAutoGeneration\n
+ * CR WAVE2 LL_DAC_SetWaveAutoGeneration
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @param WaveAutoGeneration This parameter can be one of the following values:
+ * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_NONE
+ * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_NOISE
+ * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_TRIANGLE
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_SetWaveAutoGeneration(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t WaveAutoGeneration)
+{
+ MODIFY_REG(DACx->CR,
+ DAC_CR_WAVE1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK),
+ WaveAutoGeneration << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
+}
+
+/**
+ * @brief Get the waveform automatic generation mode
+ * for the selected DAC channel.
+ * @rmtoll CR WAVE1 LL_DAC_GetWaveAutoGeneration\n
+ * CR WAVE2 LL_DAC_GetWaveAutoGeneration
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_NONE
+ * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_NOISE
+ * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_TRIANGLE
+ */
+__STATIC_INLINE uint32_t LL_DAC_GetWaveAutoGeneration(DAC_TypeDef *DACx, uint32_t DAC_Channel)
+{
+ return (uint32_t)(READ_BIT(DACx->CR, DAC_CR_WAVE1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))
+ >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)
+ );
+}
+
+/**
+ * @brief Set the noise waveform generation for the selected DAC channel:
+ * Noise mode and parameters LFSR (linear feedback shift register).
+ * @note For wave generation to be effective, DAC channel
+ * wave generation mode must be enabled using
+ * function @ref LL_DAC_SetWaveAutoGeneration().
+ * @note This setting can be set when the selected DAC channel is disabled
+ * (otherwise, the setting operation is ignored).
+ * @rmtoll CR MAMP1 LL_DAC_SetWaveNoiseLFSR\n
+ * CR MAMP2 LL_DAC_SetWaveNoiseLFSR
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @param NoiseLFSRMask This parameter can be one of the following values:
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BIT0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS1_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS2_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS3_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS4_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS5_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS6_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS7_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS8_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS9_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS10_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS11_0
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_SetWaveNoiseLFSR(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t NoiseLFSRMask)
+{
+ MODIFY_REG(DACx->CR,
+ DAC_CR_MAMP1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK),
+ NoiseLFSRMask << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
+}
+
+/**
+ * @brief Set the noise waveform generation for the selected DAC channel:
+ * Noise mode and parameters LFSR (linear feedback shift register).
+ * @rmtoll CR MAMP1 LL_DAC_GetWaveNoiseLFSR\n
+ * CR MAMP2 LL_DAC_GetWaveNoiseLFSR
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BIT0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS1_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS2_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS3_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS4_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS5_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS6_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS7_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS8_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS9_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS10_0
+ * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS11_0
+ */
+__STATIC_INLINE uint32_t LL_DAC_GetWaveNoiseLFSR(DAC_TypeDef *DACx, uint32_t DAC_Channel)
+{
+ return (uint32_t)(READ_BIT(DACx->CR, DAC_CR_MAMP1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))
+ >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)
+ );
+}
+
+/**
+ * @brief Set the triangle waveform generation for the selected DAC channel:
+ * triangle mode and amplitude.
+ * @note For wave generation to be effective, DAC channel
+ * wave generation mode must be enabled using
+ * function @ref LL_DAC_SetWaveAutoGeneration().
+ * @note This setting can be set when the selected DAC channel is disabled
+ * (otherwise, the setting operation is ignored).
+ * @rmtoll CR MAMP1 LL_DAC_SetWaveTriangleAmplitude\n
+ * CR MAMP2 LL_DAC_SetWaveTriangleAmplitude
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @param TriangleAmplitude This parameter can be one of the following values:
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_1
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_3
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_7
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_15
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_31
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_63
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_127
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_255
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_511
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_1023
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_2047
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_4095
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_SetWaveTriangleAmplitude(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t TriangleAmplitude)
+{
+ MODIFY_REG(DACx->CR,
+ DAC_CR_MAMP1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK),
+ TriangleAmplitude << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
+}
+
+/**
+ * @brief Set the triangle waveform generation for the selected DAC channel:
+ * triangle mode and amplitude.
+ * @rmtoll CR MAMP1 LL_DAC_GetWaveTriangleAmplitude\n
+ * CR MAMP2 LL_DAC_GetWaveTriangleAmplitude
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_1
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_3
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_7
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_15
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_31
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_63
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_127
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_255
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_511
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_1023
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_2047
+ * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_4095
+ */
+__STATIC_INLINE uint32_t LL_DAC_GetWaveTriangleAmplitude(DAC_TypeDef *DACx, uint32_t DAC_Channel)
+{
+ return (uint32_t)(READ_BIT(DACx->CR, DAC_CR_MAMP1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))
+ >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)
+ );
+}
+
+/**
+ * @brief Set the output buffer for the selected DAC channel.
+ * @rmtoll CR BOFF1 LL_DAC_SetOutputBuffer\n
+ * CR BOFF2 LL_DAC_SetOutputBuffer
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @param OutputBuffer This parameter can be one of the following values:
+ * @arg @ref LL_DAC_OUTPUT_BUFFER_ENABLE
+ * @arg @ref LL_DAC_OUTPUT_BUFFER_DISABLE
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_SetOutputBuffer(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t OutputBuffer)
+{
+ MODIFY_REG(DACx->CR,
+ DAC_CR_BOFF1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK),
+ OutputBuffer << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
+}
+
+/**
+ * @brief Get the output buffer state for the selected DAC channel.
+ * @rmtoll CR BOFF1 LL_DAC_GetOutputBuffer\n
+ * CR BOFF2 LL_DAC_GetOutputBuffer
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_DAC_OUTPUT_BUFFER_ENABLE
+ * @arg @ref LL_DAC_OUTPUT_BUFFER_DISABLE
+ */
+__STATIC_INLINE uint32_t LL_DAC_GetOutputBuffer(DAC_TypeDef *DACx, uint32_t DAC_Channel)
+{
+ return (uint32_t)(READ_BIT(DACx->CR, DAC_CR_BOFF1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))
+ >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)
+ );
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup DAC_LL_EF_DMA_Management DMA Management
+ * @{
+ */
+
+/**
+ * @brief Enable DAC DMA transfer request of the selected channel.
+ * @note To configure DMA source address (peripheral address),
+ * use function @ref LL_DAC_DMA_GetRegAddr().
+ * @rmtoll CR DMAEN1 LL_DAC_EnableDMAReq\n
+ * CR DMAEN2 LL_DAC_EnableDMAReq
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_EnableDMAReq(DAC_TypeDef *DACx, uint32_t DAC_Channel)
+{
+ SET_BIT(DACx->CR,
+ DAC_CR_DMAEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
+}
+
+/**
+ * @brief Disable DAC DMA transfer request of the selected channel.
+ * @note To configure DMA source address (peripheral address),
+ * use function @ref LL_DAC_DMA_GetRegAddr().
+ * @rmtoll CR DMAEN1 LL_DAC_DisableDMAReq\n
+ * CR DMAEN2 LL_DAC_DisableDMAReq
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_DisableDMAReq(DAC_TypeDef *DACx, uint32_t DAC_Channel)
+{
+ CLEAR_BIT(DACx->CR,
+ DAC_CR_DMAEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
+}
+
+/**
+ * @brief Get DAC DMA transfer request state of the selected channel.
+ * (0: DAC DMA transfer request is disabled, 1: DAC DMA transfer request is enabled)
+ * @rmtoll CR DMAEN1 LL_DAC_IsDMAReqEnabled\n
+ * CR DMAEN2 LL_DAC_IsDMAReqEnabled
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DAC_IsDMAReqEnabled(DAC_TypeDef *DACx, uint32_t DAC_Channel)
+{
+ return (READ_BIT(DACx->CR,
+ DAC_CR_DMAEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))
+ == (DAC_CR_DMAEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)));
+}
+
+/**
+ * @brief Function to help to configure DMA transfer to DAC: retrieve the
+ * DAC register address from DAC instance and a list of DAC registers
+ * intended to be used (most commonly) with DMA transfer.
+ * @note These DAC registers are data holding registers:
+ * when DAC conversion is requested, DAC generates a DMA transfer
+ * request to have data available in DAC data holding registers.
+ * @note This macro is intended to be used with LL DMA driver, refer to
+ * function "LL_DMA_ConfigAddresses()".
+ * Example:
+ * LL_DMA_ConfigAddresses(DMA1,
+ * LL_DMA_CHANNEL_1,
+ * (uint32_t)&< array or variable >,
+ * LL_DAC_DMA_GetRegAddr(DAC1, LL_DAC_CHANNEL_1, LL_DAC_DMA_REG_DATA_12BITS_RIGHT_ALIGNED),
+ * LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
+ * @rmtoll DHR12R1 DACC1DHR LL_DAC_DMA_GetRegAddr\n
+ * DHR12L1 DACC1DHR LL_DAC_DMA_GetRegAddr\n
+ * DHR8R1 DACC1DHR LL_DAC_DMA_GetRegAddr\n
+ * DHR12R2 DACC2DHR LL_DAC_DMA_GetRegAddr\n
+ * DHR12L2 DACC2DHR LL_DAC_DMA_GetRegAddr\n
+ * DHR8R2 DACC2DHR LL_DAC_DMA_GetRegAddr
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @param Register This parameter can be one of the following values:
+ * @arg @ref LL_DAC_DMA_REG_DATA_12BITS_RIGHT_ALIGNED
+ * @arg @ref LL_DAC_DMA_REG_DATA_12BITS_LEFT_ALIGNED
+ * @arg @ref LL_DAC_DMA_REG_DATA_8BITS_RIGHT_ALIGNED
+ * @retval DAC register address
+ */
+__STATIC_INLINE uint32_t LL_DAC_DMA_GetRegAddr(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t Register)
+{
+ /* Retrieve address of register DHR12Rx, DHR12Lx or DHR8Rx depending on */
+ /* DAC channel selected. */
+ return ((uint32_t)(__DAC_PTR_REG_OFFSET((DACx)->DHR12R1, __DAC_MASK_SHIFT(DAC_Channel, Register))));
+}
+/**
+ * @}
+ */
+
+/** @defgroup DAC_LL_EF_Operation Operation on DAC channels
+ * @{
+ */
+
+/**
+ * @brief Enable DAC selected channel.
+ * @rmtoll CR EN1 LL_DAC_Enable\n
+ * CR EN2 LL_DAC_Enable
+ * @note After enable from off state, DAC channel requires a delay
+ * for output voltage to reach accuracy +/- 1 LSB.
+ * Refer to device datasheet, parameter "tWAKEUP".
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_Enable(DAC_TypeDef *DACx, uint32_t DAC_Channel)
+{
+ SET_BIT(DACx->CR,
+ DAC_CR_EN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
+}
+
+/**
+ * @brief Disable DAC selected channel.
+ * @rmtoll CR EN1 LL_DAC_Disable\n
+ * CR EN2 LL_DAC_Disable
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_Disable(DAC_TypeDef *DACx, uint32_t DAC_Channel)
+{
+ CLEAR_BIT(DACx->CR,
+ DAC_CR_EN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
+}
+
+/**
+ * @brief Get DAC enable state of the selected channel.
+ * (0: DAC channel is disabled, 1: DAC channel is enabled)
+ * @rmtoll CR EN1 LL_DAC_IsEnabled\n
+ * CR EN2 LL_DAC_IsEnabled
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DAC_IsEnabled(DAC_TypeDef *DACx, uint32_t DAC_Channel)
+{
+ return (READ_BIT(DACx->CR,
+ DAC_CR_EN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))
+ == (DAC_CR_EN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)));
+}
+
+/**
+ * @brief Enable DAC trigger of the selected channel.
+ * @note - If DAC trigger is disabled, DAC conversion is performed
+ * automatically once the data holding register is updated,
+ * using functions "LL_DAC_ConvertData{8; 12}{Right; Left} Aligned()":
+ * @ref LL_DAC_ConvertData12RightAligned(), ...
+ * - If DAC trigger is enabled, DAC conversion is performed
+ * only when a hardware of software trigger event is occurring.
+ * Select trigger source using
+ * function @ref LL_DAC_SetTriggerSource().
+ * @rmtoll CR TEN1 LL_DAC_EnableTrigger\n
+ * CR TEN2 LL_DAC_EnableTrigger
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_EnableTrigger(DAC_TypeDef *DACx, uint32_t DAC_Channel)
+{
+ SET_BIT(DACx->CR,
+ DAC_CR_TEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
+}
+
+/**
+ * @brief Disable DAC trigger of the selected channel.
+ * @rmtoll CR TEN1 LL_DAC_DisableTrigger\n
+ * CR TEN2 LL_DAC_DisableTrigger
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_DisableTrigger(DAC_TypeDef *DACx, uint32_t DAC_Channel)
+{
+ CLEAR_BIT(DACx->CR,
+ DAC_CR_TEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK));
+}
+
+/**
+ * @brief Get DAC trigger state of the selected channel.
+ * (0: DAC trigger is disabled, 1: DAC trigger is enabled)
+ * @rmtoll CR TEN1 LL_DAC_IsTriggerEnabled\n
+ * CR TEN2 LL_DAC_IsTriggerEnabled
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DAC_IsTriggerEnabled(DAC_TypeDef *DACx, uint32_t DAC_Channel)
+{
+ return (READ_BIT(DACx->CR,
+ DAC_CR_TEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))
+ == (DAC_CR_TEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)));
+}
+
+/**
+ * @brief Trig DAC conversion by software for the selected DAC channel.
+ * @note Preliminarily, DAC trigger must be set to software trigger
+ * using function @ref LL_DAC_SetTriggerSource()
+ * with parameter "LL_DAC_TRIGGER_SOFTWARE".
+ * and DAC trigger must be enabled using
+ * function @ref LL_DAC_EnableTrigger().
+ * @note For devices featuring DAC with 2 channels: this function
+ * can perform a SW start of both DAC channels simultaneously.
+ * Two channels can be selected as parameter.
+ * Example: (LL_DAC_CHANNEL_1 | LL_DAC_CHANNEL_2)
+ * @rmtoll SWTRIGR SWTRIG1 LL_DAC_TrigSWConversion\n
+ * SWTRIGR SWTRIG2 LL_DAC_TrigSWConversion
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can a combination of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_TrigSWConversion(DAC_TypeDef *DACx, uint32_t DAC_Channel)
+{
+ SET_BIT(DACx->SWTRIGR,
+ (DAC_Channel & DAC_SWTR_CHX_MASK));
+}
+
+/**
+ * @brief Set the data to be loaded in the data holding register
+ * in format 12 bits left alignment (LSB aligned on bit 0),
+ * for the selected DAC channel.
+ * @rmtoll DHR12R1 DACC1DHR LL_DAC_ConvertData12RightAligned\n
+ * DHR12R2 DACC2DHR LL_DAC_ConvertData12RightAligned
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @param Data Value between Min_Data=0x000 and Max_Data=0xFFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_ConvertData12RightAligned(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t Data)
+{
+ register uint32_t *preg = __DAC_PTR_REG_OFFSET(DACx->DHR12R1, __DAC_MASK_SHIFT(DAC_Channel, DAC_REG_DHR12RX_REGOFFSET_MASK));
+
+ MODIFY_REG(*preg,
+ DAC_DHR12R1_DACC1DHR,
+ Data);
+}
+
+/**
+ * @brief Set the data to be loaded in the data holding register
+ * in format 12 bits left alignment (MSB aligned on bit 15),
+ * for the selected DAC channel.
+ * @rmtoll DHR12L1 DACC1DHR LL_DAC_ConvertData12LeftAligned\n
+ * DHR12L2 DACC2DHR LL_DAC_ConvertData12LeftAligned
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @param Data Value between Min_Data=0x000 and Max_Data=0xFFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_ConvertData12LeftAligned(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t Data)
+{
+ register uint32_t *preg = __DAC_PTR_REG_OFFSET(DACx->DHR12R1, __DAC_MASK_SHIFT(DAC_Channel, DAC_REG_DHR12LX_REGOFFSET_MASK));
+
+ MODIFY_REG(*preg,
+ DAC_DHR12L1_DACC1DHR,
+ Data);
+}
+
+/**
+ * @brief Set the data to be loaded in the data holding register
+ * in format 8 bits left alignment (LSB aligned on bit 0),
+ * for the selected DAC channel.
+ * @rmtoll DHR8R1 DACC1DHR LL_DAC_ConvertData8RightAligned\n
+ * DHR8R2 DACC2DHR LL_DAC_ConvertData8RightAligned
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @param Data Value between Min_Data=0x00 and Max_Data=0xFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_ConvertData8RightAligned(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t Data)
+{
+ register uint32_t *preg = __DAC_PTR_REG_OFFSET(DACx->DHR12R1, __DAC_MASK_SHIFT(DAC_Channel, DAC_REG_DHR8RX_REGOFFSET_MASK));
+
+ MODIFY_REG(*preg,
+ DAC_DHR8R1_DACC1DHR,
+ Data);
+}
+
+/**
+ * @brief Set the data to be loaded in the data holding register
+ * in format 12 bits left alignment (LSB aligned on bit 0),
+ * for both DAC channels.
+ * @rmtoll DHR12RD DACC1DHR LL_DAC_ConvertDualData12RightAligned\n
+ * DHR12RD DACC2DHR LL_DAC_ConvertDualData12RightAligned
+ * @param DACx DAC instance
+ * @param DataChannel1 Value between Min_Data=0x000 and Max_Data=0xFFF
+ * @param DataChannel2 Value between Min_Data=0x000 and Max_Data=0xFFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_ConvertDualData12RightAligned(DAC_TypeDef *DACx, uint32_t DataChannel1, uint32_t DataChannel2)
+{
+ MODIFY_REG(DACx->DHR12RD,
+ (DAC_DHR12RD_DACC2DHR | DAC_DHR12RD_DACC1DHR),
+ ((DataChannel2 << DAC_DHR12RD_DACC2DHR_BITOFFSET_POS) | DataChannel1));
+}
+
+/**
+ * @brief Set the data to be loaded in the data holding register
+ * in format 12 bits left alignment (MSB aligned on bit 15),
+ * for both DAC channels.
+ * @rmtoll DHR12LD DACC1DHR LL_DAC_ConvertDualData12LeftAligned\n
+ * DHR12LD DACC2DHR LL_DAC_ConvertDualData12LeftAligned
+ * @param DACx DAC instance
+ * @param DataChannel1 Value between Min_Data=0x000 and Max_Data=0xFFF
+ * @param DataChannel2 Value between Min_Data=0x000 and Max_Data=0xFFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_ConvertDualData12LeftAligned(DAC_TypeDef *DACx, uint32_t DataChannel1, uint32_t DataChannel2)
+{
+ /* Note: Data of DAC channel 2 shift value subtracted of 4 because */
+ /* data on 16 bits and DAC channel 2 bits field is on the 12 MSB, */
+ /* the 4 LSB must be taken into account for the shift value. */
+ MODIFY_REG(DACx->DHR12LD,
+ (DAC_DHR12LD_DACC2DHR | DAC_DHR12LD_DACC1DHR),
+ ((DataChannel2 << (DAC_DHR12LD_DACC2DHR_BITOFFSET_POS - 4U)) | DataChannel1));
+}
+
+/**
+ * @brief Set the data to be loaded in the data holding register
+ * in format 8 bits left alignment (LSB aligned on bit 0),
+ * for both DAC channels.
+ * @rmtoll DHR8RD DACC1DHR LL_DAC_ConvertDualData8RightAligned\n
+ * DHR8RD DACC2DHR LL_DAC_ConvertDualData8RightAligned
+ * @param DACx DAC instance
+ * @param DataChannel1 Value between Min_Data=0x00 and Max_Data=0xFF
+ * @param DataChannel2 Value between Min_Data=0x00 and Max_Data=0xFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_ConvertDualData8RightAligned(DAC_TypeDef *DACx, uint32_t DataChannel1, uint32_t DataChannel2)
+{
+ MODIFY_REG(DACx->DHR8RD,
+ (DAC_DHR8RD_DACC2DHR | DAC_DHR8RD_DACC1DHR),
+ ((DataChannel2 << DAC_DHR8RD_DACC2DHR_BITOFFSET_POS) | DataChannel1));
+}
+
+/**
+ * @brief Retrieve output data currently generated for the selected DAC channel.
+ * @note Whatever alignment and resolution settings
+ * (using functions "LL_DAC_ConvertData{8; 12}{Right; Left} Aligned()":
+ * @ref LL_DAC_ConvertData12RightAligned(), ...),
+ * output data format is 12 bits right aligned (LSB aligned on bit 0).
+ * @rmtoll DOR1 DACC1DOR LL_DAC_RetrieveOutputData\n
+ * DOR2 DACC2DOR LL_DAC_RetrieveOutputData
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @retval Value between Min_Data=0x000 and Max_Data=0xFFF
+ */
+__STATIC_INLINE uint32_t LL_DAC_RetrieveOutputData(DAC_TypeDef *DACx, uint32_t DAC_Channel)
+{
+ register uint32_t *preg = __DAC_PTR_REG_OFFSET(DACx->DOR1, __DAC_MASK_SHIFT(DAC_Channel, DAC_REG_DORX_REGOFFSET_MASK));
+
+ return (uint16_t) READ_BIT(*preg, DAC_DOR1_DACC1DOR);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup DAC_LL_EF_FLAG_Management FLAG Management
+ * @{
+ */
+#if defined(DAC_SR_DMAUDR1)
+/**
+ * @brief Get DAC underrun flag for DAC channel 1
+ * @rmtoll SR DMAUDR1 LL_DAC_IsActiveFlag_DMAUDR1
+ * @param DACx DAC instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DAC_IsActiveFlag_DMAUDR1(DAC_TypeDef *DACx)
+{
+ return (READ_BIT(DACx->SR, LL_DAC_FLAG_DMAUDR1) == (LL_DAC_FLAG_DMAUDR1));
+}
+#endif /* DAC_SR_DMAUDR1 */
+
+#if defined(DAC_SR_DMAUDR2)
+/**
+ * @brief Get DAC underrun flag for DAC channel 2
+ * @rmtoll SR DMAUDR2 LL_DAC_IsActiveFlag_DMAUDR2
+ * @param DACx DAC instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DAC_IsActiveFlag_DMAUDR2(DAC_TypeDef *DACx)
+{
+ return (READ_BIT(DACx->SR, LL_DAC_FLAG_DMAUDR2) == (LL_DAC_FLAG_DMAUDR2));
+}
+#endif /* DAC_SR_DMAUDR2 */
+
+#if defined(DAC_SR_DMAUDR1)
+/**
+ * @brief Clear DAC underrun flag for DAC channel 1
+ * @rmtoll SR DMAUDR1 LL_DAC_ClearFlag_DMAUDR1
+ * @param DACx DAC instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_ClearFlag_DMAUDR1(DAC_TypeDef *DACx)
+{
+ WRITE_REG(DACx->SR, LL_DAC_FLAG_DMAUDR1);
+}
+#endif /* DAC_SR_DMAUDR1 */
+
+#if defined(DAC_SR_DMAUDR2)
+/**
+ * @brief Clear DAC underrun flag for DAC channel 2
+ * @rmtoll SR DMAUDR2 LL_DAC_ClearFlag_DMAUDR2
+ * @param DACx DAC instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_ClearFlag_DMAUDR2(DAC_TypeDef *DACx)
+{
+ WRITE_REG(DACx->SR, LL_DAC_FLAG_DMAUDR2);
+}
+#endif /* DAC_SR_DMAUDR2 */
+
+/**
+ * @}
+ */
+/** @defgroup DAC_LL_EF_IT_Management IT management
+ * @{
+ */
+
+#if defined(DAC_CR_DMAUDRIE1)
+/**
+ * @brief Enable DMA underrun interrupt for DAC channel 1
+ * @rmtoll CR DMAUDRIE1 LL_DAC_EnableIT_DMAUDR1
+ * @param DACx DAC instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_EnableIT_DMAUDR1(DAC_TypeDef *DACx)
+{
+ SET_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE1);
+}
+#endif /* DAC_CR_DMAUDRIE1 */
+
+#if defined(DAC_CR_DMAUDRIE2)
+/**
+ * @brief Enable DMA underrun interrupt for DAC channel 2
+ * @rmtoll CR DMAUDRIE2 LL_DAC_EnableIT_DMAUDR2
+ * @param DACx DAC instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_EnableIT_DMAUDR2(DAC_TypeDef *DACx)
+{
+ SET_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE2);
+}
+#endif /* DAC_CR_DMAUDRIE2 */
+
+#if defined(DAC_CR_DMAUDRIE1)
+/**
+ * @brief Disable DMA underrun interrupt for DAC channel 1
+ * @rmtoll CR DMAUDRIE1 LL_DAC_DisableIT_DMAUDR1
+ * @param DACx DAC instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_DisableIT_DMAUDR1(DAC_TypeDef *DACx)
+{
+ CLEAR_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE1);
+}
+#endif /* DAC_CR_DMAUDRIE1 */
+
+#if defined(DAC_CR_DMAUDRIE2)
+/**
+ * @brief Disable DMA underrun interrupt for DAC channel 2
+ * @rmtoll CR DMAUDRIE2 LL_DAC_DisableIT_DMAUDR2
+ * @param DACx DAC instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DAC_DisableIT_DMAUDR2(DAC_TypeDef *DACx)
+{
+ CLEAR_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE2);
+}
+#endif /* DAC_CR_DMAUDRIE2 */
+
+#if defined(DAC_CR_DMAUDRIE1)
+/**
+ * @brief Get DMA underrun interrupt for DAC channel 1
+ * @rmtoll CR DMAUDRIE1 LL_DAC_IsEnabledIT_DMAUDR1
+ * @param DACx DAC instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DAC_IsEnabledIT_DMAUDR1(DAC_TypeDef *DACx)
+{
+ return (READ_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE1) == (LL_DAC_IT_DMAUDRIE1));
+}
+#endif /* DAC_CR_DMAUDRIE1 */
+
+#if defined(DAC_CR_DMAUDRIE2)
+/**
+ * @brief Get DMA underrun interrupt for DAC channel 2
+ * @rmtoll CR DMAUDRIE2 LL_DAC_IsEnabledIT_DMAUDR2
+ * @param DACx DAC instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DAC_IsEnabledIT_DMAUDR2(DAC_TypeDef *DACx)
+{
+ return (READ_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE2) == (LL_DAC_IT_DMAUDRIE2));
+}
+#endif /* DAC_CR_DMAUDRIE2 */
+
+/**
+ * @}
+ */
+
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup DAC_LL_EF_Init Initialization and de-initialization functions
+ * @{
+ */
+
+ErrorStatus LL_DAC_DeInit(DAC_TypeDef* DACx);
+ErrorStatus LL_DAC_Init(DAC_TypeDef* DACx, uint32_t DAC_Channel, LL_DAC_InitTypeDef* DAC_InitStruct);
+void LL_DAC_StructInit(LL_DAC_InitTypeDef* DAC_InitStruct);
+
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* DAC */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_LL_DAC_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_dma.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_dma.h
new file mode 100644
index 0000000..b1bf5b9
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_dma.h
@@ -0,0 +1,1976 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_dma.h
+ * @author MCD Application Team
+ * @brief Header file of DMA LL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_DMA_H
+#define __STM32F1xx_LL_DMA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx.h"
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (DMA1) || defined (DMA2)
+
+/** @defgroup DMA_LL DMA
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/** @defgroup DMA_LL_Private_Variables DMA Private Variables
+ * @{
+ */
+/* Array used to get the DMA channel register offset versus channel index LL_DMA_CHANNEL_x */
+static const uint8_t CHANNEL_OFFSET_TAB[] =
+{
+ (uint8_t)(DMA1_Channel1_BASE - DMA1_BASE),
+ (uint8_t)(DMA1_Channel2_BASE - DMA1_BASE),
+ (uint8_t)(DMA1_Channel3_BASE - DMA1_BASE),
+ (uint8_t)(DMA1_Channel4_BASE - DMA1_BASE),
+ (uint8_t)(DMA1_Channel5_BASE - DMA1_BASE),
+ (uint8_t)(DMA1_Channel6_BASE - DMA1_BASE),
+ (uint8_t)(DMA1_Channel7_BASE - DMA1_BASE)
+};
+/**
+ * @}
+ */
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup DMA_LL_Private_Macros DMA Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+#endif /*USE_FULL_LL_DRIVER*/
+
+/* Exported types ------------------------------------------------------------*/
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup DMA_LL_ES_INIT DMA Exported Init structure
+ * @{
+ */
+typedef struct
+{
+ uint32_t PeriphOrM2MSrcAddress; /*!< Specifies the peripheral base address for DMA transfer
+ or as Source base address in case of memory to memory transfer direction.
+
+ This parameter must be a value between Min_Data = 0 and Max_Data = 0xFFFFFFFF. */
+
+ uint32_t MemoryOrM2MDstAddress; /*!< Specifies the memory base address for DMA transfer
+ or as Destination base address in case of memory to memory transfer direction.
+
+ This parameter must be a value between Min_Data = 0 and Max_Data = 0xFFFFFFFF. */
+
+ uint32_t Direction; /*!< Specifies if the data will be transferred from memory to peripheral,
+ from memory to memory or from peripheral to memory.
+ This parameter can be a value of @ref DMA_LL_EC_DIRECTION
+
+ This feature can be modified afterwards using unitary function @ref LL_DMA_SetDataTransferDirection(). */
+
+ uint32_t Mode; /*!< Specifies the normal or circular operation mode.
+ This parameter can be a value of @ref DMA_LL_EC_MODE
+ @note: The circular buffer mode cannot be used if the memory to memory
+ data transfer direction is configured on the selected Channel
+
+ This feature can be modified afterwards using unitary function @ref LL_DMA_SetMode(). */
+
+ uint32_t PeriphOrM2MSrcIncMode; /*!< Specifies whether the Peripheral address or Source address in case of memory to memory transfer direction
+ is incremented or not.
+ This parameter can be a value of @ref DMA_LL_EC_PERIPH
+
+ This feature can be modified afterwards using unitary function @ref LL_DMA_SetPeriphIncMode(). */
+
+ uint32_t MemoryOrM2MDstIncMode; /*!< Specifies whether the Memory address or Destination address in case of memory to memory transfer direction
+ is incremented or not.
+ This parameter can be a value of @ref DMA_LL_EC_MEMORY
+
+ This feature can be modified afterwards using unitary function @ref LL_DMA_SetMemoryIncMode(). */
+
+ uint32_t PeriphOrM2MSrcDataSize; /*!< Specifies the Peripheral data size alignment or Source data size alignment (byte, half word, word)
+ in case of memory to memory transfer direction.
+ This parameter can be a value of @ref DMA_LL_EC_PDATAALIGN
+
+ This feature can be modified afterwards using unitary function @ref LL_DMA_SetPeriphSize(). */
+
+ uint32_t MemoryOrM2MDstDataSize; /*!< Specifies the Memory data size alignment or Destination data size alignment (byte, half word, word)
+ in case of memory to memory transfer direction.
+ This parameter can be a value of @ref DMA_LL_EC_MDATAALIGN
+
+ This feature can be modified afterwards using unitary function @ref LL_DMA_SetMemorySize(). */
+
+ uint32_t NbData; /*!< Specifies the number of data to transfer, in data unit.
+ The data unit is equal to the source buffer configuration set in PeripheralSize
+ or MemorySize parameters depending in the transfer direction.
+ This parameter must be a value between Min_Data = 0 and Max_Data = 0x0000FFFF
+
+ This feature can be modified afterwards using unitary function @ref LL_DMA_SetDataLength(). */
+
+ uint32_t Priority; /*!< Specifies the channel priority level.
+ This parameter can be a value of @ref DMA_LL_EC_PRIORITY
+
+ This feature can be modified afterwards using unitary function @ref LL_DMA_SetChannelPriorityLevel(). */
+
+} LL_DMA_InitTypeDef;
+/**
+ * @}
+ */
+#endif /*USE_FULL_LL_DRIVER*/
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup DMA_LL_Exported_Constants DMA Exported Constants
+ * @{
+ */
+/** @defgroup DMA_LL_EC_CLEAR_FLAG Clear Flags Defines
+ * @brief Flags defines which can be used with LL_DMA_WriteReg function
+ * @{
+ */
+#define LL_DMA_IFCR_CGIF1 DMA_IFCR_CGIF1 /*!< Channel 1 global flag */
+#define LL_DMA_IFCR_CTCIF1 DMA_IFCR_CTCIF1 /*!< Channel 1 transfer complete flag */
+#define LL_DMA_IFCR_CHTIF1 DMA_IFCR_CHTIF1 /*!< Channel 1 half transfer flag */
+#define LL_DMA_IFCR_CTEIF1 DMA_IFCR_CTEIF1 /*!< Channel 1 transfer error flag */
+#define LL_DMA_IFCR_CGIF2 DMA_IFCR_CGIF2 /*!< Channel 2 global flag */
+#define LL_DMA_IFCR_CTCIF2 DMA_IFCR_CTCIF2 /*!< Channel 2 transfer complete flag */
+#define LL_DMA_IFCR_CHTIF2 DMA_IFCR_CHTIF2 /*!< Channel 2 half transfer flag */
+#define LL_DMA_IFCR_CTEIF2 DMA_IFCR_CTEIF2 /*!< Channel 2 transfer error flag */
+#define LL_DMA_IFCR_CGIF3 DMA_IFCR_CGIF3 /*!< Channel 3 global flag */
+#define LL_DMA_IFCR_CTCIF3 DMA_IFCR_CTCIF3 /*!< Channel 3 transfer complete flag */
+#define LL_DMA_IFCR_CHTIF3 DMA_IFCR_CHTIF3 /*!< Channel 3 half transfer flag */
+#define LL_DMA_IFCR_CTEIF3 DMA_IFCR_CTEIF3 /*!< Channel 3 transfer error flag */
+#define LL_DMA_IFCR_CGIF4 DMA_IFCR_CGIF4 /*!< Channel 4 global flag */
+#define LL_DMA_IFCR_CTCIF4 DMA_IFCR_CTCIF4 /*!< Channel 4 transfer complete flag */
+#define LL_DMA_IFCR_CHTIF4 DMA_IFCR_CHTIF4 /*!< Channel 4 half transfer flag */
+#define LL_DMA_IFCR_CTEIF4 DMA_IFCR_CTEIF4 /*!< Channel 4 transfer error flag */
+#define LL_DMA_IFCR_CGIF5 DMA_IFCR_CGIF5 /*!< Channel 5 global flag */
+#define LL_DMA_IFCR_CTCIF5 DMA_IFCR_CTCIF5 /*!< Channel 5 transfer complete flag */
+#define LL_DMA_IFCR_CHTIF5 DMA_IFCR_CHTIF5 /*!< Channel 5 half transfer flag */
+#define LL_DMA_IFCR_CTEIF5 DMA_IFCR_CTEIF5 /*!< Channel 5 transfer error flag */
+#define LL_DMA_IFCR_CGIF6 DMA_IFCR_CGIF6 /*!< Channel 6 global flag */
+#define LL_DMA_IFCR_CTCIF6 DMA_IFCR_CTCIF6 /*!< Channel 6 transfer complete flag */
+#define LL_DMA_IFCR_CHTIF6 DMA_IFCR_CHTIF6 /*!< Channel 6 half transfer flag */
+#define LL_DMA_IFCR_CTEIF6 DMA_IFCR_CTEIF6 /*!< Channel 6 transfer error flag */
+#define LL_DMA_IFCR_CGIF7 DMA_IFCR_CGIF7 /*!< Channel 7 global flag */
+#define LL_DMA_IFCR_CTCIF7 DMA_IFCR_CTCIF7 /*!< Channel 7 transfer complete flag */
+#define LL_DMA_IFCR_CHTIF7 DMA_IFCR_CHTIF7 /*!< Channel 7 half transfer flag */
+#define LL_DMA_IFCR_CTEIF7 DMA_IFCR_CTEIF7 /*!< Channel 7 transfer error flag */
+/**
+ * @}
+ */
+
+/** @defgroup DMA_LL_EC_GET_FLAG Get Flags Defines
+ * @brief Flags defines which can be used with LL_DMA_ReadReg function
+ * @{
+ */
+#define LL_DMA_ISR_GIF1 DMA_ISR_GIF1 /*!< Channel 1 global flag */
+#define LL_DMA_ISR_TCIF1 DMA_ISR_TCIF1 /*!< Channel 1 transfer complete flag */
+#define LL_DMA_ISR_HTIF1 DMA_ISR_HTIF1 /*!< Channel 1 half transfer flag */
+#define LL_DMA_ISR_TEIF1 DMA_ISR_TEIF1 /*!< Channel 1 transfer error flag */
+#define LL_DMA_ISR_GIF2 DMA_ISR_GIF2 /*!< Channel 2 global flag */
+#define LL_DMA_ISR_TCIF2 DMA_ISR_TCIF2 /*!< Channel 2 transfer complete flag */
+#define LL_DMA_ISR_HTIF2 DMA_ISR_HTIF2 /*!< Channel 2 half transfer flag */
+#define LL_DMA_ISR_TEIF2 DMA_ISR_TEIF2 /*!< Channel 2 transfer error flag */
+#define LL_DMA_ISR_GIF3 DMA_ISR_GIF3 /*!< Channel 3 global flag */
+#define LL_DMA_ISR_TCIF3 DMA_ISR_TCIF3 /*!< Channel 3 transfer complete flag */
+#define LL_DMA_ISR_HTIF3 DMA_ISR_HTIF3 /*!< Channel 3 half transfer flag */
+#define LL_DMA_ISR_TEIF3 DMA_ISR_TEIF3 /*!< Channel 3 transfer error flag */
+#define LL_DMA_ISR_GIF4 DMA_ISR_GIF4 /*!< Channel 4 global flag */
+#define LL_DMA_ISR_TCIF4 DMA_ISR_TCIF4 /*!< Channel 4 transfer complete flag */
+#define LL_DMA_ISR_HTIF4 DMA_ISR_HTIF4 /*!< Channel 4 half transfer flag */
+#define LL_DMA_ISR_TEIF4 DMA_ISR_TEIF4 /*!< Channel 4 transfer error flag */
+#define LL_DMA_ISR_GIF5 DMA_ISR_GIF5 /*!< Channel 5 global flag */
+#define LL_DMA_ISR_TCIF5 DMA_ISR_TCIF5 /*!< Channel 5 transfer complete flag */
+#define LL_DMA_ISR_HTIF5 DMA_ISR_HTIF5 /*!< Channel 5 half transfer flag */
+#define LL_DMA_ISR_TEIF5 DMA_ISR_TEIF5 /*!< Channel 5 transfer error flag */
+#define LL_DMA_ISR_GIF6 DMA_ISR_GIF6 /*!< Channel 6 global flag */
+#define LL_DMA_ISR_TCIF6 DMA_ISR_TCIF6 /*!< Channel 6 transfer complete flag */
+#define LL_DMA_ISR_HTIF6 DMA_ISR_HTIF6 /*!< Channel 6 half transfer flag */
+#define LL_DMA_ISR_TEIF6 DMA_ISR_TEIF6 /*!< Channel 6 transfer error flag */
+#define LL_DMA_ISR_GIF7 DMA_ISR_GIF7 /*!< Channel 7 global flag */
+#define LL_DMA_ISR_TCIF7 DMA_ISR_TCIF7 /*!< Channel 7 transfer complete flag */
+#define LL_DMA_ISR_HTIF7 DMA_ISR_HTIF7 /*!< Channel 7 half transfer flag */
+#define LL_DMA_ISR_TEIF7 DMA_ISR_TEIF7 /*!< Channel 7 transfer error flag */
+/**
+ * @}
+ */
+
+/** @defgroup DMA_LL_EC_IT IT Defines
+ * @brief IT defines which can be used with LL_DMA_ReadReg and LL_DMA_WriteReg functions
+ * @{
+ */
+#define LL_DMA_CCR_TCIE DMA_CCR_TCIE /*!< Transfer complete interrupt */
+#define LL_DMA_CCR_HTIE DMA_CCR_HTIE /*!< Half Transfer interrupt */
+#define LL_DMA_CCR_TEIE DMA_CCR_TEIE /*!< Transfer error interrupt */
+/**
+ * @}
+ */
+
+/** @defgroup DMA_LL_EC_CHANNEL CHANNEL
+ * @{
+ */
+#define LL_DMA_CHANNEL_1 0x00000001U /*!< DMA Channel 1 */
+#define LL_DMA_CHANNEL_2 0x00000002U /*!< DMA Channel 2 */
+#define LL_DMA_CHANNEL_3 0x00000003U /*!< DMA Channel 3 */
+#define LL_DMA_CHANNEL_4 0x00000004U /*!< DMA Channel 4 */
+#define LL_DMA_CHANNEL_5 0x00000005U /*!< DMA Channel 5 */
+#define LL_DMA_CHANNEL_6 0x00000006U /*!< DMA Channel 6 */
+#define LL_DMA_CHANNEL_7 0x00000007U /*!< DMA Channel 7 */
+#if defined(USE_FULL_LL_DRIVER)
+#define LL_DMA_CHANNEL_ALL 0xFFFF0000U /*!< DMA Channel all (used only for function @ref LL_DMA_DeInit(). */
+#endif /*USE_FULL_LL_DRIVER*/
+/**
+ * @}
+ */
+
+/** @defgroup DMA_LL_EC_DIRECTION Transfer Direction
+ * @{
+ */
+#define LL_DMA_DIRECTION_PERIPH_TO_MEMORY 0x00000000U /*!< Peripheral to memory direction */
+#define LL_DMA_DIRECTION_MEMORY_TO_PERIPH DMA_CCR_DIR /*!< Memory to peripheral direction */
+#define LL_DMA_DIRECTION_MEMORY_TO_MEMORY DMA_CCR_MEM2MEM /*!< Memory to memory direction */
+/**
+ * @}
+ */
+
+/** @defgroup DMA_LL_EC_MODE Transfer mode
+ * @{
+ */
+#define LL_DMA_MODE_NORMAL 0x00000000U /*!< Normal Mode */
+#define LL_DMA_MODE_CIRCULAR DMA_CCR_CIRC /*!< Circular Mode */
+/**
+ * @}
+ */
+
+/** @defgroup DMA_LL_EC_PERIPH Peripheral increment mode
+ * @{
+ */
+#define LL_DMA_PERIPH_INCREMENT DMA_CCR_PINC /*!< Peripheral increment mode Enable */
+#define LL_DMA_PERIPH_NOINCREMENT 0x00000000U /*!< Peripheral increment mode Disable */
+/**
+ * @}
+ */
+
+/** @defgroup DMA_LL_EC_MEMORY Memory increment mode
+ * @{
+ */
+#define LL_DMA_MEMORY_INCREMENT DMA_CCR_MINC /*!< Memory increment mode Enable */
+#define LL_DMA_MEMORY_NOINCREMENT 0x00000000U /*!< Memory increment mode Disable */
+/**
+ * @}
+ */
+
+/** @defgroup DMA_LL_EC_PDATAALIGN Peripheral data alignment
+ * @{
+ */
+#define LL_DMA_PDATAALIGN_BYTE 0x00000000U /*!< Peripheral data alignment : Byte */
+#define LL_DMA_PDATAALIGN_HALFWORD DMA_CCR_PSIZE_0 /*!< Peripheral data alignment : HalfWord */
+#define LL_DMA_PDATAALIGN_WORD DMA_CCR_PSIZE_1 /*!< Peripheral data alignment : Word */
+/**
+ * @}
+ */
+
+/** @defgroup DMA_LL_EC_MDATAALIGN Memory data alignment
+ * @{
+ */
+#define LL_DMA_MDATAALIGN_BYTE 0x00000000U /*!< Memory data alignment : Byte */
+#define LL_DMA_MDATAALIGN_HALFWORD DMA_CCR_MSIZE_0 /*!< Memory data alignment : HalfWord */
+#define LL_DMA_MDATAALIGN_WORD DMA_CCR_MSIZE_1 /*!< Memory data alignment : Word */
+/**
+ * @}
+ */
+
+/** @defgroup DMA_LL_EC_PRIORITY Transfer Priority level
+ * @{
+ */
+#define LL_DMA_PRIORITY_LOW 0x00000000U /*!< Priority level : Low */
+#define LL_DMA_PRIORITY_MEDIUM DMA_CCR_PL_0 /*!< Priority level : Medium */
+#define LL_DMA_PRIORITY_HIGH DMA_CCR_PL_1 /*!< Priority level : High */
+#define LL_DMA_PRIORITY_VERYHIGH DMA_CCR_PL /*!< Priority level : Very_High */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup DMA_LL_Exported_Macros DMA Exported Macros
+ * @{
+ */
+
+/** @defgroup DMA_LL_EM_WRITE_READ Common Write and read registers macros
+ * @{
+ */
+/**
+ * @brief Write a value in DMA register
+ * @param __INSTANCE__ DMA Instance
+ * @param __REG__ Register to be written
+ * @param __VALUE__ Value to be written in the register
+ * @retval None
+ */
+#define LL_DMA_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
+
+/**
+ * @brief Read a value in DMA register
+ * @param __INSTANCE__ DMA Instance
+ * @param __REG__ Register to be read
+ * @retval Register value
+ */
+#define LL_DMA_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
+/**
+ * @}
+ */
+
+/** @defgroup DMA_LL_EM_CONVERT_DMAxCHANNELy Convert DMAxChannely
+ * @{
+ */
+
+/**
+ * @brief Convert DMAx_Channely into DMAx
+ * @param __CHANNEL_INSTANCE__ DMAx_Channely
+ * @retval DMAx
+ */
+#if defined(DMA2)
+#define __LL_DMA_GET_INSTANCE(__CHANNEL_INSTANCE__) \
+(((uint32_t)(__CHANNEL_INSTANCE__) > ((uint32_t)DMA1_Channel7)) ? DMA2 : DMA1)
+#else
+#define __LL_DMA_GET_INSTANCE(__CHANNEL_INSTANCE__) (DMA1)
+#endif
+
+/**
+ * @brief Convert DMAx_Channely into LL_DMA_CHANNEL_y
+ * @param __CHANNEL_INSTANCE__ DMAx_Channely
+ * @retval LL_DMA_CHANNEL_y
+ */
+#if defined (DMA2)
+#define __LL_DMA_GET_CHANNEL(__CHANNEL_INSTANCE__) \
+(((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel1)) ? LL_DMA_CHANNEL_1 : \
+ ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel1)) ? LL_DMA_CHANNEL_1 : \
+ ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel2)) ? LL_DMA_CHANNEL_2 : \
+ ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel2)) ? LL_DMA_CHANNEL_2 : \
+ ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel3)) ? LL_DMA_CHANNEL_3 : \
+ ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel3)) ? LL_DMA_CHANNEL_3 : \
+ ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel4)) ? LL_DMA_CHANNEL_4 : \
+ ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel4)) ? LL_DMA_CHANNEL_4 : \
+ ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel5)) ? LL_DMA_CHANNEL_5 : \
+ ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel5)) ? LL_DMA_CHANNEL_5 : \
+ ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel6)) ? LL_DMA_CHANNEL_6 : \
+ LL_DMA_CHANNEL_7)
+#else
+#define __LL_DMA_GET_CHANNEL(__CHANNEL_INSTANCE__) \
+(((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel1)) ? LL_DMA_CHANNEL_1 : \
+ ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel2)) ? LL_DMA_CHANNEL_2 : \
+ ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel3)) ? LL_DMA_CHANNEL_3 : \
+ ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel4)) ? LL_DMA_CHANNEL_4 : \
+ ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel5)) ? LL_DMA_CHANNEL_5 : \
+ ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel6)) ? LL_DMA_CHANNEL_6 : \
+ LL_DMA_CHANNEL_7)
+#endif
+
+/**
+ * @brief Convert DMA Instance DMAx and LL_DMA_CHANNEL_y into DMAx_Channely
+ * @param __DMA_INSTANCE__ DMAx
+ * @param __CHANNEL__ LL_DMA_CHANNEL_y
+ * @retval DMAx_Channely
+ */
+#if defined (DMA2)
+#define __LL_DMA_GET_CHANNEL_INSTANCE(__DMA_INSTANCE__, __CHANNEL__) \
+((((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_1))) ? DMA1_Channel1 : \
+ (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_1))) ? DMA2_Channel1 : \
+ (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_2))) ? DMA1_Channel2 : \
+ (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_2))) ? DMA2_Channel2 : \
+ (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_3))) ? DMA1_Channel3 : \
+ (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_3))) ? DMA2_Channel3 : \
+ (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_4))) ? DMA1_Channel4 : \
+ (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_4))) ? DMA2_Channel4 : \
+ (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_5))) ? DMA1_Channel5 : \
+ (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_5))) ? DMA2_Channel5 : \
+ (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_6))) ? DMA1_Channel6 : \
+ DMA1_Channel7)
+#else
+#define __LL_DMA_GET_CHANNEL_INSTANCE(__DMA_INSTANCE__, __CHANNEL__) \
+((((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_1))) ? DMA1_Channel1 : \
+ (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_2))) ? DMA1_Channel2 : \
+ (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_3))) ? DMA1_Channel3 : \
+ (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_4))) ? DMA1_Channel4 : \
+ (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_5))) ? DMA1_Channel5 : \
+ (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_6))) ? DMA1_Channel6 : \
+ DMA1_Channel7)
+#endif
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup DMA_LL_Exported_Functions DMA Exported Functions
+ * @{
+ */
+
+/** @defgroup DMA_LL_EF_Configuration Configuration
+ * @{
+ */
+/**
+ * @brief Enable DMA channel.
+ * @rmtoll CCR EN LL_DMA_EnableChannel
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_EnableChannel(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ SET_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_EN);
+}
+
+/**
+ * @brief Disable DMA channel.
+ * @rmtoll CCR EN LL_DMA_DisableChannel
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_DisableChannel(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ CLEAR_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_EN);
+}
+
+/**
+ * @brief Check if DMA channel is enabled or disabled.
+ * @rmtoll CCR EN LL_DMA_IsEnabledChannel
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsEnabledChannel(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
+ DMA_CCR_EN) == (DMA_CCR_EN));
+}
+
+/**
+ * @brief Configure all parameters link to DMA transfer.
+ * @rmtoll CCR DIR LL_DMA_ConfigTransfer\n
+ * CCR MEM2MEM LL_DMA_ConfigTransfer\n
+ * CCR CIRC LL_DMA_ConfigTransfer\n
+ * CCR PINC LL_DMA_ConfigTransfer\n
+ * CCR MINC LL_DMA_ConfigTransfer\n
+ * CCR PSIZE LL_DMA_ConfigTransfer\n
+ * CCR MSIZE LL_DMA_ConfigTransfer\n
+ * CCR PL LL_DMA_ConfigTransfer
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @param Configuration This parameter must be a combination of all the following values:
+ * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_MEMORY or @ref LL_DMA_DIRECTION_MEMORY_TO_PERIPH or @ref LL_DMA_DIRECTION_MEMORY_TO_MEMORY
+ * @arg @ref LL_DMA_MODE_NORMAL or @ref LL_DMA_MODE_CIRCULAR
+ * @arg @ref LL_DMA_PERIPH_INCREMENT or @ref LL_DMA_PERIPH_NOINCREMENT
+ * @arg @ref LL_DMA_MEMORY_INCREMENT or @ref LL_DMA_MEMORY_NOINCREMENT
+ * @arg @ref LL_DMA_PDATAALIGN_BYTE or @ref LL_DMA_PDATAALIGN_HALFWORD or @ref LL_DMA_PDATAALIGN_WORD
+ * @arg @ref LL_DMA_MDATAALIGN_BYTE or @ref LL_DMA_MDATAALIGN_HALFWORD or @ref LL_DMA_MDATAALIGN_WORD
+ * @arg @ref LL_DMA_PRIORITY_LOW or @ref LL_DMA_PRIORITY_MEDIUM or @ref LL_DMA_PRIORITY_HIGH or @ref LL_DMA_PRIORITY_VERYHIGH
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ConfigTransfer(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t Configuration)
+{
+ MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
+ DMA_CCR_DIR | DMA_CCR_MEM2MEM | DMA_CCR_CIRC | DMA_CCR_PINC | DMA_CCR_MINC | DMA_CCR_PSIZE | DMA_CCR_MSIZE | DMA_CCR_PL,
+ Configuration);
+}
+
+/**
+ * @brief Set Data transfer direction (read from peripheral or from memory).
+ * @rmtoll CCR DIR LL_DMA_SetDataTransferDirection\n
+ * CCR MEM2MEM LL_DMA_SetDataTransferDirection
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @param Direction This parameter can be one of the following values:
+ * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_MEMORY
+ * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_PERIPH
+ * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_MEMORY
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_SetDataTransferDirection(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t Direction)
+{
+ MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
+ DMA_CCR_DIR | DMA_CCR_MEM2MEM, Direction);
+}
+
+/**
+ * @brief Get Data transfer direction (read from peripheral or from memory).
+ * @rmtoll CCR DIR LL_DMA_GetDataTransferDirection\n
+ * CCR MEM2MEM LL_DMA_GetDataTransferDirection
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_MEMORY
+ * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_PERIPH
+ * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_MEMORY
+ */
+__STATIC_INLINE uint32_t LL_DMA_GetDataTransferDirection(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
+ DMA_CCR_DIR | DMA_CCR_MEM2MEM));
+}
+
+/**
+ * @brief Set DMA mode circular or normal.
+ * @note The circular buffer mode cannot be used if the memory-to-memory
+ * data transfer is configured on the selected Channel.
+ * @rmtoll CCR CIRC LL_DMA_SetMode
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @param Mode This parameter can be one of the following values:
+ * @arg @ref LL_DMA_MODE_NORMAL
+ * @arg @ref LL_DMA_MODE_CIRCULAR
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_SetMode(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t Mode)
+{
+ MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_CIRC,
+ Mode);
+}
+
+/**
+ * @brief Get DMA mode circular or normal.
+ * @rmtoll CCR CIRC LL_DMA_GetMode
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_DMA_MODE_NORMAL
+ * @arg @ref LL_DMA_MODE_CIRCULAR
+ */
+__STATIC_INLINE uint32_t LL_DMA_GetMode(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
+ DMA_CCR_CIRC));
+}
+
+/**
+ * @brief Set Peripheral increment mode.
+ * @rmtoll CCR PINC LL_DMA_SetPeriphIncMode
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @param PeriphOrM2MSrcIncMode This parameter can be one of the following values:
+ * @arg @ref LL_DMA_PERIPH_INCREMENT
+ * @arg @ref LL_DMA_PERIPH_NOINCREMENT
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_SetPeriphIncMode(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t PeriphOrM2MSrcIncMode)
+{
+ MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_PINC,
+ PeriphOrM2MSrcIncMode);
+}
+
+/**
+ * @brief Get Peripheral increment mode.
+ * @rmtoll CCR PINC LL_DMA_GetPeriphIncMode
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_DMA_PERIPH_INCREMENT
+ * @arg @ref LL_DMA_PERIPH_NOINCREMENT
+ */
+__STATIC_INLINE uint32_t LL_DMA_GetPeriphIncMode(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
+ DMA_CCR_PINC));
+}
+
+/**
+ * @brief Set Memory increment mode.
+ * @rmtoll CCR MINC LL_DMA_SetMemoryIncMode
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @param MemoryOrM2MDstIncMode This parameter can be one of the following values:
+ * @arg @ref LL_DMA_MEMORY_INCREMENT
+ * @arg @ref LL_DMA_MEMORY_NOINCREMENT
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_SetMemoryIncMode(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t MemoryOrM2MDstIncMode)
+{
+ MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_MINC,
+ MemoryOrM2MDstIncMode);
+}
+
+/**
+ * @brief Get Memory increment mode.
+ * @rmtoll CCR MINC LL_DMA_GetMemoryIncMode
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_DMA_MEMORY_INCREMENT
+ * @arg @ref LL_DMA_MEMORY_NOINCREMENT
+ */
+__STATIC_INLINE uint32_t LL_DMA_GetMemoryIncMode(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
+ DMA_CCR_MINC));
+}
+
+/**
+ * @brief Set Peripheral size.
+ * @rmtoll CCR PSIZE LL_DMA_SetPeriphSize
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @param PeriphOrM2MSrcDataSize This parameter can be one of the following values:
+ * @arg @ref LL_DMA_PDATAALIGN_BYTE
+ * @arg @ref LL_DMA_PDATAALIGN_HALFWORD
+ * @arg @ref LL_DMA_PDATAALIGN_WORD
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_SetPeriphSize(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t PeriphOrM2MSrcDataSize)
+{
+ MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_PSIZE,
+ PeriphOrM2MSrcDataSize);
+}
+
+/**
+ * @brief Get Peripheral size.
+ * @rmtoll CCR PSIZE LL_DMA_GetPeriphSize
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_DMA_PDATAALIGN_BYTE
+ * @arg @ref LL_DMA_PDATAALIGN_HALFWORD
+ * @arg @ref LL_DMA_PDATAALIGN_WORD
+ */
+__STATIC_INLINE uint32_t LL_DMA_GetPeriphSize(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
+ DMA_CCR_PSIZE));
+}
+
+/**
+ * @brief Set Memory size.
+ * @rmtoll CCR MSIZE LL_DMA_SetMemorySize
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @param MemoryOrM2MDstDataSize This parameter can be one of the following values:
+ * @arg @ref LL_DMA_MDATAALIGN_BYTE
+ * @arg @ref LL_DMA_MDATAALIGN_HALFWORD
+ * @arg @ref LL_DMA_MDATAALIGN_WORD
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_SetMemorySize(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t MemoryOrM2MDstDataSize)
+{
+ MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_MSIZE,
+ MemoryOrM2MDstDataSize);
+}
+
+/**
+ * @brief Get Memory size.
+ * @rmtoll CCR MSIZE LL_DMA_GetMemorySize
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_DMA_MDATAALIGN_BYTE
+ * @arg @ref LL_DMA_MDATAALIGN_HALFWORD
+ * @arg @ref LL_DMA_MDATAALIGN_WORD
+ */
+__STATIC_INLINE uint32_t LL_DMA_GetMemorySize(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
+ DMA_CCR_MSIZE));
+}
+
+/**
+ * @brief Set Channel priority level.
+ * @rmtoll CCR PL LL_DMA_SetChannelPriorityLevel
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @param Priority This parameter can be one of the following values:
+ * @arg @ref LL_DMA_PRIORITY_LOW
+ * @arg @ref LL_DMA_PRIORITY_MEDIUM
+ * @arg @ref LL_DMA_PRIORITY_HIGH
+ * @arg @ref LL_DMA_PRIORITY_VERYHIGH
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_SetChannelPriorityLevel(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t Priority)
+{
+ MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_PL,
+ Priority);
+}
+
+/**
+ * @brief Get Channel priority level.
+ * @rmtoll CCR PL LL_DMA_GetChannelPriorityLevel
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_DMA_PRIORITY_LOW
+ * @arg @ref LL_DMA_PRIORITY_MEDIUM
+ * @arg @ref LL_DMA_PRIORITY_HIGH
+ * @arg @ref LL_DMA_PRIORITY_VERYHIGH
+ */
+__STATIC_INLINE uint32_t LL_DMA_GetChannelPriorityLevel(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
+ DMA_CCR_PL));
+}
+
+/**
+ * @brief Set Number of data to transfer.
+ * @note This action has no effect if
+ * channel is enabled.
+ * @rmtoll CNDTR NDT LL_DMA_SetDataLength
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @param NbData Between Min_Data = 0 and Max_Data = 0x0000FFFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_SetDataLength(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t NbData)
+{
+ MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CNDTR,
+ DMA_CNDTR_NDT, NbData);
+}
+
+/**
+ * @brief Get Number of data to transfer.
+ * @note Once the channel is enabled, the return value indicate the
+ * remaining bytes to be transmitted.
+ * @rmtoll CNDTR NDT LL_DMA_GetDataLength
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
+ */
+__STATIC_INLINE uint32_t LL_DMA_GetDataLength(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CNDTR,
+ DMA_CNDTR_NDT));
+}
+
+/**
+ * @brief Configure the Source and Destination addresses.
+ * @note This API must not be called when the DMA channel is enabled.
+ * @note Each IP using DMA provides an API to get directly the register adress (LL_PPP_DMA_GetRegAddr).
+ * @rmtoll CPAR PA LL_DMA_ConfigAddresses\n
+ * CMAR MA LL_DMA_ConfigAddresses
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @param SrcAddress Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
+ * @param DstAddress Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
+ * @param Direction This parameter can be one of the following values:
+ * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_MEMORY
+ * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_PERIPH
+ * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_MEMORY
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ConfigAddresses(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t SrcAddress,
+ uint32_t DstAddress, uint32_t Direction)
+{
+ /* Direction Memory to Periph */
+ if (Direction == LL_DMA_DIRECTION_MEMORY_TO_PERIPH)
+ {
+ WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CMAR, SrcAddress);
+ WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CPAR, DstAddress);
+ }
+ /* Direction Periph to Memory and Memory to Memory */
+ else
+ {
+ WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CPAR, SrcAddress);
+ WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CMAR, DstAddress);
+ }
+}
+
+/**
+ * @brief Set the Memory address.
+ * @note Interface used for direction LL_DMA_DIRECTION_PERIPH_TO_MEMORY or LL_DMA_DIRECTION_MEMORY_TO_PERIPH only.
+ * @note This API must not be called when the DMA channel is enabled.
+ * @rmtoll CMAR MA LL_DMA_SetMemoryAddress
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @param MemoryAddress Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_SetMemoryAddress(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t MemoryAddress)
+{
+ WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CMAR, MemoryAddress);
+}
+
+/**
+ * @brief Set the Peripheral address.
+ * @note Interface used for direction LL_DMA_DIRECTION_PERIPH_TO_MEMORY or LL_DMA_DIRECTION_MEMORY_TO_PERIPH only.
+ * @note This API must not be called when the DMA channel is enabled.
+ * @rmtoll CPAR PA LL_DMA_SetPeriphAddress
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @param PeriphAddress Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_SetPeriphAddress(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t PeriphAddress)
+{
+ WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CPAR, PeriphAddress);
+}
+
+/**
+ * @brief Get Memory address.
+ * @note Interface used for direction LL_DMA_DIRECTION_PERIPH_TO_MEMORY or LL_DMA_DIRECTION_MEMORY_TO_PERIPH only.
+ * @rmtoll CMAR MA LL_DMA_GetMemoryAddress
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
+ */
+__STATIC_INLINE uint32_t LL_DMA_GetMemoryAddress(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ return (READ_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CMAR));
+}
+
+/**
+ * @brief Get Peripheral address.
+ * @note Interface used for direction LL_DMA_DIRECTION_PERIPH_TO_MEMORY or LL_DMA_DIRECTION_MEMORY_TO_PERIPH only.
+ * @rmtoll CPAR PA LL_DMA_GetPeriphAddress
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
+ */
+__STATIC_INLINE uint32_t LL_DMA_GetPeriphAddress(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ return (READ_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CPAR));
+}
+
+/**
+ * @brief Set the Memory to Memory Source address.
+ * @note Interface used for direction LL_DMA_DIRECTION_MEMORY_TO_MEMORY only.
+ * @note This API must not be called when the DMA channel is enabled.
+ * @rmtoll CPAR PA LL_DMA_SetM2MSrcAddress
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @param MemoryAddress Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_SetM2MSrcAddress(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t MemoryAddress)
+{
+ WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CPAR, MemoryAddress);
+}
+
+/**
+ * @brief Set the Memory to Memory Destination address.
+ * @note Interface used for direction LL_DMA_DIRECTION_MEMORY_TO_MEMORY only.
+ * @note This API must not be called when the DMA channel is enabled.
+ * @rmtoll CMAR MA LL_DMA_SetM2MDstAddress
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @param MemoryAddress Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_SetM2MDstAddress(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t MemoryAddress)
+{
+ WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CMAR, MemoryAddress);
+}
+
+/**
+ * @brief Get the Memory to Memory Source address.
+ * @note Interface used for direction LL_DMA_DIRECTION_MEMORY_TO_MEMORY only.
+ * @rmtoll CPAR PA LL_DMA_GetM2MSrcAddress
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
+ */
+__STATIC_INLINE uint32_t LL_DMA_GetM2MSrcAddress(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ return (READ_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CPAR));
+}
+
+/**
+ * @brief Get the Memory to Memory Destination address.
+ * @note Interface used for direction LL_DMA_DIRECTION_MEMORY_TO_MEMORY only.
+ * @rmtoll CMAR MA LL_DMA_GetM2MDstAddress
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF
+ */
+__STATIC_INLINE uint32_t LL_DMA_GetM2MDstAddress(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ return (READ_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CMAR));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup DMA_LL_EF_FLAG_Management FLAG_Management
+ * @{
+ */
+
+/**
+ * @brief Get Channel 1 global interrupt flag.
+ * @rmtoll ISR GIF1 LL_DMA_IsActiveFlag_GI1
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI1(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_GIF1) == (DMA_ISR_GIF1));
+}
+
+/**
+ * @brief Get Channel 2 global interrupt flag.
+ * @rmtoll ISR GIF2 LL_DMA_IsActiveFlag_GI2
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI2(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_GIF2) == (DMA_ISR_GIF2));
+}
+
+/**
+ * @brief Get Channel 3 global interrupt flag.
+ * @rmtoll ISR GIF3 LL_DMA_IsActiveFlag_GI3
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI3(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_GIF3) == (DMA_ISR_GIF3));
+}
+
+/**
+ * @brief Get Channel 4 global interrupt flag.
+ * @rmtoll ISR GIF4 LL_DMA_IsActiveFlag_GI4
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI4(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_GIF4) == (DMA_ISR_GIF4));
+}
+
+/**
+ * @brief Get Channel 5 global interrupt flag.
+ * @rmtoll ISR GIF5 LL_DMA_IsActiveFlag_GI5
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI5(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_GIF5) == (DMA_ISR_GIF5));
+}
+
+/**
+ * @brief Get Channel 6 global interrupt flag.
+ * @rmtoll ISR GIF6 LL_DMA_IsActiveFlag_GI6
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI6(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_GIF6) == (DMA_ISR_GIF6));
+}
+
+/**
+ * @brief Get Channel 7 global interrupt flag.
+ * @rmtoll ISR GIF7 LL_DMA_IsActiveFlag_GI7
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI7(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_GIF7) == (DMA_ISR_GIF7));
+}
+
+/**
+ * @brief Get Channel 1 transfer complete flag.
+ * @rmtoll ISR TCIF1 LL_DMA_IsActiveFlag_TC1
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC1(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF1) == (DMA_ISR_TCIF1));
+}
+
+/**
+ * @brief Get Channel 2 transfer complete flag.
+ * @rmtoll ISR TCIF2 LL_DMA_IsActiveFlag_TC2
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC2(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF2) == (DMA_ISR_TCIF2));
+}
+
+/**
+ * @brief Get Channel 3 transfer complete flag.
+ * @rmtoll ISR TCIF3 LL_DMA_IsActiveFlag_TC3
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC3(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF3) == (DMA_ISR_TCIF3));
+}
+
+/**
+ * @brief Get Channel 4 transfer complete flag.
+ * @rmtoll ISR TCIF4 LL_DMA_IsActiveFlag_TC4
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC4(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF4) == (DMA_ISR_TCIF4));
+}
+
+/**
+ * @brief Get Channel 5 transfer complete flag.
+ * @rmtoll ISR TCIF5 LL_DMA_IsActiveFlag_TC5
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC5(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF5) == (DMA_ISR_TCIF5));
+}
+
+/**
+ * @brief Get Channel 6 transfer complete flag.
+ * @rmtoll ISR TCIF6 LL_DMA_IsActiveFlag_TC6
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC6(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF6) == (DMA_ISR_TCIF6));
+}
+
+/**
+ * @brief Get Channel 7 transfer complete flag.
+ * @rmtoll ISR TCIF7 LL_DMA_IsActiveFlag_TC7
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC7(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF7) == (DMA_ISR_TCIF7));
+}
+
+/**
+ * @brief Get Channel 1 half transfer flag.
+ * @rmtoll ISR HTIF1 LL_DMA_IsActiveFlag_HT1
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT1(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF1) == (DMA_ISR_HTIF1));
+}
+
+/**
+ * @brief Get Channel 2 half transfer flag.
+ * @rmtoll ISR HTIF2 LL_DMA_IsActiveFlag_HT2
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT2(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF2) == (DMA_ISR_HTIF2));
+}
+
+/**
+ * @brief Get Channel 3 half transfer flag.
+ * @rmtoll ISR HTIF3 LL_DMA_IsActiveFlag_HT3
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT3(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF3) == (DMA_ISR_HTIF3));
+}
+
+/**
+ * @brief Get Channel 4 half transfer flag.
+ * @rmtoll ISR HTIF4 LL_DMA_IsActiveFlag_HT4
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT4(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF4) == (DMA_ISR_HTIF4));
+}
+
+/**
+ * @brief Get Channel 5 half transfer flag.
+ * @rmtoll ISR HTIF5 LL_DMA_IsActiveFlag_HT5
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT5(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF5) == (DMA_ISR_HTIF5));
+}
+
+/**
+ * @brief Get Channel 6 half transfer flag.
+ * @rmtoll ISR HTIF6 LL_DMA_IsActiveFlag_HT6
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT6(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF6) == (DMA_ISR_HTIF6));
+}
+
+/**
+ * @brief Get Channel 7 half transfer flag.
+ * @rmtoll ISR HTIF7 LL_DMA_IsActiveFlag_HT7
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT7(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF7) == (DMA_ISR_HTIF7));
+}
+
+/**
+ * @brief Get Channel 1 transfer error flag.
+ * @rmtoll ISR TEIF1 LL_DMA_IsActiveFlag_TE1
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE1(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF1) == (DMA_ISR_TEIF1));
+}
+
+/**
+ * @brief Get Channel 2 transfer error flag.
+ * @rmtoll ISR TEIF2 LL_DMA_IsActiveFlag_TE2
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE2(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF2) == (DMA_ISR_TEIF2));
+}
+
+/**
+ * @brief Get Channel 3 transfer error flag.
+ * @rmtoll ISR TEIF3 LL_DMA_IsActiveFlag_TE3
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE3(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF3) == (DMA_ISR_TEIF3));
+}
+
+/**
+ * @brief Get Channel 4 transfer error flag.
+ * @rmtoll ISR TEIF4 LL_DMA_IsActiveFlag_TE4
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE4(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF4) == (DMA_ISR_TEIF4));
+}
+
+/**
+ * @brief Get Channel 5 transfer error flag.
+ * @rmtoll ISR TEIF5 LL_DMA_IsActiveFlag_TE5
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE5(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF5) == (DMA_ISR_TEIF5));
+}
+
+/**
+ * @brief Get Channel 6 transfer error flag.
+ * @rmtoll ISR TEIF6 LL_DMA_IsActiveFlag_TE6
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE6(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF6) == (DMA_ISR_TEIF6));
+}
+
+/**
+ * @brief Get Channel 7 transfer error flag.
+ * @rmtoll ISR TEIF7 LL_DMA_IsActiveFlag_TE7
+ * @param DMAx DMAx Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE7(DMA_TypeDef *DMAx)
+{
+ return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF7) == (DMA_ISR_TEIF7));
+}
+
+/**
+ * @brief Clear Channel 1 global interrupt flag.
+ * @rmtoll IFCR CGIF1 LL_DMA_ClearFlag_GI1
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_GI1(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF1);
+}
+
+/**
+ * @brief Clear Channel 2 global interrupt flag.
+ * @rmtoll IFCR CGIF2 LL_DMA_ClearFlag_GI2
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_GI2(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF2);
+}
+
+/**
+ * @brief Clear Channel 3 global interrupt flag.
+ * @rmtoll IFCR CGIF3 LL_DMA_ClearFlag_GI3
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_GI3(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF3);
+}
+
+/**
+ * @brief Clear Channel 4 global interrupt flag.
+ * @rmtoll IFCR CGIF4 LL_DMA_ClearFlag_GI4
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_GI4(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF4);
+}
+
+/**
+ * @brief Clear Channel 5 global interrupt flag.
+ * @rmtoll IFCR CGIF5 LL_DMA_ClearFlag_GI5
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_GI5(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF5);
+}
+
+/**
+ * @brief Clear Channel 6 global interrupt flag.
+ * @rmtoll IFCR CGIF6 LL_DMA_ClearFlag_GI6
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_GI6(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF6);
+}
+
+/**
+ * @brief Clear Channel 7 global interrupt flag.
+ * @rmtoll IFCR CGIF7 LL_DMA_ClearFlag_GI7
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_GI7(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF7);
+}
+
+/**
+ * @brief Clear Channel 1 transfer complete flag.
+ * @rmtoll IFCR CTCIF1 LL_DMA_ClearFlag_TC1
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_TC1(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF1);
+}
+
+/**
+ * @brief Clear Channel 2 transfer complete flag.
+ * @rmtoll IFCR CTCIF2 LL_DMA_ClearFlag_TC2
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_TC2(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF2);
+}
+
+/**
+ * @brief Clear Channel 3 transfer complete flag.
+ * @rmtoll IFCR CTCIF3 LL_DMA_ClearFlag_TC3
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_TC3(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF3);
+}
+
+/**
+ * @brief Clear Channel 4 transfer complete flag.
+ * @rmtoll IFCR CTCIF4 LL_DMA_ClearFlag_TC4
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_TC4(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF4);
+}
+
+/**
+ * @brief Clear Channel 5 transfer complete flag.
+ * @rmtoll IFCR CTCIF5 LL_DMA_ClearFlag_TC5
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_TC5(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF5);
+}
+
+/**
+ * @brief Clear Channel 6 transfer complete flag.
+ * @rmtoll IFCR CTCIF6 LL_DMA_ClearFlag_TC6
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_TC6(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF6);
+}
+
+/**
+ * @brief Clear Channel 7 transfer complete flag.
+ * @rmtoll IFCR CTCIF7 LL_DMA_ClearFlag_TC7
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_TC7(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF7);
+}
+
+/**
+ * @brief Clear Channel 1 half transfer flag.
+ * @rmtoll IFCR CHTIF1 LL_DMA_ClearFlag_HT1
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_HT1(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF1);
+}
+
+/**
+ * @brief Clear Channel 2 half transfer flag.
+ * @rmtoll IFCR CHTIF2 LL_DMA_ClearFlag_HT2
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_HT2(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF2);
+}
+
+/**
+ * @brief Clear Channel 3 half transfer flag.
+ * @rmtoll IFCR CHTIF3 LL_DMA_ClearFlag_HT3
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_HT3(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF3);
+}
+
+/**
+ * @brief Clear Channel 4 half transfer flag.
+ * @rmtoll IFCR CHTIF4 LL_DMA_ClearFlag_HT4
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_HT4(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF4);
+}
+
+/**
+ * @brief Clear Channel 5 half transfer flag.
+ * @rmtoll IFCR CHTIF5 LL_DMA_ClearFlag_HT5
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_HT5(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF5);
+}
+
+/**
+ * @brief Clear Channel 6 half transfer flag.
+ * @rmtoll IFCR CHTIF6 LL_DMA_ClearFlag_HT6
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_HT6(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF6);
+}
+
+/**
+ * @brief Clear Channel 7 half transfer flag.
+ * @rmtoll IFCR CHTIF7 LL_DMA_ClearFlag_HT7
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_HT7(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF7);
+}
+
+/**
+ * @brief Clear Channel 1 transfer error flag.
+ * @rmtoll IFCR CTEIF1 LL_DMA_ClearFlag_TE1
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_TE1(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF1);
+}
+
+/**
+ * @brief Clear Channel 2 transfer error flag.
+ * @rmtoll IFCR CTEIF2 LL_DMA_ClearFlag_TE2
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_TE2(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF2);
+}
+
+/**
+ * @brief Clear Channel 3 transfer error flag.
+ * @rmtoll IFCR CTEIF3 LL_DMA_ClearFlag_TE3
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_TE3(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF3);
+}
+
+/**
+ * @brief Clear Channel 4 transfer error flag.
+ * @rmtoll IFCR CTEIF4 LL_DMA_ClearFlag_TE4
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_TE4(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF4);
+}
+
+/**
+ * @brief Clear Channel 5 transfer error flag.
+ * @rmtoll IFCR CTEIF5 LL_DMA_ClearFlag_TE5
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_TE5(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF5);
+}
+
+/**
+ * @brief Clear Channel 6 transfer error flag.
+ * @rmtoll IFCR CTEIF6 LL_DMA_ClearFlag_TE6
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_TE6(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF6);
+}
+
+/**
+ * @brief Clear Channel 7 transfer error flag.
+ * @rmtoll IFCR CTEIF7 LL_DMA_ClearFlag_TE7
+ * @param DMAx DMAx Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_ClearFlag_TE7(DMA_TypeDef *DMAx)
+{
+ WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF7);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup DMA_LL_EF_IT_Management IT_Management
+ * @{
+ */
+
+/**
+ * @brief Enable Transfer complete interrupt.
+ * @rmtoll CCR TCIE LL_DMA_EnableIT_TC
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_EnableIT_TC(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ SET_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_TCIE);
+}
+
+/**
+ * @brief Enable Half transfer interrupt.
+ * @rmtoll CCR HTIE LL_DMA_EnableIT_HT
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_EnableIT_HT(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ SET_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_HTIE);
+}
+
+/**
+ * @brief Enable Transfer error interrupt.
+ * @rmtoll CCR TEIE LL_DMA_EnableIT_TE
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_EnableIT_TE(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ SET_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_TEIE);
+}
+
+/**
+ * @brief Disable Transfer complete interrupt.
+ * @rmtoll CCR TCIE LL_DMA_DisableIT_TC
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_DisableIT_TC(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ CLEAR_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_TCIE);
+}
+
+/**
+ * @brief Disable Half transfer interrupt.
+ * @rmtoll CCR HTIE LL_DMA_DisableIT_HT
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_DisableIT_HT(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ CLEAR_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_HTIE);
+}
+
+/**
+ * @brief Disable Transfer error interrupt.
+ * @rmtoll CCR TEIE LL_DMA_DisableIT_TE
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval None
+ */
+__STATIC_INLINE void LL_DMA_DisableIT_TE(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ CLEAR_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR, DMA_CCR_TEIE);
+}
+
+/**
+ * @brief Check if Transfer complete Interrupt is enabled.
+ * @rmtoll CCR TCIE LL_DMA_IsEnabledIT_TC
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsEnabledIT_TC(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
+ DMA_CCR_TCIE) == (DMA_CCR_TCIE));
+}
+
+/**
+ * @brief Check if Half transfer Interrupt is enabled.
+ * @rmtoll CCR HTIE LL_DMA_IsEnabledIT_HT
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsEnabledIT_HT(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
+ DMA_CCR_HTIE) == (DMA_CCR_HTIE));
+}
+
+/**
+ * @brief Check if Transfer error Interrupt is enabled.
+ * @rmtoll CCR TEIE LL_DMA_IsEnabledIT_TE
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_DMA_IsEnabledIT_TE(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ return (READ_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U])))->CCR,
+ DMA_CCR_TEIE) == (DMA_CCR_TEIE));
+}
+
+/**
+ * @}
+ */
+
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup DMA_LL_EF_Init Initialization and de-initialization functions
+ * @{
+ */
+
+uint32_t LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Channel, LL_DMA_InitTypeDef *DMA_InitStruct);
+uint32_t LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Channel);
+void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct);
+
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* DMA1 || DMA2 */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_LL_DMA_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_exti.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_exti.h
new file mode 100644
index 0000000..fd17bcc
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_exti.h
@@ -0,0 +1,904 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_exti.h
+ * @author MCD Application Team
+ * @brief Header file of EXTI LL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_EXTI_H
+#define __STM32F1xx_LL_EXTI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx.h"
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (EXTI)
+
+/** @defgroup EXTI_LL EXTI
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private Macros ------------------------------------------------------------*/
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup EXTI_LL_Private_Macros EXTI Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+#endif /*USE_FULL_LL_DRIVER*/
+/* Exported types ------------------------------------------------------------*/
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup EXTI_LL_ES_INIT EXTI Exported Init structure
+ * @{
+ */
+typedef struct
+{
+
+ uint32_t Line_0_31; /*!< Specifies the EXTI lines to be enabled or disabled for Lines in range 0 to 31
+ This parameter can be any combination of @ref EXTI_LL_EC_LINE */
+
+ FunctionalState LineCommand; /*!< Specifies the new state of the selected EXTI lines.
+ This parameter can be set either to ENABLE or DISABLE */
+
+ uint8_t Mode; /*!< Specifies the mode for the EXTI lines.
+ This parameter can be a value of @ref EXTI_LL_EC_MODE. */
+
+ uint8_t Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.
+ This parameter can be a value of @ref EXTI_LL_EC_TRIGGER. */
+} LL_EXTI_InitTypeDef;
+
+/**
+ * @}
+ */
+#endif /*USE_FULL_LL_DRIVER*/
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup EXTI_LL_Exported_Constants EXTI Exported Constants
+ * @{
+ */
+
+/** @defgroup EXTI_LL_EC_LINE LINE
+ * @{
+ */
+#define LL_EXTI_LINE_0 EXTI_IMR_IM0 /*!< Extended line 0 */
+#define LL_EXTI_LINE_1 EXTI_IMR_IM1 /*!< Extended line 1 */
+#define LL_EXTI_LINE_2 EXTI_IMR_IM2 /*!< Extended line 2 */
+#define LL_EXTI_LINE_3 EXTI_IMR_IM3 /*!< Extended line 3 */
+#define LL_EXTI_LINE_4 EXTI_IMR_IM4 /*!< Extended line 4 */
+#define LL_EXTI_LINE_5 EXTI_IMR_IM5 /*!< Extended line 5 */
+#define LL_EXTI_LINE_6 EXTI_IMR_IM6 /*!< Extended line 6 */
+#define LL_EXTI_LINE_7 EXTI_IMR_IM7 /*!< Extended line 7 */
+#define LL_EXTI_LINE_8 EXTI_IMR_IM8 /*!< Extended line 8 */
+#define LL_EXTI_LINE_9 EXTI_IMR_IM9 /*!< Extended line 9 */
+#define LL_EXTI_LINE_10 EXTI_IMR_IM10 /*!< Extended line 10 */
+#define LL_EXTI_LINE_11 EXTI_IMR_IM11 /*!< Extended line 11 */
+#define LL_EXTI_LINE_12 EXTI_IMR_IM12 /*!< Extended line 12 */
+#define LL_EXTI_LINE_13 EXTI_IMR_IM13 /*!< Extended line 13 */
+#define LL_EXTI_LINE_14 EXTI_IMR_IM14 /*!< Extended line 14 */
+#define LL_EXTI_LINE_15 EXTI_IMR_IM15 /*!< Extended line 15 */
+#if defined(EXTI_IMR_IM16)
+#define LL_EXTI_LINE_16 EXTI_IMR_IM16 /*!< Extended line 16 */
+#endif
+#define LL_EXTI_LINE_17 EXTI_IMR_IM17 /*!< Extended line 17 */
+#if defined(EXTI_IMR_IM18)
+#define LL_EXTI_LINE_18 EXTI_IMR_IM18 /*!< Extended line 18 */
+#endif
+#if defined(EXTI_IMR_IM19)
+#define LL_EXTI_LINE_19 EXTI_IMR_IM19 /*!< Extended line 19 */
+#endif
+#if defined(EXTI_IMR_IM20)
+#define LL_EXTI_LINE_20 EXTI_IMR_IM20 /*!< Extended line 20 */
+#endif
+#if defined(EXTI_IMR_IM21)
+#define LL_EXTI_LINE_21 EXTI_IMR_IM21 /*!< Extended line 21 */
+#endif
+#if defined(EXTI_IMR_IM22)
+#define LL_EXTI_LINE_22 EXTI_IMR_IM22 /*!< Extended line 22 */
+#endif
+#if defined(EXTI_IMR_IM23)
+#define LL_EXTI_LINE_23 EXTI_IMR_IM23 /*!< Extended line 23 */
+#endif
+#if defined(EXTI_IMR_IM24)
+#define LL_EXTI_LINE_24 EXTI_IMR_IM24 /*!< Extended line 24 */
+#endif
+#if defined(EXTI_IMR_IM25)
+#define LL_EXTI_LINE_25 EXTI_IMR_IM25 /*!< Extended line 25 */
+#endif
+#if defined(EXTI_IMR_IM26)
+#define LL_EXTI_LINE_26 EXTI_IMR_IM26 /*!< Extended line 26 */
+#endif
+#if defined(EXTI_IMR_IM27)
+#define LL_EXTI_LINE_27 EXTI_IMR_IM27 /*!< Extended line 27 */
+#endif
+#if defined(EXTI_IMR_IM28)
+#define LL_EXTI_LINE_28 EXTI_IMR_IM28 /*!< Extended line 28 */
+#endif
+#if defined(EXTI_IMR_IM29)
+#define LL_EXTI_LINE_29 EXTI_IMR_IM29 /*!< Extended line 29 */
+#endif
+#if defined(EXTI_IMR_IM30)
+#define LL_EXTI_LINE_30 EXTI_IMR_IM30 /*!< Extended line 30 */
+#endif
+#if defined(EXTI_IMR_IM31)
+#define LL_EXTI_LINE_31 EXTI_IMR_IM31 /*!< Extended line 31 */
+#endif
+#define LL_EXTI_LINE_ALL_0_31 EXTI_IMR_IM /*!< All Extended line not reserved*/
+
+
+#define LL_EXTI_LINE_ALL (0xFFFFFFFFU) /*!< All Extended line */
+
+#if defined(USE_FULL_LL_DRIVER)
+#define LL_EXTI_LINE_NONE (0x00000000U) /*!< None Extended line */
+#endif /*USE_FULL_LL_DRIVER*/
+
+/**
+ * @}
+ */
+#if defined(USE_FULL_LL_DRIVER)
+
+/** @defgroup EXTI_LL_EC_MODE Mode
+ * @{
+ */
+#define LL_EXTI_MODE_IT ((uint8_t)0x00) /*!< Interrupt Mode */
+#define LL_EXTI_MODE_EVENT ((uint8_t)0x01) /*!< Event Mode */
+#define LL_EXTI_MODE_IT_EVENT ((uint8_t)0x02) /*!< Interrupt & Event Mode */
+/**
+ * @}
+ */
+
+/** @defgroup EXTI_LL_EC_TRIGGER Edge Trigger
+ * @{
+ */
+#define LL_EXTI_TRIGGER_NONE ((uint8_t)0x00) /*!< No Trigger Mode */
+#define LL_EXTI_TRIGGER_RISING ((uint8_t)0x01) /*!< Trigger Rising Mode */
+#define LL_EXTI_TRIGGER_FALLING ((uint8_t)0x02) /*!< Trigger Falling Mode */
+#define LL_EXTI_TRIGGER_RISING_FALLING ((uint8_t)0x03) /*!< Trigger Rising & Falling Mode */
+
+/**
+ * @}
+ */
+
+
+#endif /*USE_FULL_LL_DRIVER*/
+
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup EXTI_LL_Exported_Macros EXTI Exported Macros
+ * @{
+ */
+
+/** @defgroup EXTI_LL_EM_WRITE_READ Common Write and read registers Macros
+ * @{
+ */
+
+/**
+ * @brief Write a value in EXTI register
+ * @param __REG__ Register to be written
+ * @param __VALUE__ Value to be written in the register
+ * @retval None
+ */
+#define LL_EXTI_WriteReg(__REG__, __VALUE__) WRITE_REG(EXTI->__REG__, (__VALUE__))
+
+/**
+ * @brief Read a value in EXTI register
+ * @param __REG__ Register to be read
+ * @retval Register value
+ */
+#define LL_EXTI_ReadReg(__REG__) READ_REG(EXTI->__REG__)
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup EXTI_LL_Exported_Functions EXTI Exported Functions
+ * @{
+ */
+/** @defgroup EXTI_LL_EF_IT_Management IT_Management
+ * @{
+ */
+
+/**
+ * @brief Enable ExtiLine Interrupt request for Lines in range 0 to 31
+ * @note The reset value for the direct or internal lines (see RM)
+ * is set to 1 in order to enable the interrupt by default.
+ * Bits are set automatically at Power on.
+ * @rmtoll IMR IMx LL_EXTI_EnableIT_0_31
+ * @param ExtiLine This parameter can be one of the following values:
+ * @arg @ref LL_EXTI_LINE_0
+ * @arg @ref LL_EXTI_LINE_1
+ * @arg @ref LL_EXTI_LINE_2
+ * @arg @ref LL_EXTI_LINE_3
+ * @arg @ref LL_EXTI_LINE_4
+ * @arg @ref LL_EXTI_LINE_5
+ * @arg @ref LL_EXTI_LINE_6
+ * @arg @ref LL_EXTI_LINE_7
+ * @arg @ref LL_EXTI_LINE_8
+ * @arg @ref LL_EXTI_LINE_9
+ * @arg @ref LL_EXTI_LINE_10
+ * @arg @ref LL_EXTI_LINE_11
+ * @arg @ref LL_EXTI_LINE_12
+ * @arg @ref LL_EXTI_LINE_13
+ * @arg @ref LL_EXTI_LINE_14
+ * @arg @ref LL_EXTI_LINE_15
+ * @arg @ref LL_EXTI_LINE_16
+ * @arg @ref LL_EXTI_LINE_17
+ * @arg @ref LL_EXTI_LINE_18
+ * @arg @ref LL_EXTI_LINE_19
+ * @arg @ref LL_EXTI_LINE_ALL_0_31
+ * @note Please check each device line mapping for EXTI Line availability
+ * @retval None
+ */
+__STATIC_INLINE void LL_EXTI_EnableIT_0_31(uint32_t ExtiLine)
+{
+ SET_BIT(EXTI->IMR, ExtiLine);
+}
+
+/**
+ * @brief Disable ExtiLine Interrupt request for Lines in range 0 to 31
+ * @note The reset value for the direct or internal lines (see RM)
+ * is set to 1 in order to enable the interrupt by default.
+ * Bits are set automatically at Power on.
+ * @rmtoll IMR IMx LL_EXTI_DisableIT_0_31
+ * @param ExtiLine This parameter can be one of the following values:
+ * @arg @ref LL_EXTI_LINE_0
+ * @arg @ref LL_EXTI_LINE_1
+ * @arg @ref LL_EXTI_LINE_2
+ * @arg @ref LL_EXTI_LINE_3
+ * @arg @ref LL_EXTI_LINE_4
+ * @arg @ref LL_EXTI_LINE_5
+ * @arg @ref LL_EXTI_LINE_6
+ * @arg @ref LL_EXTI_LINE_7
+ * @arg @ref LL_EXTI_LINE_8
+ * @arg @ref LL_EXTI_LINE_9
+ * @arg @ref LL_EXTI_LINE_10
+ * @arg @ref LL_EXTI_LINE_11
+ * @arg @ref LL_EXTI_LINE_12
+ * @arg @ref LL_EXTI_LINE_13
+ * @arg @ref LL_EXTI_LINE_14
+ * @arg @ref LL_EXTI_LINE_15
+ * @arg @ref LL_EXTI_LINE_16
+ * @arg @ref LL_EXTI_LINE_17
+ * @arg @ref LL_EXTI_LINE_18
+ * @arg @ref LL_EXTI_LINE_19
+ * @arg @ref LL_EXTI_LINE_ALL_0_31
+ * @note Please check each device line mapping for EXTI Line availability
+ * @retval None
+ */
+__STATIC_INLINE void LL_EXTI_DisableIT_0_31(uint32_t ExtiLine)
+{
+ CLEAR_BIT(EXTI->IMR, ExtiLine);
+}
+
+
+/**
+ * @brief Indicate if ExtiLine Interrupt request is enabled for Lines in range 0 to 31
+ * @note The reset value for the direct or internal lines (see RM)
+ * is set to 1 in order to enable the interrupt by default.
+ * Bits are set automatically at Power on.
+ * @rmtoll IMR IMx LL_EXTI_IsEnabledIT_0_31
+ * @param ExtiLine This parameter can be one of the following values:
+ * @arg @ref LL_EXTI_LINE_0
+ * @arg @ref LL_EXTI_LINE_1
+ * @arg @ref LL_EXTI_LINE_2
+ * @arg @ref LL_EXTI_LINE_3
+ * @arg @ref LL_EXTI_LINE_4
+ * @arg @ref LL_EXTI_LINE_5
+ * @arg @ref LL_EXTI_LINE_6
+ * @arg @ref LL_EXTI_LINE_7
+ * @arg @ref LL_EXTI_LINE_8
+ * @arg @ref LL_EXTI_LINE_9
+ * @arg @ref LL_EXTI_LINE_10
+ * @arg @ref LL_EXTI_LINE_11
+ * @arg @ref LL_EXTI_LINE_12
+ * @arg @ref LL_EXTI_LINE_13
+ * @arg @ref LL_EXTI_LINE_14
+ * @arg @ref LL_EXTI_LINE_15
+ * @arg @ref LL_EXTI_LINE_16
+ * @arg @ref LL_EXTI_LINE_17
+ * @arg @ref LL_EXTI_LINE_18
+ * @arg @ref LL_EXTI_LINE_19
+ * @arg @ref LL_EXTI_LINE_ALL_0_31
+ * @note Please check each device line mapping for EXTI Line availability
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_EXTI_IsEnabledIT_0_31(uint32_t ExtiLine)
+{
+ return (READ_BIT(EXTI->IMR, ExtiLine) == (ExtiLine));
+}
+
+
+/**
+ * @}
+ */
+
+/** @defgroup EXTI_LL_EF_Event_Management Event_Management
+ * @{
+ */
+
+/**
+ * @brief Enable ExtiLine Event request for Lines in range 0 to 31
+ * @rmtoll EMR EMx LL_EXTI_EnableEvent_0_31
+ * @param ExtiLine This parameter can be one of the following values:
+ * @arg @ref LL_EXTI_LINE_0
+ * @arg @ref LL_EXTI_LINE_1
+ * @arg @ref LL_EXTI_LINE_2
+ * @arg @ref LL_EXTI_LINE_3
+ * @arg @ref LL_EXTI_LINE_4
+ * @arg @ref LL_EXTI_LINE_5
+ * @arg @ref LL_EXTI_LINE_6
+ * @arg @ref LL_EXTI_LINE_7
+ * @arg @ref LL_EXTI_LINE_8
+ * @arg @ref LL_EXTI_LINE_9
+ * @arg @ref LL_EXTI_LINE_10
+ * @arg @ref LL_EXTI_LINE_11
+ * @arg @ref LL_EXTI_LINE_12
+ * @arg @ref LL_EXTI_LINE_13
+ * @arg @ref LL_EXTI_LINE_14
+ * @arg @ref LL_EXTI_LINE_15
+ * @arg @ref LL_EXTI_LINE_16
+ * @arg @ref LL_EXTI_LINE_17
+ * @arg @ref LL_EXTI_LINE_18
+ * @arg @ref LL_EXTI_LINE_19
+ * @arg @ref LL_EXTI_LINE_ALL_0_31
+ * @note Please check each device line mapping for EXTI Line availability
+ * @retval None
+ */
+__STATIC_INLINE void LL_EXTI_EnableEvent_0_31(uint32_t ExtiLine)
+{
+ SET_BIT(EXTI->EMR, ExtiLine);
+
+}
+
+
+/**
+ * @brief Disable ExtiLine Event request for Lines in range 0 to 31
+ * @rmtoll EMR EMx LL_EXTI_DisableEvent_0_31
+ * @param ExtiLine This parameter can be one of the following values:
+ * @arg @ref LL_EXTI_LINE_0
+ * @arg @ref LL_EXTI_LINE_1
+ * @arg @ref LL_EXTI_LINE_2
+ * @arg @ref LL_EXTI_LINE_3
+ * @arg @ref LL_EXTI_LINE_4
+ * @arg @ref LL_EXTI_LINE_5
+ * @arg @ref LL_EXTI_LINE_6
+ * @arg @ref LL_EXTI_LINE_7
+ * @arg @ref LL_EXTI_LINE_8
+ * @arg @ref LL_EXTI_LINE_9
+ * @arg @ref LL_EXTI_LINE_10
+ * @arg @ref LL_EXTI_LINE_11
+ * @arg @ref LL_EXTI_LINE_12
+ * @arg @ref LL_EXTI_LINE_13
+ * @arg @ref LL_EXTI_LINE_14
+ * @arg @ref LL_EXTI_LINE_15
+ * @arg @ref LL_EXTI_LINE_16
+ * @arg @ref LL_EXTI_LINE_17
+ * @arg @ref LL_EXTI_LINE_18
+ * @arg @ref LL_EXTI_LINE_19
+ * @arg @ref LL_EXTI_LINE_ALL_0_31
+ * @note Please check each device line mapping for EXTI Line availability
+ * @retval None
+ */
+__STATIC_INLINE void LL_EXTI_DisableEvent_0_31(uint32_t ExtiLine)
+{
+ CLEAR_BIT(EXTI->EMR, ExtiLine);
+}
+
+
+/**
+ * @brief Indicate if ExtiLine Event request is enabled for Lines in range 0 to 31
+ * @rmtoll EMR EMx LL_EXTI_IsEnabledEvent_0_31
+ * @param ExtiLine This parameter can be one of the following values:
+ * @arg @ref LL_EXTI_LINE_0
+ * @arg @ref LL_EXTI_LINE_1
+ * @arg @ref LL_EXTI_LINE_2
+ * @arg @ref LL_EXTI_LINE_3
+ * @arg @ref LL_EXTI_LINE_4
+ * @arg @ref LL_EXTI_LINE_5
+ * @arg @ref LL_EXTI_LINE_6
+ * @arg @ref LL_EXTI_LINE_7
+ * @arg @ref LL_EXTI_LINE_8
+ * @arg @ref LL_EXTI_LINE_9
+ * @arg @ref LL_EXTI_LINE_10
+ * @arg @ref LL_EXTI_LINE_11
+ * @arg @ref LL_EXTI_LINE_12
+ * @arg @ref LL_EXTI_LINE_13
+ * @arg @ref LL_EXTI_LINE_14
+ * @arg @ref LL_EXTI_LINE_15
+ * @arg @ref LL_EXTI_LINE_16
+ * @arg @ref LL_EXTI_LINE_17
+ * @arg @ref LL_EXTI_LINE_18
+ * @arg @ref LL_EXTI_LINE_19
+ * @arg @ref LL_EXTI_LINE_ALL_0_31
+ * @note Please check each device line mapping for EXTI Line availability
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_EXTI_IsEnabledEvent_0_31(uint32_t ExtiLine)
+{
+ return (READ_BIT(EXTI->EMR, ExtiLine) == (ExtiLine));
+
+}
+
+
+/**
+ * @}
+ */
+
+/** @defgroup EXTI_LL_EF_Rising_Trigger_Management Rising_Trigger_Management
+ * @{
+ */
+
+/**
+ * @brief Enable ExtiLine Rising Edge Trigger for Lines in range 0 to 31
+ * @note The configurable wakeup lines are edge-triggered. No glitch must be
+ * generated on these lines. If a rising edge on a configurable interrupt
+ * line occurs during a write operation in the EXTI_RTSR register, the
+ * pending bit is not set.
+ * Rising and falling edge triggers can be set for
+ * the same interrupt line. In this case, both generate a trigger
+ * condition.
+ * @rmtoll RTSR RTx LL_EXTI_EnableRisingTrig_0_31
+ * @param ExtiLine This parameter can be a combination of the following values:
+ * @arg @ref LL_EXTI_LINE_0
+ * @arg @ref LL_EXTI_LINE_1
+ * @arg @ref LL_EXTI_LINE_2
+ * @arg @ref LL_EXTI_LINE_3
+ * @arg @ref LL_EXTI_LINE_4
+ * @arg @ref LL_EXTI_LINE_5
+ * @arg @ref LL_EXTI_LINE_6
+ * @arg @ref LL_EXTI_LINE_7
+ * @arg @ref LL_EXTI_LINE_8
+ * @arg @ref LL_EXTI_LINE_9
+ * @arg @ref LL_EXTI_LINE_10
+ * @arg @ref LL_EXTI_LINE_11
+ * @arg @ref LL_EXTI_LINE_12
+ * @arg @ref LL_EXTI_LINE_13
+ * @arg @ref LL_EXTI_LINE_14
+ * @arg @ref LL_EXTI_LINE_15
+ * @arg @ref LL_EXTI_LINE_16
+ * @arg @ref LL_EXTI_LINE_18
+ * @arg @ref LL_EXTI_LINE_19
+ * @note Please check each device line mapping for EXTI Line availability
+ * @retval None
+ */
+__STATIC_INLINE void LL_EXTI_EnableRisingTrig_0_31(uint32_t ExtiLine)
+{
+ SET_BIT(EXTI->RTSR, ExtiLine);
+
+}
+
+
+/**
+ * @brief Disable ExtiLine Rising Edge Trigger for Lines in range 0 to 31
+ * @note The configurable wakeup lines are edge-triggered. No glitch must be
+ * generated on these lines. If a rising edge on a configurable interrupt
+ * line occurs during a write operation in the EXTI_RTSR register, the
+ * pending bit is not set.
+ * Rising and falling edge triggers can be set for
+ * the same interrupt line. In this case, both generate a trigger
+ * condition.
+ * @rmtoll RTSR RTx LL_EXTI_DisableRisingTrig_0_31
+ * @param ExtiLine This parameter can be a combination of the following values:
+ * @arg @ref LL_EXTI_LINE_0
+ * @arg @ref LL_EXTI_LINE_1
+ * @arg @ref LL_EXTI_LINE_2
+ * @arg @ref LL_EXTI_LINE_3
+ * @arg @ref LL_EXTI_LINE_4
+ * @arg @ref LL_EXTI_LINE_5
+ * @arg @ref LL_EXTI_LINE_6
+ * @arg @ref LL_EXTI_LINE_7
+ * @arg @ref LL_EXTI_LINE_8
+ * @arg @ref LL_EXTI_LINE_9
+ * @arg @ref LL_EXTI_LINE_10
+ * @arg @ref LL_EXTI_LINE_11
+ * @arg @ref LL_EXTI_LINE_12
+ * @arg @ref LL_EXTI_LINE_13
+ * @arg @ref LL_EXTI_LINE_14
+ * @arg @ref LL_EXTI_LINE_15
+ * @arg @ref LL_EXTI_LINE_16
+ * @arg @ref LL_EXTI_LINE_18
+ * @arg @ref LL_EXTI_LINE_19
+ * @note Please check each device line mapping for EXTI Line availability
+ * @retval None
+ */
+__STATIC_INLINE void LL_EXTI_DisableRisingTrig_0_31(uint32_t ExtiLine)
+{
+ CLEAR_BIT(EXTI->RTSR, ExtiLine);
+
+}
+
+
+/**
+ * @brief Check if rising edge trigger is enabled for Lines in range 0 to 31
+ * @rmtoll RTSR RTx LL_EXTI_IsEnabledRisingTrig_0_31
+ * @param ExtiLine This parameter can be a combination of the following values:
+ * @arg @ref LL_EXTI_LINE_0
+ * @arg @ref LL_EXTI_LINE_1
+ * @arg @ref LL_EXTI_LINE_2
+ * @arg @ref LL_EXTI_LINE_3
+ * @arg @ref LL_EXTI_LINE_4
+ * @arg @ref LL_EXTI_LINE_5
+ * @arg @ref LL_EXTI_LINE_6
+ * @arg @ref LL_EXTI_LINE_7
+ * @arg @ref LL_EXTI_LINE_8
+ * @arg @ref LL_EXTI_LINE_9
+ * @arg @ref LL_EXTI_LINE_10
+ * @arg @ref LL_EXTI_LINE_11
+ * @arg @ref LL_EXTI_LINE_12
+ * @arg @ref LL_EXTI_LINE_13
+ * @arg @ref LL_EXTI_LINE_14
+ * @arg @ref LL_EXTI_LINE_15
+ * @arg @ref LL_EXTI_LINE_16
+ * @arg @ref LL_EXTI_LINE_18
+ * @arg @ref LL_EXTI_LINE_19
+ * @note Please check each device line mapping for EXTI Line availability
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_EXTI_IsEnabledRisingTrig_0_31(uint32_t ExtiLine)
+{
+ return (READ_BIT(EXTI->RTSR, ExtiLine) == (ExtiLine));
+}
+
+
+/**
+ * @}
+ */
+
+/** @defgroup EXTI_LL_EF_Falling_Trigger_Management Falling_Trigger_Management
+ * @{
+ */
+
+/**
+ * @brief Enable ExtiLine Falling Edge Trigger for Lines in range 0 to 31
+ * @note The configurable wakeup lines are edge-triggered. No glitch must be
+ * generated on these lines. If a falling edge on a configurable interrupt
+ * line occurs during a write operation in the EXTI_FTSR register, the
+ * pending bit is not set.
+ * Rising and falling edge triggers can be set for
+ * the same interrupt line. In this case, both generate a trigger
+ * condition.
+ * @rmtoll FTSR FTx LL_EXTI_EnableFallingTrig_0_31
+ * @param ExtiLine This parameter can be a combination of the following values:
+ * @arg @ref LL_EXTI_LINE_0
+ * @arg @ref LL_EXTI_LINE_1
+ * @arg @ref LL_EXTI_LINE_2
+ * @arg @ref LL_EXTI_LINE_3
+ * @arg @ref LL_EXTI_LINE_4
+ * @arg @ref LL_EXTI_LINE_5
+ * @arg @ref LL_EXTI_LINE_6
+ * @arg @ref LL_EXTI_LINE_7
+ * @arg @ref LL_EXTI_LINE_8
+ * @arg @ref LL_EXTI_LINE_9
+ * @arg @ref LL_EXTI_LINE_10
+ * @arg @ref LL_EXTI_LINE_11
+ * @arg @ref LL_EXTI_LINE_12
+ * @arg @ref LL_EXTI_LINE_13
+ * @arg @ref LL_EXTI_LINE_14
+ * @arg @ref LL_EXTI_LINE_15
+ * @arg @ref LL_EXTI_LINE_16
+ * @arg @ref LL_EXTI_LINE_18
+ * @arg @ref LL_EXTI_LINE_19
+ * @note Please check each device line mapping for EXTI Line availability
+ * @retval None
+ */
+__STATIC_INLINE void LL_EXTI_EnableFallingTrig_0_31(uint32_t ExtiLine)
+{
+ SET_BIT(EXTI->FTSR, ExtiLine);
+}
+
+
+/**
+ * @brief Disable ExtiLine Falling Edge Trigger for Lines in range 0 to 31
+ * @note The configurable wakeup lines are edge-triggered. No glitch must be
+ * generated on these lines. If a Falling edge on a configurable interrupt
+ * line occurs during a write operation in the EXTI_FTSR register, the
+ * pending bit is not set.
+ * Rising and falling edge triggers can be set for the same interrupt line.
+ * In this case, both generate a trigger condition.
+ * @rmtoll FTSR FTx LL_EXTI_DisableFallingTrig_0_31
+ * @param ExtiLine This parameter can be a combination of the following values:
+ * @arg @ref LL_EXTI_LINE_0
+ * @arg @ref LL_EXTI_LINE_1
+ * @arg @ref LL_EXTI_LINE_2
+ * @arg @ref LL_EXTI_LINE_3
+ * @arg @ref LL_EXTI_LINE_4
+ * @arg @ref LL_EXTI_LINE_5
+ * @arg @ref LL_EXTI_LINE_6
+ * @arg @ref LL_EXTI_LINE_7
+ * @arg @ref LL_EXTI_LINE_8
+ * @arg @ref LL_EXTI_LINE_9
+ * @arg @ref LL_EXTI_LINE_10
+ * @arg @ref LL_EXTI_LINE_11
+ * @arg @ref LL_EXTI_LINE_12
+ * @arg @ref LL_EXTI_LINE_13
+ * @arg @ref LL_EXTI_LINE_14
+ * @arg @ref LL_EXTI_LINE_15
+ * @arg @ref LL_EXTI_LINE_16
+ * @arg @ref LL_EXTI_LINE_18
+ * @arg @ref LL_EXTI_LINE_19
+ * @note Please check each device line mapping for EXTI Line availability
+ * @retval None
+ */
+__STATIC_INLINE void LL_EXTI_DisableFallingTrig_0_31(uint32_t ExtiLine)
+{
+ CLEAR_BIT(EXTI->FTSR, ExtiLine);
+}
+
+
+/**
+ * @brief Check if falling edge trigger is enabled for Lines in range 0 to 31
+ * @rmtoll FTSR FTx LL_EXTI_IsEnabledFallingTrig_0_31
+ * @param ExtiLine This parameter can be a combination of the following values:
+ * @arg @ref LL_EXTI_LINE_0
+ * @arg @ref LL_EXTI_LINE_1
+ * @arg @ref LL_EXTI_LINE_2
+ * @arg @ref LL_EXTI_LINE_3
+ * @arg @ref LL_EXTI_LINE_4
+ * @arg @ref LL_EXTI_LINE_5
+ * @arg @ref LL_EXTI_LINE_6
+ * @arg @ref LL_EXTI_LINE_7
+ * @arg @ref LL_EXTI_LINE_8
+ * @arg @ref LL_EXTI_LINE_9
+ * @arg @ref LL_EXTI_LINE_10
+ * @arg @ref LL_EXTI_LINE_11
+ * @arg @ref LL_EXTI_LINE_12
+ * @arg @ref LL_EXTI_LINE_13
+ * @arg @ref LL_EXTI_LINE_14
+ * @arg @ref LL_EXTI_LINE_15
+ * @arg @ref LL_EXTI_LINE_16
+ * @arg @ref LL_EXTI_LINE_18
+ * @arg @ref LL_EXTI_LINE_19
+ * @note Please check each device line mapping for EXTI Line availability
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_EXTI_IsEnabledFallingTrig_0_31(uint32_t ExtiLine)
+{
+ return (READ_BIT(EXTI->FTSR, ExtiLine) == (ExtiLine));
+}
+
+
+/**
+ * @}
+ */
+
+/** @defgroup EXTI_LL_EF_Software_Interrupt_Management Software_Interrupt_Management
+ * @{
+ */
+
+/**
+ * @brief Generate a software Interrupt Event for Lines in range 0 to 31
+ * @note If the interrupt is enabled on this line in the EXTI_IMR, writing a 1 to
+ * this bit when it is at '0' sets the corresponding pending bit in EXTI_PR
+ * resulting in an interrupt request generation.
+ * This bit is cleared by clearing the corresponding bit in the EXTI_PR
+ * register (by writing a 1 into the bit)
+ * @rmtoll SWIER SWIx LL_EXTI_GenerateSWI_0_31
+ * @param ExtiLine This parameter can be a combination of the following values:
+ * @arg @ref LL_EXTI_LINE_0
+ * @arg @ref LL_EXTI_LINE_1
+ * @arg @ref LL_EXTI_LINE_2
+ * @arg @ref LL_EXTI_LINE_3
+ * @arg @ref LL_EXTI_LINE_4
+ * @arg @ref LL_EXTI_LINE_5
+ * @arg @ref LL_EXTI_LINE_6
+ * @arg @ref LL_EXTI_LINE_7
+ * @arg @ref LL_EXTI_LINE_8
+ * @arg @ref LL_EXTI_LINE_9
+ * @arg @ref LL_EXTI_LINE_10
+ * @arg @ref LL_EXTI_LINE_11
+ * @arg @ref LL_EXTI_LINE_12
+ * @arg @ref LL_EXTI_LINE_13
+ * @arg @ref LL_EXTI_LINE_14
+ * @arg @ref LL_EXTI_LINE_15
+ * @arg @ref LL_EXTI_LINE_16
+ * @arg @ref LL_EXTI_LINE_18
+ * @arg @ref LL_EXTI_LINE_19
+ * @note Please check each device line mapping for EXTI Line availability
+ * @retval None
+ */
+__STATIC_INLINE void LL_EXTI_GenerateSWI_0_31(uint32_t ExtiLine)
+{
+ SET_BIT(EXTI->SWIER, ExtiLine);
+}
+
+
+/**
+ * @}
+ */
+
+/** @defgroup EXTI_LL_EF_Flag_Management Flag_Management
+ * @{
+ */
+
+/**
+ * @brief Check if the ExtLine Flag is set or not for Lines in range 0 to 31
+ * @note This bit is set when the selected edge event arrives on the interrupt
+ * line. This bit is cleared by writing a 1 to the bit.
+ * @rmtoll PR PIFx LL_EXTI_IsActiveFlag_0_31
+ * @param ExtiLine This parameter can be a combination of the following values:
+ * @arg @ref LL_EXTI_LINE_0
+ * @arg @ref LL_EXTI_LINE_1
+ * @arg @ref LL_EXTI_LINE_2
+ * @arg @ref LL_EXTI_LINE_3
+ * @arg @ref LL_EXTI_LINE_4
+ * @arg @ref LL_EXTI_LINE_5
+ * @arg @ref LL_EXTI_LINE_6
+ * @arg @ref LL_EXTI_LINE_7
+ * @arg @ref LL_EXTI_LINE_8
+ * @arg @ref LL_EXTI_LINE_9
+ * @arg @ref LL_EXTI_LINE_10
+ * @arg @ref LL_EXTI_LINE_11
+ * @arg @ref LL_EXTI_LINE_12
+ * @arg @ref LL_EXTI_LINE_13
+ * @arg @ref LL_EXTI_LINE_14
+ * @arg @ref LL_EXTI_LINE_15
+ * @arg @ref LL_EXTI_LINE_16
+ * @arg @ref LL_EXTI_LINE_18
+ * @arg @ref LL_EXTI_LINE_19
+ * @note Please check each device line mapping for EXTI Line availability
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_EXTI_IsActiveFlag_0_31(uint32_t ExtiLine)
+{
+ return (READ_BIT(EXTI->PR, ExtiLine) == (ExtiLine));
+}
+
+
+/**
+ * @brief Read ExtLine Combination Flag for Lines in range 0 to 31
+ * @note This bit is set when the selected edge event arrives on the interrupt
+ * line. This bit is cleared by writing a 1 to the bit.
+ * @rmtoll PR PIFx LL_EXTI_ReadFlag_0_31
+ * @param ExtiLine This parameter can be a combination of the following values:
+ * @arg @ref LL_EXTI_LINE_0
+ * @arg @ref LL_EXTI_LINE_1
+ * @arg @ref LL_EXTI_LINE_2
+ * @arg @ref LL_EXTI_LINE_3
+ * @arg @ref LL_EXTI_LINE_4
+ * @arg @ref LL_EXTI_LINE_5
+ * @arg @ref LL_EXTI_LINE_6
+ * @arg @ref LL_EXTI_LINE_7
+ * @arg @ref LL_EXTI_LINE_8
+ * @arg @ref LL_EXTI_LINE_9
+ * @arg @ref LL_EXTI_LINE_10
+ * @arg @ref LL_EXTI_LINE_11
+ * @arg @ref LL_EXTI_LINE_12
+ * @arg @ref LL_EXTI_LINE_13
+ * @arg @ref LL_EXTI_LINE_14
+ * @arg @ref LL_EXTI_LINE_15
+ * @arg @ref LL_EXTI_LINE_16
+ * @arg @ref LL_EXTI_LINE_18
+ * @arg @ref LL_EXTI_LINE_19
+ * @note Please check each device line mapping for EXTI Line availability
+ * @retval @note This bit is set when the selected edge event arrives on the interrupt
+ */
+__STATIC_INLINE uint32_t LL_EXTI_ReadFlag_0_31(uint32_t ExtiLine)
+{
+ return (uint32_t)(READ_BIT(EXTI->PR, ExtiLine));
+}
+
+
+/**
+ * @brief Clear ExtLine Flags for Lines in range 0 to 31
+ * @note This bit is set when the selected edge event arrives on the interrupt
+ * line. This bit is cleared by writing a 1 to the bit.
+ * @rmtoll PR PIFx LL_EXTI_ClearFlag_0_31
+ * @param ExtiLine This parameter can be a combination of the following values:
+ * @arg @ref LL_EXTI_LINE_0
+ * @arg @ref LL_EXTI_LINE_1
+ * @arg @ref LL_EXTI_LINE_2
+ * @arg @ref LL_EXTI_LINE_3
+ * @arg @ref LL_EXTI_LINE_4
+ * @arg @ref LL_EXTI_LINE_5
+ * @arg @ref LL_EXTI_LINE_6
+ * @arg @ref LL_EXTI_LINE_7
+ * @arg @ref LL_EXTI_LINE_8
+ * @arg @ref LL_EXTI_LINE_9
+ * @arg @ref LL_EXTI_LINE_10
+ * @arg @ref LL_EXTI_LINE_11
+ * @arg @ref LL_EXTI_LINE_12
+ * @arg @ref LL_EXTI_LINE_13
+ * @arg @ref LL_EXTI_LINE_14
+ * @arg @ref LL_EXTI_LINE_15
+ * @arg @ref LL_EXTI_LINE_16
+ * @arg @ref LL_EXTI_LINE_18
+ * @arg @ref LL_EXTI_LINE_19
+ * @note Please check each device line mapping for EXTI Line availability
+ * @retval None
+ */
+__STATIC_INLINE void LL_EXTI_ClearFlag_0_31(uint32_t ExtiLine)
+{
+ WRITE_REG(EXTI->PR, ExtiLine);
+}
+
+
+/**
+ * @}
+ */
+
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup EXTI_LL_EF_Init Initialization and de-initialization functions
+ * @{
+ */
+
+uint32_t LL_EXTI_Init(LL_EXTI_InitTypeDef *EXTI_InitStruct);
+uint32_t LL_EXTI_DeInit(void);
+void LL_EXTI_StructInit(LL_EXTI_InitTypeDef *EXTI_InitStruct);
+
+
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* EXTI */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_LL_EXTI_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_fsmc.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_fsmc.h
new file mode 100644
index 0000000..2db50da
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_fsmc.h
@@ -0,0 +1,1079 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_fsmc.h
+ * @author MCD Application Team
+ * @brief Header file of FSMC HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_FSMC_H
+#define __STM32F1xx_LL_FSMC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#if defined(FSMC_BANK1)
+
+/** @addtogroup FSMC_LL
+ * @{
+ */
+
+
+/* Exported typedef ----------------------------------------------------------*/
+
+/** @defgroup FSMC_NORSRAM_Exported_typedef FSMC Low Layer Exported Types
+ * @{
+ */
+
+/**
+ * @brief FSMC NORSRAM Configuration Structure definition
+ */
+typedef struct
+{
+ uint32_t NSBank; /*!< Specifies the NORSRAM memory device that will be used.
+ This parameter can be a value of @ref FSMC_NORSRAM_Bank */
+
+ uint32_t DataAddressMux; /*!< Specifies whether the address and data values are
+ multiplexed on the data bus or not.
+ This parameter can be a value of @ref FSMC_Data_Address_Bus_Multiplexing */
+
+ uint32_t MemoryType; /*!< Specifies the type of external memory attached to
+ the corresponding memory device.
+ This parameter can be a value of @ref FSMC_Memory_Type */
+
+ uint32_t MemoryDataWidth; /*!< Specifies the external memory device width.
+ This parameter can be a value of @ref FSMC_NORSRAM_Data_Width */
+
+ uint32_t 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 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 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 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 WriteOperation; /*!< Enables or disables the write operation in the selected device by the FSMC.
+ This parameter can be a value of @ref FSMC_Write_Operation */
+
+ uint32_t 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 ExtendedMode; /*!< Enables or disables the extended mode.
+ This parameter can be a value of @ref FSMC_Extended_Mode */
+
+ uint32_t 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 WriteBurst; /*!< Enables or disables the write burst operation.
+ This parameter can be a value of @ref FSMC_Write_Burst */
+
+}FSMC_NORSRAM_InitTypeDef;
+
+/**
+ * @brief FSMC NORSRAM Timing parameters structure definition
+ */
+typedef struct
+{
+ uint32_t AddressSetupTime; /*!< Defines the number of HCLK cycles to configure
+ the duration of the address setup time.
+ This parameter can be a value between Min_Data = 0 and Max_Data = 15.
+ @note This parameter is not used with synchronous NOR Flash memories. */
+
+ uint32_t AddressHoldTime; /*!< Defines the number of HCLK cycles to configure
+ the duration of the address hold time.
+ This parameter can be a value between Min_Data = 1 and Max_Data = 15.
+ @note This parameter is not used with synchronous NOR Flash memories. */
+
+ uint32_t DataSetupTime; /*!< Defines the number of HCLK cycles to configure
+ the duration of the data setup time.
+ This parameter can be a value between Min_Data = 1 and Max_Data = 255.
+ @note This parameter is used for SRAMs, ROMs and asynchronous multiplexed
+ NOR Flash memories. */
+
+ uint32_t BusTurnAroundDuration; /*!< Defines the number of HCLK cycles to configure
+ the duration of the bus turnaround.
+ This parameter can be a value between Min_Data = 0 and Max_Data = 15.
+ @note This parameter is only used for multiplexed NOR Flash memories. */
+
+ uint32_t CLKDivision; /*!< Defines the period of CLK clock output signal, expressed in number of
+ HCLK cycles. This parameter can be a value between Min_Data = 2 and Max_Data = 16.
+ @note This parameter is not used for asynchronous NOR Flash, SRAM or ROM
+ accesses. */
+
+ uint32_t DataLatency; /*!< Defines the number of memory clock cycles to issue
+ to the memory before getting the first data.
+ The parameter value 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 Min_Data = 2 and Max_Data = 17 in NOR Flash memories
+ with synchronous burst mode enable */
+
+ uint32_t AccessMode; /*!< Specifies the asynchronous access mode.
+ This parameter can be a value of @ref FSMC_Access_Mode */
+
+}FSMC_NORSRAM_TimingTypeDef;
+
+#if (defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
+/**
+ * @brief FSMC NAND Configuration Structure definition
+ */
+typedef struct
+{
+ uint32_t NandBank; /*!< Specifies the NAND memory device that will be used.
+ This parameter can be a value of @ref FSMC_NAND_Bank */
+
+ uint32_t Waitfeature; /*!< Enables or disables the Wait feature for the NAND Memory device.
+ This parameter can be any value of @ref FSMC_Wait_feature */
+
+ uint32_t MemoryDataWidth; /*!< Specifies the external memory device width.
+ This parameter can be any value of @ref FSMC_NAND_Data_Width */
+
+ uint32_t EccComputation; /*!< Enables or disables the ECC computation.
+ This parameter can be any value of @ref FSMC_ECC */
+
+ uint32_t ECCPageSize; /*!< Defines the page size for the extended ECC.
+ This parameter can be any value of @ref FSMC_ECC_Page_Size */
+
+ uint32_t TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between CLE low and RE low.
+ This parameter can be a value between Min_Data = 0 and Max_Data = 255 */
+
+ uint32_t TARSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between ALE low and RE low.
+ This parameter can be a number between Min_Data = 0 and Max_Data = 255 */
+
+}FSMC_NAND_InitTypeDef;
+
+/**
+ * @brief FSMC NAND/PCCARD Timing parameters structure definition
+ */
+typedef struct
+{
+ uint32_t 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 Min_Data = 0 and Max_Data = 255 */
+
+ uint32_t 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 Min_Data = 0 and Max_Data = 255 */
+
+ uint32_t HoldSetupTime; /*!< Defines the number of HCLK clock cycles to hold address
+ (and data for write access) after the command de-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 number between Min_Data = 0 and Max_Data = 255 */
+
+ uint32_t HiZSetupTime; /*!< Defines the number of HCLK clock cycles during which the
+ data bus 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 Min_Data = 0 and Max_Data = 255 */
+
+}FSMC_NAND_PCC_TimingTypeDef;
+
+/**
+ * @brief FSMC NAND Configuration Structure definition
+ */
+typedef struct
+{
+ uint32_t Waitfeature; /*!< Enables or disables the Wait feature for the PCCARD Memory device.
+ This parameter can be any value of @ref FSMC_Wait_feature */
+
+ uint32_t TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between CLE low and RE low.
+ This parameter can be a value between Min_Data = 0 and Max_Data = 255 */
+
+ uint32_t TARSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between ALE low and RE low.
+ This parameter can be a number between Min_Data = 0 and Max_Data = 255 */
+
+}FSMC_PCCARD_InitTypeDef;
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup FSMC_Exported_Constants FSMC Low Layer Exported Constants
+ * @{
+ */
+
+/** @defgroup FSMC_NORSRAM_Exported_constants FSMC NOR/SRAM Exported constants
+ * @{
+ */
+/** @defgroup FSMC_NORSRAM_Bank FSMC NOR/SRAM Bank
+ * @{
+ */
+#define FSMC_NORSRAM_BANK1 0x00000000U
+#define FSMC_NORSRAM_BANK2 0x00000002U
+#define FSMC_NORSRAM_BANK3 0x00000004U
+#define FSMC_NORSRAM_BANK4 0x00000006U
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Data_Address_Bus_Multiplexing FSMC Data Address Bus Multiplexing
+ * @{
+ */
+#define FSMC_DATA_ADDRESS_MUX_DISABLE 0x00000000U
+#define FSMC_DATA_ADDRESS_MUX_ENABLE ((uint32_t)FSMC_BCRx_MUXEN)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Memory_Type FSMC Memory Type
+ * @{
+ */
+#define FSMC_MEMORY_TYPE_SRAM 0x00000000U
+#define FSMC_MEMORY_TYPE_PSRAM ((uint32_t)FSMC_BCRx_MTYP_0)
+#define FSMC_MEMORY_TYPE_NOR ((uint32_t)FSMC_BCRx_MTYP_1)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NORSRAM_Data_Width FSMC NOR/SRAM Data Width
+ * @{
+ */
+#define FSMC_NORSRAM_MEM_BUS_WIDTH_8 0x00000000U
+#define FSMC_NORSRAM_MEM_BUS_WIDTH_16 ((uint32_t)FSMC_BCRx_MWID_0)
+#define FSMC_NORSRAM_MEM_BUS_WIDTH_32 ((uint32_t)FSMC_BCRx_MWID_1)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NORSRAM_Flash_Access FSMC NOR/SRAM Flash Access
+ * @{
+ */
+#define FSMC_NORSRAM_FLASH_ACCESS_ENABLE ((uint32_t)FSMC_BCRx_FACCEN)
+#define FSMC_NORSRAM_FLASH_ACCESS_DISABLE 0x00000000U
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Burst_Access_Mode FSMC Burst Access Mode
+ * @{
+ */
+#define FSMC_BURST_ACCESS_MODE_DISABLE 0x00000000U
+#define FSMC_BURST_ACCESS_MODE_ENABLE ((uint32_t)FSMC_BCRx_BURSTEN)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_Signal_Polarity FSMC Wait Signal Polarity
+ * @{
+ */
+#define FSMC_WAIT_SIGNAL_POLARITY_LOW 0x00000000U
+#define FSMC_WAIT_SIGNAL_POLARITY_HIGH ((uint32_t)FSMC_BCRx_WAITPOL)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wrap_Mode FSMC Wrap Mode
+ * @{
+ */
+#define FSMC_WRAP_MODE_DISABLE 0x00000000U
+#define FSMC_WRAP_MODE_ENABLE ((uint32_t)FSMC_BCRx_WRAPMOD)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_Timing FSMC Wait Timing
+ * @{
+ */
+#define FSMC_WAIT_TIMING_BEFORE_WS 0x00000000U
+#define FSMC_WAIT_TIMING_DURING_WS ((uint32_t)FSMC_BCRx_WAITCFG)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Write_Operation FSMC Write Operation
+ * @{
+ */
+#define FSMC_WRITE_OPERATION_DISABLE 0x00000000U
+#define FSMC_WRITE_OPERATION_ENABLE ((uint32_t)FSMC_BCRx_WREN)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_Signal FSMC Wait Signal
+ * @{
+ */
+#define FSMC_WAIT_SIGNAL_DISABLE 0x00000000U
+#define FSMC_WAIT_SIGNAL_ENABLE ((uint32_t)FSMC_BCRx_WAITEN)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Extended_Mode FSMC Extended Mode
+ * @{
+ */
+#define FSMC_EXTENDED_MODE_DISABLE 0x00000000U
+#define FSMC_EXTENDED_MODE_ENABLE ((uint32_t)FSMC_BCRx_EXTMOD)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_AsynchronousWait FSMC Asynchronous Wait
+ * @{
+ */
+#define FSMC_ASYNCHRONOUS_WAIT_DISABLE 0x00000000U
+#define FSMC_ASYNCHRONOUS_WAIT_ENABLE ((uint32_t)FSMC_BCRx_ASYNCWAIT)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Write_Burst FSMC Write Burst
+ * @{
+ */
+#define FSMC_WRITE_BURST_DISABLE 0x00000000U
+#define FSMC_WRITE_BURST_ENABLE ((uint32_t)FSMC_BCRx_CBURSTRW)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Access_Mode FSMC Access Mode
+ * @{
+ */
+#define FSMC_ACCESS_MODE_A 0x00000000U
+#define FSMC_ACCESS_MODE_B ((uint32_t)FSMC_BTRx_ACCMOD_0)
+#define FSMC_ACCESS_MODE_C ((uint32_t)FSMC_BTRx_ACCMOD_1)
+#define FSMC_ACCESS_MODE_D ((uint32_t)(FSMC_BTRx_ACCMOD_0 | FSMC_BTRx_ACCMOD_1))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#if (defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
+/** @defgroup FSMC_NAND_Controller FSMC NAND and PCCARD Controller
+ * @{
+ */
+/** @defgroup FSMC_NAND_Bank FSMC NAND Bank
+ * @{
+ */
+#define FSMC_NAND_BANK2 0x00000010U
+#define FSMC_NAND_BANK3 0x00000100U
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_feature FSMC Wait feature
+ * @{
+ */
+#define FSMC_NAND_PCC_WAIT_FEATURE_DISABLE 0x00000000U
+#define FSMC_NAND_PCC_WAIT_FEATURE_ENABLE ((uint32_t)FSMC_PCRx_PWAITEN)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_PCR_Memory_Type FSMC PCR Memory Type
+ * @{
+ */
+#define FSMC_PCR_MEMORY_TYPE_PCCARD 0x00000000U
+#define FSMC_PCR_MEMORY_TYPE_NAND ((uint32_t)FSMC_PCRx_PTYP)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NAND_Data_Width FSMC NAND Data Width
+ * @{
+ */
+#define FSMC_NAND_PCC_MEM_BUS_WIDTH_8 0x00000000U
+#define FSMC_NAND_PCC_MEM_BUS_WIDTH_16 ((uint32_t)FSMC_PCRx_PWID_0)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_ECC FSMC NAND ECC
+ * @{
+ */
+#define FSMC_NAND_ECC_DISABLE 0x00000000U
+#define FSMC_NAND_ECC_ENABLE ((uint32_t)FSMC_PCRx_ECCEN)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_ECC_Page_Size FSMC ECC Page Size
+ * @{
+ */
+#define FSMC_NAND_ECC_PAGE_SIZE_256BYTE 0x00000000U
+#define FSMC_NAND_ECC_PAGE_SIZE_512BYTE ((uint32_t)FSMC_PCRx_ECCPS_0)
+#define FSMC_NAND_ECC_PAGE_SIZE_1024BYTE ((uint32_t)FSMC_PCRx_ECCPS_1)
+#define FSMC_NAND_ECC_PAGE_SIZE_2048BYTE ((uint32_t)FSMC_PCRx_ECCPS_0|FSMC_PCRx_ECCPS_1)
+#define FSMC_NAND_ECC_PAGE_SIZE_4096BYTE ((uint32_t)FSMC_PCRx_ECCPS_2)
+#define FSMC_NAND_ECC_PAGE_SIZE_8192BYTE ((uint32_t)FSMC_PCRx_ECCPS_0|FSMC_PCRx_ECCPS_2)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+
+/** @defgroup FSMC_LL_Interrupt_definition FSMC Interrupt definition
+ * @brief FSMC Interrupt definition
+ * @{
+ */
+#define FSMC_IT_RISING_EDGE ((uint32_t)FSMC_SRx_IREN)
+#define FSMC_IT_LEVEL ((uint32_t)FSMC_SRx_ILEN)
+#define FSMC_IT_FALLING_EDGE ((uint32_t)FSMC_SRx_IFEN)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_LL_Flag_definition FSMC Flag definition
+ * @brief FSMC Flag definition
+ * @{
+ */
+#define FSMC_FLAG_RISING_EDGE ((uint32_t)FSMC_SRx_IRS)
+#define FSMC_FLAG_LEVEL ((uint32_t)FSMC_SRx_ILS)
+#define FSMC_FLAG_FALLING_EDGE ((uint32_t)FSMC_SRx_IFS)
+#define FSMC_FLAG_FEMPT ((uint32_t)FSMC_SRx_FEMPT)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_LL_Alias_definition FSMC Alias definition
+ * @{
+ */
+#define FSMC_NORSRAM_TypeDef FSMC_Bank1_TypeDef
+#define FSMC_NORSRAM_EXTENDED_TypeDef FSMC_Bank1E_TypeDef
+#define FSMC_NAND_TypeDef FSMC_Bank2_3_TypeDef
+#define FSMC_PCCARD_TypeDef FSMC_Bank4_TypeDef
+
+#define FSMC_NORSRAM_DEVICE FSMC_Bank1
+#define FSMC_NORSRAM_EXTENDED_DEVICE FSMC_Bank1E
+#define FSMC_NAND_DEVICE FSMC_Bank2_3
+#define FSMC_PCCARD_DEVICE FSMC_Bank4
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup FSMC_Exported_Macros FSMC Low Layer Exported Macros
+ * @{
+ */
+
+/** @defgroup FSMC_LL_NOR_Macros FSMC NOR/SRAM Exported Macros
+ * @brief macros to handle NOR device enable/disable and read/write operations
+ * @{
+ */
+
+/**
+ * @brief Enable the NORSRAM device access.
+ * @param __INSTANCE__: FSMC_NORSRAM Instance
+ * @param __BANK__: FSMC_NORSRAM Bank
+ * @retval none
+ */
+#define __FSMC_NORSRAM_ENABLE(__INSTANCE__, __BANK__) SET_BIT((__INSTANCE__)->BTCR[(__BANK__)], FSMC_BCRx_MBKEN)
+
+/**
+ * @brief Disable the NORSRAM device access.
+ * @param __INSTANCE__: FSMC_NORSRAM Instance
+ * @param __BANK__: FSMC_NORSRAM Bank
+ * @retval none
+ */
+#define __FSMC_NORSRAM_DISABLE(__INSTANCE__, __BANK__) CLEAR_BIT((__INSTANCE__)->BTCR[(__BANK__)], FSMC_BCRx_MBKEN)
+
+/**
+ * @}
+ */
+
+#if (defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
+/** @defgroup FSMC_LL_NAND_Macros FSMC NAND Macros
+ * @brief macros to handle NAND device enable/disable
+ * @{
+ */
+
+/**
+ * @brief Enable the NAND device access.
+ * @param __INSTANCE__: FSMC_NAND Instance
+ * @param __BANK__: FSMC_NAND Bank
+ * @retval None
+ */
+#define __FSMC_NAND_ENABLE(__INSTANCE__, __BANK__) (((__BANK__) == FSMC_NAND_BANK2)? SET_BIT((__INSTANCE__)->PCR2, FSMC_PCRx_PBKEN): \
+ SET_BIT((__INSTANCE__)->PCR3, FSMC_PCRx_PBKEN))
+
+/**
+ * @brief Disable the NAND device access.
+ * @param __INSTANCE__: FSMC_NAND Instance
+ * @param __BANK__: FSMC_NAND Bank
+ * @retval None
+ */
+#define __FSMC_NAND_DISABLE(__INSTANCE__, __BANK__) (((__BANK__) == FSMC_NAND_BANK2)? CLEAR_BIT((__INSTANCE__)->PCR2, FSMC_PCRx_PBKEN): \
+ CLEAR_BIT((__INSTANCE__)->PCR3, FSMC_PCRx_PBKEN))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_LL_PCCARD_Macros FSMC PCCARD Macros
+ * @brief macros to handle PCCARD read/write operations
+ * @{
+ */
+/**
+ * @brief Enable the PCCARD device access.
+ * @param __INSTANCE__: FSMC_PCCARD Instance
+ * @retval None
+ */
+#define __FSMC_PCCARD_ENABLE(__INSTANCE__) SET_BIT((__INSTANCE__)->PCR4, FSMC_PCRx_PBKEN)
+
+/**
+ * @brief Disable the PCCARD device access.
+ * @param __INSTANCE__: FSMC_PCCARD Instance
+ * @retval None
+ */
+#define __FSMC_PCCARD_DISABLE(__INSTANCE__) CLEAR_BIT((__INSTANCE__)->PCR4, FSMC_PCRx_PBKEN)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_LL_Flag_Interrupt_Macros FSMC Flag&Interrupt Macros
+ * @brief macros to handle FSMC flags and interrupts
+ * @{
+ */
+
+/**
+ * @brief Enable the NAND device interrupt.
+ * @param __INSTANCE__: FSMC_NAND Instance
+ * @param __BANK__: FSMC_NAND Bank
+ * @param __INTERRUPT__: FSMC_NAND interrupt
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_IT_RISING_EDGE: Interrupt rising edge.
+ * @arg FSMC_IT_LEVEL: Interrupt level.
+ * @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge.
+ * @retval None
+ */
+#define __FSMC_NAND_ENABLE_IT(__INSTANCE__, __BANK__, __INTERRUPT__) (((__BANK__) == FSMC_NAND_BANK2)? SET_BIT((__INSTANCE__)->SR2, (__INTERRUPT__)): \
+ SET_BIT((__INSTANCE__)->SR3, (__INTERRUPT__)))
+
+/**
+ * @brief Disable the NAND device interrupt.
+ * @param __INSTANCE__: FSMC_NAND Instance
+ * @param __BANK__: FSMC_NAND Bank
+ * @param __INTERRUPT__: FSMC_NAND interrupt
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_IT_RISING_EDGE: Interrupt rising edge.
+ * @arg FSMC_IT_LEVEL: Interrupt level.
+ * @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge.
+ * @retval None
+ */
+#define __FSMC_NAND_DISABLE_IT(__INSTANCE__, __BANK__, __INTERRUPT__) (((__BANK__) == FSMC_NAND_BANK2)? CLEAR_BIT((__INSTANCE__)->SR2, (__INTERRUPT__)): \
+ CLEAR_BIT((__INSTANCE__)->SR3, (__INTERRUPT__)))
+
+/**
+ * @brief Get flag status of the NAND device.
+ * @param __INSTANCE__: FSMC_NAND Instance
+ * @param __BANK__ : FSMC_NAND Bank
+ * @param __FLAG__ : FSMC_NAND flag
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag.
+ * @arg FSMC_FLAG_LEVEL: Interrupt level edge flag.
+ * @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag.
+ * @arg FSMC_FLAG_FEMPT: FIFO empty flag.
+ * @retval The state of FLAG (SET or RESET).
+ */
+#define __FSMC_NAND_GET_FLAG(__INSTANCE__, __BANK__, __FLAG__) (((__BANK__) == FSMC_NAND_BANK2)? (((__INSTANCE__)->SR2 &(__FLAG__)) == (__FLAG__)): \
+ (((__INSTANCE__)->SR3 &(__FLAG__)) == (__FLAG__)))
+/**
+ * @brief Clear flag status of the NAND device.
+ * @param __INSTANCE__: FSMC_NAND Instance
+ * @param __BANK__: FSMC_NAND Bank
+ * @param __FLAG__: FSMC_NAND flag
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag.
+ * @arg FSMC_FLAG_LEVEL: Interrupt level edge flag.
+ * @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag.
+ * @arg FSMC_FLAG_FEMPT: FIFO empty flag.
+ * @retval None
+ */
+#define __FSMC_NAND_CLEAR_FLAG(__INSTANCE__, __BANK__, __FLAG__) (((__BANK__) == FSMC_NAND_BANK2)? CLEAR_BIT((__INSTANCE__)->SR2, (__FLAG__)): \
+ CLEAR_BIT((__INSTANCE__)->SR3, (__FLAG__)))
+
+/**
+ * @brief Enable the PCCARD device interrupt.
+ * @param __INSTANCE__: FSMC_PCCARD Instance
+ * @param __INTERRUPT__: FSMC_PCCARD interrupt
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_IT_RISING_EDGE: Interrupt rising edge.
+ * @arg FSMC_IT_LEVEL: Interrupt level.
+ * @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge.
+ * @retval None
+ */
+#define __FSMC_PCCARD_ENABLE_IT(__INSTANCE__, __INTERRUPT__) SET_BIT((__INSTANCE__)->SR4, (__INTERRUPT__))
+
+/**
+ * @brief Disable the PCCARD device interrupt.
+ * @param __INSTANCE__: FSMC_PCCARD Instance
+ * @param __INTERRUPT__: FSMC_PCCARD interrupt
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_IT_RISING_EDGE: Interrupt rising edge.
+ * @arg FSMC_IT_LEVEL: Interrupt level.
+ * @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge.
+ * @retval None
+ */
+#define __FSMC_PCCARD_DISABLE_IT(__INSTANCE__, __INTERRUPT__) CLEAR_BIT((__INSTANCE__)->SR4, (__INTERRUPT__))
+
+/**
+ * @brief Get flag status of the PCCARD device.
+ * @param __INSTANCE__: FSMC_PCCARD Instance
+ * @param __FLAG__: FSMC_PCCARD flag
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag.
+ * @arg FSMC_FLAG_LEVEL: Interrupt level edge flag.
+ * @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag.
+ * @arg FSMC_FLAG_FEMPT: FIFO empty flag.
+ * @retval The state of FLAG (SET or RESET).
+ */
+#define __FSMC_PCCARD_GET_FLAG(__INSTANCE__, __FLAG__) (((__INSTANCE__)->SR4 &(__FLAG__)) == (__FLAG__))
+
+/**
+ * @brief Clear flag status of the PCCARD device.
+ * @param __INSTANCE__: FSMC_PCCARD Instance
+ * @param __FLAG__: FSMC_PCCARD flag
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag.
+ * @arg FSMC_FLAG_LEVEL: Interrupt level edge flag.
+ * @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag.
+ * @arg FSMC_FLAG_FEMPT: FIFO empty flag.
+ * @retval None
+ */
+#define __FSMC_PCCARD_CLEAR_FLAG(__INSTANCE__, __FLAG__) CLEAR_BIT((__INSTANCE__)->SR4, (__FLAG__))
+
+/**
+ * @}
+ */
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_LL_Private_Macros FSMC Low Layer Private Macros
+ * @{
+ */
+#define IS_FSMC_NORSRAM_BANK(__BANK__) (((__BANK__) == FSMC_NORSRAM_BANK1) || \
+ ((__BANK__) == FSMC_NORSRAM_BANK2) || \
+ ((__BANK__) == FSMC_NORSRAM_BANK3) || \
+ ((__BANK__) == FSMC_NORSRAM_BANK4))
+
+#define IS_FSMC_MUX(__MUX__) (((__MUX__) == FSMC_DATA_ADDRESS_MUX_DISABLE) || \
+ ((__MUX__) == FSMC_DATA_ADDRESS_MUX_ENABLE))
+
+#define IS_FSMC_MEMORY(__MEMORY__) (((__MEMORY__) == FSMC_MEMORY_TYPE_SRAM) || \
+ ((__MEMORY__) == FSMC_MEMORY_TYPE_PSRAM)|| \
+ ((__MEMORY__) == FSMC_MEMORY_TYPE_NOR))
+
+#define IS_FSMC_NORSRAM_MEMORY_WIDTH(__WIDTH__) (((__WIDTH__) == FSMC_NORSRAM_MEM_BUS_WIDTH_8) || \
+ ((__WIDTH__) == FSMC_NORSRAM_MEM_BUS_WIDTH_16) || \
+ ((__WIDTH__) == FSMC_NORSRAM_MEM_BUS_WIDTH_32))
+
+#define IS_FSMC_WRITE_BURST(__BURST__) (((__BURST__) == FSMC_WRITE_BURST_DISABLE) || \
+ ((__BURST__) == FSMC_WRITE_BURST_ENABLE))
+
+#define IS_FSMC_ACCESS_MODE(__MODE__) (((__MODE__) == FSMC_ACCESS_MODE_A) || \
+ ((__MODE__) == FSMC_ACCESS_MODE_B) || \
+ ((__MODE__) == FSMC_ACCESS_MODE_C) || \
+ ((__MODE__) == FSMC_ACCESS_MODE_D))
+
+#define IS_FSMC_NAND_BANK(__BANK__) (((__BANK__) == FSMC_NAND_BANK2) || \
+ ((__BANK__) == FSMC_NAND_BANK3))
+
+#define IS_FSMC_WAIT_FEATURE(__FEATURE__) (((__FEATURE__) == FSMC_NAND_PCC_WAIT_FEATURE_DISABLE) || \
+ ((__FEATURE__) == FSMC_NAND_PCC_WAIT_FEATURE_ENABLE))
+
+#define IS_FSMC_NAND_MEMORY_WIDTH(__WIDTH__) (((__WIDTH__) == FSMC_NAND_PCC_MEM_BUS_WIDTH_8) || \
+ ((__WIDTH__) == FSMC_NAND_PCC_MEM_BUS_WIDTH_16))
+
+#define IS_FSMC_ECC_STATE(__STATE__) (((__STATE__) == FSMC_NAND_ECC_DISABLE) || \
+ ((__STATE__) == FSMC_NAND_ECC_ENABLE))
+
+#define IS_FSMC_ECCPAGE_SIZE(__SIZE__) (((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_256BYTE) || \
+ ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_512BYTE) || \
+ ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_1024BYTE) || \
+ ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_2048BYTE) || \
+ ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_4096BYTE) || \
+ ((__SIZE__) == FSMC_NAND_ECC_PAGE_SIZE_8192BYTE))
+
+/** @defgroup FSMC_TCLR_Setup_Time FSMC_TCLR_Setup_Time
+ * @{
+ */
+#define IS_FSMC_TCLR_TIME(__TIME__) ((__TIME__) <= 255U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_TAR_Setup_Time FSMC_TAR_Setup_Time
+ * @{
+ */
+#define IS_FSMC_TAR_TIME(__TIME__) ((__TIME__) <= 255U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Setup_Time FSMC_Setup_Time
+ * @{
+ */
+#define IS_FSMC_SETUP_TIME(__TIME__) ((__TIME__) <= 255U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_Setup_Time FSMC_Wait_Setup_Time
+ * @{
+ */
+#define IS_FSMC_WAIT_TIME(__TIME__) ((__TIME__) <= 255U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Hold_Setup_Time FSMC_Hold_Setup_Time
+ * @{
+ */
+#define IS_FSMC_HOLD_TIME(__TIME__) ((__TIME__) <= 255U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_HiZ_Setup_Time FSMC_HiZ_Setup_Time
+ * @{
+ */
+#define IS_FSMC_HIZ_TIME(__TIME__) ((__TIME__) <= 255U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NORSRAM_Device_Instance FSMC NOR/SRAM Device Instance
+ * @{
+ */
+#define IS_FSMC_NORSRAM_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_NORSRAM_DEVICE)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NORSRAM_EXTENDED_Device_Instance FSMC NOR/SRAM EXTENDED Device Instance
+ * @{
+ */
+#define IS_FSMC_NORSRAM_EXTENDED_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_NORSRAM_EXTENDED_DEVICE)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NAND_Device_Instance FSMC NAND Device Instance
+ * @{
+ */
+#define IS_FSMC_NAND_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_NAND_DEVICE)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_PCCARD_Device_Instance FSMC PCCARD Device Instance
+ * @{
+ */
+#define IS_FSMC_PCCARD_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_PCCARD_DEVICE)
+
+/**
+ * @}
+ */
+#define IS_FSMC_BURSTMODE(__STATE__) (((__STATE__) == FSMC_BURST_ACCESS_MODE_DISABLE) || \
+ ((__STATE__) == FSMC_BURST_ACCESS_MODE_ENABLE))
+
+#define IS_FSMC_WAIT_POLARITY(__POLARITY__) (((__POLARITY__) == FSMC_WAIT_SIGNAL_POLARITY_LOW) || \
+ ((__POLARITY__) == FSMC_WAIT_SIGNAL_POLARITY_HIGH))
+
+#define IS_FSMC_WRAP_MODE(__MODE__) (((__MODE__) == FSMC_WRAP_MODE_DISABLE) || \
+ ((__MODE__) == FSMC_WRAP_MODE_ENABLE))
+
+#define IS_FSMC_WAIT_SIGNAL_ACTIVE(__ACTIVE__) (((__ACTIVE__) == FSMC_WAIT_TIMING_BEFORE_WS) || \
+ ((__ACTIVE__) == FSMC_WAIT_TIMING_DURING_WS))
+
+#define IS_FSMC_WRITE_OPERATION(__OPERATION__) (((__OPERATION__) == FSMC_WRITE_OPERATION_DISABLE) || \
+ ((__OPERATION__) == FSMC_WRITE_OPERATION_ENABLE))
+
+#define IS_FSMC_WAITE_SIGNAL(__SIGNAL__) (((__SIGNAL__) == FSMC_WAIT_SIGNAL_DISABLE) || \
+ ((__SIGNAL__) == FSMC_WAIT_SIGNAL_ENABLE))
+
+#define IS_FSMC_EXTENDED_MODE(__MODE__) (((__MODE__) == FSMC_EXTENDED_MODE_DISABLE) || \
+ ((__MODE__) == FSMC_EXTENDED_MODE_ENABLE))
+
+#define IS_FSMC_ASYNWAIT(__STATE__) (((__STATE__) == FSMC_ASYNCHRONOUS_WAIT_DISABLE) || \
+ ((__STATE__) == FSMC_ASYNCHRONOUS_WAIT_ENABLE))
+
+#define IS_FSMC_CLK_DIV(__DIV__) (((__DIV__) > 1U) && ((__DIV__) <= 16U))
+
+/** @defgroup FSMC_Data_Latency FSMC Data Latency
+ * @{
+ */
+#define IS_FSMC_DATA_LATENCY(__LATENCY__) (((__LATENCY__) > 1U) && ((__LATENCY__) <= 17U))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Address_Setup_Time FSMC Address Setup Time
+ * @{
+ */
+#define IS_FSMC_ADDRESS_SETUP_TIME(__TIME__) ((__TIME__) <= 15U)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Address_Hold_Time FSMC Address Hold Time
+ * @{
+ */
+#define IS_FSMC_ADDRESS_HOLD_TIME(__TIME__) (((__TIME__) > 0U) && ((__TIME__) <= 15U))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Data_Setup_Time FSMC Data Setup Time
+ * @{
+ */
+#define IS_FSMC_DATASETUP_TIME(__TIME__) (((__TIME__) > 0U) && ((__TIME__) <= 255U))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Bus_Turn_around_Duration FSMC Bus Turn around Duration
+ * @{
+ */
+#define IS_FSMC_TURNAROUND_TIME(__TIME__) ((__TIME__) <= 15U)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_LL_Private_Constants FSMC Low Layer Private Constants
+ * @{
+ */
+
+/* ----------------------- FSMC registers bit mask --------------------------- */
+#if (defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
+/* --- PCR Register ---*/
+/* PCR register clear mask */
+#define PCR_CLEAR_MASK ((uint32_t)(FSMC_PCRx_PWAITEN | FSMC_PCRx_PBKEN | \
+ FSMC_PCRx_PTYP | FSMC_PCRx_PWID | \
+ FSMC_PCRx_ECCEN | FSMC_PCRx_TCLR | \
+ FSMC_PCRx_TAR | FSMC_PCRx_ECCPS))
+
+/* --- PMEM Register ---*/
+/* PMEM register clear mask */
+#define PMEM_CLEAR_MASK ((uint32_t)(FSMC_PMEMx_MEMSETx | FSMC_PMEMx_MEMWAITx |\
+ FSMC_PMEMx_MEMHOLDx | FSMC_PMEMx_MEMHIZx))
+
+/* --- PATT Register ---*/
+/* PATT register clear mask */
+#define PATT_CLEAR_MASK ((uint32_t)(FSMC_PATTx_ATTSETx | FSMC_PATTx_ATTWAITx |\
+ FSMC_PATTx_ATTHOLDx | FSMC_PATTx_ATTHIZx))
+
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+/* --- BCR Register ---*/
+/* BCR register clear mask */
+#define BCR_CLEAR_MASK ((uint32_t)(FSMC_BCRx_FACCEN | FSMC_BCRx_MUXEN | \
+ FSMC_BCRx_MTYP | FSMC_BCRx_MWID | \
+ FSMC_BCRx_BURSTEN | FSMC_BCRx_WAITPOL | \
+ FSMC_BCRx_WRAPMOD | FSMC_BCRx_WAITCFG | \
+ FSMC_BCRx_WREN | FSMC_BCRx_WAITEN | \
+ FSMC_BCRx_EXTMOD | FSMC_BCRx_ASYNCWAIT | \
+ FSMC_BCRx_CBURSTRW))
+/* --- BTR Register ---*/
+/* BTR register clear mask */
+#define BTR_CLEAR_MASK ((uint32_t)(FSMC_BTRx_ADDSET | FSMC_BTRx_ADDHLD |\
+ FSMC_BTRx_DATAST | FSMC_BTRx_BUSTURN |\
+ FSMC_BTRx_CLKDIV | FSMC_BTRx_DATLAT |\
+ FSMC_BTRx_ACCMOD))
+
+/* --- BWTR Register ---*/
+/* BWTR register clear mask */
+#if (defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
+#define BWTR_CLEAR_MASK ((uint32_t)(FSMC_BWTRx_ADDSET | FSMC_BWTRx_ADDHLD | \
+ FSMC_BWTRx_DATAST | FSMC_BWTRx_ACCMOD | \
+ FSMC_BWTRx_BUSTURN))
+#else
+#define BWTR_CLEAR_MASK ((uint32_t)(FSMC_BWTRx_ADDSET | FSMC_BWTRx_ADDHLD | \
+ FSMC_BWTRx_DATAST | FSMC_BWTRx_ACCMOD | \
+ FSMC_BWTRx_CLKDIV | FSMC_BWTRx_DATLAT))
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+
+/* --- PIO4 Register ---*/
+/* PIO4 register clear mask */
+#define PIO4_CLEAR_MASK ((uint32_t)(FSMC_PIO4_IOSET4 | FSMC_PIO4_IOWAIT4 | \
+ FSMC_PIO4_IOHOLD4 | FSMC_PIO4_IOHIZ4))
+/**
+ * @}
+ */
+/* Exported functions --------------------------------------------------------*/
+
+/** @addtogroup FSMC_LL_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup FSMC_NORSRAM
+ * @{
+ */
+
+/** @addtogroup FSMC_NORSRAM_Group1
+ * @{
+ */
+/* FSMC_NORSRAM Controller functions ******************************************/
+/* Initialization/de-initialization functions */
+HAL_StatusTypeDef FSMC_NORSRAM_Init(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_InitTypeDef *Init);
+HAL_StatusTypeDef FSMC_NORSRAM_Timing_Init(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank);
+HAL_StatusTypeDef FSMC_NORSRAM_Extended_Timing_Init(FSMC_NORSRAM_EXTENDED_TypeDef *Device, FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, uint32_t ExtendedMode);
+HAL_StatusTypeDef FSMC_NORSRAM_DeInit(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank);
+/**
+ * @}
+ */
+
+/** @addtogroup FSMC_NORSRAM_Group2
+ * @{
+ */
+/* FSMC_NORSRAM Control functions */
+HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Enable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank);
+HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Disable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#if (defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
+/** @addtogroup FSMC_NAND
+ * @{
+ */
+
+/* FSMC_NAND Controller functions **********************************************/
+/* Initialization/de-initialization functions */
+/** @addtogroup FSMC_NAND_Exported_Functions_Group1
+ * @{
+ */
+HAL_StatusTypeDef FSMC_NAND_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_InitTypeDef *Init);
+HAL_StatusTypeDef FSMC_NAND_CommonSpace_Timing_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank);
+HAL_StatusTypeDef FSMC_NAND_AttributeSpace_Timing_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank);
+HAL_StatusTypeDef FSMC_NAND_DeInit(FSMC_NAND_TypeDef *Device, uint32_t Bank);
+/**
+ * @}
+ */
+
+/* FSMC_NAND Control functions */
+/** @addtogroup FSMC_NAND_Exported_Functions_Group2
+ * @{
+ */
+HAL_StatusTypeDef FSMC_NAND_ECC_Enable(FSMC_NAND_TypeDef *Device, uint32_t Bank);
+HAL_StatusTypeDef FSMC_NAND_ECC_Disable(FSMC_NAND_TypeDef *Device, uint32_t Bank);
+HAL_StatusTypeDef FSMC_NAND_GetECC(FSMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank, uint32_t Timeout);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup FSMC_PCCARD
+ * @{
+ */
+
+/* FSMC_PCCARD Controller functions ********************************************/
+/* Initialization/de-initialization functions */
+/** @addtogroup FSMC_PCCARD_Exported_Functions_Group1
+ * @{
+ */
+HAL_StatusTypeDef FSMC_PCCARD_Init(FSMC_PCCARD_TypeDef *Device, FSMC_PCCARD_InitTypeDef *Init);
+HAL_StatusTypeDef FSMC_PCCARD_CommonSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing);
+HAL_StatusTypeDef FSMC_PCCARD_AttributeSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing);
+HAL_StatusTypeDef FSMC_PCCARD_IOSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing);
+HAL_StatusTypeDef FSMC_PCCARD_DeInit(FSMC_PCCARD_TypeDef *Device);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* FSMC_BANK1 */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_LL_FSMC_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_gpio.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_gpio.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_gpio.h
rename to templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_gpio.h
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_i2c.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_i2c.h
new file mode 100644
index 0000000..c4e3e53
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_i2c.h
@@ -0,0 +1,1800 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_i2c.h
+ * @author MCD Application Team
+ * @brief Header file of I2C LL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_I2C_H
+#define __STM32F1xx_LL_I2C_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx.h"
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (I2C1) || defined (I2C2)
+
+/** @defgroup I2C_LL I2C
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup I2C_LL_Private_Constants I2C Private Constants
+ * @{
+ */
+
+/* Defines used to perform compute and check in the macros */
+#define LL_I2C_MAX_SPEED_STANDARD 100000U
+#define LL_I2C_MAX_SPEED_FAST 400000U
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup I2C_LL_Private_Macros I2C Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+#endif /*USE_FULL_LL_DRIVER*/
+
+/* Exported types ------------------------------------------------------------*/
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup I2C_LL_ES_INIT I2C Exported Init structure
+ * @{
+ */
+typedef struct
+{
+ uint32_t PeripheralMode; /*!< Specifies the peripheral mode.
+ This parameter can be a value of @ref I2C_LL_EC_PERIPHERAL_MODE
+
+ This feature can be modified afterwards using unitary function @ref LL_I2C_SetMode(). */
+
+ uint32_t ClockSpeed; /*!< Specifies the clock frequency.
+ This parameter must be set to a value lower than 400kHz (in Hz)
+
+ This feature can be modified afterwards using unitary function @ref LL_I2C_SetClockPeriod()
+ or @ref LL_I2C_SetDutyCycle() or @ref LL_I2C_SetClockSpeedMode() or @ref LL_I2C_ConfigSpeed(). */
+
+ uint32_t DutyCycle; /*!< Specifies the I2C fast mode duty cycle.
+ This parameter can be a value of @ref I2C_LL_EC_DUTYCYCLE
+
+ This feature can be modified afterwards using unitary function @ref LL_I2C_SetDutyCycle(). */
+
+ uint32_t OwnAddress1; /*!< Specifies the device own address 1.
+ This parameter must be a value between Min_Data = 0x00 and Max_Data = 0x3FF
+
+ This feature can be modified afterwards using unitary function @ref LL_I2C_SetOwnAddress1(). */
+
+ uint32_t TypeAcknowledge; /*!< Specifies the ACKnowledge or Non ACKnowledge condition after the address receive match code or next received byte.
+ This parameter can be a value of @ref I2C_LL_EC_I2C_ACKNOWLEDGE
+
+ This feature can be modified afterwards using unitary function @ref LL_I2C_AcknowledgeNextData(). */
+
+ uint32_t OwnAddrSize; /*!< Specifies the device own address 1 size (7-bit or 10-bit).
+ This parameter can be a value of @ref I2C_LL_EC_OWNADDRESS1
+
+ This feature can be modified afterwards using unitary function @ref LL_I2C_SetOwnAddress1(). */
+} LL_I2C_InitTypeDef;
+/**
+ * @}
+ */
+#endif /*USE_FULL_LL_DRIVER*/
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup I2C_LL_Exported_Constants I2C Exported Constants
+ * @{
+ */
+
+/** @defgroup I2C_LL_EC_GET_FLAG Get Flags Defines
+ * @brief Flags defines which can be used with LL_I2C_ReadReg function
+ * @{
+ */
+#define LL_I2C_SR1_SB I2C_SR1_SB /*!< Start Bit (master mode) */
+#define LL_I2C_SR1_ADDR I2C_SR1_ADDR /*!< Address sent (master mode) or
+ Address matched flag (slave mode) */
+#define LL_I2C_SR1_BTF I2C_SR1_BTF /*!< Byte Transfer Finished flag */
+#define LL_I2C_SR1_ADD10 I2C_SR1_ADD10 /*!< 10-bit header sent (master mode) */
+#define LL_I2C_SR1_STOPF I2C_SR1_STOPF /*!< Stop detection flag (slave mode) */
+#define LL_I2C_SR1_RXNE I2C_SR1_RXNE /*!< Data register not empty (receivers) */
+#define LL_I2C_SR1_TXE I2C_SR1_TXE /*!< Data register empty (transmitters) */
+#define LL_I2C_SR1_BERR I2C_SR1_BERR /*!< Bus error */
+#define LL_I2C_SR1_ARLO I2C_SR1_ARLO /*!< Arbitration lost */
+#define LL_I2C_SR1_AF I2C_SR1_AF /*!< Acknowledge failure flag */
+#define LL_I2C_SR1_OVR I2C_SR1_OVR /*!< Overrun/Underrun */
+#define LL_I2C_SR1_PECERR I2C_ISR_PECERR /*!< PEC Error in reception (SMBus mode) */
+#define LL_I2C_SR1_TIMEOUT I2C_ISR_TIMEOUT /*!< Timeout detection flag (SMBus mode) */
+#define LL_I2C_SR1_SMALERT I2C_ISR_SMALERT /*!< SMBus alert (SMBus mode) */
+#define LL_I2C_SR2_MSL I2C_SR2_MSL /*!< Master/Slave flag */
+#define LL_I2C_SR2_BUSY I2C_SR2_BUSY /*!< Bus busy flag */
+#define LL_I2C_SR2_TRA I2C_SR2_TRA /*!< Transmitter/receiver direction */
+#define LL_I2C_SR2_GENCALL I2C_SR2_GENCALL /*!< General call address (Slave mode) */
+#define LL_I2C_SR2_SMBDEFAULT I2C_SR2_SMBDEFAULT /*!< SMBus Device default address (Slave mode) */
+#define LL_I2C_SR2_SMBHOST I2C_SR2_SMBHOST /*!< SMBus Host address (Slave mode) */
+#define LL_I2C_SR2_DUALF I2C_SR2_DUALF /*!< Dual flag (Slave mode) */
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EC_IT IT Defines
+ * @brief IT defines which can be used with LL_I2C_ReadReg and LL_I2C_WriteReg functions
+ * @{
+ */
+#define LL_I2C_CR2_ITEVTEN I2C_CR2_ITEVTEN /*!< Events interrupts enable */
+#define LL_I2C_CR2_ITBUFEN I2C_CR2_ITBUFEN /*!< Buffer interrupts enable */
+#define LL_I2C_CR2_ITERREN I2C_CR2_ITERREN /*!< Error interrupts enable */
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EC_OWNADDRESS1 Own Address 1 Length
+ * @{
+ */
+#define LL_I2C_OWNADDRESS1_7BIT 0x00004000U /*!< Own address 1 is a 7-bit address. */
+#define LL_I2C_OWNADDRESS1_10BIT (uint32_t)(I2C_OAR1_ADDMODE | 0x00004000U) /*!< Own address 1 is a 10-bit address. */
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EC_DUTYCYCLE Fast Mode Duty Cycle
+ * @{
+ */
+#define LL_I2C_DUTYCYCLE_2 0x00000000U /*!< I2C fast mode Tlow/Thigh = 2 */
+#define LL_I2C_DUTYCYCLE_16_9 I2C_CCR_DUTY /*!< I2C fast mode Tlow/Thigh = 16/9 */
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EC_CLOCK_SPEED_MODE Master Clock Speed Mode
+ * @{
+ */
+#define LL_I2C_CLOCK_SPEED_STANDARD_MODE 0x00000000U /*!< Master clock speed range is standard mode */
+#define LL_I2C_CLOCK_SPEED_FAST_MODE I2C_CCR_FS /*!< Master clock speed range is fast mode */
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EC_PERIPHERAL_MODE Peripheral Mode
+ * @{
+ */
+#define LL_I2C_MODE_I2C 0x00000000U /*!< I2C Master or Slave mode */
+#define LL_I2C_MODE_SMBUS_HOST (uint32_t)(I2C_CR1_SMBUS | I2C_CR1_SMBTYPE | I2C_CR1_ENARP) /*!< SMBus Host address acknowledge */
+#define LL_I2C_MODE_SMBUS_DEVICE I2C_CR1_SMBUS /*!< SMBus Device default mode (Default address not acknowledge) */
+#define LL_I2C_MODE_SMBUS_DEVICE_ARP (uint32_t)(I2C_CR1_SMBUS | I2C_CR1_ENARP) /*!< SMBus Device Default address acknowledge */
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EC_I2C_ACKNOWLEDGE Acknowledge Generation
+ * @{
+ */
+#define LL_I2C_ACK I2C_CR1_ACK /*!< ACK is sent after current received byte. */
+#define LL_I2C_NACK 0x00000000U /*!< NACK is sent after current received byte.*/
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EC_DIRECTION Read Write Direction
+ * @{
+ */
+#define LL_I2C_DIRECTION_WRITE I2C_SR2_TRA /*!< Bus is in write transfer */
+#define LL_I2C_DIRECTION_READ 0x00000000U /*!< Bus is in read transfer */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup I2C_LL_Exported_Macros I2C Exported Macros
+ * @{
+ */
+
+/** @defgroup I2C_LL_EM_WRITE_READ Common Write and read registers Macros
+ * @{
+ */
+
+/**
+ * @brief Write a value in I2C register
+ * @param __INSTANCE__ I2C Instance
+ * @param __REG__ Register to be written
+ * @param __VALUE__ Value to be written in the register
+ * @retval None
+ */
+#define LL_I2C_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
+
+/**
+ * @brief Read a value in I2C register
+ * @param __INSTANCE__ I2C Instance
+ * @param __REG__ Register to be read
+ * @retval Register value
+ */
+#define LL_I2C_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EM_Exported_Macros_Helper Exported_Macros_Helper
+ * @{
+ */
+
+/**
+ * @brief Convert Peripheral Clock Frequency in Mhz.
+ * @param __PCLK__ This parameter must be a value of peripheral clock (in Hz).
+ * @retval Value of peripheral clock (in Mhz)
+ */
+#define __LL_I2C_FREQ_HZ_TO_MHZ(__PCLK__) (uint32_t)((__PCLK__)/1000000U)
+
+/**
+ * @brief Convert Peripheral Clock Frequency in Hz.
+ * @param __PCLK__ This parameter must be a value of peripheral clock (in Mhz).
+ * @retval Value of peripheral clock (in Hz)
+ */
+#define __LL_I2C_FREQ_MHZ_TO_HZ(__PCLK__) (uint32_t)((__PCLK__)*1000000U)
+
+/**
+ * @brief Compute I2C Clock rising time.
+ * @param __FREQRANGE__ This parameter must be a value of peripheral clock (in Mhz).
+ * @param __SPEED__ This parameter must be a value lower than 400kHz (in Hz).
+ * @retval Value between Min_Data=0x02 and Max_Data=0x3F
+ */
+#define __LL_I2C_RISE_TIME(__FREQRANGE__, __SPEED__) (uint32_t)(((__SPEED__) <= LL_I2C_MAX_SPEED_STANDARD) ? ((__FREQRANGE__) + 1U) : ((((__FREQRANGE__) * 300U) / 1000U) + 1U))
+
+/**
+ * @brief Compute Speed clock range to a Clock Control Register (I2C_CCR_CCR) value.
+ * @param __PCLK__ This parameter must be a value of peripheral clock (in Hz).
+ * @param __SPEED__ This parameter must be a value lower than 400kHz (in Hz).
+ * @param __DUTYCYCLE__ This parameter can be one of the following values:
+ * @arg @ref LL_I2C_DUTYCYCLE_2
+ * @arg @ref LL_I2C_DUTYCYCLE_16_9
+ * @retval Value between Min_Data=0x004 and Max_Data=0xFFF, except in FAST DUTY mode where Min_Data=0x001.
+ */
+#define __LL_I2C_SPEED_TO_CCR(__PCLK__, __SPEED__, __DUTYCYCLE__) (uint32_t)(((__SPEED__) <= LL_I2C_MAX_SPEED_STANDARD)? \
+ (__LL_I2C_SPEED_STANDARD_TO_CCR((__PCLK__), (__SPEED__))) : \
+ (__LL_I2C_SPEED_FAST_TO_CCR((__PCLK__), (__SPEED__), (__DUTYCYCLE__))))
+
+/**
+ * @brief Compute Speed Standard clock range to a Clock Control Register (I2C_CCR_CCR) value.
+ * @param __PCLK__ This parameter must be a value of peripheral clock (in Hz).
+ * @param __SPEED__ This parameter must be a value lower than 100kHz (in Hz).
+ * @retval Value between Min_Data=0x004 and Max_Data=0xFFF.
+ */
+#define __LL_I2C_SPEED_STANDARD_TO_CCR(__PCLK__, __SPEED__) (uint32_t)(((((__PCLK__)/((__SPEED__) << 1U)) & I2C_CCR_CCR) < 4U)? 4U:((__PCLK__) / ((__SPEED__) << 1U)))
+
+/**
+ * @brief Compute Speed Fast clock range to a Clock Control Register (I2C_CCR_CCR) value.
+ * @param __PCLK__ This parameter must be a value of peripheral clock (in Hz).
+ * @param __SPEED__ This parameter must be a value between Min_Data=100Khz and Max_Data=400Khz (in Hz).
+ * @param __DUTYCYCLE__ This parameter can be one of the following values:
+ * @arg @ref LL_I2C_DUTYCYCLE_2
+ * @arg @ref LL_I2C_DUTYCYCLE_16_9
+ * @retval Value between Min_Data=0x001 and Max_Data=0xFFF
+ */
+#define __LL_I2C_SPEED_FAST_TO_CCR(__PCLK__, __SPEED__, __DUTYCYCLE__) (uint32_t)(((__DUTYCYCLE__) == LL_I2C_DUTYCYCLE_2)? \
+ (((((__PCLK__) / ((__SPEED__) * 3U)) & I2C_CCR_CCR) == 0U)? 1U:((__PCLK__) / ((__SPEED__) * 3U))) : \
+ (((((__PCLK__) / ((__SPEED__) * 25U)) & I2C_CCR_CCR) == 0U)? 1U:((__PCLK__) / ((__SPEED__) * 25U))))
+
+/**
+ * @brief Get the Least significant bits of a 10-Bits address.
+ * @param __ADDRESS__ This parameter must be a value of a 10-Bits slave address.
+ * @retval Value between Min_Data=0x00 and Max_Data=0xFF
+ */
+#define __LL_I2C_10BIT_ADDRESS(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FF))))
+
+/**
+ * @brief Convert a 10-Bits address to a 10-Bits header with Write direction.
+ * @param __ADDRESS__ This parameter must be a value of a 10-Bits slave address.
+ * @retval Value between Min_Data=0xF0 and Max_Data=0xF6
+ */
+#define __LL_I2C_10BIT_HEADER_WRITE(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0x0300))) >> 7) | (uint16_t)(0xF0))))
+
+/**
+ * @brief Convert a 10-Bits address to a 10-Bits header with Read direction.
+ * @param __ADDRESS__ This parameter must be a value of a 10-Bits slave address.
+ * @retval Value between Min_Data=0xF1 and Max_Data=0xF7
+ */
+#define __LL_I2C_10BIT_HEADER_READ(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0x0300))) >> 7) | (uint16_t)(0xF1))))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup I2C_LL_Exported_Functions I2C Exported Functions
+ * @{
+ */
+
+/** @defgroup I2C_LL_EF_Configuration Configuration
+ * @{
+ */
+
+/**
+ * @brief Enable I2C peripheral (PE = 1).
+ * @rmtoll CR1 PE LL_I2C_Enable
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_Enable(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_PE);
+}
+
+/**
+ * @brief Disable I2C peripheral (PE = 0).
+ * @rmtoll CR1 PE LL_I2C_Disable
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_Disable(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR1, I2C_CR1_PE);
+}
+
+/**
+ * @brief Check if the I2C peripheral is enabled or disabled.
+ * @rmtoll CR1 PE LL_I2C_IsEnabled
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabled(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR1, I2C_CR1_PE) == (I2C_CR1_PE));
+}
+
+
+/**
+ * @brief Enable DMA transmission requests.
+ * @rmtoll CR2 DMAEN LL_I2C_EnableDMAReq_TX
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableDMAReq_TX(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR2, I2C_CR2_DMAEN);
+}
+
+/**
+ * @brief Disable DMA transmission requests.
+ * @rmtoll CR2 DMAEN LL_I2C_DisableDMAReq_TX
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableDMAReq_TX(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR2, I2C_CR2_DMAEN);
+}
+
+/**
+ * @brief Check if DMA transmission requests are enabled or disabled.
+ * @rmtoll CR2 DMAEN LL_I2C_IsEnabledDMAReq_TX
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledDMAReq_TX(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR2, I2C_CR2_DMAEN) == (I2C_CR2_DMAEN));
+}
+
+/**
+ * @brief Enable DMA reception requests.
+ * @rmtoll CR2 DMAEN LL_I2C_EnableDMAReq_RX
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableDMAReq_RX(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR2, I2C_CR2_DMAEN);
+}
+
+/**
+ * @brief Disable DMA reception requests.
+ * @rmtoll CR2 DMAEN LL_I2C_DisableDMAReq_RX
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableDMAReq_RX(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR2, I2C_CR2_DMAEN);
+}
+
+/**
+ * @brief Check if DMA reception requests are enabled or disabled.
+ * @rmtoll CR2 DMAEN LL_I2C_IsEnabledDMAReq_RX
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledDMAReq_RX(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR2, I2C_CR2_DMAEN) == (I2C_CR2_DMAEN));
+}
+
+/**
+ * @brief Get the data register address used for DMA transfer.
+ * @rmtoll DR DR LL_I2C_DMA_GetRegAddr
+ * @param I2Cx I2C Instance.
+ * @retval Address of data register
+ */
+__STATIC_INLINE uint32_t LL_I2C_DMA_GetRegAddr(I2C_TypeDef *I2Cx)
+{
+ return (uint32_t) & (I2Cx->DR);
+}
+
+/**
+ * @brief Enable Clock stretching.
+ * @note This bit can only be programmed when the I2C is disabled (PE = 0).
+ * @rmtoll CR1 NOSTRETCH LL_I2C_EnableClockStretching
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableClockStretching(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR1, I2C_CR1_NOSTRETCH);
+}
+
+/**
+ * @brief Disable Clock stretching.
+ * @note This bit can only be programmed when the I2C is disabled (PE = 0).
+ * @rmtoll CR1 NOSTRETCH LL_I2C_DisableClockStretching
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableClockStretching(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_NOSTRETCH);
+}
+
+/**
+ * @brief Check if Clock stretching is enabled or disabled.
+ * @rmtoll CR1 NOSTRETCH LL_I2C_IsEnabledClockStretching
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledClockStretching(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR1, I2C_CR1_NOSTRETCH) != (I2C_CR1_NOSTRETCH));
+}
+
+/**
+ * @brief Enable General Call.
+ * @note When enabled the Address 0x00 is ACKed.
+ * @rmtoll CR1 ENGC LL_I2C_EnableGeneralCall
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableGeneralCall(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_ENGC);
+}
+
+/**
+ * @brief Disable General Call.
+ * @note When disabled the Address 0x00 is NACKed.
+ * @rmtoll CR1 ENGC LL_I2C_DisableGeneralCall
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableGeneralCall(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR1, I2C_CR1_ENGC);
+}
+
+/**
+ * @brief Check if General Call is enabled or disabled.
+ * @rmtoll CR1 ENGC LL_I2C_IsEnabledGeneralCall
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledGeneralCall(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR1, I2C_CR1_ENGC) == (I2C_CR1_ENGC));
+}
+
+/**
+ * @brief Set the Own Address1.
+ * @rmtoll OAR1 ADD0 LL_I2C_SetOwnAddress1\n
+ * OAR1 ADD1_7 LL_I2C_SetOwnAddress1\n
+ * OAR1 ADD8_9 LL_I2C_SetOwnAddress1\n
+ * OAR1 ADDMODE LL_I2C_SetOwnAddress1
+ * @param I2Cx I2C Instance.
+ * @param OwnAddress1 This parameter must be a value between Min_Data=0 and Max_Data=0x3FF.
+ * @param OwnAddrSize This parameter can be one of the following values:
+ * @arg @ref LL_I2C_OWNADDRESS1_7BIT
+ * @arg @ref LL_I2C_OWNADDRESS1_10BIT
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_SetOwnAddress1(I2C_TypeDef *I2Cx, uint32_t OwnAddress1, uint32_t OwnAddrSize)
+{
+ MODIFY_REG(I2Cx->OAR1, I2C_OAR1_ADD0 | I2C_OAR1_ADD1_7 | I2C_OAR1_ADD8_9 | I2C_OAR1_ADDMODE, OwnAddress1 | OwnAddrSize);
+}
+
+/**
+ * @brief Set the 7bits Own Address2.
+ * @note This action has no effect if own address2 is enabled.
+ * @rmtoll OAR2 ADD2 LL_I2C_SetOwnAddress2
+ * @param I2Cx I2C Instance.
+ * @param OwnAddress2 This parameter must be a value between Min_Data=0 and Max_Data=0x7F.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_SetOwnAddress2(I2C_TypeDef *I2Cx, uint32_t OwnAddress2)
+{
+ MODIFY_REG(I2Cx->OAR2, I2C_OAR2_ADD2, OwnAddress2);
+}
+
+/**
+ * @brief Enable acknowledge on Own Address2 match address.
+ * @rmtoll OAR2 ENDUAL LL_I2C_EnableOwnAddress2
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableOwnAddress2(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->OAR2, I2C_OAR2_ENDUAL);
+}
+
+/**
+ * @brief Disable acknowledge on Own Address2 match address.
+ * @rmtoll OAR2 ENDUAL LL_I2C_DisableOwnAddress2
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableOwnAddress2(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->OAR2, I2C_OAR2_ENDUAL);
+}
+
+/**
+ * @brief Check if Own Address1 acknowledge is enabled or disabled.
+ * @rmtoll OAR2 ENDUAL LL_I2C_IsEnabledOwnAddress2
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledOwnAddress2(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->OAR2, I2C_OAR2_ENDUAL) == (I2C_OAR2_ENDUAL));
+}
+
+/**
+ * @brief Configure the Peripheral clock frequency.
+ * @rmtoll CR2 FREQ LL_I2C_SetPeriphClock
+ * @param I2Cx I2C Instance.
+ * @param PeriphClock Peripheral Clock (in Hz)
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_SetPeriphClock(I2C_TypeDef *I2Cx, uint32_t PeriphClock)
+{
+ MODIFY_REG(I2Cx->CR2, I2C_CR2_FREQ, __LL_I2C_FREQ_HZ_TO_MHZ(PeriphClock));
+}
+
+/**
+ * @brief Get the Peripheral clock frequency.
+ * @rmtoll CR2 FREQ LL_I2C_GetPeriphClock
+ * @param I2Cx I2C Instance.
+ * @retval Value of Peripheral Clock (in Hz)
+ */
+__STATIC_INLINE uint32_t LL_I2C_GetPeriphClock(I2C_TypeDef *I2Cx)
+{
+ return (uint32_t)(__LL_I2C_FREQ_MHZ_TO_HZ(READ_BIT(I2Cx->CR2, I2C_CR2_FREQ)));
+}
+
+/**
+ * @brief Configure the Duty cycle (Fast mode only).
+ * @rmtoll CCR DUTY LL_I2C_SetDutyCycle
+ * @param I2Cx I2C Instance.
+ * @param DutyCycle This parameter can be one of the following values:
+ * @arg @ref LL_I2C_DUTYCYCLE_2
+ * @arg @ref LL_I2C_DUTYCYCLE_16_9
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_SetDutyCycle(I2C_TypeDef *I2Cx, uint32_t DutyCycle)
+{
+ MODIFY_REG(I2Cx->CCR, I2C_CCR_DUTY, DutyCycle);
+}
+
+/**
+ * @brief Get the Duty cycle (Fast mode only).
+ * @rmtoll CCR DUTY LL_I2C_GetDutyCycle
+ * @param I2Cx I2C Instance.
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_I2C_DUTYCYCLE_2
+ * @arg @ref LL_I2C_DUTYCYCLE_16_9
+ */
+__STATIC_INLINE uint32_t LL_I2C_GetDutyCycle(I2C_TypeDef *I2Cx)
+{
+ return (uint32_t)(READ_BIT(I2Cx->CCR, I2C_CCR_DUTY));
+}
+
+/**
+ * @brief Configure the I2C master clock speed mode.
+ * @rmtoll CCR FS LL_I2C_SetClockSpeedMode
+ * @param I2Cx I2C Instance.
+ * @param ClockSpeedMode This parameter can be one of the following values:
+ * @arg @ref LL_I2C_CLOCK_SPEED_STANDARD_MODE
+ * @arg @ref LL_I2C_CLOCK_SPEED_FAST_MODE
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_SetClockSpeedMode(I2C_TypeDef *I2Cx, uint32_t ClockSpeedMode)
+{
+ MODIFY_REG(I2Cx->CCR, I2C_CCR_FS, ClockSpeedMode);
+}
+
+/**
+ * @brief Get the the I2C master speed mode.
+ * @rmtoll CCR FS LL_I2C_GetClockSpeedMode
+ * @param I2Cx I2C Instance.
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_I2C_CLOCK_SPEED_STANDARD_MODE
+ * @arg @ref LL_I2C_CLOCK_SPEED_FAST_MODE
+ */
+__STATIC_INLINE uint32_t LL_I2C_GetClockSpeedMode(I2C_TypeDef *I2Cx)
+{
+ return (uint32_t)(READ_BIT(I2Cx->CCR, I2C_CCR_FS));
+}
+
+/**
+ * @brief Configure the SCL, SDA rising time.
+ * @note This bit can only be programmed when the I2C is disabled (PE = 0).
+ * @rmtoll TRISE TRISE LL_I2C_SetRiseTime
+ * @param I2Cx I2C Instance.
+ * @param RiseTime This parameter must be a value between Min_Data=0x02 and Max_Data=0x3F.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_SetRiseTime(I2C_TypeDef *I2Cx, uint32_t RiseTime)
+{
+ MODIFY_REG(I2Cx->TRISE, I2C_TRISE_TRISE, RiseTime);
+}
+
+/**
+ * @brief Get the SCL, SDA rising time.
+ * @rmtoll TRISE TRISE LL_I2C_GetRiseTime
+ * @param I2Cx I2C Instance.
+ * @retval Value between Min_Data=0x02 and Max_Data=0x3F
+ */
+__STATIC_INLINE uint32_t LL_I2C_GetRiseTime(I2C_TypeDef *I2Cx)
+{
+ return (uint32_t)(READ_BIT(I2Cx->TRISE, I2C_TRISE_TRISE));
+}
+
+/**
+ * @brief Configure the SCL high and low period.
+ * @note This bit can only be programmed when the I2C is disabled (PE = 0).
+ * @rmtoll CCR CCR LL_I2C_SetClockPeriod
+ * @param I2Cx I2C Instance.
+ * @param ClockPeriod This parameter must be a value between Min_Data=0x004 and Max_Data=0xFFF, except in FAST DUTY mode where Min_Data=0x001.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_SetClockPeriod(I2C_TypeDef *I2Cx, uint32_t ClockPeriod)
+{
+ MODIFY_REG(I2Cx->CCR, I2C_CCR_CCR, ClockPeriod);
+}
+
+/**
+ * @brief Get the SCL high and low period.
+ * @rmtoll CCR CCR LL_I2C_GetClockPeriod
+ * @param I2Cx I2C Instance.
+ * @retval Value between Min_Data=0x004 and Max_Data=0xFFF, except in FAST DUTY mode where Min_Data=0x001.
+ */
+__STATIC_INLINE uint32_t LL_I2C_GetClockPeriod(I2C_TypeDef *I2Cx)
+{
+ return (uint32_t)(READ_BIT(I2Cx->CCR, I2C_CCR_CCR));
+}
+
+/**
+ * @brief Configure the SCL speed.
+ * @note This bit can only be programmed when the I2C is disabled (PE = 0).
+ * @rmtoll CR2 FREQ LL_I2C_ConfigSpeed\n
+ * TRISE TRISE LL_I2C_ConfigSpeed\n
+ * CCR FS LL_I2C_ConfigSpeed\n
+ * CCR DUTY LL_I2C_ConfigSpeed\n
+ * CCR CCR LL_I2C_ConfigSpeed
+ * @param I2Cx I2C Instance.
+ * @param PeriphClock Peripheral Clock (in Hz)
+ * @param ClockSpeed This parameter must be a value lower than 400kHz (in Hz).
+ * @param DutyCycle This parameter can be one of the following values:
+ * @arg @ref LL_I2C_DUTYCYCLE_2
+ * @arg @ref LL_I2C_DUTYCYCLE_16_9
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ConfigSpeed(I2C_TypeDef *I2Cx, uint32_t PeriphClock, uint32_t ClockSpeed,
+ uint32_t DutyCycle)
+{
+ register uint32_t freqrange = 0x0U;
+ register uint32_t clockconfig = 0x0U;
+
+ /* Compute frequency range */
+ freqrange = __LL_I2C_FREQ_HZ_TO_MHZ(PeriphClock);
+
+ /* Configure I2Cx: Frequency range register */
+ MODIFY_REG(I2Cx->CR2, I2C_CR2_FREQ, freqrange);
+
+ /* Configure I2Cx: Rise Time register */
+ MODIFY_REG(I2Cx->TRISE, I2C_TRISE_TRISE, __LL_I2C_RISE_TIME(freqrange, ClockSpeed));
+
+ /* Configure Speed mode, Duty Cycle and Clock control register value */
+ if (ClockSpeed > LL_I2C_MAX_SPEED_STANDARD)
+ {
+ /* Set Speed mode at fast and duty cycle for Clock Speed request in fast clock range */
+ clockconfig = LL_I2C_CLOCK_SPEED_FAST_MODE | \
+ __LL_I2C_SPEED_FAST_TO_CCR(PeriphClock, ClockSpeed, DutyCycle) | \
+ DutyCycle;
+ }
+ else
+ {
+ /* Set Speed mode at standard for Clock Speed request in standard clock range */
+ clockconfig = LL_I2C_CLOCK_SPEED_STANDARD_MODE | \
+ __LL_I2C_SPEED_STANDARD_TO_CCR(PeriphClock, ClockSpeed);
+ }
+
+ /* Configure I2Cx: Clock control register */
+ MODIFY_REG(I2Cx->CCR, (I2C_CCR_FS | I2C_CCR_DUTY | I2C_CCR_CCR), clockconfig);
+}
+
+/**
+ * @brief Configure peripheral mode.
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll CR1 SMBUS LL_I2C_SetMode\n
+ * CR1 SMBTYPE LL_I2C_SetMode\n
+ * CR1 ENARP LL_I2C_SetMode
+ * @param I2Cx I2C Instance.
+ * @param PeripheralMode This parameter can be one of the following values:
+ * @arg @ref LL_I2C_MODE_I2C
+ * @arg @ref LL_I2C_MODE_SMBUS_HOST
+ * @arg @ref LL_I2C_MODE_SMBUS_DEVICE
+ * @arg @ref LL_I2C_MODE_SMBUS_DEVICE_ARP
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_SetMode(I2C_TypeDef *I2Cx, uint32_t PeripheralMode)
+{
+ MODIFY_REG(I2Cx->CR1, I2C_CR1_SMBUS | I2C_CR1_SMBTYPE | I2C_CR1_ENARP, PeripheralMode);
+}
+
+/**
+ * @brief Get peripheral mode.
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll CR1 SMBUS LL_I2C_GetMode\n
+ * CR1 SMBTYPE LL_I2C_GetMode\n
+ * CR1 ENARP LL_I2C_GetMode
+ * @param I2Cx I2C Instance.
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_I2C_MODE_I2C
+ * @arg @ref LL_I2C_MODE_SMBUS_HOST
+ * @arg @ref LL_I2C_MODE_SMBUS_DEVICE
+ * @arg @ref LL_I2C_MODE_SMBUS_DEVICE_ARP
+ */
+__STATIC_INLINE uint32_t LL_I2C_GetMode(I2C_TypeDef *I2Cx)
+{
+ return (uint32_t)(READ_BIT(I2Cx->CR1, I2C_CR1_SMBUS | I2C_CR1_SMBTYPE | I2C_CR1_ENARP));
+}
+
+/**
+ * @brief Enable SMBus alert (Host or Device mode)
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @note SMBus Device mode:
+ * - SMBus Alert pin is drived low and
+ * Alert Response Address Header acknowledge is enabled.
+ * SMBus Host mode:
+ * - SMBus Alert pin management is supported.
+ * @rmtoll CR1 ALERT LL_I2C_EnableSMBusAlert
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableSMBusAlert(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_ALERT);
+}
+
+/**
+ * @brief Disable SMBus alert (Host or Device mode)
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @note SMBus Device mode:
+ * - SMBus Alert pin is not drived (can be used as a standard GPIO) and
+ * Alert Response Address Header acknowledge is disabled.
+ * SMBus Host mode:
+ * - SMBus Alert pin management is not supported.
+ * @rmtoll CR1 ALERT LL_I2C_DisableSMBusAlert
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableSMBusAlert(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR1, I2C_CR1_ALERT);
+}
+
+/**
+ * @brief Check if SMBus alert (Host or Device mode) is enabled or disabled.
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll CR1 ALERT LL_I2C_IsEnabledSMBusAlert
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledSMBusAlert(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR1, I2C_CR1_ALERT) == (I2C_CR1_ALERT));
+}
+
+/**
+ * @brief Enable SMBus Packet Error Calculation (PEC).
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll CR1 ENPEC LL_I2C_EnableSMBusPEC
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableSMBusPEC(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_ENPEC);
+}
+
+/**
+ * @brief Disable SMBus Packet Error Calculation (PEC).
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll CR1 ENPEC LL_I2C_DisableSMBusPEC
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableSMBusPEC(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR1, I2C_CR1_ENPEC);
+}
+
+/**
+ * @brief Check if SMBus Packet Error Calculation (PEC) is enabled or disabled.
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll CR1 ENPEC LL_I2C_IsEnabledSMBusPEC
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledSMBusPEC(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR1, I2C_CR1_ENPEC) == (I2C_CR1_ENPEC));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EF_IT_Management IT_Management
+ * @{
+ */
+
+/**
+ * @brief Enable TXE interrupt.
+ * @rmtoll CR2 ITEVTEN LL_I2C_EnableIT_TX\n
+ * CR2 ITBUFEN LL_I2C_EnableIT_TX
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableIT_TX(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
+}
+
+/**
+ * @brief Disable TXE interrupt.
+ * @rmtoll CR2 ITEVTEN LL_I2C_DisableIT_TX\n
+ * CR2 ITBUFEN LL_I2C_DisableIT_TX
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableIT_TX(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
+}
+
+/**
+ * @brief Check if the TXE Interrupt is enabled or disabled.
+ * @rmtoll CR2 ITEVTEN LL_I2C_IsEnabledIT_TX\n
+ * CR2 ITBUFEN LL_I2C_IsEnabledIT_TX
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_TX(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN) == (I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN));
+}
+
+/**
+ * @brief Enable RXNE interrupt.
+ * @rmtoll CR2 ITEVTEN LL_I2C_EnableIT_RX\n
+ * CR2 ITBUFEN LL_I2C_EnableIT_RX
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableIT_RX(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
+}
+
+/**
+ * @brief Disable RXNE interrupt.
+ * @rmtoll CR2 ITEVTEN LL_I2C_DisableIT_RX\n
+ * CR2 ITBUFEN LL_I2C_DisableIT_RX
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableIT_RX(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
+}
+
+/**
+ * @brief Check if the RXNE Interrupt is enabled or disabled.
+ * @rmtoll CR2 ITEVTEN LL_I2C_IsEnabledIT_RX\n
+ * CR2 ITBUFEN LL_I2C_IsEnabledIT_RX
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_RX(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN) == (I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN));
+}
+
+/**
+ * @brief Enable Events interrupts.
+ * @note Any of these events will generate interrupt :
+ * Start Bit (SB)
+ * Address sent, Address matched (ADDR)
+ * 10-bit header sent (ADD10)
+ * Stop detection (STOPF)
+ * Byte transfer finished (BTF)
+ *
+ * @note Any of these events will generate interrupt if Buffer interrupts are enabled too(using unitary function @ref LL_I2C_EnableIT_BUF()) :
+ * Receive buffer not empty (RXNE)
+ * Transmit buffer empty (TXE)
+ * @rmtoll CR2 ITEVTEN LL_I2C_EnableIT_EVT
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableIT_EVT(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN);
+}
+
+/**
+ * @brief Disable Events interrupts.
+ * @note Any of these events will generate interrupt :
+ * Start Bit (SB)
+ * Address sent, Address matched (ADDR)
+ * 10-bit header sent (ADD10)
+ * Stop detection (STOPF)
+ * Byte transfer finished (BTF)
+ * Receive buffer not empty (RXNE)
+ * Transmit buffer empty (TXE)
+ * @rmtoll CR2 ITEVTEN LL_I2C_DisableIT_EVT
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableIT_EVT(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN);
+}
+
+/**
+ * @brief Check if Events interrupts are enabled or disabled.
+ * @rmtoll CR2 ITEVTEN LL_I2C_IsEnabledIT_EVT
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_EVT(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN) == (I2C_CR2_ITEVTEN));
+}
+
+/**
+ * @brief Enable Buffer interrupts.
+ * @note Any of these Buffer events will generate interrupt if Events interrupts are enabled too(using unitary function @ref LL_I2C_EnableIT_EVT()) :
+ * Receive buffer not empty (RXNE)
+ * Transmit buffer empty (TXE)
+ * @rmtoll CR2 ITBUFEN LL_I2C_EnableIT_BUF
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableIT_BUF(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR2, I2C_CR2_ITBUFEN);
+}
+
+/**
+ * @brief Disable Buffer interrupts.
+ * @note Any of these Buffer events will generate interrupt :
+ * Receive buffer not empty (RXNE)
+ * Transmit buffer empty (TXE)
+ * @rmtoll CR2 ITBUFEN LL_I2C_DisableIT_BUF
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableIT_BUF(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR2, I2C_CR2_ITBUFEN);
+}
+
+/**
+ * @brief Check if Buffer interrupts are enabled or disabled.
+ * @rmtoll CR2 ITBUFEN LL_I2C_IsEnabledIT_BUF
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_BUF(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR2, I2C_CR2_ITBUFEN) == (I2C_CR2_ITBUFEN));
+}
+
+/**
+ * @brief Enable Error interrupts.
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @note Any of these errors will generate interrupt :
+ * Bus Error detection (BERR)
+ * Arbitration Loss (ARLO)
+ * Acknowledge Failure(AF)
+ * Overrun/Underrun (OVR)
+ * SMBus Timeout detection (TIMEOUT)
+ * SMBus PEC error detection (PECERR)
+ * SMBus Alert pin event detection (SMBALERT)
+ * @rmtoll CR2 ITERREN LL_I2C_EnableIT_ERR
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableIT_ERR(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR2, I2C_CR2_ITERREN);
+}
+
+/**
+ * @brief Disable Error interrupts.
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @note Any of these errors will generate interrupt :
+ * Bus Error detection (BERR)
+ * Arbitration Loss (ARLO)
+ * Acknowledge Failure(AF)
+ * Overrun/Underrun (OVR)
+ * SMBus Timeout detection (TIMEOUT)
+ * SMBus PEC error detection (PECERR)
+ * SMBus Alert pin event detection (SMBALERT)
+ * @rmtoll CR2 ITERREN LL_I2C_DisableIT_ERR
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableIT_ERR(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR2, I2C_CR2_ITERREN);
+}
+
+/**
+ * @brief Check if Error interrupts are enabled or disabled.
+ * @rmtoll CR2 ITERREN LL_I2C_IsEnabledIT_ERR
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_ERR(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR2, I2C_CR2_ITERREN) == (I2C_CR2_ITERREN));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EF_FLAG_management FLAG_management
+ * @{
+ */
+
+/**
+ * @brief Indicate the status of Transmit data register empty flag.
+ * @note RESET: When next data is written in Transmit data register.
+ * SET: When Transmit data register is empty.
+ * @rmtoll SR1 TXE LL_I2C_IsActiveFlag_TXE
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_TXE(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_TXE) == (I2C_SR1_TXE));
+}
+
+/**
+ * @brief Indicate the status of Byte Transfer Finished flag.
+ * RESET: When Data byte transfer not done.
+ * SET: When Data byte transfer succeeded.
+ * @rmtoll SR1 BTF LL_I2C_IsActiveFlag_BTF
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_BTF(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_BTF) == (I2C_SR1_BTF));
+}
+
+/**
+ * @brief Indicate the status of Receive data register not empty flag.
+ * @note RESET: When Receive data register is read.
+ * SET: When the received data is copied in Receive data register.
+ * @rmtoll SR1 RXNE LL_I2C_IsActiveFlag_RXNE
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_RXNE(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_RXNE) == (I2C_SR1_RXNE));
+}
+
+/**
+ * @brief Indicate the status of Start Bit (master mode).
+ * @note RESET: When No Start condition.
+ * SET: When Start condition is generated.
+ * @rmtoll SR1 SB LL_I2C_IsActiveFlag_SB
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_SB(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_SB) == (I2C_SR1_SB));
+}
+
+/**
+ * @brief Indicate the status of Address sent (master mode) or Address matched flag (slave mode).
+ * @note RESET: Clear default value.
+ * SET: When the address is fully sent (master mode) or when the received slave address matched with one of the enabled slave address (slave mode).
+ * @rmtoll SR1 ADDR LL_I2C_IsActiveFlag_ADDR
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_ADDR(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_ADDR) == (I2C_SR1_ADDR));
+}
+
+/**
+ * @brief Indicate the status of 10-bit header sent (master mode).
+ * @note RESET: When no ADD10 event occured.
+ * SET: When the master has sent the first address byte (header).
+ * @rmtoll SR1 ADD10 LL_I2C_IsActiveFlag_ADD10
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_ADD10(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_ADD10) == (I2C_SR1_ADD10));
+}
+
+/**
+ * @brief Indicate the status of Acknowledge failure flag.
+ * @note RESET: No acknowledge failure.
+ * SET: When an acknowledge failure is received after a byte transmission.
+ * @rmtoll SR1 AF LL_I2C_IsActiveFlag_AF
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_AF(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_AF) == (I2C_SR1_AF));
+}
+
+/**
+ * @brief Indicate the status of Stop detection flag (slave mode).
+ * @note RESET: Clear default value.
+ * SET: When a Stop condition is detected.
+ * @rmtoll SR1 STOPF LL_I2C_IsActiveFlag_STOP
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_STOP(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_STOPF) == (I2C_SR1_STOPF));
+}
+
+/**
+ * @brief Indicate the status of Bus error flag.
+ * @note RESET: Clear default value.
+ * SET: When a misplaced Start or Stop condition is detected.
+ * @rmtoll SR1 BERR LL_I2C_IsActiveFlag_BERR
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_BERR(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_BERR) == (I2C_SR1_BERR));
+}
+
+/**
+ * @brief Indicate the status of Arbitration lost flag.
+ * @note RESET: Clear default value.
+ * SET: When arbitration lost.
+ * @rmtoll SR1 ARLO LL_I2C_IsActiveFlag_ARLO
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_ARLO(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_ARLO) == (I2C_SR1_ARLO));
+}
+
+/**
+ * @brief Indicate the status of Overrun/Underrun flag.
+ * @note RESET: Clear default value.
+ * SET: When an overrun/underrun error occurs (Clock Stretching Disabled).
+ * @rmtoll SR1 OVR LL_I2C_IsActiveFlag_OVR
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_OVR(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_OVR) == (I2C_SR1_OVR));
+}
+
+/**
+ * @brief Indicate the status of SMBus PEC error flag in reception.
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll SR1 PECERR LL_I2C_IsActiveSMBusFlag_PECERR
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_PECERR(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_PECERR) == (I2C_SR1_PECERR));
+}
+
+/**
+ * @brief Indicate the status of SMBus Timeout detection flag.
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll SR1 TIMEOUT LL_I2C_IsActiveSMBusFlag_TIMEOUT
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_TIMEOUT(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_TIMEOUT) == (I2C_SR1_TIMEOUT));
+}
+
+/**
+ * @brief Indicate the status of SMBus alert flag.
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll SR1 SMBALERT LL_I2C_IsActiveSMBusFlag_ALERT
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_ALERT(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_SMBALERT) == (I2C_SR1_SMBALERT));
+}
+
+/**
+ * @brief Indicate the status of Bus Busy flag.
+ * @note RESET: Clear default value.
+ * SET: When a Start condition is detected.
+ * @rmtoll SR2 BUSY LL_I2C_IsActiveFlag_BUSY
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_BUSY(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR2, I2C_SR2_BUSY) == (I2C_SR2_BUSY));
+}
+
+/**
+ * @brief Indicate the status of Dual flag.
+ * @note RESET: Received address matched with OAR1.
+ * SET: Received address matched with OAR2.
+ * @rmtoll SR2 DUALF LL_I2C_IsActiveFlag_DUAL
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_DUAL(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR2, I2C_SR2_DUALF) == (I2C_SR2_DUALF));
+}
+
+/**
+ * @brief Indicate the status of SMBus Host address reception (Slave mode).
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @note RESET: No SMBus Host address
+ * SET: SMBus Host address received.
+ * @note This status is cleared by hardware after a STOP condition or repeated START condition.
+ * @rmtoll SR2 SMBHOST LL_I2C_IsActiveSMBusFlag_SMBHOST
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_SMBHOST(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR2, I2C_SR2_SMBHOST) == (I2C_SR2_SMBHOST));
+}
+
+/**
+ * @brief Indicate the status of SMBus Device default address reception (Slave mode).
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @note RESET: No SMBus Device default address
+ * SET: SMBus Device default address received.
+ * @note This status is cleared by hardware after a STOP condition or repeated START condition.
+ * @rmtoll SR2 SMBDEFAULT LL_I2C_IsActiveSMBusFlag_SMBDEFAULT
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_SMBDEFAULT(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR2, I2C_SR2_SMBDEFAULT) == (I2C_SR2_SMBDEFAULT));
+}
+
+/**
+ * @brief Indicate the status of General call address reception (Slave mode).
+ * @note RESET: No Generall call address
+ * SET: General call address received.
+ * @note This status is cleared by hardware after a STOP condition or repeated START condition.
+ * @rmtoll SR2 GENCALL LL_I2C_IsActiveFlag_GENCALL
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_GENCALL(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR2, I2C_SR2_GENCALL) == (I2C_SR2_GENCALL));
+}
+
+/**
+ * @brief Indicate the status of Master/Slave flag.
+ * @note RESET: Slave Mode.
+ * SET: Master Mode.
+ * @rmtoll SR2 MSL LL_I2C_IsActiveFlag_MSL
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_MSL(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR2, I2C_SR2_MSL) == (I2C_SR2_MSL));
+}
+
+/**
+ * @brief Clear Address Matched flag.
+ * @note Clearing this flag is done by a read access to the I2Cx_SR1
+ * register followed by a read access to the I2Cx_SR2 register.
+ * @rmtoll SR1 ADDR LL_I2C_ClearFlag_ADDR
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearFlag_ADDR(I2C_TypeDef *I2Cx)
+{
+ __IO uint32_t tmpreg;
+ tmpreg = I2Cx->SR1;
+ (void) tmpreg;
+ tmpreg = I2Cx->SR2;
+ (void) tmpreg;
+}
+
+/**
+ * @brief Clear Acknowledge failure flag.
+ * @rmtoll SR1 AF LL_I2C_ClearFlag_AF
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearFlag_AF(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->SR1, I2C_SR1_AF);
+}
+
+/**
+ * @brief Clear Stop detection flag.
+ * @note Clearing this flag is done by a read access to the I2Cx_SR1
+ * register followed by a write access to I2Cx_CR1 register.
+ * @rmtoll SR1 STOPF LL_I2C_ClearFlag_STOP\n
+ * CR1 PE LL_I2C_ClearFlag_STOP
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearFlag_STOP(I2C_TypeDef *I2Cx)
+{
+ __IO uint32_t tmpreg;
+ tmpreg = I2Cx->SR1;
+ (void) tmpreg;
+ SET_BIT(I2Cx->CR1, I2C_CR1_PE);
+}
+
+/**
+ * @brief Clear Bus error flag.
+ * @rmtoll SR1 BERR LL_I2C_ClearFlag_BERR
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearFlag_BERR(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->SR1, I2C_SR1_BERR);
+}
+
+/**
+ * @brief Clear Arbitration lost flag.
+ * @rmtoll SR1 ARLO LL_I2C_ClearFlag_ARLO
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearFlag_ARLO(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->SR1, I2C_SR1_ARLO);
+}
+
+/**
+ * @brief Clear Overrun/Underrun flag.
+ * @rmtoll SR1 OVR LL_I2C_ClearFlag_OVR
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearFlag_OVR(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->SR1, I2C_SR1_OVR);
+}
+
+/**
+ * @brief Clear SMBus PEC error flag.
+ * @rmtoll SR1 PECERR LL_I2C_ClearSMBusFlag_PECERR
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearSMBusFlag_PECERR(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->SR1, I2C_SR1_PECERR);
+}
+
+/**
+ * @brief Clear SMBus Timeout detection flag.
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll SR1 TIMEOUT LL_I2C_ClearSMBusFlag_TIMEOUT
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearSMBusFlag_TIMEOUT(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->SR1, I2C_SR1_TIMEOUT);
+}
+
+/**
+ * @brief Clear SMBus Alert flag.
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll SR1 SMBALERT LL_I2C_ClearSMBusFlag_ALERT
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearSMBusFlag_ALERT(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->SR1, I2C_SR1_SMBALERT);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EF_Data_Management Data_Management
+ * @{
+ */
+
+/**
+ * @brief Enable Reset of I2C peripheral.
+ * @rmtoll CR1 SWRST LL_I2C_EnableReset
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableReset(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_SWRST);
+}
+
+/**
+ * @brief Disable Reset of I2C peripheral.
+ * @rmtoll CR1 SWRST LL_I2C_DisableReset
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableReset(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR1, I2C_CR1_SWRST);
+}
+
+/**
+ * @brief Check if the I2C peripheral is under reset state or not.
+ * @rmtoll CR1 SWRST LL_I2C_IsResetEnabled
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsResetEnabled(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR1, I2C_CR1_SWRST) == (I2C_CR1_SWRST));
+}
+
+/**
+ * @brief Prepare the generation of a ACKnowledge or Non ACKnowledge condition after the address receive match code or next received byte.
+ * @note Usage in Slave or Master mode.
+ * @rmtoll CR1 ACK LL_I2C_AcknowledgeNextData
+ * @param I2Cx I2C Instance.
+ * @param TypeAcknowledge This parameter can be one of the following values:
+ * @arg @ref LL_I2C_ACK
+ * @arg @ref LL_I2C_NACK
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_AcknowledgeNextData(I2C_TypeDef *I2Cx, uint32_t TypeAcknowledge)
+{
+ MODIFY_REG(I2Cx->CR1, I2C_CR1_ACK, TypeAcknowledge);
+}
+
+/**
+ * @brief Generate a START or RESTART condition
+ * @note The START bit can be set even if bus is BUSY or I2C is in slave mode.
+ * This action has no effect when RELOAD is set.
+ * @rmtoll CR1 START LL_I2C_GenerateStartCondition
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_GenerateStartCondition(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_START);
+}
+
+/**
+ * @brief Generate a STOP condition after the current byte transfer (master mode).
+ * @rmtoll CR1 STOP LL_I2C_GenerateStopCondition
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_GenerateStopCondition(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_STOP);
+}
+
+/**
+ * @brief Enable bit POS (master/host mode).
+ * @note In that case, the ACK bit controls the (N)ACK of the next byte received or the PEC bit indicates that the next byte in shift register is a PEC.
+ * @rmtoll CR1 POS LL_I2C_EnableBitPOS
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableBitPOS(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_POS);
+}
+
+/**
+ * @brief Disable bit POS (master/host mode).
+ * @note In that case, the ACK bit controls the (N)ACK of the current byte received or the PEC bit indicates that the current byte in shift register is a PEC.
+ * @rmtoll CR1 POS LL_I2C_DisableBitPOS
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableBitPOS(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR1, I2C_CR1_POS);
+}
+
+/**
+ * @brief Check if bit POS is enabled or disabled.
+ * @rmtoll CR1 POS LL_I2C_IsEnabledBitPOS
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledBitPOS(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR1, I2C_CR1_POS) == (I2C_CR1_POS));
+}
+
+/**
+ * @brief Indicate the value of transfer direction.
+ * @note RESET: Bus is in read transfer (peripheral point of view).
+ * SET: Bus is in write transfer (peripheral point of view).
+ * @rmtoll SR2 TRA LL_I2C_GetTransferDirection
+ * @param I2Cx I2C Instance.
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_I2C_DIRECTION_WRITE
+ * @arg @ref LL_I2C_DIRECTION_READ
+ */
+__STATIC_INLINE uint32_t LL_I2C_GetTransferDirection(I2C_TypeDef *I2Cx)
+{
+ return (uint32_t)(READ_BIT(I2Cx->SR2, I2C_SR2_TRA));
+}
+
+/**
+ * @brief Enable DMA last transfer.
+ * @note This action mean that next DMA EOT is the last transfer.
+ * @rmtoll CR2 LAST LL_I2C_EnableLastDMA
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableLastDMA(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR2, I2C_CR2_LAST);
+}
+
+/**
+ * @brief Disable DMA last transfer.
+ * @note This action mean that next DMA EOT is not the last transfer.
+ * @rmtoll CR2 LAST LL_I2C_DisableLastDMA
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableLastDMA(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR2, I2C_CR2_LAST);
+}
+
+/**
+ * @brief Check if DMA last transfer is enabled or disabled.
+ * @rmtoll CR2 LAST LL_I2C_IsEnabledLastDMA
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledLastDMA(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR2, I2C_CR2_LAST) == (I2C_CR2_LAST));
+}
+
+/**
+ * @brief Enable transfer or internal comparison of the SMBus Packet Error byte (transmission or reception mode).
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @note This feature is cleared by hardware when the PEC byte is transferred or compared,
+ * or by a START or STOP condition, it is also cleared by software.
+ * @rmtoll CR1 PEC LL_I2C_EnableSMBusPECCompare
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableSMBusPECCompare(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_PEC);
+}
+
+/**
+ * @brief Disable transfer or internal comparison of the SMBus Packet Error byte (transmission or reception mode).
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll CR1 PEC LL_I2C_DisableSMBusPECCompare
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableSMBusPECCompare(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR1, I2C_CR1_PEC);
+}
+
+/**
+ * @brief Check if the SMBus Packet Error byte transfer or internal comparison is requested or not.
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll CR1 PEC LL_I2C_IsEnabledSMBusPECCompare
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledSMBusPECCompare(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR1, I2C_CR1_PEC) == (I2C_CR1_PEC));
+}
+
+/**
+ * @brief Get the SMBus Packet Error byte calculated.
+ * @note Macro @ref IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll SR2 PEC LL_I2C_GetSMBusPEC
+ * @param I2Cx I2C Instance.
+ * @retval Value between Min_Data=0x00 and Max_Data=0xFF
+ */
+__STATIC_INLINE uint32_t LL_I2C_GetSMBusPEC(I2C_TypeDef *I2Cx)
+{
+ return (uint32_t)(READ_BIT(I2Cx->SR2, I2C_SR2_PEC) >> I2C_SR2_PEC_Pos);
+}
+
+/**
+ * @brief Read Receive Data register.
+ * @rmtoll DR DR LL_I2C_ReceiveData8
+ * @param I2Cx I2C Instance.
+ * @retval Value between Min_Data=0x0 and Max_Data=0xFF
+ */
+__STATIC_INLINE uint8_t LL_I2C_ReceiveData8(I2C_TypeDef *I2Cx)
+{
+ return (uint8_t)(READ_BIT(I2Cx->DR, I2C_DR_DR));
+}
+
+/**
+ * @brief Write in Transmit Data Register .
+ * @rmtoll DR DR LL_I2C_TransmitData8
+ * @param I2Cx I2C Instance.
+ * @param Data Value between Min_Data=0x0 and Max_Data=0xFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_TransmitData8(I2C_TypeDef *I2Cx, uint8_t Data)
+{
+ MODIFY_REG(I2Cx->DR, I2C_DR_DR, Data);
+}
+
+/**
+ * @}
+ */
+
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup I2C_LL_EF_Init Initialization and de-initialization functions
+ * @{
+ */
+
+uint32_t LL_I2C_Init(I2C_TypeDef *I2Cx, LL_I2C_InitTypeDef *I2C_InitStruct);
+uint32_t LL_I2C_DeInit(I2C_TypeDef *I2Cx);
+void LL_I2C_StructInit(LL_I2C_InitTypeDef *I2C_InitStruct);
+
+
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* I2C1 || I2C2 */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_LL_I2C_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_iwdg.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_iwdg.h
new file mode 100644
index 0000000..0f39fb5
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_iwdg.h
@@ -0,0 +1,327 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_iwdg.h
+ * @author MCD Application Team
+ * @brief Header file of IWDG LL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_IWDG_H
+#define __STM32F1xx_LL_IWDG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx.h"
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined(IWDG)
+
+/** @defgroup IWDG_LL IWDG
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup IWDG_LL_Private_Constants IWDG Private Constants
+ * @{
+ */
+
+#define LL_IWDG_KEY_RELOAD 0x0000AAAAU /*!< IWDG Reload Counter Enable */
+#define LL_IWDG_KEY_ENABLE 0x0000CCCCU /*!< IWDG Peripheral Enable */
+#define LL_IWDG_KEY_WR_ACCESS_ENABLE 0x00005555U /*!< IWDG KR Write Access Enable */
+#define LL_IWDG_KEY_WR_ACCESS_DISABLE 0x00000000U /*!< IWDG KR Write Access Disable */
+
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup IWDG_LL_Exported_Constants IWDG Exported Constants
+ * @{
+ */
+
+/** @defgroup IWDG_LL_EC_GET_FLAG Get Flags Defines
+ * @brief Flags defines which can be used with LL_IWDG_ReadReg function
+ * @{
+ */
+#define LL_IWDG_SR_PVU IWDG_SR_PVU /*!< Watchdog prescaler value update */
+#define LL_IWDG_SR_RVU IWDG_SR_RVU /*!< Watchdog counter reload value update */
+
+/**
+ * @}
+ */
+
+/** @defgroup IWDG_LL_EC_PRESCALER Prescaler Divider
+ * @{
+ */
+#define LL_IWDG_PRESCALER_4 0x00000000U /*!< Divider by 4 */
+#define LL_IWDG_PRESCALER_8 (IWDG_PR_PR_0) /*!< Divider by 8 */
+#define LL_IWDG_PRESCALER_16 (IWDG_PR_PR_1) /*!< Divider by 16 */
+#define LL_IWDG_PRESCALER_32 (IWDG_PR_PR_1 | IWDG_PR_PR_0) /*!< Divider by 32 */
+#define LL_IWDG_PRESCALER_64 (IWDG_PR_PR_2) /*!< Divider by 64 */
+#define LL_IWDG_PRESCALER_128 (IWDG_PR_PR_2 | IWDG_PR_PR_0) /*!< Divider by 128 */
+#define LL_IWDG_PRESCALER_256 (IWDG_PR_PR_2 | IWDG_PR_PR_1) /*!< Divider by 256 */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup IWDG_LL_Exported_Macros IWDG Exported Macros
+ * @{
+ */
+
+/** @defgroup IWDG_LL_EM_WRITE_READ Common Write and read registers Macros
+ * @{
+ */
+
+/**
+ * @brief Write a value in IWDG register
+ * @param __INSTANCE__ IWDG Instance
+ * @param __REG__ Register to be written
+ * @param __VALUE__ Value to be written in the register
+ * @retval None
+ */
+#define LL_IWDG_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
+
+/**
+ * @brief Read a value in IWDG register
+ * @param __INSTANCE__ IWDG Instance
+ * @param __REG__ Register to be read
+ * @retval Register value
+ */
+#define LL_IWDG_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup IWDG_LL_Exported_Functions IWDG Exported Functions
+ * @{
+ */
+/** @defgroup IWDG_LL_EF_Configuration Configuration
+ * @{
+ */
+
+/**
+ * @brief Start the Independent Watchdog
+ * @note Except if the hardware watchdog option is selected
+ * @rmtoll KR KEY LL_IWDG_Enable
+ * @param IWDGx IWDG Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_IWDG_Enable(IWDG_TypeDef *IWDGx)
+{
+ WRITE_REG(IWDG->KR, LL_IWDG_KEY_ENABLE);
+}
+
+/**
+ * @brief Reloads IWDG counter with value defined in the reload register
+ * @rmtoll KR KEY LL_IWDG_ReloadCounter
+ * @param IWDGx IWDG Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_IWDG_ReloadCounter(IWDG_TypeDef *IWDGx)
+{
+ WRITE_REG(IWDG->KR, LL_IWDG_KEY_RELOAD);
+}
+
+/**
+ * @brief Enable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers
+ * @rmtoll KR KEY LL_IWDG_EnableWriteAccess
+ * @param IWDGx IWDG Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_IWDG_EnableWriteAccess(IWDG_TypeDef *IWDGx)
+{
+ WRITE_REG(IWDG->KR, LL_IWDG_KEY_WR_ACCESS_ENABLE);
+}
+
+/**
+ * @brief Disable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers
+ * @rmtoll KR KEY LL_IWDG_DisableWriteAccess
+ * @param IWDGx IWDG Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_IWDG_DisableWriteAccess(IWDG_TypeDef *IWDGx)
+{
+ WRITE_REG(IWDG->KR, LL_IWDG_KEY_WR_ACCESS_DISABLE);
+}
+
+/**
+ * @brief Select the prescaler of the IWDG
+ * @rmtoll PR PR LL_IWDG_SetPrescaler
+ * @param IWDGx IWDG Instance
+ * @param Prescaler This parameter can be one of the following values:
+ * @arg @ref LL_IWDG_PRESCALER_4
+ * @arg @ref LL_IWDG_PRESCALER_8
+ * @arg @ref LL_IWDG_PRESCALER_16
+ * @arg @ref LL_IWDG_PRESCALER_32
+ * @arg @ref LL_IWDG_PRESCALER_64
+ * @arg @ref LL_IWDG_PRESCALER_128
+ * @arg @ref LL_IWDG_PRESCALER_256
+ * @retval None
+ */
+__STATIC_INLINE void LL_IWDG_SetPrescaler(IWDG_TypeDef *IWDGx, uint32_t Prescaler)
+{
+ WRITE_REG(IWDGx->PR, IWDG_PR_PR & Prescaler);
+}
+
+/**
+ * @brief Get the selected prescaler of the IWDG
+ * @rmtoll PR PR LL_IWDG_GetPrescaler
+ * @param IWDGx IWDG Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_IWDG_PRESCALER_4
+ * @arg @ref LL_IWDG_PRESCALER_8
+ * @arg @ref LL_IWDG_PRESCALER_16
+ * @arg @ref LL_IWDG_PRESCALER_32
+ * @arg @ref LL_IWDG_PRESCALER_64
+ * @arg @ref LL_IWDG_PRESCALER_128
+ * @arg @ref LL_IWDG_PRESCALER_256
+ */
+__STATIC_INLINE uint32_t LL_IWDG_GetPrescaler(IWDG_TypeDef *IWDGx)
+{
+ return (uint32_t)(READ_REG(IWDGx->PR));
+}
+
+/**
+ * @brief Specify the IWDG down-counter reload value
+ * @rmtoll RLR RL LL_IWDG_SetReloadCounter
+ * @param IWDGx IWDG Instance
+ * @param Counter Value between Min_Data=0 and Max_Data=0x0FFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_IWDG_SetReloadCounter(IWDG_TypeDef *IWDGx, uint32_t Counter)
+{
+ WRITE_REG(IWDGx->RLR, IWDG_RLR_RL & Counter);
+}
+
+/**
+ * @brief Get the specified IWDG down-counter reload value
+ * @rmtoll RLR RL LL_IWDG_GetReloadCounter
+ * @param IWDGx IWDG Instance
+ * @retval Value between Min_Data=0 and Max_Data=0x0FFF
+ */
+__STATIC_INLINE uint32_t LL_IWDG_GetReloadCounter(IWDG_TypeDef *IWDGx)
+{
+ return (uint32_t)(READ_REG(IWDGx->RLR));
+}
+
+
+/**
+ * @}
+ */
+
+/** @defgroup IWDG_LL_EF_FLAG_Management FLAG_Management
+ * @{
+ */
+
+/**
+ * @brief Check if flag Prescaler Value Update is set or not
+ * @rmtoll SR PVU LL_IWDG_IsActiveFlag_PVU
+ * @param IWDGx IWDG Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_IWDG_IsActiveFlag_PVU(IWDG_TypeDef *IWDGx)
+{
+ return (READ_BIT(IWDGx->SR, IWDG_SR_PVU) == (IWDG_SR_PVU));
+}
+
+/**
+ * @brief Check if flag Reload Value Update is set or not
+ * @rmtoll SR RVU LL_IWDG_IsActiveFlag_RVU
+ * @param IWDGx IWDG Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_IWDG_IsActiveFlag_RVU(IWDG_TypeDef *IWDGx)
+{
+ return (READ_BIT(IWDGx->SR, IWDG_SR_RVU) == (IWDG_SR_RVU));
+}
+
+
+/**
+ * @brief Check if all flags Prescaler, Reload & Window Value Update are reset or not
+ * @rmtoll SR PVU LL_IWDG_IsReady\n
+ * SR RVU LL_IWDG_IsReady
+ * @param IWDGx IWDG Instance
+ * @retval State of bits (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_IWDG_IsReady(IWDG_TypeDef *IWDGx)
+{
+ return (READ_BIT(IWDGx->SR, IWDG_SR_PVU | IWDG_SR_RVU) == 0U);
+}
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* IWDG) */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_LL_IWDG_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_pwr.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_pwr.h
new file mode 100644
index 0000000..f4106da
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_pwr.h
@@ -0,0 +1,456 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_pwr.h
+ * @author MCD Application Team
+ * @brief Header file of PWR LL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_PWR_H
+#define __STM32F1xx_LL_PWR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx.h"
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined(PWR)
+
+/** @defgroup PWR_LL PWR
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup PWR_LL_Exported_Constants PWR Exported Constants
+ * @{
+ */
+
+/** @defgroup PWR_LL_EC_CLEAR_FLAG Clear Flags Defines
+ * @brief Flags defines which can be used with LL_PWR_WriteReg function
+ * @{
+ */
+#define LL_PWR_CR_CSBF PWR_CR_CSBF /*!< Clear standby flag */
+#define LL_PWR_CR_CWUF PWR_CR_CWUF /*!< Clear wakeup flag */
+/**
+ * @}
+ */
+
+/** @defgroup PWR_LL_EC_GET_FLAG Get Flags Defines
+ * @brief Flags defines which can be used with LL_PWR_ReadReg function
+ * @{
+ */
+#define LL_PWR_CSR_WUF PWR_CSR_WUF /*!< Wakeup flag */
+#define LL_PWR_CSR_SBF PWR_CSR_SBF /*!< Standby flag */
+#define LL_PWR_CSR_PVDO PWR_CSR_PVDO /*!< Power voltage detector output flag */
+#define LL_PWR_CSR_EWUP1 PWR_CSR_EWUP /*!< Enable WKUP pin 1 */
+/**
+ * @}
+ */
+
+
+/** @defgroup PWR_LL_EC_MODE_PWR Mode Power
+ * @{
+ */
+#define LL_PWR_MODE_STOP_MAINREGU 0x00000000U /*!< Enter Stop mode when the CPU enters deepsleep */
+#define LL_PWR_MODE_STOP_LPREGU (PWR_CR_LPDS) /*!< Enter Stop mode (with low power Regulator ON) when the CPU enters deepsleep */
+#define LL_PWR_MODE_STANDBY (PWR_CR_PDDS) /*!< Enter Standby mode when the CPU enters deepsleep */
+/**
+ * @}
+ */
+
+/** @defgroup PWR_LL_EC_REGU_MODE_DS_MODE Regulator Mode In Deep Sleep Mode
+ * @{
+ */
+#define LL_PWR_REGU_DSMODE_MAIN 0x00000000U /*!< Voltage Regulator in main mode during deepsleep mode */
+#define LL_PWR_REGU_DSMODE_LOW_POWER (PWR_CR_LPDS) /*!< Voltage Regulator in low-power mode during deepsleep mode */
+/**
+ * @}
+ */
+
+/** @defgroup PWR_LL_EC_PVDLEVEL Power Voltage Detector Level
+ * @{
+ */
+#define LL_PWR_PVDLEVEL_0 (PWR_CR_PLS_LEV0) /*!< Voltage threshold detected by PVD 2.2 V */
+#define LL_PWR_PVDLEVEL_1 (PWR_CR_PLS_LEV1) /*!< Voltage threshold detected by PVD 2.3 V */
+#define LL_PWR_PVDLEVEL_2 (PWR_CR_PLS_LEV2) /*!< Voltage threshold detected by PVD 2.4 V */
+#define LL_PWR_PVDLEVEL_3 (PWR_CR_PLS_LEV3) /*!< Voltage threshold detected by PVD 2.5 V */
+#define LL_PWR_PVDLEVEL_4 (PWR_CR_PLS_LEV4) /*!< Voltage threshold detected by PVD 2.6 V */
+#define LL_PWR_PVDLEVEL_5 (PWR_CR_PLS_LEV5) /*!< Voltage threshold detected by PVD 2.7 V */
+#define LL_PWR_PVDLEVEL_6 (PWR_CR_PLS_LEV6) /*!< Voltage threshold detected by PVD 2.8 V */
+#define LL_PWR_PVDLEVEL_7 (PWR_CR_PLS_LEV7) /*!< Voltage threshold detected by PVD 2.9 V */
+/**
+ * @}
+ */
+/** @defgroup PWR_LL_EC_WAKEUP_PIN Wakeup Pins
+ * @{
+ */
+#define LL_PWR_WAKEUP_PIN1 (PWR_CSR_EWUP) /*!< WKUP pin 1 : PA0 */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup PWR_LL_Exported_Macros PWR Exported Macros
+ * @{
+ */
+
+/** @defgroup PWR_LL_EM_WRITE_READ Common write and read registers Macros
+ * @{
+ */
+
+/**
+ * @brief Write a value in PWR register
+ * @param __REG__ Register to be written
+ * @param __VALUE__ Value to be written in the register
+ * @retval None
+ */
+#define LL_PWR_WriteReg(__REG__, __VALUE__) WRITE_REG(PWR->__REG__, (__VALUE__))
+
+/**
+ * @brief Read a value in PWR register
+ * @param __REG__ Register to be read
+ * @retval Register value
+ */
+#define LL_PWR_ReadReg(__REG__) READ_REG(PWR->__REG__)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup PWR_LL_Exported_Functions PWR Exported Functions
+ * @{
+ */
+
+/** @defgroup PWR_LL_EF_Configuration Configuration
+ * @{
+ */
+
+/**
+ * @brief Enable access to the backup domain
+ * @rmtoll CR DBP LL_PWR_EnableBkUpAccess
+ * @retval None
+ */
+__STATIC_INLINE void LL_PWR_EnableBkUpAccess(void)
+{
+ SET_BIT(PWR->CR, PWR_CR_DBP);
+}
+
+/**
+ * @brief Disable access to the backup domain
+ * @rmtoll CR DBP LL_PWR_DisableBkUpAccess
+ * @retval None
+ */
+__STATIC_INLINE void LL_PWR_DisableBkUpAccess(void)
+{
+ CLEAR_BIT(PWR->CR, PWR_CR_DBP);
+}
+
+/**
+ * @brief Check if the backup domain is enabled
+ * @rmtoll CR DBP LL_PWR_IsEnabledBkUpAccess
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_PWR_IsEnabledBkUpAccess(void)
+{
+ return (READ_BIT(PWR->CR, PWR_CR_DBP) == (PWR_CR_DBP));
+}
+
+/**
+ * @brief Set voltage Regulator mode during deep sleep mode
+ * @rmtoll CR LPDS LL_PWR_SetRegulModeDS
+ * @param RegulMode This parameter can be one of the following values:
+ * @arg @ref LL_PWR_REGU_DSMODE_MAIN
+ * @arg @ref LL_PWR_REGU_DSMODE_LOW_POWER
+ * @retval None
+ */
+__STATIC_INLINE void LL_PWR_SetRegulModeDS(uint32_t RegulMode)
+{
+ MODIFY_REG(PWR->CR, PWR_CR_LPDS, RegulMode);
+}
+
+/**
+ * @brief Get voltage Regulator mode during deep sleep mode
+ * @rmtoll CR LPDS LL_PWR_GetRegulModeDS
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_PWR_REGU_DSMODE_MAIN
+ * @arg @ref LL_PWR_REGU_DSMODE_LOW_POWER
+ */
+__STATIC_INLINE uint32_t LL_PWR_GetRegulModeDS(void)
+{
+ return (uint32_t)(READ_BIT(PWR->CR, PWR_CR_LPDS));
+}
+
+/**
+ * @brief Set Power Down mode when CPU enters deepsleep
+ * @rmtoll CR PDDS LL_PWR_SetPowerMode\n
+ * @rmtoll CR LPDS LL_PWR_SetPowerMode
+ * @param PDMode This parameter can be one of the following values:
+ * @arg @ref LL_PWR_MODE_STOP_MAINREGU
+ * @arg @ref LL_PWR_MODE_STOP_LPREGU
+ * @arg @ref LL_PWR_MODE_STANDBY
+ * @retval None
+ */
+__STATIC_INLINE void LL_PWR_SetPowerMode(uint32_t PDMode)
+{
+ MODIFY_REG(PWR->CR, (PWR_CR_PDDS| PWR_CR_LPDS), PDMode);
+}
+
+/**
+ * @brief Get Power Down mode when CPU enters deepsleep
+ * @rmtoll CR PDDS LL_PWR_GetPowerMode\n
+ * @rmtoll CR LPDS LL_PWR_GetPowerMode
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_PWR_MODE_STOP_MAINREGU
+ * @arg @ref LL_PWR_MODE_STOP_LPREGU
+ * @arg @ref LL_PWR_MODE_STANDBY
+ */
+__STATIC_INLINE uint32_t LL_PWR_GetPowerMode(void)
+{
+ return (uint32_t)(READ_BIT(PWR->CR, (PWR_CR_PDDS| PWR_CR_LPDS)));
+}
+
+/**
+ * @brief Configure the voltage threshold detected by the Power Voltage Detector
+ * @rmtoll CR PLS LL_PWR_SetPVDLevel
+ * @param PVDLevel This parameter can be one of the following values:
+ * @arg @ref LL_PWR_PVDLEVEL_0
+ * @arg @ref LL_PWR_PVDLEVEL_1
+ * @arg @ref LL_PWR_PVDLEVEL_2
+ * @arg @ref LL_PWR_PVDLEVEL_3
+ * @arg @ref LL_PWR_PVDLEVEL_4
+ * @arg @ref LL_PWR_PVDLEVEL_5
+ * @arg @ref LL_PWR_PVDLEVEL_6
+ * @arg @ref LL_PWR_PVDLEVEL_7
+ * @retval None
+ */
+__STATIC_INLINE void LL_PWR_SetPVDLevel(uint32_t PVDLevel)
+{
+ MODIFY_REG(PWR->CR, PWR_CR_PLS, PVDLevel);
+}
+
+/**
+ * @brief Get the voltage threshold detection
+ * @rmtoll CR PLS LL_PWR_GetPVDLevel
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_PWR_PVDLEVEL_0
+ * @arg @ref LL_PWR_PVDLEVEL_1
+ * @arg @ref LL_PWR_PVDLEVEL_2
+ * @arg @ref LL_PWR_PVDLEVEL_3
+ * @arg @ref LL_PWR_PVDLEVEL_4
+ * @arg @ref LL_PWR_PVDLEVEL_5
+ * @arg @ref LL_PWR_PVDLEVEL_6
+ * @arg @ref LL_PWR_PVDLEVEL_7
+ */
+__STATIC_INLINE uint32_t LL_PWR_GetPVDLevel(void)
+{
+ return (uint32_t)(READ_BIT(PWR->CR, PWR_CR_PLS));
+}
+
+/**
+ * @brief Enable Power Voltage Detector
+ * @rmtoll CR PVDE LL_PWR_EnablePVD
+ * @retval None
+ */
+__STATIC_INLINE void LL_PWR_EnablePVD(void)
+{
+ SET_BIT(PWR->CR, PWR_CR_PVDE);
+}
+
+/**
+ * @brief Disable Power Voltage Detector
+ * @rmtoll CR PVDE LL_PWR_DisablePVD
+ * @retval None
+ */
+__STATIC_INLINE void LL_PWR_DisablePVD(void)
+{
+ CLEAR_BIT(PWR->CR, PWR_CR_PVDE);
+}
+
+/**
+ * @brief Check if Power Voltage Detector is enabled
+ * @rmtoll CR PVDE LL_PWR_IsEnabledPVD
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_PWR_IsEnabledPVD(void)
+{
+ return (READ_BIT(PWR->CR, PWR_CR_PVDE) == (PWR_CR_PVDE));
+}
+
+/**
+ * @brief Enable the WakeUp PINx functionality
+ * @rmtoll CSR EWUP LL_PWR_EnableWakeUpPin
+ * @param WakeUpPin This parameter can be one of the following values:
+ * @arg @ref LL_PWR_WAKEUP_PIN1
+ * @retval None
+ */
+__STATIC_INLINE void LL_PWR_EnableWakeUpPin(uint32_t WakeUpPin)
+{
+ SET_BIT(PWR->CSR, WakeUpPin);
+}
+
+/**
+ * @brief Disable the WakeUp PINx functionality
+ * @rmtoll CSR EWUP LL_PWR_DisableWakeUpPin
+ * @param WakeUpPin This parameter can be one of the following values:
+ * @arg @ref LL_PWR_WAKEUP_PIN1
+ * @retval None
+ */
+__STATIC_INLINE void LL_PWR_DisableWakeUpPin(uint32_t WakeUpPin)
+{
+ CLEAR_BIT(PWR->CSR, WakeUpPin);
+}
+
+/**
+ * @brief Check if the WakeUp PINx functionality is enabled
+ * @rmtoll CSR EWUP LL_PWR_IsEnabledWakeUpPin
+ * @param WakeUpPin This parameter can be one of the following values:
+ * @arg @ref LL_PWR_WAKEUP_PIN1
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_PWR_IsEnabledWakeUpPin(uint32_t WakeUpPin)
+{
+ return (READ_BIT(PWR->CSR, WakeUpPin) == (WakeUpPin));
+}
+
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_LL_EF_FLAG_Management FLAG_Management
+ * @{
+ */
+
+/**
+ * @brief Get Wake-up Flag
+ * @rmtoll CSR WUF LL_PWR_IsActiveFlag_WU
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_WU(void)
+{
+ return (READ_BIT(PWR->CSR, PWR_CSR_WUF) == (PWR_CSR_WUF));
+}
+
+/**
+ * @brief Get Standby Flag
+ * @rmtoll CSR SBF LL_PWR_IsActiveFlag_SB
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_SB(void)
+{
+ return (READ_BIT(PWR->CSR, PWR_CSR_SBF) == (PWR_CSR_SBF));
+}
+
+/**
+ * @brief Indicate whether VDD voltage is below the selected PVD threshold
+ * @rmtoll CSR PVDO LL_PWR_IsActiveFlag_PVDO
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_PVDO(void)
+{
+ return (READ_BIT(PWR->CSR, PWR_CSR_PVDO) == (PWR_CSR_PVDO));
+}
+
+/**
+ * @brief Clear Standby Flag
+ * @rmtoll CR CSBF LL_PWR_ClearFlag_SB
+ * @retval None
+ */
+__STATIC_INLINE void LL_PWR_ClearFlag_SB(void)
+{
+ SET_BIT(PWR->CR, PWR_CR_CSBF);
+}
+
+/**
+ * @brief Clear Wake-up Flags
+ * @rmtoll CR CWUF LL_PWR_ClearFlag_WU
+ * @retval None
+ */
+__STATIC_INLINE void LL_PWR_ClearFlag_WU(void)
+{
+ SET_BIT(PWR->CR, PWR_CR_CWUF);
+}
+
+/**
+ * @}
+ */
+
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup PWR_LL_EF_Init De-initialization function
+ * @{
+ */
+ErrorStatus LL_PWR_DeInit(void);
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* defined(PWR) */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_LL_PWR_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_rcc.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_rcc.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_rcc.h
rename to templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_rcc.h
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_rtc.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_rtc.h
new file mode 100644
index 0000000..c434010
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_rtc.h
@@ -0,0 +1,1019 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_rtc.h
+ * @author MCD Application Team
+ * @brief Header file of RTC LL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_RTC_H
+#define __STM32F1xx_LL_RTC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx.h"
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined(RTC)
+
+/** @defgroup RTC_LL RTC
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+
+/* Private macros ------------------------------------------------------------*/
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup RTC_LL_Private_Macros RTC Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+#endif /*USE_FULL_LL_DRIVER*/
+
+/* Exported types ------------------------------------------------------------*/
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup RTC_LL_ES_INIT RTC Exported Init structure
+ * @{
+ */
+
+/**
+ * @brief RTC Init structures definition
+ */
+typedef struct
+{
+ uint32_t AsynchPrescaler; /*!< Specifies the RTC Asynchronous Predivider value.
+ This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFFFFF
+
+ This feature can be modified afterwards using unitary function
+ @ref LL_RTC_SetAsynchPrescaler(). */
+
+ uint32_t OutPutSource; /*!< Specifies which signal will be routed to the RTC Tamper pin.
+ This parameter can be a value of @ref LL_RTC_Output_Source
+
+ This feature can be modified afterwards using unitary function
+ @ref LL_RTC_SetOutputSource(). */
+
+} LL_RTC_InitTypeDef;
+
+/**
+ * @brief RTC Time structure definition
+ */
+typedef struct
+{
+ uint8_t Hours; /*!< Specifies the RTC Time Hours.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 23 */
+
+ uint8_t Minutes; /*!< Specifies the RTC Time Minutes.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 59 */
+
+ uint8_t Seconds; /*!< Specifies the RTC Time Seconds.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 59 */
+} LL_RTC_TimeTypeDef;
+
+
+/**
+ * @brief RTC Alarm structure definition
+ */
+typedef struct
+{
+ LL_RTC_TimeTypeDef AlarmTime; /*!< Specifies the RTC Alarm Time members. */
+
+} LL_RTC_AlarmTypeDef;
+
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup RTC_LL_Exported_Constants RTC Exported Constants
+ * @{
+ */
+
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup RTC_LL_EC_FORMAT FORMAT
+ * @{
+ */
+#define LL_RTC_FORMAT_BIN (0x000000000U) /*!< Binary data format */
+#define LL_RTC_FORMAT_BCD (0x000000001U) /*!< BCD data format */
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/** @defgroup RTC_LL_EC_BKP BACKUP
+ * @{
+ */
+#if RTC_BKP_NUMBER > 0
+#define LL_RTC_BKP_DR1 (0x00000001U)
+#define LL_RTC_BKP_DR2 (0x00000002U)
+#define LL_RTC_BKP_DR3 (0x00000003U)
+#define LL_RTC_BKP_DR4 (0x00000004U)
+#define LL_RTC_BKP_DR5 (0x00000005U)
+#define LL_RTC_BKP_DR6 (0x00000006U)
+#define LL_RTC_BKP_DR7 (0x00000007U)
+#define LL_RTC_BKP_DR8 (0x00000008U)
+#define LL_RTC_BKP_DR9 (0x00000009U)
+#define LL_RTC_BKP_DR10 (0x0000000AU)
+#endif /* RTC_BKP_NUMBER > 0 */
+#if RTC_BKP_NUMBER > 10
+#define LL_RTC_BKP_DR11 (0x0000000BU)
+#define LL_RTC_BKP_DR12 (0x0000000CU)
+#define LL_RTC_BKP_DR13 (0x0000000DU)
+#define LL_RTC_BKP_DR14 (0x0000000EU)
+#define LL_RTC_BKP_DR15 (0x0000000FU)
+#define LL_RTC_BKP_DR16 (0x00000010U)
+#define LL_RTC_BKP_DR17 (0x00000011U)
+#define LL_RTC_BKP_DR18 (0x00000012U)
+#define LL_RTC_BKP_DR19 (0x00000013U)
+#define LL_RTC_BKP_DR20 (0x00000014U)
+#define LL_RTC_BKP_DR21 (0x00000015U)
+#define LL_RTC_BKP_DR22 (0x00000016U)
+#define LL_RTC_BKP_DR23 (0x00000017U)
+#define LL_RTC_BKP_DR24 (0x00000018U)
+#define LL_RTC_BKP_DR25 (0x00000019U)
+#define LL_RTC_BKP_DR26 (0x0000001AU)
+#define LL_RTC_BKP_DR27 (0x0000001BU)
+#define LL_RTC_BKP_DR28 (0x0000001CU)
+#define LL_RTC_BKP_DR29 (0x0000001DU)
+#define LL_RTC_BKP_DR30 (0x0000001EU)
+#define LL_RTC_BKP_DR31 (0x0000001FU)
+#define LL_RTC_BKP_DR32 (0x00000020U)
+#define LL_RTC_BKP_DR33 (0x00000021U)
+#define LL_RTC_BKP_DR34 (0x00000022U)
+#define LL_RTC_BKP_DR35 (0x00000023U)
+#define LL_RTC_BKP_DR36 (0x00000024U)
+#define LL_RTC_BKP_DR37 (0x00000025U)
+#define LL_RTC_BKP_DR38 (0x00000026U)
+#define LL_RTC_BKP_DR39 (0x00000027U)
+#define LL_RTC_BKP_DR40 (0x00000028U)
+#define LL_RTC_BKP_DR41 (0x00000029U)
+#define LL_RTC_BKP_DR42 (0x0000002AU)
+#endif /* RTC_BKP_NUMBER > 10 */
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_LL_EC_TAMPLEVEL Tamper Active Level
+ * @{
+ */
+#define LL_RTC_TAMPER_ACTIVELEVEL_LOW BKP_CR_TPAL /*!< A high level on the TAMPER pin resets all data backup registers (if TPE bit is set) */
+#define LL_RTC_TAMPER_ACTIVELEVEL_HIGH (0x00000000U) /*!< A low level on the TAMPER pin resets all data backup registers (if TPE bit is set) */
+
+/**
+ * @}
+ */
+
+/** @defgroup LL_RTC_Output_Source Clock Source to output on the Tamper Pin
+ * @{
+ */
+#define LL_RTC_CALIB_OUTPUT_NONE (0x00000000U) /*!< Calibration output disabled */
+#define LL_RTC_CALIB_OUTPUT_RTCCLOCK BKP_RTCCR_CCO /*!< Calibration output is RTC Clock with a frequency divided by 64 on the TAMPER Pin */
+#define LL_RTC_CALIB_OUTPUT_ALARM BKP_RTCCR_ASOE /*!< Calibration output is Alarm pulse signal on the TAMPER pin */
+#define LL_RTC_CALIB_OUTPUT_SECOND (BKP_RTCCR_ASOS | BKP_RTCCR_ASOE) /*!< Calibration output is Second pulse signal on the TAMPER pin*/
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup RTC_LL_Exported_Macros RTC Exported Macros
+ * @{
+ */
+
+/** @defgroup RTC_LL_EM_WRITE_READ Common Write and read registers Macros
+ * @{
+ */
+
+/**
+ * @brief Write a value in RTC register
+ * @param __INSTANCE__ RTC Instance
+ * @param __REG__ Register to be written
+ * @param __VALUE__ Value to be written in the register
+ * @retval None
+ */
+#define LL_RTC_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
+
+/**
+ * @brief Read a value in RTC register
+ * @param __INSTANCE__ RTC Instance
+ * @param __REG__ Register to be read
+ * @retval Register value
+ */
+#define LL_RTC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
+/**
+ * @}
+ */
+
+/** @defgroup RTC_LL_EM_Convert Convert helper Macros
+ * @{
+ */
+
+/**
+ * @brief Helper macro to convert a value from 2 digit decimal format to BCD format
+ * @param __VALUE__ Byte to be converted
+ * @retval Converted byte
+ */
+#define __LL_RTC_CONVERT_BIN2BCD(__VALUE__) (uint8_t)((((__VALUE__) / 10U) << 4U) | ((__VALUE__) % 10U))
+
+/**
+ * @brief Helper macro to convert a value from BCD format to 2 digit decimal format
+ * @param __VALUE__ BCD value to be converted
+ * @retval Converted byte
+ */
+#define __LL_RTC_CONVERT_BCD2BIN(__VALUE__) (uint8_t)(((uint8_t)((__VALUE__) & (uint8_t)0xF0U) >> (uint8_t)0x4U) * 10U + ((__VALUE__) & (uint8_t)0x0FU))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup RTC_LL_Exported_Functions RTC Exported Functions
+ * @{
+ */
+
+/** @defgroup RTC_LL_EF_Configuration Configuration
+ * @{
+ */
+
+/**
+ * @brief Set Asynchronous prescaler factor
+ * @rmtoll PRLH PRL LL_RTC_SetAsynchPrescaler\n
+ * @rmtoll PRLL PRL LL_RTC_SetAsynchPrescaler\n
+ * @param RTCx RTC Instance
+ * @param AsynchPrescaler Value between Min_Data = 0 and Max_Data = 0xFFFFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_SetAsynchPrescaler(RTC_TypeDef *RTCx, uint32_t AsynchPrescaler)
+{
+ MODIFY_REG(RTCx->PRLH, RTC_PRLH_PRL, (AsynchPrescaler >> 16));
+ MODIFY_REG(RTCx->PRLL, RTC_PRLL_PRL, (AsynchPrescaler & RTC_PRLL_PRL));
+}
+
+/**
+ * @brief Get Asynchronous prescaler factor
+ * @rmtoll DIVH DIV LL_RTC_GetDivider\n
+ * @rmtoll DIVL DIV LL_RTC_GetDivider\n
+ * @param RTCx RTC Instance
+ * @retval Value between Min_Data = 0 and Max_Data = 0xFFFFF
+ */
+__STATIC_INLINE uint32_t LL_RTC_GetDivider(RTC_TypeDef *RTCx)
+{
+ register uint16_t Highprescaler = 0 , Lowprescaler = 0;
+ Highprescaler = READ_REG(RTCx->DIVH & RTC_DIVH_RTC_DIV);
+ Lowprescaler = READ_REG(RTCx->DIVL & RTC_DIVL_RTC_DIV);
+
+ return (((uint32_t) Highprescaler << 16U) | Lowprescaler);
+}
+
+/**
+ * @brief Set Output Source
+ * @rmtoll RTCCR CCO LL_RTC_SetOutputSource
+ * @rmtoll RTCCR ASOE LL_RTC_SetOutputSource
+ * @rmtoll RTCCR ASOS LL_RTC_SetOutputSource
+ * @param BKPx BKP Instance
+ * @param OutputSource This parameter can be one of the following values:
+ * @arg @ref LL_RTC_CALIB_OUTPUT_NONE
+ * @arg @ref LL_RTC_CALIB_OUTPUT_RTCCLOCK
+ * @arg @ref LL_RTC_CALIB_OUTPUT_ALARM
+ * @arg @ref LL_RTC_CALIB_OUTPUT_SECOND
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_SetOutputSource(BKP_TypeDef *BKPx, uint32_t OutputSource)
+{
+ MODIFY_REG(BKPx->RTCCR, (BKP_RTCCR_CCO | BKP_RTCCR_ASOE | BKP_RTCCR_ASOS), OutputSource);
+}
+
+/**
+ * @brief Get Output Source
+ * @rmtoll RTCCR CCO LL_RTC_GetOutPutSource
+ * @rmtoll RTCCR ASOE LL_RTC_GetOutPutSource
+ * @rmtoll RTCCR ASOS LL_RTC_GetOutPutSource
+ * @param BKPx BKP Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_RTC_CALIB_OUTPUT_NONE
+ * @arg @ref LL_RTC_CALIB_OUTPUT_RTCCLOCK
+ * @arg @ref LL_RTC_CALIB_OUTPUT_ALARM
+ * @arg @ref LL_RTC_CALIB_OUTPUT_SECOND
+ */
+__STATIC_INLINE uint32_t LL_RTC_GetOutPutSource(BKP_TypeDef *BKPx)
+{
+ return (uint32_t)(READ_BIT(BKPx->RTCCR, (BKP_RTCCR_CCO | BKP_RTCCR_ASOE | BKP_RTCCR_ASOS)));
+}
+
+/**
+ * @brief Enable the write protection for RTC registers.
+ * @rmtoll CRL CNF LL_RTC_EnableWriteProtection
+ * @param RTCx RTC Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_EnableWriteProtection(RTC_TypeDef *RTCx)
+{
+ CLEAR_BIT(RTCx->CRL, RTC_CRL_CNF);
+}
+
+/**
+ * @brief Disable the write protection for RTC registers.
+ * @rmtoll CRL RTC_CRL_CNF LL_RTC_DisableWriteProtection
+ * @param RTCx RTC Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_DisableWriteProtection(RTC_TypeDef *RTCx)
+{
+ SET_BIT(RTCx->CRL, RTC_CRL_CNF);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_LL_EF_Time Time
+ * @{
+ */
+
+/**
+ * @brief Set time counter in BCD format
+ * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
+ * @note It can be written in initialization mode only (@ref LL_RTC_EnterInitMode function)
+ * @rmtoll CNTH CNT LL_RTC_TIME_Set\n
+ * CNTL CNT LL_RTC_TIME_Set\n
+ * @param RTCx RTC Instance
+ * @param TimeCounter Value between Min_Data=0x00 and Max_Data=0xFFFFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_TIME_Set(RTC_TypeDef *RTCx, uint32_t TimeCounter)
+{
+ /* Set RTC COUNTER MSB word */
+ WRITE_REG(RTCx->CNTH, (TimeCounter >> 16U));
+ /* Set RTC COUNTER LSB word */
+ WRITE_REG(RTCx->CNTL, (TimeCounter & RTC_CNTL_RTC_CNT));
+}
+
+/**
+ * @brief Get time counter in BCD format
+ * @rmtoll CNTH CNT LL_RTC_TIME_Get\n
+ * CNTL CNT LL_RTC_TIME_Get\n
+ * @param RTCx RTC Instance
+ * @retval Value between Min_Data = 0 and Max_Data = 0xFFFFF
+ */
+__STATIC_INLINE uint32_t LL_RTC_TIME_Get(RTC_TypeDef *RTCx)
+{
+ register uint16_t high = 0, low = 0;
+
+ high = READ_REG(RTCx->CNTH & RTC_CNTH_RTC_CNT);
+ low = READ_REG(RTCx->CNTL & RTC_CNTL_RTC_CNT);
+ return ((uint32_t)(((uint32_t) high << 16U) | low));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_LL_EF_ALARM ALARM
+ * @{
+ */
+
+/**
+ * @brief Set Alarm Counter
+ * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
+ * @rmtoll ALRH ALR LL_RTC_ALARM_Set\n
+ * @rmtoll ALRL ALR LL_RTC_ALARM_Set\n
+ * @param RTCx RTC Instance
+ * @param AlarmCounter Value between Min_Data=0x00 and Max_Data=0xFFFFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_ALARM_Set(RTC_TypeDef *RTCx, uint32_t AlarmCounter)
+{
+ /* Set RTC COUNTER MSB word */
+ WRITE_REG(RTCx->ALRH, (AlarmCounter >> 16));
+ /* Set RTC COUNTER LSB word */
+ WRITE_REG(RTCx->ALRL, (AlarmCounter & RTC_ALRL_RTC_ALR));
+}
+
+/**
+ * @brief Get Alarm Counter
+ * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
+ * @rmtoll ALRH ALR LL_RTC_ALARM_Get\n
+ * @rmtoll ALRL ALR LL_RTC_ALARM_Get\n
+ * @param RTCx RTC Instance
+ * @retval None
+ */
+__STATIC_INLINE uint32_t LL_RTC_ALARM_Get(RTC_TypeDef *RTCx)
+{
+ register uint16_t high = 0, low = 0;
+
+ high = READ_REG(RTCx->ALRH & RTC_ALRH_RTC_ALR);
+ low = READ_REG(RTCx->ALRL & RTC_ALRL_RTC_ALR);
+
+ return (((uint32_t) high << 16U) | low);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_LL_EF_Tamper Tamper
+ * @{
+ */
+
+/**
+ * @brief Enable RTC_TAMPx input detection
+ * @rmtoll CR TPE LL_RTC_TAMPER_Enable\n
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_TAMPER_Enable(BKP_TypeDef *BKPx)
+{
+ SET_BIT(BKPx->CR, BKP_CR_TPE);
+}
+
+/**
+ * @brief Disable RTC_TAMPx Tamper
+ * @rmtoll CR TPE LL_RTC_TAMPER_Disable\n
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_TAMPER_Disable(BKP_TypeDef *BKPx)
+{
+ CLEAR_BIT(BKP->CR, BKP_CR_TPE);
+}
+
+/**
+ * @brief Enable Active level for Tamper input
+ * @rmtoll CR TPAL LL_RTC_TAMPER_SetActiveLevel\n
+ * @param BKPx BKP Instance
+ * @param Tamper This parameter can be a combination of the following values:
+ * @arg @ref LL_RTC_TAMPER_ACTIVELEVEL_LOW
+ * @arg @ref LL_RTC_TAMPER_ACTIVELEVEL_HIGH
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_TAMPER_SetActiveLevel(BKP_TypeDef *BKPx, uint32_t Tamper)
+{
+ MODIFY_REG(BKPx->CR, BKP_CR_TPAL, Tamper);
+}
+
+/**
+ * @brief Disable Active level for Tamper input
+ * @rmtoll CR TPAL LL_RTC_TAMPER_SetActiveLevel\n
+ * @retval None
+ */
+__STATIC_INLINE uint32_t LL_RTC_TAMPER_GetActiveLevel(BKP_TypeDef *BKPx)
+{
+ return (uint32_t)(READ_BIT(BKPx->CR, BKP_CR_TPAL));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_LL_EF_Backup_Registers Backup_Registers
+ * @{
+ */
+
+/**
+ * @brief Writes a data in a specified RTC Backup data register.
+ * @rmtoll BKPDR DR LL_RTC_BKP_SetRegister
+ * @param BKPx BKP Instance
+ * @param BackupRegister This parameter can be one of the following values:
+ * @arg @ref LL_RTC_BKP_DR1
+ * @arg @ref LL_RTC_BKP_DR2
+ * @arg @ref LL_RTC_BKP_DR3
+ * @arg @ref LL_RTC_BKP_DR4
+ * @arg @ref LL_RTC_BKP_DR5
+ * @arg @ref LL_RTC_BKP_DR6
+ * @arg @ref LL_RTC_BKP_DR7
+ * @arg @ref LL_RTC_BKP_DR8
+ * @arg @ref LL_RTC_BKP_DR9
+ * @arg @ref LL_RTC_BKP_DR10
+ * @arg @ref LL_RTC_BKP_DR11 (*)
+ * @arg @ref LL_RTC_BKP_DR12 (*)
+ * @arg @ref LL_RTC_BKP_DR13 (*)
+ * @arg @ref LL_RTC_BKP_DR14 (*)
+ * @arg @ref LL_RTC_BKP_DR15 (*)
+ * @arg @ref LL_RTC_BKP_DR16 (*)
+ * @arg @ref LL_RTC_BKP_DR17 (*)
+ * @arg @ref LL_RTC_BKP_DR18 (*)
+ * @arg @ref LL_RTC_BKP_DR19 (*)
+ * @arg @ref LL_RTC_BKP_DR20 (*)
+ * @arg @ref LL_RTC_BKP_DR21 (*)
+ * @arg @ref LL_RTC_BKP_DR22 (*)
+ * @arg @ref LL_RTC_BKP_DR23 (*)
+ * @arg @ref LL_RTC_BKP_DR24 (*)
+ * @arg @ref LL_RTC_BKP_DR25 (*)
+ * @arg @ref LL_RTC_BKP_DR26 (*)
+ * @arg @ref LL_RTC_BKP_DR27 (*)
+ * @arg @ref LL_RTC_BKP_DR28 (*)
+ * @arg @ref LL_RTC_BKP_DR29 (*)
+ * @arg @ref LL_RTC_BKP_DR30 (*)
+ * @arg @ref LL_RTC_BKP_DR31 (*)
+ * @arg @ref LL_RTC_BKP_DR32 (*)
+ * @arg @ref LL_RTC_BKP_DR33 (*)
+ * @arg @ref LL_RTC_BKP_DR34 (*)
+ * @arg @ref LL_RTC_BKP_DR35 (*)
+ * @arg @ref LL_RTC_BKP_DR36 (*)
+ * @arg @ref LL_RTC_BKP_DR37 (*)
+ * @arg @ref LL_RTC_BKP_DR38 (*)
+ * @arg @ref LL_RTC_BKP_DR39 (*)
+ * @arg @ref LL_RTC_BKP_DR40 (*)
+ * @arg @ref LL_RTC_BKP_DR41 (*)
+ * @arg @ref LL_RTC_BKP_DR42 (*)
+ * (*) value not defined in all devices.
+ * @param Data Value between Min_Data=0x00 and Max_Data=0xFFFFFFFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_BKP_SetRegister(BKP_TypeDef *BKPx, uint32_t BackupRegister, uint32_t Data)
+{
+ register uint32_t tmp = 0U;
+
+ tmp = (uint32_t)BKP_BASE;
+ tmp += (BackupRegister * 4U);
+
+ /* Write the specified register */
+ *(__IO uint32_t *)tmp = (uint32_t)Data;
+}
+
+/**
+ * @brief Reads data from the specified RTC Backup data Register.
+ * @rmtoll BKPDR DR LL_RTC_BKP_GetRegister
+ * @param BKPx BKP Instance
+ * @param BackupRegister This parameter can be one of the following values:
+ * @arg @ref LL_RTC_BKP_DR1
+ * @arg @ref LL_RTC_BKP_DR2
+ * @arg @ref LL_RTC_BKP_DR3
+ * @arg @ref LL_RTC_BKP_DR4
+ * @arg @ref LL_RTC_BKP_DR5
+ * @arg @ref LL_RTC_BKP_DR6
+ * @arg @ref LL_RTC_BKP_DR7
+ * @arg @ref LL_RTC_BKP_DR8
+ * @arg @ref LL_RTC_BKP_DR9
+ * @arg @ref LL_RTC_BKP_DR10
+ * @arg @ref LL_RTC_BKP_DR11 (*)
+ * @arg @ref LL_RTC_BKP_DR12 (*)
+ * @arg @ref LL_RTC_BKP_DR13 (*)
+ * @arg @ref LL_RTC_BKP_DR14 (*)
+ * @arg @ref LL_RTC_BKP_DR15 (*)
+ * @arg @ref LL_RTC_BKP_DR16 (*)
+ * @arg @ref LL_RTC_BKP_DR17 (*)
+ * @arg @ref LL_RTC_BKP_DR18 (*)
+ * @arg @ref LL_RTC_BKP_DR19 (*)
+ * @arg @ref LL_RTC_BKP_DR20 (*)
+ * @arg @ref LL_RTC_BKP_DR21 (*)
+ * @arg @ref LL_RTC_BKP_DR22 (*)
+ * @arg @ref LL_RTC_BKP_DR23 (*)
+ * @arg @ref LL_RTC_BKP_DR24 (*)
+ * @arg @ref LL_RTC_BKP_DR25 (*)
+ * @arg @ref LL_RTC_BKP_DR26 (*)
+ * @arg @ref LL_RTC_BKP_DR27 (*)
+ * @arg @ref LL_RTC_BKP_DR28 (*)
+ * @arg @ref LL_RTC_BKP_DR29 (*)
+ * @arg @ref LL_RTC_BKP_DR30 (*)
+ * @arg @ref LL_RTC_BKP_DR31 (*)
+ * @arg @ref LL_RTC_BKP_DR32 (*)
+ * @arg @ref LL_RTC_BKP_DR33 (*)
+ * @arg @ref LL_RTC_BKP_DR34 (*)
+ * @arg @ref LL_RTC_BKP_DR35 (*)
+ * @arg @ref LL_RTC_BKP_DR36 (*)
+ * @arg @ref LL_RTC_BKP_DR37 (*)
+ * @arg @ref LL_RTC_BKP_DR38 (*)
+ * @arg @ref LL_RTC_BKP_DR39 (*)
+ * @arg @ref LL_RTC_BKP_DR40 (*)
+ * @arg @ref LL_RTC_BKP_DR41 (*)
+ * @arg @ref LL_RTC_BKP_DR42 (*)
+ * @retval Value between Min_Data=0x00 and Max_Data=0xFFFFFFFF
+ */
+__STATIC_INLINE uint32_t LL_RTC_BKP_GetRegister(BKP_TypeDef *BKPx, uint32_t BackupRegister)
+{
+ register uint32_t tmp = 0U;
+
+ tmp = (uint32_t)BKP_BASE;
+ tmp += (BackupRegister * 4U);
+
+ /* Read the specified register */
+ return ((*(__IO uint32_t *)tmp) & BKP_DR1_D);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_LL_EF_Calibration Calibration
+ * @{
+ */
+
+/**
+ * @brief Set the coarse digital calibration
+ * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
+ * @note It can be written in initialization mode only (@ref LL_RTC_EnterInitMode function)
+ * @rmtoll RTCCR CAL LL_RTC_CAL_SetCoarseDigital\n
+ * @param BKPx RTC Instance
+ * @param Value value of coarse calibration expressed in ppm (coded on 5 bits)
+ * @note This Calibration value should be between 0 and 121 when using positive sign with a 4-ppm step.
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_CAL_SetCoarseDigital(BKP_TypeDef* BKPx, uint32_t Value)
+{
+ MODIFY_REG(BKPx->RTCCR,BKP_RTCCR_CAL, Value);
+}
+
+/**
+ * @brief Get the coarse digital calibration value
+ * @rmtoll RTCCR CAL LL_RTC_CAL_SetCoarseDigital\n
+ * @param BKPx BKP Instance
+ * @retval value of coarse calibration expressed in ppm (coded on 5 bits)
+ */
+__STATIC_INLINE uint32_t LL_RTC_CAL_GetCoarseDigital(BKP_TypeDef *BKPx)
+{
+ return (uint32_t)(READ_BIT(BKPx->RTCCR, BKP_RTCCR_CAL));
+}
+/**
+ * @}
+ */
+
+/** @defgroup RTC_LL_EF_FLAG_Management FLAG_Management
+ * @{
+ */
+
+/**
+ * @brief Get RTC_TAMPI Interruption detection flag
+ * @rmtoll CSR TIF LL_RTC_IsActiveFlag_TAMPI
+ * @param BKPx BKP Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMPI(BKP_TypeDef *BKPx)
+{
+ return (READ_BIT(BKPx->CSR, BKP_CSR_TIF) == (BKP_CSR_TIF));
+}
+
+/**
+ * @brief Clear RTC_TAMP Interruption detection flag
+ * @rmtoll CSR CTI LL_RTC_ClearFlag_TAMPI
+ * @param BKPx BKP Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_ClearFlag_TAMPI(BKP_TypeDef *BKPx)
+{
+ SET_BIT(BKPx->CSR, BKP_CSR_CTI);
+}
+
+/**
+ * @brief Get RTC_TAMPE Event detection flag
+ * @rmtoll CSR TEF LL_RTC_IsActiveFlag_TAMPE
+ * @param BKPx BKP Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMPE(BKP_TypeDef *BKPx)
+{
+ return (READ_BIT(BKPx->CSR, BKP_CSR_TEF) == (BKP_CSR_TEF));
+}
+
+/**
+ * @brief Clear RTC_TAMPE Even detection flag
+ * @rmtoll CSR CTE LL_RTC_ClearFlag_TAMPE
+ * @param BKPx BKP Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_ClearFlag_TAMPE(BKP_TypeDef *BKPx)
+{
+ SET_BIT(BKPx->CSR, BKP_CSR_CTE);
+}
+
+/**
+ * @brief Get Alarm flag
+ * @rmtoll CRL ALRF LL_RTC_IsActiveFlag_ALR
+ * @param RTCx RTC Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ALR(RTC_TypeDef *RTCx)
+{
+ return (READ_BIT(RTCx->CRL, RTC_CRL_ALRF) == (RTC_CRL_ALRF));
+}
+
+/**
+ * @brief Clear Alarm flag
+ * @rmtoll CRL ALRF LL_RTC_ClearFlag_ALR
+ * @param RTCx RTC Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_ClearFlag_ALR(RTC_TypeDef *RTCx)
+{
+ CLEAR_BIT(RTCx->CRL, RTC_CRL_ALRF);
+}
+
+/**
+ * @brief Get Registers synchronization flag
+ * @rmtoll CRL RSF LL_RTC_IsActiveFlag_RS
+ * @param RTCx RTC Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_RS(RTC_TypeDef *RTCx)
+{
+ return (READ_BIT(RTCx->CRL, RTC_CRL_RSF) == (RTC_CRL_RSF));
+}
+
+/**
+ * @brief Clear Registers synchronization flag
+ * @rmtoll CRL RSF LL_RTC_ClearFlag_RS
+ * @param RTCx RTC Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_ClearFlag_RS(RTC_TypeDef *RTCx)
+{
+ CLEAR_BIT(RTCx->CRL, RTC_CRL_RSF);
+}
+
+/**
+ * @brief Get Registers OverFlow flag
+ * @rmtoll CRL OWF LL_RTC_IsActiveFlag_OW
+ * @param RTCx RTC Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_OW(RTC_TypeDef *RTCx)
+{
+ return (READ_BIT(RTCx->CRL, RTC_CRL_OWF) == (RTC_CRL_OWF));
+}
+
+/**
+ * @brief Clear Registers OverFlow flag
+ * @rmtoll CRL OWF LL_RTC_ClearFlag_OW
+ * @param RTCx RTC Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_ClearFlag_OW(RTC_TypeDef *RTCx)
+{
+ CLEAR_BIT(RTCx->CRL, RTC_CRL_OWF);
+}
+
+/**
+ * @brief Get Registers synchronization flag
+ * @rmtoll CRL SECF LL_RTC_IsActiveFlag_SEC
+ * @param RTCx RTC Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_SEC(RTC_TypeDef *RTCx)
+{
+ return (READ_BIT(RTCx->CRL, RTC_CRL_SECF) == (RTC_CRL_SECF));
+}
+
+/**
+ * @brief Clear Registers synchronization flag
+ * @rmtoll CRL SECF LL_RTC_ClearFlag_SEC
+ * @param RTCx RTC Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_ClearFlag_SEC(RTC_TypeDef *RTCx)
+{
+ CLEAR_BIT(RTCx->CRL, RTC_CRL_SECF);
+}
+
+/**
+ * @brief Get RTC Operation OFF status flag
+ * @rmtoll CRL RTOFF LL_RTC_IsActiveFlag_RTOF
+ * @param RTCx RTC Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_RTOF(RTC_TypeDef *RTCx)
+{
+ return (READ_BIT(RTCx->CRL, RTC_CRL_RTOFF) == (RTC_CRL_RTOFF));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_LL_EF_IT_Management IT_Management
+ * @{
+ */
+
+/**
+ * @brief Enable Alarm interrupt
+ * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
+ * @rmtoll CRH ALRIE LL_RTC_EnableIT_ALR
+ * @param RTCx RTC Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_EnableIT_ALR(RTC_TypeDef *RTCx)
+{
+ SET_BIT(RTCx->CRH, RTC_CRH_ALRIE);
+}
+
+/**
+ * @brief Disable Alarm interrupt
+ * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
+ * @rmtoll CRH ALRIE LL_RTC_DisableIT_ALR
+ * @param RTCx RTC Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_DisableIT_ALR(RTC_TypeDef *RTCx)
+{
+ CLEAR_BIT(RTCx->CRH, RTC_CRH_ALRIE);
+}
+
+/**
+ * @brief Check if Alarm interrupt is enabled or not
+ * @rmtoll CRH ALRIE LL_RTC_IsEnabledIT_ALR
+ * @param RTCx RTC Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_ALR(RTC_TypeDef *RTCx)
+{
+ return (READ_BIT(RTCx->CRH, RTC_CRH_ALRIE) == (RTC_CRH_ALRIE));
+}
+
+/**
+ * @brief Enable Second Interrupt interrupt
+ * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
+ * @rmtoll CRH SECIE LL_RTC_EnableIT_SEC
+ * @param RTCx RTC Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_EnableIT_SEC(RTC_TypeDef *RTCx)
+{
+ SET_BIT(RTCx->CRH, RTC_CRH_SECIE);
+}
+
+/**
+ * @brief Disable Second interrupt
+ * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
+ * @rmtoll CRH SECIE LL_RTC_DisableIT_SEC
+ * @param RTCx RTC Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_DisableIT_SEC(RTC_TypeDef *RTCx)
+{
+ CLEAR_BIT(RTCx->CRH, RTC_CRH_SECIE);
+}
+
+/**
+ * @brief Check if Second interrupt is enabled or not
+ * @rmtoll CRH SECIE LL_RTC_IsEnabledIT_SEC
+ * @param RTCx RTC Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_SEC(RTC_TypeDef *RTCx)
+{
+ return (READ_BIT(RTCx->CRH, RTC_CRH_SECIE) == (RTC_CRH_SECIE));
+}
+
+/**
+ * @brief Enable OverFlow interrupt
+ * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
+ * @rmtoll CRH OWIE LL_RTC_EnableIT_OW
+ * @param RTCx RTC Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_EnableIT_OW(RTC_TypeDef *RTCx)
+{
+ SET_BIT(RTCx->CRH, RTC_CRH_OWIE);
+}
+
+/**
+ * @brief Disable OverFlow interrupt
+ * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before.
+ * @rmtoll CRH OWIE LL_RTC_DisableIT_OW
+ * @param RTCx RTC Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_DisableIT_OW(RTC_TypeDef *RTCx)
+{
+ CLEAR_BIT(RTCx->CRH, RTC_CRH_OWIE);
+}
+
+/**
+ * @brief Check if OverFlow interrupt is enabled or not
+ * @rmtoll CRH OWIE LL_RTC_IsEnabledIT_OW
+ * @param RTCx RTC Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_OW(RTC_TypeDef *RTCx)
+{
+ return (READ_BIT(RTCx->CRH, RTC_CRH_OWIE) == (RTC_CRH_OWIE));
+}
+
+/**
+ * @brief Enable Tamper interrupt
+ * @rmtoll CSR TPIE LL_RTC_EnableIT_TAMP
+ * @param BKPx BKP Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_EnableIT_TAMP(BKP_TypeDef *BKPx)
+{
+ SET_BIT(BKPx->CSR,BKP_CSR_TPIE);
+}
+
+/**
+ * @brief Disable Tamper interrupt
+ * @rmtoll CSR TPIE LL_RTC_EnableIT_TAMP
+ * @param BKPx BKP Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RTC_DisableIT_TAMP(BKP_TypeDef *BKPx)
+{
+ CLEAR_BIT(BKPx->CSR,BKP_CSR_TPIE);
+}
+
+/**
+ * @brief Check if all the TAMPER interrupts are enabled or not
+ * @rmtoll CSR TPIE LL_RTC_IsEnabledIT_TAMP
+ * @param BKPx BKP Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_TAMP(BKP_TypeDef *BKPx)
+{
+ return (READ_BIT(BKPx->CSR,BKP_CSR_TPIE) == BKP_CSR_TPIE);
+}
+/**
+ * @}
+ */
+
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup RTC_LL_EF_Init Initialization and de-initialization functions
+ * @{
+ */
+
+ErrorStatus LL_RTC_DeInit(RTC_TypeDef *RTCx);
+ErrorStatus LL_RTC_Init(RTC_TypeDef *RTCx, LL_RTC_InitTypeDef *RTC_InitStruct);
+void LL_RTC_StructInit(LL_RTC_InitTypeDef *RTC_InitStruct);
+ErrorStatus LL_RTC_TIME_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_TimeTypeDef *RTC_TimeStruct);
+void LL_RTC_TIME_StructInit(LL_RTC_TimeTypeDef *RTC_TimeStruct);
+ErrorStatus LL_RTC_ALARM_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_AlarmTypeDef *RTC_AlarmStruct);
+void LL_RTC_ALARM_StructInit(LL_RTC_AlarmTypeDef *RTC_AlarmStruct);
+ErrorStatus LL_RTC_EnterInitMode(RTC_TypeDef *RTCx);
+ErrorStatus LL_RTC_ExitInitMode(RTC_TypeDef *RTCx);
+ErrorStatus LL_RTC_WaitForSynchro(RTC_TypeDef *RTCx);
+ErrorStatus LL_RTC_TIME_SetCounter(RTC_TypeDef *RTCx, uint32_t TimeCounter);
+ErrorStatus LL_RTC_ALARM_SetCounter(RTC_TypeDef *RTCx, uint32_t AlarmCounter);
+
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* defined(RTC) */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_LL_RTC_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_sdmmc.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_sdmmc.h
new file mode 100644
index 0000000..828346c
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_sdmmc.h
@@ -0,0 +1,1125 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_sdmmc.h
+ * @author MCD Application Team
+ * @brief Header file of low layer SDMMC HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __stm32f1xx_LL_SD_H
+#define __stm32f1xx_LL_SD_H
+
+#if defined(STM32F103xE) || defined(STM32F103xG)
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup SDMMC_LL
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup SDMMC_LL_Exported_Types SDMMC_LL Exported Types
+ * @{
+ */
+
+/**
+ * @brief SDMMC Configuration Structure definition
+ */
+typedef struct
+{
+ uint32_t ClockEdge; /*!< Specifies the clock transition on which the bit capture is made.
+ This parameter can be a value of @ref SDMMC_LL_Clock_Edge */
+
+ uint32_t ClockBypass; /*!< Specifies whether the SDIO Clock divider bypass is
+ enabled or disabled.
+ This parameter can be a value of @ref SDMMC_LL_Clock_Bypass */
+
+ uint32_t ClockPowerSave; /*!< Specifies whether SDIO Clock output is enabled or
+ disabled when the bus is idle.
+ This parameter can be a value of @ref SDMMC_LL_Clock_Power_Save */
+
+ uint32_t BusWide; /*!< Specifies the SDIO bus width.
+ This parameter can be a value of @ref SDMMC_LL_Bus_Wide */
+
+ uint32_t HardwareFlowControl; /*!< Specifies whether the SDIO hardware flow control is enabled or disabled.
+ This parameter can be a value of @ref SDMMC_LL_Hardware_Flow_Control */
+
+ uint32_t ClockDiv; /*!< Specifies the clock frequency of the SDIO controller.
+ This parameter can be a value between Min_Data = 0 and Max_Data = 255 */
+
+}SDIO_InitTypeDef;
+
+
+/**
+ * @brief SDIO Command Control structure
+ */
+typedef struct
+{
+ uint32_t Argument; /*!< Specifies the SDIO command argument which is sent
+ to a card as part of a command message. If a command
+ contains an argument, it must be loaded into this register
+ before writing the command to the command register. */
+
+ uint32_t CmdIndex; /*!< Specifies the SDIO command index. It must be Min_Data = 0 and
+ Max_Data = 64 */
+
+ uint32_t Response; /*!< Specifies the SDIO response type.
+ This parameter can be a value of @ref SDMMC_LL_Response_Type */
+
+ uint32_t WaitForInterrupt; /*!< Specifies whether SDIO wait for interrupt request is
+ enabled or disabled.
+ This parameter can be a value of @ref SDMMC_LL_Wait_Interrupt_State */
+
+ uint32_t CPSM; /*!< Specifies whether SDIO Command path state machine (CPSM)
+ is enabled or disabled.
+ This parameter can be a value of @ref SDMMC_LL_CPSM_State */
+}SDIO_CmdInitTypeDef;
+
+
+/**
+ * @brief SDIO Data Control structure
+ */
+typedef struct
+{
+ uint32_t DataTimeOut; /*!< Specifies the data timeout period in card bus clock periods. */
+
+ uint32_t DataLength; /*!< Specifies the number of data bytes to be transferred. */
+
+ uint32_t DataBlockSize; /*!< Specifies the data block size for block transfer.
+ This parameter can be a value of @ref SDMMC_LL_Data_Block_Size */
+
+ uint32_t TransferDir; /*!< Specifies the data transfer direction, whether the transfer
+ is a read or write.
+ This parameter can be a value of @ref SDMMC_LL_Transfer_Direction */
+
+ uint32_t TransferMode; /*!< Specifies whether data transfer is in stream or block mode.
+ This parameter can be a value of @ref SDMMC_LL_Transfer_Type */
+
+ uint32_t DPSM; /*!< Specifies whether SDIO Data path state machine (DPSM)
+ is enabled or disabled.
+ This parameter can be a value of @ref SDMMC_LL_DPSM_State */
+}SDIO_DataInitTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup SDMMC_LL_Exported_Constants SDMMC_LL Exported Constants
+ * @{
+ */
+#define SDMMC_ERROR_NONE 0x00000000U /*!< No error */
+#define SDMMC_ERROR_CMD_CRC_FAIL 0x00000001U /*!< Command response received (but CRC check failed) */
+#define SDMMC_ERROR_DATA_CRC_FAIL 0x00000002U /*!< Data block sent/received (CRC check failed) */
+#define SDMMC_ERROR_CMD_RSP_TIMEOUT 0x00000004U /*!< Command response timeout */
+#define SDMMC_ERROR_DATA_TIMEOUT 0x00000008U /*!< Data timeout */
+#define SDMMC_ERROR_TX_UNDERRUN 0x00000010U /*!< Transmit FIFO underrun */
+#define SDMMC_ERROR_RX_OVERRUN 0x00000020U /*!< Receive FIFO overrun */
+#define SDMMC_ERROR_ADDR_MISALIGNED 0x00000040U /*!< Misaligned address */
+#define SDMMC_ERROR_BLOCK_LEN_ERR 0x00000080U /*!< Transferred block length is not allowed for the card or the
+ number of transferred bytes does not match the block length */
+#define SDMMC_ERROR_ERASE_SEQ_ERR 0x00000100U /*!< An error in the sequence of erase command occurs */
+#define SDMMC_ERROR_BAD_ERASE_PARAM 0x00000200U /*!< An invalid selection for erase groups */
+#define SDMMC_ERROR_WRITE_PROT_VIOLATION 0x00000400U /*!< Attempt to program a write protect block */
+#define SDMMC_ERROR_LOCK_UNLOCK_FAILED 0x00000800U /*!< Sequence or password error has been detected in unlock
+ command or if there was an attempt to access a locked card */
+#define SDMMC_ERROR_COM_CRC_FAILED 0x00001000U /*!< CRC check of the previous command failed */
+#define SDMMC_ERROR_ILLEGAL_CMD 0x00002000U /*!< Command is not legal for the card state */
+#define SDMMC_ERROR_CARD_ECC_FAILED 0x00004000U /*!< Card internal ECC was applied but failed to correct the data */
+#define SDMMC_ERROR_CC_ERR 0x00008000U /*!< Internal card controller error */
+#define SDMMC_ERROR_GENERAL_UNKNOWN_ERR 0x00010000U /*!< General or unknown error */
+#define SDMMC_ERROR_STREAM_READ_UNDERRUN 0x00020000U /*!< The card could not sustain data reading in stream rmode */
+#define SDMMC_ERROR_STREAM_WRITE_OVERRUN 0x00040000U /*!< The card could not sustain data programming in stream mode */
+#define SDMMC_ERROR_CID_CSD_OVERWRITE 0x00080000U /*!< CID/CSD overwrite error */
+#define SDMMC_ERROR_WP_ERASE_SKIP 0x00100000U /*!< Only partial address space was erased */
+#define SDMMC_ERROR_CARD_ECC_DISABLED 0x00200000U /*!< Command has been executed without using internal ECC */
+#define SDMMC_ERROR_ERASE_RESET 0x00400000U /*!< Erase sequence was cleared before executing because an out
+ of erase sequence command was received */
+#define SDMMC_ERROR_AKE_SEQ_ERR 0x00800000U /*!< Error in sequence of authentication */
+#define SDMMC_ERROR_INVALID_VOLTRANGE 0x01000000U /*!< Error in case of invalid voltage range */
+#define SDMMC_ERROR_ADDR_OUT_OF_RANGE 0x02000000U /*!< Error when addressed block is out of range */
+#define SDMMC_ERROR_REQUEST_NOT_APPLICABLE 0x04000000U /*!< Error when command request is not applicable */
+#define SDMMC_ERROR_INVALID_PARAMETER 0x08000000U /*!< the used parameter is not valid */
+#define SDMMC_ERROR_UNSUPPORTED_FEATURE 0x10000000U /*!< Error when feature is not insupported */
+#define SDMMC_ERROR_BUSY 0x20000000U /*!< Error when transfer process is busy */
+#define SDMMC_ERROR_DMA 0x40000000U /*!< Error while DMA transfer */
+#define SDMMC_ERROR_TIMEOUT 0x80000000U /*!< Timeout error */
+
+/**
+ * @brief SDMMC Commands Index
+ */
+#define SDMMC_CMD_GO_IDLE_STATE ((uint8_t)0) /*!< Resets the SD memory card. */
+#define SDMMC_CMD_SEND_OP_COND ((uint8_t)1) /*!< Sends host capacity support information and activates the card's initialization process. */
+#define SDMMC_CMD_ALL_SEND_CID ((uint8_t)2) /*!< Asks any card connected to the host to send the CID numbers on the CMD line. */
+#define SDMMC_CMD_SET_REL_ADDR ((uint8_t)3) /*!< Asks the card to publish a new relative address (RCA). */
+#define SDMMC_CMD_SET_DSR ((uint8_t)4) /*!< Programs the DSR of all cards. */
+#define SDMMC_CMD_SDMMC_SEN_OP_COND ((uint8_t)5) /*!< Sends host capacity support information (HCS) and asks the accessed card to send its
+ operating condition register (OCR) content in the response on the CMD line. */
+#define SDMMC_CMD_HS_SWITCH ((uint8_t)6) /*!< Checks switchable function (mode 0) and switch card function (mode 1). */
+#define SDMMC_CMD_SEL_DESEL_CARD ((uint8_t)7) /*!< Selects the card by its own relative address and gets deselected by any other address */
+#define SDMMC_CMD_HS_SEND_EXT_CSD ((uint8_t)8) /*!< Sends SD Memory Card interface condition, which includes host supply voltage information
+ and asks the card whether card supports voltage. */
+#define SDMMC_CMD_SEND_CSD ((uint8_t)9) /*!< Addressed card sends its card specific data (CSD) on the CMD line. */
+#define SDMMC_CMD_SEND_CID ((uint8_t)10) /*!< Addressed card sends its card identification (CID) on the CMD line. */
+#define SDMMC_CMD_READ_DAT_UNTIL_STOP ((uint8_t)11) /*!< SD card doesn't support it. */
+#define SDMMC_CMD_STOP_TRANSMISSION ((uint8_t)12) /*!< Forces the card to stop transmission. */
+#define SDMMC_CMD_SEND_STATUS ((uint8_t)13) /*!< Addressed card sends its status register. */
+#define SDMMC_CMD_HS_BUSTEST_READ ((uint8_t)14) /*!< Reserved */
+#define SDMMC_CMD_GO_INACTIVE_STATE ((uint8_t)15) /*!< Sends an addressed card into the inactive state. */
+#define SDMMC_CMD_SET_BLOCKLEN ((uint8_t)16) /*!< Sets the block length (in bytes for SDSC) for all following block commands
+ (read, write, lock). Default block length is fixed to 512 Bytes. Not effective
+ for SDHS and SDXC. */
+#define SDMMC_CMD_READ_SINGLE_BLOCK ((uint8_t)17) /*!< Reads single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of
+ fixed 512 bytes in case of SDHC and SDXC. */
+#define SDMMC_CMD_READ_MULT_BLOCK ((uint8_t)18) /*!< Continuously transfers data blocks from card to host until interrupted by
+ STOP_TRANSMISSION command. */
+#define SDMMC_CMD_HS_BUSTEST_WRITE ((uint8_t)19) /*!< 64 bytes tuning pattern is sent for SDR50 and SDR104. */
+#define SDMMC_CMD_WRITE_DAT_UNTIL_STOP ((uint8_t)20) /*!< Speed class control command. */
+#define SDMMC_CMD_SET_BLOCK_COUNT ((uint8_t)23) /*!< Specify block count for CMD18 and CMD25. */
+#define SDMMC_CMD_WRITE_SINGLE_BLOCK ((uint8_t)24) /*!< Writes single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of
+ fixed 512 bytes in case of SDHC and SDXC. */
+#define SDMMC_CMD_WRITE_MULT_BLOCK ((uint8_t)25) /*!< Continuously writes blocks of data until a STOP_TRANSMISSION follows. */
+#define SDMMC_CMD_PROG_CID ((uint8_t)26) /*!< Reserved for manufacturers. */
+#define SDMMC_CMD_PROG_CSD ((uint8_t)27) /*!< Programming of the programmable bits of the CSD. */
+#define SDMMC_CMD_SET_WRITE_PROT ((uint8_t)28) /*!< Sets the write protection bit of the addressed group. */
+#define SDMMC_CMD_CLR_WRITE_PROT ((uint8_t)29) /*!< Clears the write protection bit of the addressed group. */
+#define SDMMC_CMD_SEND_WRITE_PROT ((uint8_t)30) /*!< Asks the card to send the status of the write protection bits. */
+#define SDMMC_CMD_SD_ERASE_GRP_START ((uint8_t)32) /*!< Sets the address of the first write block to be erased. (For SD card only). */
+#define SDMMC_CMD_SD_ERASE_GRP_END ((uint8_t)33) /*!< Sets the address of the last write block of the continuous range to be erased. */
+#define SDMMC_CMD_ERASE_GRP_START ((uint8_t)35) /*!< Sets the address of the first write block to be erased. Reserved for each command
+ system set by switch function command (CMD6). */
+#define SDMMC_CMD_ERASE_GRP_END ((uint8_t)36) /*!< Sets the address of the last write block of the continuous range to be erased.
+ Reserved for each command system set by switch function command (CMD6). */
+#define SDMMC_CMD_ERASE ((uint8_t)38) /*!< Reserved for SD security applications. */
+#define SDMMC_CMD_FAST_IO ((uint8_t)39) /*!< SD card doesn't support it (Reserved). */
+#define SDMMC_CMD_GO_IRQ_STATE ((uint8_t)40) /*!< SD card doesn't support it (Reserved). */
+#define SDMMC_CMD_LOCK_UNLOCK ((uint8_t)42) /*!< Sets/resets the password or lock/unlock the card. The size of the data block is set by
+ the SET_BLOCK_LEN command. */
+#define SDMMC_CMD_APP_CMD ((uint8_t)55) /*!< Indicates to the card that the next command is an application specific command rather
+ than a standard command. */
+#define SDMMC_CMD_GEN_CMD ((uint8_t)56) /*!< Used either to transfer a data block to the card or to get a data block from the card
+ for general purpose/application specific commands. */
+#define SDMMC_CMD_NO_CMD ((uint8_t)64) /*!< No command */
+
+/**
+ * @brief Following commands are SD Card Specific commands.
+ * SDMMC_APP_CMD should be sent before sending these commands.
+ */
+#define SDMMC_CMD_APP_SD_SET_BUSWIDTH ((uint8_t)6) /*!< (ACMD6) Defines the data bus width to be used for data transfer. The allowed data bus
+ widths are given in SCR register. */
+#define SDMMC_CMD_SD_APP_STATUS ((uint8_t)13) /*!< (ACMD13) Sends the SD status. */
+#define SDMMC_CMD_SD_APP_SEND_NUM_WRITE_BLOCKS ((uint8_t)22) /*!< (ACMD22) Sends the number of the written (without errors) write blocks. Responds with
+ 32bit+CRC data block. */
+#define SDMMC_CMD_SD_APP_OP_COND ((uint8_t)41) /*!< (ACMD41) Sends host capacity support information (HCS) and asks the accessed card to
+ send its operating condition register (OCR) content in the response on the CMD line. */
+#define SDMMC_CMD_SD_APP_SET_CLR_CARD_DETECT ((uint8_t)42) /*!< (ACMD42) Connect/Disconnect the 50 KOhm pull-up resistor on CD/DAT3 (pin 1) of the card */
+#define SDMMC_CMD_SD_APP_SEND_SCR ((uint8_t)51) /*!< Reads the SD Configuration Register (SCR). */
+#define SDMMC_CMD_SDMMC_RW_DIRECT ((uint8_t)52) /*!< For SD I/O card only, reserved for security specification. */
+#define SDMMC_CMD_SDMMC_RW_EXTENDED ((uint8_t)53) /*!< For SD I/O card only, reserved for security specification. */
+
+/**
+ * @brief Following commands are SD Card Specific security commands.
+ * SDMMC_CMD_APP_CMD should be sent before sending these commands.
+ */
+#define SDMMC_CMD_SD_APP_GET_MKB ((uint8_t)43)
+#define SDMMC_CMD_SD_APP_GET_MID ((uint8_t)44)
+#define SDMMC_CMD_SD_APP_SET_CER_RN1 ((uint8_t)45)
+#define SDMMC_CMD_SD_APP_GET_CER_RN2 ((uint8_t)46)
+#define SDMMC_CMD_SD_APP_SET_CER_RES2 ((uint8_t)47)
+#define SDMMC_CMD_SD_APP_GET_CER_RES1 ((uint8_t)48)
+#define SDMMC_CMD_SD_APP_SECURE_READ_MULTIPLE_BLOCK ((uint8_t)18)
+#define SDMMC_CMD_SD_APP_SECURE_WRITE_MULTIPLE_BLOCK ((uint8_t)25)
+#define SDMMC_CMD_SD_APP_SECURE_ERASE ((uint8_t)38)
+#define SDMMC_CMD_SD_APP_CHANGE_SECURE_AREA ((uint8_t)49)
+#define SDMMC_CMD_SD_APP_SECURE_WRITE_MKB ((uint8_t)48)
+
+/**
+ * @brief Masks for errors Card Status R1 (OCR Register)
+ */
+#define SDMMC_OCR_ADDR_OUT_OF_RANGE 0x80000000U
+#define SDMMC_OCR_ADDR_MISALIGNED 0x40000000U
+#define SDMMC_OCR_BLOCK_LEN_ERR 0x20000000U
+#define SDMMC_OCR_ERASE_SEQ_ERR 0x10000000U
+#define SDMMC_OCR_BAD_ERASE_PARAM 0x08000000U
+#define SDMMC_OCR_WRITE_PROT_VIOLATION 0x04000000U
+#define SDMMC_OCR_LOCK_UNLOCK_FAILED 0x01000000U
+#define SDMMC_OCR_COM_CRC_FAILED 0x00800000U
+#define SDMMC_OCR_ILLEGAL_CMD 0x00400000U
+#define SDMMC_OCR_CARD_ECC_FAILED 0x00200000U
+#define SDMMC_OCR_CC_ERROR 0x00100000U
+#define SDMMC_OCR_GENERAL_UNKNOWN_ERROR 0x00080000U
+#define SDMMC_OCR_STREAM_READ_UNDERRUN 0x00040000U
+#define SDMMC_OCR_STREAM_WRITE_OVERRUN 0x00020000U
+#define SDMMC_OCR_CID_CSD_OVERWRITE 0x00010000U
+#define SDMMC_OCR_WP_ERASE_SKIP 0x00008000U
+#define SDMMC_OCR_CARD_ECC_DISABLED 0x00004000U
+#define SDMMC_OCR_ERASE_RESET 0x00002000U
+#define SDMMC_OCR_AKE_SEQ_ERROR 0x00000008U
+#define SDMMC_OCR_ERRORBITS 0xFDFFE008U
+
+/**
+ * @brief Masks for R6 Response
+ */
+#define SDMMC_R6_GENERAL_UNKNOWN_ERROR 0x00002000U
+#define SDMMC_R6_ILLEGAL_CMD 0x00004000U
+#define SDMMC_R6_COM_CRC_FAILED 0x00008000U
+
+#define SDMMC_VOLTAGE_WINDOW_SD 0x80100000U
+#define SDMMC_HIGH_CAPACITY 0x40000000U
+#define SDMMC_STD_CAPACITY 0x00000000U
+#define SDMMC_CHECK_PATTERN 0x000001AAU
+
+#define SDMMC_MAX_VOLT_TRIAL 0x0000FFFFU
+
+#define SDMMC_MAX_TRIAL 0x0000FFFFU
+
+#define SDMMC_ALLZERO 0x00000000U
+
+#define SDMMC_WIDE_BUS_SUPPORT 0x00040000U
+#define SDMMC_SINGLE_BUS_SUPPORT 0x00010000U
+#define SDMMC_CARD_LOCKED 0x02000000U
+
+#define SDMMC_DATATIMEOUT 0xFFFFFFFFU
+
+#define SDMMC_0TO7BITS 0x000000FFU
+#define SDMMC_8TO15BITS 0x0000FF00U
+#define SDMMC_16TO23BITS 0x00FF0000U
+#define SDMMC_24TO31BITS 0xFF000000U
+#define SDMMC_MAX_DATA_LENGTH 0x01FFFFFFU
+
+#define SDMMC_HALFFIFO 0x00000008U
+#define SDMMC_HALFFIFOBYTES 0x00000020U
+
+/**
+ * @brief Command Class supported
+ */
+#define SDIO_CCCC_ERASE 0x00000020U
+
+#define SDIO_CMDTIMEOUT 5000U /* Command send and response timeout */
+#define SDIO_MAXERASETIMEOUT 63000U /* Max erase Timeout 63 s */
+
+
+/** @defgroup SDIO_LL_Clock_Edge Clock Edge
+ * @{
+ */
+#define SDIO_CLOCK_EDGE_RISING 0x00000000U
+#define SDIO_CLOCK_EDGE_FALLING SDIO_CLKCR_NEGEDGE
+
+#define IS_SDIO_CLOCK_EDGE(EDGE) (((EDGE) == SDIO_CLOCK_EDGE_RISING) || \
+ ((EDGE) == SDIO_CLOCK_EDGE_FALLING))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_Clock_Bypass Clock Bypass
+ * @{
+ */
+#define SDIO_CLOCK_BYPASS_DISABLE 0x00000000U
+#define SDIO_CLOCK_BYPASS_ENABLE SDIO_CLKCR_BYPASS
+
+#define IS_SDIO_CLOCK_BYPASS(BYPASS) (((BYPASS) == SDIO_CLOCK_BYPASS_DISABLE) || \
+ ((BYPASS) == SDIO_CLOCK_BYPASS_ENABLE))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_Clock_Power_Save Clock Power Saving
+ * @{
+ */
+#define SDIO_CLOCK_POWER_SAVE_DISABLE 0x00000000U
+#define SDIO_CLOCK_POWER_SAVE_ENABLE SDIO_CLKCR_PWRSAV
+
+#define IS_SDIO_CLOCK_POWER_SAVE(SAVE) (((SAVE) == SDIO_CLOCK_POWER_SAVE_DISABLE) || \
+ ((SAVE) == SDIO_CLOCK_POWER_SAVE_ENABLE))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_Bus_Wide Bus Width
+ * @{
+ */
+#define SDIO_BUS_WIDE_1B 0x00000000U
+#define SDIO_BUS_WIDE_4B SDIO_CLKCR_WIDBUS_0
+#define SDIO_BUS_WIDE_8B SDIO_CLKCR_WIDBUS_1
+
+#define IS_SDIO_BUS_WIDE(WIDE) (((WIDE) == SDIO_BUS_WIDE_1B) || \
+ ((WIDE) == SDIO_BUS_WIDE_4B) || \
+ ((WIDE) == SDIO_BUS_WIDE_8B))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_Hardware_Flow_Control Hardware Flow Control
+ * @{
+ */
+#define SDIO_HARDWARE_FLOW_CONTROL_DISABLE 0x00000000U
+#define SDIO_HARDWARE_FLOW_CONTROL_ENABLE SDIO_CLKCR_HWFC_EN
+
+#define IS_SDIO_HARDWARE_FLOW_CONTROL(CONTROL) (((CONTROL) == SDIO_HARDWARE_FLOW_CONTROL_DISABLE) || \
+ ((CONTROL) == SDIO_HARDWARE_FLOW_CONTROL_ENABLE))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_Clock_Division Clock Division
+ * @{
+ */
+#define IS_SDIO_CLKDIV(DIV) ((DIV) <= 0xFFU)
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_Command_Index Command Index
+ * @{
+ */
+#define IS_SDIO_CMD_INDEX(INDEX) ((INDEX) < 0x40U)
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_Response_Type Response Type
+ * @{
+ */
+#define SDIO_RESPONSE_NO 0x00000000U
+#define SDIO_RESPONSE_SHORT SDIO_CMD_WAITRESP_0
+#define SDIO_RESPONSE_LONG SDIO_CMD_WAITRESP
+
+#define IS_SDIO_RESPONSE(RESPONSE) (((RESPONSE) == SDIO_RESPONSE_NO) || \
+ ((RESPONSE) == SDIO_RESPONSE_SHORT) || \
+ ((RESPONSE) == SDIO_RESPONSE_LONG))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_Wait_Interrupt_State Wait Interrupt
+ * @{
+ */
+#define SDIO_WAIT_NO 0x00000000U
+#define SDIO_WAIT_IT SDIO_CMD_WAITINT
+#define SDIO_WAIT_PEND SDIO_CMD_WAITPEND
+
+#define IS_SDIO_WAIT(WAIT) (((WAIT) == SDIO_WAIT_NO) || \
+ ((WAIT) == SDIO_WAIT_IT) || \
+ ((WAIT) == SDIO_WAIT_PEND))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_CPSM_State CPSM State
+ * @{
+ */
+#define SDIO_CPSM_DISABLE 0x00000000U
+#define SDIO_CPSM_ENABLE SDIO_CMD_CPSMEN
+
+#define IS_SDIO_CPSM(CPSM) (((CPSM) == SDIO_CPSM_DISABLE) || \
+ ((CPSM) == SDIO_CPSM_ENABLE))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_Response_Registers Response Register
+ * @{
+ */
+#define SDIO_RESP1 0x00000000U
+#define SDIO_RESP2 0x00000004U
+#define SDIO_RESP3 0x00000008U
+#define SDIO_RESP4 0x0000000CU
+
+#define IS_SDIO_RESP(RESP) (((RESP) == SDIO_RESP1) || \
+ ((RESP) == SDIO_RESP2) || \
+ ((RESP) == SDIO_RESP3) || \
+ ((RESP) == SDIO_RESP4))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_Data_Length Data Lenght
+ * @{
+ */
+#define IS_SDIO_DATA_LENGTH(LENGTH) ((LENGTH) <= 0x01FFFFFFU)
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_Data_Block_Size Data Block Size
+ * @{
+ */
+#define SDIO_DATABLOCK_SIZE_1B 0x00000000U
+#define SDIO_DATABLOCK_SIZE_2B SDIO_DCTRL_DBLOCKSIZE_0
+#define SDIO_DATABLOCK_SIZE_4B SDIO_DCTRL_DBLOCKSIZE_1
+#define SDIO_DATABLOCK_SIZE_8B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_1)
+#define SDIO_DATABLOCK_SIZE_16B SDIO_DCTRL_DBLOCKSIZE_2
+#define SDIO_DATABLOCK_SIZE_32B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_2)
+#define SDIO_DATABLOCK_SIZE_64B (SDIO_DCTRL_DBLOCKSIZE_1|SDIO_DCTRL_DBLOCKSIZE_2)
+#define SDIO_DATABLOCK_SIZE_128B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_1|SDIO_DCTRL_DBLOCKSIZE_2)
+#define SDIO_DATABLOCK_SIZE_256B SDIO_DCTRL_DBLOCKSIZE_3
+#define SDIO_DATABLOCK_SIZE_512B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_3)
+#define SDIO_DATABLOCK_SIZE_1024B (SDIO_DCTRL_DBLOCKSIZE_1|SDIO_DCTRL_DBLOCKSIZE_3)
+#define SDIO_DATABLOCK_SIZE_2048B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_1|SDIO_DCTRL_DBLOCKSIZE_3)
+#define SDIO_DATABLOCK_SIZE_4096B (SDIO_DCTRL_DBLOCKSIZE_2|SDIO_DCTRL_DBLOCKSIZE_3)
+#define SDIO_DATABLOCK_SIZE_8192B (SDIO_DCTRL_DBLOCKSIZE_0|SDIO_DCTRL_DBLOCKSIZE_2|SDIO_DCTRL_DBLOCKSIZE_3)
+#define SDIO_DATABLOCK_SIZE_16384B (SDIO_DCTRL_DBLOCKSIZE_1|SDIO_DCTRL_DBLOCKSIZE_2|SDIO_DCTRL_DBLOCKSIZE_3)
+
+#define IS_SDIO_BLOCK_SIZE(SIZE) (((SIZE) == SDIO_DATABLOCK_SIZE_1B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_2B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_4B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_8B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_16B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_32B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_64B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_128B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_256B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_512B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_1024B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_2048B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_4096B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_8192B) || \
+ ((SIZE) == SDIO_DATABLOCK_SIZE_16384B))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_Transfer_Direction Transfer Direction
+ * @{
+ */
+#define SDIO_TRANSFER_DIR_TO_CARD 0x00000000U
+#define SDIO_TRANSFER_DIR_TO_SDIO SDIO_DCTRL_DTDIR
+
+#define IS_SDIO_TRANSFER_DIR(DIR) (((DIR) == SDIO_TRANSFER_DIR_TO_CARD) || \
+ ((DIR) == SDIO_TRANSFER_DIR_TO_SDIO))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_Transfer_Type Transfer Type
+ * @{
+ */
+#define SDIO_TRANSFER_MODE_BLOCK 0x00000000U
+#define SDIO_TRANSFER_MODE_STREAM SDIO_DCTRL_DTMODE
+
+#define IS_SDIO_TRANSFER_MODE(MODE) (((MODE) == SDIO_TRANSFER_MODE_BLOCK) || \
+ ((MODE) == SDIO_TRANSFER_MODE_STREAM))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_DPSM_State DPSM State
+ * @{
+ */
+#define SDIO_DPSM_DISABLE 0x00000000U
+#define SDIO_DPSM_ENABLE SDIO_DCTRL_DTEN
+
+#define IS_SDIO_DPSM(DPSM) (((DPSM) == SDIO_DPSM_DISABLE) ||\
+ ((DPSM) == SDIO_DPSM_ENABLE))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_Read_Wait_Mode Read Wait Mode
+ * @{
+ */
+#define SDIO_READ_WAIT_MODE_DATA2 0x00000000U
+#define SDIO_READ_WAIT_MODE_CLK (SDIO_DCTRL_RWMOD)
+
+#define IS_SDIO_READWAIT_MODE(MODE) (((MODE) == SDIO_READ_WAIT_MODE_CLK) || \
+ ((MODE) == SDIO_READ_WAIT_MODE_DATA2))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_Interrupt_sources Interrupt Sources
+ * @{
+ */
+#define SDIO_IT_CCRCFAIL SDIO_STA_CCRCFAIL
+#define SDIO_IT_DCRCFAIL SDIO_STA_DCRCFAIL
+#define SDIO_IT_CTIMEOUT SDIO_STA_CTIMEOUT
+#define SDIO_IT_DTIMEOUT SDIO_STA_DTIMEOUT
+#define SDIO_IT_TXUNDERR SDIO_STA_TXUNDERR
+#define SDIO_IT_RXOVERR SDIO_STA_RXOVERR
+#define SDIO_IT_CMDREND SDIO_STA_CMDREND
+#define SDIO_IT_CMDSENT SDIO_STA_CMDSENT
+#define SDIO_IT_DATAEND SDIO_STA_DATAEND
+#define SDIO_IT_STBITERR SDIO_STA_STBITERR
+#define SDIO_IT_DBCKEND SDIO_STA_DBCKEND
+#define SDIO_IT_CMDACT SDIO_STA_CMDACT
+#define SDIO_IT_TXACT SDIO_STA_TXACT
+#define SDIO_IT_RXACT SDIO_STA_RXACT
+#define SDIO_IT_TXFIFOHE SDIO_STA_TXFIFOHE
+#define SDIO_IT_RXFIFOHF SDIO_STA_RXFIFOHF
+#define SDIO_IT_TXFIFOF SDIO_STA_TXFIFOF
+#define SDIO_IT_RXFIFOF SDIO_STA_RXFIFOF
+#define SDIO_IT_TXFIFOE SDIO_STA_TXFIFOE
+#define SDIO_IT_RXFIFOE SDIO_STA_RXFIFOE
+#define SDIO_IT_TXDAVL SDIO_STA_TXDAVL
+#define SDIO_IT_RXDAVL SDIO_STA_RXDAVL
+#define SDIO_IT_SDIOIT SDIO_STA_SDIOIT
+#define SDIO_IT_CEATAEND SDIO_STA_CEATAEND
+/**
+ * @}
+ */
+
+/** @defgroup SDMMC_LL_Flags Flags
+ * @{
+ */
+#define SDIO_FLAG_CCRCFAIL SDIO_STA_CCRCFAIL
+#define SDIO_FLAG_DCRCFAIL SDIO_STA_DCRCFAIL
+#define SDIO_FLAG_CTIMEOUT SDIO_STA_CTIMEOUT
+#define SDIO_FLAG_DTIMEOUT SDIO_STA_DTIMEOUT
+#define SDIO_FLAG_TXUNDERR SDIO_STA_TXUNDERR
+#define SDIO_FLAG_RXOVERR SDIO_STA_RXOVERR
+#define SDIO_FLAG_CMDREND SDIO_STA_CMDREND
+#define SDIO_FLAG_CMDSENT SDIO_STA_CMDSENT
+#define SDIO_FLAG_DATAEND SDIO_STA_DATAEND
+#define SDIO_FLAG_STBITERR SDIO_STA_STBITERR
+#define SDIO_FLAG_DBCKEND SDIO_STA_DBCKEND
+#define SDIO_FLAG_CMDACT SDIO_STA_CMDACT
+#define SDIO_FLAG_TXACT SDIO_STA_TXACT
+#define SDIO_FLAG_RXACT SDIO_STA_RXACT
+#define SDIO_FLAG_TXFIFOHE SDIO_STA_TXFIFOHE
+#define SDIO_FLAG_RXFIFOHF SDIO_STA_RXFIFOHF
+#define SDIO_FLAG_TXFIFOF SDIO_STA_TXFIFOF
+#define SDIO_FLAG_RXFIFOF SDIO_STA_RXFIFOF
+#define SDIO_FLAG_TXFIFOE SDIO_STA_TXFIFOE
+#define SDIO_FLAG_RXFIFOE SDIO_STA_RXFIFOE
+#define SDIO_FLAG_TXDAVL SDIO_STA_TXDAVL
+#define SDIO_FLAG_RXDAVL SDIO_STA_RXDAVL
+#define SDIO_FLAG_SDIOIT SDIO_STA_SDIOIT
+#define SDIO_FLAG_CEATAEND SDIO_STA_CEATAEND
+#define SDIO_STATIC_FLAGS ((uint32_t)(SDIO_FLAG_CCRCFAIL | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_CTIMEOUT |\
+ SDIO_FLAG_DTIMEOUT | SDIO_FLAG_TXUNDERR | SDIO_FLAG_RXOVERR |\
+ SDIO_FLAG_CMDREND | SDIO_FLAG_CMDSENT | SDIO_FLAG_DATAEND |\
+ SDIO_FLAG_DBCKEND))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup SDIO_LL_Exported_macros SDIO_LL Exported Macros
+ * @{
+ */
+
+/** @defgroup SDMMC_LL_Alias_Region Bit Address in the alias region
+ * @{
+ */
+/* ------------ SDIO registers bit address in the alias region -------------- */
+#define SDIO_OFFSET (SDIO_BASE - PERIPH_BASE)
+
+/* --- CLKCR Register ---*/
+/* Alias word address of CLKEN bit */
+#define CLKCR_OFFSET (SDIO_OFFSET + 0x04U)
+#define CLKEN_BITNUMBER 0x08U
+#define CLKCR_CLKEN_BB (PERIPH_BB_BASE + (CLKCR_OFFSET * 32U) + (CLKEN_BITNUMBER * 4U))
+
+/* --- CMD Register ---*/
+/* Alias word address of SDIOSUSPEND bit */
+#define CMD_OFFSET (SDIO_OFFSET + 0x0CU)
+#define SDIOSUSPEND_BITNUMBER 0x0BU
+#define CMD_SDIOSUSPEND_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32U) + (SDIOSUSPEND_BITNUMBER * 4U))
+
+/* Alias word address of ENCMDCOMPL bit */
+#define ENCMDCOMPL_BITNUMBER 0x0CU
+#define CMD_ENCMDCOMPL_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32U) + (ENCMDCOMPL_BITNUMBER * 4U))
+
+/* Alias word address of NIEN bit */
+#define NIEN_BITNUMBER 0x0DU
+#define CMD_NIEN_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32U) + (NIEN_BITNUMBER * 4U))
+
+/* Alias word address of ATACMD bit */
+#define ATACMD_BITNUMBER 0x0EU
+#define CMD_ATACMD_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32U) + (ATACMD_BITNUMBER * 4U))
+
+/* --- DCTRL Register ---*/
+/* Alias word address of DMAEN bit */
+#define DCTRL_OFFSET (SDIO_OFFSET + 0x2CU)
+#define DMAEN_BITNUMBER 0x03U
+#define DCTRL_DMAEN_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32U) + (DMAEN_BITNUMBER * 4U))
+
+/* Alias word address of RWSTART bit */
+#define RWSTART_BITNUMBER 0x08U
+#define DCTRL_RWSTART_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32U) + (RWSTART_BITNUMBER * 4U))
+
+/* Alias word address of RWSTOP bit */
+#define RWSTOP_BITNUMBER 0x09U
+#define DCTRL_RWSTOP_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32U) + (RWSTOP_BITNUMBER * 4U))
+
+/* Alias word address of RWMOD bit */
+#define RWMOD_BITNUMBER 0x0AU
+#define DCTRL_RWMOD_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32U) + (RWMOD_BITNUMBER * 4U))
+
+/* Alias word address of SDIOEN bit */
+#define SDIOEN_BITNUMBER 0x0BU
+#define DCTRL_SDIOEN_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32U) + (SDIOEN_BITNUMBER * 4U))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_Register Bits And Addresses Definitions
+ * @brief SDIO_LL registers bit address in the alias region
+ * @{
+ */
+/* ---------------------- SDIO registers bit mask --------------------------- */
+/* --- CLKCR Register ---*/
+/* CLKCR register clear mask */
+#define CLKCR_CLEAR_MASK ((uint32_t)(SDIO_CLKCR_CLKDIV | SDIO_CLKCR_PWRSAV |\
+ SDIO_CLKCR_BYPASS | SDIO_CLKCR_WIDBUS |\
+ SDIO_CLKCR_NEGEDGE | SDIO_CLKCR_HWFC_EN))
+
+/* --- DCTRL Register ---*/
+/* SDIO DCTRL Clear Mask */
+#define DCTRL_CLEAR_MASK ((uint32_t)(SDIO_DCTRL_DTEN | SDIO_DCTRL_DTDIR |\
+ SDIO_DCTRL_DTMODE | SDIO_DCTRL_DBLOCKSIZE))
+
+/* --- CMD Register ---*/
+/* CMD Register clear mask */
+#define CMD_CLEAR_MASK ((uint32_t)(SDIO_CMD_CMDINDEX | SDIO_CMD_WAITRESP |\
+ SDIO_CMD_WAITINT | SDIO_CMD_WAITPEND |\
+ SDIO_CMD_CPSMEN | SDIO_CMD_SDIOSUSPEND))
+
+/* SDIO RESP Registers Address */
+#define SDIO_RESP_ADDR ((uint32_t)(SDIO_BASE + 0x14))
+
+/* SDIO Intialization Frequency (400KHz max) */
+#define SDIO_INIT_CLK_DIV ((uint8_t)0xC3)
+
+/* SDIO Data Transfer Frequency */
+#define SDIO_TRANSFER_CLK_DIV ((uint8_t)0x9)
+
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_LL_Interrupt_Clock Interrupt And Clock Configuration
+ * @brief macros to handle interrupts and specific clock configurations
+ * @{
+ */
+
+/**
+ * @brief Enable the SDIO device.
+ * @param __INSTANCE__: SDIO Instance
+ * @retval None
+ */
+#define __SDIO_ENABLE(__INSTANCE__) (*(__IO uint32_t *)CLKCR_CLKEN_BB = ENABLE)
+
+/**
+ * @brief Disable the SDIO device.
+ * @param __INSTANCE__: SDIO Instance
+ * @retval None
+ */
+#define __SDIO_DISABLE(__INSTANCE__) (*(__IO uint32_t *)CLKCR_CLKEN_BB = DISABLE)
+
+/**
+ * @brief Enable the SDIO DMA transfer.
+ * @param __INSTANCE__: SDIO Instance
+ * @retval None
+ */
+#define __SDIO_DMA_ENABLE(__INSTANCE__) (*(__IO uint32_t *)DCTRL_DMAEN_BB = ENABLE)
+/**
+ * @brief Disable the SDIO DMA transfer.
+ * @param __INSTANCE__: SDIO Instance
+ * @retval None
+ */
+#define __SDIO_DMA_DISABLE(__INSTANCE__) (*(__IO uint32_t *)DCTRL_DMAEN_BB = DISABLE)
+
+/**
+ * @brief Enable the SDIO device interrupt.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @param __INTERRUPT__ : specifies the SDIO interrupt sources to be enabled.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
+ * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
+ * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
+ * @arg SDIO_IT_RXACT: Data receive in progress interrupt
+ * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
+ * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
+ * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
+ * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
+ * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
+ * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
+ * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
+ * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @retval None
+ */
+#define __SDIO_ENABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->MASK |= (__INTERRUPT__))
+
+/**
+ * @brief Disable the SDIO device interrupt.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @param __INTERRUPT__ : specifies the SDIO interrupt sources to be disabled.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
+ * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
+ * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
+ * @arg SDIO_IT_RXACT: Data receive in progress interrupt
+ * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
+ * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
+ * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
+ * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
+ * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
+ * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
+ * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
+ * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @retval None
+ */
+#define __SDIO_DISABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->MASK &= ~(__INTERRUPT__))
+
+/**
+ * @brief Checks whether the specified SDIO flag is set or not.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @param __FLAG__: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed)
+ * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed)
+ * @arg SDIO_FLAG_CTIMEOUT: Command response timeout
+ * @arg SDIO_FLAG_DTIMEOUT: Data timeout
+ * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error
+ * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error
+ * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed)
+ * @arg SDIO_FLAG_CMDSENT: Command sent (no response required)
+ * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero)
+ * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed)
+ * @arg SDIO_FLAG_CMDACT: Command transfer in progress
+ * @arg SDIO_FLAG_TXACT: Data transmit in progress
+ * @arg SDIO_FLAG_RXACT: Data receive in progress
+ * @arg SDIO_FLAG_TXFIFOHE: Transmit FIFO Half Empty
+ * @arg SDIO_FLAG_RXFIFOHF: Receive FIFO Half Full
+ * @arg SDIO_FLAG_TXFIFOF: Transmit FIFO full
+ * @arg SDIO_FLAG_RXFIFOF: Receive FIFO full
+ * @arg SDIO_FLAG_TXFIFOE: Transmit FIFO empty
+ * @arg SDIO_FLAG_RXFIFOE: Receive FIFO empty
+ * @arg SDIO_FLAG_TXDAVL: Data available in transmit FIFO
+ * @arg SDIO_FLAG_RXDAVL: Data available in receive FIFO
+ * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received
+ * @retval The new state of SDIO_FLAG (SET or RESET).
+ */
+#define __SDIO_GET_FLAG(__INSTANCE__, __FLAG__) (((__INSTANCE__)->STA &(__FLAG__)) != RESET)
+
+
+/**
+ * @brief Clears the SDIO pending flags.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @param __FLAG__: specifies the flag to clear.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed)
+ * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed)
+ * @arg SDIO_FLAG_CTIMEOUT: Command response timeout
+ * @arg SDIO_FLAG_DTIMEOUT: Data timeout
+ * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error
+ * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error
+ * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed)
+ * @arg SDIO_FLAG_CMDSENT: Command sent (no response required)
+ * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero)
+ * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed)
+ * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received
+ * @retval None
+ */
+#define __SDIO_CLEAR_FLAG(__INSTANCE__, __FLAG__) ((__INSTANCE__)->ICR = (__FLAG__))
+
+/**
+ * @brief Checks whether the specified SDIO interrupt has occurred or not.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @param __INTERRUPT__: specifies the SDIO interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
+ * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
+ * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
+ * @arg SDIO_IT_RXACT: Data receive in progress interrupt
+ * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
+ * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
+ * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
+ * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
+ * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
+ * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
+ * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
+ * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @retval The new state of SDIO_IT (SET or RESET).
+ */
+#define __SDIO_GET_IT (__INSTANCE__, __INTERRUPT__) (((__INSTANCE__)->STA &(__INTERRUPT__)) == (__INTERRUPT__))
+
+/**
+ * @brief Clears the SDIO's interrupt pending bits.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @param __INTERRUPT__: specifies the interrupt pending bit to clear.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIO_DCOUNT, is zero) interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @retval None
+ */
+#define __SDIO_CLEAR_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->ICR = (__INTERRUPT__))
+
+/**
+ * @brief Enable Start the SD I/O Read Wait operation.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_START_READWAIT_ENABLE(__INSTANCE__) (*(__IO uint32_t *) DCTRL_RWSTART_BB = ENABLE)
+
+/**
+ * @brief Disable Start the SD I/O Read Wait operations.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_START_READWAIT_DISABLE(__INSTANCE__) (*(__IO uint32_t *) DCTRL_RWSTART_BB = DISABLE)
+
+/**
+ * @brief Enable Start the SD I/O Read Wait operation.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_STOP_READWAIT_ENABLE(__INSTANCE__) (*(__IO uint32_t *) DCTRL_RWSTOP_BB = ENABLE)
+
+/**
+ * @brief Disable Stop the SD I/O Read Wait operations.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_STOP_READWAIT_DISABLE(__INSTANCE__) (*(__IO uint32_t *) DCTRL_RWSTOP_BB = DISABLE)
+
+/**
+ * @brief Enable the SD I/O Mode Operation.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_OPERATION_ENABLE(__INSTANCE__) (*(__IO uint32_t *) DCTRL_SDIOEN_BB = ENABLE)
+
+/**
+ * @brief Disable the SD I/O Mode Operation.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_OPERATION_DISABLE(__INSTANCE__) (*(__IO uint32_t *) DCTRL_SDIOEN_BB = DISABLE)
+
+/**
+ * @brief Enable the SD I/O Suspend command sending.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_SUSPEND_CMD_ENABLE(__INSTANCE__) (*(__IO uint32_t *) CMD_SDIOSUSPEND_BB = ENABLE)
+
+/**
+ * @brief Disable the SD I/O Suspend command sending.
+ * @param __INSTANCE__ : Pointer to SDIO register base
+ * @retval None
+ */
+#define __SDIO_SUSPEND_CMD_DISABLE(__INSTANCE__) (*(__IO uint32_t *) CMD_SDIOSUSPEND_BB = DISABLE)
+/**
+ * @brief Enable the command completion signal.
+ * @retval None
+ */
+#define __SDIO_CEATA_CMD_COMPLETION_ENABLE() (*(__IO uint32_t *) CMD_ENCMDCOMPL_BB = ENABLE)
+
+/**
+ * @brief Disable the command completion signal.
+ * @retval None
+ */
+#define __SDIO_CEATA_CMD_COMPLETION_DISABLE() (*(__IO uint32_t *) CMD_ENCMDCOMPL_BB = DISABLE)
+
+/**
+ * @brief Enable the CE-ATA interrupt.
+ * @retval None
+ */
+#define __SDIO_CEATA_ENABLE_IT() (*(__IO uint32_t *) CMD_NIEN_BB = (uint32_t)0U)
+
+/**
+ * @brief Disable the CE-ATA interrupt.
+ * @retval None
+ */
+#define __SDIO_CEATA_DISABLE_IT() (*(__IO uint32_t *) CMD_NIEN_BB = (uint32_t)1U)
+
+/**
+ * @brief Enable send CE-ATA command (CMD61).
+ * @retval None
+ */
+#define __SDIO_CEATA_SENDCMD_ENABLE() (*(__IO uint32_t *) CMD_ATACMD_BB = ENABLE)
+
+/**
+ * @brief Disable send CE-ATA command (CMD61).
+ * @retval None
+ */
+#define __SDIO_CEATA_SENDCMD_DISABLE() (*(__IO uint32_t *) CMD_ATACMD_BB = DISABLE)
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup SDMMC_LL_Exported_Functions
+ * @{
+ */
+
+/* Initialization/de-initialization functions **********************************/
+/** @addtogroup HAL_SDMMC_LL_Group1
+ * @{
+ */
+HAL_StatusTypeDef SDIO_Init(SDIO_TypeDef *SDIOx, SDIO_InitTypeDef Init);
+/**
+ * @}
+ */
+
+/* I/O operation functions *****************************************************/
+/** @addtogroup HAL_SDMMC_LL_Group2
+ * @{
+ */
+/* Blocking mode: Polling */
+uint32_t SDIO_ReadFIFO(SDIO_TypeDef *SDIOx);
+HAL_StatusTypeDef SDIO_WriteFIFO(SDIO_TypeDef *SDIOx, uint32_t *pWriteData);
+/**
+ * @}
+ */
+
+/* Peripheral Control functions ************************************************/
+/** @addtogroup HAL_SDMMC_LL_Group3
+ * @{
+ */
+HAL_StatusTypeDef SDIO_PowerState_ON(SDIO_TypeDef *SDIOx);
+HAL_StatusTypeDef SDIO_PowerState_OFF(SDIO_TypeDef *SDIOx);
+uint32_t SDIO_GetPowerState(SDIO_TypeDef *SDIOx);
+
+/* Command path state machine (CPSM) management functions */
+HAL_StatusTypeDef SDIO_SendCommand(SDIO_TypeDef *SDIOx, SDIO_CmdInitTypeDef *Command);
+uint8_t SDIO_GetCommandResponse(SDIO_TypeDef *SDIOx);
+uint32_t SDIO_GetResponse(SDIO_TypeDef *SDIOx, uint32_t Response);
+
+/* Data path state machine (DPSM) management functions */
+HAL_StatusTypeDef SDIO_ConfigData(SDIO_TypeDef *SDIOx, SDIO_DataInitTypeDef* Data);
+uint32_t SDIO_GetDataCounter(SDIO_TypeDef *SDIOx);
+uint32_t SDIO_GetFIFOCount(SDIO_TypeDef *SDIOx);
+
+/* SDMMC Cards mode management functions */
+HAL_StatusTypeDef SDIO_SetSDMMCReadWaitMode(SDIO_TypeDef *SDIOx, uint32_t SDIO_ReadWaitMode);
+
+/* SDMMC Commands management functions */
+uint32_t SDMMC_CmdBlockLength(SDIO_TypeDef *SDIOx, uint32_t BlockSize);
+uint32_t SDMMC_CmdReadSingleBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd);
+uint32_t SDMMC_CmdReadMultiBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd);
+uint32_t SDMMC_CmdWriteSingleBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd);
+uint32_t SDMMC_CmdWriteMultiBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd);
+uint32_t SDMMC_CmdSDEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd);
+uint32_t SDMMC_CmdSDEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd);
+uint32_t SDMMC_CmdErase(SDIO_TypeDef *SDIOx);
+uint32_t SDMMC_CmdStopTransfer(SDIO_TypeDef *SDIOx);
+uint32_t SDMMC_CmdSelDesel(SDIO_TypeDef *SDIOx, uint64_t Addr);
+uint32_t SDMMC_CmdGoIdleState(SDIO_TypeDef *SDIOx);
+uint32_t SDMMC_CmdOperCond(SDIO_TypeDef *SDIOx);
+uint32_t SDMMC_CmdAppCommand(SDIO_TypeDef *SDIOx, uint32_t Argument);
+uint32_t SDMMC_CmdAppOperCommand(SDIO_TypeDef *SDIOx, uint32_t SdType);
+uint32_t SDMMC_CmdBusWidth(SDIO_TypeDef *SDIOx, uint32_t BusWidth);
+uint32_t SDMMC_CmdSendSCR(SDIO_TypeDef *SDIOx);
+uint32_t SDMMC_CmdSendCID(SDIO_TypeDef *SDIOx);
+uint32_t SDMMC_CmdSendCSD(SDIO_TypeDef *SDIOx, uint32_t Argument);
+uint32_t SDMMC_CmdSetRelAdd(SDIO_TypeDef *SDIOx, uint16_t *pRCA);
+uint32_t SDMMC_CmdSendStatus(SDIO_TypeDef *SDIOx, uint32_t Argument);
+uint32_t SDMMC_CmdStatusRegister(SDIO_TypeDef *SDIOx);
+
+uint32_t SDMMC_CmdOpCondition(SDIO_TypeDef *SDIOx, uint32_t Argument);
+uint32_t SDMMC_CmdSwitch(SDIO_TypeDef *SDIOx, uint32_t Argument);
+uint32_t SDMMC_CmdEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd);
+uint32_t SDMMC_CmdEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32F103xE || STM32F103xG */
+
+#endif /* __stm32f1xx_LL_SD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_spi.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_spi.h
new file mode 100644
index 0000000..379ae2d
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_spi.h
@@ -0,0 +1,1920 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_spi.h
+ * @author MCD Application Team
+ * @brief Header file of SPI LL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_SPI_H
+#define __STM32F1xx_LL_SPI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx.h"
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (SPI1) || defined (SPI2) || defined (SPI3)
+
+/** @defgroup SPI_LL SPI
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+
+/* Exported types ------------------------------------------------------------*/
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup SPI_LL_ES_INIT SPI Exported Init structure
+ * @{
+ */
+
+/**
+ * @brief SPI Init structures definition
+ */
+typedef struct
+{
+ uint32_t TransferDirection; /*!< Specifies the SPI unidirectional or bidirectional data mode.
+ This parameter can be a value of @ref SPI_LL_EC_TRANSFER_MODE.
+
+ This feature can be modified afterwards using unitary function @ref LL_SPI_SetTransferDirection().*/
+
+ uint32_t Mode; /*!< Specifies the SPI mode (Master/Slave).
+ This parameter can be a value of @ref SPI_LL_EC_MODE.
+
+ This feature can be modified afterwards using unitary function @ref LL_SPI_SetMode().*/
+
+ uint32_t DataWidth; /*!< Specifies the SPI data width.
+ This parameter can be a value of @ref SPI_LL_EC_DATAWIDTH.
+
+ This feature can be modified afterwards using unitary function @ref LL_SPI_SetDataWidth().*/
+
+ uint32_t ClockPolarity; /*!< Specifies the serial clock steady state.
+ This parameter can be a value of @ref SPI_LL_EC_POLARITY.
+
+ This feature can be modified afterwards using unitary function @ref LL_SPI_SetClockPolarity().*/
+
+ uint32_t ClockPhase; /*!< Specifies the clock active edge for the bit capture.
+ This parameter can be a value of @ref SPI_LL_EC_PHASE.
+
+ This feature can be modified afterwards using unitary function @ref LL_SPI_SetClockPhase().*/
+
+ uint32_t NSS; /*!< Specifies whether the NSS signal is managed by hardware (NSS pin) or by software using the SSI bit.
+ This parameter can be a value of @ref SPI_LL_EC_NSS_MODE.
+
+ This feature can be modified afterwards using unitary function @ref LL_SPI_SetNSSMode().*/
+
+ uint32_t BaudRate; /*!< Specifies the BaudRate prescaler value which will be used to configure the transmit and receive SCK clock.
+ This parameter can be a value of @ref SPI_LL_EC_BAUDRATEPRESCALER.
+ @note The communication clock is derived from the master clock. The slave clock does not need to be set.
+
+ This feature can be modified afterwards using unitary function @ref LL_SPI_SetBaudRatePrescaler().*/
+
+ uint32_t BitOrder; /*!< Specifies whether data transfers start from MSB or LSB bit.
+ This parameter can be a value of @ref SPI_LL_EC_BIT_ORDER.
+
+ This feature can be modified afterwards using unitary function @ref LL_SPI_SetTransferBitOrder().*/
+
+ uint32_t CRCCalculation; /*!< Specifies if the CRC calculation is enabled or not.
+ This parameter can be a value of @ref SPI_LL_EC_CRC_CALCULATION.
+
+ This feature can be modified afterwards using unitary functions @ref LL_SPI_EnableCRC() and @ref LL_SPI_DisableCRC().*/
+
+ uint32_t CRCPoly; /*!< Specifies the polynomial used for the CRC calculation.
+ This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFFFF.
+
+ This feature can be modified afterwards using unitary function @ref LL_SPI_SetCRCPolynomial().*/
+
+} LL_SPI_InitTypeDef;
+
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup SPI_LL_Exported_Constants SPI Exported Constants
+ * @{
+ */
+
+/** @defgroup SPI_LL_EC_GET_FLAG Get Flags Defines
+ * @brief Flags defines which can be used with LL_SPI_ReadReg function
+ * @{
+ */
+#define LL_SPI_SR_RXNE SPI_SR_RXNE /*!< Rx buffer not empty flag */
+#define LL_SPI_SR_TXE SPI_SR_TXE /*!< Tx buffer empty flag */
+#define LL_SPI_SR_BSY SPI_SR_BSY /*!< Busy flag */
+#define LL_SPI_SR_CRCERR SPI_SR_CRCERR /*!< CRC error flag */
+#define LL_SPI_SR_MODF SPI_SR_MODF /*!< Mode fault flag */
+#define LL_SPI_SR_OVR SPI_SR_OVR /*!< Overrun flag */
+#define LL_SPI_SR_FRE SPI_SR_FRE /*!< TI mode frame format error flag */
+/**
+ * @}
+ */
+
+/** @defgroup SPI_LL_EC_IT IT Defines
+ * @brief IT defines which can be used with LL_SPI_ReadReg and LL_SPI_WriteReg functions
+ * @{
+ */
+#define LL_SPI_CR2_RXNEIE SPI_CR2_RXNEIE /*!< Rx buffer not empty interrupt enable */
+#define LL_SPI_CR2_TXEIE SPI_CR2_TXEIE /*!< Tx buffer empty interrupt enable */
+#define LL_SPI_CR2_ERRIE SPI_CR2_ERRIE /*!< Error interrupt enable */
+/**
+ * @}
+ */
+
+/** @defgroup SPI_LL_EC_MODE Operation Mode
+ * @{
+ */
+#define LL_SPI_MODE_MASTER (SPI_CR1_MSTR | SPI_CR1_SSI) /*!< Master configuration */
+#define LL_SPI_MODE_SLAVE 0x00000000U /*!< Slave configuration */
+/**
+ * @}
+ */
+
+
+/** @defgroup SPI_LL_EC_PHASE Clock Phase
+ * @{
+ */
+#define LL_SPI_PHASE_1EDGE 0x00000000U /*!< First clock transition is the first data capture edge */
+#define LL_SPI_PHASE_2EDGE (SPI_CR1_CPHA) /*!< Second clock transition is the first data capture edge */
+/**
+ * @}
+ */
+
+/** @defgroup SPI_LL_EC_POLARITY Clock Polarity
+ * @{
+ */
+#define LL_SPI_POLARITY_LOW 0x00000000U /*!< Clock to 0 when idle */
+#define LL_SPI_POLARITY_HIGH (SPI_CR1_CPOL) /*!< Clock to 1 when idle */
+/**
+ * @}
+ */
+
+/** @defgroup SPI_LL_EC_BAUDRATEPRESCALER Baud Rate Prescaler
+ * @{
+ */
+#define LL_SPI_BAUDRATEPRESCALER_DIV2 0x00000000U /*!< BaudRate control equal to fPCLK/2 */
+#define LL_SPI_BAUDRATEPRESCALER_DIV4 (SPI_CR1_BR_0) /*!< BaudRate control equal to fPCLK/4 */
+#define LL_SPI_BAUDRATEPRESCALER_DIV8 (SPI_CR1_BR_1) /*!< BaudRate control equal to fPCLK/8 */
+#define LL_SPI_BAUDRATEPRESCALER_DIV16 (SPI_CR1_BR_1 | SPI_CR1_BR_0) /*!< BaudRate control equal to fPCLK/16 */
+#define LL_SPI_BAUDRATEPRESCALER_DIV32 (SPI_CR1_BR_2) /*!< BaudRate control equal to fPCLK/32 */
+#define LL_SPI_BAUDRATEPRESCALER_DIV64 (SPI_CR1_BR_2 | SPI_CR1_BR_0) /*!< BaudRate control equal to fPCLK/64 */
+#define LL_SPI_BAUDRATEPRESCALER_DIV128 (SPI_CR1_BR_2 | SPI_CR1_BR_1) /*!< BaudRate control equal to fPCLK/128 */
+#define LL_SPI_BAUDRATEPRESCALER_DIV256 (SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0) /*!< BaudRate control equal to fPCLK/256 */
+/**
+ * @}
+ */
+
+/** @defgroup SPI_LL_EC_BIT_ORDER Transmission Bit Order
+ * @{
+ */
+#define LL_SPI_LSB_FIRST (SPI_CR1_LSBFIRST) /*!< Data is transmitted/received with the LSB first */
+#define LL_SPI_MSB_FIRST 0x00000000U /*!< Data is transmitted/received with the MSB first */
+/**
+ * @}
+ */
+
+/** @defgroup SPI_LL_EC_TRANSFER_MODE Transfer Mode
+ * @{
+ */
+#define LL_SPI_FULL_DUPLEX 0x00000000U /*!< Full-Duplex mode. Rx and Tx transfer on 2 lines */
+#define LL_SPI_SIMPLEX_RX (SPI_CR1_RXONLY) /*!< Simplex Rx mode. Rx transfer only on 1 line */
+#define LL_SPI_HALF_DUPLEX_RX (SPI_CR1_BIDIMODE) /*!< Half-Duplex Rx mode. Rx transfer on 1 line */
+#define LL_SPI_HALF_DUPLEX_TX (SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE) /*!< Half-Duplex Tx mode. Tx transfer on 1 line */
+/**
+ * @}
+ */
+
+/** @defgroup SPI_LL_EC_NSS_MODE Slave Select Pin Mode
+ * @{
+ */
+#define LL_SPI_NSS_SOFT (SPI_CR1_SSM) /*!< NSS managed internally. NSS pin not used and free */
+#define LL_SPI_NSS_HARD_INPUT 0x00000000U /*!< NSS pin used in Input. Only used in Master mode */
+#define LL_SPI_NSS_HARD_OUTPUT (((uint32_t)SPI_CR2_SSOE << 16U)) /*!< NSS pin used in Output. Only used in Slave mode as chip select */
+/**
+ * @}
+ */
+
+/** @defgroup SPI_LL_EC_DATAWIDTH Datawidth
+ * @{
+ */
+#define LL_SPI_DATAWIDTH_8BIT 0x00000000U /*!< Data length for SPI transfer: 8 bits */
+#define LL_SPI_DATAWIDTH_16BIT (SPI_CR1_DFF) /*!< Data length for SPI transfer: 16 bits */
+/**
+ * @}
+ */
+#if defined(USE_FULL_LL_DRIVER)
+
+/** @defgroup SPI_LL_EC_CRC_CALCULATION CRC Calculation
+ * @{
+ */
+#define LL_SPI_CRCCALCULATION_DISABLE 0x00000000U /*!< CRC calculation disabled */
+#define LL_SPI_CRCCALCULATION_ENABLE (SPI_CR1_CRCEN) /*!< CRC calculation enabled */
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup SPI_LL_Exported_Macros SPI Exported Macros
+ * @{
+ */
+
+/** @defgroup SPI_LL_EM_WRITE_READ Common Write and read registers Macros
+ * @{
+ */
+
+/**
+ * @brief Write a value in SPI register
+ * @param __INSTANCE__ SPI Instance
+ * @param __REG__ Register to be written
+ * @param __VALUE__ Value to be written in the register
+ * @retval None
+ */
+#define LL_SPI_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
+
+/**
+ * @brief Read a value in SPI register
+ * @param __INSTANCE__ SPI Instance
+ * @param __REG__ Register to be read
+ * @retval Register value
+ */
+#define LL_SPI_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup SPI_LL_Exported_Functions SPI Exported Functions
+ * @{
+ */
+
+/** @defgroup SPI_LL_EF_Configuration Configuration
+ * @{
+ */
+
+/**
+ * @brief Enable SPI peripheral
+ * @rmtoll CR1 SPE LL_SPI_Enable
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_Enable(SPI_TypeDef *SPIx)
+{
+ SET_BIT(SPIx->CR1, SPI_CR1_SPE);
+}
+
+/**
+ * @brief Disable SPI peripheral
+ * @note When disabling the SPI, follow the procedure described in the Reference Manual.
+ * @rmtoll CR1 SPE LL_SPI_Disable
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_Disable(SPI_TypeDef *SPIx)
+{
+ CLEAR_BIT(SPIx->CR1, SPI_CR1_SPE);
+}
+
+/**
+ * @brief Check if SPI peripheral is enabled
+ * @rmtoll CR1 SPE LL_SPI_IsEnabled
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_SPI_IsEnabled(SPI_TypeDef *SPIx)
+{
+ return (READ_BIT(SPIx->CR1, SPI_CR1_SPE) == (SPI_CR1_SPE));
+}
+
+/**
+ * @brief Set SPI operation mode to Master or Slave
+ * @note This bit should not be changed when communication is ongoing.
+ * @rmtoll CR1 MSTR LL_SPI_SetMode\n
+ * CR1 SSI LL_SPI_SetMode
+ * @param SPIx SPI Instance
+ * @param Mode This parameter can be one of the following values:
+ * @arg @ref LL_SPI_MODE_MASTER
+ * @arg @ref LL_SPI_MODE_SLAVE
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_SetMode(SPI_TypeDef *SPIx, uint32_t Mode)
+{
+ MODIFY_REG(SPIx->CR1, SPI_CR1_MSTR | SPI_CR1_SSI, Mode);
+}
+
+/**
+ * @brief Get SPI operation mode (Master or Slave)
+ * @rmtoll CR1 MSTR LL_SPI_GetMode\n
+ * CR1 SSI LL_SPI_GetMode
+ * @param SPIx SPI Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_SPI_MODE_MASTER
+ * @arg @ref LL_SPI_MODE_SLAVE
+ */
+__STATIC_INLINE uint32_t LL_SPI_GetMode(SPI_TypeDef *SPIx)
+{
+ return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_MSTR | SPI_CR1_SSI));
+}
+
+
+/**
+ * @brief Set clock phase
+ * @note This bit should not be changed when communication is ongoing.
+ * This bit is not used in SPI TI mode.
+ * @rmtoll CR1 CPHA LL_SPI_SetClockPhase
+ * @param SPIx SPI Instance
+ * @param ClockPhase This parameter can be one of the following values:
+ * @arg @ref LL_SPI_PHASE_1EDGE
+ * @arg @ref LL_SPI_PHASE_2EDGE
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_SetClockPhase(SPI_TypeDef *SPIx, uint32_t ClockPhase)
+{
+ MODIFY_REG(SPIx->CR1, SPI_CR1_CPHA, ClockPhase);
+}
+
+/**
+ * @brief Get clock phase
+ * @rmtoll CR1 CPHA LL_SPI_GetClockPhase
+ * @param SPIx SPI Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_SPI_PHASE_1EDGE
+ * @arg @ref LL_SPI_PHASE_2EDGE
+ */
+__STATIC_INLINE uint32_t LL_SPI_GetClockPhase(SPI_TypeDef *SPIx)
+{
+ return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_CPHA));
+}
+
+/**
+ * @brief Set clock polarity
+ * @note This bit should not be changed when communication is ongoing.
+ * This bit is not used in SPI TI mode.
+ * @rmtoll CR1 CPOL LL_SPI_SetClockPolarity
+ * @param SPIx SPI Instance
+ * @param ClockPolarity This parameter can be one of the following values:
+ * @arg @ref LL_SPI_POLARITY_LOW
+ * @arg @ref LL_SPI_POLARITY_HIGH
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_SetClockPolarity(SPI_TypeDef *SPIx, uint32_t ClockPolarity)
+{
+ MODIFY_REG(SPIx->CR1, SPI_CR1_CPOL, ClockPolarity);
+}
+
+/**
+ * @brief Get clock polarity
+ * @rmtoll CR1 CPOL LL_SPI_GetClockPolarity
+ * @param SPIx SPI Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_SPI_POLARITY_LOW
+ * @arg @ref LL_SPI_POLARITY_HIGH
+ */
+__STATIC_INLINE uint32_t LL_SPI_GetClockPolarity(SPI_TypeDef *SPIx)
+{
+ return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_CPOL));
+}
+
+/**
+ * @brief Set baud rate prescaler
+ * @note These bits should not be changed when communication is ongoing. SPI BaudRate = fPCLK/Prescaler.
+ * @rmtoll CR1 BR LL_SPI_SetBaudRatePrescaler
+ * @param SPIx SPI Instance
+ * @param BaudRate This parameter can be one of the following values:
+ * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV2
+ * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV4
+ * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV8
+ * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV16
+ * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV32
+ * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV64
+ * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV128
+ * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV256
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_SetBaudRatePrescaler(SPI_TypeDef *SPIx, uint32_t BaudRate)
+{
+ MODIFY_REG(SPIx->CR1, SPI_CR1_BR, BaudRate);
+}
+
+/**
+ * @brief Get baud rate prescaler
+ * @rmtoll CR1 BR LL_SPI_GetBaudRatePrescaler
+ * @param SPIx SPI Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV2
+ * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV4
+ * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV8
+ * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV16
+ * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV32
+ * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV64
+ * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV128
+ * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV256
+ */
+__STATIC_INLINE uint32_t LL_SPI_GetBaudRatePrescaler(SPI_TypeDef *SPIx)
+{
+ return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_BR));
+}
+
+/**
+ * @brief Set transfer bit order
+ * @note This bit should not be changed when communication is ongoing. This bit is not used in SPI TI mode.
+ * @rmtoll CR1 LSBFIRST LL_SPI_SetTransferBitOrder
+ * @param SPIx SPI Instance
+ * @param BitOrder This parameter can be one of the following values:
+ * @arg @ref LL_SPI_LSB_FIRST
+ * @arg @ref LL_SPI_MSB_FIRST
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_SetTransferBitOrder(SPI_TypeDef *SPIx, uint32_t BitOrder)
+{
+ MODIFY_REG(SPIx->CR1, SPI_CR1_LSBFIRST, BitOrder);
+}
+
+/**
+ * @brief Get transfer bit order
+ * @rmtoll CR1 LSBFIRST LL_SPI_GetTransferBitOrder
+ * @param SPIx SPI Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_SPI_LSB_FIRST
+ * @arg @ref LL_SPI_MSB_FIRST
+ */
+__STATIC_INLINE uint32_t LL_SPI_GetTransferBitOrder(SPI_TypeDef *SPIx)
+{
+ return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_LSBFIRST));
+}
+
+/**
+ * @brief Set transfer direction mode
+ * @note For Half-Duplex mode, Rx Direction is set by default.
+ * In master mode, the MOSI pin is used and in slave mode, the MISO pin is used for Half-Duplex.
+ * @rmtoll CR1 RXONLY LL_SPI_SetTransferDirection\n
+ * CR1 BIDIMODE LL_SPI_SetTransferDirection\n
+ * CR1 BIDIOE LL_SPI_SetTransferDirection
+ * @param SPIx SPI Instance
+ * @param TransferDirection This parameter can be one of the following values:
+ * @arg @ref LL_SPI_FULL_DUPLEX
+ * @arg @ref LL_SPI_SIMPLEX_RX
+ * @arg @ref LL_SPI_HALF_DUPLEX_RX
+ * @arg @ref LL_SPI_HALF_DUPLEX_TX
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_SetTransferDirection(SPI_TypeDef *SPIx, uint32_t TransferDirection)
+{
+ MODIFY_REG(SPIx->CR1, SPI_CR1_RXONLY | SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE, TransferDirection);
+}
+
+/**
+ * @brief Get transfer direction mode
+ * @rmtoll CR1 RXONLY LL_SPI_GetTransferDirection\n
+ * CR1 BIDIMODE LL_SPI_GetTransferDirection\n
+ * CR1 BIDIOE LL_SPI_GetTransferDirection
+ * @param SPIx SPI Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_SPI_FULL_DUPLEX
+ * @arg @ref LL_SPI_SIMPLEX_RX
+ * @arg @ref LL_SPI_HALF_DUPLEX_RX
+ * @arg @ref LL_SPI_HALF_DUPLEX_TX
+ */
+__STATIC_INLINE uint32_t LL_SPI_GetTransferDirection(SPI_TypeDef *SPIx)
+{
+ return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_RXONLY | SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE));
+}
+
+/**
+ * @brief Set frame data width
+ * @rmtoll CR1 DFF LL_SPI_SetDataWidth
+ * @param SPIx SPI Instance
+ * @param DataWidth This parameter can be one of the following values:
+ * @arg @ref LL_SPI_DATAWIDTH_8BIT
+ * @arg @ref LL_SPI_DATAWIDTH_16BIT
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_SetDataWidth(SPI_TypeDef *SPIx, uint32_t DataWidth)
+{
+ MODIFY_REG(SPIx->CR1, SPI_CR1_DFF, DataWidth);
+}
+
+/**
+ * @brief Get frame data width
+ * @rmtoll CR1 DFF LL_SPI_GetDataWidth
+ * @param SPIx SPI Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_SPI_DATAWIDTH_8BIT
+ * @arg @ref LL_SPI_DATAWIDTH_16BIT
+ */
+__STATIC_INLINE uint32_t LL_SPI_GetDataWidth(SPI_TypeDef *SPIx)
+{
+ return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_DFF));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SPI_LL_EF_CRC_Management CRC Management
+ * @{
+ */
+
+/**
+ * @brief Enable CRC
+ * @note This bit should be written only when SPI is disabled (SPE = 0) for correct operation.
+ * @rmtoll CR1 CRCEN LL_SPI_EnableCRC
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_EnableCRC(SPI_TypeDef *SPIx)
+{
+ SET_BIT(SPIx->CR1, SPI_CR1_CRCEN);
+}
+
+/**
+ * @brief Disable CRC
+ * @note This bit should be written only when SPI is disabled (SPE = 0) for correct operation.
+ * @rmtoll CR1 CRCEN LL_SPI_DisableCRC
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_DisableCRC(SPI_TypeDef *SPIx)
+{
+ CLEAR_BIT(SPIx->CR1, SPI_CR1_CRCEN);
+}
+
+/**
+ * @brief Check if CRC is enabled
+ * @note This bit should be written only when SPI is disabled (SPE = 0) for correct operation.
+ * @rmtoll CR1 CRCEN LL_SPI_IsEnabledCRC
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_SPI_IsEnabledCRC(SPI_TypeDef *SPIx)
+{
+ return (READ_BIT(SPIx->CR1, SPI_CR1_CRCEN) == (SPI_CR1_CRCEN));
+}
+
+/**
+ * @brief Set CRCNext to transfer CRC on the line
+ * @note This bit has to be written as soon as the last data is written in the SPIx_DR register.
+ * @rmtoll CR1 CRCNEXT LL_SPI_SetCRCNext
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_SetCRCNext(SPI_TypeDef *SPIx)
+{
+ SET_BIT(SPIx->CR1, SPI_CR1_CRCNEXT);
+}
+
+/**
+ * @brief Set polynomial for CRC calculation
+ * @rmtoll CRCPR CRCPOLY LL_SPI_SetCRCPolynomial
+ * @param SPIx SPI Instance
+ * @param CRCPoly This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFFFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_SetCRCPolynomial(SPI_TypeDef *SPIx, uint32_t CRCPoly)
+{
+ WRITE_REG(SPIx->CRCPR, (uint16_t)CRCPoly);
+}
+
+/**
+ * @brief Get polynomial for CRC calculation
+ * @rmtoll CRCPR CRCPOLY LL_SPI_GetCRCPolynomial
+ * @param SPIx SPI Instance
+ * @retval Returned value is a number between Min_Data = 0x00 and Max_Data = 0xFFFF
+ */
+__STATIC_INLINE uint32_t LL_SPI_GetCRCPolynomial(SPI_TypeDef *SPIx)
+{
+ return (uint32_t)(READ_REG(SPIx->CRCPR));
+}
+
+/**
+ * @brief Get Rx CRC
+ * @rmtoll RXCRCR RXCRC LL_SPI_GetRxCRC
+ * @param SPIx SPI Instance
+ * @retval Returned value is a number between Min_Data = 0x00 and Max_Data = 0xFFFF
+ */
+__STATIC_INLINE uint32_t LL_SPI_GetRxCRC(SPI_TypeDef *SPIx)
+{
+ return (uint32_t)(READ_REG(SPIx->RXCRCR));
+}
+
+/**
+ * @brief Get Tx CRC
+ * @rmtoll TXCRCR TXCRC LL_SPI_GetTxCRC
+ * @param SPIx SPI Instance
+ * @retval Returned value is a number between Min_Data = 0x00 and Max_Data = 0xFFFF
+ */
+__STATIC_INLINE uint32_t LL_SPI_GetTxCRC(SPI_TypeDef *SPIx)
+{
+ return (uint32_t)(READ_REG(SPIx->TXCRCR));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SPI_LL_EF_NSS_Management Slave Select Pin Management
+ * @{
+ */
+
+/**
+ * @brief Set NSS mode
+ * @note LL_SPI_NSS_SOFT Mode is not used in SPI TI mode.
+ * @rmtoll CR1 SSM LL_SPI_SetNSSMode\n
+ * @rmtoll CR2 SSOE LL_SPI_SetNSSMode
+ * @param SPIx SPI Instance
+ * @param NSS This parameter can be one of the following values:
+ * @arg @ref LL_SPI_NSS_SOFT
+ * @arg @ref LL_SPI_NSS_HARD_INPUT
+ * @arg @ref LL_SPI_NSS_HARD_OUTPUT
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_SetNSSMode(SPI_TypeDef *SPIx, uint32_t NSS)
+{
+ MODIFY_REG(SPIx->CR1, SPI_CR1_SSM, NSS);
+ MODIFY_REG(SPIx->CR2, SPI_CR2_SSOE, ((uint32_t)(NSS >> 16U)));
+}
+
+/**
+ * @brief Get NSS mode
+ * @rmtoll CR1 SSM LL_SPI_GetNSSMode\n
+ * @rmtoll CR2 SSOE LL_SPI_GetNSSMode
+ * @param SPIx SPI Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_SPI_NSS_SOFT
+ * @arg @ref LL_SPI_NSS_HARD_INPUT
+ * @arg @ref LL_SPI_NSS_HARD_OUTPUT
+ */
+__STATIC_INLINE uint32_t LL_SPI_GetNSSMode(SPI_TypeDef *SPIx)
+{
+ register uint32_t Ssm = (READ_BIT(SPIx->CR1, SPI_CR1_SSM));
+ register uint32_t Ssoe = (READ_BIT(SPIx->CR2, SPI_CR2_SSOE) << 16U);
+ return (Ssm | Ssoe);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SPI_LL_EF_FLAG_Management FLAG Management
+ * @{
+ */
+
+/**
+ * @brief Check if Rx buffer is not empty
+ * @rmtoll SR RXNE LL_SPI_IsActiveFlag_RXNE
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_RXNE(SPI_TypeDef *SPIx)
+{
+ return (READ_BIT(SPIx->SR, SPI_SR_RXNE) == (SPI_SR_RXNE));
+}
+
+/**
+ * @brief Check if Tx buffer is empty
+ * @rmtoll SR TXE LL_SPI_IsActiveFlag_TXE
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_TXE(SPI_TypeDef *SPIx)
+{
+ return (READ_BIT(SPIx->SR, SPI_SR_TXE) == (SPI_SR_TXE));
+}
+
+/**
+ * @brief Get CRC error flag
+ * @rmtoll SR CRCERR LL_SPI_IsActiveFlag_CRCERR
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_CRCERR(SPI_TypeDef *SPIx)
+{
+ return (READ_BIT(SPIx->SR, SPI_SR_CRCERR) == (SPI_SR_CRCERR));
+}
+
+/**
+ * @brief Get mode fault error flag
+ * @rmtoll SR MODF LL_SPI_IsActiveFlag_MODF
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_MODF(SPI_TypeDef *SPIx)
+{
+ return (READ_BIT(SPIx->SR, SPI_SR_MODF) == (SPI_SR_MODF));
+}
+
+/**
+ * @brief Get overrun error flag
+ * @rmtoll SR OVR LL_SPI_IsActiveFlag_OVR
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_OVR(SPI_TypeDef *SPIx)
+{
+ return (READ_BIT(SPIx->SR, SPI_SR_OVR) == (SPI_SR_OVR));
+}
+
+/**
+ * @brief Get busy flag
+ * @note The BSY flag is cleared under any one of the following conditions:
+ * -When the SPI is correctly disabled
+ * -When a fault is detected in Master mode (MODF bit set to 1)
+ * -In Master mode, when it finishes a data transmission and no new data is ready to be
+ * sent
+ * -In Slave mode, when the BSY flag is set to '0' for at least one SPI clock cycle between
+ * each data transfer.
+ * @rmtoll SR BSY LL_SPI_IsActiveFlag_BSY
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_BSY(SPI_TypeDef *SPIx)
+{
+ return (READ_BIT(SPIx->SR, SPI_SR_BSY) == (SPI_SR_BSY));
+}
+
+
+/**
+ * @brief Clear CRC error flag
+ * @rmtoll SR CRCERR LL_SPI_ClearFlag_CRCERR
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_ClearFlag_CRCERR(SPI_TypeDef *SPIx)
+{
+ CLEAR_BIT(SPIx->SR, SPI_SR_CRCERR);
+}
+
+/**
+ * @brief Clear mode fault error flag
+ * @note Clearing this flag is done by a read access to the SPIx_SR
+ * register followed by a write access to the SPIx_CR1 register
+ * @rmtoll SR MODF LL_SPI_ClearFlag_MODF
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_ClearFlag_MODF(SPI_TypeDef *SPIx)
+{
+ __IO uint32_t tmpreg;
+ tmpreg = SPIx->SR;
+ (void) tmpreg;
+ tmpreg = CLEAR_BIT(SPIx->CR1, SPI_CR1_SPE);
+ (void) tmpreg;
+}
+
+/**
+ * @brief Clear overrun error flag
+ * @note Clearing this flag is done by a read access to the SPIx_DR
+ * register followed by a read access to the SPIx_SR register
+ * @rmtoll SR OVR LL_SPI_ClearFlag_OVR
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_ClearFlag_OVR(SPI_TypeDef *SPIx)
+{
+ __IO uint32_t tmpreg;
+ tmpreg = SPIx->DR;
+ (void) tmpreg;
+ tmpreg = SPIx->SR;
+ (void) tmpreg;
+}
+
+
+/**
+ * @}
+ */
+
+/** @defgroup SPI_LL_EF_IT_Management Interrupt Management
+ * @{
+ */
+
+/**
+ * @brief Enable error interrupt
+ * @note This bit controls the generation of an interrupt when an error condition occurs (CRCERR, OVR, MODF in SPI mode, FRE at TI mode).
+ * @rmtoll CR2 ERRIE LL_SPI_EnableIT_ERR
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_EnableIT_ERR(SPI_TypeDef *SPIx)
+{
+ SET_BIT(SPIx->CR2, SPI_CR2_ERRIE);
+}
+
+/**
+ * @brief Enable Rx buffer not empty interrupt
+ * @rmtoll CR2 RXNEIE LL_SPI_EnableIT_RXNE
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_EnableIT_RXNE(SPI_TypeDef *SPIx)
+{
+ SET_BIT(SPIx->CR2, SPI_CR2_RXNEIE);
+}
+
+/**
+ * @brief Enable Tx buffer empty interrupt
+ * @rmtoll CR2 TXEIE LL_SPI_EnableIT_TXE
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_EnableIT_TXE(SPI_TypeDef *SPIx)
+{
+ SET_BIT(SPIx->CR2, SPI_CR2_TXEIE);
+}
+
+/**
+ * @brief Disable error interrupt
+ * @note This bit controls the generation of an interrupt when an error condition occurs (CRCERR, OVR, MODF in SPI mode, FRE at TI mode).
+ * @rmtoll CR2 ERRIE LL_SPI_DisableIT_ERR
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_DisableIT_ERR(SPI_TypeDef *SPIx)
+{
+ CLEAR_BIT(SPIx->CR2, SPI_CR2_ERRIE);
+}
+
+/**
+ * @brief Disable Rx buffer not empty interrupt
+ * @rmtoll CR2 RXNEIE LL_SPI_DisableIT_RXNE
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_DisableIT_RXNE(SPI_TypeDef *SPIx)
+{
+ CLEAR_BIT(SPIx->CR2, SPI_CR2_RXNEIE);
+}
+
+/**
+ * @brief Disable Tx buffer empty interrupt
+ * @rmtoll CR2 TXEIE LL_SPI_DisableIT_TXE
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_DisableIT_TXE(SPI_TypeDef *SPIx)
+{
+ CLEAR_BIT(SPIx->CR2, SPI_CR2_TXEIE);
+}
+
+/**
+ * @brief Check if error interrupt is enabled
+ * @rmtoll CR2 ERRIE LL_SPI_IsEnabledIT_ERR
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_ERR(SPI_TypeDef *SPIx)
+{
+ return (READ_BIT(SPIx->CR2, SPI_CR2_ERRIE) == (SPI_CR2_ERRIE));
+}
+
+/**
+ * @brief Check if Rx buffer not empty interrupt is enabled
+ * @rmtoll CR2 RXNEIE LL_SPI_IsEnabledIT_RXNE
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_RXNE(SPI_TypeDef *SPIx)
+{
+ return (READ_BIT(SPIx->CR2, SPI_CR2_RXNEIE) == (SPI_CR2_RXNEIE));
+}
+
+/**
+ * @brief Check if Tx buffer empty interrupt
+ * @rmtoll CR2 TXEIE LL_SPI_IsEnabledIT_TXE
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_TXE(SPI_TypeDef *SPIx)
+{
+ return (READ_BIT(SPIx->CR2, SPI_CR2_TXEIE) == (SPI_CR2_TXEIE));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SPI_LL_EF_DMA_Management DMA Management
+ * @{
+ */
+
+/**
+ * @brief Enable DMA Rx
+ * @rmtoll CR2 RXDMAEN LL_SPI_EnableDMAReq_RX
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_EnableDMAReq_RX(SPI_TypeDef *SPIx)
+{
+ SET_BIT(SPIx->CR2, SPI_CR2_RXDMAEN);
+}
+
+/**
+ * @brief Disable DMA Rx
+ * @rmtoll CR2 RXDMAEN LL_SPI_DisableDMAReq_RX
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_DisableDMAReq_RX(SPI_TypeDef *SPIx)
+{
+ CLEAR_BIT(SPIx->CR2, SPI_CR2_RXDMAEN);
+}
+
+/**
+ * @brief Check if DMA Rx is enabled
+ * @rmtoll CR2 RXDMAEN LL_SPI_IsEnabledDMAReq_RX
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_SPI_IsEnabledDMAReq_RX(SPI_TypeDef *SPIx)
+{
+ return (READ_BIT(SPIx->CR2, SPI_CR2_RXDMAEN) == (SPI_CR2_RXDMAEN));
+}
+
+/**
+ * @brief Enable DMA Tx
+ * @rmtoll CR2 TXDMAEN LL_SPI_EnableDMAReq_TX
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_EnableDMAReq_TX(SPI_TypeDef *SPIx)
+{
+ SET_BIT(SPIx->CR2, SPI_CR2_TXDMAEN);
+}
+
+/**
+ * @brief Disable DMA Tx
+ * @rmtoll CR2 TXDMAEN LL_SPI_DisableDMAReq_TX
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_DisableDMAReq_TX(SPI_TypeDef *SPIx)
+{
+ CLEAR_BIT(SPIx->CR2, SPI_CR2_TXDMAEN);
+}
+
+/**
+ * @brief Check if DMA Tx is enabled
+ * @rmtoll CR2 TXDMAEN LL_SPI_IsEnabledDMAReq_TX
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_SPI_IsEnabledDMAReq_TX(SPI_TypeDef *SPIx)
+{
+ return (READ_BIT(SPIx->CR2, SPI_CR2_TXDMAEN) == (SPI_CR2_TXDMAEN));
+}
+
+/**
+ * @brief Get the data register address used for DMA transfer
+ * @rmtoll DR DR LL_SPI_DMA_GetRegAddr
+ * @param SPIx SPI Instance
+ * @retval Address of data register
+ */
+__STATIC_INLINE uint32_t LL_SPI_DMA_GetRegAddr(SPI_TypeDef *SPIx)
+{
+ return (uint32_t) & (SPIx->DR);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SPI_LL_EF_DATA_Management DATA Management
+ * @{
+ */
+
+/**
+ * @brief Read 8-Bits in the data register
+ * @rmtoll DR DR LL_SPI_ReceiveData8
+ * @param SPIx SPI Instance
+ * @retval RxData Value between Min_Data=0x00 and Max_Data=0xFF
+ */
+__STATIC_INLINE uint8_t LL_SPI_ReceiveData8(SPI_TypeDef *SPIx)
+{
+ return (uint8_t)(READ_REG(SPIx->DR));
+}
+
+/**
+ * @brief Read 16-Bits in the data register
+ * @rmtoll DR DR LL_SPI_ReceiveData16
+ * @param SPIx SPI Instance
+ * @retval RxData Value between Min_Data=0x00 and Max_Data=0xFFFF
+ */
+__STATIC_INLINE uint16_t LL_SPI_ReceiveData16(SPI_TypeDef *SPIx)
+{
+ return (uint16_t)(READ_REG(SPIx->DR));
+}
+
+/**
+ * @brief Write 8-Bits in the data register
+ * @rmtoll DR DR LL_SPI_TransmitData8
+ * @param SPIx SPI Instance
+ * @param TxData Value between Min_Data=0x00 and Max_Data=0xFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_TransmitData8(SPI_TypeDef *SPIx, uint8_t TxData)
+{
+ SPIx->DR = TxData;
+}
+
+/**
+ * @brief Write 16-Bits in the data register
+ * @rmtoll DR DR LL_SPI_TransmitData16
+ * @param SPIx SPI Instance
+ * @param TxData Value between Min_Data=0x00 and Max_Data=0xFFFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_SPI_TransmitData16(SPI_TypeDef *SPIx, uint16_t TxData)
+{
+ SPIx->DR = TxData;
+}
+
+/**
+ * @}
+ */
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup SPI_LL_EF_Init Initialization and de-initialization functions
+ * @{
+ */
+
+ErrorStatus LL_SPI_DeInit(SPI_TypeDef *SPIx);
+ErrorStatus LL_SPI_Init(SPI_TypeDef *SPIx, LL_SPI_InitTypeDef *SPI_InitStruct);
+void LL_SPI_StructInit(LL_SPI_InitTypeDef *SPI_InitStruct);
+
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#if defined(SPI_I2S_SUPPORT)
+/** @defgroup I2S_LL I2S
+ * @{
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+
+/* Exported types ------------------------------------------------------------*/
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup I2S_LL_ES_INIT I2S Exported Init structure
+ * @{
+ */
+
+/**
+ * @brief I2S Init structure definition
+ */
+
+typedef struct
+{
+ uint32_t Mode; /*!< Specifies the I2S operating mode.
+ This parameter can be a value of @ref I2S_LL_EC_MODE
+
+ This feature can be modified afterwards using unitary function @ref LL_I2S_SetTransferMode().*/
+
+ uint32_t Standard; /*!< Specifies the standard used for the I2S communication.
+ This parameter can be a value of @ref I2S_LL_EC_STANDARD
+
+ This feature can be modified afterwards using unitary function @ref LL_I2S_SetStandard().*/
+
+
+ uint32_t DataFormat; /*!< Specifies the data format for the I2S communication.
+ This parameter can be a value of @ref I2S_LL_EC_DATA_FORMAT
+
+ This feature can be modified afterwards using unitary function @ref LL_I2S_SetDataFormat().*/
+
+
+ uint32_t MCLKOutput; /*!< Specifies whether the I2S MCLK output is enabled or not.
+ This parameter can be a value of @ref I2S_LL_EC_MCLK_OUTPUT
+
+ This feature can be modified afterwards using unitary functions @ref LL_I2S_EnableMasterClock() or @ref LL_I2S_DisableMasterClock.*/
+
+
+ uint32_t AudioFreq; /*!< Specifies the frequency selected for the I2S communication.
+ This parameter can be a value of @ref I2S_LL_EC_AUDIO_FREQ
+
+ Audio Frequency can be modified afterwards using Reference manual formulas to calculate Prescaler Linear, Parity
+ and unitary functions @ref LL_I2S_SetPrescalerLinear() and @ref LL_I2S_SetPrescalerParity() to set it.*/
+
+
+ uint32_t ClockPolarity; /*!< Specifies the idle state of the I2S clock.
+ This parameter can be a value of @ref I2S_LL_EC_POLARITY
+
+ This feature can be modified afterwards using unitary function @ref LL_I2S_SetClockPolarity().*/
+
+} LL_I2S_InitTypeDef;
+
+/**
+ * @}
+ */
+#endif /*USE_FULL_LL_DRIVER*/
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup I2S_LL_Exported_Constants I2S Exported Constants
+ * @{
+ */
+
+/** @defgroup I2S_LL_EC_GET_FLAG Get Flags Defines
+ * @brief Flags defines which can be used with LL_I2S_ReadReg function
+ * @{
+ */
+#define LL_I2S_SR_RXNE LL_SPI_SR_RXNE /*!< Rx buffer not empty flag */
+#define LL_I2S_SR_TXE LL_SPI_SR_TXE /*!< Tx buffer empty flag */
+#define LL_I2S_SR_BSY LL_SPI_SR_BSY /*!< Busy flag */
+#define LL_I2S_SR_UDR SPI_SR_UDR /*!< Underrun flag */
+#define LL_I2S_SR_OVR LL_SPI_SR_OVR /*!< Overrun flag */
+#define LL_I2S_SR_FRE LL_SPI_SR_FRE /*!< TI mode frame format error flag */
+/**
+ * @}
+ */
+
+/** @defgroup SPI_LL_EC_IT IT Defines
+ * @brief IT defines which can be used with LL_SPI_ReadReg and LL_SPI_WriteReg functions
+ * @{
+ */
+#define LL_I2S_CR2_RXNEIE LL_SPI_CR2_RXNEIE /*!< Rx buffer not empty interrupt enable */
+#define LL_I2S_CR2_TXEIE LL_SPI_CR2_TXEIE /*!< Tx buffer empty interrupt enable */
+#define LL_I2S_CR2_ERRIE LL_SPI_CR2_ERRIE /*!< Error interrupt enable */
+/**
+ * @}
+ */
+
+/** @defgroup I2S_LL_EC_DATA_FORMAT Data format
+ * @{
+ */
+#define LL_I2S_DATAFORMAT_16B 0x00000000U /*!< Data length 16 bits, Channel lenght 16bit */
+#define LL_I2S_DATAFORMAT_16B_EXTENDED (SPI_I2SCFGR_CHLEN) /*!< Data length 16 bits, Channel lenght 32bit */
+#define LL_I2S_DATAFORMAT_24B (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN_0) /*!< Data length 24 bits, Channel lenght 32bit */
+#define LL_I2S_DATAFORMAT_32B (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN_1) /*!< Data length 16 bits, Channel lenght 32bit */
+/**
+ * @}
+ */
+
+/** @defgroup I2S_LL_EC_POLARITY Clock Polarity
+ * @{
+ */
+#define LL_I2S_POLARITY_LOW 0x00000000U /*!< Clock steady state is low level */
+#define LL_I2S_POLARITY_HIGH (SPI_I2SCFGR_CKPOL) /*!< Clock steady state is high level */
+/**
+ * @}
+ */
+
+/** @defgroup I2S_LL_EC_STANDARD I2s Standard
+ * @{
+ */
+#define LL_I2S_STANDARD_PHILIPS 0x00000000U /*!< I2S standard philips */
+#define LL_I2S_STANDARD_MSB (SPI_I2SCFGR_I2SSTD_0) /*!< MSB justified standard (left justified) */
+#define LL_I2S_STANDARD_LSB (SPI_I2SCFGR_I2SSTD_1) /*!< LSB justified standard (right justified) */
+#define LL_I2S_STANDARD_PCM_SHORT (SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1) /*!< PCM standard, short frame synchronization */
+#define LL_I2S_STANDARD_PCM_LONG (SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1 | SPI_I2SCFGR_PCMSYNC) /*!< PCM standard, long frame synchronization */
+/**
+ * @}
+ */
+
+/** @defgroup I2S_LL_EC_MODE Operation Mode
+ * @{
+ */
+#define LL_I2S_MODE_SLAVE_TX 0x00000000U /*!< Slave Tx configuration */
+#define LL_I2S_MODE_SLAVE_RX (SPI_I2SCFGR_I2SCFG_0) /*!< Slave Rx configuration */
+#define LL_I2S_MODE_MASTER_TX (SPI_I2SCFGR_I2SCFG_1) /*!< Master Tx configuration */
+#define LL_I2S_MODE_MASTER_RX (SPI_I2SCFGR_I2SCFG_0 | SPI_I2SCFGR_I2SCFG_1) /*!< Master Rx configuration */
+/**
+ * @}
+ */
+
+/** @defgroup I2S_LL_EC_PRESCALER_FACTOR Prescaler Factor
+ * @{
+ */
+#define LL_I2S_PRESCALER_PARITY_EVEN 0x00000000U /*!< Odd factor: Real divider value is = I2SDIV * 2 */
+#define LL_I2S_PRESCALER_PARITY_ODD (SPI_I2SPR_ODD >> 8U) /*!< Odd factor: Real divider value is = (I2SDIV * 2)+1 */
+/**
+ * @}
+ */
+
+#if defined(USE_FULL_LL_DRIVER)
+
+/** @defgroup I2S_LL_EC_MCLK_OUTPUT MCLK Output
+ * @{
+ */
+#define LL_I2S_MCLK_OUTPUT_DISABLE 0x00000000U /*!< Master clock output is disabled */
+#define LL_I2S_MCLK_OUTPUT_ENABLE (SPI_I2SPR_MCKOE) /*!< Master clock output is enabled */
+/**
+ * @}
+ */
+
+/** @defgroup I2S_LL_EC_AUDIO_FREQ Audio Frequency
+ * @{
+ */
+
+#define LL_I2S_AUDIOFREQ_192K 192000U /*!< Audio Frequency configuration 192000 Hz */
+#define LL_I2S_AUDIOFREQ_96K 96000U /*!< Audio Frequency configuration 96000 Hz */
+#define LL_I2S_AUDIOFREQ_48K 48000U /*!< Audio Frequency configuration 48000 Hz */
+#define LL_I2S_AUDIOFREQ_44K 44100U /*!< Audio Frequency configuration 44100 Hz */
+#define LL_I2S_AUDIOFREQ_32K 32000U /*!< Audio Frequency configuration 32000 Hz */
+#define LL_I2S_AUDIOFREQ_22K 22050U /*!< Audio Frequency configuration 22050 Hz */
+#define LL_I2S_AUDIOFREQ_16K 16000U /*!< Audio Frequency configuration 16000 Hz */
+#define LL_I2S_AUDIOFREQ_11K 11025U /*!< Audio Frequency configuration 11025 Hz */
+#define LL_I2S_AUDIOFREQ_8K 8000U /*!< Audio Frequency configuration 8000 Hz */
+#define LL_I2S_AUDIOFREQ_DEFAULT 2U /*!< Audio Freq not specified. Register I2SDIV = 2 */
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup I2S_LL_Exported_Macros I2S Exported Macros
+ * @{
+ */
+
+/** @defgroup I2S_LL_EM_WRITE_READ Common Write and read registers Macros
+ * @{
+ */
+
+/**
+ * @brief Write a value in I2S register
+ * @param __INSTANCE__ I2S Instance
+ * @param __REG__ Register to be written
+ * @param __VALUE__ Value to be written in the register
+ * @retval None
+ */
+#define LL_I2S_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
+
+/**
+ * @brief Read a value in I2S register
+ * @param __INSTANCE__ I2S Instance
+ * @param __REG__ Register to be read
+ * @retval Register value
+ */
+#define LL_I2S_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup I2S_LL_Exported_Functions I2S Exported Functions
+ * @{
+ */
+
+/** @defgroup I2S_LL_EF_Configuration Configuration
+ * @{
+ */
+
+/**
+ * @brief Select I2S mode and Enable I2S peripheral
+ * @rmtoll I2SCFGR I2SMOD LL_I2S_Enable\n
+ * I2SCFGR I2SE LL_I2S_Enable
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_Enable(SPI_TypeDef *SPIx)
+{
+ SET_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SE);
+}
+
+/**
+ * @brief Disable I2S peripheral
+ * @rmtoll I2SCFGR I2SE LL_I2S_Disable
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_Disable(SPI_TypeDef *SPIx)
+{
+ CLEAR_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SE);
+}
+
+/**
+ * @brief Check if I2S peripheral is enabled
+ * @rmtoll I2SCFGR I2SE LL_I2S_IsEnabled
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2S_IsEnabled(SPI_TypeDef *SPIx)
+{
+ return (READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SE) == (SPI_I2SCFGR_I2SE));
+}
+
+/**
+ * @brief Set I2S data frame length
+ * @rmtoll I2SCFGR DATLEN LL_I2S_SetDataFormat\n
+ * I2SCFGR CHLEN LL_I2S_SetDataFormat
+ * @param SPIx SPI Instance
+ * @param DataFormat This parameter can be one of the following values:
+ * @arg @ref LL_I2S_DATAFORMAT_16B
+ * @arg @ref LL_I2S_DATAFORMAT_16B_EXTENDED
+ * @arg @ref LL_I2S_DATAFORMAT_24B
+ * @arg @ref LL_I2S_DATAFORMAT_32B
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_SetDataFormat(SPI_TypeDef *SPIx, uint32_t DataFormat)
+{
+ MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN, DataFormat);
+}
+
+/**
+ * @brief Get I2S data frame length
+ * @rmtoll I2SCFGR DATLEN LL_I2S_GetDataFormat\n
+ * I2SCFGR CHLEN LL_I2S_GetDataFormat
+ * @param SPIx SPI Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_I2S_DATAFORMAT_16B
+ * @arg @ref LL_I2S_DATAFORMAT_16B_EXTENDED
+ * @arg @ref LL_I2S_DATAFORMAT_24B
+ * @arg @ref LL_I2S_DATAFORMAT_32B
+ */
+__STATIC_INLINE uint32_t LL_I2S_GetDataFormat(SPI_TypeDef *SPIx)
+{
+ return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN));
+}
+
+/**
+ * @brief Set I2S clock polarity
+ * @rmtoll I2SCFGR CKPOL LL_I2S_SetClockPolarity
+ * @param SPIx SPI Instance
+ * @param ClockPolarity This parameter can be one of the following values:
+ * @arg @ref LL_I2S_POLARITY_LOW
+ * @arg @ref LL_I2S_POLARITY_HIGH
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_SetClockPolarity(SPI_TypeDef *SPIx, uint32_t ClockPolarity)
+{
+ SET_BIT(SPIx->I2SCFGR, ClockPolarity);
+}
+
+/**
+ * @brief Get I2S clock polarity
+ * @rmtoll I2SCFGR CKPOL LL_I2S_GetClockPolarity
+ * @param SPIx SPI Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_I2S_POLARITY_LOW
+ * @arg @ref LL_I2S_POLARITY_HIGH
+ */
+__STATIC_INLINE uint32_t LL_I2S_GetClockPolarity(SPI_TypeDef *SPIx)
+{
+ return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_CKPOL));
+}
+
+/**
+ * @brief Set I2S standard protocol
+ * @rmtoll I2SCFGR I2SSTD LL_I2S_SetStandard\n
+ * I2SCFGR PCMSYNC LL_I2S_SetStandard
+ * @param SPIx SPI Instance
+ * @param Standard This parameter can be one of the following values:
+ * @arg @ref LL_I2S_STANDARD_PHILIPS
+ * @arg @ref LL_I2S_STANDARD_MSB
+ * @arg @ref LL_I2S_STANDARD_LSB
+ * @arg @ref LL_I2S_STANDARD_PCM_SHORT
+ * @arg @ref LL_I2S_STANDARD_PCM_LONG
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_SetStandard(SPI_TypeDef *SPIx, uint32_t Standard)
+{
+ MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC, Standard);
+}
+
+/**
+ * @brief Get I2S standard protocol
+ * @rmtoll I2SCFGR I2SSTD LL_I2S_GetStandard\n
+ * I2SCFGR PCMSYNC LL_I2S_GetStandard
+ * @param SPIx SPI Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_I2S_STANDARD_PHILIPS
+ * @arg @ref LL_I2S_STANDARD_MSB
+ * @arg @ref LL_I2S_STANDARD_LSB
+ * @arg @ref LL_I2S_STANDARD_PCM_SHORT
+ * @arg @ref LL_I2S_STANDARD_PCM_LONG
+ */
+__STATIC_INLINE uint32_t LL_I2S_GetStandard(SPI_TypeDef *SPIx)
+{
+ return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC));
+}
+
+/**
+ * @brief Set I2S transfer mode
+ * @rmtoll I2SCFGR I2SCFG LL_I2S_SetTransferMode
+ * @param SPIx SPI Instance
+ * @param Mode This parameter can be one of the following values:
+ * @arg @ref LL_I2S_MODE_SLAVE_TX
+ * @arg @ref LL_I2S_MODE_SLAVE_RX
+ * @arg @ref LL_I2S_MODE_MASTER_TX
+ * @arg @ref LL_I2S_MODE_MASTER_RX
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_SetTransferMode(SPI_TypeDef *SPIx, uint32_t Mode)
+{
+ MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_I2SCFG, Mode);
+}
+
+/**
+ * @brief Get I2S transfer mode
+ * @rmtoll I2SCFGR I2SCFG LL_I2S_GetTransferMode
+ * @param SPIx SPI Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_I2S_MODE_SLAVE_TX
+ * @arg @ref LL_I2S_MODE_SLAVE_RX
+ * @arg @ref LL_I2S_MODE_MASTER_TX
+ * @arg @ref LL_I2S_MODE_MASTER_RX
+ */
+__STATIC_INLINE uint32_t LL_I2S_GetTransferMode(SPI_TypeDef *SPIx)
+{
+ return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SCFG));
+}
+
+/**
+ * @brief Set I2S linear prescaler
+ * @rmtoll I2SPR I2SDIV LL_I2S_SetPrescalerLinear
+ * @param SPIx SPI Instance
+ * @param PrescalerLinear Value between Min_Data=0x02 and Max_Data=0xFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_SetPrescalerLinear(SPI_TypeDef *SPIx, uint8_t PrescalerLinear)
+{
+ MODIFY_REG(SPIx->I2SPR, SPI_I2SPR_I2SDIV, PrescalerLinear);
+}
+
+/**
+ * @brief Get I2S linear prescaler
+ * @rmtoll I2SPR I2SDIV LL_I2S_GetPrescalerLinear
+ * @param SPIx SPI Instance
+ * @retval PrescalerLinear Value between Min_Data=0x02 and Max_Data=0xFF
+ */
+__STATIC_INLINE uint32_t LL_I2S_GetPrescalerLinear(SPI_TypeDef *SPIx)
+{
+ return (uint32_t)(READ_BIT(SPIx->I2SPR, SPI_I2SPR_I2SDIV));
+}
+
+/**
+ * @brief Set I2S parity prescaler
+ * @rmtoll I2SPR ODD LL_I2S_SetPrescalerParity
+ * @param SPIx SPI Instance
+ * @param PrescalerParity This parameter can be one of the following values:
+ * @arg @ref LL_I2S_PRESCALER_PARITY_EVEN
+ * @arg @ref LL_I2S_PRESCALER_PARITY_ODD
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_SetPrescalerParity(SPI_TypeDef *SPIx, uint32_t PrescalerParity)
+{
+ MODIFY_REG(SPIx->I2SPR, SPI_I2SPR_ODD, PrescalerParity << 8U);
+}
+
+/**
+ * @brief Get I2S parity prescaler
+ * @rmtoll I2SPR ODD LL_I2S_GetPrescalerParity
+ * @param SPIx SPI Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_I2S_PRESCALER_PARITY_EVEN
+ * @arg @ref LL_I2S_PRESCALER_PARITY_ODD
+ */
+__STATIC_INLINE uint32_t LL_I2S_GetPrescalerParity(SPI_TypeDef *SPIx)
+{
+ return (uint32_t)(READ_BIT(SPIx->I2SPR, SPI_I2SPR_ODD) >> 8U);
+}
+
+/**
+ * @brief Enable the master clock ouput (Pin MCK)
+ * @rmtoll I2SPR MCKOE LL_I2S_EnableMasterClock
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_EnableMasterClock(SPI_TypeDef *SPIx)
+{
+ SET_BIT(SPIx->I2SPR, SPI_I2SPR_MCKOE);
+}
+
+/**
+ * @brief Disable the master clock ouput (Pin MCK)
+ * @rmtoll I2SPR MCKOE LL_I2S_DisableMasterClock
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_DisableMasterClock(SPI_TypeDef *SPIx)
+{
+ CLEAR_BIT(SPIx->I2SPR, SPI_I2SPR_MCKOE);
+}
+
+/**
+ * @brief Check if the master clock ouput (Pin MCK) is enabled
+ * @rmtoll I2SPR MCKOE LL_I2S_IsEnabledMasterClock
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2S_IsEnabledMasterClock(SPI_TypeDef *SPIx)
+{
+ return (READ_BIT(SPIx->I2SPR, SPI_I2SPR_MCKOE) == (SPI_I2SPR_MCKOE));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2S_LL_EF_FLAG FLAG Management
+ * @{
+ */
+
+/**
+ * @brief Check if Rx buffer is not empty
+ * @rmtoll SR RXNE LL_I2S_IsActiveFlag_RXNE
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_RXNE(SPI_TypeDef *SPIx)
+{
+ return LL_SPI_IsActiveFlag_RXNE(SPIx);
+}
+
+/**
+ * @brief Check if Tx buffer is empty
+ * @rmtoll SR TXE LL_I2S_IsActiveFlag_TXE
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_TXE(SPI_TypeDef *SPIx)
+{
+ return LL_SPI_IsActiveFlag_TXE(SPIx);
+}
+
+/**
+ * @brief Get busy flag
+ * @rmtoll SR BSY LL_I2S_IsActiveFlag_BSY
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_BSY(SPI_TypeDef *SPIx)
+{
+ return LL_SPI_IsActiveFlag_BSY(SPIx);
+}
+
+/**
+ * @brief Get overrun error flag
+ * @rmtoll SR OVR LL_I2S_IsActiveFlag_OVR
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_OVR(SPI_TypeDef *SPIx)
+{
+ return LL_SPI_IsActiveFlag_OVR(SPIx);
+}
+
+/**
+ * @brief Get underrun error flag
+ * @rmtoll SR UDR LL_I2S_IsActiveFlag_UDR
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_UDR(SPI_TypeDef *SPIx)
+{
+ return (READ_BIT(SPIx->SR, SPI_SR_UDR) == (SPI_SR_UDR));
+}
+
+/**
+ * @brief Get channel side flag.
+ * @note 0: Channel Left has to be transmitted or has been received\n
+ * 1: Channel Right has to be transmitted or has been received\n
+ * It has no significance in PCM mode.
+ * @rmtoll SR CHSIDE LL_I2S_IsActiveFlag_CHSIDE
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_CHSIDE(SPI_TypeDef *SPIx)
+{
+ return (READ_BIT(SPIx->SR, SPI_SR_CHSIDE) == (SPI_SR_CHSIDE));
+}
+
+/**
+ * @brief Clear overrun error flag
+ * @rmtoll SR OVR LL_I2S_ClearFlag_OVR
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_ClearFlag_OVR(SPI_TypeDef *SPIx)
+{
+ LL_SPI_ClearFlag_OVR(SPIx);
+}
+
+/**
+ * @brief Clear underrun error flag
+ * @rmtoll SR UDR LL_I2S_ClearFlag_UDR
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_ClearFlag_UDR(SPI_TypeDef *SPIx)
+{
+ __IO uint32_t tmpreg;
+ tmpreg = SPIx->SR;
+ (void)tmpreg;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2S_LL_EF_IT Interrupt Management
+ * @{
+ */
+
+/**
+ * @brief Enable error IT
+ * @note This bit controls the generation of an interrupt when an error condition occurs (OVR, UDR and FRE in I2S mode).
+ * @rmtoll CR2 ERRIE LL_I2S_EnableIT_ERR
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_EnableIT_ERR(SPI_TypeDef *SPIx)
+{
+ LL_SPI_EnableIT_ERR(SPIx);
+}
+
+/**
+ * @brief Enable Rx buffer not empty IT
+ * @rmtoll CR2 RXNEIE LL_I2S_EnableIT_RXNE
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_EnableIT_RXNE(SPI_TypeDef *SPIx)
+{
+ LL_SPI_EnableIT_RXNE(SPIx);
+}
+
+/**
+ * @brief Enable Tx buffer empty IT
+ * @rmtoll CR2 TXEIE LL_I2S_EnableIT_TXE
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_EnableIT_TXE(SPI_TypeDef *SPIx)
+{
+ LL_SPI_EnableIT_TXE(SPIx);
+}
+
+/**
+ * @brief Disable error IT
+ * @note This bit controls the generation of an interrupt when an error condition occurs (OVR, UDR and FRE in I2S mode).
+ * @rmtoll CR2 ERRIE LL_I2S_DisableIT_ERR
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_DisableIT_ERR(SPI_TypeDef *SPIx)
+{
+ LL_SPI_DisableIT_ERR(SPIx);
+}
+
+/**
+ * @brief Disable Rx buffer not empty IT
+ * @rmtoll CR2 RXNEIE LL_I2S_DisableIT_RXNE
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_DisableIT_RXNE(SPI_TypeDef *SPIx)
+{
+ LL_SPI_DisableIT_RXNE(SPIx);
+}
+
+/**
+ * @brief Disable Tx buffer empty IT
+ * @rmtoll CR2 TXEIE LL_I2S_DisableIT_TXE
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_DisableIT_TXE(SPI_TypeDef *SPIx)
+{
+ LL_SPI_DisableIT_TXE(SPIx);
+}
+
+/**
+ * @brief Check if ERR IT is enabled
+ * @rmtoll CR2 ERRIE LL_I2S_IsEnabledIT_ERR
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_ERR(SPI_TypeDef *SPIx)
+{
+ return LL_SPI_IsEnabledIT_ERR(SPIx);
+}
+
+/**
+ * @brief Check if RXNE IT is enabled
+ * @rmtoll CR2 RXNEIE LL_I2S_IsEnabledIT_RXNE
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_RXNE(SPI_TypeDef *SPIx)
+{
+ return LL_SPI_IsEnabledIT_RXNE(SPIx);
+}
+
+/**
+ * @brief Check if TXE IT is enabled
+ * @rmtoll CR2 TXEIE LL_I2S_IsEnabledIT_TXE
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_TXE(SPI_TypeDef *SPIx)
+{
+ return LL_SPI_IsEnabledIT_TXE(SPIx);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2S_LL_EF_DMA DMA Management
+ * @{
+ */
+
+/**
+ * @brief Enable DMA Rx
+ * @rmtoll CR2 RXDMAEN LL_I2S_EnableDMAReq_RX
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_EnableDMAReq_RX(SPI_TypeDef *SPIx)
+{
+ LL_SPI_EnableDMAReq_RX(SPIx);
+}
+
+/**
+ * @brief Disable DMA Rx
+ * @rmtoll CR2 RXDMAEN LL_I2S_DisableDMAReq_RX
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_DisableDMAReq_RX(SPI_TypeDef *SPIx)
+{
+ LL_SPI_DisableDMAReq_RX(SPIx);
+}
+
+/**
+ * @brief Check if DMA Rx is enabled
+ * @rmtoll CR2 RXDMAEN LL_I2S_IsEnabledDMAReq_RX
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2S_IsEnabledDMAReq_RX(SPI_TypeDef *SPIx)
+{
+ return LL_SPI_IsEnabledDMAReq_RX(SPIx);
+}
+
+/**
+ * @brief Enable DMA Tx
+ * @rmtoll CR2 TXDMAEN LL_I2S_EnableDMAReq_TX
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_EnableDMAReq_TX(SPI_TypeDef *SPIx)
+{
+ LL_SPI_EnableDMAReq_TX(SPIx);
+}
+
+/**
+ * @brief Disable DMA Tx
+ * @rmtoll CR2 TXDMAEN LL_I2S_DisableDMAReq_TX
+ * @param SPIx SPI Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_DisableDMAReq_TX(SPI_TypeDef *SPIx)
+{
+ LL_SPI_DisableDMAReq_TX(SPIx);
+}
+
+/**
+ * @brief Check if DMA Tx is enabled
+ * @rmtoll CR2 TXDMAEN LL_I2S_IsEnabledDMAReq_TX
+ * @param SPIx SPI Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2S_IsEnabledDMAReq_TX(SPI_TypeDef *SPIx)
+{
+ return LL_SPI_IsEnabledDMAReq_TX(SPIx);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2S_LL_EF_DATA DATA Management
+ * @{
+ */
+
+/**
+ * @brief Read 16-Bits in data register
+ * @rmtoll DR DR LL_I2S_ReceiveData16
+ * @param SPIx SPI Instance
+ * @retval RxData Value between Min_Data=0x0000 and Max_Data=0xFFFF
+ */
+__STATIC_INLINE uint16_t LL_I2S_ReceiveData16(SPI_TypeDef *SPIx)
+{
+ return LL_SPI_ReceiveData16(SPIx);
+}
+
+/**
+ * @brief Write 16-Bits in data register
+ * @rmtoll DR DR LL_I2S_TransmitData16
+ * @param SPIx SPI Instance
+ * @param TxData Value between Min_Data=0x0000 and Max_Data=0xFFFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2S_TransmitData16(SPI_TypeDef *SPIx, uint16_t TxData)
+{
+ LL_SPI_TransmitData16(SPIx, TxData);
+}
+
+/**
+ * @}
+ */
+
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup I2S_LL_EF_Init Initialization and de-initialization functions
+ * @{
+ */
+
+ErrorStatus LL_I2S_DeInit(SPI_TypeDef *SPIx);
+ErrorStatus LL_I2S_Init(SPI_TypeDef *SPIx, LL_I2S_InitTypeDef *I2S_InitStruct);
+void LL_I2S_StructInit(LL_I2S_InitTypeDef *I2S_InitStruct);
+void LL_I2S_ConfigPrescaler(SPI_TypeDef *SPIx, uint32_t PrescalerLinear, uint32_t PrescalerParity);
+
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* SPI_I2S_SUPPORT */
+
+#endif /* defined (SPI1) || defined (SPI2) || defined (SPI3) */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_LL_SPI_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_system.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_system.h
new file mode 100644
index 0000000..d7583f1
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_system.h
@@ -0,0 +1,590 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_system.h
+ * @author MCD Application Team
+ * @brief Header file of SYSTEM LL module.
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The LL SYSTEM driver contains a set of generic APIs that can be
+ used by user:
+ (+) Some of the FLASH features need to be handled in the SYSTEM file.
+ (+) Access to DBGCMU registers
+ (+) Access to SYSCFG registers
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_SYSTEM_H
+#define __STM32F1xx_LL_SYSTEM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx.h"
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (FLASH) || defined (DBGMCU)
+
+/** @defgroup SYSTEM_LL SYSTEM
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup SYSTEM_LL_Private_Constants SYSTEM Private Constants
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup SYSTEM_LL_Exported_Constants SYSTEM Exported Constants
+ * @{
+ */
+
+
+
+/** @defgroup SYSTEM_LL_EC_TRACE DBGMCU TRACE Pin Assignment
+ * @{
+ */
+#define LL_DBGMCU_TRACE_NONE 0x00000000U /*!< TRACE pins not assigned (default state) */
+#define LL_DBGMCU_TRACE_ASYNCH DBGMCU_CR_TRACE_IOEN /*!< TRACE pin assignment for Asynchronous Mode */
+#define LL_DBGMCU_TRACE_SYNCH_SIZE1 (DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE_0) /*!< TRACE pin assignment for Synchronous Mode with a TRACEDATA size of 1 */
+#define LL_DBGMCU_TRACE_SYNCH_SIZE2 (DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE_1) /*!< TRACE pin assignment for Synchronous Mode with a TRACEDATA size of 2 */
+#define LL_DBGMCU_TRACE_SYNCH_SIZE4 (DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE) /*!< TRACE pin assignment for Synchronous Mode with a TRACEDATA size of 4 */
+/**
+ * @}
+ */
+
+/** @defgroup SYSTEM_LL_EC_APB1_GRP1_STOP_IP DBGMCU APB1 GRP1 STOP IP
+ * @{
+ */
+#define LL_DBGMCU_APB1_GRP1_TIM2_STOP DBGMCU_CR_DBG_TIM2_STOP /*!< TIM2 counter stopped when core is halted */
+#define LL_DBGMCU_APB1_GRP1_TIM3_STOP DBGMCU_CR_DBG_TIM3_STOP /*!< TIM3 counter stopped when core is halted */
+#define LL_DBGMCU_APB1_GRP1_TIM4_STOP DBGMCU_CR_DBG_TIM4_STOP /*!< TIM4 counter stopped when core is halted */
+#if defined(DBGMCU_CR_DBG_TIM5_STOP)
+#define LL_DBGMCU_APB1_GRP1_TIM5_STOP DBGMCU_CR_DBG_TIM5_STOP /*!< TIM5 counter stopped when core is halted */
+#endif /* DBGMCU_CR_DBG_TIM5_STOP */
+#if defined(DBGMCU_CR_DBG_TIM6_STOP)
+#define LL_DBGMCU_APB1_GRP1_TIM6_STOP DBGMCU_CR_DBG_TIM6_STOP /*!< TIM6 counter stopped when core is halted */
+#endif /* DBGMCU_CR_DBG_TIM6_STOP */
+#if defined(DBGMCU_CR_DBG_TIM7_STOP)
+#define LL_DBGMCU_APB1_GRP1_TIM7_STOP DBGMCU_CR_DBG_TIM7_STOP /*!< TIM7 counter stopped when core is halted */
+#endif /* DBGMCU_CR_DBG_TIM7_STOP */
+#if defined(DBGMCU_CR_DBG_TIM12_STOP)
+#define LL_DBGMCU_APB1_GRP1_TIM12_STOP DBGMCU_CR_DBG_TIM12_STOP /*!< TIM12 counter stopped when core is halted */
+#endif /* DBGMCU_CR_DBG_TIM12_STOP */
+#if defined(DBGMCU_CR_DBG_TIM13_STOP)
+#define LL_DBGMCU_APB1_GRP1_TIM13_STOP DBGMCU_CR_DBG_TIM13_STOP /*!< TIM13 counter stopped when core is halted */
+#endif /* DBGMCU_CR_DBG_TIM13_STOP */
+#if defined(DBGMCU_CR_DBG_TIM14_STOP)
+#define LL_DBGMCU_APB1_GRP1_TIM14_STOP DBGMCU_CR_DBG_TIM14_STOP /*!< TIM14 counter stopped when core is halted */
+#endif /* DBGMCU_CR_DBG_TIM14_STOP */
+#define LL_DBGMCU_APB1_GRP1_WWDG_STOP DBGMCU_CR_DBG_WWDG_STOP /*!< Debug Window Watchdog stopped when Core is halted */
+#define LL_DBGMCU_APB1_GRP1_IWDG_STOP DBGMCU_CR_DBG_IWDG_STOP /*!< Debug Independent Watchdog stopped when Core is halted */
+#define LL_DBGMCU_APB1_GRP1_I2C1_STOP DBGMCU_CR_DBG_I2C1_SMBUS_TIMEOUT /*!< I2C1 SMBUS timeout mode stopped when Core is halted */
+#if defined(DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT)
+#define LL_DBGMCU_APB1_GRP1_I2C2_STOP DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT /*!< I2C2 SMBUS timeout mode stopped when Core is halted */
+#endif /* DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT */
+#if defined(DBGMCU_CR_DBG_CAN1_STOP)
+#define LL_DBGMCU_APB1_GRP1_CAN1_STOP DBGMCU_CR_DBG_CAN1_STOP /*!< CAN1 debug stopped when Core is halted */
+#endif /* DBGMCU_CR_DBG_CAN1_STOP */
+#if defined(DBGMCU_CR_DBG_CAN2_STOP)
+#define LL_DBGMCU_APB1_GRP1_CAN2_STOP DBGMCU_CR_DBG_CAN2_STOP /*!< CAN2 debug stopped when Core is halted */
+#endif /* DBGMCU_CR_DBG_CAN2_STOP */
+/**
+ * @}
+ */
+
+/** @defgroup SYSTEM_LL_EC_APB2_GRP1_STOP_IP DBGMCU APB2 GRP1 STOP IP
+ * @{
+ */
+#define LL_DBGMCU_APB2_GRP1_TIM1_STOP DBGMCU_CR_DBG_TIM1_STOP /*!< TIM1 counter stopped when core is halted */
+#if defined(DBGMCU_CR_DBG_TIM8_STOP)
+#define LL_DBGMCU_APB2_GRP1_TIM8_STOP DBGMCU_CR_DBG_TIM8_STOP /*!< TIM8 counter stopped when core is halted */
+#endif /* DBGMCU_CR_DBG_CAN1_STOP */
+#if defined(DBGMCU_CR_DBG_TIM9_STOP)
+#define LL_DBGMCU_APB2_GRP1_TIM9_STOP DBGMCU_CR_DBG_TIM9_STOP /*!< TIM9 counter stopped when core is halted */
+#endif /* DBGMCU_CR_DBG_TIM9_STOP */
+#if defined(DBGMCU_CR_DBG_TIM10_STOP)
+#define LL_DBGMCU_APB2_GRP1_TIM10_STOP DBGMCU_CR_DBG_TIM10_STOP /*!< TIM10 counter stopped when core is halted */
+#endif /* DBGMCU_CR_DBG_TIM10_STOP */
+#if defined(DBGMCU_CR_DBG_TIM11_STOP)
+#define LL_DBGMCU_APB2_GRP1_TIM11_STOP DBGMCU_CR_DBG_TIM11_STOP /*!< TIM11 counter stopped when core is halted */
+#endif /* DBGMCU_CR_DBG_TIM11_STOP */
+#if defined(DBGMCU_CR_DBG_TIM15_STOP)
+#define LL_DBGMCU_APB2_GRP1_TIM15_STOP DBGMCU_CR_DBG_TIM15_STOP /*!< TIM15 counter stopped when core is halted */
+#endif /* DBGMCU_CR_DBG_TIM15_STOP */
+#if defined(DBGMCU_CR_DBG_TIM16_STOP)
+#define LL_DBGMCU_APB2_GRP1_TIM16_STOP DBGMCU_CR_DBG_TIM16_STOP /*!< TIM16 counter stopped when core is halted */
+#endif /* DBGMCU_CR_DBG_TIM16_STOP */
+#if defined(DBGMCU_CR_DBG_TIM17_STOP)
+#define LL_DBGMCU_APB2_GRP1_TIM17_STOP DBGMCU_CR_DBG_TIM17_STOP /*!< TIM17 counter stopped when core is halted */
+#endif /* DBGMCU_CR_DBG_TIM17_STOP */
+/**
+ * @}
+ */
+
+/** @defgroup SYSTEM_LL_EC_LATENCY FLASH LATENCY
+ * @{
+ */
+#if defined(FLASH_ACR_LATENCY)
+#define LL_FLASH_LATENCY_0 0x00000000U /*!< FLASH Zero Latency cycle */
+#define LL_FLASH_LATENCY_1 FLASH_ACR_LATENCY_0 /*!< FLASH One Latency cycle */
+#define LL_FLASH_LATENCY_2 FLASH_ACR_LATENCY_1 /*!< FLASH Two wait states */
+#else
+#endif /* FLASH_ACR_LATENCY */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup SYSTEM_LL_Exported_Functions SYSTEM Exported Functions
+ * @{
+ */
+
+
+
+/** @defgroup SYSTEM_LL_EF_DBGMCU DBGMCU
+ * @{
+ */
+
+/**
+ * @brief Return the device identifier
+ * @note For Low Density devices, the device ID is 0x412
+ * @note For Medium Density devices, the device ID is 0x410
+ * @note For High Density devices, the device ID is 0x414
+ * @note For XL Density devices, the device ID is 0x430
+ * @note For Connectivity Line devices, the device ID is 0x418
+ * @rmtoll DBGMCU_IDCODE DEV_ID LL_DBGMCU_GetDeviceID
+ * @retval Values between Min_Data=0x00 and Max_Data=0xFFF
+ */
+__STATIC_INLINE uint32_t LL_DBGMCU_GetDeviceID(void)
+{
+ return (uint32_t)(READ_BIT(DBGMCU->IDCODE, DBGMCU_IDCODE_DEV_ID));
+}
+
+/**
+ * @brief Return the device revision identifier
+ * @note This field indicates the revision of the device.
+ For example, it is read as revA -> 0x1000,for Low Density devices
+ For example, it is read as revA -> 0x0000, revB -> 0x2000, revZ -> 0x2001, rev1,2,3,X or Y -> 0x2003,for Medium Density devices
+ For example, it is read as revA or 1 -> 0x1000, revZ -> 0x1001,rev1,2,3,X or Y -> 0x1003,for Medium Density devices
+ For example, it is read as revA or 1 -> 0x1003,for XL Density devices
+ For example, it is read as revA -> 0x1000, revZ -> 0x1001 for Connectivity line devices
+ * @rmtoll DBGMCU_IDCODE REV_ID LL_DBGMCU_GetRevisionID
+ * @retval Values between Min_Data=0x00 and Max_Data=0xFFFF
+ */
+__STATIC_INLINE uint32_t LL_DBGMCU_GetRevisionID(void)
+{
+ return (uint32_t)(READ_BIT(DBGMCU->IDCODE, DBGMCU_IDCODE_REV_ID) >> DBGMCU_IDCODE_REV_ID_Pos);
+}
+
+/**
+ * @brief Enable the Debug Module during SLEEP mode
+ * @rmtoll DBGMCU_CR DBG_SLEEP LL_DBGMCU_EnableDBGSleepMode
+ * @retval None
+ */
+__STATIC_INLINE void LL_DBGMCU_EnableDBGSleepMode(void)
+{
+ SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
+}
+
+/**
+ * @brief Disable the Debug Module during SLEEP mode
+ * @rmtoll DBGMCU_CR DBG_SLEEP LL_DBGMCU_DisableDBGSleepMode
+ * @retval None
+ */
+__STATIC_INLINE void LL_DBGMCU_DisableDBGSleepMode(void)
+{
+ CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
+}
+
+/**
+ * @brief Enable the Debug Module during STOP mode
+ * @rmtoll DBGMCU_CR DBG_STOP LL_DBGMCU_EnableDBGStopMode
+ * @retval None
+ */
+__STATIC_INLINE void LL_DBGMCU_EnableDBGStopMode(void)
+{
+ SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
+}
+
+/**
+ * @brief Disable the Debug Module during STOP mode
+ * @rmtoll DBGMCU_CR DBG_STOP LL_DBGMCU_DisableDBGStopMode
+ * @retval None
+ */
+__STATIC_INLINE void LL_DBGMCU_DisableDBGStopMode(void)
+{
+ CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
+}
+
+/**
+ * @brief Enable the Debug Module during STANDBY mode
+ * @rmtoll DBGMCU_CR DBG_STANDBY LL_DBGMCU_EnableDBGStandbyMode
+ * @retval None
+ */
+__STATIC_INLINE void LL_DBGMCU_EnableDBGStandbyMode(void)
+{
+ SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
+}
+
+/**
+ * @brief Disable the Debug Module during STANDBY mode
+ * @rmtoll DBGMCU_CR DBG_STANDBY LL_DBGMCU_DisableDBGStandbyMode
+ * @retval None
+ */
+__STATIC_INLINE void LL_DBGMCU_DisableDBGStandbyMode(void)
+{
+ CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
+}
+
+/**
+ * @brief Set Trace pin assignment control
+ * @rmtoll DBGMCU_CR TRACE_IOEN LL_DBGMCU_SetTracePinAssignment\n
+ * DBGMCU_CR TRACE_MODE LL_DBGMCU_SetTracePinAssignment
+ * @param PinAssignment This parameter can be one of the following values:
+ * @arg @ref LL_DBGMCU_TRACE_NONE
+ * @arg @ref LL_DBGMCU_TRACE_ASYNCH
+ * @arg @ref LL_DBGMCU_TRACE_SYNCH_SIZE1
+ * @arg @ref LL_DBGMCU_TRACE_SYNCH_SIZE2
+ * @arg @ref LL_DBGMCU_TRACE_SYNCH_SIZE4
+ * @retval None
+ */
+__STATIC_INLINE void LL_DBGMCU_SetTracePinAssignment(uint32_t PinAssignment)
+{
+ MODIFY_REG(DBGMCU->CR, DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE, PinAssignment);
+}
+
+/**
+ * @brief Get Trace pin assignment control
+ * @rmtoll DBGMCU_CR TRACE_IOEN LL_DBGMCU_GetTracePinAssignment\n
+ * DBGMCU_CR TRACE_MODE LL_DBGMCU_GetTracePinAssignment
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_DBGMCU_TRACE_NONE
+ * @arg @ref LL_DBGMCU_TRACE_ASYNCH
+ * @arg @ref LL_DBGMCU_TRACE_SYNCH_SIZE1
+ * @arg @ref LL_DBGMCU_TRACE_SYNCH_SIZE2
+ * @arg @ref LL_DBGMCU_TRACE_SYNCH_SIZE4
+ */
+__STATIC_INLINE uint32_t LL_DBGMCU_GetTracePinAssignment(void)
+{
+ return (uint32_t)(READ_BIT(DBGMCU->CR, DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE));
+}
+
+/**
+ * @brief Freeze APB1 peripherals (group1 peripherals)
+ * @rmtoll DBGMCU_CR_APB1 DBG_TIM2_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_TIM3_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_TIM4_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_TIM5_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_TIM6_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_TIM7_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_TIM12_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_TIM13_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_TIM14_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_RTC_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_WWDG_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_IWDG_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_I2C1_SMBUS_TIMEOUT LL_DBGMCU_APB1_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_I2C2_SMBUS_TIMEOUT LL_DBGMCU_APB1_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_CAN1_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_CAN2_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_DBGMCU_APB1_GRP1_TIM2_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_TIM3_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_TIM4_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_TIM5_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_TIM6_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_TIM7_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_TIM12_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_TIM13_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_TIM14_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_WWDG_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_IWDG_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_I2C1_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_I2C2_STOP (*)
+ * @arg @ref LL_DBGMCU_APB1_GRP1_CAN1_STOP (*)
+ * @arg @ref LL_DBGMCU_APB1_GRP1_CAN2_STOP (*)
+ *
+ * (*) value not defined in all devices.
+ * @retval None
+ */
+__STATIC_INLINE void LL_DBGMCU_APB1_GRP1_FreezePeriph(uint32_t Periphs)
+{
+ SET_BIT(DBGMCU->CR, Periphs);
+}
+
+/**
+ * @brief Unfreeze APB1 peripherals (group1 peripherals)
+ * @rmtoll DBGMCU_CR_APB1 DBG_TIM2_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_TIM3_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_TIM4_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_TIM5_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_TIM6_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_TIM7_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_TIM12_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_TIM13_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_TIM14_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_RTC_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_WWDG_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_IWDG_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_I2C1_SMBUS_TIMEOUT LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_I2C2_SMBUS_TIMEOUT LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_CAN1_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n
+ * DBGMCU_CR_APB1 DBG_CAN2_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_DBGMCU_APB1_GRP1_TIM2_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_TIM3_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_TIM4_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_TIM5_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_TIM6_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_TIM7_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_TIM12_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_TIM13_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_TIM14_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_RTC_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_WWDG_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_IWDG_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_I2C1_STOP
+ * @arg @ref LL_DBGMCU_APB1_GRP1_I2C2_STOP (*)
+ * @arg @ref LL_DBGMCU_APB1_GRP1_CAN1_STOP (*)
+ * @arg @ref LL_DBGMCU_APB1_GRP1_CAN2_STOP (*)
+ *
+ * (*) value not defined in all devices.
+ * @retval None
+ */
+__STATIC_INLINE void LL_DBGMCU_APB1_GRP1_UnFreezePeriph(uint32_t Periphs)
+{
+ CLEAR_BIT(DBGMCU->CR, Periphs);
+}
+
+/**
+ * @brief Freeze APB2 peripherals
+ * @rmtoll DBGMCU_CR_APB2 DBG_TIM1_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB2 DBG_TIM8_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB2 DBG_TIM9_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB2 DBG_TIM10_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB2 DBG_TIM11_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB2 DBG_TIM15_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB2 DBG_TIM16_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB2 DBG_TIM17_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_DBGMCU_APB2_GRP1_TIM1_STOP
+ * @arg @ref LL_DBGMCU_APB2_GRP1_TIM8_STOP (*)
+ * @arg @ref LL_DBGMCU_APB2_GRP1_TIM9_STOP (*)
+ * @arg @ref LL_DBGMCU_APB2_GRP1_TIM10_STOP (*)
+ * @arg @ref LL_DBGMCU_APB2_GRP1_TIM11_STOP (*)
+ * @arg @ref LL_DBGMCU_APB2_GRP1_TIM15_STOP (*)
+ * @arg @ref LL_DBGMCU_APB2_GRP1_TIM16_STOP (*)
+ * @arg @ref LL_DBGMCU_APB2_GRP1_TIM17_STOP (*)
+ *
+ * (*) value not defined in all devices.
+ * @retval None
+ */
+__STATIC_INLINE void LL_DBGMCU_APB2_GRP1_FreezePeriph(uint32_t Periphs)
+{
+ SET_BIT(DBGMCU->CR, Periphs);
+}
+
+/**
+ * @brief Unfreeze APB2 peripherals
+ * @rmtoll DBGMCU_CR_APB2 DBG_TIM1_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB2 DBG_TIM8_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB2 DBG_TIM9_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB2 DBG_TIM10_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB2 DBG_TIM11_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB2 DBG_TIM15_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB2 DBG_TIM16_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph\n
+ * DBGMCU_CR_APB2 DBG_TIM17_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph
+ * @param Periphs This parameter can be a combination of the following values:
+ * @arg @ref LL_DBGMCU_APB2_GRP1_TIM1_STOP
+ * @arg @ref LL_DBGMCU_APB2_GRP1_TIM8_STOP (*)
+ * @arg @ref LL_DBGMCU_APB2_GRP1_TIM9_STOP (*)
+ * @arg @ref LL_DBGMCU_APB2_GRP1_TIM10_STOP (*)
+ * @arg @ref LL_DBGMCU_APB2_GRP1_TIM11_STOP (*)
+ * @arg @ref LL_DBGMCU_APB2_GRP1_TIM15_STOP (*)
+ * @arg @ref LL_DBGMCU_APB2_GRP1_TIM16_STOP (*)
+ * @arg @ref LL_DBGMCU_APB2_GRP1_TIM17_STOP (*)
+ *
+ * (*) value not defined in all devices.
+ * @retval None
+ */
+__STATIC_INLINE void LL_DBGMCU_APB2_GRP1_UnFreezePeriph(uint32_t Periphs)
+{
+ CLEAR_BIT(DBGMCU->CR, Periphs);
+}
+/**
+ * @}
+ */
+
+#if defined(FLASH_ACR_LATENCY)
+/** @defgroup SYSTEM_LL_EF_FLASH FLASH
+ * @{
+ */
+
+/**
+ * @brief Set FLASH Latency
+ * @rmtoll FLASH_ACR LATENCY LL_FLASH_SetLatency
+ * @param Latency This parameter can be one of the following values:
+ * @arg @ref LL_FLASH_LATENCY_0
+ * @arg @ref LL_FLASH_LATENCY_1
+ * @arg @ref LL_FLASH_LATENCY_2
+ * @retval None
+ */
+__STATIC_INLINE void LL_FLASH_SetLatency(uint32_t Latency)
+{
+ MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, Latency);
+}
+
+/**
+ * @brief Get FLASH Latency
+ * @rmtoll FLASH_ACR LATENCY LL_FLASH_GetLatency
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_FLASH_LATENCY_0
+ * @arg @ref LL_FLASH_LATENCY_1
+ * @arg @ref LL_FLASH_LATENCY_2
+ */
+__STATIC_INLINE uint32_t LL_FLASH_GetLatency(void)
+{
+ return (uint32_t)(READ_BIT(FLASH->ACR, FLASH_ACR_LATENCY));
+}
+
+/**
+ * @brief Enable Prefetch
+ * @rmtoll FLASH_ACR PRFTBE LL_FLASH_EnablePrefetch
+ * @retval None
+ */
+__STATIC_INLINE void LL_FLASH_EnablePrefetch(void)
+{
+ SET_BIT(FLASH->ACR, FLASH_ACR_PRFTBE);
+}
+
+/**
+ * @brief Disable Prefetch
+ * @rmtoll FLASH_ACR PRFTBE LL_FLASH_DisablePrefetch
+ * @retval None
+ */
+__STATIC_INLINE void LL_FLASH_DisablePrefetch(void)
+{
+ CLEAR_BIT(FLASH->ACR, FLASH_ACR_PRFTBE);
+}
+
+/**
+ * @brief Check if Prefetch buffer is enabled
+ * @rmtoll FLASH_ACR PRFTBS LL_FLASH_IsPrefetchEnabled
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_FLASH_IsPrefetchEnabled(void)
+{
+ return (READ_BIT(FLASH->ACR, FLASH_ACR_PRFTBS) == (FLASH_ACR_PRFTBS));
+}
+
+#endif /* FLASH_ACR_LATENCY */
+/**
+ * @brief Enable Flash Half Cycle Access
+ * @rmtoll FLASH_ACR HLFCYA LL_FLASH_EnableHalfCycleAccess
+ * @retval None
+ */
+__STATIC_INLINE void LL_FLASH_EnableHalfCycleAccess(void)
+{
+ SET_BIT(FLASH->ACR, FLASH_ACR_HLFCYA);
+}
+
+/**
+ * @brief Disable Flash Half Cycle Access
+ * @rmtoll FLASH_ACR HLFCYA LL_FLASH_DisableHalfCycleAccess
+ * @retval None
+ */
+__STATIC_INLINE void LL_FLASH_DisableHalfCycleAccess(void)
+{
+ CLEAR_BIT(FLASH->ACR, FLASH_ACR_HLFCYA);
+}
+
+/**
+ * @brief Check if Flash Half Cycle Access is enabled or not
+ * @rmtoll FLASH_ACR HLFCYA LL_FLASH_IsHalfCycleAccessEnabled
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_FLASH_IsHalfCycleAccessEnabled(void)
+{
+ return (READ_BIT(FLASH->ACR, FLASH_ACR_HLFCYA) == (FLASH_ACR_HLFCYA));
+}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* defined (FLASH) || defined (DBGMCU) */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_LL_SYSTEM_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_tim.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_tim.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_tim.h
rename to templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_tim.h
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usart.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usart.h
similarity index 100%
rename from assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usart.h
rename to templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usart.h
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usb.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usb.h
new file mode 100644
index 0000000..f551663
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usb.h
@@ -0,0 +1,614 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_usb.h
+ * @author MCD Application Team
+ * @brief Header file of USB Low Layer HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_USB_H
+#define __STM32F1xx_LL_USB_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#if defined(STM32F102x6) || defined(STM32F102xB) || \
+ defined(STM32F103x6) || defined(STM32F103xB) || \
+ defined(STM32F103xE) || defined(STM32F103xG) || \
+ defined(STM32F105xC) || defined(STM32F107xC)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup USB_LL
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup USB_LL_Exported_Types USB Low Layer Exported Types
+ * @{
+ */
+/**
+ * @brief USB Mode definition
+ */
+typedef enum
+{
+ USB_DEVICE_MODE = 0,
+ USB_HOST_MODE = 1,
+ USB_DRD_MODE = 2
+}USB_ModeTypeDef;
+
+#if defined (USB_OTG_FS)
+/**
+ * @brief URB States definition
+ */
+typedef enum {
+ URB_IDLE = 0,
+ URB_DONE,
+ URB_NOTREADY,
+ URB_NYET,
+ URB_ERROR,
+ URB_STALL
+}USB_OTG_URBStateTypeDef;
+
+/**
+ * @brief Host channel States definition
+ */
+typedef enum {
+ HC_IDLE = 0,
+ HC_XFRC,
+ HC_HALTED,
+ HC_NAK,
+ HC_NYET,
+ HC_STALL,
+ HC_XACTERR,
+ HC_BBLERR,
+ HC_DATATGLERR
+}USB_OTG_HCStateTypeDef;
+
+/**
+ * @brief USB OTG Initialization Structure definition
+ */
+typedef struct
+{
+ uint32_t dev_endpoints; /*!< Device Endpoints number.
+ This parameter depends on the used USB core.
+ This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
+
+ uint32_t Host_channels; /*!< Host Channels number.
+ This parameter Depends on the used USB core.
+ This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
+
+ uint32_t speed; /*!< USB Core speed.
+ This parameter can be any value of @ref USB_Core_Speed_ */
+
+ uint32_t ep0_mps; /*!< Set the Endpoint 0 Max Packet size.
+ This parameter can be any value of @ref USB_EP0_MPS_ */
+
+ uint32_t Sof_enable; /*!< Enable or disable the output of the SOF signal. */
+
+ uint32_t low_power_enable; /*!< Enable or disable the low power mode. */
+
+ uint32_t vbus_sensing_enable; /*!< Enable or disable the VBUS Sensing feature. */
+
+ uint32_t use_external_vbus; /*!< Enable or disable the use of the external VBUS. */
+}USB_OTG_CfgTypeDef;
+
+typedef struct
+{
+ uint8_t num; /*!< Endpoint number
+ This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
+
+ uint8_t is_in; /*!< Endpoint direction
+ This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
+
+ uint8_t is_stall; /*!< Endpoint stall condition
+ This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
+
+ uint8_t type; /*!< Endpoint type
+ This parameter can be any value of @ref USB_EP_Type_ */
+
+ uint8_t data_pid_start; /*!< Initial data PID
+ This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
+
+ uint8_t even_odd_frame; /*!< IFrame parity
+ This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
+
+ uint16_t tx_fifo_num; /*!< Transmission FIFO number
+ This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
+
+ uint32_t maxpacket; /*!< Endpoint Max packet size
+ This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
+
+ uint8_t *xfer_buff; /*!< Pointer to transfer buffer */
+
+ uint32_t dma_addr; /*!< 32 bits aligned transfer buffer address */
+
+ uint32_t xfer_len; /*!< Current transfer length */
+
+ uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer */
+}USB_OTG_EPTypeDef;
+
+typedef struct
+{
+ uint8_t dev_addr ; /*!< USB device address.
+ This parameter must be a number between Min_Data = 1 and Max_Data = 255 */
+
+ uint8_t ch_num; /*!< Host channel number.
+ This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
+
+ uint8_t ep_num; /*!< Endpoint number.
+ This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
+
+ uint8_t ep_is_in; /*!< Endpoint direction
+ This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
+
+ uint8_t speed; /*!< USB Host speed.
+ This parameter can be any value of @ref USB_Core_Speed_ */
+
+ uint8_t do_ping; /*!< Enable or disable the use of the PING protocol for HS mode. */
+
+ uint8_t process_ping; /*!< Execute the PING protocol for HS mode. */
+
+ uint8_t ep_type; /*!< Endpoint Type.
+ This parameter can be any value of @ref USB_EP_Type_ */
+
+ uint16_t max_packet; /*!< Endpoint Max packet size.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
+
+ uint8_t data_pid; /*!< Initial data PID.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
+
+ uint8_t *xfer_buff; /*!< Pointer to transfer buffer. */
+
+ uint32_t xfer_len; /*!< Current transfer length. */
+
+ uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer. */
+
+ uint8_t toggle_in; /*!< IN transfer current toggle flag.
+ This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
+
+ uint8_t toggle_out; /*!< OUT transfer current toggle flag
+ This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
+
+ uint32_t dma_addr; /*!< 32 bits aligned transfer buffer address. */
+
+ uint32_t ErrCnt; /*!< Host channel error count.*/
+
+ USB_OTG_URBStateTypeDef urb_state; /*!< URB state.
+ This parameter can be any value of @ref USB_OTG_URBStateTypeDef */
+
+ USB_OTG_HCStateTypeDef state; /*!< Host Channel state.
+ This parameter can be any value of @ref USB_OTG_HCStateTypeDef */
+}USB_OTG_HCTypeDef;
+#endif /* USB_OTG_FS */
+
+#if defined (USB)
+/**
+ * @brief USB Initialization Structure definition
+ */
+typedef struct
+{
+ uint32_t dev_endpoints; /*!< Device Endpoints number.
+ This parameter depends on the used USB core.
+ This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
+
+ uint32_t speed; /*!< USB Core speed.
+ This parameter can be any value of @ref USB_Core_Speed */
+
+ uint32_t ep0_mps; /*!< Set the Endpoint 0 Max Packet size.
+ This parameter can be any value of @ref USB_EP0_MPS */
+
+ uint32_t phy_itface; /*!< Select the used PHY interface.
+ This parameter can be any value of @ref USB_Core_PHY */
+
+ uint32_t Sof_enable; /*!< Enable or disable the output of the SOF signal. */
+
+ uint32_t low_power_enable; /*!< Enable or disable Low Power mode */
+
+ uint32_t lpm_enable; /*!< Enable or disable Battery charging. */
+
+ uint32_t battery_charging_enable; /*!< Enable or disable Battery charging. */
+} USB_CfgTypeDef;
+
+typedef struct
+{
+ uint8_t num; /*!< Endpoint number
+ This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
+
+ uint8_t is_in; /*!< Endpoint direction
+ This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
+
+ uint8_t is_stall; /*!< Endpoint stall condition
+ This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
+
+ uint8_t type; /*!< Endpoint type
+ This parameter can be any value of @ref USB_EP_Type */
+
+ uint16_t pmaadress; /*!< PMA Address
+ This parameter can be any value between Min_addr = 0 and Max_addr = 1K */
+
+ uint16_t pmaaddr0; /*!< PMA Address0
+ This parameter can be any value between Min_addr = 0 and Max_addr = 1K */
+
+ uint16_t pmaaddr1; /*!< PMA Address1
+ This parameter can be any value between Min_addr = 0 and Max_addr = 1K */
+
+ uint8_t doublebuffer; /*!< Double buffer enable
+ This parameter can be 0 or 1 */
+
+ uint16_t tx_fifo_num; /*!< This parameter is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral
+ This parameter is added to ensure compatibility across USB peripherals */
+
+ uint32_t maxpacket; /*!< Endpoint Max packet size
+ This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
+
+ uint8_t *xfer_buff; /*!< Pointer to transfer buffer */
+
+ uint32_t xfer_len; /*!< Current transfer length */
+
+ uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer */
+
+} USB_EPTypeDef;
+#endif /* USB */
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup USB_LL_Exported_Constants USB Low Layer Exported Constants
+ * @{
+ */
+#if defined (USB_OTG_FS)
+/** @defgroup USB_LL_Core_Mode USB Low Layer Core Mode
+ * @{
+ */
+#define USB_OTG_MODE_DEVICE 0
+#define USB_OTG_MODE_HOST 1
+#define USB_OTG_MODE_DRD 2
+/**
+ * @}
+ */
+
+/** @defgroup USB_LL_Core_Speed USB Low Layer Core Speed
+ * @{
+ */
+#define USB_OTG_SPEED_LOW 2
+#define USB_OTG_SPEED_FULL 3
+
+/**
+ * @}
+ */
+
+/** @defgroup USB_LL_Core_PHY USB Low Layer Core PHY
+ * @{
+ */
+#define USB_OTG_ULPI_PHY 1
+#define USB_OTG_EMBEDDED_PHY 2
+/**
+ * @}
+ */
+
+/** @defgroup USB_LL_Core_MPS USB Low Layer Core MPS
+ * @{
+ */
+#define USB_OTG_FS_MAX_PACKET_SIZE 64
+#define USB_OTG_MAX_EP0_SIZE 64
+/**
+ * @}
+ */
+
+/** @defgroup USB_LL_Core_PHY_Frequency USB Low Layer Core PHY Frequency
+ * @{
+ */
+#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ (1 << 1)
+#define DSTS_ENUMSPD_LS_PHY_6MHZ (2 << 1)
+#define DSTS_ENUMSPD_FS_PHY_48MHZ (3 << 1)
+/**
+ * @}
+ */
+
+/** @defgroup USB_LL_CORE_Frame_Interval USB Low Layer Core Frame Interval
+ * @{
+ */
+#define DCFG_FRAME_INTERVAL_80 0
+#define DCFG_FRAME_INTERVAL_85 1
+#define DCFG_FRAME_INTERVAL_90 2
+#define DCFG_FRAME_INTERVAL_95 3
+/**
+ * @}
+ */
+
+/** @defgroup USB_LL_EP0_MPS USB Low Layer EP0 MPS
+ * @{
+ */
+#define DEP0CTL_MPS_64 0
+#define DEP0CTL_MPS_32 1
+#define DEP0CTL_MPS_16 2
+#define DEP0CTL_MPS_8 3
+/**
+ * @}
+ */
+
+/** @defgroup USB_LL_EP_Speed USB Low Layer EP Speed
+ * @{
+ */
+#define EP_SPEED_LOW 0
+#define EP_SPEED_FULL 1
+#define EP_SPEED_HIGH 2
+/**
+ * @}
+ */
+
+/** @defgroup USB_LL_EP_Type USB Low Layer EP Type
+ * @{
+ */
+#define EP_TYPE_CTRL 0
+#define EP_TYPE_ISOC 1
+#define EP_TYPE_BULK 2
+#define EP_TYPE_INTR 3
+#define EP_TYPE_MSK 3
+/**
+ * @}
+ */
+
+/** @defgroup USB_LL_STS_Defines USB Low Layer STS Defines
+ * @{
+ */
+#define STS_GOUT_NAK 1
+#define STS_DATA_UPDT 2
+#define STS_XFER_COMP 3
+#define STS_SETUP_COMP 4
+#define STS_SETUP_UPDT 6
+/**
+ * @}
+ */
+
+/** @defgroup USB_LL_HCFG_SPEED_Defines USB Low Layer HCFG Speed Defines
+ * @{
+ */
+#define HCFG_30_60_MHZ 0
+#define HCFG_48_MHZ 1
+#define HCFG_6_MHZ 2
+/**
+ * @}
+ */
+
+/** @defgroup USB_LL_HPRT0_PRTSPD_SPEED_Defines USB Low Layer HPRT0 PRTSPD Speed Defines
+ * @{
+ */
+#define HPRT0_PRTSPD_HIGH_SPEED 0
+#define HPRT0_PRTSPD_FULL_SPEED 1
+#define HPRT0_PRTSPD_LOW_SPEED 2
+/**
+ * @}
+ */
+
+#define HCCHAR_CTRL 0
+#define HCCHAR_ISOC 1
+#define HCCHAR_BULK 2
+#define HCCHAR_INTR 3
+
+#define HC_PID_DATA0 0
+#define HC_PID_DATA2 1
+#define HC_PID_DATA1 2
+#define HC_PID_SETUP 3
+
+#define GRXSTS_PKTSTS_IN 2
+#define GRXSTS_PKTSTS_IN_XFER_COMP 3
+#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5
+#define GRXSTS_PKTSTS_CH_HALTED 7
+
+#define USBx_PCGCCTL *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_PCGCCTL_BASE)
+#define USBx_HPRT0 *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_HOST_PORT_BASE)
+
+#define USBx_DEVICE ((USB_OTG_DeviceTypeDef *)((uint32_t )USBx + USB_OTG_DEVICE_BASE))
+#define USBx_INEP(i) ((USB_OTG_INEndpointTypeDef *)((uint32_t)USBx + USB_OTG_IN_ENDPOINT_BASE + (i)*USB_OTG_EP_REG_SIZE))
+#define USBx_OUTEP(i) ((USB_OTG_OUTEndpointTypeDef *)((uint32_t)USBx + USB_OTG_OUT_ENDPOINT_BASE + (i)*USB_OTG_EP_REG_SIZE))
+#define USBx_DFIFO(i) *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_FIFO_BASE + (i) * USB_OTG_FIFO_SIZE)
+
+#define USBx_HOST ((USB_OTG_HostTypeDef *)((uint32_t )USBx + USB_OTG_HOST_BASE))
+#define USBx_HC(i) ((USB_OTG_HostChannelTypeDef *)((uint32_t)USBx + USB_OTG_HOST_CHANNEL_BASE + (i)*USB_OTG_HOST_CHANNEL_SIZE))
+#endif /* USB_OTG_FS */
+
+#if defined (USB)
+/** @defgroup USB_LL_EP0_MPS USB Low Layer EP0 MPS
+ * @{
+ */
+#define DEP0CTL_MPS_64 0
+#define DEP0CTL_MPS_32 1
+#define DEP0CTL_MPS_16 2
+#define DEP0CTL_MPS_8 3
+/**
+ * @}
+ */
+
+/** @defgroup USB_LL_EP_Type USB Low Layer EP Type
+ * @{
+ */
+#define EP_TYPE_CTRL 0
+#define EP_TYPE_ISOC 1
+#define EP_TYPE_BULK 2
+#define EP_TYPE_INTR 3
+#define EP_TYPE_MSK 3
+/**
+ * @}
+ */
+
+#define BTABLE_ADDRESS (0x000)
+#endif /* USB */
+/**
+ * @}
+ */
+
+/* Exported macros -----------------------------------------------------------*/
+/** @defgroup USB_LL_Exported_Macros USB Low Layer Exported Macros
+ * @{
+ */
+#if defined (USB_OTG_FS)
+#define USB_MASK_INTERRUPT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->GINTMSK &= ~(__INTERRUPT__))
+#define USB_UNMASK_INTERRUPT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->GINTMSK |= (__INTERRUPT__))
+
+#define CLEAR_IN_EP_INTR(__EPNUM__, __INTERRUPT__) (USBx_INEP(__EPNUM__)->DIEPINT = (__INTERRUPT__))
+#define CLEAR_OUT_EP_INTR(__EPNUM__, __INTERRUPT__) (USBx_OUTEP(__EPNUM__)->DOEPINT = (__INTERRUPT__))
+#endif /* USB_OTG_FS */
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup USB_LL_Exported_Functions USB Low Layer Exported Functions
+ * @{
+ */
+/** @addtogroup USB_LL_Exported_Functions_Group1 Peripheral Control functions
+ * @{
+ */
+#if defined (USB_OTG_FS)
+HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef Init);
+HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef Init);
+HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx);
+HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx);
+HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx , USB_ModeTypeDef mode);
+HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx , uint8_t speed);
+HAL_StatusTypeDef USB_FlushRxFifo (USB_OTG_GlobalTypeDef *USBx);
+HAL_StatusTypeDef USB_FlushTxFifo (USB_OTG_GlobalTypeDef *USBx, uint32_t num );
+HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
+HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
+HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep);
+HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep);
+HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len);
+void * USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len);
+HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep);
+HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep);
+HAL_StatusTypeDef USB_SetDevAddress (USB_OTG_GlobalTypeDef *USBx, uint8_t address);
+HAL_StatusTypeDef USB_DevConnect (USB_OTG_GlobalTypeDef *USBx);
+HAL_StatusTypeDef USB_DevDisconnect (USB_OTG_GlobalTypeDef *USBx);
+HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx);
+HAL_StatusTypeDef USB_ActivateSetup (USB_OTG_GlobalTypeDef *USBx);
+HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t *psetup);
+uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx);
+uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx);
+uint32_t USB_ReadInterrupts (USB_OTG_GlobalTypeDef *USBx);
+uint32_t USB_ReadDevAllOutEpInterrupt (USB_OTG_GlobalTypeDef *USBx);
+uint32_t USB_ReadDevOutEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum);
+uint32_t USB_ReadDevAllInEpInterrupt (USB_OTG_GlobalTypeDef *USBx);
+uint32_t USB_ReadDevInEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum);
+void USB_ClearInterrupts (USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt);
+
+HAL_StatusTypeDef USB_HostInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg);
+HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx , uint8_t freq);
+HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx);
+HAL_StatusTypeDef USB_DriveVbus (USB_OTG_GlobalTypeDef *USBx, uint8_t state);
+uint32_t USB_GetHostSpeed (USB_OTG_GlobalTypeDef *USBx);
+uint32_t USB_GetCurrentFrame (USB_OTG_GlobalTypeDef *USBx);
+HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx,
+ uint8_t ch_num,
+ uint8_t epnum,
+ uint8_t dev_address,
+ uint8_t speed,
+ uint8_t ep_type,
+ uint16_t mps);
+HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc);
+uint32_t USB_HC_ReadInterrupt (USB_OTG_GlobalTypeDef *USBx);
+HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx , uint8_t hc_num);
+HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx , uint8_t ch_num);
+HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx);
+HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx);
+HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx);
+#endif /* USB_OTG_FS */
+
+#if defined (USB)
+HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef Init);
+HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef Init);
+HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx);
+HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx);
+HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx , USB_ModeTypeDef mode);
+HAL_StatusTypeDef USB_SetDevSpeed(USB_TypeDef *USBx , uint8_t speed);
+HAL_StatusTypeDef USB_FlushRxFifo (USB_TypeDef *USBx);
+HAL_StatusTypeDef USB_FlushTxFifo (USB_TypeDef *USBx, uint32_t num );
+HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep);
+HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep);
+HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx , USB_EPTypeDef *ep);
+HAL_StatusTypeDef USB_WritePacket(USB_TypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len);
+void * USB_ReadPacket(USB_TypeDef *USBx, uint8_t *dest, uint16_t len);
+HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx , USB_EPTypeDef *ep);
+HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx , USB_EPTypeDef *ep);
+HAL_StatusTypeDef USB_SetDevAddress (USB_TypeDef *USBx, uint8_t address);
+HAL_StatusTypeDef USB_DevConnect (USB_TypeDef *USBx);
+HAL_StatusTypeDef USB_DevDisconnect (USB_TypeDef *USBx);
+HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx);
+HAL_StatusTypeDef USB_EP0_OutStart(USB_TypeDef *USBx, uint8_t *psetup);
+uint32_t USB_ReadInterrupts (USB_TypeDef *USBx);
+uint32_t USB_ReadDevAllOutEpInterrupt (USB_TypeDef *USBx);
+uint32_t USB_ReadDevOutEPInterrupt (USB_TypeDef *USBx , uint8_t epnum);
+uint32_t USB_ReadDevAllInEpInterrupt (USB_TypeDef *USBx);
+uint32_t USB_ReadDevInEPInterrupt (USB_TypeDef *USBx , uint8_t epnum);
+void USB_ClearInterrupts (USB_TypeDef *USBx, uint32_t interrupt);
+
+HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx);
+HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx);
+void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes);
+void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes);
+#endif /* USB */
+/**
+ * @}
+ */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F102x6 || STM32F102xB || */
+ /* STM32F103x6 || STM32F103xB || */
+ /* STM32F103xE || STM32F103xG || */
+ /* STM32F105xC || STM32F107xC */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __STM32F1xx_LL_USB_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_utils.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_utils.h
new file mode 100644
index 0000000..0a040b7
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_utils.h
@@ -0,0 +1,282 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_utils.h
+ * @author MCD Application Team
+ * @brief Header file of UTILS LL module.
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The LL UTILS driver contains a set of generic APIs that can be
+ used by user:
+ (+) Device electronic signature
+ (+) Timing functions
+ (+) PLL configuration functions
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_UTILS_H
+#define __STM32F1xx_LL_UTILS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx.h"
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+/** @defgroup UTILS_LL UTILS
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup UTILS_LL_Private_Constants UTILS Private Constants
+ * @{
+ */
+
+/* Max delay can be used in LL_mDelay */
+#define LL_MAX_DELAY 0xFFFFFFFFU
+
+/**
+ * @brief Unique device ID register base address
+ */
+#define UID_BASE_ADDRESS UID_BASE
+
+/**
+ * @brief Flash size data register base address
+ */
+#define FLASHSIZE_BASE_ADDRESS FLASHSIZE_BASE
+
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup UTILS_LL_Private_Macros UTILS Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup UTILS_LL_ES_INIT UTILS Exported structures
+ * @{
+ */
+/**
+ * @brief UTILS PLL structure definition
+ */
+typedef struct
+{
+ uint32_t PLLMul; /*!< Multiplication factor for PLL VCO input clock.
+ This parameter can be a value of @ref RCC_LL_EC_PLL_MUL
+
+ This feature can be modified afterwards using unitary function
+ @ref LL_RCC_PLL_ConfigDomain_SYS(). */
+
+ uint32_t Prediv; /*!< Division factor for HSE used as PLL clock source.
+ This parameter can be a value of @ref RCC_LL_EC_PREDIV_DIV
+
+ This feature can be modified afterwards using unitary function
+ @ref LL_RCC_PLL_ConfigDomain_SYS(). */
+} LL_UTILS_PLLInitTypeDef;
+
+/**
+ * @brief UTILS System, AHB and APB buses clock configuration structure definition
+ */
+typedef struct
+{
+ uint32_t AHBCLKDivider; /*!< The AHB clock (HCLK) divider. This clock is derived from the system clock (SYSCLK).
+ This parameter can be a value of @ref RCC_LL_EC_SYSCLK_DIV
+
+ This feature can be modified afterwards using unitary function
+ @ref LL_RCC_SetAHBPrescaler(). */
+
+ uint32_t APB1CLKDivider; /*!< The APB1 clock (PCLK1) divider. This clock is derived from the AHB clock (HCLK).
+ This parameter can be a value of @ref RCC_LL_EC_APB1_DIV
+
+ This feature can be modified afterwards using unitary function
+ @ref LL_RCC_SetAPB1Prescaler(). */
+
+ uint32_t APB2CLKDivider; /*!< The APB2 clock (PCLK2) divider. This clock is derived from the AHB clock (HCLK).
+ This parameter can be a value of @ref RCC_LL_EC_APB2_DIV
+
+ This feature can be modified afterwards using unitary function
+ @ref LL_RCC_SetAPB2Prescaler(). */
+
+} LL_UTILS_ClkInitTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup UTILS_LL_Exported_Constants UTILS Exported Constants
+ * @{
+ */
+
+/** @defgroup UTILS_EC_HSE_BYPASS HSE Bypass activation
+ * @{
+ */
+#define LL_UTILS_HSEBYPASS_OFF 0x00000000U /*!< HSE Bypass is not enabled */
+#define LL_UTILS_HSEBYPASS_ON 0x00000001U /*!< HSE Bypass is enabled */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup UTILS_LL_Exported_Functions UTILS Exported Functions
+ * @{
+ */
+
+/** @defgroup UTILS_EF_DEVICE_ELECTRONIC_SIGNATURE DEVICE ELECTRONIC SIGNATURE
+ * @{
+ */
+
+/**
+ * @brief Get Word0 of the unique device identifier (UID based on 96 bits)
+ * @retval UID[31:0]
+ */
+__STATIC_INLINE uint32_t LL_GetUID_Word0(void)
+{
+ return (uint32_t)(READ_REG(*((uint32_t *)UID_BASE_ADDRESS)));
+}
+
+/**
+ * @brief Get Word1 of the unique device identifier (UID based on 96 bits)
+ * @retval UID[63:32]
+ */
+__STATIC_INLINE uint32_t LL_GetUID_Word1(void)
+{
+ return (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE_ADDRESS + 4U))));
+}
+
+/**
+ * @brief Get Word2 of the unique device identifier (UID based on 96 bits)
+ * @retval UID[95:64]
+ */
+__STATIC_INLINE uint32_t LL_GetUID_Word2(void)
+{
+ return (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE_ADDRESS + 8U))));
+}
+
+/**
+ * @brief Get Flash memory size
+ * @note This bitfield indicates the size of the device Flash memory expressed in
+ * Kbytes. As an example, 0x040 corresponds to 64 Kbytes.
+ * @retval FLASH_SIZE[15:0]: Flash memory size
+ */
+__STATIC_INLINE uint32_t LL_GetFlashSize(void)
+{
+ return (uint16_t)(READ_REG(*((uint32_t *)FLASHSIZE_BASE_ADDRESS)));
+}
+
+
+/**
+ * @}
+ */
+
+/** @defgroup UTILS_LL_EF_DELAY DELAY
+ * @{
+ */
+
+/**
+ * @brief This function configures the Cortex-M SysTick source of the time base.
+ * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
+ * @note When a RTOS is used, it is recommended to avoid changing the SysTick
+ * configuration by calling this function, for a delay use rather osDelay RTOS service.
+ * @param Ticks Number of ticks
+ * @retval None
+ */
+__STATIC_INLINE void LL_InitTick(uint32_t HCLKFrequency, uint32_t Ticks)
+{
+ /* Configure the SysTick to have interrupt in 1ms time base */
+ SysTick->LOAD = (uint32_t)((HCLKFrequency / Ticks) - 1UL); /* set reload register */
+ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable the Systick Timer */
+}
+
+void LL_Init1msTick(uint32_t HCLKFrequency);
+void LL_mDelay(uint32_t Delay);
+
+/**
+ * @}
+ */
+
+/** @defgroup UTILS_EF_SYSTEM SYSTEM
+ * @{
+ */
+
+void LL_SetSystemCoreClock(uint32_t HCLKFrequency);
+ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
+ LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
+ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
+ LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_LL_UTILS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_wwdg.h b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_wwdg.h
new file mode 100644
index 0000000..70f06ac
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_wwdg.h
@@ -0,0 +1,340 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_wwdg.h
+ * @author MCD Application Team
+ * @brief Header file of WWDG LL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_WWDG_H
+#define __STM32F1xx_LL_WWDG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx.h"
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (WWDG)
+
+/** @defgroup WWDG_LL WWDG
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/* Private constants ---------------------------------------------------------*/
+
+/* Private macros ------------------------------------------------------------*/
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup WWDG_LL_Exported_Constants WWDG Exported Constants
+ * @{
+ */
+
+
+/** @defgroup WWDG_LL_EC_IT IT Defines
+ * @brief IT defines which can be used with LL_WWDG_ReadReg and LL_WWDG_WriteReg functions
+ * @{
+ */
+#define LL_WWDG_CFR_EWI WWDG_CFR_EWI
+/**
+ * @}
+ */
+
+/** @defgroup WWDG_LL_EC_PRESCALER PRESCALER
+* @{
+*/
+#define LL_WWDG_PRESCALER_1 0x00000000U /*!< WWDG counter clock = (PCLK1/4096)/1 */
+#define LL_WWDG_PRESCALER_2 WWDG_CFR_WDGTB_0 /*!< WWDG counter clock = (PCLK1/4096)/2 */
+#define LL_WWDG_PRESCALER_4 WWDG_CFR_WDGTB_1 /*!< WWDG counter clock = (PCLK1/4096)/4 */
+#define LL_WWDG_PRESCALER_8 (WWDG_CFR_WDGTB_0 | WWDG_CFR_WDGTB_1) /*!< WWDG counter clock = (PCLK1/4096)/8 */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup WWDG_LL_Exported_Macros WWDG Exported Macros
+ * @{
+ */
+/** @defgroup WWDG_LL_EM_WRITE_READ Common Write and read registers macros
+ * @{
+ */
+/**
+ * @brief Write a value in WWDG register
+ * @param __INSTANCE__ WWDG Instance
+ * @param __REG__ Register to be written
+ * @param __VALUE__ Value to be written in the register
+ * @retval None
+ */
+#define LL_WWDG_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
+
+/**
+ * @brief Read a value in WWDG register
+ * @param __INSTANCE__ WWDG Instance
+ * @param __REG__ Register to be read
+ * @retval Register value
+ */
+#define LL_WWDG_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup WWDG_LL_Exported_Functions WWDG Exported Functions
+ * @{
+ */
+
+/** @defgroup WWDG_LL_EF_Configuration Configuration
+ * @{
+ */
+/**
+ * @brief Enable Window Watchdog. The watchdog is always disabled after a reset.
+ * @note It is enabled by setting the WDGA bit in the WWDG_CR register,
+ * then it cannot be disabled again except by a reset.
+ * This bit is set by software and only cleared by hardware after a reset.
+ * When WDGA = 1, the watchdog can generate a reset.
+ * @rmtoll CR WDGA LL_WWDG_Enable
+ * @param WWDGx WWDG Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_WWDG_Enable(WWDG_TypeDef *WWDGx)
+{
+ SET_BIT(WWDGx->CR, WWDG_CR_WDGA);
+}
+
+/**
+ * @brief Checks if Window Watchdog is enabled
+ * @rmtoll CR WDGA LL_WWDG_IsEnabled
+ * @param WWDGx WWDG Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_WWDG_IsEnabled(WWDG_TypeDef *WWDGx)
+{
+ return (READ_BIT(WWDGx->CR, WWDG_CR_WDGA) == (WWDG_CR_WDGA));
+}
+
+/**
+ * @brief Set the Watchdog counter value to provided value (7-bits T[6:0])
+ * @note When writing to the WWDG_CR register, always write 1 in the MSB b6 to avoid generating an immediate reset
+ * This counter is decremented every (4096 x 2expWDGTB) PCLK cycles
+ * A reset is produced when it rolls over from 0x40 to 0x3F (bit T6 becomes cleared)
+ * Setting the counter lower then 0x40 causes an immediate reset (if WWDG enabled)
+ * @rmtoll CR T LL_WWDG_SetCounter
+ * @param WWDGx WWDG Instance
+ * @param Counter 0..0x7F (7 bit counter value)
+ * @retval None
+ */
+__STATIC_INLINE void LL_WWDG_SetCounter(WWDG_TypeDef *WWDGx, uint32_t Counter)
+{
+ MODIFY_REG(WWDGx->CR, WWDG_CR_T, Counter);
+}
+
+/**
+ * @brief Return current Watchdog Counter Value (7 bits counter value)
+ * @rmtoll CR T LL_WWDG_GetCounter
+ * @param WWDGx WWDG Instance
+ * @retval 7 bit Watchdog Counter value
+ */
+__STATIC_INLINE uint32_t LL_WWDG_GetCounter(WWDG_TypeDef *WWDGx)
+{
+ return (uint32_t)(READ_BIT(WWDGx->CR, WWDG_CR_T));
+}
+
+/**
+ * @brief Set the time base of the prescaler (WDGTB).
+ * @note Prescaler is used to apply ratio on PCLK clock, so that Watchdog counter
+ * is decremented every (4096 x 2expWDGTB) PCLK cycles
+ * @rmtoll CFR WDGTB LL_WWDG_SetPrescaler
+ * @param WWDGx WWDG Instance
+ * @param Prescaler This parameter can be one of the following values:
+ * @arg @ref LL_WWDG_PRESCALER_1
+ * @arg @ref LL_WWDG_PRESCALER_2
+ * @arg @ref LL_WWDG_PRESCALER_4
+ * @arg @ref LL_WWDG_PRESCALER_8
+ * @retval None
+ */
+__STATIC_INLINE void LL_WWDG_SetPrescaler(WWDG_TypeDef *WWDGx, uint32_t Prescaler)
+{
+ MODIFY_REG(WWDGx->CFR, WWDG_CFR_WDGTB, Prescaler);
+}
+
+/**
+ * @brief Return current Watchdog Prescaler Value
+ * @rmtoll CFR WDGTB LL_WWDG_GetPrescaler
+ * @param WWDGx WWDG Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_WWDG_PRESCALER_1
+ * @arg @ref LL_WWDG_PRESCALER_2
+ * @arg @ref LL_WWDG_PRESCALER_4
+ * @arg @ref LL_WWDG_PRESCALER_8
+ */
+__STATIC_INLINE uint32_t LL_WWDG_GetPrescaler(WWDG_TypeDef *WWDGx)
+{
+ return (uint32_t)(READ_BIT(WWDGx->CFR, WWDG_CFR_WDGTB));
+}
+
+/**
+ * @brief Set the Watchdog Window value to be compared to the downcounter (7-bits W[6:0]).
+ * @note This window value defines when write in the WWDG_CR register
+ * to program Watchdog counter is allowed.
+ * Watchdog counter value update must occur only when the counter value
+ * is lower than the Watchdog window register value.
+ * Otherwise, a MCU reset is generated if the 7-bit Watchdog counter value
+ * (in the control register) is refreshed before the downcounter has reached
+ * the watchdog window register value.
+ * Physically is possible to set the Window lower then 0x40 but it is not recommended.
+ * To generate an immediate reset, it is possible to set the Counter lower than 0x40.
+ * @rmtoll CFR W LL_WWDG_SetWindow
+ * @param WWDGx WWDG Instance
+ * @param Window 0x00..0x7F (7 bit Window value)
+ * @retval None
+ */
+__STATIC_INLINE void LL_WWDG_SetWindow(WWDG_TypeDef *WWDGx, uint32_t Window)
+{
+ MODIFY_REG(WWDGx->CFR, WWDG_CFR_W, Window);
+}
+
+/**
+ * @brief Return current Watchdog Window Value (7 bits value)
+ * @rmtoll CFR W LL_WWDG_GetWindow
+ * @param WWDGx WWDG Instance
+ * @retval 7 bit Watchdog Window value
+ */
+__STATIC_INLINE uint32_t LL_WWDG_GetWindow(WWDG_TypeDef *WWDGx)
+{
+ return (uint32_t)(READ_BIT(WWDGx->CFR, WWDG_CFR_W));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup WWDG_LL_EF_FLAG_Management FLAG_Management
+ * @{
+ */
+/**
+ * @brief Indicates if the WWDG Early Wakeup Interrupt Flag is set or not.
+ * @note This bit is set by hardware when the counter has reached the value 0x40.
+ * It must be cleared by software by writing 0.
+ * A write of 1 has no effect. This bit is also set if the interrupt is not enabled.
+ * @rmtoll SR EWIF LL_WWDG_IsActiveFlag_EWKUP
+ * @param WWDGx WWDG Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_WWDG_IsActiveFlag_EWKUP(WWDG_TypeDef *WWDGx)
+{
+ return (READ_BIT(WWDGx->SR, WWDG_SR_EWIF) == (WWDG_SR_EWIF));
+}
+
+/**
+ * @brief Clear WWDG Early Wakeup Interrupt Flag (EWIF)
+ * @rmtoll SR EWIF LL_WWDG_ClearFlag_EWKUP
+ * @param WWDGx WWDG Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_WWDG_ClearFlag_EWKUP(WWDG_TypeDef *WWDGx)
+{
+ WRITE_REG(WWDGx->SR, ~WWDG_SR_EWIF);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup WWDG_LL_EF_IT_Management IT_Management
+ * @{
+ */
+/**
+ * @brief Enable the Early Wakeup Interrupt.
+ * @note When set, an interrupt occurs whenever the counter reaches value 0x40.
+ * This interrupt is only cleared by hardware after a reset
+ * @rmtoll CFR EWI LL_WWDG_EnableIT_EWKUP
+ * @param WWDGx WWDG Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_WWDG_EnableIT_EWKUP(WWDG_TypeDef *WWDGx)
+{
+ SET_BIT(WWDGx->CFR, WWDG_CFR_EWI);
+}
+
+/**
+ * @brief Check if Early Wakeup Interrupt is enabled
+ * @rmtoll CFR EWI LL_WWDG_IsEnabledIT_EWKUP
+ * @param WWDGx WWDG Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_WWDG_IsEnabledIT_EWKUP(WWDG_TypeDef *WWDGx)
+{
+ return (READ_BIT(WWDGx->CFR, WWDG_CFR_EWI) == (WWDG_CFR_EWI));
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* WWDG */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_LL_WWDG_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c
new file mode 100644
index 0000000..a449258
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c
@@ -0,0 +1,595 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal.c
+ * @author MCD Application Team
+ * @brief HAL module driver.
+ * This is the common part of the HAL initialization
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The common HAL driver contains a set of generic and common APIs that can be
+ used by the PPP peripheral drivers and the user to start using the HAL.
+ [..]
+ The HAL contains two APIs' categories:
+ (+) Common HAL APIs
+ (+) Services HAL APIs
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup HAL HAL
+ * @brief HAL module driver.
+ * @{
+ */
+
+#ifdef HAL_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/** @defgroup HAL_Private_Constants HAL Private Constants
+ * @{
+ */
+/**
+ * @brief STM32F1xx HAL Driver version number V1.1.3
+ */
+#define __STM32F1xx_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */
+#define __STM32F1xx_HAL_VERSION_SUB1 (0x01U) /*!< [23:16] sub1 version */
+#define __STM32F1xx_HAL_VERSION_SUB2 (0x03U) /*!< [15:8] sub2 version */
+#define __STM32F1xx_HAL_VERSION_RC (0x00U) /*!< [7:0] release candidate */
+#define __STM32F1xx_HAL_VERSION ((__STM32F1xx_HAL_VERSION_MAIN << 24)\
+ |(__STM32F1xx_HAL_VERSION_SUB1 << 16)\
+ |(__STM32F1xx_HAL_VERSION_SUB2 << 8 )\
+ |(__STM32F1xx_HAL_VERSION_RC))
+
+#define IDCODE_DEVID_MASK 0x00000FFFU
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/** @defgroup HAL_Private_Variables HAL Private Variables
+ * @{
+ */
+__IO uint32_t uwTick;
+uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid PRIO */
+HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */
+/**
+ * @}
+ */
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions ---------------------------------------------------------*/
+
+/** @defgroup HAL_Exported_Functions HAL Exported Functions
+ * @{
+ */
+
+/** @defgroup HAL_Exported_Functions_Group1 Initialization and de-initialization Functions
+ * @brief Initialization and de-initialization functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Initializes the Flash interface, the NVIC allocation and initial clock
+ configuration. It initializes the systick also when timeout is needed
+ and the backup domain when enabled.
+ (+) de-Initializes common part of the HAL.
+ (+) Configure The time base source to have 1ms time base with a dedicated
+ Tick interrupt priority.
+ (++) SysTick timer is used by default as source of time base, but user
+ can eventually implement his proper time base source (a general purpose
+ timer for example or other time source), keeping in mind that Time base
+ duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
+ handled in milliseconds basis.
+ (++) Time base configuration function (HAL_InitTick ()) is called automatically
+ at the beginning of the program after reset by HAL_Init() or at any time
+ when clock is configured, by HAL_RCC_ClockConfig().
+ (++) Source of time base is configured to generate interrupts at regular
+ time intervals. Care must be taken if HAL_Delay() is called from a
+ peripheral ISR process, the Tick interrupt line must have higher priority
+ (numerically lower) than the peripheral interrupt. Otherwise the caller
+ ISR process will be blocked.
+ (++) functions affecting time base configurations are declared as __weak
+ to make override possible in case of other implementations in user file.
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief This function is used to initialize the HAL Library; it must be the first
+ * instruction to be executed in the main program (before to call any other
+ * HAL function), it performs the following:
+ * Configure the Flash prefetch.
+ * Configures the SysTick to generate an interrupt each 1 millisecond,
+ * which is clocked by the HSI (at this stage, the clock is not yet
+ * configured and thus the system is running from the internal HSI at 16 MHz).
+ * Set NVIC Group Priority to 4.
+ * Calls the HAL_MspInit() callback function defined in user file
+ * "stm32f1xx_hal_msp.c" to do the global low level hardware initialization
+ *
+ * @note SysTick is used as time base for the HAL_Delay() function, the application
+ * need to ensure that the SysTick time base is always set to 1 millisecond
+ * to have correct HAL operation.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_Init(void)
+{
+ /* Configure Flash prefetch */
+#if (PREFETCH_ENABLE != 0)
+#if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || \
+ defined(STM32F102x6) || defined(STM32F102xB) || \
+ defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || \
+ defined(STM32F105xC) || defined(STM32F107xC)
+
+ /* Prefetch buffer is not available on value line devices */
+ __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
+#endif
+#endif /* PREFETCH_ENABLE */
+
+ /* Set Interrupt Group Priority */
+ HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
+
+ /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */
+ HAL_InitTick(TICK_INT_PRIORITY);
+
+ /* Init the low level hardware */
+ HAL_MspInit();
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief This function de-Initializes common part of the HAL and stops the systick.
+ * of time base.
+ * @note This function is optional.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DeInit(void)
+{
+ /* Reset of all peripherals */
+ __HAL_RCC_APB1_FORCE_RESET();
+ __HAL_RCC_APB1_RELEASE_RESET();
+
+ __HAL_RCC_APB2_FORCE_RESET();
+ __HAL_RCC_APB2_RELEASE_RESET();
+
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ __HAL_RCC_AHB_FORCE_RESET();
+ __HAL_RCC_AHB_RELEASE_RESET();
+#endif
+
+ /* De-Init the low level hardware */
+ HAL_MspDeInit();
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Initialize the MSP.
+ * @retval None
+ */
+__weak void HAL_MspInit(void)
+{
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes the MSP.
+ * @retval None
+ */
+__weak void HAL_MspDeInit(void)
+{
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief This function configures the source of the time base.
+ * The time source is configured to have 1ms time base with a dedicated
+ * Tick interrupt priority.
+ * @note This function is called automatically at the beginning of program after
+ * reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig().
+ * @note In the default implementation, SysTick timer is the source of time base.
+ * It is used to generate interrupts at regular time intervals.
+ * Care must be taken if HAL_Delay() is called from a peripheral ISR process,
+ * The SysTick interrupt must have higher priority (numerically lower)
+ * than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
+ * The function is declared as __weak to be overwritten in case of other
+ * implementation in user file.
+ * @param TickPriority Tick interrupt priority.
+ * @retval HAL status
+ */
+__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
+{
+ /* Configure the SysTick to have interrupt in 1ms time basis*/
+ if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Configure the SysTick IRQ priority */
+ if (TickPriority < (1UL << __NVIC_PRIO_BITS))
+ {
+ HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
+ uwTickPrio = TickPriority;
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup HAL_Exported_Functions_Group2 HAL Control functions
+ * @brief HAL Control functions
+ *
+@verbatim
+ ===============================================================================
+ ##### HAL Control functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Provide a tick value in millisecond
+ (+) Provide a blocking delay in millisecond
+ (+) Suspend the time base source interrupt
+ (+) Resume the time base source interrupt
+ (+) Get the HAL API driver version
+ (+) Get the device identifier
+ (+) Get the device revision identifier
+ (+) Enable/Disable Debug module during SLEEP mode
+ (+) Enable/Disable Debug module during STOP mode
+ (+) Enable/Disable Debug module during STANDBY mode
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief This function is called to increment a global variable "uwTick"
+ * used as application time base.
+ * @note In the default implementation, this variable is incremented each 1ms
+ * in SysTick ISR.
+ * @note This function is declared as __weak to be overwritten in case of other
+ * implementations in user file.
+ * @retval None
+ */
+__weak void HAL_IncTick(void)
+{
+ uwTick += uwTickFreq;
+}
+
+/**
+ * @brief Provides a tick value in millisecond.
+ * @note This function is declared as __weak to be overwritten in case of other
+ * implementations in user file.
+ * @retval tick value
+ */
+__weak uint32_t HAL_GetTick(void)
+{
+ return uwTick;
+}
+
+/**
+ * @brief This function returns a tick priority.
+ * @retval tick priority
+ */
+uint32_t HAL_GetTickPrio(void)
+{
+ return uwTickPrio;
+}
+
+/**
+ * @brief Set new tick Freq.
+ * @retval Status
+ */
+HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+ assert_param(IS_TICKFREQ(Freq));
+
+ if (uwTickFreq != Freq)
+ {
+ uwTickFreq = Freq;
+
+ /* Apply the new tick Freq */
+ status = HAL_InitTick(uwTickPrio);
+ }
+
+ return status;
+}
+
+/**
+ * @brief Return tick frequency.
+ * @retval tick period in Hz
+ */
+HAL_TickFreqTypeDef HAL_GetTickFreq(void)
+{
+ return uwTickFreq;
+}
+
+/**
+ * @brief This function provides minimum delay (in milliseconds) based
+ * on variable incremented.
+ * @note In the default implementation , SysTick timer is the source of time base.
+ * It is used to generate interrupts at regular time intervals where uwTick
+ * is incremented.
+ * @note This function is declared as __weak to be overwritten in case of other
+ * implementations in user file.
+ * @param Delay specifies the delay time length, in milliseconds.
+ * @retval None
+ */
+__weak void HAL_Delay(uint32_t Delay)
+{
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t wait = Delay;
+
+ /* Add a freq to guarantee minimum wait */
+ if (wait < HAL_MAX_DELAY)
+ {
+ wait += (uint32_t)(uwTickFreq);
+ }
+
+ while ((HAL_GetTick() - tickstart) < wait)
+ {
+ }
+}
+
+/**
+ * @brief Suspend Tick increment.
+ * @note In the default implementation , SysTick timer is the source of time base. It is
+ * used to generate interrupts at regular time intervals. Once HAL_SuspendTick()
+ * is called, the SysTick interrupt will be disabled and so Tick increment
+ * is suspended.
+ * @note This function is declared as __weak to be overwritten in case of other
+ * implementations in user file.
+ * @retval None
+ */
+__weak void HAL_SuspendTick(void)
+{
+ /* Disable SysTick Interrupt */
+ CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
+}
+
+/**
+ * @brief Resume Tick increment.
+ * @note In the default implementation , SysTick timer is the source of time base. It is
+ * used to generate interrupts at regular time intervals. Once HAL_ResumeTick()
+ * is called, the SysTick interrupt will be enabled and so Tick increment
+ * is resumed.
+ * @note This function is declared as __weak to be overwritten in case of other
+ * implementations in user file.
+ * @retval None
+ */
+__weak void HAL_ResumeTick(void)
+{
+ /* Enable SysTick Interrupt */
+ SET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
+}
+
+/**
+ * @brief Returns the HAL revision
+ * @retval version 0xXYZR (8bits for each decimal, R for RC)
+ */
+uint32_t HAL_GetHalVersion(void)
+{
+ return __STM32F1xx_HAL_VERSION;
+}
+
+/**
+ * @brief Returns the device revision identifier.
+ * Note: On devices STM32F10xx8 and STM32F10xxB,
+ * STM32F101xC/D/E and STM32F103xC/D/E,
+ * STM32F101xF/G and STM32F103xF/G
+ * STM32F10xx4 and STM32F10xx6
+ * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
+ * debug mode (not accessible by the user software in normal mode).
+ * Refer to errata sheet of these devices for more details.
+ * @retval Device revision identifier
+ */
+uint32_t HAL_GetREVID(void)
+{
+ return ((DBGMCU->IDCODE) >> DBGMCU_IDCODE_REV_ID_Pos);
+}
+
+/**
+ * @brief Returns the device identifier.
+ * Note: On devices STM32F10xx8 and STM32F10xxB,
+ * STM32F101xC/D/E and STM32F103xC/D/E,
+ * STM32F101xF/G and STM32F103xF/G
+ * STM32F10xx4 and STM32F10xx6
+ * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
+ * debug mode (not accessible by the user software in normal mode).
+ * Refer to errata sheet of these devices for more details.
+ * @retval Device identifier
+ */
+uint32_t HAL_GetDEVID(void)
+{
+ return ((DBGMCU->IDCODE) & IDCODE_DEVID_MASK);
+}
+
+/**
+ * @brief Enable the Debug Module during SLEEP mode
+ * @retval None
+ */
+void HAL_DBGMCU_EnableDBGSleepMode(void)
+{
+ SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
+}
+
+/**
+ * @brief Disable the Debug Module during SLEEP mode
+ * Note: On devices STM32F10xx8 and STM32F10xxB,
+ * STM32F101xC/D/E and STM32F103xC/D/E,
+ * STM32F101xF/G and STM32F103xF/G
+ * STM32F10xx4 and STM32F10xx6
+ * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
+ * debug mode (not accessible by the user software in normal mode).
+ * Refer to errata sheet of these devices for more details.
+ * @retval None
+ */
+void HAL_DBGMCU_DisableDBGSleepMode(void)
+{
+ CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
+}
+
+/**
+ * @brief Enable the Debug Module during STOP mode
+ * Note: On devices STM32F10xx8 and STM32F10xxB,
+ * STM32F101xC/D/E and STM32F103xC/D/E,
+ * STM32F101xF/G and STM32F103xF/G
+ * STM32F10xx4 and STM32F10xx6
+ * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
+ * debug mode (not accessible by the user software in normal mode).
+ * Refer to errata sheet of these devices for more details.
+ * Note: On all STM32F1 devices:
+ * If the system tick timer interrupt is enabled during the Stop mode
+ * debug (DBG_STOP bit set in the DBGMCU_CR register ), it will wakeup
+ * the system from Stop mode.
+ * Workaround: To debug the Stop mode, disable the system tick timer
+ * interrupt.
+ * Refer to errata sheet of these devices for more details.
+ * Note: On all STM32F1 devices:
+ * If the system tick timer interrupt is enabled during the Stop mode
+ * debug (DBG_STOP bit set in the DBGMCU_CR register ), it will wakeup
+ * the system from Stop mode.
+ * Workaround: To debug the Stop mode, disable the system tick timer
+ * interrupt.
+ * Refer to errata sheet of these devices for more details.
+ * @retval None
+ */
+void HAL_DBGMCU_EnableDBGStopMode(void)
+{
+ SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
+}
+
+/**
+ * @brief Disable the Debug Module during STOP mode
+ * Note: On devices STM32F10xx8 and STM32F10xxB,
+ * STM32F101xC/D/E and STM32F103xC/D/E,
+ * STM32F101xF/G and STM32F103xF/G
+ * STM32F10xx4 and STM32F10xx6
+ * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
+ * debug mode (not accessible by the user software in normal mode).
+ * Refer to errata sheet of these devices for more details.
+ * @retval None
+ */
+void HAL_DBGMCU_DisableDBGStopMode(void)
+{
+ CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
+}
+
+/**
+ * @brief Enable the Debug Module during STANDBY mode
+ * Note: On devices STM32F10xx8 and STM32F10xxB,
+ * STM32F101xC/D/E and STM32F103xC/D/E,
+ * STM32F101xF/G and STM32F103xF/G
+ * STM32F10xx4 and STM32F10xx6
+ * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
+ * debug mode (not accessible by the user software in normal mode).
+ * Refer to errata sheet of these devices for more details.
+ * @retval None
+ */
+void HAL_DBGMCU_EnableDBGStandbyMode(void)
+{
+ SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
+}
+
+/**
+ * @brief Disable the Debug Module during STANDBY mode
+ * Note: On devices STM32F10xx8 and STM32F10xxB,
+ * STM32F101xC/D/E and STM32F103xC/D/E,
+ * STM32F101xF/G and STM32F103xF/G
+ * STM32F10xx4 and STM32F10xx6
+ * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
+ * debug mode (not accessible by the user software in normal mode).
+ * Refer to errata sheet of these devices for more details.
+ * @retval None
+ */
+void HAL_DBGMCU_DisableDBGStandbyMode(void)
+{
+ CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
+}
+
+/**
+ * @brief Return the unique device identifier (UID based on 96 bits)
+ * @param UID pointer to 3 words array.
+ * @retval Device identifier
+ */
+void HAL_GetUID(uint32_t *UID)
+{
+ UID[0] = (uint32_t)(READ_REG(*((uint32_t *)UID_BASE)));
+ UID[1] = (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE + 4U))));
+ UID[2] = (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE + 8U))));
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc.c
new file mode 100644
index 0000000..de1ba75
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc.c
@@ -0,0 +1,2110 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_adc.c
+ * @author MCD Application Team
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Analog to Digital Convertor (ADC)
+ * peripheral:
+ * + Initialization and de-initialization functions
+ * ++ Initialization and Configuration of ADC
+ * + Operation functions
+ * ++ Start, stop, get result of conversions of regular
+ * group, using 3 possible modes: polling, interruption or DMA.
+ * + Control functions
+ * ++ Channels configuration on regular group
+ * ++ Channels configuration on injected group
+ * ++ Analog Watchdog configuration
+ * + State functions
+ * ++ ADC state machine management
+ * ++ Interrupts and flags management
+ * Other functions (extended functions) are available in file
+ * "stm32f1xx_hal_adc_ex.c".
+ *
+ @verbatim
+ ==============================================================================
+ ##### ADC peripheral features #####
+ ==============================================================================
+ [..]
+ (+) 12-bit resolution
+
+ (+) Interrupt generation at the end of regular conversion, end of injected
+ conversion, and in case of analog watchdog or overrun events.
+
+ (+) Single and continuous conversion modes.
+
+ (+) Scan mode for conversion of several channels sequentially.
+
+ (+) Data alignment with in-built data coherency.
+
+ (+) Programmable sampling time (channel wise)
+
+ (+) ADC conversion of regular group and injected group.
+
+ (+) External trigger (timer or EXTI)
+ for both regular and injected groups.
+
+ (+) DMA request generation for transfer of conversions data of regular group.
+
+ (+) Multimode Dual mode (available on devices with 2 ADCs or more).
+
+ (+) Configurable DMA data storage in Multimode Dual mode (available on devices
+ with 2 DCs or more).
+
+ (+) Configurable delay between conversions in Dual interleaved mode (available
+ on devices with 2 DCs or more).
+
+ (+) ADC calibration
+
+ (+) ADC supply requirements: 2.4 V to 3.6 V at full speed and down to 1.8 V at
+ slower speed.
+
+ (+) ADC input range: from Vref- (connected to Vssa) to Vref+ (connected to
+ Vdda or to an external voltage reference).
+
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+
+ *** Configuration of top level parameters related to ADC ***
+ ============================================================
+ [..]
+
+ (#) Enable the ADC interface
+ (++) As prerequisite, ADC clock must be configured at RCC top level.
+ Caution: On STM32F1, ADC clock frequency max is 14MHz (refer
+ to device datasheet).
+ Therefore, ADC clock prescaler must be configured in
+ function of ADC clock source frequency to remain below
+ this maximum frequency.
+ (++) One clock setting is mandatory:
+ ADC clock (core clock, also possibly conversion clock).
+ (+++) Example:
+ Into HAL_ADC_MspInit() (recommended code location) or with
+ other device clock parameters configuration:
+ (+++) RCC_PeriphCLKInitTypeDef PeriphClkInit;
+ (+++) __ADC1_CLK_ENABLE();
+ (+++) PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
+ (+++) PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV2;
+ (+++) HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
+
+ (#) ADC pins configuration
+ (++) Enable the clock for the ADC GPIOs
+ using macro __HAL_RCC_GPIOx_CLK_ENABLE()
+ (++) Configure these ADC pins in analog mode
+ using function HAL_GPIO_Init()
+
+ (#) Optionally, in case of usage of ADC with interruptions:
+ (++) Configure the NVIC for ADC
+ using function HAL_NVIC_EnableIRQ(ADCx_IRQn)
+ (++) Insert the ADC interruption handler function HAL_ADC_IRQHandler()
+ into the function of corresponding ADC interruption vector
+ ADCx_IRQHandler().
+
+ (#) Optionally, in case of usage of DMA:
+ (++) Configure the DMA (DMA channel, mode normal or circular, ...)
+ using function HAL_DMA_Init().
+ (++) Configure the NVIC for DMA
+ using function HAL_NVIC_EnableIRQ(DMAx_Channelx_IRQn)
+ (++) Insert the ADC interruption handler function HAL_ADC_IRQHandler()
+ into the function of corresponding DMA interruption vector
+ DMAx_Channelx_IRQHandler().
+
+ *** Configuration of ADC, groups regular/injected, channels parameters ***
+ ==========================================================================
+ [..]
+
+ (#) Configure the ADC parameters (resolution, data alignment, ...)
+ and regular group parameters (conversion trigger, sequencer, ...)
+ using function HAL_ADC_Init().
+
+ (#) Configure the channels for regular group parameters (channel number,
+ channel rank into sequencer, ..., into regular group)
+ using function HAL_ADC_ConfigChannel().
+
+ (#) Optionally, configure the injected group parameters (conversion trigger,
+ sequencer, ..., of injected group)
+ and the channels for injected group parameters (channel number,
+ channel rank into sequencer, ..., into injected group)
+ using function HAL_ADCEx_InjectedConfigChannel().
+
+ (#) Optionally, configure the analog watchdog parameters (channels
+ monitored, thresholds, ...)
+ using function HAL_ADC_AnalogWDGConfig().
+
+ (#) Optionally, for devices with several ADC instances: configure the
+ multimode parameters
+ using function HAL_ADCEx_MultiModeConfigChannel().
+
+ *** Execution of ADC conversions ***
+ ====================================
+ [..]
+
+ (#) Optionally, perform an automatic ADC calibration to improve the
+ conversion accuracy
+ using function HAL_ADCEx_Calibration_Start().
+
+ (#) ADC driver can be used among three modes: polling, interruption,
+ transfer by DMA.
+
+ (++) ADC conversion by polling:
+ (+++) Activate the ADC peripheral and start conversions
+ using function HAL_ADC_Start()
+ (+++) Wait for ADC conversion completion
+ using function HAL_ADC_PollForConversion()
+ (or for injected group: HAL_ADCEx_InjectedPollForConversion() )
+ (+++) Retrieve conversion results
+ using function HAL_ADC_GetValue()
+ (or for injected group: HAL_ADCEx_InjectedGetValue() )
+ (+++) Stop conversion and disable the ADC peripheral
+ using function HAL_ADC_Stop()
+
+ (++) ADC conversion by interruption:
+ (+++) Activate the ADC peripheral and start conversions
+ using function HAL_ADC_Start_IT()
+ (+++) Wait for ADC conversion completion by call of function
+ HAL_ADC_ConvCpltCallback()
+ (this function must be implemented in user program)
+ (or for injected group: HAL_ADCEx_InjectedConvCpltCallback() )
+ (+++) Retrieve conversion results
+ using function HAL_ADC_GetValue()
+ (or for injected group: HAL_ADCEx_InjectedGetValue() )
+ (+++) Stop conversion and disable the ADC peripheral
+ using function HAL_ADC_Stop_IT()
+
+ (++) ADC conversion with transfer by DMA:
+ (+++) Activate the ADC peripheral and start conversions
+ using function HAL_ADC_Start_DMA()
+ (+++) Wait for ADC conversion completion by call of function
+ HAL_ADC_ConvCpltCallback() or HAL_ADC_ConvHalfCpltCallback()
+ (these functions must be implemented in user program)
+ (+++) Conversion results are automatically transferred by DMA into
+ destination variable address.
+ (+++) Stop conversion and disable the ADC peripheral
+ using function HAL_ADC_Stop_DMA()
+
+ (++) For devices with several ADCs: ADC multimode conversion
+ with transfer by DMA:
+ (+++) Activate the ADC peripheral (slave) and start conversions
+ using function HAL_ADC_Start()
+ (+++) Activate the ADC peripheral (master) and start conversions
+ using function HAL_ADCEx_MultiModeStart_DMA()
+ (+++) Wait for ADC conversion completion by call of function
+ HAL_ADC_ConvCpltCallback() or HAL_ADC_ConvHalfCpltCallback()
+ (these functions must be implemented in user program)
+ (+++) Conversion results are automatically transferred by DMA into
+ destination variable address.
+ (+++) Stop conversion and disable the ADC peripheral (master)
+ using function HAL_ADCEx_MultiModeStop_DMA()
+ (+++) Stop conversion and disable the ADC peripheral (slave)
+ using function HAL_ADC_Stop_IT()
+
+ [..]
+
+ (@) Callback functions must be implemented in user program:
+ (+@) HAL_ADC_ErrorCallback()
+ (+@) HAL_ADC_LevelOutOfWindowCallback() (callback of analog watchdog)
+ (+@) HAL_ADC_ConvCpltCallback()
+ (+@) HAL_ADC_ConvHalfCpltCallback
+ (+@) HAL_ADCEx_InjectedConvCpltCallback()
+
+ *** Deinitialization of ADC ***
+ ============================================================
+ [..]
+
+ (#) Disable the ADC interface
+ (++) ADC clock can be hard reset and disabled at RCC top level.
+ (++) Hard reset of ADC peripherals
+ using macro __ADCx_FORCE_RESET(), __ADCx_RELEASE_RESET().
+ (++) ADC clock disable
+ using the equivalent macro/functions as configuration step.
+ (+++) Example:
+ Into HAL_ADC_MspDeInit() (recommended code location) or with
+ other device clock parameters configuration:
+ (+++) PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC
+ (+++) PeriphClkInit.AdcClockSelection = RCC_ADCPLLCLK2_OFF
+ (+++) HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit)
+
+ (#) ADC pins configuration
+ (++) Disable the clock for the ADC GPIOs
+ using macro __HAL_RCC_GPIOx_CLK_DISABLE()
+
+ (#) Optionally, in case of usage of ADC with interruptions:
+ (++) Disable the NVIC for ADC
+ using function HAL_NVIC_EnableIRQ(ADCx_IRQn)
+
+ (#) Optionally, in case of usage of DMA:
+ (++) Deinitialize the DMA
+ using function HAL_DMA_Init().
+ (++) Disable the NVIC for DMA
+ using function HAL_NVIC_EnableIRQ(DMAx_Channelx_IRQn)
+
+ [..]
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup ADC ADC
+ * @brief ADC HAL module driver
+ * @{
+ */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup ADC_Private_Constants ADC Private Constants
+ * @{
+ */
+
+ /* Timeout values for ADC enable and disable settling time. */
+ /* Values defined to be higher than worst cases: low clocks freq, */
+ /* maximum prescaler. */
+ /* Ex of profile low frequency : Clock source at 0.1 MHz, ADC clock */
+ /* prescaler 4, sampling time 12.5 ADC clock cycles, resolution 12 bits. */
+ /* Unit: ms */
+ #define ADC_ENABLE_TIMEOUT 2U
+ #define ADC_DISABLE_TIMEOUT 2U
+
+ /* Delay for ADC stabilization time. */
+ /* Maximum delay is 1us (refer to device datasheet, parameter tSTAB). */
+ /* Unit: us */
+ #define ADC_STAB_DELAY_US 1U
+
+ /* Delay for temperature sensor stabilization time. */
+ /* Maximum delay is 10us (refer to device datasheet, parameter tSTART). */
+ /* Unit: us */
+ #define ADC_TEMPSENSOR_DELAY_US 10U
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup ADC_Private_Functions ADC Private Functions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup ADC_Exported_Functions ADC Exported Functions
+ * @{
+ */
+
+/** @defgroup ADC_Exported_Functions_Group1 Initialization/de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Initialize and configure the ADC.
+ (+) De-initialize the ADC.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the ADC peripheral and regular group according to
+ * parameters specified in structure "ADC_InitTypeDef".
+ * @note As prerequisite, ADC clock must be configured at RCC top level
+ * (clock source APB2).
+ * See commented example code below that can be copied and uncommented
+ * into HAL_ADC_MspInit().
+ * @note Possibility to update parameters on the fly:
+ * This function initializes the ADC MSP (HAL_ADC_MspInit()) only when
+ * coming from ADC state reset. Following calls to this function can
+ * be used to reconfigure some parameters of ADC_InitTypeDef
+ * structure on the fly, without modifying MSP configuration. If ADC
+ * MSP has to be modified again, HAL_ADC_DeInit() must be called
+ * before HAL_ADC_Init().
+ * The setting of these parameters is conditioned to ADC state.
+ * For parameters constraints, see comments of structure
+ * "ADC_InitTypeDef".
+ * @note This function configures the ADC within 2 scopes: scope of entire
+ * ADC and scope of regular group. For parameters details, see comments
+ * of structure "ADC_InitTypeDef".
+ * @param hadc: ADC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+ uint32_t tmp_cr1 = 0U;
+ uint32_t tmp_cr2 = 0U;
+ uint32_t tmp_sqr1 = 0U;
+
+ /* Check ADC handle */
+ if(hadc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_DATA_ALIGN(hadc->Init.DataAlign));
+ assert_param(IS_ADC_SCAN_MODE(hadc->Init.ScanConvMode));
+ assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
+ assert_param(IS_ADC_EXTTRIG(hadc->Init.ExternalTrigConv));
+
+ if(hadc->Init.ScanConvMode != ADC_SCAN_DISABLE)
+ {
+ assert_param(IS_ADC_REGULAR_NB_CONV(hadc->Init.NbrOfConversion));
+ assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DiscontinuousConvMode));
+ if(hadc->Init.DiscontinuousConvMode != DISABLE)
+ {
+ assert_param(IS_ADC_REGULAR_DISCONT_NUMBER(hadc->Init.NbrOfDiscConversion));
+ }
+ }
+
+ /* As prerequisite, into HAL_ADC_MspInit(), ADC clock must be configured */
+ /* at RCC top level. */
+ /* Refer to header of this file for more details on clock enabling */
+ /* procedure. */
+
+ /* Actions performed only if ADC is coming from state reset: */
+ /* - Initialization of ADC MSP */
+ if (hadc->State == HAL_ADC_STATE_RESET)
+ {
+ /* Initialize ADC error code */
+ ADC_CLEAR_ERRORCODE(hadc);
+
+ /* Allocate lock resource and initialize it */
+ hadc->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware */
+ HAL_ADC_MspInit(hadc);
+ }
+
+ /* Stop potential conversion on going, on regular and injected groups */
+ /* Disable ADC peripheral */
+ /* Note: In case of ADC already enabled, precaution to not launch an */
+ /* unwanted conversion while modifying register CR2 by writing 1 to */
+ /* bit ADON. */
+ tmp_hal_status = ADC_ConversionStop_Disable(hadc);
+
+
+ /* Configuration of ADC parameters if previous preliminary actions are */
+ /* correctly completed. */
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL) &&
+ (tmp_hal_status == HAL_OK) )
+ {
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_BUSY_INTERNAL);
+
+ /* Set ADC parameters */
+
+ /* Configuration of ADC: */
+ /* - data alignment */
+ /* - external trigger to start conversion */
+ /* - external trigger polarity (always set to 1, because needed for all */
+ /* triggers: external trigger of SW start) */
+ /* - continuous conversion mode */
+ /* Note: External trigger polarity (ADC_CR2_EXTTRIG) is set into */
+ /* HAL_ADC_Start_xxx functions because if set in this function, */
+ /* a conversion on injected group would start a conversion also on */
+ /* regular group after ADC enabling. */
+ tmp_cr2 |= (hadc->Init.DataAlign |
+ ADC_CFGR_EXTSEL(hadc, hadc->Init.ExternalTrigConv) |
+ ADC_CR2_CONTINUOUS(hadc->Init.ContinuousConvMode) );
+
+ /* Configuration of ADC: */
+ /* - scan mode */
+ /* - discontinuous mode disable/enable */
+ /* - discontinuous mode number of conversions */
+ tmp_cr1 |= (ADC_CR1_SCAN_SET(hadc->Init.ScanConvMode));
+
+ /* Enable discontinuous mode only if continuous mode is disabled */
+ /* Note: If parameter "Init.ScanConvMode" is set to disable, parameter */
+ /* discontinuous is set anyway, but will have no effect on ADC HW. */
+ if (hadc->Init.DiscontinuousConvMode == ENABLE)
+ {
+ if (hadc->Init.ContinuousConvMode == DISABLE)
+ {
+ /* Enable the selected ADC regular discontinuous mode */
+ /* Set the number of channels to be converted in discontinuous mode */
+ SET_BIT(tmp_cr1, ADC_CR1_DISCEN |
+ ADC_CR1_DISCONTINUOUS_NUM(hadc->Init.NbrOfDiscConversion) );
+ }
+ else
+ {
+ /* ADC regular group settings continuous and sequencer discontinuous*/
+ /* cannot be enabled simultaneously. */
+
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ /* Set ADC error code to ADC IP internal error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+ }
+ }
+
+ /* Update ADC configuration register CR1 with previous settings */
+ MODIFY_REG(hadc->Instance->CR1,
+ ADC_CR1_SCAN |
+ ADC_CR1_DISCEN |
+ ADC_CR1_DISCNUM ,
+ tmp_cr1 );
+
+ /* Update ADC configuration register CR2 with previous settings */
+ MODIFY_REG(hadc->Instance->CR2,
+ ADC_CR2_ALIGN |
+ ADC_CR2_EXTSEL |
+ ADC_CR2_EXTTRIG |
+ ADC_CR2_CONT ,
+ tmp_cr2 );
+
+ /* Configuration of regular group sequencer: */
+ /* - if scan mode is disabled, regular channels sequence length is set to */
+ /* 0x00: 1 channel converted (channel on regular rank 1) */
+ /* Parameter "NbrOfConversion" is discarded. */
+ /* Note: Scan mode is present by hardware on this device and, if */
+ /* disabled, discards automatically nb of conversions. Anyway, nb of */
+ /* conversions is forced to 0x00 for alignment over all STM32 devices. */
+ /* - if scan mode is enabled, regular channels sequence length is set to */
+ /* parameter "NbrOfConversion" */
+ if (ADC_CR1_SCAN_SET(hadc->Init.ScanConvMode) == ADC_SCAN_ENABLE)
+ {
+ tmp_sqr1 = ADC_SQR1_L_SHIFT(hadc->Init.NbrOfConversion);
+ }
+
+ MODIFY_REG(hadc->Instance->SQR1,
+ ADC_SQR1_L ,
+ tmp_sqr1 );
+
+ /* Check back that ADC registers have effectively been configured to */
+ /* ensure of no potential problem of ADC core IP clocking. */
+ /* Check through register CR2 (excluding bits set in other functions: */
+ /* execution control bits (ADON, JSWSTART, SWSTART), regular group bits */
+ /* (DMA), injected group bits (JEXTTRIG and JEXTSEL), channel internal */
+ /* measurement path bit (TSVREFE). */
+ if (READ_BIT(hadc->Instance->CR2, ~(ADC_CR2_ADON | ADC_CR2_DMA |
+ ADC_CR2_SWSTART | ADC_CR2_JSWSTART |
+ ADC_CR2_JEXTTRIG | ADC_CR2_JEXTSEL |
+ ADC_CR2_TSVREFE ))
+ == tmp_cr2)
+ {
+ /* Set ADC error code to none */
+ ADC_CLEAR_ERRORCODE(hadc);
+
+ /* Set the ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_BUSY_INTERNAL,
+ HAL_ADC_STATE_READY);
+ }
+ else
+ {
+ /* Update ADC state machine to error */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_BUSY_INTERNAL,
+ HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Set ADC error code to ADC IP internal error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+
+ tmp_hal_status = HAL_ERROR;
+ }
+
+ }
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+
+ tmp_hal_status = HAL_ERROR;
+ }
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Deinitialize the ADC peripheral registers to their default reset
+ * values, with deinitialization of the ADC MSP.
+ * If needed, the example code can be copied and uncommented into
+ * function HAL_ADC_MspDeInit().
+ * @param hadc: ADC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef* hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+
+ /* Check ADC handle */
+ if(hadc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL);
+
+ /* Stop potential conversion on going, on regular and injected groups */
+ /* Disable ADC peripheral */
+ tmp_hal_status = ADC_ConversionStop_Disable(hadc);
+
+
+ /* Configuration of ADC parameters if previous preliminary actions are */
+ /* correctly completed. */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* ========== Reset ADC registers ========== */
+
+
+
+
+ /* Reset register SR */
+ __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_AWD | ADC_FLAG_JEOC | ADC_FLAG_EOC |
+ ADC_FLAG_JSTRT | ADC_FLAG_STRT));
+
+ /* Reset register CR1 */
+ CLEAR_BIT(hadc->Instance->CR1, (ADC_CR1_AWDEN | ADC_CR1_JAWDEN | ADC_CR1_DISCNUM |
+ ADC_CR1_JDISCEN | ADC_CR1_DISCEN | ADC_CR1_JAUTO |
+ ADC_CR1_AWDSGL | ADC_CR1_SCAN | ADC_CR1_JEOCIE |
+ ADC_CR1_AWDIE | ADC_CR1_EOCIE | ADC_CR1_AWDCH ));
+
+ /* Reset register CR2 */
+ CLEAR_BIT(hadc->Instance->CR2, (ADC_CR2_TSVREFE | ADC_CR2_SWSTART | ADC_CR2_JSWSTART |
+ ADC_CR2_EXTTRIG | ADC_CR2_EXTSEL | ADC_CR2_JEXTTRIG |
+ ADC_CR2_JEXTSEL | ADC_CR2_ALIGN | ADC_CR2_DMA |
+ ADC_CR2_RSTCAL | ADC_CR2_CAL | ADC_CR2_CONT |
+ ADC_CR2_ADON ));
+
+ /* Reset register SMPR1 */
+ CLEAR_BIT(hadc->Instance->SMPR1, (ADC_SMPR1_SMP17 | ADC_SMPR1_SMP16 | ADC_SMPR1_SMP15 |
+ ADC_SMPR1_SMP14 | ADC_SMPR1_SMP13 | ADC_SMPR1_SMP12 |
+ ADC_SMPR1_SMP11 | ADC_SMPR1_SMP10 ));
+
+ /* Reset register SMPR2 */
+ CLEAR_BIT(hadc->Instance->SMPR2, (ADC_SMPR2_SMP9 | ADC_SMPR2_SMP8 | ADC_SMPR2_SMP7 |
+ ADC_SMPR2_SMP6 | ADC_SMPR2_SMP5 | ADC_SMPR2_SMP4 |
+ ADC_SMPR2_SMP3 | ADC_SMPR2_SMP2 | ADC_SMPR2_SMP1 |
+ ADC_SMPR2_SMP0 ));
+
+ /* Reset register JOFR1 */
+ CLEAR_BIT(hadc->Instance->JOFR1, ADC_JOFR1_JOFFSET1);
+ /* Reset register JOFR2 */
+ CLEAR_BIT(hadc->Instance->JOFR2, ADC_JOFR2_JOFFSET2);
+ /* Reset register JOFR3 */
+ CLEAR_BIT(hadc->Instance->JOFR3, ADC_JOFR3_JOFFSET3);
+ /* Reset register JOFR4 */
+ CLEAR_BIT(hadc->Instance->JOFR4, ADC_JOFR4_JOFFSET4);
+
+ /* Reset register HTR */
+ CLEAR_BIT(hadc->Instance->HTR, ADC_HTR_HT);
+ /* Reset register LTR */
+ CLEAR_BIT(hadc->Instance->LTR, ADC_LTR_LT);
+
+ /* Reset register SQR1 */
+ CLEAR_BIT(hadc->Instance->SQR1, ADC_SQR1_L |
+ ADC_SQR1_SQ16 | ADC_SQR1_SQ15 |
+ ADC_SQR1_SQ14 | ADC_SQR1_SQ13 );
+
+ /* Reset register SQR1 */
+ CLEAR_BIT(hadc->Instance->SQR1, ADC_SQR1_L |
+ ADC_SQR1_SQ16 | ADC_SQR1_SQ15 |
+ ADC_SQR1_SQ14 | ADC_SQR1_SQ13 );
+
+ /* Reset register SQR2 */
+ CLEAR_BIT(hadc->Instance->SQR2, ADC_SQR2_SQ12 | ADC_SQR2_SQ11 | ADC_SQR2_SQ10 |
+ ADC_SQR2_SQ9 | ADC_SQR2_SQ8 | ADC_SQR2_SQ7 );
+
+ /* Reset register SQR3 */
+ CLEAR_BIT(hadc->Instance->SQR3, ADC_SQR3_SQ6 | ADC_SQR3_SQ5 | ADC_SQR3_SQ4 |
+ ADC_SQR3_SQ3 | ADC_SQR3_SQ2 | ADC_SQR3_SQ1 );
+
+ /* Reset register JSQR */
+ CLEAR_BIT(hadc->Instance->JSQR, ADC_JSQR_JL |
+ ADC_JSQR_JSQ4 | ADC_JSQR_JSQ3 |
+ ADC_JSQR_JSQ2 | ADC_JSQR_JSQ1 );
+
+ /* Reset register JSQR */
+ CLEAR_BIT(hadc->Instance->JSQR, ADC_JSQR_JL |
+ ADC_JSQR_JSQ4 | ADC_JSQR_JSQ3 |
+ ADC_JSQR_JSQ2 | ADC_JSQR_JSQ1 );
+
+ /* Reset register DR */
+ /* bits in access mode read only, no direct reset applicable*/
+
+ /* Reset registers JDR1, JDR2, JDR3, JDR4 */
+ /* bits in access mode read only, no direct reset applicable*/
+
+ /* ========== Hard reset ADC peripheral ========== */
+ /* Performs a global reset of the entire ADC peripheral: ADC state is */
+ /* forced to a similar state after device power-on. */
+ /* If needed, copy-paste and uncomment the following reset code into */
+ /* function "void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)": */
+ /* */
+ /* __HAL_RCC_ADC1_FORCE_RESET() */
+ /* __HAL_RCC_ADC1_RELEASE_RESET() */
+
+ /* DeInit the low level hardware */
+ HAL_ADC_MspDeInit(hadc);
+
+ /* Set ADC error code to none */
+ ADC_CLEAR_ERRORCODE(hadc);
+
+ /* Set ADC state */
+ hadc->State = HAL_ADC_STATE_RESET;
+
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Initializes the ADC MSP.
+ * @param hadc: ADC handle
+ * @retval None
+ */
+__weak void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
+ /* NOTE : This function should not be modified. When the callback is needed,
+ function HAL_ADC_MspInit must be implemented in the user file.
+ */
+}
+
+/**
+ * @brief DeInitializes the ADC MSP.
+ * @param hadc: ADC handle
+ * @retval None
+ */
+__weak void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
+ /* NOTE : This function should not be modified. When the callback is needed,
+ function HAL_ADC_MspDeInit must be implemented in the user file.
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Exported_Functions_Group2 IO operation functions
+ * @brief Input and Output operation functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Start conversion of regular group.
+ (+) Stop conversion of regular group.
+ (+) Poll for conversion complete on regular group.
+ (+) Poll for conversion event.
+ (+) Get result of regular channel conversion.
+ (+) Start conversion of regular group and enable interruptions.
+ (+) Stop conversion of regular group and disable interruptions.
+ (+) Handle ADC interrupt request
+ (+) Start conversion of regular group and enable DMA transfer.
+ (+) Stop conversion of regular group and disable ADC DMA transfer.
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables ADC, starts conversion of regular group.
+ * Interruptions enabled in this function: None.
+ * @param hadc: ADC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Enable the ADC peripheral */
+ tmp_hal_status = ADC_Enable(hadc);
+
+ /* Start conversion if ADC is effectively enabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ /* - Clear state bitfield related to regular group conversion results */
+ /* - Set state bitfield related to regular operation */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC,
+ HAL_ADC_STATE_REG_BUSY);
+
+ /* Set group injected state (from auto-injection) and multimode state */
+ /* for all cases of multimode: independent mode, multimode ADC master */
+ /* or multimode ADC slave (for devices with several ADCs): */
+ if (ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc))
+ {
+ /* Set ADC state (ADC independent or master) */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+
+ /* If conversions on group regular are also triggering group injected, */
+ /* update ADC state. */
+ if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET)
+ {
+ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
+ }
+ }
+ else
+ {
+ /* Set ADC state (ADC slave) */
+ SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+
+ /* If conversions on group regular are also triggering group injected, */
+ /* update ADC state. */
+ if (ADC_MULTIMODE_AUTO_INJECTED(hadc))
+ {
+ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
+ }
+ }
+
+ /* State machine update: Check if an injected conversion is ongoing */
+ if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY))
+ {
+ /* Reset ADC error code fields related to conversions on group regular */
+ CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA));
+ }
+ else
+ {
+ /* Reset ADC all error code fields */
+ ADC_CLEAR_ERRORCODE(hadc);
+ }
+
+ /* Process unlocked */
+ /* Unlock before starting ADC conversions: in case of potential */
+ /* interruption, to let the process to ADC IRQ Handler. */
+ __HAL_UNLOCK(hadc);
+
+ /* Clear regular group conversion flag */
+ /* (To ensure of no unknown state from potential previous ADC operations) */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC);
+
+ /* Enable conversion of regular group. */
+ /* If software start has been selected, conversion starts immediately. */
+ /* If external trigger has been selected, conversion will start at next */
+ /* trigger event. */
+ /* Case of multimode enabled: */
+ /* - if ADC is slave, ADC is enabled only (conversion is not started). */
+ /* - if ADC is master, ADC is enabled and conversion is started. */
+ /* If ADC is master, ADC is enabled and conversion is started. */
+ /* Note: Alternate trigger for single conversion could be to force an */
+ /* additional set of bit ADON "hadc->Instance->CR2 |= ADC_CR2_ADON;"*/
+ if (ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
+ ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc) )
+ {
+ /* Start ADC conversion on regular group with SW start */
+ SET_BIT(hadc->Instance->CR2, (ADC_CR2_SWSTART | ADC_CR2_EXTTRIG));
+ }
+ else
+ {
+ /* Start ADC conversion on regular group with external trigger */
+ SET_BIT(hadc->Instance->CR2, ADC_CR2_EXTTRIG);
+ }
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+ }
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Stop ADC conversion of regular group (and injected channels in
+ * case of auto_injection mode), disable ADC peripheral.
+ * @note: ADC peripheral disable is forcing stop of potential
+ * conversion on injected group. If injected group is under use, it
+ * should be preliminarily stopped using HAL_ADCEx_InjectedStop function.
+ * @param hadc: ADC handle
+ * @retval HAL status.
+ */
+HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Stop potential conversion on going, on regular and injected groups */
+ /* Disable ADC peripheral */
+ tmp_hal_status = ADC_ConversionStop_Disable(hadc);
+
+ /* Check if ADC is effectively disabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_READY);
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Wait for regular group conversion to be completed.
+ * @note This function cannot be used in a particular setup: ADC configured
+ * in DMA mode.
+ * In this case, DMA resets the flag EOC and polling cannot be
+ * performed on each conversion.
+ * @note On STM32F1 devices, limitation in case of sequencer enabled
+ * (several ranks selected): polling cannot be done on each
+ * conversion inside the sequence. In this case, polling is replaced by
+ * wait for maximum conversion time.
+ * @param hadc: ADC handle
+ * @param Timeout: Timeout value in millisecond.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)
+{
+ uint32_t tickstart = 0U;
+
+ /* Variables for polling in case of scan mode enabled and polling for each */
+ /* conversion. */
+ __IO uint32_t Conversion_Timeout_CPU_cycles = 0U;
+ uint32_t Conversion_Timeout_CPU_cycles_max = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Get tick count */
+ tickstart = HAL_GetTick();
+
+ /* Verification that ADC configuration is compliant with polling for */
+ /* each conversion: */
+ /* Particular case is ADC configured in DMA mode */
+ if (HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_DMA))
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_ERROR;
+ }
+
+ /* Polling for end of conversion: differentiation if single/sequence */
+ /* conversion. */
+ /* - If single conversion for regular group (Scan mode disabled or enabled */
+ /* with NbrOfConversion =1), flag EOC is used to determine the */
+ /* conversion completion. */
+ /* - If sequence conversion for regular group (scan mode enabled and */
+ /* NbrOfConversion >=2), flag EOC is set only at the end of the */
+ /* sequence. */
+ /* To poll for each conversion, the maximum conversion time is computed */
+ /* from ADC conversion time (selected sampling time + conversion time of */
+ /* 12.5 ADC clock cycles) and APB2/ADC clock prescalers (depending on */
+ /* settings, conversion time range can be from 28 to 32256 CPU cycles). */
+ /* As flag EOC is not set after each conversion, no timeout status can */
+ /* be set. */
+ if (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_SCAN) &&
+ HAL_IS_BIT_CLR(hadc->Instance->SQR1, ADC_SQR1_L) )
+ {
+ /* Wait until End of Conversion flag is raised */
+ while(HAL_IS_BIT_CLR(hadc->Instance->SR, ADC_FLAG_EOC))
+ {
+ /* Check if timeout is disabled (set to infinite wait) */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U) || ((HAL_GetTick() - tickstart ) > Timeout))
+ {
+ /* Update ADC state machine to timeout */
+ SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Replace polling by wait for maximum conversion time */
+ /* - Computation of CPU clock cycles corresponding to ADC clock cycles */
+ /* and ADC maximum conversion cycles on all channels. */
+ /* - Wait for the expected ADC clock cycles delay */
+ Conversion_Timeout_CPU_cycles_max = ((SystemCoreClock
+ / HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_ADC))
+ * ADC_CONVCYCLES_MAX_RANGE(hadc) );
+
+ while(Conversion_Timeout_CPU_cycles < Conversion_Timeout_CPU_cycles_max)
+ {
+ /* Check if timeout is disabled (set to infinite wait) */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
+ {
+ /* Update ADC state machine to timeout */
+ SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ Conversion_Timeout_CPU_cycles ++;
+ }
+ }
+
+ /* Clear regular group conversion flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_STRT | ADC_FLAG_EOC);
+
+ /* Update ADC state machine */
+ SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
+
+ /* Determine whether any further conversion upcoming on group regular */
+ /* by external trigger, continuous mode or scan sequence on going. */
+ /* Note: On STM32F1 devices, in case of sequencer enabled */
+ /* (several ranks selected), end of conversion flag is raised */
+ /* at the end of the sequence. */
+ if(ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
+ (hadc->Init.ContinuousConvMode == DISABLE) )
+ {
+ /* Set ADC state */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
+
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY))
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_READY);
+ }
+ }
+
+ /* Return ADC state */
+ return HAL_OK;
+}
+
+/**
+ * @brief Poll for conversion event.
+ * @param hadc: ADC handle
+ * @param EventType: the ADC event type.
+ * This parameter can be one of the following values:
+ * @arg ADC_AWD_EVENT: ADC Analog watchdog event.
+ * @param Timeout: Timeout value in millisecond.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventType, uint32_t Timeout)
+{
+ uint32_t tickstart = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_EVENT_TYPE(EventType));
+
+ /* Get tick count */
+ tickstart = HAL_GetTick();
+
+ /* Check selected event flag */
+ while(__HAL_ADC_GET_FLAG(hadc, EventType) == RESET)
+ {
+ /* Check if timeout is disabled (set to infinite wait) */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U) || ((HAL_GetTick() - tickstart ) > Timeout))
+ {
+ /* Update ADC state machine to timeout */
+ SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* Analog watchdog (level out of window) event */
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_AWD1);
+
+ /* Clear ADC analog watchdog flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD);
+
+ /* Return ADC state */
+ return HAL_OK;
+}
+
+/**
+ * @brief Enables ADC, starts conversion of regular group with interruption.
+ * Interruptions enabled in this function:
+ * - EOC (end of conversion of regular group)
+ * Each of these interruptions has its dedicated callback function.
+ * @param hadc: ADC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Enable the ADC peripheral */
+ tmp_hal_status = ADC_Enable(hadc);
+
+ /* Start conversion if ADC is effectively enabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ /* - Clear state bitfield related to regular group conversion results */
+ /* - Set state bitfield related to regular operation */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP,
+ HAL_ADC_STATE_REG_BUSY);
+
+ /* Set group injected state (from auto-injection) and multimode state */
+ /* for all cases of multimode: independent mode, multimode ADC master */
+ /* or multimode ADC slave (for devices with several ADCs): */
+ if (ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc))
+ {
+ /* Set ADC state (ADC independent or master) */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+
+ /* If conversions on group regular are also triggering group injected, */
+ /* update ADC state. */
+ if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET)
+ {
+ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
+ }
+ }
+ else
+ {
+ /* Set ADC state (ADC slave) */
+ SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+
+ /* If conversions on group regular are also triggering group injected, */
+ /* update ADC state. */
+ if (ADC_MULTIMODE_AUTO_INJECTED(hadc))
+ {
+ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
+ }
+ }
+
+ /* State machine update: Check if an injected conversion is ongoing */
+ if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY))
+ {
+ /* Reset ADC error code fields related to conversions on group regular */
+ CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA));
+ }
+ else
+ {
+ /* Reset ADC all error code fields */
+ ADC_CLEAR_ERRORCODE(hadc);
+ }
+
+ /* Process unlocked */
+ /* Unlock before starting ADC conversions: in case of potential */
+ /* interruption, to let the process to ADC IRQ Handler. */
+ __HAL_UNLOCK(hadc);
+
+ /* Clear regular group conversion flag and overrun flag */
+ /* (To ensure of no unknown state from potential previous ADC operations) */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC);
+
+ /* Enable end of conversion interrupt for regular group */
+ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_EOC);
+
+ /* Enable conversion of regular group. */
+ /* If software start has been selected, conversion starts immediately. */
+ /* If external trigger has been selected, conversion will start at next */
+ /* trigger event. */
+ /* Case of multimode enabled: */
+ /* - if ADC is slave, ADC is enabled only (conversion is not started). */
+ /* - if ADC is master, ADC is enabled and conversion is started. */
+ if (ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
+ ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc) )
+ {
+ /* Start ADC conversion on regular group with SW start */
+ SET_BIT(hadc->Instance->CR2, (ADC_CR2_SWSTART | ADC_CR2_EXTTRIG));
+ }
+ else
+ {
+ /* Start ADC conversion on regular group with external trigger */
+ SET_BIT(hadc->Instance->CR2, ADC_CR2_EXTTRIG);
+ }
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+ }
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Stop ADC conversion of regular group (and injected group in
+ * case of auto_injection mode), disable interrution of
+ * end-of-conversion, disable ADC peripheral.
+ * @param hadc: ADC handle
+ * @retval None
+ */
+HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Stop potential conversion on going, on regular and injected groups */
+ /* Disable ADC peripheral */
+ tmp_hal_status = ADC_ConversionStop_Disable(hadc);
+
+ /* Check if ADC is effectively disabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Disable ADC end of conversion interrupt for regular group */
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC);
+
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_READY);
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Enables ADC, starts conversion of regular group and transfers result
+ * through DMA.
+ * Interruptions enabled in this function:
+ * - DMA transfer complete
+ * - DMA half transfer
+ * Each of these interruptions has its dedicated callback function.
+ * @note For devices with several ADCs: This function is for single-ADC mode
+ * only. For multimode, use the dedicated MultimodeStart function.
+ * @note On STM32F1 devices, only ADC1 and ADC3 (ADC availability depending
+ * on devices) have DMA capability.
+ * ADC2 converted data can be transferred in dual ADC mode using DMA
+ * of ADC1 (ADC master in multimode).
+ * In case of using ADC1 with DMA on a device featuring 2 ADC
+ * instances: ADC1 conversion register DR contains ADC1 conversion
+ * result (ADC1 register DR bits 0 to 11) and, additionally, ADC2 last
+ * conversion result (ADC1 register DR bits 16 to 27). Therefore, to
+ * have DMA transferring the conversion results of ADC1 only, DMA must
+ * be configured to transfer size: half word.
+ * @param hadc: ADC handle
+ * @param pData: The destination Buffer address.
+ * @param Length: The length of data to be transferred from ADC peripheral to memory.
+ * @retval None
+ */
+HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_DMA_CAPABILITY_INSTANCE(hadc->Instance));
+
+ /* Verification if multimode is disabled (for devices with several ADC) */
+ /* If multimode is enabled, dedicated function multimode conversion */
+ /* start DMA must be used. */
+ if(ADC_MULTIMODE_IS_ENABLE(hadc) == RESET)
+ {
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Enable the ADC peripheral */
+ tmp_hal_status = ADC_Enable(hadc);
+
+ /* Start conversion if ADC is effectively enabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ /* - Clear state bitfield related to regular group conversion results */
+ /* - Set state bitfield related to regular operation */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP,
+ HAL_ADC_STATE_REG_BUSY);
+
+ /* Set group injected state (from auto-injection) and multimode state */
+ /* for all cases of multimode: independent mode, multimode ADC master */
+ /* or multimode ADC slave (for devices with several ADCs): */
+ if (ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc))
+ {
+ /* Set ADC state (ADC independent or master) */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+
+ /* If conversions on group regular are also triggering group injected, */
+ /* update ADC state. */
+ if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET)
+ {
+ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
+ }
+ }
+ else
+ {
+ /* Set ADC state (ADC slave) */
+ SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+
+ /* If conversions on group regular are also triggering group injected, */
+ /* update ADC state. */
+ if (ADC_MULTIMODE_AUTO_INJECTED(hadc))
+ {
+ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
+ }
+ }
+
+ /* State machine update: Check if an injected conversion is ongoing */
+ if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY))
+ {
+ /* Reset ADC error code fields related to conversions on group regular */
+ CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA));
+ }
+ else
+ {
+ /* Reset ADC all error code fields */
+ ADC_CLEAR_ERRORCODE(hadc);
+ }
+
+ /* Process unlocked */
+ /* Unlock before starting ADC conversions: in case of potential */
+ /* interruption, to let the process to ADC IRQ Handler. */
+ __HAL_UNLOCK(hadc);
+
+ /* Set the DMA transfer complete callback */
+ hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt;
+
+ /* Set the DMA half transfer complete callback */
+ hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt;
+
+ /* Set the DMA error callback */
+ hadc->DMA_Handle->XferErrorCallback = ADC_DMAError;
+
+
+ /* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC */
+ /* start (in case of SW start): */
+
+ /* Clear regular group conversion flag and overrun flag */
+ /* (To ensure of no unknown state from potential previous ADC */
+ /* operations) */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC);
+
+ /* Enable ADC DMA mode */
+ SET_BIT(hadc->Instance->CR2, ADC_CR2_DMA);
+
+ /* Start the DMA channel */
+ HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length);
+
+ /* Enable conversion of regular group. */
+ /* If software start has been selected, conversion starts immediately. */
+ /* If external trigger has been selected, conversion will start at next */
+ /* trigger event. */
+ if (ADC_IS_SOFTWARE_START_REGULAR(hadc))
+ {
+ /* Start ADC conversion on regular group with SW start */
+ SET_BIT(hadc->Instance->CR2, (ADC_CR2_SWSTART | ADC_CR2_EXTTRIG));
+ }
+ else
+ {
+ /* Start ADC conversion on regular group with external trigger */
+ SET_BIT(hadc->Instance->CR2, ADC_CR2_EXTTRIG);
+ }
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+ }
+ }
+ else
+ {
+ tmp_hal_status = HAL_ERROR;
+ }
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Stop ADC conversion of regular group (and injected group in
+ * case of auto_injection mode), disable ADC DMA transfer, disable
+ * ADC peripheral.
+ * @note: ADC peripheral disable is forcing stop of potential
+ * conversion on injected group. If injected group is under use, it
+ * should be preliminarily stopped using HAL_ADCEx_InjectedStop function.
+ * @note For devices with several ADCs: This function is for single-ADC mode
+ * only. For multimode, use the dedicated MultimodeStop function.
+ * @note On STM32F1 devices, only ADC1 and ADC3 (ADC availability depending
+ * on devices) have DMA capability.
+ * @param hadc: ADC handle
+ * @retval HAL status.
+ */
+HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_DMA_CAPABILITY_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Stop potential conversion on going, on regular and injected groups */
+ /* Disable ADC peripheral */
+ tmp_hal_status = ADC_ConversionStop_Disable(hadc);
+
+ /* Check if ADC is effectively disabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Disable ADC DMA mode */
+ CLEAR_BIT(hadc->Instance->CR2, ADC_CR2_DMA);
+
+ /* Disable the DMA channel (in case of DMA in circular mode or stop while */
+ /* DMA transfer is on going) */
+ tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
+
+ /* Check if DMA channel effectively disabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_READY);
+ }
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
+ }
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Get ADC regular group conversion result.
+ * @note Reading register DR automatically clears ADC flag EOC
+ * (ADC group regular end of unitary conversion).
+ * @note This function does not clear ADC flag EOS
+ * (ADC group regular end of sequence conversion).
+ * Occurrence of flag EOS rising:
+ * - If sequencer is composed of 1 rank, flag EOS is equivalent
+ * to flag EOC.
+ * - If sequencer is composed of several ranks, during the scan
+ * sequence flag EOC only is raised, at the end of the scan sequence
+ * both flags EOC and EOS are raised.
+ * To clear this flag, either use function:
+ * in programming model IT: @ref HAL_ADC_IRQHandler(), in programming
+ * model polling: @ref HAL_ADC_PollForConversion()
+ * or @ref __HAL_ADC_CLEAR_FLAG(&hadc, ADC_FLAG_EOS).
+ * @param hadc: ADC handle
+ * @retval ADC group regular conversion data
+ */
+uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Note: EOC flag is not cleared here by software because automatically */
+ /* cleared by hardware when reading register DR. */
+
+ /* Return ADC converted value */
+ return hadc->Instance->DR;
+}
+
+/**
+ * @brief Handles ADC interrupt request
+ * @param hadc: ADC handle
+ * @retval None
+ */
+void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+ assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
+ assert_param(IS_ADC_REGULAR_NB_CONV(hadc->Init.NbrOfConversion));
+
+
+ /* ========== Check End of Conversion flag for regular group ========== */
+ if(__HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_EOC))
+ {
+ if(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOC) )
+ {
+ /* Update state machine on conversion status if not in error state */
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL))
+ {
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
+ }
+
+ /* Determine whether any further conversion upcoming on group regular */
+ /* by external trigger, continuous mode or scan sequence on going. */
+ /* Note: On STM32F1 devices, in case of sequencer enabled */
+ /* (several ranks selected), end of conversion flag is raised */
+ /* at the end of the sequence. */
+ if(ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
+ (hadc->Init.ContinuousConvMode == DISABLE) )
+ {
+ /* Disable ADC end of conversion interrupt on group regular */
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC);
+
+ /* Set ADC state */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
+
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY))
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_READY);
+ }
+ }
+
+ /* Conversion complete callback */
+ HAL_ADC_ConvCpltCallback(hadc);
+
+ /* Clear regular group conversion flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_STRT | ADC_FLAG_EOC);
+ }
+ }
+
+ /* ========== Check End of Conversion flag for injected group ========== */
+ if(__HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_JEOC))
+ {
+ if(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOC))
+ {
+ /* Update state machine on conversion status if not in error state */
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL))
+ {
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC);
+ }
+
+ /* Determine whether any further conversion upcoming on group injected */
+ /* by external trigger, scan sequence on going or by automatic injected */
+ /* conversion from group regular (same conditions as group regular */
+ /* interruption disabling above). */
+ /* Note: On STM32F1 devices, in case of sequencer enabled */
+ /* (several ranks selected), end of conversion flag is raised */
+ /* at the end of the sequence. */
+ if(ADC_IS_SOFTWARE_START_INJECTED(hadc) ||
+ (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) &&
+ (ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
+ (hadc->Init.ContinuousConvMode == DISABLE) ) ) )
+ {
+ /* Disable ADC end of conversion interrupt on group injected */
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);
+
+ /* Set ADC state */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
+
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_READY);
+ }
+ }
+
+ /* Conversion complete callback */
+ HAL_ADCEx_InjectedConvCpltCallback(hadc);
+
+ /* Clear injected group conversion flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JSTRT | ADC_FLAG_JEOC));
+ }
+ }
+
+ /* ========== Check Analog watchdog flags ========== */
+ if(__HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_AWD))
+ {
+ if(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_AWD))
+ {
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_AWD1);
+
+ /* Level out of window callback */
+ HAL_ADC_LevelOutOfWindowCallback(hadc);
+
+ /* Clear the ADC analog watchdog flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD);
+ }
+ }
+
+}
+
+/**
+ * @brief Conversion complete callback in non blocking mode
+ * @param hadc: ADC handle
+ * @retval None
+ */
+__weak void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
+ /* NOTE : This function should not be modified. When the callback is needed,
+ function HAL_ADC_ConvCpltCallback must be implemented in the user file.
+ */
+}
+
+/**
+ * @brief Conversion DMA half-transfer callback in non blocking mode
+ * @param hadc: ADC handle
+ * @retval None
+ */
+__weak void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
+ /* NOTE : This function should not be modified. When the callback is needed,
+ function HAL_ADC_ConvHalfCpltCallback must be implemented in the user file.
+ */
+}
+
+/**
+ * @brief Analog watchdog callback in non blocking mode.
+ * @param hadc: ADC handle
+ * @retval None
+ */
+__weak void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
+ /* NOTE : This function should not be modified. When the callback is needed,
+ function HAL_ADC_LevelOutOfWindowCallback must be implemented in the user file.
+ */
+}
+
+/**
+ * @brief ADC error callback in non blocking mode
+ * (ADC conversion with interruption or transfer by DMA)
+ * @param hadc: ADC handle
+ * @retval None
+ */
+__weak void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
+ /* NOTE : This function should not be modified. When the callback is needed,
+ function HAL_ADC_ErrorCallback must be implemented in the user file.
+ */
+}
+
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Exported_Functions_Group3 Peripheral Control functions
+ * @brief Peripheral Control functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Configure channels on regular group
+ (+) Configure the analog watchdog
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the the selected channel to be linked to the regular
+ * group.
+ * @note In case of usage of internal measurement channels:
+ * Vbat/VrefInt/TempSensor.
+ * These internal paths can be be disabled using function
+ * HAL_ADC_DeInit().
+ * @note Possibility to update parameters on the fly:
+ * This function initializes channel into regular group, following
+ * calls to this function can be used to reconfigure some parameters
+ * of structure "ADC_ChannelConfTypeDef" on the fly, without reseting
+ * the ADC.
+ * The setting of these parameters is conditioned to ADC state.
+ * For parameters constraints, see comments of structure
+ * "ADC_ChannelConfTypeDef".
+ * @param hadc: ADC handle
+ * @param sConfig: Structure of ADC channel for regular group.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+ __IO uint32_t wait_loop_index = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_CHANNEL(sConfig->Channel));
+ assert_param(IS_ADC_REGULAR_RANK(sConfig->Rank));
+ assert_param(IS_ADC_SAMPLE_TIME(sConfig->SamplingTime));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+
+ /* Regular sequence configuration */
+ /* For Rank 1 to 6 */
+ if (sConfig->Rank < 7U)
+ {
+ MODIFY_REG(hadc->Instance->SQR3 ,
+ ADC_SQR3_RK(ADC_SQR3_SQ1, sConfig->Rank) ,
+ ADC_SQR3_RK(sConfig->Channel, sConfig->Rank) );
+ }
+ /* For Rank 7 to 12 */
+ else if (sConfig->Rank < 13U)
+ {
+ MODIFY_REG(hadc->Instance->SQR2 ,
+ ADC_SQR2_RK(ADC_SQR2_SQ7, sConfig->Rank) ,
+ ADC_SQR2_RK(sConfig->Channel, sConfig->Rank) );
+ }
+ /* For Rank 13 to 16 */
+ else
+ {
+ MODIFY_REG(hadc->Instance->SQR1 ,
+ ADC_SQR1_RK(ADC_SQR1_SQ13, sConfig->Rank) ,
+ ADC_SQR1_RK(sConfig->Channel, sConfig->Rank) );
+ }
+
+
+ /* Channel sampling time configuration */
+ /* For channels 10 to 17 */
+ if (sConfig->Channel >= ADC_CHANNEL_10)
+ {
+ MODIFY_REG(hadc->Instance->SMPR1 ,
+ ADC_SMPR1(ADC_SMPR1_SMP10, sConfig->Channel) ,
+ ADC_SMPR1(sConfig->SamplingTime, sConfig->Channel) );
+ }
+ else /* For channels 0 to 9 */
+ {
+ MODIFY_REG(hadc->Instance->SMPR2 ,
+ ADC_SMPR2(ADC_SMPR2_SMP0, sConfig->Channel) ,
+ ADC_SMPR2(sConfig->SamplingTime, sConfig->Channel) );
+ }
+
+ /* If ADC1 Channel_16 or Channel_17 is selected, enable Temperature sensor */
+ /* and VREFINT measurement path. */
+ if ((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) ||
+ (sConfig->Channel == ADC_CHANNEL_VREFINT) )
+ {
+ /* For STM32F1 devices with several ADC: Only ADC1 can access internal */
+ /* measurement channels (VrefInt/TempSensor). If these channels are */
+ /* intended to be set on other ADC instances, an error is reported. */
+ if (hadc->Instance == ADC1)
+ {
+ if (READ_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE) == RESET)
+ {
+ SET_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE);
+
+ if ((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR))
+ {
+ /* Delay for temperature sensor stabilization time */
+ /* Compute number of CPU cycles to wait for */
+ wait_loop_index = (ADC_TEMPSENSOR_DELAY_US * (SystemCoreClock / 1000000U));
+ while(wait_loop_index != 0U)
+ {
+ wait_loop_index--;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ tmp_hal_status = HAL_ERROR;
+ }
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Configures the analog watchdog.
+ * @note Analog watchdog thresholds can be modified while ADC conversion
+ * is on going.
+ * In this case, some constraints must be taken into account:
+ * the programmed threshold values are effective from the next
+ * ADC EOC (end of unitary conversion).
+ * Considering that registers write delay may happen due to
+ * bus activity, this might cause an uncertainty on the
+ * effective timing of the new programmed threshold values.
+ * @param hadc: ADC handle
+ * @param AnalogWDGConfig: Structure of ADC analog watchdog configuration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDGConfTypeDef* AnalogWDGConfig)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_ANALOG_WATCHDOG_MODE(AnalogWDGConfig->WatchdogMode));
+ assert_param(IS_FUNCTIONAL_STATE(AnalogWDGConfig->ITMode));
+ assert_param(IS_ADC_RANGE(AnalogWDGConfig->HighThreshold));
+ assert_param(IS_ADC_RANGE(AnalogWDGConfig->LowThreshold));
+
+ if((AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REG) ||
+ (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_INJEC) ||
+ (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC) )
+ {
+ assert_param(IS_ADC_CHANNEL(AnalogWDGConfig->Channel));
+ }
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Analog watchdog configuration */
+
+ /* Configure ADC Analog watchdog interrupt */
+ if(AnalogWDGConfig->ITMode == ENABLE)
+ {
+ /* Enable the ADC Analog watchdog interrupt */
+ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_AWD);
+ }
+ else
+ {
+ /* Disable the ADC Analog watchdog interrupt */
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_AWD);
+ }
+
+ /* Configuration of analog watchdog: */
+ /* - Set the analog watchdog enable mode: regular and/or injected groups, */
+ /* one or all channels. */
+ /* - Set the Analog watchdog channel (is not used if watchdog */
+ /* mode "all channels": ADC_CFGR_AWD1SGL=0). */
+ MODIFY_REG(hadc->Instance->CR1 ,
+ ADC_CR1_AWDSGL |
+ ADC_CR1_JAWDEN |
+ ADC_CR1_AWDEN |
+ ADC_CR1_AWDCH ,
+ AnalogWDGConfig->WatchdogMode |
+ AnalogWDGConfig->Channel );
+
+ /* Set the high threshold */
+ WRITE_REG(hadc->Instance->HTR, AnalogWDGConfig->HighThreshold);
+
+ /* Set the low threshold */
+ WRITE_REG(hadc->Instance->LTR, AnalogWDGConfig->LowThreshold);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_Exported_Functions_Group4 Peripheral State functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral State and Errors functions #####
+ ===============================================================================
+ [..]
+ This subsection provides functions to get in run-time the status of the
+ peripheral.
+ (+) Check the ADC state
+ (+) Check the ADC error code
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief return the ADC state
+ * @param hadc: ADC handle
+ * @retval HAL state
+ */
+uint32_t HAL_ADC_GetState(ADC_HandleTypeDef* hadc)
+{
+ /* Return ADC state */
+ return hadc->State;
+}
+
+/**
+ * @brief Return the ADC error code
+ * @param hadc: ADC handle
+ * @retval ADC Error Code
+ */
+uint32_t HAL_ADC_GetError(ADC_HandleTypeDef *hadc)
+{
+ return hadc->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Private_Functions ADC Private Functions
+ * @{
+ */
+
+/**
+ * @brief Enable the selected ADC.
+ * @note Prerequisite condition to use this function: ADC must be disabled
+ * and voltage regulator must be enabled (done into HAL_ADC_Init()).
+ * @param hadc: ADC handle
+ * @retval HAL status.
+ */
+HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef* hadc)
+{
+ uint32_t tickstart = 0U;
+ __IO uint32_t wait_loop_index = 0U;
+
+ /* ADC enable and wait for ADC ready (in case of ADC is disabled or */
+ /* enabling phase not yet completed: flag ADC ready not yet set). */
+ /* Timeout implemented to not be stuck if ADC cannot be enabled (possible */
+ /* causes: ADC clock not running, ...). */
+ if (ADC_IS_ENABLE(hadc) == RESET)
+ {
+ /* Enable the Peripheral */
+ __HAL_ADC_ENABLE(hadc);
+
+ /* Delay for ADC stabilization time */
+ /* Compute number of CPU cycles to wait for */
+ wait_loop_index = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000U));
+ while(wait_loop_index != 0U)
+ {
+ wait_loop_index--;
+ }
+
+ /* Get tick count */
+ tickstart = HAL_GetTick();
+
+ /* Wait for ADC effectively enabled */
+ while(ADC_IS_ENABLE(hadc) == RESET)
+ {
+ if((HAL_GetTick() - tickstart) > ADC_ENABLE_TIMEOUT)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Set ADC error code to ADC IP internal error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_ERROR;
+ }
+ }
+ }
+
+ /* Return HAL status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stop ADC conversion and disable the selected ADC
+ * @note Prerequisite condition to use this function: ADC conversions must be
+ * stopped to disable the ADC.
+ * @param hadc: ADC handle
+ * @retval HAL status.
+ */
+HAL_StatusTypeDef ADC_ConversionStop_Disable(ADC_HandleTypeDef* hadc)
+{
+ uint32_t tickstart = 0U;
+
+ /* Verification if ADC is not already disabled */
+ if (ADC_IS_ENABLE(hadc) != RESET)
+ {
+ /* Disable the ADC peripheral */
+ __HAL_ADC_DISABLE(hadc);
+
+ /* Get tick count */
+ tickstart = HAL_GetTick();
+
+ /* Wait for ADC effectively disabled */
+ while(ADC_IS_ENABLE(hadc) != RESET)
+ {
+ if((HAL_GetTick() - tickstart) > ADC_DISABLE_TIMEOUT)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Set ADC error code to ADC IP internal error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+
+ return HAL_ERROR;
+ }
+ }
+ }
+
+ /* Return HAL status */
+ return HAL_OK;
+}
+
+/**
+ * @brief DMA transfer complete callback.
+ * @param hdma: pointer to DMA handle.
+ * @retval None
+ */
+void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma)
+{
+ /* Retrieve ADC handle corresponding to current DMA handle */
+ ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ /* Update state machine on conversion status if not in error state */
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL | HAL_ADC_STATE_ERROR_DMA))
+ {
+ /* Update ADC state machine */
+ SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
+
+ /* Determine whether any further conversion upcoming on group regular */
+ /* by external trigger, continuous mode or scan sequence on going. */
+ /* Note: On STM32F1 devices, in case of sequencer enabled */
+ /* (several ranks selected), end of conversion flag is raised */
+ /* at the end of the sequence. */
+ if(ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
+ (hadc->Init.ContinuousConvMode == DISABLE) )
+ {
+ /* Set ADC state */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
+
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY))
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_READY);
+ }
+ }
+
+ /* Conversion complete callback */
+ HAL_ADC_ConvCpltCallback(hadc);
+ }
+ else
+ {
+ /* Call DMA error callback */
+ hadc->DMA_Handle->XferErrorCallback(hdma);
+ }
+}
+
+/**
+ * @brief DMA half transfer complete callback.
+ * @param hdma: pointer to DMA handle.
+ * @retval None
+ */
+void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma)
+{
+ /* Retrieve ADC handle corresponding to current DMA handle */
+ ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ /* Half conversion callback */
+ HAL_ADC_ConvHalfCpltCallback(hadc);
+}
+
+/**
+ * @brief DMA error callback
+ * @param hdma: pointer to DMA handle.
+ * @retval None
+ */
+void ADC_DMAError(DMA_HandleTypeDef *hdma)
+{
+ /* Retrieve ADC handle corresponding to current DMA handle */
+ ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
+
+ /* Set ADC error code to DMA error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_DMA);
+
+ /* Error callback */
+ HAL_ADC_ErrorCallback(hadc);
+}
+
+/**
+ * @}
+ */
+
+#endif /* HAL_ADC_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc_ex.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc_ex.c
new file mode 100644
index 0000000..2d539a2
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc_ex.c
@@ -0,0 +1,1339 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_adc_ex.c
+ * @author MCD Application Team
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Analog to Digital Convertor (ADC)
+ * peripheral:
+ * + Operation functions
+ * ++ Start, stop, get result of conversions of injected
+ * group, using 2 possible modes: polling, interruption.
+ * ++ Multimode feature (available on devices with 2 ADCs or more)
+ * ++ Calibration (ADC automatic self-calibration)
+ * + Control functions
+ * ++ Channels configuration on injected group
+ * Other functions (generic functions) are available in file
+ * "stm32f1xx_hal_adc.c".
+ *
+ @verbatim
+ [..]
+ (@) Sections "ADC peripheral features" and "How to use this driver" are
+ available in file of generic functions "stm32f1xx_hal_adc.c".
+ [..]
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup ADCEx ADCEx
+ * @brief ADC Extension HAL module driver
+ * @{
+ */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup ADCEx_Private_Constants ADCEx Private Constants
+ * @{
+ */
+
+ /* Delay for ADC calibration: */
+ /* Hardware prerequisite before starting a calibration: the ADC must have */
+ /* been in power-on state for at least two ADC clock cycles. */
+ /* Unit: ADC clock cycles */
+ #define ADC_PRECALIBRATION_DELAY_ADCCLOCKCYCLES 2U
+
+ /* Timeout value for ADC calibration */
+ /* Value defined to be higher than worst cases: low clocks freq, */
+ /* maximum prescaler. */
+ /* Ex of profile low frequency : Clock source at 0.1 MHz, ADC clock */
+ /* prescaler 4, sampling time 12.5 ADC clock cycles, resolution 12 bits. */
+ /* Unit: ms */
+ #define ADC_CALIBRATION_TIMEOUT 10U
+
+ /* Delay for temperature sensor stabilization time. */
+ /* Maximum delay is 10us (refer to device datasheet, parameter tSTART). */
+ /* Unit: us */
+ #define ADC_TEMPSENSOR_DELAY_US 10U
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup ADCEx_Exported_Functions ADCEx Exported Functions
+ * @{
+ */
+
+/** @defgroup ADCEx_Exported_Functions_Group1 Extended Extended IO operation functions
+ * @brief Extended Extended Input and Output operation functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Start conversion of injected group.
+ (+) Stop conversion of injected group.
+ (+) Poll for conversion complete on injected group.
+ (+) Get result of injected channel conversion.
+ (+) Start conversion of injected group and enable interruptions.
+ (+) Stop conversion of injected group and disable interruptions.
+
+ (+) Start multimode and enable DMA transfer.
+ (+) Stop multimode and disable ADC DMA transfer.
+ (+) Get result of multimode conversion.
+
+ (+) Perform the ADC self-calibration for single or differential ending.
+ (+) Get calibration factors for single or differential ending.
+ (+) Set calibration factors for single or differential ending.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Perform an ADC automatic self-calibration
+ * Calibration prerequisite: ADC must be disabled (execute this
+ * function before HAL_ADC_Start() or after HAL_ADC_Stop() ).
+ * During calibration process, ADC is enabled. ADC is let enabled at
+ * the completion of this function.
+ * @param hadc: ADC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+ uint32_t tickstart;
+ __IO uint32_t wait_loop_index = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* 1. Calibration prerequisite: */
+ /* - ADC must be disabled for at least two ADC clock cycles in disable */
+ /* mode before ADC enable */
+ /* Stop potential conversion on going, on regular and injected groups */
+ /* Disable ADC peripheral */
+ tmp_hal_status = ADC_ConversionStop_Disable(hadc);
+
+ /* Check if ADC is effectively disabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_BUSY_INTERNAL);
+
+ /* Hardware prerequisite: delay before starting the calibration. */
+ /* - Computation of CPU clock cycles corresponding to ADC clock cycles. */
+ /* - Wait for the expected ADC clock cycles delay */
+ wait_loop_index = ((SystemCoreClock
+ / HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_ADC))
+ * ADC_PRECALIBRATION_DELAY_ADCCLOCKCYCLES );
+
+ while(wait_loop_index != 0U)
+ {
+ wait_loop_index--;
+ }
+
+ /* 2. Enable the ADC peripheral */
+ ADC_Enable(hadc);
+
+ /* 3. Resets ADC calibration registers */
+ SET_BIT(hadc->Instance->CR2, ADC_CR2_RSTCAL);
+
+ tickstart = HAL_GetTick();
+
+ /* Wait for calibration reset completion */
+ while(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_RSTCAL))
+ {
+ if((HAL_GetTick() - tickstart) > ADC_CALIBRATION_TIMEOUT)
+ {
+ /* Update ADC state machine to error */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_BUSY_INTERNAL,
+ HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_ERROR;
+ }
+ }
+
+
+ /* 4. Start ADC calibration */
+ SET_BIT(hadc->Instance->CR2, ADC_CR2_CAL);
+
+ tickstart = HAL_GetTick();
+
+ /* Wait for calibration completion */
+ while(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_CAL))
+ {
+ if((HAL_GetTick() - tickstart) > ADC_CALIBRATION_TIMEOUT)
+ {
+ /* Update ADC state machine to error */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_BUSY_INTERNAL,
+ HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_ERROR;
+ }
+ }
+
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_BUSY_INTERNAL,
+ HAL_ADC_STATE_READY);
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Enables ADC, starts conversion of injected group.
+ * Interruptions enabled in this function: None.
+ * @param hadc: ADC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef* hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Enable the ADC peripheral */
+ tmp_hal_status = ADC_Enable(hadc);
+
+ /* Start conversion if ADC is effectively enabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ /* - Clear state bitfield related to injected group conversion results */
+ /* - Set state bitfield related to injected operation */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
+ HAL_ADC_STATE_INJ_BUSY);
+
+ /* Case of independent mode or multimode (for devices with several ADCs): */
+ /* Set multimode state. */
+ if (ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc))
+ {
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+ }
+ else
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+ }
+
+ /* Check if a regular conversion is ongoing */
+ /* Note: On this device, there is no ADC error code fields related to */
+ /* conversions on group injected only. In case of conversion on */
+ /* going on group regular, no error code is reset. */
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
+ {
+ /* Reset ADC all error code fields */
+ ADC_CLEAR_ERRORCODE(hadc);
+ }
+
+ /* Process unlocked */
+ /* Unlock before starting ADC conversions: in case of potential */
+ /* interruption, to let the process to ADC IRQ Handler. */
+ __HAL_UNLOCK(hadc);
+
+ /* Clear injected group conversion flag */
+ /* (To ensure of no unknown state from potential previous ADC operations) */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC);
+
+ /* Enable conversion of injected group. */
+ /* If software start has been selected, conversion starts immediately. */
+ /* If external trigger has been selected, conversion will start at next */
+ /* trigger event. */
+ /* If automatic injected conversion is enabled, conversion will start */
+ /* after next regular group conversion. */
+ /* Case of multimode enabled (for devices with several ADCs): if ADC is */
+ /* slave, ADC is enabled only (conversion is not started). If ADC is */
+ /* master, ADC is enabled and conversion is started. */
+ if (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO))
+ {
+ if (ADC_IS_SOFTWARE_START_INJECTED(hadc) &&
+ ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc) )
+ {
+ /* Start ADC conversion on injected group with SW start */
+ SET_BIT(hadc->Instance->CR2, (ADC_CR2_JSWSTART | ADC_CR2_JEXTTRIG));
+ }
+ else
+ {
+ /* Start ADC conversion on injected group with external trigger */
+ SET_BIT(hadc->Instance->CR2, ADC_CR2_JEXTTRIG);
+ }
+ }
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+ }
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Stop conversion of injected channels. Disable ADC peripheral if
+ * no regular conversion is on going.
+ * @note If ADC must be disabled and if conversion is on going on
+ * regular group, function HAL_ADC_Stop must be used to stop both
+ * injected and regular groups, and disable the ADC.
+ * @note If injected group mode auto-injection is enabled,
+ * function HAL_ADC_Stop must be used.
+ * @note In case of auto-injection mode, HAL_ADC_Stop must be used.
+ * @param hadc: ADC handle
+ * @retval None
+ */
+HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef* hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Stop potential conversion and disable ADC peripheral */
+ /* Conditioned to: */
+ /* - No conversion on the other group (regular group) is intended to */
+ /* continue (injected and regular groups stop conversion and ADC disable */
+ /* are common) */
+ /* - In case of auto-injection mode, HAL_ADC_Stop must be used. */
+ if(((hadc->State & HAL_ADC_STATE_REG_BUSY) == RESET) &&
+ HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) )
+ {
+ /* Stop potential conversion on going, on regular and injected groups */
+ /* Disable ADC peripheral */
+ tmp_hal_status = ADC_ConversionStop_Disable(hadc);
+
+ /* Check if ADC is effectively disabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_READY);
+ }
+ }
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ tmp_hal_status = HAL_ERROR;
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Wait for injected group conversion to be completed.
+ * @param hadc: ADC handle
+ * @param Timeout: Timeout value in millisecond.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)
+{
+ uint32_t tickstart;
+
+ /* Variables for polling in case of scan mode enabled and polling for each */
+ /* conversion. */
+ __IO uint32_t Conversion_Timeout_CPU_cycles = 0U;
+ uint32_t Conversion_Timeout_CPU_cycles_max = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Get timeout */
+ tickstart = HAL_GetTick();
+
+ /* Polling for end of conversion: differentiation if single/sequence */
+ /* conversion. */
+ /* For injected group, flag JEOC is set only at the end of the sequence, */
+ /* not for each conversion within the sequence. */
+ /* - If single conversion for injected group (scan mode disabled or */
+ /* InjectedNbrOfConversion ==1), flag JEOC is used to determine the */
+ /* conversion completion. */
+ /* - If sequence conversion for injected group (scan mode enabled and */
+ /* InjectedNbrOfConversion >=2), flag JEOC is set only at the end of the */
+ /* sequence. */
+ /* To poll for each conversion, the maximum conversion time is computed */
+ /* from ADC conversion time (selected sampling time + conversion time of */
+ /* 12.5 ADC clock cycles) and APB2/ADC clock prescalers (depending on */
+ /* settings, conversion time range can be from 28 to 32256 CPU cycles). */
+ /* As flag JEOC is not set after each conversion, no timeout status can */
+ /* be set. */
+ if ((hadc->Instance->JSQR & ADC_JSQR_JL) == RESET)
+ {
+ /* Wait until End of Conversion flag is raised */
+ while(HAL_IS_BIT_CLR(hadc->Instance->SR, ADC_FLAG_JEOC))
+ {
+ /* Check if timeout is disabled (set to infinite wait) */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U) || ((HAL_GetTick() - tickstart ) > Timeout))
+ {
+ /* Update ADC state machine to timeout */
+ SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Replace polling by wait for maximum conversion time */
+ /* - Computation of CPU clock cycles corresponding to ADC clock cycles */
+ /* and ADC maximum conversion cycles on all channels. */
+ /* - Wait for the expected ADC clock cycles delay */
+ Conversion_Timeout_CPU_cycles_max = ((SystemCoreClock
+ / HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_ADC))
+ * ADC_CONVCYCLES_MAX_RANGE(hadc) );
+
+ while(Conversion_Timeout_CPU_cycles < Conversion_Timeout_CPU_cycles_max)
+ {
+ /* Check if timeout is disabled (set to infinite wait) */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
+ {
+ /* Update ADC state machine to timeout */
+ SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ Conversion_Timeout_CPU_cycles ++;
+ }
+ }
+
+ /* Clear injected group conversion flag */
+ /* Note: On STM32F1 ADC, clear regular conversion flag raised */
+ /* simultaneously. */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JSTRT | ADC_FLAG_JEOC | ADC_FLAG_EOC);
+
+ /* Update ADC state machine */
+ SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC);
+
+ /* Determine whether any further conversion upcoming on group injected */
+ /* by external trigger or by automatic injected conversion */
+ /* from group regular. */
+ if(ADC_IS_SOFTWARE_START_INJECTED(hadc) ||
+ (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) &&
+ (ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
+ (hadc->Init.ContinuousConvMode == DISABLE) ) ) )
+ {
+ /* Set ADC state */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
+
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_READY);
+ }
+ }
+
+ /* Return ADC state */
+ return HAL_OK;
+}
+
+/**
+ * @brief Enables ADC, starts conversion of injected group with interruption.
+ * - JEOC (end of conversion of injected group)
+ * Each of these interruptions has its dedicated callback function.
+ * @param hadc: ADC handle
+ * @retval HAL status.
+ */
+HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef* hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Enable the ADC peripheral */
+ tmp_hal_status = ADC_Enable(hadc);
+
+ /* Start conversion if ADC is effectively enabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ /* - Clear state bitfield related to injected group conversion results */
+ /* - Set state bitfield related to injected operation */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
+ HAL_ADC_STATE_INJ_BUSY);
+
+ /* Case of independent mode or multimode (for devices with several ADCs): */
+ /* Set multimode state. */
+ if (ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc))
+ {
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+ }
+ else
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+ }
+
+ /* Check if a regular conversion is ongoing */
+ /* Note: On this device, there is no ADC error code fields related to */
+ /* conversions on group injected only. In case of conversion on */
+ /* going on group regular, no error code is reset. */
+ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
+ {
+ /* Reset ADC all error code fields */
+ ADC_CLEAR_ERRORCODE(hadc);
+ }
+
+ /* Process unlocked */
+ /* Unlock before starting ADC conversions: in case of potential */
+ /* interruption, to let the process to ADC IRQ Handler. */
+ __HAL_UNLOCK(hadc);
+
+ /* Clear injected group conversion flag */
+ /* (To ensure of no unknown state from potential previous ADC operations) */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC);
+
+ /* Enable end of conversion interrupt for injected channels */
+ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
+
+ /* Start conversion of injected group if software start has been selected */
+ /* and if automatic injected conversion is disabled. */
+ /* If external trigger has been selected, conversion will start at next */
+ /* trigger event. */
+ /* If automatic injected conversion is enabled, conversion will start */
+ /* after next regular group conversion. */
+ if (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO))
+ {
+ if (ADC_IS_SOFTWARE_START_INJECTED(hadc) &&
+ ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc) )
+ {
+ /* Start ADC conversion on injected group with SW start */
+ SET_BIT(hadc->Instance->CR2, (ADC_CR2_JSWSTART | ADC_CR2_JEXTTRIG));
+ }
+ else
+ {
+ /* Start ADC conversion on injected group with external trigger */
+ SET_BIT(hadc->Instance->CR2, ADC_CR2_JEXTTRIG);
+ }
+ }
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+ }
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Stop conversion of injected channels, disable interruption of
+ * end-of-conversion. Disable ADC peripheral if no regular conversion
+ * is on going.
+ * @note If ADC must be disabled and if conversion is on going on
+ * regular group, function HAL_ADC_Stop must be used to stop both
+ * injected and regular groups, and disable the ADC.
+ * @note If injected group mode auto-injection is enabled,
+ * function HAL_ADC_Stop must be used.
+ * @param hadc: ADC handle
+ * @retval None
+ */
+HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef* hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Stop potential conversion and disable ADC peripheral */
+ /* Conditioned to: */
+ /* - No conversion on the other group (regular group) is intended to */
+ /* continue (injected and regular groups stop conversion and ADC disable */
+ /* are common) */
+ /* - In case of auto-injection mode, HAL_ADC_Stop must be used. */
+ if(((hadc->State & HAL_ADC_STATE_REG_BUSY) == RESET) &&
+ HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) )
+ {
+ /* Stop potential conversion on going, on regular and injected groups */
+ /* Disable ADC peripheral */
+ tmp_hal_status = ADC_ConversionStop_Disable(hadc);
+
+ /* Check if ADC is effectively disabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Disable ADC end of conversion interrupt for injected channels */
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);
+
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_READY);
+ }
+ }
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ tmp_hal_status = HAL_ERROR;
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
+/**
+ * @brief Enables ADC, starts conversion of regular group and transfers result
+ * through DMA.
+ * Multimode must have been previously configured using
+ * HAL_ADCEx_MultiModeConfigChannel() function.
+ * Interruptions enabled in this function:
+ * - DMA transfer complete
+ * - DMA half transfer
+ * Each of these interruptions has its dedicated callback function.
+ * @note: On STM32F1 devices, ADC slave regular group must be configured
+ * with conversion trigger ADC_SOFTWARE_START.
+ * @note: ADC slave can be enabled preliminarily using single-mode
+ * HAL_ADC_Start() function.
+ * @param hadc: ADC handle of ADC master (handle of ADC slave must not be used)
+ * @param pData: The destination Buffer address.
+ * @param Length: The length of data to be transferred from ADC peripheral to memory.
+ * @retval None
+ */
+HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+ ADC_HandleTypeDef tmphadcSlave;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance));
+ assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Set a temporary handle of the ADC slave associated to the ADC master */
+ ADC_MULTI_SLAVE(hadc, &tmphadcSlave);
+
+ /* On STM32F1 devices, ADC slave regular group must be configured with */
+ /* conversion trigger ADC_SOFTWARE_START. */
+ /* Note: External trigger of ADC slave must be enabled, it is already done */
+ /* into function "HAL_ADC_Init()". */
+ if(!ADC_IS_SOFTWARE_START_REGULAR(&tmphadcSlave))
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_ERROR;
+ }
+
+ /* Enable the ADC peripherals: master and slave (in case if not already */
+ /* enabled previously) */
+ tmp_hal_status = ADC_Enable(hadc);
+ if (tmp_hal_status == HAL_OK)
+ {
+ tmp_hal_status = ADC_Enable(&tmphadcSlave);
+ }
+
+ /* Start conversion if all ADCs of multimode are effectively enabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state (ADC master) */
+ /* - Clear state bitfield related to regular group conversion results */
+ /* - Set state bitfield related to regular operation */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_MULTIMODE_SLAVE,
+ HAL_ADC_STATE_REG_BUSY);
+
+ /* If conversions on group regular are also triggering group injected, */
+ /* update ADC state. */
+ if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET)
+ {
+ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
+ }
+
+ /* Process unlocked */
+ /* Unlock before starting ADC conversions: in case of potential */
+ /* interruption, to let the process to ADC IRQ Handler. */
+ __HAL_UNLOCK(hadc);
+
+ /* Set ADC error code to none */
+ ADC_CLEAR_ERRORCODE(hadc);
+
+
+ /* Set the DMA transfer complete callback */
+ hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt;
+
+ /* Set the DMA half transfer complete callback */
+ hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt;
+
+ /* Set the DMA error callback */
+ hadc->DMA_Handle->XferErrorCallback = ADC_DMAError;
+
+
+ /* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC */
+ /* start (in case of SW start): */
+
+ /* Clear regular group conversion flag and overrun flag */
+ /* (To ensure of no unknown state from potential previous ADC operations) */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC);
+
+ /* Enable ADC DMA mode of ADC master */
+ SET_BIT(hadc->Instance->CR2, ADC_CR2_DMA);
+
+ /* Start the DMA channel */
+ HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length);
+
+ /* Start conversion of regular group if software start has been selected. */
+ /* If external trigger has been selected, conversion will start at next */
+ /* trigger event. */
+ /* Note: Alternate trigger for single conversion could be to force an */
+ /* additional set of bit ADON "hadc->Instance->CR2 |= ADC_CR2_ADON;"*/
+ if (ADC_IS_SOFTWARE_START_REGULAR(hadc))
+ {
+ /* Start ADC conversion on regular group with SW start */
+ SET_BIT(hadc->Instance->CR2, (ADC_CR2_SWSTART | ADC_CR2_EXTTRIG));
+ }
+ else
+ {
+ /* Start ADC conversion on regular group with external trigger */
+ SET_BIT(hadc->Instance->CR2, ADC_CR2_EXTTRIG);
+ }
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+ }
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Stop ADC conversion of regular group (and injected channels in
+ * case of auto_injection mode), disable ADC DMA transfer, disable
+ * ADC peripheral.
+ * @note Multimode is kept enabled after this function. To disable multimode
+ * (set with HAL_ADCEx_MultiModeConfigChannel(), ADC must be
+ * reinitialized using HAL_ADC_Init() or HAL_ADC_ReInit().
+ * @note In case of DMA configured in circular mode, function
+ * HAL_ADC_Stop_DMA must be called after this function with handle of
+ * ADC slave, to properly disable the DMA channel.
+ * @param hadc: ADC handle of ADC master (handle of ADC slave must not be used)
+ * @retval None
+ */
+HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef* hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+ ADC_HandleTypeDef tmphadcSlave;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+
+ /* Stop potential conversion on going, on regular and injected groups */
+ /* Disable ADC master peripheral */
+ tmp_hal_status = ADC_ConversionStop_Disable(hadc);
+
+ /* Check if ADC is effectively disabled */
+ if(tmp_hal_status == HAL_OK)
+ {
+ /* Set a temporary handle of the ADC slave associated to the ADC master */
+ ADC_MULTI_SLAVE(hadc, &tmphadcSlave);
+
+ /* Disable ADC slave peripheral */
+ tmp_hal_status = ADC_ConversionStop_Disable(&tmphadcSlave);
+
+ /* Check if ADC is effectively disabled */
+ if(tmp_hal_status != HAL_OK)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_ERROR;
+ }
+
+ /* Disable ADC DMA mode */
+ CLEAR_BIT(hadc->Instance->CR2, ADC_CR2_DMA);
+
+ /* Reset configuration of ADC DMA continuous request for dual mode */
+ CLEAR_BIT(hadc->Instance->CR1, ADC_CR1_DUALMOD);
+
+ /* Disable the DMA channel (in case of DMA in circular mode or stop while */
+ /* while DMA transfer is on going) */
+ tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
+
+ /* Change ADC state (ADC master) */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_READY);
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
+
+/**
+ * @brief Get ADC injected group conversion result.
+ * @note Reading register JDRx automatically clears ADC flag JEOC
+ * (ADC group injected end of unitary conversion).
+ * @note This function does not clear ADC flag JEOS
+ * (ADC group injected end of sequence conversion)
+ * Occurrence of flag JEOS rising:
+ * - If sequencer is composed of 1 rank, flag JEOS is equivalent
+ * to flag JEOC.
+ * - If sequencer is composed of several ranks, during the scan
+ * sequence flag JEOC only is raised, at the end of the scan sequence
+ * both flags JEOC and EOS are raised.
+ * Flag JEOS must not be cleared by this function because
+ * it would not be compliant with low power features
+ * (feature low power auto-wait, not available on all STM32 families).
+ * To clear this flag, either use function:
+ * in programming model IT: @ref HAL_ADC_IRQHandler(), in programming
+ * model polling: @ref HAL_ADCEx_InjectedPollForConversion()
+ * or @ref __HAL_ADC_CLEAR_FLAG(&hadc, ADC_FLAG_JEOS).
+ * @param hadc: ADC handle
+ * @param InjectedRank: the converted ADC injected rank.
+ * This parameter can be one of the following values:
+ * @arg ADC_INJECTED_RANK_1: Injected Channel1 selected
+ * @arg ADC_INJECTED_RANK_2: Injected Channel2 selected
+ * @arg ADC_INJECTED_RANK_3: Injected Channel3 selected
+ * @arg ADC_INJECTED_RANK_4: Injected Channel4 selected
+ * @retval ADC group injected conversion data
+ */
+uint32_t HAL_ADCEx_InjectedGetValue(ADC_HandleTypeDef* hadc, uint32_t InjectedRank)
+{
+ uint32_t tmp_jdr = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_INJECTED_RANK(InjectedRank));
+
+ /* Get ADC converted value */
+ switch(InjectedRank)
+ {
+ case ADC_INJECTED_RANK_4:
+ tmp_jdr = hadc->Instance->JDR4;
+ break;
+ case ADC_INJECTED_RANK_3:
+ tmp_jdr = hadc->Instance->JDR3;
+ break;
+ case ADC_INJECTED_RANK_2:
+ tmp_jdr = hadc->Instance->JDR2;
+ break;
+ case ADC_INJECTED_RANK_1:
+ default:
+ tmp_jdr = hadc->Instance->JDR1;
+ break;
+ }
+
+ /* Return ADC converted value */
+ return tmp_jdr;
+}
+
+#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
+/**
+ * @brief Returns the last ADC Master&Slave regular conversions results data
+ * in the selected multi mode.
+ * @param hadc: ADC handle of ADC master (handle of ADC slave must not be used)
+ * @retval The converted data value.
+ */
+uint32_t HAL_ADCEx_MultiModeGetValue(ADC_HandleTypeDef* hadc)
+{
+ uint32_t tmpDR = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance));
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Note: EOC flag is not cleared here by software because automatically */
+ /* cleared by hardware when reading register DR. */
+
+ /* On STM32F1 devices, ADC1 data register DR contains ADC2 conversions */
+ /* only if ADC1 DMA mode is enabled. */
+ tmpDR = hadc->Instance->DR;
+
+ if (HAL_IS_BIT_CLR(ADC1->CR2, ADC_CR2_DMA))
+ {
+ tmpDR |= (ADC2->DR << 16U);
+ }
+
+ /* Return ADC converted value */
+ return tmpDR;
+}
+#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
+
+/**
+ * @brief Injected conversion complete callback in non blocking mode
+ * @param hadc: ADC handle
+ * @retval None
+ */
+__weak void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_ADCEx_InjectedConvCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup ADCEx_Exported_Functions_Group2 Extended Peripheral Control functions
+ * @brief Extended Peripheral Control functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Configure channels on injected group
+ (+) Configure multimode
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the ADC injected group and the selected channel to be
+ * linked to the injected group.
+ * @note Possibility to update parameters on the fly:
+ * This function initializes injected group, following calls to this
+ * function can be used to reconfigure some parameters of structure
+ * "ADC_InjectionConfTypeDef" on the fly, without reseting the ADC.
+ * The setting of these parameters is conditioned to ADC state:
+ * this function must be called when ADC is not under conversion.
+ * @param hadc: ADC handle
+ * @param sConfigInjected: Structure of ADC injected group and ADC channel for
+ * injected group.
+ * @retval None
+ */
+HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc, ADC_InjectionConfTypeDef* sConfigInjected)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+ __IO uint32_t wait_loop_index = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_CHANNEL(sConfigInjected->InjectedChannel));
+ assert_param(IS_ADC_SAMPLE_TIME(sConfigInjected->InjectedSamplingTime));
+ assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->AutoInjectedConv));
+ assert_param(IS_ADC_EXTTRIGINJEC(sConfigInjected->ExternalTrigInjecConv));
+ assert_param(IS_ADC_RANGE(sConfigInjected->InjectedOffset));
+
+ if(hadc->Init.ScanConvMode != ADC_SCAN_DISABLE)
+ {
+ assert_param(IS_ADC_INJECTED_RANK(sConfigInjected->InjectedRank));
+ assert_param(IS_ADC_INJECTED_NB_CONV(sConfigInjected->InjectedNbrOfConversion));
+ assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjectedDiscontinuousConvMode));
+ }
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Configuration of injected group sequencer: */
+ /* - if scan mode is disabled, injected channels sequence length is set to */
+ /* 0x00: 1 channel converted (channel on regular rank 1) */
+ /* Parameter "InjectedNbrOfConversion" is discarded. */
+ /* Note: Scan mode is present by hardware on this device and, if */
+ /* disabled, discards automatically nb of conversions. Anyway, nb of */
+ /* conversions is forced to 0x00 for alignment over all STM32 devices. */
+ /* - if scan mode is enabled, injected channels sequence length is set to */
+ /* parameter "InjectedNbrOfConversion". */
+ if (hadc->Init.ScanConvMode == ADC_SCAN_DISABLE)
+ {
+ if (sConfigInjected->InjectedRank == ADC_INJECTED_RANK_1)
+ {
+ /* Clear the old SQx bits for all injected ranks */
+ MODIFY_REG(hadc->Instance->JSQR ,
+ ADC_JSQR_JL |
+ ADC_JSQR_JSQ4 |
+ ADC_JSQR_JSQ3 |
+ ADC_JSQR_JSQ2 |
+ ADC_JSQR_JSQ1 ,
+ ADC_JSQR_RK_JL(sConfigInjected->InjectedChannel,
+ ADC_INJECTED_RANK_1,
+ 0x01U));
+ }
+ /* If another injected rank than rank1 was intended to be set, and could */
+ /* not due to ScanConvMode disabled, error is reported. */
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ tmp_hal_status = HAL_ERROR;
+ }
+ }
+ else
+ {
+ /* Since injected channels rank conv. order depends on total number of */
+ /* injected conversions, selected rank must be below or equal to total */
+ /* number of injected conversions to be updated. */
+ if (sConfigInjected->InjectedRank <= sConfigInjected->InjectedNbrOfConversion)
+ {
+ /* Clear the old SQx bits for the selected rank */
+ /* Set the SQx bits for the selected rank */
+ MODIFY_REG(hadc->Instance->JSQR ,
+
+ ADC_JSQR_JL |
+ ADC_JSQR_RK_JL(ADC_JSQR_JSQ1,
+ sConfigInjected->InjectedRank,
+ sConfigInjected->InjectedNbrOfConversion) ,
+
+ ADC_JSQR_JL_SHIFT(sConfigInjected->InjectedNbrOfConversion) |
+ ADC_JSQR_RK_JL(sConfigInjected->InjectedChannel,
+ sConfigInjected->InjectedRank,
+ sConfigInjected->InjectedNbrOfConversion) );
+ }
+ else
+ {
+ /* Clear the old SQx bits for the selected rank */
+ MODIFY_REG(hadc->Instance->JSQR ,
+
+ ADC_JSQR_JL |
+ ADC_JSQR_RK_JL(ADC_JSQR_JSQ1,
+ sConfigInjected->InjectedRank,
+ sConfigInjected->InjectedNbrOfConversion) ,
+
+ 0x00000000U);
+ }
+ }
+
+ /* Configuration of injected group */
+ /* Parameters update conditioned to ADC state: */
+ /* Parameters that can be updated only when ADC is disabled: */
+ /* - external trigger to start conversion */
+ /* Parameters update not conditioned to ADC state: */
+ /* - Automatic injected conversion */
+ /* - Injected discontinuous mode */
+ /* Note: In case of ADC already enabled, caution to not launch an unwanted */
+ /* conversion while modifying register CR2 by writing 1 to bit ADON. */
+ if (ADC_IS_ENABLE(hadc) == RESET)
+ {
+ MODIFY_REG(hadc->Instance->CR2 ,
+ ADC_CR2_JEXTSEL |
+ ADC_CR2_ADON ,
+ ADC_CFGR_JEXTSEL(hadc, sConfigInjected->ExternalTrigInjecConv) );
+ }
+
+
+ /* Configuration of injected group */
+ /* - Automatic injected conversion */
+ /* - Injected discontinuous mode */
+
+ /* Automatic injected conversion can be enabled if injected group */
+ /* external triggers are disabled. */
+ if (sConfigInjected->AutoInjectedConv == ENABLE)
+ {
+ if (sConfigInjected->ExternalTrigInjecConv == ADC_INJECTED_SOFTWARE_START)
+ {
+ SET_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO);
+ }
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ tmp_hal_status = HAL_ERROR;
+ }
+ }
+
+ /* Injected discontinuous can be enabled only if auto-injected mode is */
+ /* disabled. */
+ if (sConfigInjected->InjectedDiscontinuousConvMode == ENABLE)
+ {
+ if (sConfigInjected->AutoInjectedConv == DISABLE)
+ {
+ SET_BIT(hadc->Instance->CR1, ADC_CR1_JDISCEN);
+ }
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ tmp_hal_status = HAL_ERROR;
+ }
+ }
+
+
+ /* InjectedChannel sampling time configuration */
+ /* For channels 10 to 17 */
+ if (sConfigInjected->InjectedChannel >= ADC_CHANNEL_10)
+ {
+ MODIFY_REG(hadc->Instance->SMPR1 ,
+ ADC_SMPR1(ADC_SMPR1_SMP10, sConfigInjected->InjectedChannel) ,
+ ADC_SMPR1(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel) );
+ }
+ else /* For channels 0 to 9 */
+ {
+ MODIFY_REG(hadc->Instance->SMPR2 ,
+ ADC_SMPR2(ADC_SMPR2_SMP0, sConfigInjected->InjectedChannel) ,
+ ADC_SMPR2(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel) );
+ }
+
+ /* If ADC1 InjectedChannel_16 or InjectedChannel_17 is selected, enable Temperature sensor */
+ /* and VREFINT measurement path. */
+ if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) ||
+ (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT) )
+ {
+ SET_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE);
+ }
+
+
+ /* Configure the offset: offset enable/disable, InjectedChannel, offset value */
+ switch(sConfigInjected->InjectedRank)
+ {
+ case 1:
+ /* Set injected channel 1 offset */
+ MODIFY_REG(hadc->Instance->JOFR1,
+ ADC_JOFR1_JOFFSET1,
+ sConfigInjected->InjectedOffset);
+ break;
+ case 2:
+ /* Set injected channel 2 offset */
+ MODIFY_REG(hadc->Instance->JOFR2,
+ ADC_JOFR2_JOFFSET2,
+ sConfigInjected->InjectedOffset);
+ break;
+ case 3:
+ /* Set injected channel 3 offset */
+ MODIFY_REG(hadc->Instance->JOFR3,
+ ADC_JOFR3_JOFFSET3,
+ sConfigInjected->InjectedOffset);
+ break;
+ case 4:
+ default:
+ MODIFY_REG(hadc->Instance->JOFR4,
+ ADC_JOFR4_JOFFSET4,
+ sConfigInjected->InjectedOffset);
+ break;
+ }
+
+ /* If ADC1 Channel_16 or Channel_17 is selected, enable Temperature sensor */
+ /* and VREFINT measurement path. */
+ if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) ||
+ (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT) )
+ {
+ /* For STM32F1 devices with several ADC: Only ADC1 can access internal */
+ /* measurement channels (VrefInt/TempSensor). If these channels are */
+ /* intended to be set on other ADC instances, an error is reported. */
+ if (hadc->Instance == ADC1)
+ {
+ if (READ_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE) == RESET)
+ {
+ SET_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE);
+
+ if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR))
+ {
+ /* Delay for temperature sensor stabilization time */
+ /* Compute number of CPU cycles to wait for */
+ wait_loop_index = (ADC_TEMPSENSOR_DELAY_US * (SystemCoreClock / 1000000U));
+ while(wait_loop_index != 0U)
+ {
+ wait_loop_index--;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ tmp_hal_status = HAL_ERROR;
+ }
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
+/**
+ * @brief Enable ADC multimode and configure multimode parameters
+ * @note Possibility to update parameters on the fly:
+ * This function initializes multimode parameters, following
+ * calls to this function can be used to reconfigure some parameters
+ * of structure "ADC_MultiModeTypeDef" on the fly, without reseting
+ * the ADCs (both ADCs of the common group).
+ * The setting of these parameters is conditioned to ADC state.
+ * For parameters constraints, see comments of structure
+ * "ADC_MultiModeTypeDef".
+ * @note To change back configuration from multimode to single mode, ADC must
+ * be reset (using function HAL_ADC_Init() ).
+ * @param hadc: ADC handle
+ * @param multimode: Structure of ADC multimode configuration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef* hadc, ADC_MultiModeTypeDef* multimode)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+ ADC_HandleTypeDef tmphadcSlave;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_MODE(multimode->Mode));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Set a temporary handle of the ADC slave associated to the ADC master */
+ ADC_MULTI_SLAVE(hadc, &tmphadcSlave);
+
+ /* Parameters update conditioned to ADC state: */
+ /* Parameters that can be updated when ADC is disabled or enabled without */
+ /* conversion on going on regular group: */
+ /* - ADC master and ADC slave DMA configuration */
+ /* Parameters that can be updated only when ADC is disabled: */
+ /* - Multimode mode selection */
+ /* To optimize code, all multimode settings can be set when both ADCs of */
+ /* the common group are in state: disabled. */
+ if ((ADC_IS_ENABLE(hadc) == RESET) &&
+ (ADC_IS_ENABLE(&tmphadcSlave) == RESET) &&
+ (IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance)) )
+ {
+ MODIFY_REG(hadc->Instance->CR1,
+ ADC_CR1_DUALMOD ,
+ multimode->Mode );
+ }
+ /* If one of the ADC sharing the same common group is enabled, no update */
+ /* could be done on neither of the multimode structure parameters. */
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ tmp_hal_status = HAL_ERROR;
+ }
+
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_ADC_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_can.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_can.c
new file mode 100644
index 0000000..7b1b92f
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_can.c
@@ -0,0 +1,2001 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_can.c
+ * @author MCD Application Team
+ * @brief CAN HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Controller Area Network (CAN) peripheral:
+ * + Initialization and de-initialization functions
+ * + Configuration functions
+ * + Control functions
+ * + Interrupts management
+ * + Callbacks functions
+ * + Peripheral State and Error functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) Initialize the CAN low level resources by implementing the
+ HAL_CAN_MspInit():
+ (++) Enable the CAN interface clock using __HAL_RCC_CANx_CLK_ENABLE()
+ (++) Configure CAN pins
+ (+++) Enable the clock for the CAN GPIOs
+ (+++) Configure CAN pins as alternate function open-drain
+ (++) In case of using interrupts (e.g. HAL_CAN_ActivateNotification())
+ (+++) Configure the CAN interrupt priority using
+ HAL_NVIC_SetPriority()
+ (+++) Enable the CAN IRQ handler using HAL_NVIC_EnableIRQ()
+ (+++) In CAN IRQ handler, call HAL_CAN_IRQHandler()
+
+ (#) Initialize the CAN peripheral using HAL_CAN_Init() function. This
+ function resorts to HAL_CAN_MspInit() for low-level initialization.
+
+ (#) Configure the reception filters using the following configuration
+ functions:
+ (++) HAL_CAN_ConfigFilter()
+
+ (#) Start the CAN module using HAL_CAN_Start() function. At this level
+ the node is active on the bus: it receive messages, and can send
+ messages.
+
+ (#) To manage messages transmission, the following Tx control functions
+ can be used:
+ (++) HAL_CAN_AddTxMessage() to request transmission of a new
+ message.
+ (++) HAL_CAN_AbortTxRequest() to abort transmission of a pending
+ message.
+ (++) HAL_CAN_GetTxMailboxesFreeLevel() to get the number of free Tx
+ mailboxes.
+ (++) HAL_CAN_IsTxMessagePending() to check if a message is pending
+ in a Tx mailbox.
+ (++) HAL_CAN_GetTxTimestamp() to get the timestamp of Tx message
+ sent, if time triggered communication mode is enabled.
+
+ (#) When a message is received into the CAN Rx FIFOs, it can be retrieved
+ using the HAL_CAN_GetRxMessage() function. The function
+ HAL_CAN_GetRxFifoFillLevel() allows to know how many Rx message are
+ stored in the Rx Fifo.
+
+ (#) Calling the HAL_CAN_Stop() function stops the CAN module.
+
+ (#) The deinitialization is achieved with HAL_CAN_DeInit() function.
+
+
+ *** Polling mode operation ***
+ ==============================
+ [..]
+ (#) Reception:
+ (++) Monitor reception of message using HAL_CAN_GetRxFifoFillLevel()
+ until at least one message is received.
+ (++) Then get the message using HAL_CAN_GetRxMessage().
+
+ (#) Transmission:
+ (++) Monitor the Tx mailboxes availability until at least one Tx
+ mailbox is free, using HAL_CAN_GetTxMailboxesFreeLevel().
+ (++) Then request transmission of a message using
+ HAL_CAN_AddTxMessage().
+
+
+ *** Interrupt mode operation ***
+ ================================
+ [..]
+ (#) Notifications are activated using HAL_CAN_ActivateNotification()
+ function. Then, the process can be controlled through the
+ available user callbacks: HAL_CAN_xxxCallback(), using same APIs
+ HAL_CAN_GetRxMessage() and HAL_CAN_AddTxMessage().
+
+ (#) Notifications can be deactivated using
+ HAL_CAN_DeactivateNotification() function.
+
+ (#) Special care should be taken for CAN_IT_RX_FIFO0_MSG_PENDING and
+ CAN_IT_RX_FIFO1_MSG_PENDING notifications. These notifications trig
+ the callbacks HAL_CAN_RxFIFO0MsgPendingCallback() and
+ HAL_CAN_RxFIFO1MsgPendingCallback(). User has two possible options
+ here.
+ (++) Directly get the Rx message in the callback, using
+ HAL_CAN_GetRxMessage().
+ (++) Or deactivate the notification in the callback without
+ getting the Rx message. The Rx message can then be got later
+ using HAL_CAN_GetRxMessage(). Once the Rx message have been
+ read, the notification can be activated again.
+
+
+ *** Sleep mode ***
+ ==================
+ [..]
+ (#) The CAN peripheral can be put in sleep mode (low power), using
+ HAL_CAN_RequestSleep(). The sleep mode will be entered as soon as the
+ current CAN activity (transmission or reception of a CAN frame) will
+ be completed.
+
+ (#) A notification can be activated to be informed when the sleep mode
+ will be entered.
+
+ (#) It can be checked if the sleep mode is entered using
+ HAL_CAN_IsSleepActive().
+ Note that the CAN state (accessible from the API HAL_CAN_GetState())
+ is HAL_CAN_STATE_SLEEP_PENDING as soon as the sleep mode request is
+ submitted (the sleep mode is not yet entered), and become
+ HAL_CAN_STATE_SLEEP_ACTIVE when the sleep mode is effective.
+
+ (#) The wake-up from sleep mode can be trigged by two ways:
+ (++) Using HAL_CAN_WakeUp(). When returning from this function,
+ the sleep mode is exited (if return status is HAL_OK).
+ (++) When a start of Rx CAN frame is detected by the CAN peripheral,
+ if automatic wake up mode is enabled.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#if defined(CAN1)
+
+/** @defgroup CAN CAN
+ * @brief CAN driver modules
+ * @{
+ */
+
+#ifdef HAL_CAN_MODULE_ENABLED
+
+#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
+ #error "The CAN driver cannot be used with its legacy, Please enable only one CAN module at once"
+#endif
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup CAN_Private_Constants CAN Private Constants
+ * @{
+ */
+#define CAN_TIMEOUT_VALUE 10U
+/**
+ * @}
+ */
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup CAN_Exported_Functions CAN Exported Functions
+ * @{
+ */
+
+/** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de-initialization functions #####
+ ==============================================================================
+ [..] This section provides functions allowing to:
+ (+) HAL_CAN_Init : Initialize and configure the CAN.
+ (+) HAL_CAN_DeInit : De-initialize the CAN.
+ (+) HAL_CAN_MspInit : Initialize the CAN MSP.
+ (+) HAL_CAN_MspDeInit : DeInitialize the CAN MSP.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the CAN peripheral according to the specified
+ * parameters in the CAN_InitStruct.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef *hcan)
+{
+ uint32_t tickstart;
+
+ /* Check CAN handle */
+ if (hcan == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
+ assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TimeTriggeredMode));
+ assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AutoBusOff));
+ assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AutoWakeUp));
+ assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AutoRetransmission));
+ assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ReceiveFifoLocked));
+ assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TransmitFifoPriority));
+ assert_param(IS_CAN_MODE(hcan->Init.Mode));
+ assert_param(IS_CAN_SJW(hcan->Init.SyncJumpWidth));
+ assert_param(IS_CAN_BS1(hcan->Init.TimeSeg1));
+ assert_param(IS_CAN_BS2(hcan->Init.TimeSeg2));
+ assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler));
+
+ if (hcan->State == HAL_CAN_STATE_RESET)
+ {
+ /* Init the low level hardware: CLOCK, NVIC */
+ HAL_CAN_MspInit(hcan);
+ }
+
+ /* Exit from sleep mode */
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Check Sleep mode leave acknowledge */
+ while ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
+ {
+ if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
+
+ /* Change CAN state */
+ hcan->State = HAL_CAN_STATE_ERROR;
+
+ return HAL_ERROR;
+ }
+ }
+
+ /* Request initialisation */
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait initialisation acknowledge */
+ while ((hcan->Instance->MSR & CAN_MSR_INAK) == 0U)
+ {
+ if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
+
+ /* Change CAN state */
+ hcan->State = HAL_CAN_STATE_ERROR;
+
+ return HAL_ERROR;
+ }
+ }
+
+ /* Set the time triggered communication mode */
+ if (hcan->Init.TimeTriggeredMode == ENABLE)
+ {
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_TTCM);
+ }
+ else
+ {
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_TTCM);
+ }
+
+ /* Set the automatic bus-off management */
+ if (hcan->Init.AutoBusOff == ENABLE)
+ {
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_ABOM);
+ }
+ else
+ {
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_ABOM);
+ }
+
+ /* Set the automatic wake-up mode */
+ if (hcan->Init.AutoWakeUp == ENABLE)
+ {
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_AWUM);
+ }
+ else
+ {
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_AWUM);
+ }
+
+ /* Set the automatic retransmission */
+ if (hcan->Init.AutoRetransmission == ENABLE)
+ {
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_NART);
+ }
+ else
+ {
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_NART);
+ }
+
+ /* Set the receive FIFO locked mode */
+ if (hcan->Init.ReceiveFifoLocked == ENABLE)
+ {
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_RFLM);
+ }
+ else
+ {
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_RFLM);
+ }
+
+ /* Set the transmit FIFO priority */
+ if (hcan->Init.TransmitFifoPriority == ENABLE)
+ {
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_TXFP);
+ }
+ else
+ {
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_TXFP);
+ }
+
+ /* Set the bit timing register */
+ WRITE_REG(hcan->Instance->BTR, (uint32_t)(hcan->Init.Mode |
+ hcan->Init.SyncJumpWidth |
+ hcan->Init.TimeSeg1 |
+ hcan->Init.TimeSeg2 |
+ (hcan->Init.Prescaler - 1U)));
+
+ /* Initialize the error code */
+ hcan->ErrorCode = HAL_CAN_ERROR_NONE;
+
+ /* Initialize the CAN state */
+ hcan->State = HAL_CAN_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Deinitializes the CAN peripheral registers to their default
+ * reset values.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef *hcan)
+{
+ /* Check CAN handle */
+ if (hcan == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
+
+ /* Stop the CAN module */
+ (void)HAL_CAN_Stop(hcan);
+
+ /* DeInit the low level hardware: CLOCK, NVIC */
+ HAL_CAN_MspDeInit(hcan);
+
+ /* Reset the CAN peripheral */
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_RESET);
+
+ /* Reset the CAN ErrorCode */
+ hcan->ErrorCode = HAL_CAN_ERROR_NONE;
+
+ /* Change CAN state */
+ hcan->State = HAL_CAN_STATE_RESET;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the CAN MSP.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval None
+ */
+__weak void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcan);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CAN_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes the CAN MSP.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval None
+ */
+__weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef *hcan)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcan);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CAN_MspDeInit could be implemented in the user file
+ */
+}
+
+
+/**
+ * @}
+ */
+
+/** @defgroup CAN_Exported_Functions_Group2 Configuration functions
+ * @brief Configuration functions.
+ *
+@verbatim
+ ==============================================================================
+ ##### Configuration functions #####
+ ==============================================================================
+ [..] This section provides functions allowing to:
+ (+) HAL_CAN_ConfigFilter : Configure the CAN reception filters
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the CAN reception filter according to the specified
+ * parameters in the CAN_FilterInitStruct.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @param sFilterConfig pointer to a CAN_FilterTypeDef structure that
+ * contains the filter configuration information.
+ * @retval None
+ */
+HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan, CAN_FilterTypeDef *sFilterConfig)
+{
+ uint32_t filternbrbitpos;
+ CAN_TypeDef *can_ip = hcan->Instance;
+ HAL_CAN_StateTypeDef state = hcan->State;
+
+ if ((state == HAL_CAN_STATE_READY) ||
+ (state == HAL_CAN_STATE_LISTENING))
+ {
+ /* Check the parameters */
+ assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterIdHigh));
+ assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterIdLow));
+ assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterMaskIdHigh));
+ assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterMaskIdLow));
+ assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
+ assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
+ assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
+ assert_param(IS_CAN_FILTER_ACTIVATION(sFilterConfig->FilterActivation));
+
+#if defined(CAN2)
+ /* CAN1 and CAN2 are dual instances with 28 common filters banks */
+ /* Select master instance to access the filter banks */
+ can_ip = CAN1;
+
+ /* Check the parameters */
+ assert_param(IS_CAN_FILTER_BANK_DUAL(sFilterConfig->FilterBank));
+ assert_param(IS_CAN_FILTER_BANK_DUAL(sFilterConfig->SlaveStartFilterBank));
+#else
+ /* CAN1 is single instance with 14 dedicated filters banks */
+
+ /* Check the parameters */
+ assert_param(IS_CAN_FILTER_BANK_SINGLE(sFilterConfig->FilterBank));
+#endif
+
+ /* Initialisation mode for the filter */
+ SET_BIT(can_ip->FMR, CAN_FMR_FINIT);
+
+#if defined(CAN2)
+ /* Select the start filter number of CAN2 slave instance */
+ CLEAR_BIT(can_ip->FMR, CAN_FMR_CAN2SB);
+ SET_BIT(can_ip->FMR, sFilterConfig->SlaveStartFilterBank << CAN_FMR_CAN2SB_Pos);
+
+#endif
+ /* Convert filter number into bit position */
+ filternbrbitpos = (uint32_t)1 << (sFilterConfig->FilterBank & 0x1FU);
+
+ /* Filter Deactivation */
+ CLEAR_BIT(can_ip->FA1R, filternbrbitpos);
+
+ /* Filter Scale */
+ if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
+ {
+ /* 16-bit scale for the filter */
+ CLEAR_BIT(can_ip->FS1R, filternbrbitpos);
+
+ /* First 16-bit identifier and First 16-bit mask */
+ /* Or First 16-bit identifier and Second 16-bit identifier */
+ can_ip->sFilterRegister[sFilterConfig->FilterBank].FR1 =
+ ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16U) |
+ (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
+
+ /* Second 16-bit identifier and Second 16-bit mask */
+ /* Or Third 16-bit identifier and Fourth 16-bit identifier */
+ can_ip->sFilterRegister[sFilterConfig->FilterBank].FR2 =
+ ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
+ (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh);
+ }
+
+ if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
+ {
+ /* 32-bit scale for the filter */
+ SET_BIT(can_ip->FS1R, filternbrbitpos);
+
+ /* 32-bit identifier or First 32-bit identifier */
+ can_ip->sFilterRegister[sFilterConfig->FilterBank].FR1 =
+ ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh) << 16U) |
+ (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
+
+ /* 32-bit mask or Second 32-bit identifier */
+ can_ip->sFilterRegister[sFilterConfig->FilterBank].FR2 =
+ ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
+ (0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow);
+ }
+
+ /* Filter Mode */
+ if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
+ {
+ /* Id/Mask mode for the filter*/
+ CLEAR_BIT(can_ip->FM1R, filternbrbitpos);
+ }
+ else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
+ {
+ /* Identifier list mode for the filter*/
+ SET_BIT(can_ip->FM1R, filternbrbitpos);
+ }
+
+ /* Filter FIFO assignment */
+ if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
+ {
+ /* FIFO 0 assignation for the filter */
+ CLEAR_BIT(can_ip->FFA1R, filternbrbitpos);
+ }
+ else
+ {
+ /* FIFO 1 assignation for the filter */
+ SET_BIT(can_ip->FFA1R, filternbrbitpos);
+ }
+
+ /* Filter activation */
+ if (sFilterConfig->FilterActivation == CAN_FILTER_ENABLE)
+ {
+ SET_BIT(can_ip->FA1R, filternbrbitpos);
+ }
+
+ /* Leave the initialisation mode for the filter */
+ CLEAR_BIT(can_ip->FMR, CAN_FMR_FINIT);
+
+ /* Return function status */
+ return HAL_OK;
+ }
+ else
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
+
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup CAN_Exported_Functions_Group3 Control functions
+ * @brief Control functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Control functions #####
+ ==============================================================================
+ [..] This section provides functions allowing to:
+ (+) HAL_CAN_Start : Start the CAN module
+ (+) HAL_CAN_Stop : Stop the CAN module
+ (+) HAL_CAN_RequestSleep : Request sleep mode entry.
+ (+) HAL_CAN_WakeUp : Wake up from sleep mode.
+ (+) HAL_CAN_IsSleepActive : Check is sleep mode is active.
+ (+) HAL_CAN_AddTxMessage : Add a message to the Tx mailboxes
+ and activate the corresponding
+ transmission request
+ (+) HAL_CAN_AbortTxRequest : Abort transmission request
+ (+) HAL_CAN_GetTxMailboxesFreeLevel : Return Tx mailboxes free level
+ (+) HAL_CAN_IsTxMessagePending : Check if a transmission request is
+ pending on the selected Tx mailbox
+ (+) HAL_CAN_GetRxMessage : Get a CAN frame from the Rx FIFO
+ (+) HAL_CAN_GetRxFifoFillLevel : Return Rx FIFO fill level
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Start the CAN module.
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *hcan)
+{
+ uint32_t tickstart;
+
+ if (hcan->State == HAL_CAN_STATE_READY)
+ {
+ /* Change CAN peripheral state */
+ hcan->State = HAL_CAN_STATE_LISTENING;
+
+ /* Request leave initialisation */
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait the acknowledge */
+ while ((hcan->Instance->MSR & CAN_MSR_INAK) != 0U)
+ {
+ /* Check for the Timeout */
+ if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
+
+ /* Change CAN state */
+ hcan->State = HAL_CAN_STATE_ERROR;
+
+ return HAL_ERROR;
+ }
+ }
+
+ /* Reset the CAN ErrorCode */
+ hcan->ErrorCode = HAL_CAN_ERROR_NONE;
+
+ /* Return function status */
+ return HAL_OK;
+ }
+ else
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_READY;
+
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Stop the CAN module and enable access to configuration registers.
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CAN_Stop(CAN_HandleTypeDef *hcan)
+{
+ uint32_t tickstart;
+
+ if (hcan->State == HAL_CAN_STATE_LISTENING)
+ {
+ /* Request initialisation */
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait the acknowledge */
+ while ((hcan->Instance->MSR & CAN_MSR_INAK) == 0U)
+ {
+ /* Check for the Timeout */
+ if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
+
+ /* Change CAN state */
+ hcan->State = HAL_CAN_STATE_ERROR;
+
+ return HAL_ERROR;
+ }
+ }
+
+ /* Exit from sleep mode */
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
+
+ /* Change CAN peripheral state */
+ hcan->State = HAL_CAN_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+ }
+ else
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_STARTED;
+
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Request the sleep mode (low power) entry.
+ * When returning from this function, Sleep mode will be entered
+ * as soon as the current CAN activity (transmission or reception
+ * of a CAN frame) has been completed.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval HAL status.
+ */
+HAL_StatusTypeDef HAL_CAN_RequestSleep(CAN_HandleTypeDef *hcan)
+{
+ HAL_CAN_StateTypeDef state = hcan->State;
+
+ if ((state == HAL_CAN_STATE_READY) ||
+ (state == HAL_CAN_STATE_LISTENING))
+ {
+ /* Request Sleep mode */
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
+
+ /* Return function status */
+ return HAL_OK;
+ }
+ else
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
+
+ /* Return function status */
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Wake up from sleep mode.
+ * When returning with HAL_OK status from this function, Sleep mode
+ * is exited.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval HAL status.
+ */
+HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef *hcan)
+{
+ __IO uint32_t count = 0;
+ uint32_t timeout = 1000000U;
+ HAL_CAN_StateTypeDef state = hcan->State;
+
+ if ((state == HAL_CAN_STATE_READY) ||
+ (state == HAL_CAN_STATE_LISTENING))
+ {
+ /* Wake up request */
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
+
+ /* Wait sleep mode is exited */
+ do
+ {
+ /* Increment counter */
+ count++;
+
+ /* Check if timeout is reached */
+ if (count > timeout)
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
+
+ return HAL_ERROR;
+ }
+ }
+ while ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U);
+
+ /* Return function status */
+ return HAL_OK;
+ }
+ else
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
+
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Check is sleep mode is active.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval Status
+ * - 0 : Sleep mode is not active.
+ * - 1 : Sleep mode is active.
+ */
+uint32_t HAL_CAN_IsSleepActive(CAN_HandleTypeDef *hcan)
+{
+ uint32_t status = 0U;
+ HAL_CAN_StateTypeDef state = hcan->State;
+
+ if ((state == HAL_CAN_STATE_READY) ||
+ (state == HAL_CAN_STATE_LISTENING))
+ {
+ /* Check Sleep mode */
+ if ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
+ {
+ status = 1U;
+ }
+ }
+
+ /* Return function status */
+ return status;
+}
+
+/**
+ * @brief Add a message to the first free Tx mailbox and activate the
+ * corresponding transmission request.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @param pHeader pointer to a CAN_TxHeaderTypeDef structure.
+ * @param aData array containing the payload of the Tx frame.
+ * @param pTxMailbox pointer to a variable where the function will return
+ * the TxMailbox used to store the Tx message.
+ * This parameter can be a value of @arg CAN_Tx_Mailboxes.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, CAN_TxHeaderTypeDef *pHeader, uint8_t aData[], uint32_t *pTxMailbox)
+{
+ uint32_t transmitmailbox;
+ HAL_CAN_StateTypeDef state = hcan->State;
+ uint32_t tsr = READ_REG(hcan->Instance->TSR);
+
+ /* Check the parameters */
+ assert_param(IS_CAN_IDTYPE(pHeader->IDE));
+ assert_param(IS_CAN_RTR(pHeader->RTR));
+ assert_param(IS_CAN_DLC(pHeader->DLC));
+ if (pHeader->IDE == CAN_ID_STD)
+ {
+ assert_param(IS_CAN_STDID(pHeader->StdId));
+ }
+ else
+ {
+ assert_param(IS_CAN_EXTID(pHeader->ExtId));
+ }
+ assert_param(IS_FUNCTIONAL_STATE(pHeader->TransmitGlobalTime));
+
+ if ((state == HAL_CAN_STATE_READY) ||
+ (state == HAL_CAN_STATE_LISTENING))
+ {
+ /* Check that all the Tx mailboxes are not full */
+ if (((tsr & CAN_TSR_TME0) != 0U) ||
+ ((tsr & CAN_TSR_TME1) != 0U) ||
+ ((tsr & CAN_TSR_TME2) != 0U))
+ {
+ /* Select an empty transmit mailbox */
+ transmitmailbox = (tsr & CAN_TSR_CODE) >> CAN_TSR_CODE_Pos;
+
+ /* Check transmit mailbox value */
+ if (transmitmailbox > 2U)
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_INTERNAL;
+
+ return HAL_ERROR;
+ }
+
+ /* Store the Tx mailbox */
+ *pTxMailbox = (uint32_t)1 << transmitmailbox;
+
+ /* Set up the Id */
+ if (pHeader->IDE == CAN_ID_STD)
+ {
+ hcan->Instance->sTxMailBox[transmitmailbox].TIR = ((pHeader->StdId << CAN_TI0R_STID_Pos) |
+ pHeader->RTR);
+ }
+ else
+ {
+ hcan->Instance->sTxMailBox[transmitmailbox].TIR = ((pHeader->ExtId << CAN_TI0R_EXID_Pos) |
+ pHeader->IDE |
+ pHeader->RTR);
+ }
+
+ /* Set up the DLC */
+ hcan->Instance->sTxMailBox[transmitmailbox].TDTR = (pHeader->DLC);
+
+ /* Set up the Transmit Global Time mode */
+ if (pHeader->TransmitGlobalTime == ENABLE)
+ {
+ SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TDTR, CAN_TDT0R_TGT);
+ }
+
+ /* Set up the data field */
+ WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR,
+ ((uint32_t)aData[7] << CAN_TDH0R_DATA7_Pos) |
+ ((uint32_t)aData[6] << CAN_TDH0R_DATA6_Pos) |
+ ((uint32_t)aData[5] << CAN_TDH0R_DATA5_Pos) |
+ ((uint32_t)aData[4] << CAN_TDH0R_DATA4_Pos));
+ WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR,
+ ((uint32_t)aData[3] << CAN_TDL0R_DATA3_Pos) |
+ ((uint32_t)aData[2] << CAN_TDL0R_DATA2_Pos) |
+ ((uint32_t)aData[1] << CAN_TDL0R_DATA1_Pos) |
+ ((uint32_t)aData[0] << CAN_TDL0R_DATA0_Pos));
+
+ /* Request transmission */
+ SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);
+
+ /* Return function status */
+ return HAL_OK;
+ }
+ else
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;
+
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
+
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Abort transmission requests
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @param TxMailboxes List of the Tx Mailboxes to abort.
+ * This parameter can be any combination of @arg CAN_Tx_Mailboxes.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CAN_AbortTxRequest(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes)
+{
+ HAL_CAN_StateTypeDef state = hcan->State;
+
+ /* Check function parameters */
+ assert_param(IS_CAN_TX_MAILBOX_LIST(TxMailboxes));
+
+ if ((state == HAL_CAN_STATE_READY) ||
+ (state == HAL_CAN_STATE_LISTENING))
+ {
+ /* Check Tx Mailbox 0 */
+ if ((TxMailboxes & CAN_TX_MAILBOX0) != 0U)
+ {
+ /* Add cancellation request for Tx Mailbox 0 */
+ SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ0);
+ }
+
+ /* Check Tx Mailbox 1 */
+ if ((TxMailboxes & CAN_TX_MAILBOX1) != 0U)
+ {
+ /* Add cancellation request for Tx Mailbox 1 */
+ SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ1);
+ }
+
+ /* Check Tx Mailbox 2 */
+ if ((TxMailboxes & CAN_TX_MAILBOX2) != 0U)
+ {
+ /* Add cancellation request for Tx Mailbox 2 */
+ SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ2);
+ }
+
+ /* Return function status */
+ return HAL_OK;
+ }
+ else
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
+
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Return Tx Mailboxes free level: number of free Tx Mailboxes.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval Number of free Tx Mailboxes.
+ */
+uint32_t HAL_CAN_GetTxMailboxesFreeLevel(CAN_HandleTypeDef *hcan)
+{
+ uint32_t freelevel = 0U;
+ HAL_CAN_StateTypeDef state = hcan->State;
+
+ if ((state == HAL_CAN_STATE_READY) ||
+ (state == HAL_CAN_STATE_LISTENING))
+ {
+ /* Check Tx Mailbox 0 status */
+ if ((hcan->Instance->TSR & CAN_TSR_TME0) != 0U)
+ {
+ freelevel++;
+ }
+
+ /* Check Tx Mailbox 1 status */
+ if ((hcan->Instance->TSR & CAN_TSR_TME1) != 0U)
+ {
+ freelevel++;
+ }
+
+ /* Check Tx Mailbox 2 status */
+ if ((hcan->Instance->TSR & CAN_TSR_TME2) != 0U)
+ {
+ freelevel++;
+ }
+ }
+
+ /* Return Tx Mailboxes free level */
+ return freelevel;
+}
+
+/**
+ * @brief Check if a transmission request is pending on the selected Tx
+ * Mailboxes.
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @param TxMailboxes List of Tx Mailboxes to check.
+ * This parameter can be any combination of @arg CAN_Tx_Mailboxes.
+ * @retval Status
+ * - 0 : No pending transmission request on any selected Tx Mailboxes.
+ * - 1 : Pending transmission request on at least one of the selected
+ * Tx Mailbox.
+ */
+uint32_t HAL_CAN_IsTxMessagePending(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes)
+{
+ uint32_t status = 0U;
+ HAL_CAN_StateTypeDef state = hcan->State;
+
+ /* Check function parameters */
+ assert_param(IS_CAN_TX_MAILBOX_LIST(TxMailboxes));
+
+ if ((state == HAL_CAN_STATE_READY) ||
+ (state == HAL_CAN_STATE_LISTENING))
+ {
+ /* Check pending transmission request on the selected Tx Mailboxes */
+ if ((hcan->Instance->TSR & (TxMailboxes << CAN_TSR_TME0_Pos)) != (TxMailboxes << CAN_TSR_TME0_Pos))
+ {
+ status = 1U;
+ }
+ }
+
+ /* Return status */
+ return status;
+}
+
+/**
+ * @brief Return timestamp of Tx message sent, if time triggered communication
+ mode is enabled.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @param TxMailbox Tx Mailbox where the timestamp of message sent will be
+ * read.
+ * This parameter can be one value of @arg CAN_Tx_Mailboxes.
+ * @retval Timestamp of message sent from Tx Mailbox.
+ */
+uint32_t HAL_CAN_GetTxTimestamp(CAN_HandleTypeDef *hcan, uint32_t TxMailbox)
+{
+ uint32_t timestamp = 0U;
+ uint32_t transmitmailbox;
+ HAL_CAN_StateTypeDef state = hcan->State;
+
+ /* Check function parameters */
+ assert_param(IS_CAN_TX_MAILBOX(TxMailbox));
+
+ if ((state == HAL_CAN_STATE_READY) ||
+ (state == HAL_CAN_STATE_LISTENING))
+ {
+ /* Select the Tx mailbox */
+ transmitmailbox = POSITION_VAL(TxMailbox);
+
+ /* Get timestamp */
+ timestamp = (hcan->Instance->sTxMailBox[transmitmailbox].TDTR & CAN_TDT0R_TIME) >> CAN_TDT0R_TIME_Pos;
+ }
+
+ /* Return the timestamp */
+ return timestamp;
+}
+
+/**
+ * @brief Get an CAN frame from the Rx FIFO zone into the message RAM.
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @param RxFifo Fifo number of the received message to be read.
+ * This parameter can be a value of @arg CAN_receive_FIFO_number.
+ * @param pHeader pointer to a CAN_RxHeaderTypeDef structure where the header
+ * of the Rx frame will be stored.
+ * @param aData array where the payload of the Rx frame will be stored.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CAN_GetRxMessage(CAN_HandleTypeDef *hcan, uint32_t RxFifo, CAN_RxHeaderTypeDef *pHeader, uint8_t aData[])
+{
+ HAL_CAN_StateTypeDef state = hcan->State;
+
+ assert_param(IS_CAN_RX_FIFO(RxFifo));
+
+ if ((state == HAL_CAN_STATE_READY) ||
+ (state == HAL_CAN_STATE_LISTENING))
+ {
+ /* Check the Rx FIFO */
+ if (RxFifo == CAN_RX_FIFO0) /* Rx element is assigned to Rx FIFO 0 */
+ {
+ /* Check that the Rx FIFO 0 is not empty */
+ if ((hcan->Instance->RF0R & CAN_RF0R_FMP0) == 0U)
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;
+
+ return HAL_ERROR;
+ }
+ }
+ else /* Rx element is assigned to Rx FIFO 1 */
+ {
+ /* Check that the Rx FIFO 1 is not empty */
+ if ((hcan->Instance->RF1R & CAN_RF1R_FMP1) == 0U)
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;
+
+ return HAL_ERROR;
+ }
+ }
+
+ /* Get the header */
+ pHeader->IDE = CAN_RI0R_IDE & hcan->Instance->sFIFOMailBox[RxFifo].RIR;
+ if (pHeader->IDE == CAN_ID_STD)
+ {
+ pHeader->StdId = (CAN_RI0R_STID & hcan->Instance->sFIFOMailBox[RxFifo].RIR) >> CAN_TI0R_STID_Pos;
+ }
+ else
+ {
+ pHeader->ExtId = ((CAN_RI0R_EXID | CAN_RI0R_STID) & hcan->Instance->sFIFOMailBox[RxFifo].RIR) >> CAN_RI0R_EXID_Pos;
+ }
+ pHeader->RTR = (CAN_RI0R_RTR & hcan->Instance->sFIFOMailBox[RxFifo].RIR) >> CAN_RI0R_RTR_Pos;
+ pHeader->DLC = (CAN_RDT0R_DLC & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_DLC_Pos;
+ pHeader->FilterMatchIndex = (CAN_RDT0R_FMI & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_FMI_Pos;
+ pHeader->Timestamp = (CAN_RDT0R_TIME & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_TIME_Pos;
+
+ /* Get the data */
+ aData[0] = (uint8_t)((CAN_RDL0R_DATA0 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA0_Pos);
+ aData[1] = (uint8_t)((CAN_RDL0R_DATA1 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA1_Pos);
+ aData[2] = (uint8_t)((CAN_RDL0R_DATA2 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA2_Pos);
+ aData[3] = (uint8_t)((CAN_RDL0R_DATA3 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA3_Pos);
+ aData[4] = (uint8_t)((CAN_RDH0R_DATA4 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA4_Pos);
+ aData[5] = (uint8_t)((CAN_RDH0R_DATA5 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA5_Pos);
+ aData[6] = (uint8_t)((CAN_RDH0R_DATA6 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA6_Pos);
+ aData[7] = (uint8_t)((CAN_RDH0R_DATA7 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA7_Pos);
+
+ /* Release the FIFO */
+ if (RxFifo == CAN_RX_FIFO0) /* Rx element is assigned to Rx FIFO 0 */
+ {
+ /* Release RX FIFO 0 */
+ SET_BIT(hcan->Instance->RF0R, CAN_RF0R_RFOM0);
+ }
+ else /* Rx element is assigned to Rx FIFO 1 */
+ {
+ /* Release RX FIFO 1 */
+ SET_BIT(hcan->Instance->RF1R, CAN_RF1R_RFOM1);
+ }
+
+ /* Return function status */
+ return HAL_OK;
+ }
+ else
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
+
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Return Rx FIFO fill level.
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @param RxFifo Rx FIFO.
+ * This parameter can be a value of @arg CAN_receive_FIFO_number.
+ * @retval Number of messages available in Rx FIFO.
+ */
+uint32_t HAL_CAN_GetRxFifoFillLevel(CAN_HandleTypeDef *hcan, uint32_t RxFifo)
+{
+ uint32_t filllevel = 0U;
+ HAL_CAN_StateTypeDef state = hcan->State;
+
+ /* Check function parameters */
+ assert_param(IS_CAN_RX_FIFO(RxFifo));
+
+ if ((state == HAL_CAN_STATE_READY) ||
+ (state == HAL_CAN_STATE_LISTENING))
+ {
+ if (RxFifo == CAN_RX_FIFO0)
+ {
+ filllevel = hcan->Instance->RF0R & CAN_RF0R_FMP0;
+ }
+ else /* RxFifo == CAN_RX_FIFO1 */
+ {
+ filllevel = hcan->Instance->RF1R & CAN_RF1R_FMP1;
+ }
+ }
+
+ /* Return Rx FIFO fill level */
+ return filllevel;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup CAN_Exported_Functions_Group4 Interrupts management
+ * @brief Interrupts management
+ *
+@verbatim
+ ==============================================================================
+ ##### Interrupts management #####
+ ==============================================================================
+ [..] This section provides functions allowing to:
+ (+) HAL_CAN_ActivateNotification : Enable interrupts
+ (+) HAL_CAN_DeactivateNotification : Disable interrupts
+ (+) HAL_CAN_IRQHandler : Handles CAN interrupt request
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enable interrupts.
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @param ActiveITs indicates which interrupts will be enabled.
+ * This parameter can be any combination of @arg CAN_Interrupts.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan, uint32_t ActiveITs)
+{
+ HAL_CAN_StateTypeDef state = hcan->State;
+
+ /* Check function parameters */
+ assert_param(IS_CAN_IT(ActiveITs));
+
+ if ((state == HAL_CAN_STATE_READY) ||
+ (state == HAL_CAN_STATE_LISTENING))
+ {
+ /* Enable the selected interrupts */
+ __HAL_CAN_ENABLE_IT(hcan, ActiveITs);
+
+ /* Return function status */
+ return HAL_OK;
+ }
+ else
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
+
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Disable interrupts.
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @param InactiveITs indicates which interrupts will be disabled.
+ * This parameter can be any combination of @arg CAN_Interrupts.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CAN_DeactivateNotification(CAN_HandleTypeDef *hcan, uint32_t InactiveITs)
+{
+ HAL_CAN_StateTypeDef state = hcan->State;
+
+ /* Check function parameters */
+ assert_param(IS_CAN_IT(InactiveITs));
+
+ if ((state == HAL_CAN_STATE_READY) ||
+ (state == HAL_CAN_STATE_LISTENING))
+ {
+ /* Disable the selected interrupts */
+ __HAL_CAN_DISABLE_IT(hcan, InactiveITs);
+
+ /* Return function status */
+ return HAL_OK;
+ }
+ else
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
+
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Handles CAN interrupt request
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval None
+ */
+void HAL_CAN_IRQHandler(CAN_HandleTypeDef *hcan)
+{
+ uint32_t errorcode = HAL_CAN_ERROR_NONE;
+ uint32_t interrupts = READ_REG(hcan->Instance->IER);
+ uint32_t msrflags = READ_REG(hcan->Instance->MSR);
+ uint32_t tsrflags = READ_REG(hcan->Instance->TSR);
+ uint32_t rf0rflags = READ_REG(hcan->Instance->RF0R);
+ uint32_t rf1rflags = READ_REG(hcan->Instance->RF1R);
+ uint32_t esrflags = READ_REG(hcan->Instance->ESR);
+
+ /* Transmit Mailbox empty interrupt management *****************************/
+ if ((interrupts & CAN_IT_TX_MAILBOX_EMPTY) != 0U)
+ {
+ /* Transmit Mailbox 0 management *****************************************/
+ if ((tsrflags & CAN_TSR_RQCP0) != 0U)
+ {
+ /* Clear the Transmission Complete flag (and TXOK0,ALST0,TERR0 bits) */
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP0);
+
+ if ((tsrflags & CAN_TSR_TXOK0) != 0U)
+ {
+ /* Transmission Mailbox 0 complete callback */
+ /* Call weak (surcharged) callback */
+ HAL_CAN_TxMailbox0CompleteCallback(hcan);
+ }
+ else
+ {
+ if ((tsrflags & CAN_TSR_ALST0) != 0U)
+ {
+ /* Update error code */
+ errorcode |= HAL_CAN_ERROR_TX_ALST0;
+ }
+ else if ((tsrflags & CAN_TSR_TERR0) != 0U)
+ {
+ /* Update error code */
+ errorcode |= HAL_CAN_ERROR_TX_TERR0;
+ }
+ else
+ {
+ /* Transmission Mailbox 0 abort callback */
+ /* Call weak (surcharged) callback */
+ HAL_CAN_TxMailbox0AbortCallback(hcan);
+ }
+ }
+ }
+
+ /* Transmit Mailbox 1 management *****************************************/
+ if ((tsrflags & CAN_TSR_RQCP1) != 0U)
+ {
+ /* Clear the Transmission Complete flag (and TXOK1,ALST1,TERR1 bits) */
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP1);
+
+ if ((tsrflags & CAN_TSR_TXOK1) != 0U)
+ {
+ /* Transmission Mailbox 1 complete callback */
+ /* Call weak (surcharged) callback */
+ HAL_CAN_TxMailbox1CompleteCallback(hcan);
+ }
+ else
+ {
+ if ((tsrflags & CAN_TSR_ALST1) != 0U)
+ {
+ /* Update error code */
+ errorcode |= HAL_CAN_ERROR_TX_ALST1;
+ }
+ else if ((tsrflags & CAN_TSR_TERR1) != 0U)
+ {
+ /* Update error code */
+ errorcode |= HAL_CAN_ERROR_TX_TERR1;
+ }
+ else
+ {
+ /* Transmission Mailbox 1 abort callback */
+ /* Call weak (surcharged) callback */
+ HAL_CAN_TxMailbox1AbortCallback(hcan);
+ }
+ }
+ }
+
+ /* Transmit Mailbox 2 management *****************************************/
+ if ((tsrflags & CAN_TSR_RQCP2) != 0U)
+ {
+ /* Clear the Transmission Complete flag (and TXOK2,ALST2,TERR2 bits) */
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP2);
+
+ if ((tsrflags & CAN_TSR_TXOK2) != 0U)
+ {
+ /* Transmission Mailbox 2 complete callback */
+ /* Call weak (surcharged) callback */
+ HAL_CAN_TxMailbox2CompleteCallback(hcan);
+ }
+ else
+ {
+ if ((tsrflags & CAN_TSR_ALST2) != 0U)
+ {
+ /* Update error code */
+ errorcode |= HAL_CAN_ERROR_TX_ALST2;
+ }
+ else if ((tsrflags & CAN_TSR_TERR2) != 0U)
+ {
+ /* Update error code */
+ errorcode |= HAL_CAN_ERROR_TX_TERR2;
+ }
+ else
+ {
+ /* Transmission Mailbox 2 abort callback */
+ /* Call weak (surcharged) callback */
+ HAL_CAN_TxMailbox2AbortCallback(hcan);
+ }
+ }
+ }
+ }
+
+ /* Receive FIFO 0 overrun interrupt management *****************************/
+ if ((interrupts & CAN_IT_RX_FIFO0_OVERRUN) != 0U)
+ {
+ if ((rf0rflags & CAN_RF0R_FOVR0) != 0U)
+ {
+ /* Set CAN error code to Rx Fifo 0 overrun error */
+ errorcode |= HAL_CAN_ERROR_RX_FOV0;
+
+ /* Clear FIFO0 Overrun Flag */
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
+ }
+ }
+
+ /* Receive FIFO 0 full interrupt management ********************************/
+ if ((interrupts & CAN_IT_RX_FIFO0_FULL) != 0U)
+ {
+ if ((rf0rflags & CAN_RF0R_FULL0) != 0U)
+ {
+ /* Clear FIFO 0 full Flag */
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF0);
+
+ /* Receive FIFO 0 full Callback */
+ /* Call weak (surcharged) callback */
+ HAL_CAN_RxFifo0FullCallback(hcan);
+ }
+ }
+
+ /* Receive FIFO 0 message pending interrupt management *********************/
+ if ((interrupts & CAN_IT_RX_FIFO0_MSG_PENDING) != 0U)
+ {
+ /* Check if message is still pending */
+ if ((hcan->Instance->RF0R & CAN_RF0R_FMP0) != 0U)
+ {
+ /* Receive FIFO 0 mesage pending Callback */
+ /* Call weak (surcharged) callback */
+ HAL_CAN_RxFifo0MsgPendingCallback(hcan);
+ }
+ }
+
+ /* Receive FIFO 1 overrun interrupt management *****************************/
+ if ((interrupts & CAN_IT_RX_FIFO1_OVERRUN) != 0U)
+ {
+ if ((rf1rflags & CAN_RF1R_FOVR1) != 0U)
+ {
+ /* Set CAN error code to Rx Fifo 1 overrun error */
+ errorcode |= HAL_CAN_ERROR_RX_FOV1;
+
+ /* Clear FIFO1 Overrun Flag */
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
+ }
+ }
+
+ /* Receive FIFO 1 full interrupt management ********************************/
+ if ((interrupts & CAN_IT_RX_FIFO1_FULL) != 0U)
+ {
+ if ((rf1rflags & CAN_RF1R_FULL1) != 0U)
+ {
+ /* Clear FIFO 1 full Flag */
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF1);
+
+ /* Receive FIFO 1 full Callback */
+ /* Call weak (surcharged) callback */
+ HAL_CAN_RxFifo1FullCallback(hcan);
+ }
+ }
+
+ /* Receive FIFO 1 message pending interrupt management *********************/
+ if ((interrupts & CAN_IT_RX_FIFO1_MSG_PENDING) != 0U)
+ {
+ /* Check if message is still pending */
+ if ((hcan->Instance->RF1R & CAN_RF1R_FMP1) != 0U)
+ {
+ /* Receive FIFO 1 mesage pending Callback */
+ /* Call weak (surcharged) callback */
+ HAL_CAN_RxFifo1MsgPendingCallback(hcan);
+ }
+ }
+
+ /* Sleep interrupt management *********************************************/
+ if ((interrupts & CAN_IT_SLEEP_ACK) != 0U)
+ {
+ if ((msrflags & CAN_MSR_SLAKI) != 0U)
+ {
+ /* Clear Sleep interrupt Flag */
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_SLAKI);
+
+ /* Sleep Callback */
+ /* Call weak (surcharged) callback */
+ HAL_CAN_SleepCallback(hcan);
+ }
+ }
+
+ /* WakeUp interrupt management *********************************************/
+ if ((interrupts & CAN_IT_WAKEUP) != 0U)
+ {
+ if ((msrflags & CAN_MSR_WKUI) != 0U)
+ {
+ /* Clear WakeUp Flag */
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_WKU);
+
+ /* WakeUp Callback */
+ /* Call weak (surcharged) callback */
+ HAL_CAN_WakeUpFromRxMsgCallback(hcan);
+ }
+ }
+
+ /* Error interrupts management *********************************************/
+ if ((interrupts & CAN_IT_ERROR) != 0U)
+ {
+ if ((msrflags & CAN_MSR_ERRI) != 0U)
+ {
+ /* Check Error Warning Flag */
+ if (((interrupts & CAN_IT_ERROR_WARNING) != 0U) &&
+ ((esrflags & CAN_ESR_EWGF) != 0U))
+ {
+ /* Set CAN error code to Error Warning */
+ errorcode |= HAL_CAN_ERROR_EWG;
+
+ /* No need for clear of Error Warning Flag as read-only */
+ }
+
+ /* Check Error Passive Flag */
+ if (((interrupts & CAN_IT_ERROR_PASSIVE) != 0U) &&
+ ((esrflags & CAN_ESR_EPVF) != 0U))
+ {
+ /* Set CAN error code to Error Passive */
+ errorcode |= HAL_CAN_ERROR_EPV;
+
+ /* No need for clear of Error Passive Flag as read-only */
+ }
+
+ /* Check Bus-off Flag */
+ if (((interrupts & CAN_IT_BUSOFF) != 0U) &&
+ ((esrflags & CAN_ESR_BOFF) != 0U))
+ {
+ /* Set CAN error code to Bus-Off */
+ errorcode |= HAL_CAN_ERROR_BOF;
+
+ /* No need for clear of Error Bus-Off as read-only */
+ }
+
+ /* Check Last Error Code Flag */
+ if (((interrupts & CAN_IT_LAST_ERROR_CODE) != 0U) &&
+ ((esrflags & CAN_ESR_LEC) != 0U))
+ {
+ switch (esrflags & CAN_ESR_LEC)
+ {
+ case (CAN_ESR_LEC_0):
+ /* Set CAN error code to Stuff error */
+ errorcode |= HAL_CAN_ERROR_STF;
+ break;
+ case (CAN_ESR_LEC_1):
+ /* Set CAN error code to Form error */
+ errorcode |= HAL_CAN_ERROR_FOR;
+ break;
+ case (CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
+ /* Set CAN error code to Acknowledgement error */
+ errorcode |= HAL_CAN_ERROR_ACK;
+ break;
+ case (CAN_ESR_LEC_2):
+ /* Set CAN error code to Bit recessive error */
+ errorcode |= HAL_CAN_ERROR_BR;
+ break;
+ case (CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
+ /* Set CAN error code to Bit Dominant error */
+ errorcode |= HAL_CAN_ERROR_BD;
+ break;
+ case (CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
+ /* Set CAN error code to CRC error */
+ errorcode |= HAL_CAN_ERROR_CRC;
+ break;
+ default:
+ break;
+ }
+
+ /* Clear Last error code Flag */
+ CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC);
+ }
+ }
+
+ /* Clear ERRI Flag */
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_ERRI);
+ }
+
+ /* Call the Error call Back in case of Errors */
+ if (errorcode != HAL_CAN_ERROR_NONE)
+ {
+ /* Update error code in handle */
+ hcan->ErrorCode |= errorcode;
+
+ /* Call Error callback function */
+ /* Call weak (surcharged) callback */
+ HAL_CAN_ErrorCallback(hcan);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup CAN_Exported_Functions_Group5 Callback functions
+ * @brief CAN Callback functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Callback functions #####
+ ==============================================================================
+ [..]
+ This subsection provides the following callback functions:
+ (+) HAL_CAN_TxMailbox0CompleteCallback
+ (+) HAL_CAN_TxMailbox1CompleteCallback
+ (+) HAL_CAN_TxMailbox2CompleteCallback
+ (+) HAL_CAN_TxMailbox0AbortCallback
+ (+) HAL_CAN_TxMailbox1AbortCallback
+ (+) HAL_CAN_TxMailbox2AbortCallback
+ (+) HAL_CAN_RxFifo0MsgPendingCallback
+ (+) HAL_CAN_RxFifo0FullCallback
+ (+) HAL_CAN_RxFifo1MsgPendingCallback
+ (+) HAL_CAN_RxFifo1FullCallback
+ (+) HAL_CAN_SleepCallback
+ (+) HAL_CAN_WakeUpFromRxMsgCallback
+ (+) HAL_CAN_ErrorCallback
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Transmission Mailbox 0 complete callback.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval None
+ */
+__weak void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcan);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CAN_TxMailbox0CompleteCallback could be implemented in the
+ user file
+ */
+}
+
+/**
+ * @brief Transmission Mailbox 1 complete callback.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval None
+ */
+__weak void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcan);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CAN_TxMailbox1CompleteCallback could be implemented in the
+ user file
+ */
+}
+
+/**
+ * @brief Transmission Mailbox 2 complete callback.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval None
+ */
+__weak void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcan);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CAN_TxMailbox2CompleteCallback could be implemented in the
+ user file
+ */
+}
+
+/**
+ * @brief Transmission Mailbox 0 Cancellation callback.
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval None
+ */
+__weak void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcan);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CAN_TxMailbox0AbortCallback could be implemented in the
+ user file
+ */
+}
+
+/**
+ * @brief Transmission Mailbox 1 Cancellation callback.
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval None
+ */
+__weak void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcan);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CAN_TxMailbox1AbortCallback could be implemented in the
+ user file
+ */
+}
+
+/**
+ * @brief Transmission Mailbox 2 Cancellation callback.
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval None
+ */
+__weak void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcan);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CAN_TxMailbox2AbortCallback could be implemented in the
+ user file
+ */
+}
+
+/**
+ * @brief Rx FIFO 0 message pending callback.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval None
+ */
+__weak void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcan);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CAN_RxFifo0MsgPendingCallback could be implemented in the
+ user file
+ */
+}
+
+/**
+ * @brief Rx FIFO 0 full callback.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval None
+ */
+__weak void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcan);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CAN_RxFifo0FullCallback could be implemented in the user
+ file
+ */
+}
+
+/**
+ * @brief Rx FIFO 1 message pending callback.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval None
+ */
+__weak void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcan);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CAN_RxFifo1MsgPendingCallback could be implemented in the
+ user file
+ */
+}
+
+/**
+ * @brief Rx FIFO 1 full callback.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval None
+ */
+__weak void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcan);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CAN_RxFifo1FullCallback could be implemented in the user
+ file
+ */
+}
+
+/**
+ * @brief Sleep callback.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval None
+ */
+__weak void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcan);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CAN_SleepCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief WakeUp from Rx message callback.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval None
+ */
+__weak void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcan);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CAN_WakeUpFromRxMsgCallback could be implemented in the
+ user file
+ */
+}
+
+/**
+ * @brief Error CAN callback.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval None
+ */
+__weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcan);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CAN_ErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup CAN_Exported_Functions_Group6 Peripheral State and Error functions
+ * @brief CAN Peripheral State functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral State and Error functions #####
+ ==============================================================================
+ [..]
+ This subsection provides functions allowing to :
+ (+) HAL_CAN_GetState() : Return the CAN state.
+ (+) HAL_CAN_GetError() : Return the CAN error codes if any.
+ (+) HAL_CAN_ResetError(): Reset the CAN error codes if any.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Return the CAN state.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval HAL state
+ */
+HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef *hcan)
+{
+ HAL_CAN_StateTypeDef state = hcan->State;
+
+ if ((state == HAL_CAN_STATE_READY) ||
+ (state == HAL_CAN_STATE_LISTENING))
+ {
+ /* Check sleep mode acknowledge flag */
+ if ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
+ {
+ /* Sleep mode is active */
+ state = HAL_CAN_STATE_SLEEP_ACTIVE;
+ }
+ /* Check sleep mode request flag */
+ else if ((hcan->Instance->MCR & CAN_MCR_SLEEP) != 0U)
+ {
+ /* Sleep mode request is pending */
+ state = HAL_CAN_STATE_SLEEP_PENDING;
+ }
+ else
+ {
+ /* Neither sleep mode request nor sleep mode acknowledge */
+ }
+ }
+
+ /* Return CAN state */
+ return state;
+}
+
+/**
+ * @brief Return the CAN error code.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval CAN Error Code
+ */
+uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
+{
+ /* Return CAN error code */
+ return hcan->ErrorCode;
+}
+
+/**
+ * @brief Reset the CAN error code.
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
+ * the configuration information for the specified CAN.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CAN_ResetError(CAN_HandleTypeDef *hcan)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+ HAL_CAN_StateTypeDef state = hcan->State;
+
+ if ((state == HAL_CAN_STATE_READY) ||
+ (state == HAL_CAN_STATE_LISTENING))
+ {
+ /* Reset CAN error code */
+ hcan->ErrorCode = 0U;
+ }
+ else
+ {
+ /* Update error code */
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
+
+ status = HAL_ERROR;
+ }
+
+ /* Return the status */
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_CAN_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+#endif /* CAN1 */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cec.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cec.c
new file mode 100644
index 0000000..630b638
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cec.c
@@ -0,0 +1,692 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_cec.c
+ * @author MCD Application Team
+ * @brief CEC HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the High Definition Multimedia Interface
+ * Consumer Electronics Control Peripheral (CEC).
+ * + Initialization and de-initialization function
+ * + IO operation function
+ * + Peripheral Control function
+ *
+ *
+ @verbatim
+ ===============================================================================
+ ##### How to use this driver #####
+ ===============================================================================
+ [..]
+ The CEC HAL driver can be used as follow:
+
+ (#) Declare a CEC_HandleTypeDef handle structure.
+ (#) Initialize the CEC low level resources by implementing the HAL_CEC_MspInit ()API:
+ (##) Enable the CEC interface clock.
+ (##) CEC pins configuration:
+ (+++) Enable the clock for the CEC GPIOs.
+ (+++) Configure these CEC pins as alternate function pull-up.
+ (##) NVIC configuration if you need to use interrupt process (HAL_CEC_Transmit_IT()
+ and HAL_CEC_Receive_IT() APIs):
+ (+++) Configure the CEC interrupt priority.
+ (+++) Enable the NVIC CEC IRQ handle.
+ (+++) The specific CEC interrupts (Transmission complete interrupt,
+ RXNE interrupt and Error Interrupts) will be managed using the macros
+ __HAL_CEC_ENABLE_IT() and __HAL_CEC_DISABLE_IT() inside the transmit
+ and receive process.
+
+ (#) Program the Bit Timing Error Mode and the Bit Period Error Mode in the hcec Init structure.
+
+ (#) Initialize the CEC registers by calling the HAL_CEC_Init() API.
+
+ [..]
+ (@) This API (HAL_CEC_Init()) configures also the low level Hardware (GPIO, CLOCK, CORTEX...etc)
+ by calling the customed HAL_CEC_MspInit() API.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+#ifdef HAL_CEC_MODULE_ENABLED
+
+#if defined(STM32F100xB) || defined(STM32F100xE)
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup CEC CEC
+ * @brief HAL CEC module driver
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup CEC_Private_Constants CEC Private Constants
+ * @{
+ */
+#define CEC_CFGR_FIELDS (CEC_CFGR_BTEM | CEC_CFGR_BPEM )
+#define CEC_FLAG_TRANSMIT_MASK (CEC_FLAG_TSOM|CEC_FLAG_TEOM|CEC_FLAG_TBTRF)
+#define CEC_FLAG_RECEIVE_MASK (CEC_FLAG_RSOM|CEC_FLAG_REOM|CEC_FLAG_RBTF)
+#define CEC_ESR_ALL_ERROR (CEC_ESR_BTE|CEC_ESR_BPE|CEC_ESR_RBTFE|CEC_ESR_SBE|CEC_ESR_ACKE|CEC_ESR_LINE|CEC_ESR_TBTFE)
+#define CEC_RXXFERSIZE_INITIALIZE 0xFFFF /*!< Value used to initialise the RxXferSize of the handle */
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup CEC_Private_Functions CEC Private Functions
+ * @{
+ */
+static HAL_StatusTypeDef CEC_Transmit_IT(CEC_HandleTypeDef *hcec);
+static HAL_StatusTypeDef CEC_Receive_IT(CEC_HandleTypeDef *hcec);
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+
+/** @defgroup CEC_Exported_Functions CEC Exported Functions
+ * @{
+ */
+
+/** @defgroup CEC_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+===============================================================================
+ ##### Initialization and Configuration functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to initialize the CEC
+ (+) The following parameters need to be configured:
+ (++) TimingErrorFree
+ (++) PeriodErrorFree
+ (++) InitiatorAddress
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the CEC mode according to the specified
+ * parameters in the CEC_InitTypeDef and creates the associated handle .
+ * @param hcec: CEC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CEC_Init(CEC_HandleTypeDef *hcec)
+{
+ /* Check the CEC handle allocation */
+ if((hcec == NULL) ||(hcec->Init.RxBuffer == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance));
+ assert_param(IS_CEC_BIT_TIMING_ERROR_MODE(hcec->Init.TimingErrorFree));
+ assert_param(IS_CEC_BIT_PERIOD_ERROR_MODE(hcec->Init.PeriodErrorFree));
+ assert_param(IS_CEC_ADDRESS(hcec->Init.OwnAddress));
+
+ if(hcec->gState == HAL_CEC_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hcec->Lock = HAL_UNLOCKED;
+ /* Init the low level hardware : GPIO, CLOCK */
+ HAL_CEC_MspInit(hcec);
+ }
+ hcec->gState = HAL_CEC_STATE_BUSY;
+
+ /* Disable the Peripheral */
+ __HAL_CEC_DISABLE(hcec);
+
+ /* Write to CEC Control Register */
+ MODIFY_REG(hcec->Instance->CFGR, CEC_CFGR_FIELDS, hcec->Init.TimingErrorFree | hcec->Init.PeriodErrorFree);
+
+ /* Write to CEC Own Address Register */
+ MODIFY_REG(hcec->Instance->OAR, CEC_OAR_OA, hcec->Init.OwnAddress);
+
+ /* Configure the prescaler to generate the required 50 microseconds time base.*/
+ MODIFY_REG(hcec->Instance->PRES, CEC_PRES_PRES, 50U * (HAL_RCC_GetPCLK1Freq()/1000000U) - 1U);
+
+ /* Enable the following CEC Interrupt */
+ __HAL_CEC_ENABLE_IT(hcec, CEC_IT_IE);
+
+ /* Enable the CEC Peripheral */
+ __HAL_CEC_ENABLE(hcec);
+
+ hcec->ErrorCode = HAL_CEC_ERROR_NONE;
+ hcec->gState = HAL_CEC_STATE_READY;
+ hcec->RxState = HAL_CEC_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the CEC peripheral
+ * @param hcec: CEC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CEC_DeInit(CEC_HandleTypeDef *hcec)
+{
+ /* Check the CEC handle allocation */
+ if(hcec == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance));
+
+ hcec->gState = HAL_CEC_STATE_BUSY;
+
+ /* DeInit the low level hardware */
+ HAL_CEC_MspDeInit(hcec);
+
+ __HAL_RCC_CEC_FORCE_RESET();
+ __HAL_RCC_CEC_RELEASE_RESET();
+
+ hcec->ErrorCode = HAL_CEC_ERROR_NONE;
+ hcec->gState = HAL_CEC_STATE_RESET;
+ hcec->RxState = HAL_CEC_STATE_RESET;
+
+ /* Process Unlock */
+ __HAL_UNLOCK(hcec);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the Own Address of the CEC device
+ * @param hcec: CEC handle
+ * @param CEC_OwnAddress: The CEC own address.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CEC_SetDeviceAddress(CEC_HandleTypeDef *hcec, uint16_t CEC_OwnAddress)
+{
+ /* Check the parameters */
+ assert_param(IS_CEC_OWN_ADDRESS(CEC_OwnAddress));
+
+ if ((hcec->gState == HAL_CEC_STATE_READY) && (hcec->RxState == HAL_CEC_STATE_READY))
+ {
+ /* Process Locked */
+ __HAL_LOCK(hcec);
+
+ hcec->gState = HAL_CEC_STATE_BUSY;
+
+ /* Disable the Peripheral */
+ __HAL_CEC_DISABLE(hcec);
+
+ if(CEC_OwnAddress != CEC_OWN_ADDRESS_NONE)
+ {
+ MODIFY_REG(hcec->Instance->OAR, CEC_OAR_OA, hcec->Init.OwnAddress);
+ }
+ else
+ {
+ CLEAR_BIT(hcec->Instance->OAR, CEC_OAR_OA);
+ }
+
+ hcec->gState = HAL_CEC_STATE_READY;
+ hcec->ErrorCode = HAL_CEC_ERROR_NONE;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hcec);
+
+ /* Enable the Peripheral */
+ __HAL_CEC_ENABLE(hcec);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief CEC MSP Init
+ * @param hcec: CEC handle
+ * @retval None
+ */
+ __weak void HAL_CEC_MspInit(CEC_HandleTypeDef *hcec)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcec);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_CEC_MspInit can be implemented in the user file
+ */
+}
+
+/**
+ * @brief CEC MSP DeInit
+ * @param hcec: CEC handle
+ * @retval None
+ */
+ __weak void HAL_CEC_MspDeInit(CEC_HandleTypeDef *hcec)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcec);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_CEC_MspDeInit can be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup CEC_Exported_Functions_Group2 Input and Output operation functions
+ * @brief CEC Transmit/Receive functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the CEC data transfers.
+
+ (#) The CEC handle must contain the initiator (TX side) and the destination (RX side)
+ logical addresses (4-bit long addresses, 0xF for broadcast messages destination)
+
+ (#) The communication is performed using Interrupts.
+ These API's return the HAL status.
+ The end of the data processing will be indicated through the
+ dedicated CEC IRQ when using Interrupt mode.
+ The HAL_CEC_TxCpltCallback(), HAL_CEC_RxCpltCallback() user callbacks
+ will be executed respectively at the end of the transmit or Receive process
+ The HAL_CEC_ErrorCallback() user callback will be executed when a communication
+ error is detected
+
+ (#) API's with Interrupt are :
+ (+) HAL_CEC_Transmit_IT()
+ (+) HAL_CEC_IRQHandler()
+
+ (#) A set of User Callbacks are provided:
+ (+) HAL_CEC_TxCpltCallback()
+ (+) HAL_CEC_RxCpltCallback()
+ (+) HAL_CEC_ErrorCallback()
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Send data in interrupt mode
+ * @param hcec: CEC handle
+ * @param InitiatorAddress: Initiator address
+ * @param DestinationAddress: destination logical address
+ * @param pData: pointer to input byte data buffer
+ * @param Size: amount of data to be sent in bytes (without counting the header).
+ * 0 means only the header is sent (ping operation).
+ * Maximum TX size is 15 bytes (1 opcode and up to 14 operands).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CEC_Transmit_IT(CEC_HandleTypeDef *hcec, uint8_t InitiatorAddress,uint8_t DestinationAddress, uint8_t *pData, uint32_t Size)
+{
+ /* if the IP isn't already busy and if there is no previous transmission
+ already pending due to arbitration lost */
+ if(hcec->gState == HAL_CEC_STATE_READY)
+ {
+ if((pData == NULL ) && (Size > 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ assert_param(IS_CEC_ADDRESS(DestinationAddress));
+ assert_param(IS_CEC_ADDRESS(InitiatorAddress));
+ assert_param(IS_CEC_MSGSIZE(Size));
+
+ /* Process Locked */
+ __HAL_LOCK(hcec);
+ hcec->pTxBuffPtr = pData;
+ hcec->gState = HAL_CEC_STATE_BUSY_TX;
+ hcec->ErrorCode = HAL_CEC_ERROR_NONE;
+
+ /* initialize the number of bytes to send,
+ * 0 means only one header is sent (ping operation) */
+ hcec->TxXferCount = Size;
+
+ /* send header block */
+ hcec->Instance->TXD = (uint8_t)((uint32_t)InitiatorAddress << CEC_INITIATOR_LSB_POS) | DestinationAddress;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hcec);
+
+ /* case no data to be sent, sender is only pinging the system */
+ if (Size != 0)
+ {
+ /* Set TX Start of Message (TXSOM) bit */
+ MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, CEC_FLAG_TSOM);
+ }
+ else
+ {
+ /* Send a ping command */
+ MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, CEC_FLAG_TEOM|CEC_FLAG_TSOM);
+ }
+ return HAL_OK;
+
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Get size of the received frame.
+ * @param hcec: CEC handle
+ * @retval Frame size
+ */
+uint32_t HAL_CEC_GetLastReceivedFrameSize(CEC_HandleTypeDef *hcec)
+{
+ return hcec->RxXferSize;
+}
+
+/**
+ * @brief Change Rx Buffer.
+ * @param hcec: CEC handle
+ * @param Rxbuffer: Rx Buffer
+ * @note This function can be called only inside the HAL_CEC_RxCpltCallback()
+ * @retval Frame size
+ */
+void HAL_CEC_ChangeRxBuffer(CEC_HandleTypeDef *hcec, uint8_t* Rxbuffer)
+{
+ hcec->Init.RxBuffer = Rxbuffer;
+}
+
+/**
+ * @brief This function handles CEC interrupt requests.
+ * @param hcec: CEC handle
+ * @retval None
+ */
+void HAL_CEC_IRQHandler(CEC_HandleTypeDef *hcec)
+{
+ /* Save error status register for further error handling purposes */
+ hcec->ErrorCode = READ_BIT(hcec->Instance->ESR, CEC_ESR_ALL_ERROR);
+
+ /* Transmit error */
+ if(__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TERR) != RESET)
+ {
+ /* Acknowledgement of the error */
+ __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TERR);
+
+ hcec->gState = HAL_CEC_STATE_READY;
+ }
+
+ /* Receive error */
+ if(__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_RERR) != RESET)
+ {
+ /* Acknowledgement of the error */
+ __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RERR);
+ hcec->Init.RxBuffer-=hcec->RxXferSize;
+ hcec->RxXferSize = 0U;
+ hcec->RxState = HAL_CEC_STATE_READY;
+ }
+
+ if((hcec->ErrorCode & CEC_ESR_ALL_ERROR) != 0U)
+ {
+ /* Error Call Back */
+ HAL_CEC_ErrorCallback(hcec);
+ }
+
+ /* Transmit byte request or block transfer finished */
+ if(__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TBTRF) != RESET)
+ {
+ CEC_Transmit_IT(hcec);
+ }
+
+ /* Receive byte or block transfer finished */
+ if(__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_RBTF) != RESET)
+ {
+ if(hcec->RxXferSize == 0U)
+ {
+ /* reception is starting */
+ hcec->RxState = HAL_CEC_STATE_BUSY_RX;
+ }
+ CEC_Receive_IT(hcec);
+ }
+}
+
+
+/**
+ * @brief Tx Transfer completed callback
+ * @param hcec: CEC handle
+ * @retval None
+ */
+ __weak void HAL_CEC_TxCpltCallback(CEC_HandleTypeDef *hcec)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcec);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_CEC_TxCpltCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer completed callback
+ * @param hcec: CEC handle
+ * @param RxFrameSize: Size of frame
+ * @retval None
+ */
+__weak void HAL_CEC_RxCpltCallback(CEC_HandleTypeDef *hcec, uint32_t RxFrameSize)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcec);
+ UNUSED(RxFrameSize);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_CEC_RxCpltCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief CEC error callbacks
+ * @param hcec: CEC handle
+ * @retval None
+ */
+ __weak void HAL_CEC_ErrorCallback(CEC_HandleTypeDef *hcec)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcec);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_CEC_ErrorCallback can be implemented in the user file
+ */
+}
+/**
+ * @}
+ */
+
+/** @defgroup CEC_Exported_Functions_Group3 Peripheral Control functions
+ * @brief CEC control functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control function #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the CEC.
+ (+) HAL_CEC_GetState() API can be helpful to check in run-time the state of the CEC peripheral.
+ (+) HAL_CEC_GetError() API can be helpful to check in run-time the error of the CEC peripheral.
+@endverbatim
+ * @{
+ */
+/**
+ * @brief return the CEC state
+ * @param hcec: pointer to a CEC_HandleTypeDef structure that contains
+ * the configuration information for the specified CEC module.
+ * @retval HAL state
+ */
+HAL_CEC_StateTypeDef HAL_CEC_GetState(CEC_HandleTypeDef *hcec)
+{
+ uint32_t temp1= 0x00U, temp2 = 0x00U;
+ temp1 = hcec->gState;
+ temp2 = hcec->RxState;
+
+ return (HAL_CEC_StateTypeDef)(temp1 | temp2);
+}
+
+/**
+* @brief Return the CEC error code
+* @param hcec : pointer to a CEC_HandleTypeDef structure that contains
+ * the configuration information for the specified CEC.
+* @retval CEC Error Code
+*/
+uint32_t HAL_CEC_GetError(CEC_HandleTypeDef *hcec)
+{
+ return hcec->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup CEC_Private_Functions
+ * @{
+ */
+
+ /**
+ * @brief Send data in interrupt mode
+ * @param hcec: CEC handle.
+ * Function called under interruption only, once
+ * interruptions have been enabled by HAL_CEC_Transmit_IT()
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef CEC_Transmit_IT(CEC_HandleTypeDef *hcec)
+{
+ /* if the IP is already busy or if there is a previous transmission
+ already pending due to arbitration loss */
+ if((hcec->gState == HAL_CEC_STATE_BUSY_TX) || (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) != RESET))
+ {
+ /* if all data have been sent */
+ if(hcec->TxXferCount == 0U)
+ {
+ /* Acknowledge successful completion by writing 0x00 */
+ MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, 0x00U);
+
+ hcec->gState = HAL_CEC_STATE_READY;
+
+ HAL_CEC_TxCpltCallback(hcec);
+
+ return HAL_OK;
+ }
+ else
+ {
+ /* Reduce the number of bytes to transfer by one */
+ hcec->TxXferCount--;
+
+ /* Write data to TX buffer*/
+ hcec->Instance->TXD = *hcec->pTxBuffPtr++;
+
+ /* If this is the last byte of the ongoing transmission */
+ if(hcec->TxXferCount == 0U)
+ {
+ /* Acknowledge byte request and signal end of message */
+ MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, CEC_FLAG_TEOM);
+ }
+ else
+ {
+ /* Acknowledge byte request by writing 0x00 */
+ MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, 0x00U);
+ }
+
+ return HAL_OK;
+ }
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive data in interrupt mode.
+ * @param hcec: CEC handle.
+ * Function called under interruption only, once
+ * interruptions have been enabled by HAL_CEC_Receive_IT()
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef CEC_Receive_IT(CEC_HandleTypeDef *hcec)
+{
+ static uint32_t temp;
+
+ if(hcec->RxState == HAL_CEC_STATE_BUSY_RX)
+ {
+ temp = hcec->Instance->CSR;
+
+ /* Store received data */
+ hcec->RxXferSize++;
+ *hcec->Init.RxBuffer++ = hcec->Instance->RXD;
+
+ /* Acknowledge received byte by writing 0x00 */
+ MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_RECEIVE_MASK, 0x00U);
+
+ /* If the End Of Message is reached */
+ if(HAL_IS_BIT_SET(temp, CEC_FLAG_REOM))
+ {
+ /* Interrupts are not disabled due to transmission still ongoing */
+ hcec->RxState = HAL_CEC_STATE_READY;
+
+ HAL_CEC_RxCpltCallback(hcec, hcec->RxXferSize);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* defined(STM32F100xB) || defined(STM32F100xE) */
+
+#endif /* HAL_CEC_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c
new file mode 100644
index 0000000..ba8bb63
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c
@@ -0,0 +1,521 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_cortex.c
+ * @author MCD Application Team
+ * @brief CORTEX HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the CORTEX:
+ * + Initialization and de-initialization functions
+ * + Peripheral Control functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+
+ [..]
+ *** How to configure Interrupts using CORTEX HAL driver ***
+ ===========================================================
+ [..]
+ This section provides functions allowing to configure the NVIC interrupts (IRQ).
+ The Cortex-M3 exceptions are managed by CMSIS functions.
+
+ (#) Configure the NVIC Priority Grouping using HAL_NVIC_SetPriorityGrouping()
+ function according to the following table.
+ (#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority().
+ (#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ().
+ (#) please refer to programming manual for details in how to configure priority.
+
+ -@- When the NVIC_PRIORITYGROUP_0 is selected, IRQ preemption is no more possible.
+ The pending IRQ priority will be managed only by the sub priority.
+
+ -@- IRQ priority order (sorted by highest to lowest priority):
+ (+@) Lowest preemption priority
+ (+@) Lowest sub priority
+ (+@) Lowest hardware priority (IRQ number)
+
+ [..]
+ *** How to configure Systick using CORTEX HAL driver ***
+ ========================================================
+ [..]
+ Setup SysTick Timer for time base.
+
+ (+) The HAL_SYSTICK_Config()function calls the SysTick_Config() function which
+ is a CMSIS function that:
+ (++) Configures the SysTick Reload register with value passed as function parameter.
+ (++) Configures the SysTick IRQ priority to the lowest value 0x0F.
+ (++) Resets the SysTick Counter register.
+ (++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK).
+ (++) Enables the SysTick Interrupt.
+ (++) Starts the SysTick Counter.
+
+ (+) You can change the SysTick Clock source to be HCLK_Div8 by calling the macro
+ __HAL_CORTEX_SYSTICKCLK_CONFIG(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the
+ HAL_SYSTICK_Config() function call. The __HAL_CORTEX_SYSTICKCLK_CONFIG() macro is defined
+ inside the stm32f1xx_hal_cortex.h file.
+
+ (+) You can change the SysTick IRQ priority by calling the
+ HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function
+ call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is a CMSIS function.
+
+ (+) To adjust the SysTick time base, use the following formula:
+
+ Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s)
+ (++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function
+ (++) Reload Value should not exceed 0xFFFFFF
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup CORTEX CORTEX
+ * @brief CORTEX HAL module driver
+ * @{
+ */
+
+#ifdef HAL_CORTEX_MODULE_ENABLED
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup CORTEX_Exported_Functions CORTEX Exported Functions
+ * @{
+ */
+
+
+/** @defgroup CORTEX_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de-initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides the CORTEX HAL driver functions allowing to configure Interrupts
+ Systick functionalities
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Sets the priority grouping field (preemption priority and subpriority)
+ * using the required unlock sequence.
+ * @param PriorityGroup: The priority grouping bits length.
+ * This parameter can be one of the following values:
+ * @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
+ * 4 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
+ * 3 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
+ * 2 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
+ * 1 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
+ * 0 bits for subpriority
+ * @note When the NVIC_PriorityGroup_0 is selected, IRQ preemption is no more possible.
+ * The pending IRQ priority will be managed only by the subpriority.
+ * @retval None
+ */
+void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
+
+ /* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
+ NVIC_SetPriorityGrouping(PriorityGroup);
+}
+
+/**
+ * @brief Sets the priority of an interrupt.
+ * @param IRQn: External interrupt number.
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xx.h))
+ * @param PreemptPriority: The preemption priority for the IRQn channel.
+ * This parameter can be a value between 0 and 15
+ * A lower priority value indicates a higher priority
+ * @param SubPriority: the subpriority level for the IRQ channel.
+ * This parameter can be a value between 0 and 15
+ * A lower priority value indicates a higher priority.
+ * @retval None
+ */
+void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+ uint32_t prioritygroup = 0x00U;
+
+ /* Check the parameters */
+ assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
+ assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
+
+ prioritygroup = NVIC_GetPriorityGrouping();
+
+ NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
+}
+
+/**
+ * @brief Enables a device specific interrupt in the NVIC interrupt controller.
+ * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
+ * function should be called before.
+ * @param IRQn External interrupt number.
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
+ * @retval None
+ */
+void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
+
+ /* Enable interrupt */
+ NVIC_EnableIRQ(IRQn);
+}
+
+/**
+ * @brief Disables a device specific interrupt in the NVIC interrupt controller.
+ * @param IRQn External interrupt number.
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
+ * @retval None
+ */
+void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
+
+ /* Disable interrupt */
+ NVIC_DisableIRQ(IRQn);
+}
+
+/**
+ * @brief Initiates a system reset request to reset the MCU.
+ * @retval None
+ */
+void HAL_NVIC_SystemReset(void)
+{
+ /* System Reset */
+ NVIC_SystemReset();
+}
+
+/**
+ * @brief Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+ * Counter is in free running mode to generate periodic interrupts.
+ * @param TicksNumb: Specifies the ticks Number of ticks between two interrupts.
+ * @retval status: - 0 Function succeeded.
+ * - 1 Function failed.
+ */
+uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
+{
+ return SysTick_Config(TicksNumb);
+}
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_Exported_Functions_Group2 Peripheral Control functions
+ * @brief Cortex control functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the CORTEX
+ (NVIC, SYSTICK, MPU) functionalities.
+
+
+@endverbatim
+ * @{
+ */
+
+#if (__MPU_PRESENT == 1U)
+/**
+ * @brief Disables the MPU
+ * @retval None
+ */
+void HAL_MPU_Disable(void)
+{
+ /* Make sure outstanding transfers are done */
+ __DMB();
+
+ /* Disable fault exceptions */
+ SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
+
+ /* Disable the MPU and clear the control register*/
+ MPU->CTRL = 0U;
+}
+
+/**
+ * @brief Enable the MPU.
+ * @param MPU_Control: Specifies the control mode of the MPU during hard fault,
+ * NMI, FAULTMASK and privileged access to the default memory
+ * This parameter can be one of the following values:
+ * @arg MPU_HFNMI_PRIVDEF_NONE
+ * @arg MPU_HARDFAULT_NMI
+ * @arg MPU_PRIVILEGED_DEFAULT
+ * @arg MPU_HFNMI_PRIVDEF
+ * @retval None
+ */
+void HAL_MPU_Enable(uint32_t MPU_Control)
+{
+ /* Enable the MPU */
+ MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
+
+ /* Enable fault exceptions */
+ SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
+
+ /* Ensure MPU setting take effects */
+ __DSB();
+ __ISB();
+}
+
+/**
+ * @brief Initializes and configures the Region and the memory to be protected.
+ * @param MPU_Init: Pointer to a MPU_Region_InitTypeDef structure that contains
+ * the initialization and configuration information.
+ * @retval None
+ */
+void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
+{
+ /* Check the parameters */
+ assert_param(IS_MPU_REGION_NUMBER(MPU_Init->Number));
+ assert_param(IS_MPU_REGION_ENABLE(MPU_Init->Enable));
+
+ /* Set the Region number */
+ MPU->RNR = MPU_Init->Number;
+
+ if ((MPU_Init->Enable) != RESET)
+ {
+ /* Check the parameters */
+ assert_param(IS_MPU_INSTRUCTION_ACCESS(MPU_Init->DisableExec));
+ assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(MPU_Init->AccessPermission));
+ assert_param(IS_MPU_TEX_LEVEL(MPU_Init->TypeExtField));
+ assert_param(IS_MPU_ACCESS_SHAREABLE(MPU_Init->IsShareable));
+ assert_param(IS_MPU_ACCESS_CACHEABLE(MPU_Init->IsCacheable));
+ assert_param(IS_MPU_ACCESS_BUFFERABLE(MPU_Init->IsBufferable));
+ assert_param(IS_MPU_SUB_REGION_DISABLE(MPU_Init->SubRegionDisable));
+ assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size));
+
+ MPU->RBAR = MPU_Init->BaseAddress;
+ MPU->RASR = ((uint32_t)MPU_Init->DisableExec << MPU_RASR_XN_Pos) |
+ ((uint32_t)MPU_Init->AccessPermission << MPU_RASR_AP_Pos) |
+ ((uint32_t)MPU_Init->TypeExtField << MPU_RASR_TEX_Pos) |
+ ((uint32_t)MPU_Init->IsShareable << MPU_RASR_S_Pos) |
+ ((uint32_t)MPU_Init->IsCacheable << MPU_RASR_C_Pos) |
+ ((uint32_t)MPU_Init->IsBufferable << MPU_RASR_B_Pos) |
+ ((uint32_t)MPU_Init->SubRegionDisable << MPU_RASR_SRD_Pos) |
+ ((uint32_t)MPU_Init->Size << MPU_RASR_SIZE_Pos) |
+ ((uint32_t)MPU_Init->Enable << MPU_RASR_ENABLE_Pos);
+ }
+ else
+ {
+ MPU->RBAR = 0x00U;
+ MPU->RASR = 0x00U;
+ }
+}
+#endif /* __MPU_PRESENT */
+
+/**
+ * @brief Gets the priority grouping field from the NVIC Interrupt Controller.
+ * @retval Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field)
+ */
+uint32_t HAL_NVIC_GetPriorityGrouping(void)
+{
+ /* Get the PRIGROUP[10:8] field value */
+ return NVIC_GetPriorityGrouping();
+}
+
+/**
+ * @brief Gets the priority of an interrupt.
+ * @param IRQn: External interrupt number.
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
+ * @param PriorityGroup: the priority grouping bits length.
+ * This parameter can be one of the following values:
+ * @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
+ * 4 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
+ * 3 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
+ * 2 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
+ * 1 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
+ * 0 bits for subpriority
+ * @param pPreemptPriority: Pointer on the Preemptive priority value (starting from 0).
+ * @param pSubPriority: Pointer on the Subpriority value (starting from 0).
+ * @retval None
+ */
+void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t *pPreemptPriority, uint32_t *pSubPriority)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
+ /* Get priority for Cortex-M system or device specific interrupts */
+ NVIC_DecodePriority(NVIC_GetPriority(IRQn), PriorityGroup, pPreemptPriority, pSubPriority);
+}
+
+/**
+ * @brief Sets Pending bit of an external interrupt.
+ * @param IRQn External interrupt number
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
+ * @retval None
+ */
+void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
+
+ /* Set interrupt pending */
+ NVIC_SetPendingIRQ(IRQn);
+}
+
+/**
+ * @brief Gets Pending Interrupt (reads the pending register in the NVIC
+ * and returns the pending bit for the specified interrupt).
+ * @param IRQn External interrupt number.
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
+ * @retval status: - 0 Interrupt status is not pending.
+ * - 1 Interrupt status is pending.
+ */
+uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
+
+ /* Return 1 if pending else 0 */
+ return NVIC_GetPendingIRQ(IRQn);
+}
+
+/**
+ * @brief Clears the pending bit of an external interrupt.
+ * @param IRQn External interrupt number.
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
+ * @retval None
+ */
+void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
+
+ /* Clear pending interrupt */
+ NVIC_ClearPendingIRQ(IRQn);
+}
+
+/**
+ * @brief Gets active interrupt ( reads the active register in NVIC and returns the active bit).
+ * @param IRQn External interrupt number
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
+ * @retval status: - 0 Interrupt status is not pending.
+ * - 1 Interrupt status is pending.
+ */
+uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
+
+ /* Return 1 if active else 0 */
+ return NVIC_GetActive(IRQn);
+}
+
+/**
+ * @brief Configures the SysTick clock source.
+ * @param CLKSource: specifies the SysTick clock source.
+ * This parameter can be one of the following values:
+ * @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
+ * @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
+ * @retval None
+ */
+void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)
+{
+ /* Check the parameters */
+ assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource));
+ if (CLKSource == SYSTICK_CLKSOURCE_HCLK)
+ {
+ SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
+ }
+ else
+ {
+ SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK;
+ }
+}
+
+/**
+ * @brief This function handles SYSTICK interrupt request.
+ * @retval None
+ */
+void HAL_SYSTICK_IRQHandler(void)
+{
+ HAL_SYSTICK_Callback();
+}
+
+/**
+ * @brief SYSTICK callback.
+ * @retval None
+ */
+__weak void HAL_SYSTICK_Callback(void)
+{
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SYSTICK_Callback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_CORTEX_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_crc.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_crc.c
new file mode 100644
index 0000000..dc5b630
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_crc.c
@@ -0,0 +1,346 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_crc.c
+ * @author MCD Application Team
+ * @brief CRC HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Cyclic Redundancy Check (CRC) peripheral:
+ * + Initialization and de-initialization functions
+ * + Peripheral Control functions
+ * + Peripheral State functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The CRC HAL driver can be used as follows:
+
+ (#) Enable CRC AHB clock using __HAL_RCC_CRC_CLK_ENABLE();
+
+ (#) Use HAL_CRC_Accumulate() function to compute the CRC value of
+ a 32-bit data buffer using combination of the previous CRC value
+ and the new one.
+
+ (#) Use HAL_CRC_Calculate() function to compute the CRC Value of
+ a new 32-bit data buffer. This function resets the CRC computation
+ unit before starting the computation to avoid getting wrong CRC values.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup CRC CRC
+ * @brief CRC HAL module driver.
+ * @{
+ */
+
+#ifdef HAL_CRC_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup CRC_Exported_Functions CRC Exported Functions
+ * @{
+ */
+
+/** @defgroup CRC_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions.
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de-initialization functions #####
+ ==============================================================================
+ [..] This section provides functions allowing to:
+ (+) Initialize the CRC according to the specified parameters
+ in the CRC_InitTypeDef and create the associated handle
+ (+) DeInitialize the CRC peripheral
+ (+) Initialize the CRC MSP
+ (+) DeInitialize CRC MSP
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the CRC according to the specified
+ * parameters in the CRC_InitTypeDef and creates the associated handle.
+ * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains
+ * the configuration information for CRC
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc)
+{
+ /* Check the CRC handle allocation */
+ if(hcrc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
+
+ if(hcrc->State == HAL_CRC_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hcrc->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware */
+ HAL_CRC_MspInit(hcrc);
+ }
+
+ /* Change CRC peripheral state */
+ hcrc->State = HAL_CRC_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the CRC peripheral.
+ * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains
+ * the configuration information for CRC
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CRC_DeInit(CRC_HandleTypeDef *hcrc)
+{
+ /* Check the CRC handle allocation */
+ if(hcrc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
+
+ /* Change CRC peripheral state */
+ hcrc->State = HAL_CRC_STATE_BUSY;
+
+ /* DeInit the low level hardware */
+ HAL_CRC_MspDeInit(hcrc);
+
+ /* Resets the CRC calculation unit and sets the data register to 0xFFFF FFFF */
+ __HAL_CRC_DR_RESET(hcrc);
+
+ /* Reset IDR register content */
+ CLEAR_BIT(hcrc->Instance->IDR, CRC_IDR_IDR);
+
+ /* Change CRC peripheral state */
+ hcrc->State = HAL_CRC_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hcrc);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the CRC MSP.
+ * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains
+ * the configuration information for CRC
+ * @retval None
+ */
+__weak void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcrc);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CRC_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes the CRC MSP.
+ * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains
+ * the configuration information for CRC
+ * @retval None
+ */
+__weak void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcrc);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CRC_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup CRC_Exported_Functions_Group2 Peripheral Control functions
+ * @brief management functions.
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral Control functions #####
+ ==============================================================================
+ [..] This section provides functions allowing to:
+ (+) Compute the 32-bit CRC value of 32-bit data buffer,
+ using combination of the previous CRC value and the new one.
+ (+) Compute the 32-bit CRC value of 32-bit data buffer,
+ independently of the previous CRC value.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Computes the 32-bit CRC of 32-bit data buffer using combination
+ * of the previous CRC value and the new one.
+ * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains
+ * the configuration information for CRC
+ * @param pBuffer: pointer to the buffer containing the data to be computed
+ * @param BufferLength: length of the buffer to be computed (defined in word, 4 bytes)
+ * @retval 32-bit CRC
+ */
+uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
+{
+ uint32_t index = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hcrc);
+
+ /* Change CRC peripheral state */
+ hcrc->State = HAL_CRC_STATE_BUSY;
+
+ /* Enter Data to the CRC calculator */
+ for(index = 0U; index < BufferLength; index++)
+ {
+ hcrc->Instance->DR = pBuffer[index];
+ }
+
+ /* Change CRC peripheral state */
+ hcrc->State = HAL_CRC_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hcrc);
+
+ /* Return the CRC computed value */
+ return hcrc->Instance->DR;
+}
+
+/**
+ * @brief Computes the 32-bit CRC of 32-bit data buffer independently
+ * of the previous CRC value.
+ * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains
+ * the configuration information for CRC
+ * @param pBuffer: Pointer to the buffer containing the data to be computed
+ * @param BufferLength: Length of the buffer to be computed (defined in word, 4 bytes)
+ * @retval 32-bit CRC
+ */
+uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
+{
+ uint32_t index = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hcrc);
+
+ /* Change CRC peripheral state */
+ hcrc->State = HAL_CRC_STATE_BUSY;
+
+ /* Reset CRC Calculation Unit */
+ __HAL_CRC_DR_RESET(hcrc);
+
+ /* Enter Data to the CRC calculator */
+ for(index = 0U; index < BufferLength; index++)
+ {
+ hcrc->Instance->DR = pBuffer[index];
+ }
+
+ /* Change CRC peripheral state */
+ hcrc->State = HAL_CRC_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hcrc);
+
+ /* Return the CRC computed value */
+ return hcrc->Instance->DR;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup CRC_Exported_Functions_Group3 Peripheral State functions
+ * @brief Peripheral State functions.
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral State functions #####
+ ==============================================================================
+ [..]
+ This subsection permits to get in run-time the status of the peripheral.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns the CRC state.
+ * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains
+ * the configuration information for CRC
+ * @retval HAL state
+ */
+HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc)
+{
+ return hcrc->State;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_CRC_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dac.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dac.c
new file mode 100644
index 0000000..9f8d91c
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dac.c
@@ -0,0 +1,937 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_dac.c
+ * @author MCD Application Team
+ * @brief DAC HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Digital to Analog Converter (DAC) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ * + Peripheral State and Errors functions
+ *
+ *
+ @verbatim
+ ==============================================================================
+ ##### DAC Peripheral features #####
+ ==============================================================================
+ [..]
+ *** DAC Channels ***
+ ====================
+ [..]
+ The device integrates two 12-bit Digital Analog Converters that can
+ be used independently or simultaneously (dual mode):
+ (#) DAC channel1 with DAC_OUT1 (PA4) as output
+ (#) DAC channel2 with DAC_OUT2 (PA5) as output
+
+ *** DAC Triggers ***
+ ====================
+ [..]
+ Digital to Analog conversion can be non-triggered using DAC_TRIGGER_NONE
+ and DAC_OUT1/DAC_OUT2 is available once writing to DHRx register.
+ [..]
+ Digital to Analog conversion can be triggered by:
+ (#) External event: EXTI Line 9 (any GPIOx_PIN_9) using DAC_TRIGGER_EXT_IT9.
+ The used pin (GPIOx_PIN_9) must be configured in input mode.
+
+ (#) Timers TRGO: TIM2, TIM4, TIM6, TIM7
+ For STM32F10x connectivity line devices and STM32F100x devices: TIM3
+ For STM32F10x high-density and XL-density devices: TIM8
+ For STM32F100x high-density value line devices: TIM15 as
+ replacement of TIM5.
+ (DAC_TRIGGER_T2_TRGO, DAC_TRIGGER_T4_TRGO...)
+
+ (#) Software using DAC_TRIGGER_SOFTWARE
+
+ *** DAC Buffer mode feature ***
+ ===============================
+ [..]
+ Each DAC channel integrates an output buffer that can be used to
+ reduce the output impedance, and to drive external loads directly
+ without having to add an external operational amplifier.
+ To enable, the output buffer use
+ sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
+ [..]
+ (@) Refer to the device datasheet for more details about output
+ impedance value with and without output buffer.
+
+ *** DAC connect feature ***
+ ===============================
+ [..]
+ Each DAC channel can be connected internally.
+ To connect, use
+ sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_ENABLE;
+
+ *** GPIO configurations guidelines ***
+ =====================
+ [..]
+ When a DAC channel is used (ex channel1 on PA4) and the other is not
+ (ex channel1 on PA5 is configured in Analog and disabled).
+ Channel1 may disturb channel2 as coupling effect.
+ Note that there is no coupling on channel2 as soon as channel2 is turned on.
+ Coupling on adjacent channel could be avoided as follows:
+ when unused PA5 is configured as INPUT PULL-UP or DOWN.
+ PA5 is configured in ANALOG just before it is turned on.
+
+ *** DAC wave generation feature ***
+ ===================================
+ [..]
+ Both DAC channels can be used to generate
+ (#) Noise wave using HAL_DACEx_NoiseWaveGenerate()
+ (#) Triangle wave using HAL_DACEx_TriangleWaveGenerate()
+
+ *** DAC data format ***
+ =======================
+ [..]
+ The DAC data format can be:
+ (#) 8-bit right alignment using DAC_ALIGN_8B_R
+ (#) 12-bit left alignment using DAC_ALIGN_12B_L
+ (#) 12-bit right alignment using DAC_ALIGN_12B_R
+
+ *** DAC data value to voltage correspondance ***
+ ================================================
+ [..]
+ The analog output voltage on each DAC channel pin is determined
+ by the following equation:
+ [..]
+ DAC_OUTx = VREF+ * DOR / 4095
+ (+) with DOR is the Data Output Register
+ [..]
+ VEF+ is the input voltage reference (refer to the device datasheet)
+ [..]
+ e.g. To set DAC_OUT1 to 0.7V, use
+ (+) Assuming that VREF+ = 3.3V, DAC_OUT1 = (3.3 * 868) / 4095 = 0.7V
+
+ *** DMA requests ***
+ =====================
+ [..]
+ A DMA1 request can be generated when an external trigger (but not
+ a software trigger) occurs if DMA1 requests are enabled using
+ HAL_DAC_Start_DMA()
+ [..]
+ DMA requests are mapped as following:
+ (#) DAC channel1 :
+ For STM32F100x low-density, medium-density, high-density with DAC
+ DMA remap:
+ mapped on DMA1 channel3 which must be
+ already configured
+ For STM32F100x high-density without DAC DMA remap and other
+ STM32F1 devices:
+ mapped on DMA2 channel3 which must be
+ already configured
+ (#) DAC channel2 :
+ For STM32F100x low-density, medium-density, high-density with DAC
+ DMA remap:
+ mapped on DMA1 channel4 which must be
+ already configured
+ For STM32F100x high-density without DAC DMA remap and other
+ STM32F1 devices:
+ mapped on DMA2 channel4 which must be
+ already configured
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (+) DAC APB clock must be enabled to get write access to DAC
+ registers using HAL_DAC_Init()
+ (+) Configure DAC_OUTx (DAC_OUT1: PA4, DAC_OUT2: PA5) in analog mode.
+ (+) Configure the DAC channel using HAL_DAC_ConfigChannel() function.
+ (+) Enable the DAC channel using HAL_DAC_Start() or HAL_DAC_Start_DMA functions
+
+ *** Polling mode IO operation ***
+ =================================
+ [..]
+ (+) Start the DAC peripheral using HAL_DAC_Start()
+ (+) To read the DAC last data output value, use the HAL_DAC_GetValue() function.
+ (+) Stop the DAC peripheral using HAL_DAC_Stop()
+
+ *** DMA mode IO operation ***
+ ==============================
+ [..]
+ (+) Start the DAC peripheral using HAL_DAC_Start_DMA(), at this stage the user specify the length
+ of data to be transferred at each end of conversion
+ (+) At the middle of data transfer HAL_DACEx_ConvHalfCpltCallbackCh1()or HAL_DACEx_ConvHalfCpltCallbackCh2()
+ function is executed and user can add his own code by customization of function pointer
+ HAL_DAC_ConvHalfCpltCallbackCh1 or HAL_DAC_ConvHalfCpltCallbackCh2
+ (+) At The end of data transfer HAL_DAC_ConvCpltCallbackCh1()or HAL_DAC_ConvCpltCallbackCh2()
+ function is executed and user can add his own code by customization of function pointer
+ HAL_DAC_ConvCpltCallbackCh1 or HAL_DAC_ConvCpltCallbackCh2
+ (+) In case of transfer Error, HAL_DAC_ErrorCallbackCh1() or HAL_DACEx_ErrorCallbackCh2() function is executed and user can
+ add his own code by customization of function pointer HAL_DAC_ErrorCallbackCh1 or HAL_DACEx_ErrorCallbackCh2
+ (+) For STM32F100x devices with specific feature: DMA underrun.
+ In case of DMA underrun, DAC interruption triggers and execute internal function HAL_DAC_IRQHandler.
+ HAL_DAC_DMAUnderrunCallbackCh1()or HAL_DACEx_DMAUnderrunCallbackCh2()
+ function is executed and user can add his own code by customization of function pointer
+ HAL_DAC_DMAUnderrunCallbackCh1 or HAL_DACEx_DMAUnderrunCallbackCh2
+ add his own code by customization of function pointer HAL_DAC_ErrorCallbackCh1
+ (+) Stop the DAC peripheral using HAL_DAC_Stop_DMA()
+
+ *** DAC HAL driver macros list ***
+ =============================================
+ [..]
+ Below the list of most used macros in DAC HAL driver.
+
+ (+) __HAL_DAC_ENABLE : Enable the DAC peripheral (For STM32F100x devices with specific feature: DMA underrun)
+ (+) __HAL_DAC_DISABLE : Disable the DAC peripheral (For STM32F100x devices with specific feature: DMA underrun)
+ (+) __HAL_DAC_CLEAR_FLAG: Clear the DAC's pending flags (For STM32F100x devices with specific feature: DMA underrun)
+ (+) __HAL_DAC_GET_FLAG: Get the selected DAC's flag status (For STM32F100x devices with specific feature: DMA underrun)
+
+ [..]
+ (@) You can refer to the DAC HAL driver header file for more useful macros
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup DAC DAC
+ * @brief DAC driver modules
+ * @{
+ */
+
+#ifdef HAL_DAC_MODULE_ENABLED
+#if defined (STM32F100xB) || defined (STM32F100xE) || defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC)
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions -------------------------------------------------------*/
+
+/** @defgroup DAC_Exported_Functions DAC Exported Functions
+ * @{
+ */
+
+/** @defgroup DAC_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de-initialization functions #####
+ ==============================================================================
+ [..] This section provides functions allowing to:
+ (+) Initialize and configure the DAC.
+ (+) De-initialize the DAC.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the DAC peripheral according to the specified parameters
+ * in the DAC_InitStruct.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DAC_Init(DAC_HandleTypeDef* hdac)
+{
+ /* Check DAC handle */
+ if(hdac == NULL)
+ {
+ return HAL_ERROR;
+ }
+ /* Check the parameters */
+ assert_param(IS_DAC_ALL_INSTANCE(hdac->Instance));
+
+ if(hdac->State == HAL_DAC_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hdac->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware */
+ HAL_DAC_MspInit(hdac);
+ }
+
+ /* Initialize the DAC state*/
+ hdac->State = HAL_DAC_STATE_BUSY;
+
+ /* Set DAC error code to none */
+ hdac->ErrorCode = HAL_DAC_ERROR_NONE;
+
+ /* Initialize the DAC state*/
+ hdac->State = HAL_DAC_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Deinitializes the DAC peripheral registers to their default reset values.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DAC_DeInit(DAC_HandleTypeDef* hdac)
+{
+ /* Check DAC handle */
+ if(hdac == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_DAC_ALL_INSTANCE(hdac->Instance));
+
+ /* Change DAC state */
+ hdac->State = HAL_DAC_STATE_BUSY;
+
+ /* DeInit the low level hardware */
+ HAL_DAC_MspDeInit(hdac);
+
+ /* Set DAC error code to none */
+ hdac->ErrorCode = HAL_DAC_ERROR_NONE;
+
+ /* Change DAC state */
+ hdac->State = HAL_DAC_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hdac);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the DAC MSP.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @retval None
+ */
+__weak void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdac);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_DAC_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes the DAC MSP.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @retval None
+ */
+__weak void HAL_DAC_MspDeInit(DAC_HandleTypeDef* hdac)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdac);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_DAC_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup DAC_Exported_Functions_Group2 IO operation functions
+ * @brief IO operation functions
+ *
+@verbatim
+ ==============================================================================
+ ##### IO operation functions #####
+ ==============================================================================
+ [..] This section provides functions allowing to:
+ (+) Start conversion.
+ (+) Stop conversion.
+ (+) Start conversion and enable DMA transfer.
+ (+) Stop conversion and disable DMA transfer.
+ (+) Get result of conversion.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables DAC and starts conversion of channel.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @param Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_CHANNEL_1: DAC Channel1 selected
+ * @arg DAC_CHANNEL_2: DAC Channel2 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef* hdac, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(Channel));
+
+ /* Process locked */
+ __HAL_LOCK(hdac);
+
+ /* Change DAC state */
+ hdac->State = HAL_DAC_STATE_BUSY;
+
+ /* Enable the Peripharal */
+ __HAL_DAC_ENABLE(hdac, Channel);
+
+ if(Channel == DAC_CHANNEL_1)
+ {
+ /* Check if software trigger enabled */
+ if((hdac->Instance->CR & (DAC_CR_TEN1 | DAC_CR_TSEL1)) == (DAC_CR_TEN1 | DAC_CR_TSEL1))
+ {
+ /* Enable the selected DAC software conversion */
+ SET_BIT(hdac->Instance->SWTRIGR, DAC_SWTRIGR_SWTRIG1);
+ }
+ }
+ else
+ {
+ /* Check if software trigger enabled */
+ if((hdac->Instance->CR & (DAC_CR_TEN2 | DAC_CR_TSEL2)) == (DAC_CR_TEN2 | DAC_CR_TSEL2))
+ {
+ /* Enable the selected DAC software conversion*/
+ SET_BIT(hdac->Instance->SWTRIGR, DAC_SWTRIGR_SWTRIG2);
+ }
+ }
+
+ /* Change DAC state */
+ hdac->State = HAL_DAC_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hdac);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables DAC and stop conversion of channel.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @param Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_CHANNEL_1: DAC Channel1 selected
+ * @arg DAC_CHANNEL_2: DAC Channel2 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DAC_Stop(DAC_HandleTypeDef* hdac, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(Channel));
+
+ /* Disable the Peripheral */
+ __HAL_DAC_DISABLE(hdac, Channel);
+
+ /* Change DAC state */
+ hdac->State = HAL_DAC_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Enables DAC and starts conversion of channel.
+ * Note: For STM32F100x devices with specific feature: DMA underrun.
+ * On these devices, this function enables the interruption of DMA
+ * underrun.
+ * (refer to redefinition of this function in DAC extended file)
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @param Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_CHANNEL_1: DAC Channel1 selected
+ * @arg DAC_CHANNEL_2: DAC Channel2 selected
+ * @param pData: The Source memory Buffer address.
+ * @param Length: The length of data to be transferred from memory to DAC peripheral
+ * @param Alignment: Specifies the data alignment for DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
+ * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
+ * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
+ * @retval HAL status
+ */
+__weak HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t* pData, uint32_t Length, uint32_t Alignment)
+{
+ uint32_t tmpreg = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(Channel));
+ assert_param(IS_DAC_ALIGN(Alignment));
+
+ /* Process locked */
+ __HAL_LOCK(hdac);
+
+ /* Change DAC state */
+ hdac->State = HAL_DAC_STATE_BUSY;
+
+ if(Channel == DAC_CHANNEL_1)
+ {
+ /* Set the DMA transfer complete callback for channel1 */
+ hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1;
+
+ /* Set the DMA half transfer complete callback for channel1 */
+ hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1;
+
+ /* Set the DMA error callback for channel1 */
+ hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1;
+
+ /* Enable the selected DAC channel1 DMA request */
+ SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1);
+
+ /* Case of use of channel 1 */
+ switch(Alignment)
+ {
+ case DAC_ALIGN_12B_R:
+ /* Get DHR12R1 address */
+ tmpreg = (uint32_t)&hdac->Instance->DHR12R1;
+ break;
+ case DAC_ALIGN_12B_L:
+ /* Get DHR12L1 address */
+ tmpreg = (uint32_t)&hdac->Instance->DHR12L1;
+ break;
+ case DAC_ALIGN_8B_R:
+ /* Get DHR8R1 address */
+ tmpreg = (uint32_t)&hdac->Instance->DHR8R1;
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ /* Set the DMA transfer complete callback for channel2 */
+ hdac->DMA_Handle2->XferCpltCallback = DAC_DMAConvCpltCh2;
+
+ /* Set the DMA half transfer complete callback for channel2 */
+ hdac->DMA_Handle2->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh2;
+
+ /* Set the DMA error callback for channel2 */
+ hdac->DMA_Handle2->XferErrorCallback = DAC_DMAErrorCh2;
+
+ /* Enable the selected DAC channel2 DMA request */
+ SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN2);
+
+ /* Case of use of channel 2 */
+ switch(Alignment)
+ {
+ case DAC_ALIGN_12B_R:
+ /* Get DHR12R2 address */
+ tmpreg = (uint32_t)&hdac->Instance->DHR12R2;
+ break;
+ case DAC_ALIGN_12B_L:
+ /* Get DHR12L2 address */
+ tmpreg = (uint32_t)&hdac->Instance->DHR12L2;
+ break;
+ case DAC_ALIGN_8B_R:
+ /* Get DHR8R2 address */
+ tmpreg = (uint32_t)&hdac->Instance->DHR8R2;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* Enable the DMA channel */
+ if(Channel == DAC_CHANNEL_1)
+ {
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, Length);
+ }
+ else
+ {
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, tmpreg, Length);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdac);
+
+ /* Enable the Peripharal */
+ __HAL_DAC_ENABLE(hdac, Channel);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables DAC and stop conversion of channel.
+ * Note: For STM32F100x devices with specific feature: DMA underrun.
+ * On these devices, this function disables the interruption of DMA
+ * underrun.
+ * (refer to redefinition of this function in DAC extended file)
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @param Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_CHANNEL_1: DAC Channel1 selected
+ * @arg DAC_CHANNEL_2: DAC Channel2 selected
+ * @retval HAL status
+ */
+__weak HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(Channel));
+
+ /* Disable the selected DAC channel DMA request */
+ CLEAR_BIT(hdac->Instance->CR, DAC_CR_DMAEN1 << Channel);
+
+ /* Disable the Peripharal */
+ __HAL_DAC_DISABLE(hdac, Channel);
+
+ /* Disable the DMA Channel */
+ /* Channel1 is used */
+ if (Channel == DAC_CHANNEL_1)
+ {
+ status = HAL_DMA_Abort(hdac->DMA_Handle1);
+ }
+ else /* Channel2 is used for */
+ {
+ status = HAL_DMA_Abort(hdac->DMA_Handle2);
+ }
+
+ /* Check if DMA Channel effectively disabled */
+ if (status != HAL_OK)
+ {
+ /* Update ADC state machine to error */
+ hdac->State = HAL_DAC_STATE_ERROR;
+ }
+ else
+ {
+ /* Change DAC state */
+ hdac->State = HAL_DAC_STATE_READY;
+ }
+
+ /* Return function status */
+ return status;
+}
+
+/**
+ * @brief Returns the last data output value of the selected DAC channel.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @param Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_CHANNEL_1: DAC Channel1 selected
+ * @arg DAC_CHANNEL_2: DAC Channel2 selected
+ * @retval The selected DAC channel data output value.
+ */
+uint32_t HAL_DAC_GetValue(DAC_HandleTypeDef* hdac, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(Channel));
+
+ /* Returns the DAC channel data output register value */
+ if(Channel == DAC_CHANNEL_1)
+ {
+ return hdac->Instance->DOR1;
+ }
+ else
+ {
+ return hdac->Instance->DOR2;
+ }
+}
+
+/**
+ * @brief Conversion complete callback in non blocking mode for Channel1
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @retval None
+ */
+__weak void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef* hdac)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdac);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_DAC_ConvCpltCallbackCh1 could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Conversion half DMA transfer callback in non blocking mode for Channel1
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @retval None
+ */
+__weak void HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef* hdac)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdac);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_DAC_ConvHalfCpltCallbackCh1 could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Error DAC callback for Channel1.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @retval None
+ */
+__weak void HAL_DAC_ErrorCallbackCh1(DAC_HandleTypeDef *hdac)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdac);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_DAC_ErrorCallbackCh1 could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup DAC_Exported_Functions_Group3 Peripheral Control functions
+ * @brief Peripheral Control functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral Control functions #####
+ ==============================================================================
+ [..] This section provides functions allowing to:
+ (+) Configure channels.
+ (+) Set the specified data holding register value for DAC channel.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the selected DAC channel.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @param sConfig: DAC configuration structure.
+ * @param Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_CHANNEL_1: DAC Channel1 selected
+ * @arg DAC_CHANNEL_2: DAC Channel2 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DAC_ConfigChannel(DAC_HandleTypeDef* hdac, DAC_ChannelConfTypeDef* sConfig, uint32_t Channel)
+{
+ uint32_t tmpreg1 = 0U;
+
+ /* Check the DAC parameters */
+ assert_param(IS_DAC_TRIGGER(sConfig->DAC_Trigger));
+ assert_param(IS_DAC_OUTPUT_BUFFER_STATE(sConfig->DAC_OutputBuffer));
+ assert_param(IS_DAC_CHANNEL(Channel));
+
+ /* Process locked */
+ __HAL_LOCK(hdac);
+
+ /* Change DAC state */
+ hdac->State = HAL_DAC_STATE_BUSY;
+
+ /* Configure for the selected DAC channel: buffer output, trigger */
+ /* Set TSELx and TENx bits according to DAC_Trigger value */
+ /* Set BOFFx bit according to DAC_OutputBuffer value */
+ SET_BIT(tmpreg1, (sConfig->DAC_Trigger | sConfig->DAC_OutputBuffer));
+
+ /* Clear BOFFx, TENx, TSELx, WAVEx and MAMPx bits */
+ /* Calculate CR register value depending on DAC_Channel */
+ MODIFY_REG(hdac->Instance->CR,
+ ((uint32_t)(DAC_CR_MAMP1 | DAC_CR_WAVE1 | DAC_CR_TSEL1 | DAC_CR_TEN1 | DAC_CR_BOFF1)) << Channel,
+ tmpreg1 << Channel);
+
+ /* Disable wave generation */
+ hdac->Instance->CR &= ~(DAC_CR_WAVE1 << Channel);
+
+ /* Change DAC state */
+ hdac->State = HAL_DAC_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hdac);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Set the specified data holding register value for DAC channel.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @param Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_CHANNEL_1: DAC Channel1 selected
+ * @arg DAC_CHANNEL_2: DAC Channel2 selected
+ * @param Alignment: Specifies the data alignment.
+ * This parameter can be one of the following values:
+ * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
+ * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
+ * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
+ * @param Data: Data to be loaded in the selected data holding register.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data)
+{
+ __IO uint32_t tmp = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(Channel));
+ assert_param(IS_DAC_ALIGN(Alignment));
+ assert_param(IS_DAC_DATA(Data));
+
+ tmp = (uint32_t)hdac->Instance;
+ if(Channel == DAC_CHANNEL_1)
+ {
+ tmp += DAC_DHR12R1_ALIGNMENT(Alignment);
+ }
+ else
+ {
+ tmp += DAC_DHR12R2_ALIGNMENT(Alignment);
+ }
+
+ /* Set the DAC channel selected data holding register */
+ *(__IO uint32_t *) tmp = Data;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup DAC_Exported_Functions_Group4 Peripheral State and Errors functions
+ * @brief Peripheral State and Errors functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral State and Errors functions #####
+ ==============================================================================
+ [..]
+ This subsection provides functions allowing to
+ (+) Check the DAC state.
+ (+) Check the DAC Errors.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief return the DAC state
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @retval HAL state
+ */
+HAL_DAC_StateTypeDef HAL_DAC_GetState(DAC_HandleTypeDef* hdac)
+{
+ /* Return DAC state */
+ return hdac->State;
+}
+
+
+/**
+ * @brief Return the DAC error code
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @retval DAC Error Code
+ */
+uint32_t HAL_DAC_GetError(DAC_HandleTypeDef *hdac)
+{
+ return hdac->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup DAC_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief DMA conversion complete callback.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+void DAC_DMAConvCpltCh1(DMA_HandleTypeDef *hdma)
+{
+ DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ HAL_DAC_ConvCpltCallbackCh1(hdac);
+
+ hdac->State = HAL_DAC_STATE_READY;
+}
+
+/**
+ * @brief DMA half transfer complete callback.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+void DAC_DMAHalfConvCpltCh1(DMA_HandleTypeDef *hdma)
+{
+ DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ /* Conversion complete callback */
+ HAL_DAC_ConvHalfCpltCallbackCh1(hdac);
+}
+
+/**
+ * @brief DMA error callback
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+void DAC_DMAErrorCh1(DMA_HandleTypeDef *hdma)
+{
+ DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ /* Set DAC error code to DMA error */
+ hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
+
+ HAL_DAC_ErrorCallbackCh1(hdac);
+
+ hdac->State = HAL_DAC_STATE_READY;
+}
+
+/**
+ * @}
+ */
+
+#endif /* STM32F100xB || STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
+#endif /* HAL_DAC_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dac_ex.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dac_ex.c
new file mode 100644
index 0000000..486d9ec
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dac_ex.c
@@ -0,0 +1,667 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_dac_ex.c
+ * @author MCD Application Team
+ * @brief DAC HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of DAC extension peripheral:
+ * + Extended features functions
+ *
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (+) When Dual mode is enabled (i.e DAC Channel1 and Channel2 are used simultaneously) :
+ Use HAL_DACEx_DualGetValue() to get digital data to be converted and use
+ HAL_DACEx_DualSetValue() to set digital value to converted simultaneously in Channel 1 and Channel 2.
+ (+) Use HAL_DACEx_TriangleWaveGenerate() to generate Triangle signal.
+ (+) Use HAL_DACEx_NoiseWaveGenerate() to generate Noise signal.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup DACEx DACEx
+ * @brief DACEx driver module
+ * @{
+ */
+
+#ifdef HAL_DAC_MODULE_ENABLED
+#if defined (STM32F100xB) || defined (STM32F100xE) || defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC)
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup DACEx_Exported_Functions DACEx Exported Functions
+ * @{
+ */
+
+/** @defgroup DACEx_Exported_Functions_Group1 Extended features functions
+ * @brief Extended features functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Extended features functions #####
+ ==============================================================================
+ [..] This section provides functions allowing to:
+ (+) Start conversion.
+ (+) Stop conversion.
+ (+) Start conversion and enable DMA transfer.
+ (+) Stop conversion and disable DMA transfer.
+ (+) Get result of conversion.
+ (+) Get result of dual mode conversion.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns the last data output value of the selected DAC channel.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @retval The selected DAC channel data output value.
+ */
+uint32_t HAL_DACEx_DualGetValue(DAC_HandleTypeDef* hdac)
+{
+ uint32_t tmp = 0U;
+
+ tmp |= hdac->Instance->DOR1;
+
+ tmp |= hdac->Instance->DOR2 << 16U;
+
+ /* Returns the DAC channel data output register value */
+ return tmp;
+}
+
+/**
+ * @brief Enables or disables the selected DAC channel wave generation.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @param Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * DAC_CHANNEL_1 / DAC_CHANNEL_2
+ * @param Amplitude: Select max triangle amplitude.
+ * This parameter can be one of the following values:
+ * @arg DAC_TRIANGLEAMPLITUDE_1: Select max triangle amplitude of 1
+ * @arg DAC_TRIANGLEAMPLITUDE_3: Select max triangle amplitude of 3
+ * @arg DAC_TRIANGLEAMPLITUDE_7: Select max triangle amplitude of 7
+ * @arg DAC_TRIANGLEAMPLITUDE_15: Select max triangle amplitude of 15
+ * @arg DAC_TRIANGLEAMPLITUDE_31: Select max triangle amplitude of 31
+ * @arg DAC_TRIANGLEAMPLITUDE_63: Select max triangle amplitude of 63
+ * @arg DAC_TRIANGLEAMPLITUDE_127: Select max triangle amplitude of 127
+ * @arg DAC_TRIANGLEAMPLITUDE_255: Select max triangle amplitude of 255
+ * @arg DAC_TRIANGLEAMPLITUDE_511: Select max triangle amplitude of 511
+ * @arg DAC_TRIANGLEAMPLITUDE_1023: Select max triangle amplitude of 1023
+ * @arg DAC_TRIANGLEAMPLITUDE_2047: Select max triangle amplitude of 2047
+ * @arg DAC_TRIANGLEAMPLITUDE_4095: Select max triangle amplitude of 4095
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Amplitude)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(Channel));
+ assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
+
+ /* Process locked */
+ __HAL_LOCK(hdac);
+
+ /* Change DAC state */
+ hdac->State = HAL_DAC_STATE_BUSY;
+
+ /* Enable the selected wave generation for the selected DAC channel */
+ MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1)|(DAC_CR_MAMP1))<State = HAL_DAC_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hdac);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Enables or disables the selected DAC channel wave generation.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @param Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * DAC_CHANNEL_1 / DAC_CHANNEL_2
+ * @param Amplitude: Unmask DAC channel LFSR for noise wave generation.
+ * This parameter can be one of the following values:
+ * @arg DAC_LFSRUNMASK_BIT0: Unmask DAC channel LFSR bit0 for noise wave generation
+ * @arg DAC_LFSRUNMASK_BITS1_0: Unmask DAC channel LFSR bit[1:0] for noise wave generation
+ * @arg DAC_LFSRUNMASK_BITS2_0: Unmask DAC channel LFSR bit[2:0] for noise wave generation
+ * @arg DAC_LFSRUNMASK_BITS3_0: Unmask DAC channel LFSR bit[3:0] for noise wave generation
+ * @arg DAC_LFSRUNMASK_BITS4_0: Unmask DAC channel LFSR bit[4:0] for noise wave generation
+ * @arg DAC_LFSRUNMASK_BITS5_0: Unmask DAC channel LFSR bit[5:0] for noise wave generation
+ * @arg DAC_LFSRUNMASK_BITS6_0: Unmask DAC channel LFSR bit[6:0] for noise wave generation
+ * @arg DAC_LFSRUNMASK_BITS7_0: Unmask DAC channel LFSR bit[7:0] for noise wave generation
+ * @arg DAC_LFSRUNMASK_BITS8_0: Unmask DAC channel LFSR bit[8:0] for noise wave generation
+ * @arg DAC_LFSRUNMASK_BITS9_0: Unmask DAC channel LFSR bit[9:0] for noise wave generation
+ * @arg DAC_LFSRUNMASK_BITS10_0: Unmask DAC channel LFSR bit[10:0] for noise wave generation
+ * @arg DAC_LFSRUNMASK_BITS11_0: Unmask DAC channel LFSR bit[11:0] for noise wave generation
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Amplitude)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(Channel));
+ assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
+
+ /* Process locked */
+ __HAL_LOCK(hdac);
+
+ /* Change DAC state */
+ hdac->State = HAL_DAC_STATE_BUSY;
+
+ /* Enable the selected wave generation for the selected DAC channel */
+ MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1)|(DAC_CR_MAMP1))<State = HAL_DAC_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hdac);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Set the specified data holding register value for dual DAC channel.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @param Alignment: Specifies the data alignment for dual channel DAC.
+ * This parameter can be one of the following values:
+ * DAC_ALIGN_8B_R: 8bit right data alignment selected
+ * DAC_ALIGN_12B_L: 12bit left data alignment selected
+ * DAC_ALIGN_12B_R: 12bit right data alignment selected
+ * @param Data1: Data for DAC Channel2 to be loaded in the selected data holding register.
+ * @param Data2: Data for DAC Channel1 to be loaded in the selected data holding register.
+ * @note In dual mode, a unique register access is required to write in both
+ * DAC channels at the same time.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef* hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2)
+{
+ uint32_t data = 0U, tmp = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_DAC_ALIGN(Alignment));
+ assert_param(IS_DAC_DATA(Data1));
+ assert_param(IS_DAC_DATA(Data2));
+
+ /* Calculate and set dual DAC data holding register value */
+ if (Alignment == DAC_ALIGN_8B_R)
+ {
+ data = ((uint32_t)Data2 << 8U) | Data1;
+ }
+ else
+ {
+ data = ((uint32_t)Data2 << 16U) | Data1;
+ }
+
+ tmp = (uint32_t)hdac->Instance;
+ tmp += DAC_DHR12RD_ALIGNMENT(Alignment);
+
+ /* Set the dual DAC selected data holding register */
+ *(__IO uint32_t *)tmp = data;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Conversion complete callback in non blocking mode for Channel2
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @retval None
+ */
+__weak void HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef* hdac)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdac);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_DACEx_ConvCpltCallbackCh2 could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Conversion half DMA transfer callback in non blocking mode for Channel2
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @retval None
+ */
+__weak void HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef* hdac)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdac);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_DACEx_ConvHalfCpltCallbackCh2 could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Error DAC callback for Channel2.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @retval None
+ */
+__weak void HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef *hdac)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdac);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_DACEx_ErrorCallbackCh2 could be implemented in the user file
+ */
+}
+
+#if defined (STM32F100xB) || defined (STM32F100xE)
+/**
+ * @brief DMA underrun DAC callback for channel1.
+ * Note: For STM32F100x devices with specific feature: DMA underrun.
+ * On these devices, this function uses the interruption of DMA
+ * underrun.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @retval None
+ */
+__weak void HAL_DAC_DMAUnderrunCallbackCh1(DAC_HandleTypeDef *hdac)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdac);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_DAC_DMAUnderrunCallbackCh1 could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DMA underrun DAC callback for channel2.
+ * Note: For STM32F100x devices with specific feature: DMA underrun.
+ * On these devices, this function uses the interruption of DMA
+ * underrun.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @retval None
+ */
+__weak void HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef *hdac)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdac);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_DACEx_DMAUnderrunCallbackCh2 could be implemented in the user file
+ */
+}
+#endif /* STM32F100xB) || defined (STM32F100xE) */
+
+/**
+ * @}
+ */
+
+#if defined (STM32F100xB) || defined (STM32F100xE)
+/**
+ * @brief Enables DAC and starts conversion of channel.
+ * Note: For STM32F100x devices with specific feature: DMA underrun.
+ * On these devices, this function enables the interruption of DMA
+ * underrun.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @param Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_CHANNEL_1: DAC Channel1 selected
+ * @arg DAC_CHANNEL_2: DAC Channel2 selected
+ * @param pData: The destination peripheral Buffer address.
+ * @param Length: The length of data to be transferred from memory to DAC peripheral
+ * @param Alignment: Specifies the data alignment for DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
+ * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
+ * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t* pData, uint32_t Length, uint32_t Alignment)
+{
+ uint32_t tmpreg = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(Channel));
+ assert_param(IS_DAC_ALIGN(Alignment));
+
+ /* Process locked */
+ __HAL_LOCK(hdac);
+
+ /* Change DAC state */
+ hdac->State = HAL_DAC_STATE_BUSY;
+
+ if(Channel == DAC_CHANNEL_1)
+ {
+ /* Set the DMA transfer complete callback for channel1 */
+ hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1;
+
+ /* Set the DMA half transfer complete callback for channel1 */
+ hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1;
+
+ /* Set the DMA error callback for channel1 */
+ hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1;
+
+ /* Enable the selected DAC channel1 DMA request */
+ SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1);
+
+ /* Case of use of channel 1 */
+ switch(Alignment)
+ {
+ case DAC_ALIGN_12B_R:
+ /* Get DHR12R1 address */
+ tmpreg = (uint32_t)&hdac->Instance->DHR12R1;
+ break;
+ case DAC_ALIGN_12B_L:
+ /* Get DHR12L1 address */
+ tmpreg = (uint32_t)&hdac->Instance->DHR12L1;
+ break;
+ case DAC_ALIGN_8B_R:
+ /* Get DHR8R1 address */
+ tmpreg = (uint32_t)&hdac->Instance->DHR8R1;
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ /* Set the DMA transfer complete callback for channel2 */
+ hdac->DMA_Handle2->XferCpltCallback = DAC_DMAConvCpltCh2;
+
+ /* Set the DMA half transfer complete callback for channel2 */
+ hdac->DMA_Handle2->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh2;
+
+ /* Set the DMA error callback for channel2 */
+ hdac->DMA_Handle2->XferErrorCallback = DAC_DMAErrorCh2;
+
+ /* Enable the selected DAC channel2 DMA request */
+ SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN2);
+
+ /* Case of use of channel 2 */
+ switch(Alignment)
+ {
+ case DAC_ALIGN_12B_R:
+ /* Get DHR12R2 address */
+ tmpreg = (uint32_t)&hdac->Instance->DHR12R2;
+ break;
+ case DAC_ALIGN_12B_L:
+ /* Get DHR12L2 address */
+ tmpreg = (uint32_t)&hdac->Instance->DHR12L2;
+ break;
+ case DAC_ALIGN_8B_R:
+ /* Get DHR8R2 address */
+ tmpreg = (uint32_t)&hdac->Instance->DHR8R2;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* Enable the DMA channel */
+ if(Channel == DAC_CHANNEL_1)
+ {
+ /* Enable the DAC DMA underrun interrupt */
+ __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1);
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, Length);
+ }
+ else
+ {
+ /* Enable the DAC DMA underrun interrupt */
+ __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR2);
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, tmpreg, Length);
+ }
+
+ /* Enable the Peripharal */
+ __HAL_DAC_ENABLE(hdac, Channel);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdac);
+
+ /* Return function status */
+ return HAL_OK;
+}
+#endif /* STM32F100xB) || defined (STM32F100xE) */
+
+#if defined (STM32F100xB) || defined (STM32F100xE)
+/**
+ * @brief Disables DAC and stop conversion of channel.
+ * Note: For STM32F100x devices with specific feature: DMA underrun.
+ * On these devices, this function disables the interruption of DMA
+ * underrun.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @param Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_CHANNEL_1: DAC Channel1 selected
+ * @arg DAC_CHANNEL_2: DAC Channel2 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(Channel));
+
+ /* Disable the selected DAC channel DMA request */
+ hdac->Instance->CR &= ~(DAC_CR_DMAEN1 << Channel);
+
+ /* Disable the Peripharal */
+ __HAL_DAC_DISABLE(hdac, Channel);
+
+ /* Disable the DMA Channel */
+ /* Channel1 is used */
+ if(Channel == DAC_CHANNEL_1)
+ {
+ /* Disable the DMA channel */
+ status = HAL_DMA_Abort(hdac->DMA_Handle1);
+
+ /* Disable the DAC DMA underrun interrupt */
+ __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR1);
+ }
+ else /* Channel2 is used for */
+ {
+ /* Disable the DMA channel */
+ status = HAL_DMA_Abort(hdac->DMA_Handle2);
+
+ /* Disable the DAC DMA underrun interrupt */
+ __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR2);
+ }
+
+ /* Check if DMA Channel effectively disabled */
+ if(status != HAL_OK)
+ {
+ /* Update ADC state machine to error */
+ hdac->State = HAL_DAC_STATE_ERROR;
+ }
+ else
+ {
+ /* Change DAC state */
+ hdac->State = HAL_DAC_STATE_READY;
+ }
+
+ /* Return function status */
+ return status;
+}
+#endif /* STM32F100xB) || defined (STM32F100xE) */
+
+#if defined (STM32F100xB) || defined (STM32F100xE)
+/**
+ * @brief Handles DAC interrupt request
+ * Note: For STM32F100x devices with specific feature: DMA underrun.
+ * On these devices, this function uses the interruption of DMA
+ * underrun.
+ * @param hdac: pointer to a DAC_HandleTypeDef structure that contains
+ * the configuration information for the specified DAC.
+ * @retval None
+ */
+void HAL_DAC_IRQHandler(DAC_HandleTypeDef* hdac)
+{
+
+ if(__HAL_DAC_GET_IT_SOURCE(hdac, DAC_IT_DMAUDR1))
+ {
+ /* Check underrun flag of DAC channel 1 */
+ if(__HAL_DAC_GET_FLAG(hdac, DAC_FLAG_DMAUDR1))
+ {
+ /* Change DAC state to error state */
+ hdac->State = HAL_DAC_STATE_ERROR;
+
+ /* Set DAC error code to chanel1 DMA underrun error */
+ SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_DMAUNDERRUNCH1);
+
+ /* Clear the underrun flag */
+ __HAL_DAC_CLEAR_FLAG(hdac,DAC_FLAG_DMAUDR1);
+
+ /* Disable the selected DAC channel1 DMA request */
+ CLEAR_BIT(hdac->Instance->CR, DAC_CR_DMAEN1);
+
+ /* Error callback */
+ HAL_DAC_DMAUnderrunCallbackCh1(hdac);
+ }
+ }
+
+ if(__HAL_DAC_GET_IT_SOURCE(hdac, DAC_IT_DMAUDR2))
+ {
+ /* Check underrun flag of DAC channel 2 */
+ if(__HAL_DAC_GET_FLAG(hdac, DAC_FLAG_DMAUDR2))
+ {
+ /* Change DAC state to error state */
+ hdac->State = HAL_DAC_STATE_ERROR;
+
+ /* Set DAC error code to channel2 DMA underrun error */
+ SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_DMAUNDERRUNCH2);
+
+ /* Clear the underrun flag */
+ __HAL_DAC_CLEAR_FLAG(hdac,DAC_FLAG_DMAUDR2);
+
+ /* Disable the selected DAC channel1 DMA request */
+ CLEAR_BIT(hdac->Instance->CR, DAC_CR_DMAEN2);
+
+ /* Error callback */
+ HAL_DACEx_DMAUnderrunCallbackCh2(hdac);
+ }
+ }
+}
+#endif /* STM32F100xB || STM32F100xE */
+
+
+/**
+ * @}
+ */
+
+/** @defgroup DACEx_Private_Functions DACEx Private Functions
+ * @{
+ */
+
+/**
+ * @brief DMA conversion complete callback.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma)
+{
+ DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ HAL_DACEx_ConvCpltCallbackCh2(hdac);
+
+ hdac->State= HAL_DAC_STATE_READY;
+}
+
+/**
+ * @brief DMA half transfer complete callback.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma)
+{
+ DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ /* Conversion complete callback */
+ HAL_DACEx_ConvHalfCpltCallbackCh2(hdac);
+}
+
+/**
+ * @brief DMA error callback
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma)
+{
+ DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ /* Set DAC error code to DMA error */
+ hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
+
+ HAL_DACEx_ErrorCallbackCh2(hdac);
+
+ hdac->State= HAL_DAC_STATE_READY;
+}
+
+/**
+ * @}
+ */
+
+#endif /* STM32F100xB || STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
+#endif /* HAL_DAC_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c
new file mode 100644
index 0000000..d3989c2
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c
@@ -0,0 +1,902 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_dma.c
+ * @author MCD Application Team
+ * @brief DMA HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Direct Memory Access (DMA) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral State and errors functions
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) Enable and configure the peripheral to be connected to the DMA Channel
+ (except for internal SRAM / FLASH memories: no initialization is
+ necessary). Please refer to the Reference manual for connection between peripherals
+ and DMA requests.
+
+ (#) For a given Channel, program the required configuration through the following parameters:
+ Channel request, Transfer Direction, Source and Destination data formats,
+ Circular or Normal mode, Channel Priority level, Source and Destination Increment mode
+ using HAL_DMA_Init() function.
+
+ (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
+ detection.
+
+ (#) Use HAL_DMA_Abort() function to abort the current transfer
+
+ -@- In Memory-to-Memory transfer mode, Circular mode is not allowed.
+ *** Polling mode IO operation ***
+ =================================
+ [..]
+ (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source
+ address and destination address and the Length of data to be transferred
+ (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this
+ case a fixed Timeout can be configured by User depending from his application.
+
+ *** Interrupt mode IO operation ***
+ ===================================
+ [..]
+ (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
+ (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
+ (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of
+ Source address and destination address and the Length of data to be transferred.
+ In this case the DMA interrupt is configured
+ (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
+ (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can
+ add his own function by customization of function pointer XferCpltCallback and
+ XferErrorCallback (i.e. a member of DMA handle structure).
+
+ *** DMA HAL driver macros list ***
+ =============================================
+ [..]
+ Below the list of most used macros in DMA HAL driver.
+
+ (+) __HAL_DMA_ENABLE: Enable the specified DMA Channel.
+ (+) __HAL_DMA_DISABLE: Disable the specified DMA Channel.
+ (+) __HAL_DMA_GET_FLAG: Get the DMA Channel pending flags.
+ (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Channel pending flags.
+ (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Channel interrupts.
+ (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Channel interrupts.
+ (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Channel interrupt has occurred or not.
+
+ [..]
+ (@) You can refer to the DMA HAL driver header file for more useful macros
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup DMA DMA
+ * @brief DMA HAL module driver
+ * @{
+ */
+
+#ifdef HAL_DMA_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup DMA_Private_Functions DMA Private Functions
+ * @{
+ */
+static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+
+/** @defgroup DMA_Exported_Functions DMA Exported Functions
+ * @{
+ */
+
+/** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and de-initialization functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..]
+ This section provides functions allowing to initialize the DMA Channel source
+ and destination addresses, incrementation and data sizes, transfer direction,
+ circular/normal mode selection, memory-to-memory mode selection and Channel priority value.
+ [..]
+ The HAL_DMA_Init() function follows the DMA configuration procedures as described in
+ reference manual.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initialize the DMA according to the specified
+ * parameters in the DMA_InitTypeDef and initialize the associated handle.
+ * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
+{
+ uint32_t tmp = 0U;
+
+ /* Check the DMA handle allocation */
+ if(hdma == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
+ assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
+ assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
+ assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
+ assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
+ assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
+ assert_param(IS_DMA_MODE(hdma->Init.Mode));
+ assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
+
+#if defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F100xE) || defined (STM32F105xC) || defined (STM32F107xC)
+ /* calculation of the channel index */
+ if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
+ {
+ /* DMA1 */
+ hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
+ hdma->DmaBaseAddress = DMA1;
+ }
+ else
+ {
+ /* DMA2 */
+ hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2;
+ hdma->DmaBaseAddress = DMA2;
+ }
+#else
+ /* DMA1 */
+ hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
+ hdma->DmaBaseAddress = DMA1;
+#endif /* STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG || STM32F100xE || STM32F105xC || STM32F107xC */
+
+ /* Change DMA peripheral state */
+ hdma->State = HAL_DMA_STATE_BUSY;
+
+ /* Get the CR register value */
+ tmp = hdma->Instance->CCR;
+
+ /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */
+ tmp &= ((uint32_t)~(DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | \
+ DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | \
+ DMA_CCR_DIR));
+
+ /* Prepare the DMA Channel configuration */
+ tmp |= hdma->Init.Direction |
+ hdma->Init.PeriphInc | hdma->Init.MemInc |
+ hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
+ hdma->Init.Mode | hdma->Init.Priority;
+
+ /* Write to DMA Channel CR register */
+ hdma->Instance->CCR = tmp;
+
+ /* Initialise the error code */
+ hdma->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ /* Initialize the DMA state*/
+ hdma->State = HAL_DMA_STATE_READY;
+ /* Allocate lock resource and initialize it */
+ hdma->Lock = HAL_UNLOCKED;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitialize the DMA peripheral.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
+{
+ /* Check the DMA handle allocation */
+ if(hdma == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
+
+ /* Disable the selected DMA Channelx */
+ __HAL_DMA_DISABLE(hdma);
+
+ /* Reset DMA Channel control register */
+ hdma->Instance->CCR = 0U;
+
+ /* Reset DMA Channel Number of Data to Transfer register */
+ hdma->Instance->CNDTR = 0U;
+
+ /* Reset DMA Channel peripheral address register */
+ hdma->Instance->CPAR = 0U;
+
+ /* Reset DMA Channel memory address register */
+ hdma->Instance->CMAR = 0U;
+
+#if defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F100xE) || defined (STM32F105xC) || defined (STM32F107xC)
+ /* calculation of the channel index */
+ if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
+ {
+ /* DMA1 */
+ hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
+ hdma->DmaBaseAddress = DMA1;
+ }
+ else
+ {
+ /* DMA2 */
+ hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2;
+ hdma->DmaBaseAddress = DMA2;
+ }
+#else
+ /* DMA1 */
+ hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
+ hdma->DmaBaseAddress = DMA1;
+#endif /* STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG || STM32F100xE || STM32F105xC || STM32F107xC */
+
+ /* Clear all flags */
+ hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex));
+
+ /* Clean all callbacks */
+ hdma->XferCpltCallback = NULL;
+ hdma->XferHalfCpltCallback = NULL;
+ hdma->XferErrorCallback = NULL;
+ hdma->XferAbortCallback = NULL;
+
+ /* Reset the error code */
+ hdma->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ /* Reset the DMA state */
+ hdma->State = HAL_DMA_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hdma);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions
+ * @brief Input and Output operation functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Configure the source, destination address and data length and Start DMA transfer
+ (+) Configure the source, destination address and data length and
+ Start DMA transfer with interrupt
+ (+) Abort DMA transfer
+ (+) Poll for transfer complete
+ (+) Handle DMA interrupt request
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Start the DMA Transfer.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @param SrcAddress: The source memory Buffer address
+ * @param DstAddress: The destination memory Buffer address
+ * @param DataLength: The length of data to be transferred from source to destination
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_DMA_BUFFER_SIZE(DataLength));
+
+ /* Process locked */
+ __HAL_LOCK(hdma);
+
+ if(HAL_DMA_STATE_READY == hdma->State)
+ {
+ /* Change DMA peripheral state */
+ hdma->State = HAL_DMA_STATE_BUSY;
+ hdma->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ /* Disable the peripheral */
+ __HAL_DMA_DISABLE(hdma);
+
+ /* Configure the source, destination address and the data length & clear flags*/
+ DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
+
+ /* Enable the Peripheral */
+ __HAL_DMA_ENABLE(hdma);
+ }
+ else
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+ status = HAL_BUSY;
+ }
+ return status;
+}
+
+/**
+ * @brief Start the DMA Transfer with interrupt enabled.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @param SrcAddress: The source memory Buffer address
+ * @param DstAddress: The destination memory Buffer address
+ * @param DataLength: The length of data to be transferred from source to destination
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_DMA_BUFFER_SIZE(DataLength));
+
+ /* Process locked */
+ __HAL_LOCK(hdma);
+
+ if(HAL_DMA_STATE_READY == hdma->State)
+ {
+ /* Change DMA peripheral state */
+ hdma->State = HAL_DMA_STATE_BUSY;
+ hdma->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ /* Disable the peripheral */
+ __HAL_DMA_DISABLE(hdma);
+
+ /* Configure the source, destination address and the data length & clear flags*/
+ DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
+
+ /* Enable the transfer complete interrupt */
+ /* Enable the transfer Error interrupt */
+ if(NULL != hdma->XferHalfCpltCallback)
+ {
+ /* Enable the Half transfer complete interrupt as well */
+ __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
+ }
+ else
+ {
+ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
+ __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_TE));
+ }
+ /* Enable the Peripheral */
+ __HAL_DMA_ENABLE(hdma);
+ }
+ else
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ /* Remain BUSY */
+ status = HAL_BUSY;
+ }
+ return status;
+}
+
+/**
+ * @brief Abort the DMA Transfer.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Disable DMA IT */
+ __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
+
+ /* Disable the channel */
+ __HAL_DMA_DISABLE(hdma);
+
+ /* Clear all flags */
+ hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
+
+ /* Change the DMA state */
+ hdma->State = HAL_DMA_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ return status;
+}
+
+/**
+ * @brief Aborts the DMA Transfer in Interrupt mode.
+ * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if(HAL_DMA_STATE_BUSY != hdma->State)
+ {
+ /* no transfer ongoing */
+ hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
+
+ status = HAL_ERROR;
+ }
+ else
+ {
+ /* Disable DMA IT */
+ __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
+
+ /* Disable the channel */
+ __HAL_DMA_DISABLE(hdma);
+
+ /* Clear all flags */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_GI_FLAG_INDEX(hdma));
+
+ /* Change the DMA state */
+ hdma->State = HAL_DMA_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ /* Call User Abort callback */
+ if(hdma->XferAbortCallback != NULL)
+ {
+ hdma->XferAbortCallback(hdma);
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief Polling for transfer complete.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @param CompleteLevel: Specifies the DMA level complete.
+ * @param Timeout: Timeout duration.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
+{
+ uint32_t temp;
+ uint32_t tickstart = 0U;
+
+ if(HAL_DMA_STATE_BUSY != hdma->State)
+ {
+ /* no transfer ongoing */
+ hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
+ __HAL_UNLOCK(hdma);
+ return HAL_ERROR;
+ }
+
+ /* Polling mode not supported in circular mode */
+ if (RESET != (hdma->Instance->CCR & DMA_CCR_CIRC))
+ {
+ hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
+ return HAL_ERROR;
+ }
+
+ /* Get the level transfer complete flag */
+ if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
+ {
+ /* Transfer Complete flag */
+ temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
+ }
+ else
+ {
+ /* Half Transfer Complete flag */
+ temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
+ }
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
+ {
+ if((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET))
+ {
+ /* When a DMA transfer error occurs */
+ /* A hardware clear of its EN bits is performed */
+ /* Clear all flags */
+ hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
+
+ /* Update error code */
+ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE);
+
+ /* Change the DMA state */
+ hdma->State= HAL_DMA_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ return HAL_ERROR;
+ }
+ /* Check for the Timeout */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
+ {
+ /* Update error code */
+ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT);
+
+ /* Change the DMA state */
+ hdma->State = HAL_DMA_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ return HAL_ERROR;
+ }
+ }
+ }
+
+ if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
+ {
+ /* Clear the transfer complete flag */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
+
+ /* The selected Channelx EN bit is cleared (DMA is disabled and
+ all transfers are complete) */
+ hdma->State = HAL_DMA_STATE_READY;
+ }
+ else
+ {
+ /* Clear the half transfer complete flag */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hdma);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Handles DMA interrupt request.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval None
+ */
+void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
+{
+ uint32_t flag_it = hdma->DmaBaseAddress->ISR;
+ uint32_t source_it = hdma->Instance->CCR;
+
+ /* Half Transfer Complete Interrupt management ******************************/
+ if (((flag_it & (DMA_FLAG_HT1 << hdma->ChannelIndex)) != RESET) && ((source_it & DMA_IT_HT) != RESET))
+ {
+ /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
+ if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
+ {
+ /* Disable the half transfer interrupt */
+ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
+ }
+ /* Clear the half transfer complete flag */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
+
+ /* DMA peripheral state is not updated in Half Transfer */
+ /* but in Transfer Complete case */
+
+ if(hdma->XferHalfCpltCallback != NULL)
+ {
+ /* Half transfer callback */
+ hdma->XferHalfCpltCallback(hdma);
+ }
+ }
+
+ /* Transfer Complete Interrupt management ***********************************/
+ else if (((flag_it & (DMA_FLAG_TC1 << hdma->ChannelIndex)) != RESET) && ((source_it & DMA_IT_TC) != RESET))
+ {
+ if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
+ {
+ /* Disable the transfer complete and error interrupt */
+ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC);
+
+ /* Change the DMA state */
+ hdma->State = HAL_DMA_STATE_READY;
+ }
+ /* Clear the transfer complete flag */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ if(hdma->XferCpltCallback != NULL)
+ {
+ /* Transfer complete callback */
+ hdma->XferCpltCallback(hdma);
+ }
+ }
+
+ /* Transfer Error Interrupt management **************************************/
+ else if (( RESET != (flag_it & (DMA_FLAG_TE1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TE)))
+ {
+ /* When a DMA transfer error occurs */
+ /* A hardware clear of its EN bits is performed */
+ /* Disable ALL DMA IT */
+ __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
+
+ /* Clear all flags */
+ hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
+
+ /* Update error code */
+ hdma->ErrorCode = HAL_DMA_ERROR_TE;
+
+ /* Change the DMA state */
+ hdma->State = HAL_DMA_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ if (hdma->XferErrorCallback != NULL)
+ {
+ /* Transfer error callback */
+ hdma->XferErrorCallback(hdma);
+ }
+ }
+ return;
+}
+
+/**
+ * @brief Register callbacks
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @param CallbackID: User Callback identifer
+ * a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
+ * @param pCallback: pointer to private callbacsk function which has pointer to
+ * a DMA_HandleTypeDef structure as parameter.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)( DMA_HandleTypeDef * _hdma))
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process locked */
+ __HAL_LOCK(hdma);
+
+ if(HAL_DMA_STATE_READY == hdma->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_DMA_XFER_CPLT_CB_ID:
+ hdma->XferCpltCallback = pCallback;
+ break;
+
+ case HAL_DMA_XFER_HALFCPLT_CB_ID:
+ hdma->XferHalfCpltCallback = pCallback;
+ break;
+
+ case HAL_DMA_XFER_ERROR_CB_ID:
+ hdma->XferErrorCallback = pCallback;
+ break;
+
+ case HAL_DMA_XFER_ABORT_CB_ID:
+ hdma->XferAbortCallback = pCallback;
+ break;
+
+ default:
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hdma);
+
+ return status;
+}
+
+/**
+ * @brief UnRegister callbacks
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @param CallbackID: User Callback identifer
+ * a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process locked */
+ __HAL_LOCK(hdma);
+
+ if(HAL_DMA_STATE_READY == hdma->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_DMA_XFER_CPLT_CB_ID:
+ hdma->XferCpltCallback = NULL;
+ break;
+
+ case HAL_DMA_XFER_HALFCPLT_CB_ID:
+ hdma->XferHalfCpltCallback = NULL;
+ break;
+
+ case HAL_DMA_XFER_ERROR_CB_ID:
+ hdma->XferErrorCallback = NULL;
+ break;
+
+ case HAL_DMA_XFER_ABORT_CB_ID:
+ hdma->XferAbortCallback = NULL;
+ break;
+
+ case HAL_DMA_XFER_ALL_CB_ID:
+ hdma->XferCpltCallback = NULL;
+ hdma->XferHalfCpltCallback = NULL;
+ hdma->XferErrorCallback = NULL;
+ hdma->XferAbortCallback = NULL;
+ break;
+
+ default:
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hdma);
+
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup DMA_Exported_Functions_Group3 Peripheral State and Errors functions
+ * @brief Peripheral State and Errors functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral State and Errors functions #####
+ ===============================================================================
+ [..]
+ This subsection provides functions allowing to
+ (+) Check the DMA state
+ (+) Get error code
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Return the DMA hande state.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval HAL state
+ */
+HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
+{
+ /* Return DMA handle state */
+ return hdma->State;
+}
+
+/**
+ * @brief Return the DMA error code.
+ * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval DMA Error Code
+ */
+uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
+{
+ return hdma->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup DMA_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Sets the DMA Transfer parameter.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @param SrcAddress: The source memory Buffer address
+ * @param DstAddress: The destination memory Buffer address
+ * @param DataLength: The length of data to be transferred from source to destination
+ * @retval HAL status
+ */
+static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
+{
+ /* Clear all flags */
+ hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
+
+ /* Configure DMA Channel data length */
+ hdma->Instance->CNDTR = DataLength;
+
+ /* Memory to Peripheral */
+ if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
+ {
+ /* Configure DMA Channel destination address */
+ hdma->Instance->CPAR = DstAddress;
+
+ /* Configure DMA Channel source address */
+ hdma->Instance->CMAR = SrcAddress;
+ }
+ /* Peripheral to Memory */
+ else
+ {
+ /* Configure DMA Channel source address */
+ hdma->Instance->CPAR = SrcAddress;
+
+ /* Configure DMA Channel destination address */
+ hdma->Instance->CMAR = DstAddress;
+ }
+}
+
+/**
+ * @}
+ */
+
+#endif /* HAL_DMA_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_eth.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_eth.c
new file mode 100644
index 0000000..081259c
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_eth.c
@@ -0,0 +1,2043 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_eth.c
+ * @author MCD Application Team
+ * @brief ETH HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Ethernet (ETH) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ * + Peripheral State and Errors functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#)Declare a ETH_HandleTypeDef handle structure, for example:
+ ETH_HandleTypeDef heth;
+
+ (#)Fill parameters of Init structure in heth handle
+
+ (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...)
+
+ (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API:
+ (##) Enable the Ethernet interface clock using
+ (+++) __HAL_RCC_ETHMAC_CLK_ENABLE();
+ (+++) __HAL_RCC_ETHMACTX_CLK_ENABLE();
+ (+++) __HAL_RCC_ETHMACRX_CLK_ENABLE();
+
+ (##) Initialize the related GPIO clocks
+ (##) Configure Ethernet pin-out
+ (##) Configure Ethernet NVIC interrupt (IT mode)
+
+ (#)Initialize Ethernet DMA Descriptors in chain mode and point to allocated buffers:
+ (##) HAL_ETH_DMATxDescListInit(); for Transmission process
+ (##) HAL_ETH_DMARxDescListInit(); for Reception process
+
+ (#)Enable MAC and DMA transmission and reception:
+ (##) HAL_ETH_Start();
+
+ (#)Prepare ETH DMA TX Descriptors and give the hand to ETH DMA to transfer
+ the frame to MAC TX FIFO:
+ (##) HAL_ETH_TransmitFrame();
+
+ (#)Poll for a received frame in ETH RX DMA Descriptors and get received
+ frame parameters
+ (##) HAL_ETH_GetReceivedFrame(); (should be called into an infinite loop)
+
+ (#) Get a received frame when an ETH RX interrupt occurs:
+ (##) HAL_ETH_GetReceivedFrame_IT(); (called in IT mode only)
+
+ (#) Communicate with external PHY device:
+ (##) Read a specific register from the PHY
+ HAL_ETH_ReadPHYRegister();
+ (##) Write data to a specific RHY register:
+ HAL_ETH_WritePHYRegister();
+
+ (#) Configure the Ethernet MAC after ETH peripheral initialization
+ HAL_ETH_ConfigMAC(); all MAC parameters should be filled.
+
+ (#) Configure the Ethernet DMA after ETH peripheral initialization
+ HAL_ETH_ConfigDMA(); all DMA parameters should be filled.
+
+ -@- The PTP protocol and the DMA descriptors ring mode are not supported
+ in this driver
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+#if defined (STM32F107xC)
+
+/** @defgroup ETH ETH
+ * @brief ETH HAL module driver
+ * @{
+ */
+
+#ifdef HAL_ETH_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup ETH_Private_Constants ETH Private Constants
+ * @{
+ */
+#define ETH_TIMEOUT_SWRESET 500U
+#define ETH_TIMEOUT_LINKED_STATE 5000U
+#define ETH_TIMEOUT_AUTONEGO_COMPLETED 5000U
+
+/**
+ * @}
+ */
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup ETH_Private_Functions ETH Private Functions
+ * @{
+ */
+static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err);
+static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr);
+static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth);
+static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth);
+static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth);
+static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth);
+static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth);
+static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth);
+static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth);
+static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth);
+static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth);
+static void ETH_Delay(uint32_t mdelay);
+
+/**
+ * @}
+ */
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup ETH_Exported_Functions ETH Exported Functions
+ * @{
+ */
+
+/** @defgroup ETH_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+ @verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Initialize and configure the Ethernet peripheral
+ (+) De-initialize the Ethernet peripheral
+
+ @endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the Ethernet MAC and DMA according to default
+ * parameters.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
+{
+ uint32_t tmpreg1 = 0U, phyreg = 0U;
+ uint32_t hclk = 60000000U;
+ uint32_t tickstart = 0U;
+ uint32_t err = ETH_SUCCESS;
+
+ /* Check the ETH peripheral state */
+ if (heth == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check parameters */
+ assert_param(IS_ETH_AUTONEGOTIATION(heth->Init.AutoNegotiation));
+ assert_param(IS_ETH_RX_MODE(heth->Init.RxMode));
+ assert_param(IS_ETH_CHECKSUM_MODE(heth->Init.ChecksumMode));
+ assert_param(IS_ETH_MEDIA_INTERFACE(heth->Init.MediaInterface));
+
+ if (heth->State == HAL_ETH_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ heth->Lock = HAL_UNLOCKED;
+ /* Init the low level hardware : GPIO, CLOCK, NVIC. */
+ HAL_ETH_MspInit(heth);
+ }
+
+ /* Select MII or RMII Mode*/
+ AFIO->MAPR &= ~(AFIO_MAPR_MII_RMII_SEL);
+ AFIO->MAPR |= (uint32_t)heth->Init.MediaInterface;
+
+ /* Ethernet Software reset */
+ /* Set the SWR bit: resets all MAC subsystem internal registers and logic */
+ /* After reset all the registers holds their respective reset values */
+ (heth->Instance)->DMABMR |= ETH_DMABMR_SR;
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait for software reset */
+ while (((heth->Instance)->DMABMR & ETH_DMABMR_SR) != (uint32_t)RESET)
+ {
+ /* Check for the Timeout */
+ if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_SWRESET)
+ {
+ heth->State = HAL_ETH_STATE_TIMEOUT;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ /* Note: The SWR is not performed if the ETH_RX_CLK or the ETH_TX_CLK are
+ not available, please check your external PHY or the IO configuration */
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /*-------------------------------- MAC Initialization ----------------------*/
+ /* Get the ETHERNET MACMIIAR value */
+ tmpreg1 = (heth->Instance)->MACMIIAR;
+ /* Clear CSR Clock Range CR[2:0] bits */
+ tmpreg1 &= ETH_MACMIIAR_CR_MASK;
+
+ /* Get hclk frequency value */
+ hclk = HAL_RCC_GetHCLKFreq();
+
+ /* Set CR bits depending on hclk value */
+ if ((hclk >= 20000000U) && (hclk < 35000000U))
+ {
+ /* CSR Clock Range between 20-35 MHz */
+ tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV16;
+ }
+ else if ((hclk >= 35000000U) && (hclk < 60000000U))
+ {
+ /* CSR Clock Range between 35-60 MHz */
+ tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV26;
+ }
+ else
+ {
+ /* CSR Clock Range between 60-72 MHz */
+ tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV42;
+ }
+
+ /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
+ (heth->Instance)->MACMIIAR = (uint32_t)tmpreg1;
+
+ /*-------------------- PHY initialization and configuration ----------------*/
+ /* Put the PHY in reset mode */
+ if ((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_RESET)) != HAL_OK)
+ {
+ /* In case of write timeout */
+ err = ETH_ERROR;
+
+ /* Config MAC and DMA */
+ ETH_MACDMAConfig(heth, err);
+
+ /* Set the ETH peripheral state to READY */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Return HAL_ERROR */
+ return HAL_ERROR;
+ }
+
+ /* Delay to assure PHY reset */
+ HAL_Delay(PHY_RESET_DELAY);
+
+ if ((heth->Init).AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE)
+ {
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* We wait for linked status */
+ do
+ {
+ HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg);
+
+ /* Check for the Timeout */
+ if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_LINKED_STATE)
+ {
+ /* In case of write timeout */
+ err = ETH_ERROR;
+
+ /* Config MAC and DMA */
+ ETH_MACDMAConfig(heth, err);
+
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ while (((phyreg & PHY_LINKED_STATUS) != PHY_LINKED_STATUS));
+
+
+ /* Enable Auto-Negotiation */
+ if ((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_AUTONEGOTIATION)) != HAL_OK)
+ {
+ /* In case of write timeout */
+ err = ETH_ERROR;
+
+ /* Config MAC and DMA */
+ ETH_MACDMAConfig(heth, err);
+
+ /* Set the ETH peripheral state to READY */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Return HAL_ERROR */
+ return HAL_ERROR;
+ }
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait until the auto-negotiation will be completed */
+ do
+ {
+ HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg);
+
+ /* Check for the Timeout */
+ if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_AUTONEGO_COMPLETED)
+ {
+ /* In case of write timeout */
+ err = ETH_ERROR;
+
+ /* Config MAC and DMA */
+ ETH_MACDMAConfig(heth, err);
+
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ return HAL_TIMEOUT;
+ }
+
+ }
+ while (((phyreg & PHY_AUTONEGO_COMPLETE) != PHY_AUTONEGO_COMPLETE));
+
+ /* Read the result of the auto-negotiation */
+ if ((HAL_ETH_ReadPHYRegister(heth, PHY_SR, &phyreg)) != HAL_OK)
+ {
+ /* In case of write timeout */
+ err = ETH_ERROR;
+
+ /* Config MAC and DMA */
+ ETH_MACDMAConfig(heth, err);
+
+ /* Set the ETH peripheral state to READY */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Return HAL_ERROR */
+ return HAL_ERROR;
+ }
+
+ /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */
+ if ((phyreg & PHY_DUPLEX_STATUS) != (uint32_t)RESET)
+ {
+ /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
+ (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
+ }
+ else
+ {
+ /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */
+ (heth->Init).DuplexMode = ETH_MODE_HALFDUPLEX;
+ }
+ /* Configure the MAC with the speed fixed by the auto-negotiation process */
+ if ((phyreg & PHY_SPEED_STATUS) == PHY_SPEED_STATUS)
+ {
+ /* Set Ethernet speed to 10M following the auto-negotiation */
+ (heth->Init).Speed = ETH_SPEED_10M;
+ }
+ else
+ {
+ /* Set Ethernet speed to 100M following the auto-negotiation */
+ (heth->Init).Speed = ETH_SPEED_100M;
+ }
+ }
+ else /* AutoNegotiation Disable */
+ {
+ /* Check parameters */
+ assert_param(IS_ETH_SPEED(heth->Init.Speed));
+ assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode));
+
+ /* Set MAC Speed and Duplex Mode */
+ if (HAL_ETH_WritePHYRegister(heth, PHY_BCR, ((uint16_t)((heth->Init).DuplexMode >> 3U) |
+ (uint16_t)((heth->Init).Speed >> 1U))) != HAL_OK)
+ {
+ /* In case of write timeout */
+ err = ETH_ERROR;
+
+ /* Config MAC and DMA */
+ ETH_MACDMAConfig(heth, err);
+
+ /* Set the ETH peripheral state to READY */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Return HAL_ERROR */
+ return HAL_ERROR;
+ }
+
+ /* Delay to assure PHY configuration */
+ HAL_Delay(PHY_CONFIG_DELAY);
+ }
+
+ /* Config MAC and DMA */
+ ETH_MACDMAConfig(heth, err);
+
+ /* Set ETH HAL State to Ready */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief De-Initializes the ETH peripheral.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth)
+{
+ /* Set the ETH peripheral state to BUSY */
+ heth->State = HAL_ETH_STATE_BUSY;
+
+ /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
+ HAL_ETH_MspDeInit(heth);
+
+ /* Set ETH HAL state to Disabled */
+ heth->State = HAL_ETH_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(heth);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the DMA Tx descriptors in chain mode.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @param DMATxDescTab: Pointer to the first Tx desc list
+ * @param TxBuff: Pointer to the first TxBuffer list
+ * @param TxBuffCount: Number of the used Tx desc in the list
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ETH_DMATxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMATxDescTab, uint8_t *TxBuff, uint32_t TxBuffCount)
+{
+ uint32_t i = 0U;
+ ETH_DMADescTypeDef *dmatxdesc;
+
+ /* Process Locked */
+ __HAL_LOCK(heth);
+
+ /* Set the ETH peripheral state to BUSY */
+ heth->State = HAL_ETH_STATE_BUSY;
+
+ /* Set the DMATxDescToSet pointer with the first one of the DMATxDescTab list */
+ heth->TxDesc = DMATxDescTab;
+
+ /* Fill each DMATxDesc descriptor with the right values */
+ for (i = 0U; i < TxBuffCount; i++)
+ {
+ /* Get the pointer on the ith member of the Tx Desc list */
+ dmatxdesc = DMATxDescTab + i;
+
+ /* Set Second Address Chained bit */
+ dmatxdesc->Status = ETH_DMATXDESC_TCH;
+
+ /* Set Buffer1 address pointer */
+ dmatxdesc->Buffer1Addr = (uint32_t)(&TxBuff[i * ETH_TX_BUF_SIZE]);
+
+ if ((heth->Init).ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
+ {
+ /* Set the DMA Tx descriptors checksum insertion */
+ dmatxdesc->Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL;
+ }
+
+ /* Initialize the next descriptor with the Next Descriptor Polling Enable */
+ if (i < (TxBuffCount - 1U))
+ {
+ /* Set next descriptor address register with next descriptor base address */
+ dmatxdesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab + i + 1U);
+ }
+ else
+ {
+ /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
+ dmatxdesc->Buffer2NextDescAddr = (uint32_t) DMATxDescTab;
+ }
+ }
+
+ /* Set Transmit Descriptor List Address Register */
+ (heth->Instance)->DMATDLAR = (uint32_t) DMATxDescTab;
+
+ /* Set ETH HAL State to Ready */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the DMA Rx descriptors in chain mode.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @param DMARxDescTab: Pointer to the first Rx desc list
+ * @param RxBuff: Pointer to the first RxBuffer list
+ * @param RxBuffCount: Number of the used Rx desc in the list
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ETH_DMARxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount)
+{
+ uint32_t i = 0U;
+ ETH_DMADescTypeDef *DMARxDesc;
+
+ /* Process Locked */
+ __HAL_LOCK(heth);
+
+ /* Set the ETH peripheral state to BUSY */
+ heth->State = HAL_ETH_STATE_BUSY;
+
+ /* Set the Ethernet RxDesc pointer with the first one of the DMARxDescTab list */
+ heth->RxDesc = DMARxDescTab;
+
+ /* Fill each DMARxDesc descriptor with the right values */
+ for (i = 0U; i < RxBuffCount; i++)
+ {
+ /* Get the pointer on the ith member of the Rx Desc list */
+ DMARxDesc = DMARxDescTab + i;
+
+ /* Set Own bit of the Rx descriptor Status */
+ DMARxDesc->Status = ETH_DMARXDESC_OWN;
+
+ /* Set Buffer1 size and Second Address Chained bit */
+ DMARxDesc->ControlBufferSize = ETH_DMARXDESC_RCH | ETH_RX_BUF_SIZE;
+
+ /* Set Buffer1 address pointer */
+ DMARxDesc->Buffer1Addr = (uint32_t)(&RxBuff[i * ETH_RX_BUF_SIZE]);
+
+ if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
+ {
+ /* Enable Ethernet DMA Rx Descriptor interrupt */
+ DMARxDesc->ControlBufferSize &= ~ETH_DMARXDESC_DIC;
+ }
+
+ /* Initialize the next descriptor with the Next Descriptor Polling Enable */
+ if (i < (RxBuffCount - 1U))
+ {
+ /* Set next descriptor address register with next descriptor base address */
+ DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab + i + 1U);
+ }
+ else
+ {
+ /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
+ DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab);
+ }
+ }
+
+ /* Set Receive Descriptor List Address Register */
+ (heth->Instance)->DMARDLAR = (uint32_t) DMARxDescTab;
+
+ /* Set ETH HAL State to Ready */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the ETH MSP.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval None
+ */
+__weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(heth);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_ETH_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes ETH MSP.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval None
+ */
+__weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(heth);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_ETH_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup ETH_Exported_Functions_Group2 IO operation functions
+ * @brief Data transfers functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### IO operation functions #####
+ ==============================================================================
+ [..] This section provides functions allowing to:
+ (+) Transmit a frame
+ HAL_ETH_TransmitFrame();
+ (+) Receive a frame
+ HAL_ETH_GetReceivedFrame();
+ HAL_ETH_GetReceivedFrame_IT();
+ (+) Read from an External PHY register
+ HAL_ETH_ReadPHYRegister();
+ (+) Write to an External PHY register
+ HAL_ETH_WritePHYRegister();
+
+ @endverbatim
+
+ * @{
+ */
+
+/**
+ * @brief Sends an Ethernet frame.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @param FrameLength: Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength)
+{
+ uint32_t bufcount = 0U, size = 0U, i = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(heth);
+
+ /* Set the ETH peripheral state to BUSY */
+ heth->State = HAL_ETH_STATE_BUSY;
+
+ if (FrameLength == 0U)
+ {
+ /* Set ETH HAL state to READY */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ return HAL_ERROR;
+ }
+
+ /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
+ if (((heth->TxDesc)->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
+ {
+ /* OWN bit set */
+ heth->State = HAL_ETH_STATE_BUSY_TX;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ return HAL_ERROR;
+ }
+
+ /* Get the number of needed Tx buffers for the current frame */
+ if (FrameLength > ETH_TX_BUF_SIZE)
+ {
+ bufcount = FrameLength / ETH_TX_BUF_SIZE;
+ if (FrameLength % ETH_TX_BUF_SIZE)
+ {
+ bufcount++;
+ }
+ }
+ else
+ {
+ bufcount = 1U;
+ }
+ if (bufcount == 1U)
+ {
+ /* Set LAST and FIRST segment */
+ heth->TxDesc->Status |= ETH_DMATXDESC_FS | ETH_DMATXDESC_LS;
+ /* Set frame size */
+ heth->TxDesc->ControlBufferSize = (FrameLength & ETH_DMATXDESC_TBS1);
+ /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
+ heth->TxDesc->Status |= ETH_DMATXDESC_OWN;
+ /* Point to next descriptor */
+ heth->TxDesc = (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr);
+ }
+ else
+ {
+ for (i = 0U; i < bufcount; i++)
+ {
+ /* Clear FIRST and LAST segment bits */
+ heth->TxDesc->Status &= ~(ETH_DMATXDESC_FS | ETH_DMATXDESC_LS);
+
+ if (i == 0U)
+ {
+ /* Setting the first segment bit */
+ heth->TxDesc->Status |= ETH_DMATXDESC_FS;
+ }
+
+ /* Program size */
+ heth->TxDesc->ControlBufferSize = (ETH_TX_BUF_SIZE & ETH_DMATXDESC_TBS1);
+
+ if (i == (bufcount - 1U))
+ {
+ /* Setting the last segment bit */
+ heth->TxDesc->Status |= ETH_DMATXDESC_LS;
+ size = FrameLength - (bufcount - 1U) * ETH_TX_BUF_SIZE;
+ heth->TxDesc->ControlBufferSize = (size & ETH_DMATXDESC_TBS1);
+ }
+
+ /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
+ heth->TxDesc->Status |= ETH_DMATXDESC_OWN;
+ /* point to next descriptor */
+ heth->TxDesc = (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr);
+ }
+ }
+
+ /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
+ if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET)
+ {
+ /* Clear TBUS ETHERNET DMA flag */
+ (heth->Instance)->DMASR = ETH_DMASR_TBUS;
+ /* Resume DMA transmission*/
+ (heth->Instance)->DMATPDR = 0U;
+ }
+
+ /* Set ETH HAL State to Ready */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Checks for received frames.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ETH_GetReceivedFrame(ETH_HandleTypeDef *heth)
+{
+ uint32_t framelength = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(heth);
+
+ /* Check the ETH state to BUSY */
+ heth->State = HAL_ETH_STATE_BUSY;
+
+ /* Check if segment is not owned by DMA */
+ /* (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) && ((heth->RxDesc->Status & ETH_DMARXDESC_LS) != (uint32_t)RESET)) */
+ if (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET))
+ {
+ /* Check if last segment */
+ if (((heth->RxDesc->Status & ETH_DMARXDESC_LS) != (uint32_t)RESET))
+ {
+ /* increment segment count */
+ (heth->RxFrameInfos).SegCount++;
+
+ /* Check if last segment is first segment: one segment contains the frame */
+ if ((heth->RxFrameInfos).SegCount == 1U)
+ {
+ (heth->RxFrameInfos).FSRxDesc = heth->RxDesc;
+ }
+
+ heth->RxFrameInfos.LSRxDesc = heth->RxDesc;
+
+ /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
+ framelength = (((heth->RxDesc)->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4U;
+ heth->RxFrameInfos.length = framelength;
+
+ /* Get the address of the buffer start address */
+ heth->RxFrameInfos.buffer = ((heth->RxFrameInfos).FSRxDesc)->Buffer1Addr;
+ /* point to next descriptor */
+ heth->RxDesc = (ETH_DMADescTypeDef *)((heth->RxDesc)->Buffer2NextDescAddr);
+
+ /* Set HAL State to Ready */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ /* Return function status */
+ return HAL_OK;
+ }
+ /* Check if first segment */
+ else if ((heth->RxDesc->Status & ETH_DMARXDESC_FS) != (uint32_t)RESET)
+ {
+ (heth->RxFrameInfos).FSRxDesc = heth->RxDesc;
+ (heth->RxFrameInfos).LSRxDesc = NULL;
+ (heth->RxFrameInfos).SegCount = 1U;
+ /* Point to next descriptor */
+ heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
+ }
+ /* Check if intermediate segment */
+ else
+ {
+ (heth->RxFrameInfos).SegCount++;
+ /* Point to next descriptor */
+ heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
+ }
+ }
+
+ /* Set ETH HAL State to Ready */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ /* Return function status */
+ return HAL_ERROR;
+}
+
+/**
+ * @brief Gets the Received frame in interrupt mode.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ETH_GetReceivedFrame_IT(ETH_HandleTypeDef *heth)
+{
+ uint32_t descriptorscancounter = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(heth);
+
+ /* Set ETH HAL State to BUSY */
+ heth->State = HAL_ETH_STATE_BUSY;
+
+ /* Scan descriptors owned by CPU */
+ while (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) && (descriptorscancounter < ETH_RXBUFNB))
+ {
+ /* Just for security */
+ descriptorscancounter++;
+
+ /* Check if first segment in frame */
+ /* ((heth->RxDesc->Status & ETH_DMARXDESC_FS) != (uint32_t)RESET) && ((heth->RxDesc->Status & ETH_DMARXDESC_LS) == (uint32_t)RESET)) */
+ if ((heth->RxDesc->Status & (ETH_DMARXDESC_FS | ETH_DMARXDESC_LS)) == (uint32_t)ETH_DMARXDESC_FS)
+ {
+ heth->RxFrameInfos.FSRxDesc = heth->RxDesc;
+ heth->RxFrameInfos.SegCount = 1U;
+ /* Point to next descriptor */
+ heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
+ }
+ /* Check if intermediate segment */
+ /* ((heth->RxDesc->Status & ETH_DMARXDESC_LS) == (uint32_t)RESET)&& ((heth->RxDesc->Status & ETH_DMARXDESC_FS) == (uint32_t)RESET)) */
+ else if ((heth->RxDesc->Status & (ETH_DMARXDESC_LS | ETH_DMARXDESC_FS)) == (uint32_t)RESET)
+ {
+ /* Increment segment count */
+ (heth->RxFrameInfos.SegCount)++;
+ /* Point to next descriptor */
+ heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
+ }
+ /* Should be last segment */
+ else
+ {
+ /* Last segment */
+ heth->RxFrameInfos.LSRxDesc = heth->RxDesc;
+
+ /* Increment segment count */
+ (heth->RxFrameInfos.SegCount)++;
+
+ /* Check if last segment is first segment: one segment contains the frame */
+ if ((heth->RxFrameInfos.SegCount) == 1U)
+ {
+ heth->RxFrameInfos.FSRxDesc = heth->RxDesc;
+ }
+
+ /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
+ heth->RxFrameInfos.length = (((heth->RxDesc)->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4U;
+
+ /* Get the address of the buffer start address */
+ heth->RxFrameInfos.buffer = ((heth->RxFrameInfos).FSRxDesc)->Buffer1Addr;
+
+ /* Point to next descriptor */
+ heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr);
+
+ /* Set HAL State to Ready */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ /* Return function status */
+ return HAL_OK;
+ }
+ }
+
+ /* Set HAL State to Ready */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ /* Return function status */
+ return HAL_ERROR;
+}
+
+/**
+ * @brief This function handles ETH interrupt request.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval HAL status
+ */
+void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
+{
+ /* Frame received */
+ if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_R))
+ {
+ /* Receive complete callback */
+ HAL_ETH_RxCpltCallback(heth);
+
+ /* Clear the Eth DMA Rx IT pending bits */
+ __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_R);
+
+ /* Set HAL State to Ready */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ }
+ /* Frame transmitted */
+ else if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_T))
+ {
+ /* Transfer complete callback */
+ HAL_ETH_TxCpltCallback(heth);
+
+ /* Clear the Eth DMA Tx IT pending bits */
+ __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_T);
+
+ /* Set HAL State to Ready */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+ }
+
+ /* Clear the interrupt flags */
+ __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_NIS);
+
+ /* ETH DMA Error */
+ if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_AIS))
+ {
+ /* Ethernet Error callback */
+ HAL_ETH_ErrorCallback(heth);
+
+ /* Clear the interrupt flags */
+ __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_FLAG_AIS);
+
+ /* Set HAL State to Ready */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+ }
+}
+
+/**
+ * @brief Tx Transfer completed callbacks.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval None
+ */
+__weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(heth);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_ETH_TxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer completed callbacks.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval None
+ */
+__weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(heth);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_ETH_TxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Ethernet transfer error callbacks
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval None
+ */
+__weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(heth);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_ETH_TxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Reads a PHY register
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @param PHYReg: PHY register address, is the index of one of the 32 PHY register.
+ * This parameter can be one of the following values:
+ * PHY_BCR: Transceiver Basic Control Register,
+ * PHY_BSR: Transceiver Basic Status Register.
+ * More PHY register could be read depending on the used PHY
+ * @param RegValue: PHY register value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t *RegValue)
+{
+ uint32_t tmpreg1 = 0U;
+ uint32_t tickstart = 0U;
+
+ /* Check parameters */
+ assert_param(IS_ETH_PHY_ADDRESS(heth->Init.PhyAddress));
+
+ /* Check the ETH peripheral state */
+ if (heth->State == HAL_ETH_STATE_BUSY_RD)
+ {
+ return HAL_BUSY;
+ }
+ /* Set ETH HAL State to BUSY_RD */
+ heth->State = HAL_ETH_STATE_BUSY_RD;
+
+ /* Get the ETHERNET MACMIIAR value */
+ tmpreg1 = heth->Instance->MACMIIAR;
+
+ /* Keep only the CSR Clock Range CR[2:0] bits value */
+ tmpreg1 &= ~ETH_MACMIIAR_CR_MASK;
+
+ /* Prepare the MII address register value */
+ tmpreg1 |= (((uint32_t)heth->Init.PhyAddress << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */
+ tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR); /* Set the PHY register address */
+ tmpreg1 &= ~ETH_MACMIIAR_MW; /* Set the read mode */
+ tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */
+
+ /* Write the result value into the MII Address register */
+ heth->Instance->MACMIIAR = tmpreg1;
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Check for the Busy flag */
+ while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB)
+ {
+ /* Check for the Timeout */
+ if ((HAL_GetTick() - tickstart) > PHY_READ_TO)
+ {
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ return HAL_TIMEOUT;
+ }
+
+ tmpreg1 = heth->Instance->MACMIIAR;
+ }
+
+ /* Get MACMIIDR value */
+ *RegValue = (uint16_t)(heth->Instance->MACMIIDR);
+
+ /* Set ETH HAL State to READY */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Writes to a PHY register.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @param PHYReg: PHY register address, is the index of one of the 32 PHY register.
+ * This parameter can be one of the following values:
+ * PHY_BCR: Transceiver Control Register.
+ * More PHY register could be written depending on the used PHY
+ * @param RegValue: the value to write
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t RegValue)
+{
+ uint32_t tmpreg1 = 0U;
+ uint32_t tickstart = 0U;
+
+ /* Check parameters */
+ assert_param(IS_ETH_PHY_ADDRESS(heth->Init.PhyAddress));
+
+ /* Check the ETH peripheral state */
+ if (heth->State == HAL_ETH_STATE_BUSY_WR)
+ {
+ return HAL_BUSY;
+ }
+ /* Set ETH HAL State to BUSY_WR */
+ heth->State = HAL_ETH_STATE_BUSY_WR;
+
+ /* Get the ETHERNET MACMIIAR value */
+ tmpreg1 = heth->Instance->MACMIIAR;
+
+ /* Keep only the CSR Clock Range CR[2:0] bits value */
+ tmpreg1 &= ~ETH_MACMIIAR_CR_MASK;
+
+ /* Prepare the MII register address value */
+ tmpreg1 |= (((uint32_t)heth->Init.PhyAddress << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */
+ tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR); /* Set the PHY register address */
+ tmpreg1 |= ETH_MACMIIAR_MW; /* Set the write mode */
+ tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */
+
+ /* Give the value to the MII data register */
+ heth->Instance->MACMIIDR = (uint16_t)RegValue;
+
+ /* Write the result value into the MII Address register */
+ heth->Instance->MACMIIAR = tmpreg1;
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Check for the Busy flag */
+ while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB)
+ {
+ /* Check for the Timeout */
+ if ((HAL_GetTick() - tickstart) > PHY_WRITE_TO)
+ {
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ return HAL_TIMEOUT;
+ }
+
+ tmpreg1 = heth->Instance->MACMIIAR;
+ }
+
+ /* Set ETH HAL State to READY */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions
+ * @brief Peripheral Control functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Enable MAC and DMA transmission and reception.
+ HAL_ETH_Start();
+ (+) Disable MAC and DMA transmission and reception.
+ HAL_ETH_Stop();
+ (+) Set the MAC configuration in runtime mode
+ HAL_ETH_ConfigMAC();
+ (+) Set the DMA configuration in runtime mode
+ HAL_ETH_ConfigDMA();
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables Ethernet MAC and DMA reception/transmission
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth)
+{
+ /* Process Locked */
+ __HAL_LOCK(heth);
+
+ /* Set the ETH peripheral state to BUSY */
+ heth->State = HAL_ETH_STATE_BUSY;
+
+ /* Enable transmit state machine of the MAC for transmission on the MII */
+ ETH_MACTransmissionEnable(heth);
+
+ /* Enable receive state machine of the MAC for reception from the MII */
+ ETH_MACReceptionEnable(heth);
+
+ /* Flush Transmit FIFO */
+ ETH_FlushTransmitFIFO(heth);
+
+ /* Start DMA transmission */
+ ETH_DMATransmissionEnable(heth);
+
+ /* Start DMA reception */
+ ETH_DMAReceptionEnable(heth);
+
+ /* Set the ETH state to READY*/
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stop Ethernet MAC and DMA reception/transmission
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth)
+{
+ /* Process Locked */
+ __HAL_LOCK(heth);
+
+ /* Set the ETH peripheral state to BUSY */
+ heth->State = HAL_ETH_STATE_BUSY;
+
+ /* Stop DMA transmission */
+ ETH_DMATransmissionDisable(heth);
+
+ /* Stop DMA reception */
+ ETH_DMAReceptionDisable(heth);
+
+ /* Disable receive state machine of the MAC for reception from the MII */
+ ETH_MACReceptionDisable(heth);
+
+ /* Flush Transmit FIFO */
+ ETH_FlushTransmitFIFO(heth);
+
+ /* Disable transmit state machine of the MAC for transmission on the MII */
+ ETH_MACTransmissionDisable(heth);
+
+ /* Set the ETH state*/
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Set ETH MAC Configuration.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @param macconf: MAC Configuration structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef *macconf)
+{
+ uint32_t tmpreg1 = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(heth);
+
+ /* Set the ETH peripheral state to BUSY */
+ heth->State = HAL_ETH_STATE_BUSY;
+
+ assert_param(IS_ETH_SPEED(heth->Init.Speed));
+ assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode));
+
+ if (macconf != NULL)
+ {
+ /* Check the parameters */
+ assert_param(IS_ETH_WATCHDOG(macconf->Watchdog));
+ assert_param(IS_ETH_JABBER(macconf->Jabber));
+ assert_param(IS_ETH_INTER_FRAME_GAP(macconf->InterFrameGap));
+ assert_param(IS_ETH_CARRIER_SENSE(macconf->CarrierSense));
+ assert_param(IS_ETH_RECEIVE_OWN(macconf->ReceiveOwn));
+ assert_param(IS_ETH_LOOPBACK_MODE(macconf->LoopbackMode));
+ assert_param(IS_ETH_CHECKSUM_OFFLOAD(macconf->ChecksumOffload));
+ assert_param(IS_ETH_RETRY_TRANSMISSION(macconf->RetryTransmission));
+ assert_param(IS_ETH_AUTOMATIC_PADCRC_STRIP(macconf->AutomaticPadCRCStrip));
+ assert_param(IS_ETH_BACKOFF_LIMIT(macconf->BackOffLimit));
+ assert_param(IS_ETH_DEFERRAL_CHECK(macconf->DeferralCheck));
+ assert_param(IS_ETH_RECEIVE_ALL(macconf->ReceiveAll));
+ assert_param(IS_ETH_SOURCE_ADDR_FILTER(macconf->SourceAddrFilter));
+ assert_param(IS_ETH_CONTROL_FRAMES(macconf->PassControlFrames));
+ assert_param(IS_ETH_BROADCAST_FRAMES_RECEPTION(macconf->BroadcastFramesReception));
+ assert_param(IS_ETH_DESTINATION_ADDR_FILTER(macconf->DestinationAddrFilter));
+ assert_param(IS_ETH_PROMISCUOUS_MODE(macconf->PromiscuousMode));
+ assert_param(IS_ETH_MULTICAST_FRAMES_FILTER(macconf->MulticastFramesFilter));
+ assert_param(IS_ETH_UNICAST_FRAMES_FILTER(macconf->UnicastFramesFilter));
+ assert_param(IS_ETH_PAUSE_TIME(macconf->PauseTime));
+ assert_param(IS_ETH_ZEROQUANTA_PAUSE(macconf->ZeroQuantaPause));
+ assert_param(IS_ETH_PAUSE_LOW_THRESHOLD(macconf->PauseLowThreshold));
+ assert_param(IS_ETH_UNICAST_PAUSE_FRAME_DETECT(macconf->UnicastPauseFrameDetect));
+ assert_param(IS_ETH_RECEIVE_FLOWCONTROL(macconf->ReceiveFlowControl));
+ assert_param(IS_ETH_TRANSMIT_FLOWCONTROL(macconf->TransmitFlowControl));
+ assert_param(IS_ETH_VLAN_TAG_COMPARISON(macconf->VLANTagComparison));
+ assert_param(IS_ETH_VLAN_TAG_IDENTIFIER(macconf->VLANTagIdentifier));
+
+ /*------------------------ ETHERNET MACCR Configuration --------------------*/
+ /* Get the ETHERNET MACCR value */
+ tmpreg1 = (heth->Instance)->MACCR;
+ /* Clear WD, PCE, PS, TE and RE bits */
+ tmpreg1 &= ETH_MACCR_CLEAR_MASK;
+
+ tmpreg1 |= (uint32_t)(macconf->Watchdog |
+ macconf->Jabber |
+ macconf->InterFrameGap |
+ macconf->CarrierSense |
+ (heth->Init).Speed |
+ macconf->ReceiveOwn |
+ macconf->LoopbackMode |
+ (heth->Init).DuplexMode |
+ macconf->ChecksumOffload |
+ macconf->RetryTransmission |
+ macconf->AutomaticPadCRCStrip |
+ macconf->BackOffLimit |
+ macconf->DeferralCheck);
+
+ /* Write to ETHERNET MACCR */
+ (heth->Instance)->MACCR = (uint32_t)tmpreg1;
+
+ /* Wait until the write operation will be taken into account :
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACCR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACCR = tmpreg1;
+
+ /*----------------------- ETHERNET MACFFR Configuration --------------------*/
+ /* Write to ETHERNET MACFFR */
+ (heth->Instance)->MACFFR = (uint32_t)(macconf->ReceiveAll |
+ macconf->SourceAddrFilter |
+ macconf->PassControlFrames |
+ macconf->BroadcastFramesReception |
+ macconf->DestinationAddrFilter |
+ macconf->PromiscuousMode |
+ macconf->MulticastFramesFilter |
+ macconf->UnicastFramesFilter);
+
+ /* Wait until the write operation will be taken into account :
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACFFR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACFFR = tmpreg1;
+
+ /*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/
+ /* Write to ETHERNET MACHTHR */
+ (heth->Instance)->MACHTHR = (uint32_t)macconf->HashTableHigh;
+
+ /* Write to ETHERNET MACHTLR */
+ (heth->Instance)->MACHTLR = (uint32_t)macconf->HashTableLow;
+ /*----------------------- ETHERNET MACFCR Configuration --------------------*/
+
+ /* Get the ETHERNET MACFCR value */
+ tmpreg1 = (heth->Instance)->MACFCR;
+ /* Clear xx bits */
+ tmpreg1 &= ETH_MACFCR_CLEAR_MASK;
+
+ tmpreg1 |= (uint32_t)((macconf->PauseTime << 16U) |
+ macconf->ZeroQuantaPause |
+ macconf->PauseLowThreshold |
+ macconf->UnicastPauseFrameDetect |
+ macconf->ReceiveFlowControl |
+ macconf->TransmitFlowControl);
+
+ /* Write to ETHERNET MACFCR */
+ (heth->Instance)->MACFCR = (uint32_t)tmpreg1;
+
+ /* Wait until the write operation will be taken into account :
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACFCR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACFCR = tmpreg1;
+
+ /*----------------------- ETHERNET MACVLANTR Configuration -----------------*/
+ (heth->Instance)->MACVLANTR = (uint32_t)(macconf->VLANTagComparison |
+ macconf->VLANTagIdentifier);
+
+ /* Wait until the write operation will be taken into account :
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACVLANTR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACVLANTR = tmpreg1;
+ }
+ else /* macconf == NULL : here we just configure Speed and Duplex mode */
+ {
+ /*------------------------ ETHERNET MACCR Configuration --------------------*/
+ /* Get the ETHERNET MACCR value */
+ tmpreg1 = (heth->Instance)->MACCR;
+
+ /* Clear FES and DM bits */
+ tmpreg1 &= ~(0x00004800U);
+
+ tmpreg1 |= (uint32_t)(heth->Init.Speed | heth->Init.DuplexMode);
+
+ /* Write to ETHERNET MACCR */
+ (heth->Instance)->MACCR = (uint32_t)tmpreg1;
+
+ /* Wait until the write operation will be taken into account:
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACCR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACCR = tmpreg1;
+ }
+
+ /* Set the ETH state to Ready */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Sets ETH DMA Configuration.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @param dmaconf: DMA Configuration structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef *dmaconf)
+{
+ uint32_t tmpreg1 = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(heth);
+
+ /* Set the ETH peripheral state to BUSY */
+ heth->State = HAL_ETH_STATE_BUSY;
+
+ /* Check parameters */
+ assert_param(IS_ETH_DROP_TCPIP_CHECKSUM_FRAME(dmaconf->DropTCPIPChecksumErrorFrame));
+ assert_param(IS_ETH_RECEIVE_STORE_FORWARD(dmaconf->ReceiveStoreForward));
+ assert_param(IS_ETH_FLUSH_RECEIVE_FRAME(dmaconf->FlushReceivedFrame));
+ assert_param(IS_ETH_TRANSMIT_STORE_FORWARD(dmaconf->TransmitStoreForward));
+ assert_param(IS_ETH_TRANSMIT_THRESHOLD_CONTROL(dmaconf->TransmitThresholdControl));
+ assert_param(IS_ETH_FORWARD_ERROR_FRAMES(dmaconf->ForwardErrorFrames));
+ assert_param(IS_ETH_FORWARD_UNDERSIZED_GOOD_FRAMES(dmaconf->ForwardUndersizedGoodFrames));
+ assert_param(IS_ETH_RECEIVE_THRESHOLD_CONTROL(dmaconf->ReceiveThresholdControl));
+ assert_param(IS_ETH_SECOND_FRAME_OPERATE(dmaconf->SecondFrameOperate));
+ assert_param(IS_ETH_ADDRESS_ALIGNED_BEATS(dmaconf->AddressAlignedBeats));
+ assert_param(IS_ETH_FIXED_BURST(dmaconf->FixedBurst));
+ assert_param(IS_ETH_RXDMA_BURST_LENGTH(dmaconf->RxDMABurstLength));
+ assert_param(IS_ETH_TXDMA_BURST_LENGTH(dmaconf->TxDMABurstLength));
+ assert_param(IS_ETH_DMA_DESC_SKIP_LENGTH(dmaconf->DescriptorSkipLength));
+ assert_param(IS_ETH_DMA_ARBITRATION_ROUNDROBIN_RXTX(dmaconf->DMAArbitration));
+
+ /*----------------------- ETHERNET DMAOMR Configuration --------------------*/
+ /* Get the ETHERNET DMAOMR value */
+ tmpreg1 = (heth->Instance)->DMAOMR;
+ /* Clear xx bits */
+ tmpreg1 &= ETH_DMAOMR_CLEAR_MASK;
+
+ tmpreg1 |= (uint32_t)(dmaconf->DropTCPIPChecksumErrorFrame |
+ dmaconf->ReceiveStoreForward |
+ dmaconf->FlushReceivedFrame |
+ dmaconf->TransmitStoreForward |
+ dmaconf->TransmitThresholdControl |
+ dmaconf->ForwardErrorFrames |
+ dmaconf->ForwardUndersizedGoodFrames |
+ dmaconf->ReceiveThresholdControl |
+ dmaconf->SecondFrameOperate);
+
+ /* Write to ETHERNET DMAOMR */
+ (heth->Instance)->DMAOMR = (uint32_t)tmpreg1;
+
+ /* Wait until the write operation will be taken into account:
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->DMAOMR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->DMAOMR = tmpreg1;
+
+ /*----------------------- ETHERNET DMABMR Configuration --------------------*/
+ (heth->Instance)->DMABMR = (uint32_t)(dmaconf->AddressAlignedBeats |
+ dmaconf->FixedBurst |
+ dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
+ dmaconf->TxDMABurstLength |
+ (dmaconf->DescriptorSkipLength << 2U) |
+ dmaconf->DMAArbitration |
+ ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
+
+ /* Wait until the write operation will be taken into account:
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->DMABMR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->DMABMR = tmpreg1;
+
+ /* Set the ETH state to Ready */
+ heth->State = HAL_ETH_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(heth);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup ETH_Exported_Functions_Group4 Peripheral State functions
+ * @brief Peripheral State functions
+ *
+ @verbatim
+ ===============================================================================
+ ##### Peripheral State functions #####
+ ===============================================================================
+ [..]
+ This subsection permits to get in run-time the status of the peripheral
+ and the data flow.
+ (+) Get the ETH handle state:
+ HAL_ETH_GetState();
+
+
+ @endverbatim
+ * @{
+ */
+
+/**
+ * @brief Return the ETH HAL state
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval HAL state
+ */
+HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth)
+{
+ /* Return ETH state */
+ return heth->State;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup ETH_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Configures Ethernet MAC and DMA with default parameters.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @param err: Ethernet Init error
+ * @retval HAL status
+ */
+static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
+{
+ ETH_MACInitTypeDef macinit;
+ ETH_DMAInitTypeDef dmainit;
+ uint32_t tmpreg1 = 0U;
+
+ if (err != ETH_SUCCESS) /* Auto-negotiation failed */
+ {
+ /* Set Ethernet duplex mode to Full-duplex */
+ (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
+
+ /* Set Ethernet speed to 100M */
+ (heth->Init).Speed = ETH_SPEED_100M;
+ }
+
+ /* Ethernet MAC default initialization **************************************/
+ macinit.Watchdog = ETH_WATCHDOG_ENABLE;
+ macinit.Jabber = ETH_JABBER_ENABLE;
+ macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
+ macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
+ macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
+ macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
+ if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
+ {
+ macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
+ }
+ else
+ {
+ macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
+ }
+ macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE;
+ macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
+ macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
+ macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
+ macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE;
+ macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;
+ macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
+ macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;
+ macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;
+ macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;
+ macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;
+ macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
+ macinit.HashTableHigh = 0x0U;
+ macinit.HashTableLow = 0x0U;
+ macinit.PauseTime = 0x0U;
+ macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
+ macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
+ macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
+ macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
+ macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;
+ macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
+ macinit.VLANTagIdentifier = 0x0U;
+
+ /*------------------------ ETHERNET MACCR Configuration --------------------*/
+ /* Get the ETHERNET MACCR value */
+ tmpreg1 = (heth->Instance)->MACCR;
+ /* Clear WD, PCE, PS, TE and RE bits */
+ tmpreg1 &= ETH_MACCR_CLEAR_MASK;
+ /* Set the WD bit according to ETH Watchdog value */
+ /* Set the JD: bit according to ETH Jabber value */
+ /* Set the IFG bit according to ETH InterFrameGap value */
+ /* Set the DCRS bit according to ETH CarrierSense value */
+ /* Set the FES bit according to ETH Speed value */
+ /* Set the DO bit according to ETH ReceiveOwn value */
+ /* Set the LM bit according to ETH LoopbackMode value */
+ /* Set the DM bit according to ETH Mode value */
+ /* Set the IPCO bit according to ETH ChecksumOffload value */
+ /* Set the DR bit according to ETH RetryTransmission value */
+ /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */
+ /* Set the BL bit according to ETH BackOffLimit value */
+ /* Set the DC bit according to ETH DeferralCheck value */
+ tmpreg1 |= (uint32_t)(macinit.Watchdog |
+ macinit.Jabber |
+ macinit.InterFrameGap |
+ macinit.CarrierSense |
+ (heth->Init).Speed |
+ macinit.ReceiveOwn |
+ macinit.LoopbackMode |
+ (heth->Init).DuplexMode |
+ macinit.ChecksumOffload |
+ macinit.RetryTransmission |
+ macinit.AutomaticPadCRCStrip |
+ macinit.BackOffLimit |
+ macinit.DeferralCheck);
+
+ /* Write to ETHERNET MACCR */
+ (heth->Instance)->MACCR = (uint32_t)tmpreg1;
+
+ /* Wait until the write operation will be taken into account:
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACCR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACCR = tmpreg1;
+
+ /*----------------------- ETHERNET MACFFR Configuration --------------------*/
+ /* Set the RA bit according to ETH ReceiveAll value */
+ /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */
+ /* Set the PCF bit according to ETH PassControlFrames value */
+ /* Set the DBF bit according to ETH BroadcastFramesReception value */
+ /* Set the DAIF bit according to ETH DestinationAddrFilter value */
+ /* Set the PR bit according to ETH PromiscuousMode value */
+ /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */
+ /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */
+ /* Write to ETHERNET MACFFR */
+ (heth->Instance)->MACFFR = (uint32_t)(macinit.ReceiveAll |
+ macinit.SourceAddrFilter |
+ macinit.PassControlFrames |
+ macinit.BroadcastFramesReception |
+ macinit.DestinationAddrFilter |
+ macinit.PromiscuousMode |
+ macinit.MulticastFramesFilter |
+ macinit.UnicastFramesFilter);
+
+ /* Wait until the write operation will be taken into account:
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACFFR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACFFR = tmpreg1;
+
+ /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/
+ /* Write to ETHERNET MACHTHR */
+ (heth->Instance)->MACHTHR = (uint32_t)macinit.HashTableHigh;
+
+ /* Write to ETHERNET MACHTLR */
+ (heth->Instance)->MACHTLR = (uint32_t)macinit.HashTableLow;
+ /*----------------------- ETHERNET MACFCR Configuration -------------------*/
+
+ /* Get the ETHERNET MACFCR value */
+ tmpreg1 = (heth->Instance)->MACFCR;
+ /* Clear xx bits */
+ tmpreg1 &= ETH_MACFCR_CLEAR_MASK;
+
+ /* Set the PT bit according to ETH PauseTime value */
+ /* Set the DZPQ bit according to ETH ZeroQuantaPause value */
+ /* Set the PLT bit according to ETH PauseLowThreshold value */
+ /* Set the UP bit according to ETH UnicastPauseFrameDetect value */
+ /* Set the RFE bit according to ETH ReceiveFlowControl value */
+ /* Set the TFE bit according to ETH TransmitFlowControl value */
+ tmpreg1 |= (uint32_t)((macinit.PauseTime << 16U) |
+ macinit.ZeroQuantaPause |
+ macinit.PauseLowThreshold |
+ macinit.UnicastPauseFrameDetect |
+ macinit.ReceiveFlowControl |
+ macinit.TransmitFlowControl);
+
+ /* Write to ETHERNET MACFCR */
+ (heth->Instance)->MACFCR = (uint32_t)tmpreg1;
+
+ /* Wait until the write operation will be taken into account:
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACFCR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACFCR = tmpreg1;
+
+ /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/
+ /* Set the ETV bit according to ETH VLANTagComparison value */
+ /* Set the VL bit according to ETH VLANTagIdentifier value */
+ (heth->Instance)->MACVLANTR = (uint32_t)(macinit.VLANTagComparison |
+ macinit.VLANTagIdentifier);
+
+ /* Wait until the write operation will be taken into account:
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACVLANTR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACVLANTR = tmpreg1;
+
+ /* Ethernet DMA default initialization ************************************/
+ dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
+ dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
+ dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
+ dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
+ dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
+ dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
+ dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
+ dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
+ dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
+ dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
+ dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;
+ dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
+ dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
+ dmainit.DescriptorSkipLength = 0x0U;
+ dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
+
+ /* Get the ETHERNET DMAOMR value */
+ tmpreg1 = (heth->Instance)->DMAOMR;
+ /* Clear xx bits */
+ tmpreg1 &= ETH_DMAOMR_CLEAR_MASK;
+
+ /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */
+ /* Set the RSF bit according to ETH ReceiveStoreForward value */
+ /* Set the DFF bit according to ETH FlushReceivedFrame value */
+ /* Set the TSF bit according to ETH TransmitStoreForward value */
+ /* Set the TTC bit according to ETH TransmitThresholdControl value */
+ /* Set the FEF bit according to ETH ForwardErrorFrames value */
+ /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */
+ /* Set the RTC bit according to ETH ReceiveThresholdControl value */
+ /* Set the OSF bit according to ETH SecondFrameOperate value */
+ tmpreg1 |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame |
+ dmainit.ReceiveStoreForward |
+ dmainit.FlushReceivedFrame |
+ dmainit.TransmitStoreForward |
+ dmainit.TransmitThresholdControl |
+ dmainit.ForwardErrorFrames |
+ dmainit.ForwardUndersizedGoodFrames |
+ dmainit.ReceiveThresholdControl |
+ dmainit.SecondFrameOperate);
+
+ /* Write to ETHERNET DMAOMR */
+ (heth->Instance)->DMAOMR = (uint32_t)tmpreg1;
+
+ /* Wait until the write operation will be taken into account:
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->DMAOMR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->DMAOMR = tmpreg1;
+
+ /*----------------------- ETHERNET DMABMR Configuration ------------------*/
+ /* Set the AAL bit according to ETH AddressAlignedBeats value */
+ /* Set the FB bit according to ETH FixedBurst value */
+ /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */
+ /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */
+ /* Set the DSL bit according to ETH DesciptorSkipLength value */
+ /* Set the PR and DA bits according to ETH DMAArbitration value */
+ (heth->Instance)->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats |
+ dmainit.FixedBurst |
+ dmainit.RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
+ dmainit.TxDMABurstLength |
+ (dmainit.DescriptorSkipLength << 2U) |
+ dmainit.DMAArbitration |
+ ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
+
+ /* Wait until the write operation will be taken into account:
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->DMABMR;
+ HAL_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->DMABMR = tmpreg1;
+
+ if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE)
+ {
+ /* Enable the Ethernet Rx Interrupt */
+ __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R);
+ }
+
+ /* Initialize MAC address in ethernet MAC */
+ ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
+}
+
+/**
+ * @brief Configures the selected MAC address.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @param MacAddr: The MAC address to configure
+ * This parameter can be one of the following values:
+ * @arg ETH_MAC_Address0: MAC Address0
+ * @arg ETH_MAC_Address1: MAC Address1
+ * @arg ETH_MAC_Address2: MAC Address2
+ * @arg ETH_MAC_Address3: MAC Address3
+ * @param Addr: Pointer to MAC address buffer data (6 bytes)
+ * @retval HAL status
+ */
+static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)
+{
+ uint32_t tmpreg1;
+
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(heth);
+
+ /* Check the parameters */
+ assert_param(IS_ETH_MAC_ADDRESS0123(MacAddr));
+
+ /* Calculate the selected MAC address high register */
+ tmpreg1 = ((uint32_t)Addr[5U] << 8U) | (uint32_t)Addr[4U];
+ /* Load the selected MAC address high register */
+ (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_HBASE + MacAddr))) = tmpreg1;
+ /* Calculate the selected MAC address low register */
+ tmpreg1 = ((uint32_t)Addr[3U] << 24U) | ((uint32_t)Addr[2U] << 16U) | ((uint32_t)Addr[1U] << 8U) | Addr[0U];
+
+ /* Load the selected MAC address low register */
+ (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_LBASE + MacAddr))) = tmpreg1;
+}
+
+/**
+ * @brief Enables the MAC transmission.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval None
+ */
+static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth)
+{
+ __IO uint32_t tmpreg1 = 0U;
+
+ /* Enable the MAC transmission */
+ (heth->Instance)->MACCR |= ETH_MACCR_TE;
+
+ /* Wait until the write operation will be taken into account:
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACCR;
+ ETH_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACCR = tmpreg1;
+}
+
+/**
+ * @brief Disables the MAC transmission.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval None
+ */
+static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth)
+{
+ __IO uint32_t tmpreg1 = 0U;
+
+ /* Disable the MAC transmission */
+ (heth->Instance)->MACCR &= ~ETH_MACCR_TE;
+
+ /* Wait until the write operation will be taken into account:
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACCR;
+ ETH_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACCR = tmpreg1;
+}
+
+/**
+ * @brief Enables the MAC reception.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval None
+ */
+static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth)
+{
+ __IO uint32_t tmpreg1 = 0U;
+
+ /* Enable the MAC reception */
+ (heth->Instance)->MACCR |= ETH_MACCR_RE;
+
+ /* Wait until the write operation will be taken into account:
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACCR;
+ ETH_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACCR = tmpreg1;
+}
+
+/**
+ * @brief Disables the MAC reception.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval None
+ */
+static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth)
+{
+ __IO uint32_t tmpreg1 = 0U;
+
+ /* Disable the MAC reception */
+ (heth->Instance)->MACCR &= ~ETH_MACCR_RE;
+
+ /* Wait until the write operation will be taken into account:
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->MACCR;
+ ETH_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->MACCR = tmpreg1;
+}
+
+/**
+ * @brief Enables the DMA transmission.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval None
+ */
+static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth)
+{
+ /* Enable the DMA transmission */
+ (heth->Instance)->DMAOMR |= ETH_DMAOMR_ST;
+}
+
+/**
+ * @brief Disables the DMA transmission.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval None
+ */
+static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth)
+{
+ /* Disable the DMA transmission */
+ (heth->Instance)->DMAOMR &= ~ETH_DMAOMR_ST;
+}
+
+/**
+ * @brief Enables the DMA reception.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval None
+ */
+static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth)
+{
+ /* Enable the DMA reception */
+ (heth->Instance)->DMAOMR |= ETH_DMAOMR_SR;
+}
+
+/**
+ * @brief Disables the DMA reception.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval None
+ */
+static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth)
+{
+ /* Disable the DMA reception */
+ (heth->Instance)->DMAOMR &= ~ETH_DMAOMR_SR;
+}
+
+/**
+ * @brief Clears the ETHERNET transmit FIFO.
+ * @param heth: pointer to a ETH_HandleTypeDef structure that contains
+ * the configuration information for ETHERNET module
+ * @retval None
+ */
+static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth)
+{
+ __IO uint32_t tmpreg1 = 0U;
+
+ /* Set the Flush Transmit FIFO bit */
+ (heth->Instance)->DMAOMR |= ETH_DMAOMR_FTF;
+
+ /* Wait until the write operation will be taken into account:
+ at least four TX_CLK/RX_CLK clock cycles */
+ tmpreg1 = (heth->Instance)->DMAOMR;
+ ETH_Delay(ETH_REG_WRITE_DELAY);
+ (heth->Instance)->DMAOMR = tmpreg1;
+}
+
+/**
+ * @brief This function provides delay (in milliseconds) based on CPU cycles method.
+ * @param mdelay: specifies the delay time length, in milliseconds.
+ * @retval None
+ */
+static void ETH_Delay(uint32_t mdelay)
+{
+ __IO uint32_t Delay = mdelay * (SystemCoreClock / 8U / 1000U);
+ do
+ {
+ __NOP();
+ }
+ while (Delay --);
+}
+
+/**
+ * @}
+ */
+
+#endif /* HAL_ETH_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+#endif /* STM32F107xC */
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c
new file mode 100644
index 0000000..ea72390
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c
@@ -0,0 +1,983 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_flash.c
+ * @author MCD Application Team
+ * @brief FLASH HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the internal FLASH memory:
+ * + Program operations functions
+ * + Memory Control functions
+ * + Peripheral State functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### FLASH peripheral features #####
+ ==============================================================================
+ [..] The Flash memory interface manages CPU AHB I-Code and D-Code accesses
+ to the Flash memory. It implements the erase and program Flash memory operations
+ and the read and write protection mechanisms.
+
+ [..] The Flash memory interface accelerates code execution with a system of instruction
+ prefetch.
+
+ [..] The FLASH main features are:
+ (+) Flash memory read operations
+ (+) Flash memory program/erase operations
+ (+) Read / write protections
+ (+) Prefetch on I-Code
+ (+) Option Bytes programming
+
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ This driver provides functions and macros to configure and program the FLASH
+ memory of all STM32F1xx devices.
+
+ (#) FLASH Memory I/O Programming functions: this group includes all needed
+ functions to erase and program the main memory:
+ (++) Lock and Unlock the FLASH interface
+ (++) Erase function: Erase page, erase all pages
+ (++) Program functions: half word, word and doubleword
+ (#) FLASH Option Bytes Programming functions: this group includes all needed
+ functions to manage the Option Bytes:
+ (++) Lock and Unlock the Option Bytes
+ (++) Set/Reset the write protection
+ (++) Set the Read protection Level
+ (++) Program the user Option Bytes
+ (++) Launch the Option Bytes loader
+ (++) Erase Option Bytes
+ (++) Program the data Option Bytes
+ (++) Get the Write protection.
+ (++) Get the user option bytes.
+
+ (#) Interrupts and flags management functions : this group
+ includes all needed functions to:
+ (++) Handle FLASH interrupts
+ (++) Wait for last FLASH operation according to its status
+ (++) Get error flag status
+
+ [..] In addition to these function, this driver includes a set of macros allowing
+ to handle the following operations:
+
+ (+) Set/Get the latency
+ (+) Enable/Disable the prefetch buffer
+ (+) Enable/Disable the half cycle access
+ (+) Enable/Disable the FLASH interrupts
+ (+) Monitor the FLASH flags status
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_FLASH_MODULE_ENABLED
+
+/** @defgroup FLASH FLASH
+ * @brief FLASH HAL module driver
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup FLASH_Private_Constants FLASH Private Constants
+ * @{
+ */
+/**
+ * @}
+ */
+
+/* Private macro ---------------------------- ---------------------------------*/
+/** @defgroup FLASH_Private_Macros FLASH Private Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/** @defgroup FLASH_Private_Variables FLASH Private Variables
+ * @{
+ */
+/* Variables used for Erase pages under interruption*/
+FLASH_ProcessTypeDef pFlash;
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup FLASH_Private_Functions FLASH Private Functions
+ * @{
+ */
+static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data);
+static void FLASH_SetErrorCode(void);
+extern void FLASH_PageErase(uint32_t PageAddress);
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+/** @defgroup FLASH_Exported_Functions FLASH Exported Functions
+ * @{
+ */
+
+/** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
+ * @brief Programming operation functions
+ *
+@verbatim
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Program halfword, word or double word at a specified address
+ * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
+ * The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
+ *
+ * @note If an erase and a program operations are requested simultaneously,
+ * the erase operation is performed before the program one.
+ *
+ * @note FLASH should be previously erased before new programmation (only exception to this
+ * is when 0x0000 is programmed)
+ *
+ * @param TypeProgram: Indicate the way to program at a specified address.
+ * This parameter can be a value of @ref FLASH_Type_Program
+ * @param Address: Specifies the address to be programmed.
+ * @param Data: Specifies the data to be programmed
+ *
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
+{
+ HAL_StatusTypeDef status = HAL_ERROR;
+ uint8_t index = 0;
+ uint8_t nbiterations = 0;
+
+ /* Process Locked */
+ __HAL_LOCK(&pFlash);
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
+ assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
+
+#if defined(FLASH_BANK2_END)
+ if(Address <= FLASH_BANK1_END)
+ {
+#endif /* FLASH_BANK2_END */
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
+#if defined(FLASH_BANK2_END)
+ }
+ else
+ {
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperationBank2(FLASH_TIMEOUT_VALUE);
+ }
+#endif /* FLASH_BANK2_END */
+
+ if(status == HAL_OK)
+ {
+ if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
+ {
+ /* Program halfword (16-bit) at a specified address. */
+ nbiterations = 1U;
+ }
+ else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
+ {
+ /* Program word (32-bit = 2*16-bit) at a specified address. */
+ nbiterations = 2U;
+ }
+ else
+ {
+ /* Program double word (64-bit = 4*16-bit) at a specified address. */
+ nbiterations = 4U;
+ }
+
+ for (index = 0U; index < nbiterations; index++)
+ {
+ FLASH_Program_HalfWord((Address + (2U*index)), (uint16_t)(Data >> (16U*index)));
+
+#if defined(FLASH_BANK2_END)
+ if(Address <= FLASH_BANK1_END)
+ {
+#endif /* FLASH_BANK2_END */
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
+
+ /* If the program operation is completed, disable the PG Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
+#if defined(FLASH_BANK2_END)
+ }
+ else
+ {
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperationBank2(FLASH_TIMEOUT_VALUE);
+
+ /* If the program operation is completed, disable the PG Bit */
+ CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG);
+ }
+#endif /* FLASH_BANK2_END */
+ /* In case of error, stop programation procedure */
+ if (status != HAL_OK)
+ {
+ break;
+ }
+ }
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+
+ return status;
+}
+
+/**
+ * @brief Program halfword, word or double word at a specified address with interrupt enabled.
+ * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
+ * The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
+ *
+ * @note If an erase and a program operations are requested simultaneously,
+ * the erase operation is performed before the program one.
+ *
+ * @param TypeProgram: Indicate the way to program at a specified address.
+ * This parameter can be a value of @ref FLASH_Type_Program
+ * @param Address: Specifies the address to be programmed.
+ * @param Data: Specifies the data to be programmed
+ *
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process Locked */
+ __HAL_LOCK(&pFlash);
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
+ assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
+
+#if defined(FLASH_BANK2_END)
+ /* If procedure already ongoing, reject the next one */
+ if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
+ {
+ return HAL_ERROR;
+ }
+
+ if(Address <= FLASH_BANK1_END)
+ {
+ /* Enable End of FLASH Operation and Error source interrupts */
+ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1);
+
+ }else
+ {
+ /* Enable End of FLASH Operation and Error source interrupts */
+ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
+ }
+#else
+ /* Enable End of FLASH Operation and Error source interrupts */
+ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
+#endif /* FLASH_BANK2_END */
+
+ pFlash.Address = Address;
+ pFlash.Data = Data;
+
+ if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
+ {
+ pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMHALFWORD;
+ /* Program halfword (16-bit) at a specified address. */
+ pFlash.DataRemaining = 1U;
+ }
+ else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
+ {
+ pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMWORD;
+ /* Program word (32-bit : 2*16-bit) at a specified address. */
+ pFlash.DataRemaining = 2U;
+ }
+ else
+ {
+ pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMDOUBLEWORD;
+ /* Program double word (64-bit : 4*16-bit) at a specified address. */
+ pFlash.DataRemaining = 4U;
+ }
+
+ /* Program halfword (16-bit) at a specified address. */
+ FLASH_Program_HalfWord(Address, (uint16_t)Data);
+
+ return status;
+}
+
+/**
+ * @brief This function handles FLASH interrupt request.
+ * @retval None
+ */
+void HAL_FLASH_IRQHandler(void)
+{
+ uint32_t addresstmp = 0U;
+
+ /* Check FLASH operation error flags */
+#if defined(FLASH_BANK2_END)
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK1) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK1) || \
+ (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2)))
+#else
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) ||__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
+#endif /* FLASH_BANK2_END */
+ {
+ /* Return the faulty address */
+ addresstmp = pFlash.Address;
+ /* Reset address */
+ pFlash.Address = 0xFFFFFFFFU;
+
+ /* Save the Error code */
+ FLASH_SetErrorCode();
+
+ /* FLASH error interrupt user callback */
+ HAL_FLASH_OperationErrorCallback(addresstmp);
+
+ /* Stop the procedure ongoing */
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+ }
+
+ /* Check FLASH End of Operation flag */
+#if defined(FLASH_BANK2_END)
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK1))
+ {
+ /* Clear FLASH End of Operation pending bit */
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK1);
+#else
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
+ {
+ /* Clear FLASH End of Operation pending bit */
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
+#endif /* FLASH_BANK2_END */
+
+ /* Process can continue only if no error detected */
+ if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
+ {
+ if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
+ {
+ /* Nb of pages to erased can be decreased */
+ pFlash.DataRemaining--;
+
+ /* Check if there are still pages to erase */
+ if(pFlash.DataRemaining != 0U)
+ {
+ addresstmp = pFlash.Address;
+ /*Indicate user which sector has been erased */
+ HAL_FLASH_EndOfOperationCallback(addresstmp);
+
+ /*Increment sector number*/
+ addresstmp = pFlash.Address + FLASH_PAGE_SIZE;
+ pFlash.Address = addresstmp;
+
+ /* If the erase operation is completed, disable the PER Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
+
+ FLASH_PageErase(addresstmp);
+ }
+ else
+ {
+ /* No more pages to Erase, user callback can be called. */
+ /* Reset Sector and stop Erase pages procedure */
+ pFlash.Address = addresstmp = 0xFFFFFFFFU;
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+ /* FLASH EOP interrupt user callback */
+ HAL_FLASH_EndOfOperationCallback(addresstmp);
+ }
+ }
+ else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
+ {
+ /* Operation is completed, disable the MER Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
+
+#if defined(FLASH_BANK2_END)
+ /* Stop Mass Erase procedure if no pending mass erase on other bank */
+ if (HAL_IS_BIT_CLR(FLASH->CR2, FLASH_CR2_MER))
+ {
+#endif /* FLASH_BANK2_END */
+ /* MassErase ended. Return the selected bank */
+ /* FLASH EOP interrupt user callback */
+ HAL_FLASH_EndOfOperationCallback(0U);
+
+ /* Stop Mass Erase procedure*/
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+ }
+#if defined(FLASH_BANK2_END)
+ }
+#endif /* FLASH_BANK2_END */
+ else
+ {
+ /* Nb of 16-bit data to program can be decreased */
+ pFlash.DataRemaining--;
+
+ /* Check if there are still 16-bit data to program */
+ if(pFlash.DataRemaining != 0U)
+ {
+ /* Increment address to 16-bit */
+ pFlash.Address += 2U;
+ addresstmp = pFlash.Address;
+
+ /* Shift to have next 16-bit data */
+ pFlash.Data = (pFlash.Data >> 16U);
+
+ /* Operation is completed, disable the PG Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
+
+ /*Program halfword (16-bit) at a specified address.*/
+ FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
+ }
+ else
+ {
+ /* Program ended. Return the selected address */
+ /* FLASH EOP interrupt user callback */
+ if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
+ {
+ HAL_FLASH_EndOfOperationCallback(pFlash.Address);
+ }
+ else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
+ {
+ HAL_FLASH_EndOfOperationCallback(pFlash.Address - 2U);
+ }
+ else
+ {
+ HAL_FLASH_EndOfOperationCallback(pFlash.Address - 6U);
+ }
+
+ /* Reset Address and stop Program procedure */
+ pFlash.Address = 0xFFFFFFFFU;
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+ }
+ }
+ }
+ }
+
+#if defined(FLASH_BANK2_END)
+ /* Check FLASH End of Operation flag */
+ if(__HAL_FLASH_GET_FLAG( FLASH_FLAG_EOP_BANK2))
+ {
+ /* Clear FLASH End of Operation pending bit */
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2);
+
+ /* Process can continue only if no error detected */
+ if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
+ {
+ if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
+ {
+ /* Nb of pages to erased can be decreased */
+ pFlash.DataRemaining--;
+
+ /* Check if there are still pages to erase*/
+ if(pFlash.DataRemaining != 0U)
+ {
+ /* Indicate user which page address has been erased*/
+ HAL_FLASH_EndOfOperationCallback(pFlash.Address);
+
+ /* Increment page address to next page */
+ pFlash.Address += FLASH_PAGE_SIZE;
+ addresstmp = pFlash.Address;
+
+ /* Operation is completed, disable the PER Bit */
+ CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER);
+
+ FLASH_PageErase(addresstmp);
+ }
+ else
+ {
+ /*No more pages to Erase*/
+
+ /*Reset Address and stop Erase pages procedure*/
+ pFlash.Address = 0xFFFFFFFFU;
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+
+ /* FLASH EOP interrupt user callback */
+ HAL_FLASH_EndOfOperationCallback(pFlash.Address);
+ }
+ }
+ else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
+ {
+ /* Operation is completed, disable the MER Bit */
+ CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
+
+ if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_MER))
+ {
+ /* MassErase ended. Return the selected bank*/
+ /* FLASH EOP interrupt user callback */
+ HAL_FLASH_EndOfOperationCallback(0U);
+
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+ }
+ }
+ else
+ {
+ /* Nb of 16-bit data to program can be decreased */
+ pFlash.DataRemaining--;
+
+ /* Check if there are still 16-bit data to program */
+ if(pFlash.DataRemaining != 0U)
+ {
+ /* Increment address to 16-bit */
+ pFlash.Address += 2U;
+ addresstmp = pFlash.Address;
+
+ /* Shift to have next 16-bit data */
+ pFlash.Data = (pFlash.Data >> 16U);
+
+ /* Operation is completed, disable the PG Bit */
+ CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG);
+
+ /*Program halfword (16-bit) at a specified address.*/
+ FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
+ }
+ else
+ {
+ /*Program ended. Return the selected address*/
+ /* FLASH EOP interrupt user callback */
+ if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
+ {
+ HAL_FLASH_EndOfOperationCallback(pFlash.Address);
+ }
+ else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
+ {
+ HAL_FLASH_EndOfOperationCallback(pFlash.Address-2U);
+ }
+ else
+ {
+ HAL_FLASH_EndOfOperationCallback(pFlash.Address-6U);
+ }
+
+ /* Reset Address and stop Program procedure*/
+ pFlash.Address = 0xFFFFFFFFU;
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+ }
+ }
+ }
+ }
+#endif
+
+ if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
+ {
+#if defined(FLASH_BANK2_END)
+ /* Operation is completed, disable the PG, PER and MER Bits for both bank */
+ CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER));
+ CLEAR_BIT(FLASH->CR2, (FLASH_CR2_PG | FLASH_CR2_PER | FLASH_CR2_MER));
+
+ /* Disable End of FLASH Operation and Error source interrupts for both banks */
+ __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1 | FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
+#else
+ /* Operation is completed, disable the PG, PER and MER Bits */
+ CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER));
+
+ /* Disable End of FLASH Operation and Error source interrupts */
+ __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
+#endif /* FLASH_BANK2_END */
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+ }
+}
+
+/**
+ * @brief FLASH end of operation interrupt callback
+ * @param ReturnValue: The value saved in this parameter depends on the ongoing procedure
+ * - Mass Erase: No return value expected
+ * - Pages Erase: Address of the page which has been erased
+ * (if 0xFFFFFFFF, it means that all the selected pages have been erased)
+ * - Program: Address which was selected for data program
+ * @retval none
+ */
+__weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(ReturnValue);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief FLASH operation error interrupt callback
+ * @param ReturnValue: The value saved in this parameter depends on the ongoing procedure
+ * - Mass Erase: No return value expected
+ * - Pages Erase: Address of the page which returned an error
+ * - Program: Address which was selected for data program
+ * @retval none
+ */
+__weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(ReturnValue);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_FLASH_OperationErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
+ * @brief management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the FLASH
+ memory operations.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Unlock the FLASH control register access
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_Unlock(void)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
+ {
+ /* Authorize the FLASH Registers access */
+ WRITE_REG(FLASH->KEYR, FLASH_KEY1);
+ WRITE_REG(FLASH->KEYR, FLASH_KEY2);
+
+ /* Verify Flash is unlocked */
+ if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
+ {
+ status = HAL_ERROR;
+ }
+ }
+#if defined(FLASH_BANK2_END)
+ if(READ_BIT(FLASH->CR2, FLASH_CR2_LOCK) != RESET)
+ {
+ /* Authorize the FLASH BANK2 Registers access */
+ WRITE_REG(FLASH->KEYR2, FLASH_KEY1);
+ WRITE_REG(FLASH->KEYR2, FLASH_KEY2);
+
+ /* Verify Flash BANK2 is unlocked */
+ if(READ_BIT(FLASH->CR2, FLASH_CR2_LOCK) != RESET)
+ {
+ status = HAL_ERROR;
+ }
+ }
+#endif /* FLASH_BANK2_END */
+
+ return status;
+}
+
+/**
+ * @brief Locks the FLASH control register access
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_Lock(void)
+{
+ /* Set the LOCK Bit to lock the FLASH Registers access */
+ SET_BIT(FLASH->CR, FLASH_CR_LOCK);
+
+#if defined(FLASH_BANK2_END)
+ /* Set the LOCK Bit to lock the FLASH BANK2 Registers access */
+ SET_BIT(FLASH->CR2, FLASH_CR2_LOCK);
+
+#endif /* FLASH_BANK2_END */
+ return HAL_OK;
+}
+
+/**
+ * @brief Unlock the FLASH Option Control Registers access.
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
+{
+ if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_OPTWRE))
+ {
+ /* Authorizes the Option Byte register programming */
+ WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
+ WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Lock the FLASH Option Control Registers access.
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
+{
+ /* Clear the OPTWRE Bit to lock the FLASH Option Byte Registers access */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTWRE);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Launch the option byte loading.
+ * @note This function will reset automatically the MCU.
+ * @retval None
+ */
+void HAL_FLASH_OB_Launch(void)
+{
+ /* Initiates a system reset request to launch the option byte loading */
+ HAL_NVIC_SystemReset();
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Exported_Functions_Group3 Peripheral errors functions
+ * @brief Peripheral errors functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Errors functions #####
+ ===============================================================================
+ [..]
+ This subsection permit to get in run-time errors of the FLASH peripheral.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Get the specific FLASH error flag.
+ * @retval FLASH_ErrorCode The returned value can be:
+ * @ref FLASH_Error_Codes
+ */
+uint32_t HAL_FLASH_GetError(void)
+{
+ return pFlash.ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup FLASH_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Program a half-word (16-bit) at a specified address.
+ * @param Address specify the address to be programmed.
+ * @param Data specify the data to be programmed.
+ * @retval None
+ */
+static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
+{
+ /* Clean the error context */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+#if defined(FLASH_BANK2_END)
+ if(Address <= FLASH_BANK1_END)
+ {
+#endif /* FLASH_BANK2_END */
+ /* Proceed to program the new data */
+ SET_BIT(FLASH->CR, FLASH_CR_PG);
+#if defined(FLASH_BANK2_END)
+ }
+ else
+ {
+ /* Proceed to program the new data */
+ SET_BIT(FLASH->CR2, FLASH_CR2_PG);
+ }
+#endif /* FLASH_BANK2_END */
+
+ /* Write data in the address */
+ *(__IO uint16_t*)Address = Data;
+}
+
+/**
+ * @brief Wait for a FLASH operation to complete.
+ * @param Timeout maximum flash operation timeout
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
+{
+ /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
+ Even if the FLASH operation fails, the BUSY flag will be reset and an error
+ flag will be set */
+
+ uint32_t tickstart = HAL_GetTick();
+
+ while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
+ {
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* Check FLASH End of Operation flag */
+ if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
+ {
+ /* Clear FLASH End of Operation pending bit */
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
+ }
+
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) ||
+ __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) ||
+ __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
+ {
+ /*Save the error code*/
+ FLASH_SetErrorCode();
+ return HAL_ERROR;
+ }
+
+ /* There is no error flag set */
+ return HAL_OK;
+}
+
+#if defined(FLASH_BANK2_END)
+/**
+ * @brief Wait for a FLASH BANK2 operation to complete.
+ * @param Timeout maximum flash operation timeout
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef FLASH_WaitForLastOperationBank2(uint32_t Timeout)
+{
+ /* Wait for the FLASH BANK2 operation to complete by polling on BUSY flag to be reset.
+ Even if the FLASH BANK2 operation fails, the BUSY flag will be reset and an error
+ flag will be set */
+
+ uint32_t tickstart = HAL_GetTick();
+
+ while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY_BANK2))
+ {
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* Check FLASH End of Operation flag */
+ if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK2))
+ {
+ /* Clear FLASH End of Operation pending bit */
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2);
+ }
+
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))
+ {
+ /*Save the error code*/
+ FLASH_SetErrorCode();
+ return HAL_ERROR;
+ }
+
+ /* If there is an error flag set */
+ return HAL_OK;
+
+}
+#endif /* FLASH_BANK2_END */
+
+/**
+ * @brief Set the specific FLASH error flag.
+ * @retval None
+ */
+static void FLASH_SetErrorCode(void)
+{
+ uint32_t flags = 0U;
+
+#if defined(FLASH_BANK2_END)
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2))
+#else
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR))
+#endif /* FLASH_BANK2_END */
+ {
+ pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
+#if defined(FLASH_BANK2_END)
+ flags |= FLASH_FLAG_WRPERR | FLASH_FLAG_WRPERR_BANK2;
+#else
+ flags |= FLASH_FLAG_WRPERR;
+#endif /* FLASH_BANK2_END */
+ }
+#if defined(FLASH_BANK2_END)
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))
+#else
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
+#endif /* FLASH_BANK2_END */
+ {
+ pFlash.ErrorCode |= HAL_FLASH_ERROR_PROG;
+#if defined(FLASH_BANK2_END)
+ flags |= FLASH_FLAG_PGERR | FLASH_FLAG_PGERR_BANK2;
+#else
+ flags |= FLASH_FLAG_PGERR;
+#endif /* FLASH_BANK2_END */
+ }
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR))
+ {
+ pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV;
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
+ }
+
+ /* Clear FLASH error pending bits */
+ __HAL_FLASH_CLEAR_FLAG(flags);
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_FLASH_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c
new file mode 100644
index 0000000..b83fbc6
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c
@@ -0,0 +1,1143 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_flash_ex.c
+ * @author MCD Application Team
+ * @brief Extended FLASH HAL module driver.
+ *
+ * This file provides firmware functions to manage the following
+ * functionalities of the FLASH peripheral:
+ * + Extended Initialization/de-initialization functions
+ * + Extended I/O operation functions
+ * + Extended Peripheral Control functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### Flash peripheral extended features #####
+ ==============================================================================
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..] This driver provides functions to configure and program the FLASH memory
+ of all STM32F1xxx devices. It includes
+
+ (++) Set/Reset the write protection
+ (++) Program the user Option Bytes
+ (++) Get the Read protection Level
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+#ifdef HAL_FLASH_MODULE_ENABLED
+
+/** @addtogroup FLASH
+ * @{
+ */
+/** @addtogroup FLASH_Private_Variables
+ * @{
+ */
+/* Variables used for Erase pages under interruption*/
+extern FLASH_ProcessTypeDef pFlash;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx FLASHEx
+ * @brief FLASH HAL Extension module driver
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup FLASHEx_Private_Constants FLASHEx Private Constants
+ * @{
+ */
+#define FLASH_POSITION_IWDGSW_BIT FLASH_OBR_IWDG_SW_Pos
+#define FLASH_POSITION_OB_USERDATA0_BIT FLASH_OBR_DATA0_Pos
+#define FLASH_POSITION_OB_USERDATA1_BIT FLASH_OBR_DATA1_Pos
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/** @defgroup FLASHEx_Private_Macros FLASHEx Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
+ * @{
+ */
+/* Erase operations */
+static void FLASH_MassErase(uint32_t Banks);
+void FLASH_PageErase(uint32_t PageAddress);
+
+/* Option bytes control */
+static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WriteProtectPage);
+static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WriteProtectPage);
+static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel);
+static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig);
+static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data);
+static uint32_t FLASH_OB_GetWRP(void);
+static uint32_t FLASH_OB_GetRDP(void);
+static uint8_t FLASH_OB_GetUser(void);
+
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+/** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions
+ * @{
+ */
+
+/** @defgroup FLASHEx_Exported_Functions_Group1 FLASHEx Memory Erasing functions
+ * @brief FLASH Memory Erasing functions
+ *
+@verbatim
+ ==============================================================================
+ ##### FLASH Erasing Programming functions #####
+ ==============================================================================
+
+ [..] The FLASH Memory Erasing functions, includes the following functions:
+ (+) @ref HAL_FLASHEx_Erase: return only when erase has been done
+ (+) @ref HAL_FLASHEx_Erase_IT: end of erase is done when @ref HAL_FLASH_EndOfOperationCallback
+ is called with parameter 0xFFFFFFFF
+
+ [..] Any operation of erase should follow these steps:
+ (#) Call the @ref HAL_FLASH_Unlock() function to enable the flash control register and
+ program memory access.
+ (#) Call the desired function to erase page.
+ (#) Call the @ref HAL_FLASH_Lock() to disable the flash program memory access
+ (recommended to protect the FLASH memory against possible unwanted operation).
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Perform a mass erase or erase the specified FLASH memory pages
+ * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function
+ * must be called before.
+ * Call the @ref HAL_FLASH_Lock() to disable the flash memory access
+ * (recommended to protect the FLASH memory against possible unwanted operation)
+ * @param[in] pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
+ * contains the configuration information for the erasing.
+ *
+ * @param[out] PageError pointer to variable that
+ * contains the configuration information on faulty page in case of error
+ * (0xFFFFFFFF means that all the pages have been correctly erased)
+ *
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
+{
+ HAL_StatusTypeDef status = HAL_ERROR;
+ uint32_t address = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(&pFlash);
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
+
+ if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
+ {
+#if defined(FLASH_BANK2_END)
+ if (pEraseInit->Banks == FLASH_BANK_BOTH)
+ {
+ /* Mass Erase requested for Bank1 and Bank2 */
+ /* Wait for last operation to be completed */
+ if ((FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) && \
+ (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK))
+ {
+ /*Mass erase to be done*/
+ FLASH_MassErase(FLASH_BANK_BOTH);
+
+ /* Wait for last operation to be completed */
+ if ((FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) && \
+ (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK))
+ {
+ status = HAL_OK;
+ }
+
+ /* If the erase operation is completed, disable the MER Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
+ CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
+ }
+ }
+ else if (pEraseInit->Banks == FLASH_BANK_2)
+ {
+ /* Mass Erase requested for Bank2 */
+ /* Wait for last operation to be completed */
+ if (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
+ {
+ /*Mass erase to be done*/
+ FLASH_MassErase(FLASH_BANK_2);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* If the erase operation is completed, disable the MER Bit */
+ CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
+ }
+ }
+ else
+#endif /* FLASH_BANK2_END */
+ {
+ /* Mass Erase requested for Bank1 */
+ /* Wait for last operation to be completed */
+ if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
+ {
+ /*Mass erase to be done*/
+ FLASH_MassErase(FLASH_BANK_1);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* If the erase operation is completed, disable the MER Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
+ }
+ }
+ }
+ else
+ {
+ /* Page Erase is requested */
+ /* Check the parameters */
+ assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
+ assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));
+
+#if defined(FLASH_BANK2_END)
+ /* Page Erase requested on address located on bank2 */
+ if(pEraseInit->PageAddress > FLASH_BANK1_END)
+ {
+ /* Wait for last operation to be completed */
+ if (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
+ {
+ /*Initialization of PageError variable*/
+ *PageError = 0xFFFFFFFFU;
+
+ /* Erase by page by page to be done*/
+ for(address = pEraseInit->PageAddress;
+ address < (pEraseInit->PageAddress + (pEraseInit->NbPages)*FLASH_PAGE_SIZE);
+ address += FLASH_PAGE_SIZE)
+ {
+ FLASH_PageErase(address);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* If the erase operation is completed, disable the PER Bit */
+ CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER);
+
+ if (status != HAL_OK)
+ {
+ /* In case of error, stop erase procedure and return the faulty address */
+ *PageError = address;
+ break;
+ }
+ }
+ }
+ }
+ else
+#endif /* FLASH_BANK2_END */
+ {
+ /* Page Erase requested on address located on bank1 */
+ /* Wait for last operation to be completed */
+ if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
+ {
+ /*Initialization of PageError variable*/
+ *PageError = 0xFFFFFFFFU;
+
+ /* Erase page by page to be done*/
+ for(address = pEraseInit->PageAddress;
+ address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress);
+ address += FLASH_PAGE_SIZE)
+ {
+ FLASH_PageErase(address);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* If the erase operation is completed, disable the PER Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
+
+ if (status != HAL_OK)
+ {
+ /* In case of error, stop erase procedure and return the faulty address */
+ *PageError = address;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+
+ return status;
+}
+
+/**
+ * @brief Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled
+ * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function
+ * must be called before.
+ * Call the @ref HAL_FLASH_Lock() to disable the flash memory access
+ * (recommended to protect the FLASH memory against possible unwanted operation)
+ * @param pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
+ * contains the configuration information for the erasing.
+ *
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process Locked */
+ __HAL_LOCK(&pFlash);
+
+ /* If procedure already ongoing, reject the next one */
+ if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
+
+ /* Enable End of FLASH Operation and Error source interrupts */
+ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
+
+#if defined(FLASH_BANK2_END)
+ /* Enable End of FLASH Operation and Error source interrupts */
+ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
+
+#endif
+ if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
+ {
+ /*Mass erase to be done*/
+ pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE;
+ FLASH_MassErase(pEraseInit->Banks);
+ }
+ else
+ {
+ /* Erase by page to be done*/
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
+ assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));
+
+ pFlash.ProcedureOnGoing = FLASH_PROC_PAGEERASE;
+ pFlash.DataRemaining = pEraseInit->NbPages;
+ pFlash.Address = pEraseInit->PageAddress;
+
+ /*Erase 1st page and wait for IT*/
+ FLASH_PageErase(pEraseInit->PageAddress);
+ }
+
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_Exported_Functions_Group2 Option Bytes Programming functions
+ * @brief Option Bytes Programming functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Option Bytes Programming functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the FLASH
+ option bytes operations.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Erases the FLASH option bytes.
+ * @note This functions erases all option bytes except the Read protection (RDP).
+ * The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
+ * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
+ * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
+ * (system reset will occur)
+ * @retval HAL status
+ */
+
+HAL_StatusTypeDef HAL_FLASHEx_OBErase(void)
+{
+ uint8_t rdptmp = OB_RDP_LEVEL_0;
+ HAL_StatusTypeDef status = HAL_ERROR;
+
+ /* Get the actual read protection Option Byte value */
+ rdptmp = FLASH_OB_GetRDP();
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ if(status == HAL_OK)
+ {
+ /* Clean the error context */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+ /* If the previous operation is completed, proceed to erase the option bytes */
+ SET_BIT(FLASH->CR, FLASH_CR_OPTER);
+ SET_BIT(FLASH->CR, FLASH_CR_STRT);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* If the erase operation is completed, disable the OPTER Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER);
+
+ if(status == HAL_OK)
+ {
+ /* Restore the last read protection Option Byte value */
+ status = FLASH_OB_RDP_LevelConfig(rdptmp);
+ }
+ }
+
+ /* Return the erase status */
+ return status;
+}
+
+/**
+ * @brief Program option bytes
+ * @note The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
+ * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
+ * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
+ * (system reset will occur)
+ *
+ * @param pOBInit pointer to an FLASH_OBInitStruct structure that
+ * contains the configuration information for the programming.
+ *
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
+{
+ HAL_StatusTypeDef status = HAL_ERROR;
+
+ /* Process Locked */
+ __HAL_LOCK(&pFlash);
+
+ /* Check the parameters */
+ assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
+
+ /* Write protection configuration */
+ if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
+ {
+ assert_param(IS_WRPSTATE(pOBInit->WRPState));
+ if (pOBInit->WRPState == OB_WRPSTATE_ENABLE)
+ {
+ /* Enable of Write protection on the selected page */
+ status = FLASH_OB_EnableWRP(pOBInit->WRPPage);
+ }
+ else
+ {
+ /* Disable of Write protection on the selected page */
+ status = FLASH_OB_DisableWRP(pOBInit->WRPPage);
+ }
+ if (status != HAL_OK)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+ return status;
+ }
+ }
+
+ /* Read protection configuration */
+ if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP)
+ {
+ status = FLASH_OB_RDP_LevelConfig(pOBInit->RDPLevel);
+ if (status != HAL_OK)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+ return status;
+ }
+ }
+
+ /* USER configuration */
+ if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER)
+ {
+ status = FLASH_OB_UserConfig(pOBInit->USERConfig);
+ if (status != HAL_OK)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+ return status;
+ }
+ }
+
+ /* DATA configuration*/
+ if((pOBInit->OptionType & OPTIONBYTE_DATA) == OPTIONBYTE_DATA)
+ {
+ status = FLASH_OB_ProgramData(pOBInit->DATAAddress, pOBInit->DATAData);
+ if (status != HAL_OK)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+ return status;
+ }
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+
+ return status;
+}
+
+/**
+ * @brief Get the Option byte configuration
+ * @param pOBInit pointer to an FLASH_OBInitStruct structure that
+ * contains the configuration information for the programming.
+ *
+ * @retval None
+ */
+void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
+{
+ pOBInit->OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER;
+
+ /*Get WRP*/
+ pOBInit->WRPPage = FLASH_OB_GetWRP();
+
+ /*Get RDP Level*/
+ pOBInit->RDPLevel = FLASH_OB_GetRDP();
+
+ /*Get USER*/
+ pOBInit->USERConfig = FLASH_OB_GetUser();
+}
+
+/**
+ * @brief Get the Option byte user data
+ * @param DATAAdress Address of the option byte DATA
+ * This parameter can be one of the following values:
+ * @arg @ref OB_DATA_ADDRESS_DATA0
+ * @arg @ref OB_DATA_ADDRESS_DATA1
+ * @retval Value programmed in USER data
+ */
+uint32_t HAL_FLASHEx_OBGetUserData(uint32_t DATAAdress)
+{
+ uint32_t value = 0;
+
+ if (DATAAdress == OB_DATA_ADDRESS_DATA0)
+ {
+ /* Get value programmed in OB USER Data0 */
+ value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA0) >> FLASH_POSITION_OB_USERDATA0_BIT;
+ }
+ else
+ {
+ /* Get value programmed in OB USER Data1 */
+ value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA1) >> FLASH_POSITION_OB_USERDATA1_BIT;
+ }
+
+ return value;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup FLASHEx_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Full erase of FLASH memory Bank
+ * @param Banks Banks to be erased
+ * This parameter can be one of the following values:
+ * @arg @ref FLASH_BANK_1 Bank1 to be erased
+ @if STM32F101xG
+ * @arg @ref FLASH_BANK_2 Bank2 to be erased
+ * @arg @ref FLASH_BANK_BOTH Bank1 and Bank2 to be erased
+ @endif
+ @if STM32F103xG
+ * @arg @ref FLASH_BANK_2 Bank2 to be erased
+ * @arg @ref FLASH_BANK_BOTH Bank1 and Bank2 to be erased
+ @endif
+ *
+ * @retval None
+ */
+static void FLASH_MassErase(uint32_t Banks)
+{
+ /* Check the parameters */
+ assert_param(IS_FLASH_BANK(Banks));
+
+ /* Clean the error context */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+#if defined(FLASH_BANK2_END)
+ if(Banks == FLASH_BANK_BOTH)
+ {
+ /* bank1 & bank2 will be erased*/
+ SET_BIT(FLASH->CR, FLASH_CR_MER);
+ SET_BIT(FLASH->CR2, FLASH_CR2_MER);
+ SET_BIT(FLASH->CR, FLASH_CR_STRT);
+ SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
+ }
+ else if(Banks == FLASH_BANK_2)
+ {
+ /*Only bank2 will be erased*/
+ SET_BIT(FLASH->CR2, FLASH_CR2_MER);
+ SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
+ }
+ else
+ {
+#endif /* FLASH_BANK2_END */
+#if !defined(FLASH_BANK2_END)
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(Banks);
+#endif /* FLASH_BANK2_END */
+ /* Only bank1 will be erased*/
+ SET_BIT(FLASH->CR, FLASH_CR_MER);
+ SET_BIT(FLASH->CR, FLASH_CR_STRT);
+#if defined(FLASH_BANK2_END)
+ }
+#endif /* FLASH_BANK2_END */
+}
+
+/**
+ * @brief Enable the write protection of the desired pages
+ * @note An option byte erase is done automatically in this function.
+ * @note When the memory read protection level is selected (RDP level = 1),
+ * it is not possible to program or erase the flash page i if
+ * debug features are connected or boot code is executed in RAM, even if nWRPi = 1
+ *
+ * @param WriteProtectPage specifies the page(s) to be write protected.
+ * The value of this parameter depend on device used within the same series
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WriteProtectPage)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+ uint16_t WRP0_Data = 0xFFFF;
+#if defined(FLASH_WRP1_WRP1)
+ uint16_t WRP1_Data = 0xFFFF;
+#endif /* FLASH_WRP1_WRP1 */
+#if defined(FLASH_WRP2_WRP2)
+ uint16_t WRP2_Data = 0xFFFF;
+#endif /* FLASH_WRP2_WRP2 */
+#if defined(FLASH_WRP3_WRP3)
+ uint16_t WRP3_Data = 0xFFFF;
+#endif /* FLASH_WRP3_WRP3 */
+
+ /* Check the parameters */
+ assert_param(IS_OB_WRP(WriteProtectPage));
+
+ /* Get current write protected pages and the new pages to be protected ******/
+ WriteProtectPage = (uint32_t)(~((~FLASH_OB_GetWRP()) | WriteProtectPage));
+
+#if defined(OB_WRP_PAGES0TO15MASK)
+ WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK);
+#elif defined(OB_WRP_PAGES0TO31MASK)
+ WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK);
+#endif /* OB_WRP_PAGES0TO31MASK */
+
+#if defined(OB_WRP_PAGES16TO31MASK)
+ WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8U);
+#elif defined(OB_WRP_PAGES32TO63MASK)
+ WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8U);
+#endif /* OB_WRP_PAGES32TO63MASK */
+
+#if defined(OB_WRP_PAGES64TO95MASK)
+ WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16U);
+#endif /* OB_WRP_PAGES64TO95MASK */
+#if defined(OB_WRP_PAGES32TO47MASK)
+ WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16U);
+#endif /* OB_WRP_PAGES32TO47MASK */
+
+#if defined(OB_WRP_PAGES96TO127MASK)
+ WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24U);
+#elif defined(OB_WRP_PAGES48TO255MASK)
+ WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24U);
+#elif defined(OB_WRP_PAGES48TO511MASK)
+ WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO511MASK) >> 24U);
+#elif defined(OB_WRP_PAGES48TO127MASK)
+ WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24U);
+#endif /* OB_WRP_PAGES96TO127MASK */
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ if(status == HAL_OK)
+ {
+ /* Clean the error context */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+ /* To be able to write again option byte, need to perform a option byte erase */
+ status = HAL_FLASHEx_OBErase();
+ if (status == HAL_OK)
+ {
+ /* Enable write protection */
+ SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
+
+#if defined(FLASH_WRP0_WRP0)
+ if(WRP0_Data != 0xFFU)
+ {
+ OB->WRP0 &= WRP0_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+ }
+#endif /* FLASH_WRP0_WRP0 */
+
+#if defined(FLASH_WRP1_WRP1)
+ if((status == HAL_OK) && (WRP1_Data != 0xFFU))
+ {
+ OB->WRP1 &= WRP1_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+ }
+#endif /* FLASH_WRP1_WRP1 */
+
+#if defined(FLASH_WRP2_WRP2)
+ if((status == HAL_OK) && (WRP2_Data != 0xFFU))
+ {
+ OB->WRP2 &= WRP2_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+ }
+#endif /* FLASH_WRP2_WRP2 */
+
+#if defined(FLASH_WRP3_WRP3)
+ if((status == HAL_OK) && (WRP3_Data != 0xFFU))
+ {
+ OB->WRP3 &= WRP3_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+ }
+#endif /* FLASH_WRP3_WRP3 */
+
+ /* if the program operation is completed, disable the OPTPG Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
+ }
+ }
+
+ return status;
+}
+
+/**
+ * @brief Disable the write protection of the desired pages
+ * @note An option byte erase is done automatically in this function.
+ * @note When the memory read protection level is selected (RDP level = 1),
+ * it is not possible to program or erase the flash page i if
+ * debug features are connected or boot code is executed in RAM, even if nWRPi = 1
+ *
+ * @param WriteProtectPage specifies the page(s) to be write unprotected.
+ * The value of this parameter depend on device used within the same series
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WriteProtectPage)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+ uint16_t WRP0_Data = 0xFFFF;
+#if defined(FLASH_WRP1_WRP1)
+ uint16_t WRP1_Data = 0xFFFF;
+#endif /* FLASH_WRP1_WRP1 */
+#if defined(FLASH_WRP2_WRP2)
+ uint16_t WRP2_Data = 0xFFFF;
+#endif /* FLASH_WRP2_WRP2 */
+#if defined(FLASH_WRP3_WRP3)
+ uint16_t WRP3_Data = 0xFFFF;
+#endif /* FLASH_WRP3_WRP3 */
+
+ /* Check the parameters */
+ assert_param(IS_OB_WRP(WriteProtectPage));
+
+ /* Get current write protected pages and the new pages to be unprotected ******/
+ WriteProtectPage = (FLASH_OB_GetWRP() | WriteProtectPage);
+
+#if defined(OB_WRP_PAGES0TO15MASK)
+ WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK);
+#elif defined(OB_WRP_PAGES0TO31MASK)
+ WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK);
+#endif /* OB_WRP_PAGES0TO31MASK */
+
+#if defined(OB_WRP_PAGES16TO31MASK)
+ WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8U);
+#elif defined(OB_WRP_PAGES32TO63MASK)
+ WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8U);
+#endif /* OB_WRP_PAGES32TO63MASK */
+
+#if defined(OB_WRP_PAGES64TO95MASK)
+ WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16U);
+#endif /* OB_WRP_PAGES64TO95MASK */
+#if defined(OB_WRP_PAGES32TO47MASK)
+ WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16U);
+#endif /* OB_WRP_PAGES32TO47MASK */
+
+#if defined(OB_WRP_PAGES96TO127MASK)
+ WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24U);
+#elif defined(OB_WRP_PAGES48TO255MASK)
+ WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24U);
+#elif defined(OB_WRP_PAGES48TO511MASK)
+ WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO511MASK) >> 24U);
+#elif defined(OB_WRP_PAGES48TO127MASK)
+ WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24U);
+#endif /* OB_WRP_PAGES96TO127MASK */
+
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ if(status == HAL_OK)
+ {
+ /* Clean the error context */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+ /* To be able to write again option byte, need to perform a option byte erase */
+ status = HAL_FLASHEx_OBErase();
+ if (status == HAL_OK)
+ {
+ SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
+
+#if defined(FLASH_WRP0_WRP0)
+ if(WRP0_Data != 0xFFU)
+ {
+ OB->WRP0 |= WRP0_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+ }
+#endif /* FLASH_WRP0_WRP0 */
+
+#if defined(FLASH_WRP1_WRP1)
+ if((status == HAL_OK) && (WRP1_Data != 0xFFU))
+ {
+ OB->WRP1 |= WRP1_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+ }
+#endif /* FLASH_WRP1_WRP1 */
+
+#if defined(FLASH_WRP2_WRP2)
+ if((status == HAL_OK) && (WRP2_Data != 0xFFU))
+ {
+ OB->WRP2 |= WRP2_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+ }
+#endif /* FLASH_WRP2_WRP2 */
+
+#if defined(FLASH_WRP3_WRP3)
+ if((status == HAL_OK) && (WRP3_Data != 0xFFU))
+ {
+ OB->WRP3 |= WRP3_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+ }
+#endif /* FLASH_WRP3_WRP3 */
+
+ /* if the program operation is completed, disable the OPTPG Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief Set the read protection level.
+ * @param ReadProtectLevel specifies the read protection level.
+ * This parameter can be one of the following values:
+ * @arg @ref OB_RDP_LEVEL_0 No protection
+ * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_OB_RDP_LEVEL(ReadProtectLevel));
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ if(status == HAL_OK)
+ {
+ /* Clean the error context */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+ /* If the previous operation is completed, proceed to erase the option bytes */
+ SET_BIT(FLASH->CR, FLASH_CR_OPTER);
+ SET_BIT(FLASH->CR, FLASH_CR_STRT);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* If the erase operation is completed, disable the OPTER Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER);
+
+ if(status == HAL_OK)
+ {
+ /* Enable the Option Bytes Programming operation */
+ SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
+
+ WRITE_REG(OB->RDP, ReadProtectLevel);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* if the program operation is completed, disable the OPTPG Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
+ }
+ }
+
+ return status;
+}
+
+/**
+ * @brief Program the FLASH User Option Byte.
+ * @note Programming of the OB should be performed only after an erase (otherwise PGERR occurs)
+ * @param UserConfig The FLASH User Option Bytes values FLASH_OBR_IWDG_SW(Bit2),
+ * FLASH_OBR_nRST_STOP(Bit3),FLASH_OBR_nRST_STDBY(Bit4).
+ * And BFBF2(Bit5) for STM32F101xG and STM32F103xG .
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_OB_IWDG_SOURCE((UserConfig&OB_IWDG_SW)));
+ assert_param(IS_OB_STOP_SOURCE((UserConfig&OB_STOP_NO_RST)));
+ assert_param(IS_OB_STDBY_SOURCE((UserConfig&OB_STDBY_NO_RST)));
+#if defined(FLASH_BANK2_END)
+ assert_param(IS_OB_BOOT1((UserConfig&OB_BOOT1_SET)));
+#endif /* FLASH_BANK2_END */
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ if(status == HAL_OK)
+ {
+ /* Clean the error context */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+ /* Enable the Option Bytes Programming operation */
+ SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
+
+#if defined(FLASH_BANK2_END)
+ OB->USER = (UserConfig | 0xF0U);
+#else
+ OB->USER = (UserConfig | 0x88U);
+#endif /* FLASH_BANK2_END */
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* if the program operation is completed, disable the OPTPG Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
+ }
+
+ return status;
+}
+
+/**
+ * @brief Programs a half word at a specified Option Byte Data address.
+ * @note The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
+ * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
+ * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
+ * (system reset will occur)
+ * Programming of the OB should be performed only after an erase (otherwise PGERR occurs)
+ * @param Address specifies the address to be programmed.
+ * This parameter can be 0x1FFFF804 or 0x1FFFF806.
+ * @param Data specifies the data to be programmed.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data)
+{
+ HAL_StatusTypeDef status = HAL_ERROR;
+
+ /* Check the parameters */
+ assert_param(IS_OB_DATA_ADDRESS(Address));
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ if(status == HAL_OK)
+ {
+ /* Clean the error context */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+ /* Enables the Option Bytes Programming operation */
+ SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
+ *(__IO uint16_t*)Address = Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* If the program operation is completed, disable the OPTPG Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
+ }
+ /* Return the Option Byte Data Program Status */
+ return status;
+}
+
+/**
+ * @brief Return the FLASH Write Protection Option Bytes value.
+ * @retval The FLASH Write Protection Option Bytes value
+ */
+static uint32_t FLASH_OB_GetWRP(void)
+{
+ /* Return the FLASH write protection Register value */
+ return (uint32_t)(READ_REG(FLASH->WRPR));
+}
+
+/**
+ * @brief Returns the FLASH Read Protection level.
+ * @retval FLASH RDP level
+ * This parameter can be one of the following values:
+ * @arg @ref OB_RDP_LEVEL_0 No protection
+ * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
+ */
+static uint32_t FLASH_OB_GetRDP(void)
+{
+ uint32_t readstatus = OB_RDP_LEVEL_0;
+ uint32_t tmp_reg = 0U;
+
+ /* Read RDP level bits */
+ tmp_reg = READ_BIT(FLASH->OBR, FLASH_OBR_RDPRT);
+
+ if (tmp_reg == FLASH_OBR_RDPRT)
+ {
+ readstatus = OB_RDP_LEVEL_1;
+ }
+ else
+ {
+ readstatus = OB_RDP_LEVEL_0;
+ }
+
+ return readstatus;
+}
+
+/**
+ * @brief Return the FLASH User Option Byte value.
+ * @retval The FLASH User Option Bytes values: FLASH_OBR_IWDG_SW(Bit2),
+ * FLASH_OBR_nRST_STOP(Bit3),FLASH_OBR_nRST_STDBY(Bit4).
+ * And FLASH_OBR_BFB2(Bit5) for STM32F101xG and STM32F103xG .
+ */
+static uint8_t FLASH_OB_GetUser(void)
+{
+ /* Return the User Option Byte */
+ return (uint8_t)((READ_REG(FLASH->OBR) & FLASH_OBR_USER) >> FLASH_POSITION_IWDGSW_BIT);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup FLASH
+ * @{
+ */
+
+/** @addtogroup FLASH_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Erase the specified FLASH memory page
+ * @param PageAddress FLASH page to erase
+ * The value of this parameter depend on device used within the same series
+ *
+ * @retval None
+ */
+void FLASH_PageErase(uint32_t PageAddress)
+{
+ /* Clean the error context */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+#if defined(FLASH_BANK2_END)
+ if(PageAddress > FLASH_BANK1_END)
+ {
+ /* Proceed to erase the page */
+ SET_BIT(FLASH->CR2, FLASH_CR2_PER);
+ WRITE_REG(FLASH->AR2, PageAddress);
+ SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
+ }
+ else
+ {
+#endif /* FLASH_BANK2_END */
+ /* Proceed to erase the page */
+ SET_BIT(FLASH->CR, FLASH_CR_PER);
+ WRITE_REG(FLASH->AR, PageAddress);
+ SET_BIT(FLASH->CR, FLASH_CR_STRT);
+#if defined(FLASH_BANK2_END)
+ }
+#endif /* FLASH_BANK2_END */
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_FLASH_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c
new file mode 100644
index 0000000..2d56951
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c
@@ -0,0 +1,595 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_gpio.c
+ * @author MCD Application Team
+ * @brief GPIO HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the General Purpose Input/Output (GPIO) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### GPIO Peripheral features #####
+ ==============================================================================
+ [..]
+ Subject to the specific hardware characteristics of each I/O port listed in the datasheet, each
+ port bit of the General Purpose IO (GPIO) Ports, can be individually configured by software
+ in several modes:
+ (+) Input mode
+ (+) Analog mode
+ (+) Output mode
+ (+) Alternate function mode
+ (+) External interrupt/event lines
+
+ [..]
+ During and just after reset, the alternate functions and external interrupt
+ lines are not active and the I/O ports are configured in input floating mode.
+
+ [..]
+ All GPIO pins have weak internal pull-up and pull-down resistors, which can be
+ activated or not.
+
+ [..]
+ In Output or Alternate mode, each IO can be configured on open-drain or push-pull
+ type and the IO speed can be selected depending on the VDD value.
+
+ [..]
+ All ports have external interrupt/event capability. To use external interrupt
+ lines, the port must be configured in input mode. All available GPIO pins are
+ connected to the 16 external interrupt/event lines from EXTI0 to EXTI15.
+
+ [..]
+ The external interrupt/event controller consists of up to 20 edge detectors in connectivity
+ line devices, or 19 edge detectors in other devices for generating event/interrupt requests.
+ Each input line can be independently configured to select the type (event or interrupt) and
+ the corresponding trigger event (rising or falling or both). Each line can also masked
+ independently. A pending register maintains the status line of the interrupt requests
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) Enable the GPIO APB2 clock using the following function : __HAL_RCC_GPIOx_CLK_ENABLE().
+
+ (#) Configure the GPIO pin(s) using HAL_GPIO_Init().
+ (++) Configure the IO mode using "Mode" member from GPIO_InitTypeDef structure
+ (++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef
+ structure.
+ (++) In case of Output or alternate function mode selection: the speed is
+ configured through "Speed" member from GPIO_InitTypeDef structure
+ (++) Analog mode is required when a pin is to be used as ADC channel
+ or DAC output.
+ (++) In case of external interrupt/event selection the "Mode" member from
+ GPIO_InitTypeDef structure select the type (interrupt or event) and
+ the corresponding trigger event (rising or falling or both).
+
+ (#) In case of external interrupt/event mode selection, configure NVIC IRQ priority
+ mapped to the EXTI line using HAL_NVIC_SetPriority() and enable it using
+ HAL_NVIC_EnableIRQ().
+
+ (#) To get the level of a pin configured in input mode use HAL_GPIO_ReadPin().
+
+ (#) To set/reset the level of a pin configured in output mode use
+ HAL_GPIO_WritePin()/HAL_GPIO_TogglePin().
+
+ (#) To lock pin configuration until next reset use HAL_GPIO_LockPin().
+
+ (#) During and just after reset, the alternate functions are not
+ active and the GPIO pins are configured in input floating mode (except JTAG
+ pins).
+
+ (#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose
+ (PC14 and PC15, respectively) when the LSE oscillator is off. The LSE has
+ priority over the GPIO function.
+
+ (#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as
+ general purpose PD0 and PD1, respectively, when the HSE oscillator is off.
+ The HSE has priority over the GPIO function.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup GPIO GPIO
+ * @brief GPIO HAL module driver
+ * @{
+ */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @addtogroup GPIO_Private_Constants GPIO Private Constants
+ * @{
+ */
+#define GPIO_MODE 0x00000003U
+#define EXTI_MODE 0x10000000U
+#define GPIO_MODE_IT 0x00010000U
+#define GPIO_MODE_EVT 0x00020000U
+#define RISING_EDGE 0x00100000U
+#define FALLING_EDGE 0x00200000U
+#define GPIO_OUTPUT_TYPE 0x00000010U
+
+#define GPIO_NUMBER 16U
+
+/* Definitions for bit manipulation of CRL and CRH register */
+#define GPIO_CR_MODE_INPUT 0x00000000U /*!< 00: Input mode (reset state) */
+#define GPIO_CR_CNF_ANALOG 0x00000000U /*!< 00: Analog mode */
+#define GPIO_CR_CNF_INPUT_FLOATING 0x00000004U /*!< 01: Floating input (reset state) */
+#define GPIO_CR_CNF_INPUT_PU_PD 0x00000008U /*!< 10: Input with pull-up / pull-down */
+#define GPIO_CR_CNF_GP_OUTPUT_PP 0x00000000U /*!< 00: General purpose output push-pull */
+#define GPIO_CR_CNF_GP_OUTPUT_OD 0x00000004U /*!< 01: General purpose output Open-drain */
+#define GPIO_CR_CNF_AF_OUTPUT_PP 0x00000008U /*!< 10: Alternate function output Push-pull */
+#define GPIO_CR_CNF_AF_OUTPUT_OD 0x0000000CU /*!< 11: Alternate function output Open-drain */
+
+/**
+ * @}
+ */
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup GPIO_Exported_Functions GPIO Exported Functions
+ * @{
+ */
+
+/** @defgroup GPIO_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..]
+ This section provides functions allowing to initialize and de-initialize the GPIOs
+ to be ready for use.
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Initializes the GPIOx peripheral according to the specified parameters in the GPIO_Init.
+ * @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
+ * @param GPIO_Init: pointer to a GPIO_InitTypeDef structure that contains
+ * the configuration information for the specified GPIO peripheral.
+ * @retval None
+ */
+void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
+{
+ uint32_t position;
+ uint32_t ioposition = 0x00U;
+ uint32_t iocurrent = 0x00U;
+ uint32_t temp = 0x00U;
+ uint32_t config = 0x00U;
+ __IO uint32_t *configregister; /* Store the address of CRL or CRH register based on pin number */
+ uint32_t registeroffset = 0U; /* offset used during computation of CNF and MODE bits placement inside CRL or CRH register */
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
+ assert_param(IS_GPIO_PIN(GPIO_Init->Pin));
+ assert_param(IS_GPIO_MODE(GPIO_Init->Mode));
+
+ /* Configure the port pins */
+ for (position = 0U; position < GPIO_NUMBER; position++)
+ {
+ /* Get the IO position */
+ ioposition = (0x01U << position);
+
+ /* Get the current IO position */
+ iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition;
+
+ if (iocurrent == ioposition)
+ {
+ /* Check the Alternate function parameters */
+ assert_param(IS_GPIO_AF_INSTANCE(GPIOx));
+
+ /* Based on the required mode, filling config variable with MODEy[1:0] and CNFy[3:2] corresponding bits */
+ switch (GPIO_Init->Mode)
+ {
+ /* If we are configuring the pin in OUTPUT push-pull mode */
+ case GPIO_MODE_OUTPUT_PP:
+ /* Check the GPIO speed parameter */
+ assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
+ config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_PP;
+ break;
+
+ /* If we are configuring the pin in OUTPUT open-drain mode */
+ case GPIO_MODE_OUTPUT_OD:
+ /* Check the GPIO speed parameter */
+ assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
+ config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_OD;
+ break;
+
+ /* If we are configuring the pin in ALTERNATE FUNCTION push-pull mode */
+ case GPIO_MODE_AF_PP:
+ /* Check the GPIO speed parameter */
+ assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
+ config = GPIO_Init->Speed + GPIO_CR_CNF_AF_OUTPUT_PP;
+ break;
+
+ /* If we are configuring the pin in ALTERNATE FUNCTION open-drain mode */
+ case GPIO_MODE_AF_OD:
+ /* Check the GPIO speed parameter */
+ assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
+ config = GPIO_Init->Speed + GPIO_CR_CNF_AF_OUTPUT_OD;
+ break;
+
+ /* If we are configuring the pin in INPUT (also applicable to EVENT and IT mode) */
+ case GPIO_MODE_INPUT:
+ case GPIO_MODE_IT_RISING:
+ case GPIO_MODE_IT_FALLING:
+ case GPIO_MODE_IT_RISING_FALLING:
+ case GPIO_MODE_EVT_RISING:
+ case GPIO_MODE_EVT_FALLING:
+ case GPIO_MODE_EVT_RISING_FALLING:
+ /* Check the GPIO pull parameter */
+ assert_param(IS_GPIO_PULL(GPIO_Init->Pull));
+ if (GPIO_Init->Pull == GPIO_NOPULL)
+ {
+ config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_FLOATING;
+ }
+ else if (GPIO_Init->Pull == GPIO_PULLUP)
+ {
+ config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD;
+
+ /* Set the corresponding ODR bit */
+ GPIOx->BSRR = ioposition;
+ }
+ else /* GPIO_PULLDOWN */
+ {
+ config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD;
+
+ /* Reset the corresponding ODR bit */
+ GPIOx->BRR = ioposition;
+ }
+ break;
+
+ /* If we are configuring the pin in INPUT analog mode */
+ case GPIO_MODE_ANALOG:
+ config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_ANALOG;
+ break;
+
+ /* Parameters are checked with assert_param */
+ default:
+ break;
+ }
+
+ /* Check if the current bit belongs to first half or last half of the pin count number
+ in order to address CRH or CRL register*/
+ configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL : &GPIOx->CRH;
+ registeroffset = (iocurrent < GPIO_PIN_8) ? (position << 2U) : ((position - 8U) << 2U);
+
+ /* Apply the new configuration of the pin to the register */
+ MODIFY_REG((*configregister), ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << registeroffset), (config << registeroffset));
+
+ /*--------------------- EXTI Mode Configuration ------------------------*/
+ /* Configure the External Interrupt or event for the current IO */
+ if ((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE)
+ {
+ /* Enable AFIO Clock */
+ __HAL_RCC_AFIO_CLK_ENABLE();
+ temp = AFIO->EXTICR[position >> 2U];
+ CLEAR_BIT(temp, (0x0FU) << (4U * (position & 0x03U)));
+ SET_BIT(temp, (GPIO_GET_INDEX(GPIOx)) << (4U * (position & 0x03U)));
+ AFIO->EXTICR[position >> 2U] = temp;
+
+
+ /* Configure the interrupt mask */
+ if ((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT)
+ {
+ SET_BIT(EXTI->IMR, iocurrent);
+ }
+ else
+ {
+ CLEAR_BIT(EXTI->IMR, iocurrent);
+ }
+
+ /* Configure the event mask */
+ if ((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT)
+ {
+ SET_BIT(EXTI->EMR, iocurrent);
+ }
+ else
+ {
+ CLEAR_BIT(EXTI->EMR, iocurrent);
+ }
+
+ /* Enable or disable the rising trigger */
+ if ((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE)
+ {
+ SET_BIT(EXTI->RTSR, iocurrent);
+ }
+ else
+ {
+ CLEAR_BIT(EXTI->RTSR, iocurrent);
+ }
+
+ /* Enable or disable the falling trigger */
+ if ((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE)
+ {
+ SET_BIT(EXTI->FTSR, iocurrent);
+ }
+ else
+ {
+ CLEAR_BIT(EXTI->FTSR, iocurrent);
+ }
+ }
+ }
+ }
+}
+
+/**
+ * @brief De-initializes the GPIOx peripheral registers to their default reset values.
+ * @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
+ * @param GPIO_Pin: specifies the port bit to be written.
+ * This parameter can be one of GPIO_PIN_x where x can be (0..15).
+ * @retval None
+ */
+void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
+{
+ uint32_t position = 0x00U;
+ uint32_t iocurrent = 0x00U;
+ uint32_t tmp = 0x00U;
+ __IO uint32_t *configregister; /* Store the address of CRL or CRH register based on pin number */
+ uint32_t registeroffset = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+ /* Configure the port pins */
+ while ((GPIO_Pin >> position) != 0U)
+ {
+ /* Get current io position */
+ iocurrent = (GPIO_Pin) & (1U << position);
+
+ if (iocurrent)
+ {
+ /*------------------------- GPIO Mode Configuration --------------------*/
+ /* Check if the current bit belongs to first half or last half of the pin count number
+ in order to address CRH or CRL register */
+ configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL : &GPIOx->CRH;
+ registeroffset = (iocurrent < GPIO_PIN_8) ? (position << 2U) : ((position - 8U) << 2U);
+
+ /* CRL/CRH default value is floating input(0x04) shifted to correct position */
+ MODIFY_REG(*configregister, ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << registeroffset), GPIO_CRL_CNF0_0 << registeroffset);
+
+ /* ODR default value is 0 */
+ CLEAR_BIT(GPIOx->ODR, iocurrent);
+
+ /*------------------------- EXTI Mode Configuration --------------------*/
+ /* Clear the External Interrupt or Event for the current IO */
+
+ tmp = AFIO->EXTICR[position >> 2U];
+ tmp &= 0x0FU << (4U * (position & 0x03U));
+ if (tmp == (GPIO_GET_INDEX(GPIOx) << (4U * (position & 0x03U))))
+ {
+ tmp = 0x0FU << (4U * (position & 0x03U));
+ CLEAR_BIT(AFIO->EXTICR[position >> 2U], tmp);
+
+ /* Clear EXTI line configuration */
+ CLEAR_BIT(EXTI->IMR, (uint32_t)iocurrent);
+ CLEAR_BIT(EXTI->EMR, (uint32_t)iocurrent);
+
+ /* Clear Rising Falling edge configuration */
+ CLEAR_BIT(EXTI->RTSR, (uint32_t)iocurrent);
+ CLEAR_BIT(EXTI->FTSR, (uint32_t)iocurrent);
+ }
+ }
+
+ position++;
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup GPIO_Exported_Functions_Group2 IO operation functions
+ * @brief GPIO Read and Write
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the GPIOs.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Reads the specified input port pin.
+ * @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
+ * @param GPIO_Pin: specifies the port bit to read.
+ * This parameter can be GPIO_PIN_x where x can be (0..15).
+ * @retval The input port pin value.
+ */
+GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
+{
+ GPIO_PinState bitstatus;
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+ if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET)
+ {
+ bitstatus = GPIO_PIN_SET;
+ }
+ else
+ {
+ bitstatus = GPIO_PIN_RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Sets or clears the selected data port bit.
+ *
+ * @note This function uses GPIOx_BSRR register to allow atomic read/modify
+ * accesses. In this way, there is no risk of an IRQ occurring between
+ * the read and the modify access.
+ *
+ * @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
+ * @param GPIO_Pin: specifies the port bit to be written.
+ * This parameter can be one of GPIO_PIN_x where x can be (0..15).
+ * @param PinState: specifies the value to be written to the selected bit.
+ * This parameter can be one of the GPIO_PinState enum values:
+ * @arg GPIO_PIN_RESET: to clear the port pin
+ * @arg GPIO_PIN_SET: to set the port pin
+ * @retval None
+ */
+void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+ assert_param(IS_GPIO_PIN_ACTION(PinState));
+
+ if (PinState != GPIO_PIN_RESET)
+ {
+ GPIOx->BSRR = GPIO_Pin;
+ }
+ else
+ {
+ GPIOx->BSRR = (uint32_t)GPIO_Pin << 16U;
+ }
+}
+
+/**
+ * @brief Toggles the specified GPIO pin
+ * @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
+ * @param GPIO_Pin: Specifies the pins to be toggled.
+ * @retval None
+ */
+void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+ GPIOx->ODR ^= GPIO_Pin;
+}
+
+/**
+* @brief Locks GPIO Pins configuration registers.
+* @note The locking mechanism allows the IO configuration to be frozen. When the LOCK sequence
+* has been applied on a port bit, it is no longer possible to modify the value of the port bit until
+* the next reset.
+* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
+* @param GPIO_Pin: specifies the port bit to be locked.
+* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
+* @retval None
+*/
+HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
+{
+ __IO uint32_t tmp = GPIO_LCKR_LCKK;
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_LOCK_INSTANCE(GPIOx));
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+ /* Apply lock key write sequence */
+ SET_BIT(tmp, GPIO_Pin);
+ /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
+ GPIOx->LCKR = tmp;
+ /* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */
+ GPIOx->LCKR = GPIO_Pin;
+ /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
+ GPIOx->LCKR = tmp;
+ /* Read LCKK bit*/
+ tmp = GPIOx->LCKR;
+
+ if ((uint32_t)(GPIOx->LCKR & GPIO_LCKR_LCKK))
+ {
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief This function handles EXTI interrupt request.
+ * @param GPIO_Pin: Specifies the pins connected EXTI line
+ * @retval None
+ */
+void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
+{
+ /* EXTI line interrupt detected */
+ if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
+ {
+ __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
+ HAL_GPIO_EXTI_Callback(GPIO_Pin);
+ }
+}
+
+/**
+ * @brief EXTI line detection callbacks.
+ * @param GPIO_Pin: Specifies the pins connected EXTI line
+ * @retval None
+ */
+__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(GPIO_Pin);
+ /* NOTE: This function Should not be modified, when the callback is needed,
+ the HAL_GPIO_EXTI_Callback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_GPIO_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c
new file mode 100644
index 0000000..551333b
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c
@@ -0,0 +1,143 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_gpio_ex.c
+ * @author MCD Application Team
+ * @brief GPIO Extension HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the General Purpose Input/Output (GPIO) extension peripheral.
+ * + Extended features functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### GPIO Peripheral extension features #####
+ ==============================================================================
+ [..] GPIO module on STM32F1 family, manage also the AFIO register:
+ (+) Possibility to use the EVENTOUT Cortex feature
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..] This driver provides functions to use EVENTOUT Cortex feature
+ (#) Configure EVENTOUT Cortex feature using the function HAL_GPIOEx_ConfigEventout()
+ (#) Activate EVENTOUT Cortex feature using the HAL_GPIOEx_EnableEventout()
+ (#) Deactivate EVENTOUT Cortex feature using the HAL_GPIOEx_DisableEventout()
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup GPIOEx GPIOEx
+ * @brief GPIO HAL module driver
+ * @{
+ */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+
+/** @defgroup GPIOEx_Exported_Functions GPIOEx Exported Functions
+ * @{
+ */
+
+/** @defgroup GPIOEx_Exported_Functions_Group1 Extended features functions
+ * @brief Extended features functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Extended features functions #####
+ ==============================================================================
+ [..] This section provides functions allowing to:
+ (+) Configure EVENTOUT Cortex feature using the function HAL_GPIOEx_ConfigEventout()
+ (+) Activate EVENTOUT Cortex feature using the HAL_GPIOEx_EnableEventout()
+ (+) Deactivate EVENTOUT Cortex feature using the HAL_GPIOEx_DisableEventout()
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the port and pin on which the EVENTOUT Cortex signal will be connected.
+ * @param GPIO_PortSource Select the port used to output the Cortex EVENTOUT signal.
+ * This parameter can be a value of @ref GPIOEx_EVENTOUT_PORT.
+ * @param GPIO_PinSource Select the pin used to output the Cortex EVENTOUT signal.
+ * This parameter can be a value of @ref GPIOEx_EVENTOUT_PIN.
+ * @retval None
+ */
+void HAL_GPIOEx_ConfigEventout(uint32_t GPIO_PortSource, uint32_t GPIO_PinSource)
+{
+ /* Verify the parameters */
+ assert_param(IS_AFIO_EVENTOUT_PORT(GPIO_PortSource));
+ assert_param(IS_AFIO_EVENTOUT_PIN(GPIO_PinSource));
+
+ /* Apply the new configuration */
+ MODIFY_REG(AFIO->EVCR, (AFIO_EVCR_PORT) | (AFIO_EVCR_PIN), (GPIO_PortSource) | (GPIO_PinSource));
+}
+
+/**
+ * @brief Enables the Event Output.
+ * @retval None
+ */
+void HAL_GPIOEx_EnableEventout(void)
+{
+ SET_BIT(AFIO->EVCR, AFIO_EVCR_EVOE);
+}
+
+/**
+ * @brief Disables the Event Output.
+ * @retval None
+ */
+void HAL_GPIOEx_DisableEventout(void)
+{
+ CLEAR_BIT(AFIO->EVCR, AFIO_EVCR_EVOE);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_GPIO_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_hcd.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_hcd.c
new file mode 100644
index 0000000..0c377d9
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_hcd.c
@@ -0,0 +1,1194 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_hcd.c
+ * @author MCD Application Team
+ * @brief HCD HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the USB Peripheral Controller:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ * + Peripheral State functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#)Declare a HCD_HandleTypeDef handle structure, for example:
+ HCD_HandleTypeDef hhcd;
+
+ (#)Fill parameters of Init structure in HCD handle
+
+ (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...)
+
+ (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API:
+ (##) Enable the HCD/USB Low Level interface clock using the following macro
+ (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE()
+
+ (##) Initialize the related GPIO clocks
+ (##) Configure HCD pin-out
+ (##) Configure HCD NVIC interrupt
+
+ (#)Associate the Upper USB Host stack to the HAL HCD Driver:
+ (##) hhcd.pData = phost;
+
+ (#)Enable HCD transmission and reception:
+ (##) HAL_HCD_Start();
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+
+#ifdef HAL_HCD_MODULE_ENABLED
+
+#if defined(STM32F105xC) || defined(STM32F107xC)
+
+/** @defgroup HCD HCD
+ * @brief HCD HAL module driver
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private function ----------------------------------------------------------*/
+/** @defgroup HCD_Private_Functions HCD Private Functions
+ * @{
+ */
+static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
+static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
+static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd);
+static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup HCD_Exported_Functions HCD Exported Functions
+ * @{
+ */
+
+/** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initialize the host driver
+ * @param hhcd: HCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
+{
+ /* Check the HCD handle allocation */
+ if(hhcd == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance));
+
+ if(hhcd->State == HAL_HCD_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hhcd->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware : GPIO, CLOCK, NVIC... */
+ HAL_HCD_MspInit(hhcd);
+ }
+
+ hhcd->State = HAL_HCD_STATE_BUSY;
+
+ /* Disable the Interrupts */
+ __HAL_HCD_DISABLE(hhcd);
+
+ /* Init the Core (common init.) */
+ USB_CoreInit(hhcd->Instance, hhcd->Init);
+
+ /* Force Host Mode*/
+ USB_SetCurrentMode(hhcd->Instance , USB_HOST_MODE);
+
+ /* Init Host */
+ USB_HostInit(hhcd->Instance, hhcd->Init);
+
+ hhcd->State= HAL_HCD_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initialize a host channel
+ * @param hhcd: HCD handle
+ * @param ch_num: Channel number.
+ * This parameter can be a value from 1 to 15
+ * @param epnum: Endpoint number.
+ * This parameter can be a value from 1 to 15
+ * @param dev_address : Current device address
+ * This parameter can be a value from 0 to 255
+ * @param speed: Current device speed.
+ * This parameter can be one of these values:
+ * HCD_SPEED_FULL: Full speed mode,
+ * HCD_SPEED_LOW: Low speed mode
+ * @param ep_type: Endpoint Type.
+ * This parameter can be one of these values:
+ * EP_TYPE_CTRL: Control type,
+ * EP_TYPE_ISOC: Isochronous type,
+ * EP_TYPE_BULK: Bulk type,
+ * EP_TYPE_INTR: Interrupt type
+ * @param mps: Max Packet Size.
+ * This parameter can be a value from 0 to32K
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd,
+ uint8_t ch_num,
+ uint8_t epnum,
+ uint8_t dev_address,
+ uint8_t speed,
+ uint8_t ep_type,
+ uint16_t mps)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ __HAL_LOCK(hhcd);
+
+ hhcd->hc[ch_num].dev_addr = dev_address;
+ hhcd->hc[ch_num].max_packet = mps;
+ hhcd->hc[ch_num].ch_num = ch_num;
+ hhcd->hc[ch_num].ep_type = ep_type;
+ hhcd->hc[ch_num].ep_num = epnum & 0x7FU;
+ hhcd->hc[ch_num].ep_is_in = ((epnum & 0x80U) == 0x80U);
+ hhcd->hc[ch_num].speed = speed;
+
+ status = USB_HC_Init(hhcd->Instance,
+ ch_num,
+ epnum,
+ dev_address,
+ speed,
+ ep_type,
+ mps);
+ __HAL_UNLOCK(hhcd);
+
+ return status;
+}
+
+/**
+ * @brief Halt a host channel
+ * @param hhcd: HCD handle
+ * @param ch_num: Channel number.
+ * This parameter can be a value from 1 to 15
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd,
+ uint8_t ch_num)
+{
+ __HAL_LOCK(hhcd);
+ USB_HC_Halt(hhcd->Instance, ch_num);
+ __HAL_UNLOCK(hhcd);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitialize the host driver
+ * @param hhcd: HCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
+{
+ /* Check the HCD handle allocation */
+ if(hhcd == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ hhcd->State = HAL_HCD_STATE_BUSY;
+
+ /* DeInit the low level hardware */
+ HAL_HCD_MspDeInit(hhcd);
+
+ __HAL_HCD_DISABLE(hhcd);
+
+ hhcd->State = HAL_HCD_STATE_RESET;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the HCD MSP.
+ * @param hhcd: HCD handle
+ * @retval None
+ */
+__weak void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hhcd);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_HCD_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes HCD MSP.
+ * @param hhcd: HCD handle
+ * @retval None
+ */
+__weak void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hhcd);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_HCD_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup HCD_Exported_Functions_Group2 IO operation functions
+ * @brief HCD IO operation functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ This subsection provides a set of functions allowing to manage the USB Host Data
+ Transfer
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Submit a new URB for processing
+ * @param hhcd: HCD handle
+ * @param ch_num: Channel number.
+ * This parameter can be a value from 1 to 15
+ * @param direction: Channel number.
+ * This parameter can be one of these values:
+ * 0 : Output / 1 : Input
+ * @param ep_type: Endpoint Type.
+ * This parameter can be one of these values:
+ * EP_TYPE_CTRL: Control type/
+ * EP_TYPE_ISOC: Isochronous type/
+ * EP_TYPE_BULK: Bulk type/
+ * EP_TYPE_INTR: Interrupt type/
+ * @param token: Endpoint Type.
+ * This parameter can be one of these values:
+ * 0: HC_PID_SETUP / 1: HC_PID_DATA1
+ * @param pbuff: pointer to URB data
+ * @param length: Length of URB data
+ * @param do_ping: activate do ping protocol (for high speed only).
+ * This parameter can be one of these values:
+ * 0 : do ping inactive / 1 : do ping active
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
+ uint8_t ch_num,
+ uint8_t direction,
+ uint8_t ep_type,
+ uint8_t token,
+ uint8_t* pbuff,
+ uint16_t length,
+ uint8_t do_ping)
+{
+ hhcd->hc[ch_num].ep_is_in = direction;
+ hhcd->hc[ch_num].ep_type = ep_type;
+
+ if(token == 0U)
+ {
+ hhcd->hc[ch_num].data_pid = HC_PID_SETUP;
+ }
+ else
+ {
+ hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
+ }
+
+ /* Manage Data Toggle */
+ switch(ep_type)
+ {
+ case EP_TYPE_CTRL:
+ if((token == 1U) && (direction == 0U)) /*send data */
+ {
+ if (length == 0U)
+ { /* For Status OUT stage, Length==0, Status Out PID = 1 */
+ hhcd->hc[ch_num].toggle_out = 1U;
+ }
+
+ /* Set the Data Toggle bit as per the Flag */
+ if ( hhcd->hc[ch_num].toggle_out == 0U)
+ { /* Put the PID 0 */
+ hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
+ }
+ else
+ { /* Put the PID 1 */
+ hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
+ }
+ if(hhcd->hc[ch_num].urb_state != URB_NOTREADY)
+ {
+ hhcd->hc[ch_num].do_ping = do_ping;
+ }
+ }
+ break;
+
+ case EP_TYPE_BULK:
+ if(direction == 0U)
+ {
+ /* Set the Data Toggle bit as per the Flag */
+ if ( hhcd->hc[ch_num].toggle_out == 0U)
+ { /* Put the PID 0 */
+ hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
+ }
+ else
+ { /* Put the PID 1 */
+ hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
+ }
+ if(hhcd->hc[ch_num].urb_state != URB_NOTREADY)
+ {
+ hhcd->hc[ch_num].do_ping = do_ping;
+ }
+ }
+ else
+ {
+ if( hhcd->hc[ch_num].toggle_in == 0U)
+ {
+ hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
+ }
+ else
+ {
+ hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
+ }
+ }
+ break;
+
+ case EP_TYPE_INTR:
+ if(direction == 0U)
+ {
+ /* Set the Data Toggle bit as per the Flag */
+ if ( hhcd->hc[ch_num].toggle_out == 0U)
+ { /* Put the PID 0 */
+ hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
+ }
+ else
+ { /* Put the PID 1 */
+ hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
+ }
+ }
+ else
+ {
+ if( hhcd->hc[ch_num].toggle_in == 0U)
+ {
+ hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
+ }
+ else
+ {
+ hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
+ }
+ }
+ break;
+
+ case EP_TYPE_ISOC:
+ hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
+ break;
+ }
+
+ hhcd->hc[ch_num].xfer_buff = pbuff;
+ hhcd->hc[ch_num].xfer_len = length;
+ hhcd->hc[ch_num].urb_state = URB_IDLE;
+ hhcd->hc[ch_num].xfer_count = 0U;
+ hhcd->hc[ch_num].ch_num = ch_num;
+ hhcd->hc[ch_num].state = HC_IDLE;
+
+ return USB_HC_StartXfer(hhcd->Instance, &(hhcd->hc[ch_num]));
+}
+
+/**
+ * @brief handle HCD interrupt request.
+ * @param hhcd: HCD handle
+ * @retval None
+ */
+void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
+{
+ USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
+
+ uint32_t index = 0U, interrupt = 0U;
+
+ /* ensure that we are in device mode */
+ if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
+ {
+ /* Avoid spurious interrupt */
+ if(__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
+ {
+ return;
+ }
+
+ if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
+ {
+ /* Incorrect mode, acknowledge the interrupt */
+ __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
+ }
+
+ if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
+ {
+ /* Incorrect mode, acknowledge the interrupt */
+ __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
+ }
+
+ if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
+ {
+ /* Incorrect mode, acknowledge the interrupt */
+ __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
+ }
+
+ if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
+ {
+ /* Incorrect mode, acknowledge the interrupt */
+ __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
+ }
+
+ /* Handle Host Disconnect Interrupts */
+ if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
+ {
+
+ /* Cleanup HPRT */
+ USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
+ USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
+
+ /* Handle Host Port Interrupts */
+ HAL_HCD_Disconnect_Callback(hhcd);
+ USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ);
+ __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
+ }
+
+ /* Handle Host Port Interrupts */
+ if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
+ {
+ HCD_Port_IRQHandler (hhcd);
+ }
+
+ /* Handle Host SOF Interrupts */
+ if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
+ {
+ HAL_HCD_SOF_Callback(hhcd);
+ __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
+ }
+
+ /* Handle Host channel Interrupts */
+ if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
+ {
+ interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
+ for (index = 0U; index < hhcd->Init.Host_channels ; index++)
+ {
+ if (interrupt & (1 << index))
+ {
+ if ((USBx_HC(index)->HCCHAR) & USB_OTG_HCCHAR_EPDIR)
+ {
+ HCD_HC_IN_IRQHandler (hhcd, index);
+ }
+ else
+ {
+ HCD_HC_OUT_IRQHandler (hhcd, index);
+ }
+ }
+ }
+ __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
+ }
+
+ /* Handle Rx Queue Level Interrupts */
+ if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL))
+ {
+ USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
+
+ HCD_RXQLVL_IRQHandler (hhcd);
+
+ USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
+ }
+ }
+}
+
+/**
+ * @brief SOF callback.
+ * @param hhcd: HCD handle
+ * @retval None
+ */
+__weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hhcd);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_HCD_SOF_Callback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Connexion Event callback.
+ * @param hhcd: HCD handle
+ * @retval None
+ */
+__weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hhcd);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_HCD_Connect_Callback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Disonnection Event callback.
+ * @param hhcd: HCD handle
+ * @retval None
+ */
+__weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hhcd);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_HCD_Disconnect_Callback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Notify URB state change callback.
+ * @param hhcd: HCD handle
+ * @param chnum: Channel number.
+ * This parameter can be a value from 1 to 15
+ * @param urb_state:
+ * This parameter can be one of these values:
+ * URB_IDLE/
+ * URB_DONE/
+ * URB_NOTREADY/
+ * URB_NYET/
+ * URB_ERROR/
+ * URB_STALL/
+ * @retval None
+ */
+__weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hhcd);
+ UNUSED(chnum);
+ UNUSED(urb_state);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
+ * @brief management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the HCD data
+ transfers.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Start the host driver
+ * @param hhcd: HCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
+{
+ __HAL_LOCK(hhcd);
+ __HAL_HCD_ENABLE(hhcd);
+ USB_DriveVbus(hhcd->Instance, 1U);
+ __HAL_UNLOCK(hhcd);
+ return HAL_OK;
+}
+
+/**
+ * @brief Stop the host driver
+ * @param hhcd: HCD handle
+ * @retval HAL status
+ */
+
+HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
+{
+ __HAL_LOCK(hhcd);
+ USB_StopHost(hhcd->Instance);
+ __HAL_UNLOCK(hhcd);
+ return HAL_OK;
+}
+
+/**
+ * @brief Reset the host port
+ * @param hhcd: HCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
+{
+ return (USB_ResetPort(hhcd->Instance));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral State functions #####
+ ===============================================================================
+ [..]
+ This subsection permits to get in run-time the status of the peripheral
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Return the HCD handle state
+ * @param hhcd: HCD handle
+ * @retval HAL state
+ */
+HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd)
+{
+ return hhcd->State;
+}
+
+/**
+ * @brief Return URB state for a channel
+ * @param hhcd: HCD handle
+ * @param chnum: Channel number.
+ * This parameter can be a value from 1 to 15
+ * @retval URB state.
+ * This parameter can be one of these values:
+ * URB_IDLE/
+ * URB_DONE/
+ * URB_NOTREADY/
+ * URB_NYET/
+ * URB_ERROR/
+ * URB_STALL/
+ */
+HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
+{
+ return hhcd->hc[chnum].urb_state;
+}
+
+
+/**
+ * @brief Return the last host transfer size
+ * @param hhcd: HCD handle
+ * @param chnum: Channel number.
+ * This parameter can be a value from 1 to 15
+ * @retval last transfer size in byte
+ */
+uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum)
+{
+ return hhcd->hc[chnum].xfer_count;
+}
+
+/**
+ * @brief Return the Host Channel state
+ * @param hhcd: HCD handle
+ * @param chnum: Channel number.
+ * This parameter can be a value from 1 to 15
+ * @retval Host channel state
+ * This parameter can be one of the these values:
+ * HC_IDLE/
+ * HC_XFRC/
+ * HC_HALTED/
+ * HC_NYET/
+ * HC_NAK/
+ * HC_STALL/
+ * HC_XACTERR/
+ * HC_BBLERR/
+ * HC_DATATGLERR/
+ */
+HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
+{
+ return hhcd->hc[chnum].state;
+}
+
+/**
+ * @brief Return the current Host frame number
+ * @param hhcd: HCD handle
+ * @retval Current Host frame number
+ */
+uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
+{
+ return (USB_GetCurrentFrame(hhcd->Instance));
+}
+
+/**
+ * @brief Return the Host enumeration speed
+ * @param hhcd: HCD handle
+ * @retval Enumeration speed
+ */
+uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
+{
+ return (USB_GetHostSpeed(hhcd->Instance));
+}
+
+/**
+ * @}
+ */
+/**
+ * @}
+ */
+
+/** @addtogroup HCD_Private_Functions
+ * @{
+ */
+/**
+ * @brief This function handles Host Channel IN interrupt requests.
+ * @param hhcd: HCD handle
+ * @param chnum: Channel number.
+ * This parameter can be a value from 1 to 15
+ * @retval none
+ */
+static void HCD_HC_IN_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum)
+{
+ USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
+ uint32_t tmpreg = 0U;
+
+ if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR)
+ {
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
+ __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
+ }
+ else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK)
+ {
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
+ }
+
+ else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL)
+ {
+ __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
+ hhcd->hc[chnum].state = HC_STALL;
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
+ USB_HC_Halt(hhcd->Instance, chnum);
+ }
+ else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR)
+ {
+ __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
+ USB_HC_Halt(hhcd->Instance, chnum);
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
+ hhcd->hc[chnum].state = HC_DATATGLERR;
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
+ }
+
+ if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR)
+ {
+ __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
+ USB_HC_Halt(hhcd->Instance, chnum);
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
+ }
+
+ else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC)
+ {
+ hhcd->hc[chnum].state = HC_XFRC;
+ hhcd->hc[chnum].ErrCnt = 0U;
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
+
+ if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
+ (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
+ {
+ __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
+ USB_HC_Halt(hhcd->Instance, chnum);
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
+
+ }
+ else if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
+ {
+ USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
+ hhcd->hc[chnum].urb_state = URB_DONE;
+ HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
+ }
+ hhcd->hc[chnum].toggle_in ^= 1U;
+
+ }
+ else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH)
+ {
+ __HAL_HCD_MASK_HALT_HC_INT(chnum);
+
+ if(hhcd->hc[chnum].state == HC_XFRC)
+ {
+ hhcd->hc[chnum].urb_state = URB_DONE;
+ }
+ else if (hhcd->hc[chnum].state == HC_STALL)
+ {
+ hhcd->hc[chnum].urb_state = URB_STALL;
+ }
+ else if((hhcd->hc[chnum].state == HC_XACTERR) ||
+ (hhcd->hc[chnum].state == HC_DATATGLERR))
+ {
+ if(hhcd->hc[chnum].ErrCnt++ > 3U)
+ {
+ hhcd->hc[chnum].ErrCnt = 0U;
+ hhcd->hc[chnum].urb_state = URB_ERROR;
+ }
+ else
+ {
+ hhcd->hc[chnum].urb_state = URB_NOTREADY;
+ }
+
+ /* re-activate the channel */
+ tmpreg = USBx_HC(chnum)->HCCHAR;
+ tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
+ tmpreg |= USB_OTG_HCCHAR_CHENA;
+ USBx_HC(chnum)->HCCHAR = tmpreg;
+ }
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
+ HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
+ }
+
+ else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR)
+ {
+ __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
+ hhcd->hc[chnum].ErrCnt++;
+ hhcd->hc[chnum].state = HC_XACTERR;
+ USB_HC_Halt(hhcd->Instance, chnum);
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
+ }
+ else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK)
+ {
+ if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
+ {
+ __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
+ USB_HC_Halt(hhcd->Instance, chnum);
+ }
+ else if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
+ (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
+ {
+ /* re-activate the channel */
+ tmpreg = USBx_HC(chnum)->HCCHAR;
+ tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
+ tmpreg |= USB_OTG_HCCHAR_CHENA;
+ USBx_HC(chnum)->HCCHAR = tmpreg;
+ }
+ hhcd->hc[chnum].state = HC_NAK;
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
+ }
+}
+
+/**
+ * @brief This function handles Host Channel OUT interrupt requests.
+ * @param hhcd: HCD handle
+ * @param chnum: Channel number.
+ * This parameter can be a value from 1 to 15
+ * @retval none
+ */
+static void HCD_HC_OUT_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum)
+{
+ USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
+ uint32_t tmpreg = 0U;
+
+ if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR)
+ {
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
+ __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
+ }
+ else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK)
+ {
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
+
+ if( hhcd->hc[chnum].do_ping == 1U)
+ {
+ hhcd->hc[chnum].state = HC_NYET;
+ __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
+ USB_HC_Halt(hhcd->Instance, chnum);
+ hhcd->hc[chnum].urb_state = URB_NOTREADY;
+ }
+ }
+
+ else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NYET)
+ {
+ hhcd->hc[chnum].state = HC_NYET;
+ hhcd->hc[chnum].ErrCnt= 0U;
+ __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
+ USB_HC_Halt(hhcd->Instance, chnum);
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
+
+ }
+
+ else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR)
+ {
+ __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
+ USB_HC_Halt(hhcd->Instance, chnum);
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
+ }
+
+ else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC)
+ {
+ hhcd->hc[chnum].ErrCnt = 0U;
+ __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
+ USB_HC_Halt(hhcd->Instance, chnum);
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
+ hhcd->hc[chnum].state = HC_XFRC;
+ }
+ else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL)
+ {
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
+ __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
+ USB_HC_Halt(hhcd->Instance, chnum);
+ hhcd->hc[chnum].state = HC_STALL;
+ }
+ else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK)
+ {
+ hhcd->hc[chnum].ErrCnt = 0U;
+ __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
+ USB_HC_Halt(hhcd->Instance, chnum);
+ hhcd->hc[chnum].state = HC_NAK;
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
+ }
+ else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR)
+ {
+ __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
+ USB_HC_Halt(hhcd->Instance, chnum);
+ hhcd->hc[chnum].state = HC_XACTERR;
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
+ }
+ else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR)
+ {
+ __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
+ USB_HC_Halt(hhcd->Instance, chnum);
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
+ hhcd->hc[chnum].state = HC_DATATGLERR;
+ }
+ else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH)
+ {
+ __HAL_HCD_MASK_HALT_HC_INT(chnum);
+
+ if(hhcd->hc[chnum].state == HC_XFRC)
+ {
+ hhcd->hc[chnum].urb_state = URB_DONE;
+ if (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)
+ {
+ hhcd->hc[chnum].toggle_out ^= 1U;
+ }
+ }
+ else if (hhcd->hc[chnum].state == HC_NAK)
+ {
+ hhcd->hc[chnum].urb_state = URB_NOTREADY;
+ }
+ else if (hhcd->hc[chnum].state == HC_NYET)
+ {
+ hhcd->hc[chnum].urb_state = URB_NOTREADY;
+ hhcd->hc[chnum].do_ping = 0U;
+ }
+ else if (hhcd->hc[chnum].state == HC_STALL)
+ {
+ hhcd->hc[chnum].urb_state = URB_STALL;
+ }
+ else if((hhcd->hc[chnum].state == HC_XACTERR) ||
+ (hhcd->hc[chnum].state == HC_DATATGLERR))
+ {
+ if(hhcd->hc[chnum].ErrCnt++ > 3U)
+ {
+ hhcd->hc[chnum].ErrCnt = 0U;
+ hhcd->hc[chnum].urb_state = URB_ERROR;
+ }
+ else
+ {
+ hhcd->hc[chnum].urb_state = URB_NOTREADY;
+ }
+
+ /* re-activate the channel */
+ tmpreg = USBx_HC(chnum)->HCCHAR;
+ tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
+ tmpreg |= USB_OTG_HCCHAR_CHENA;
+ USBx_HC(chnum)->HCCHAR = tmpreg;
+ }
+
+ __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
+ HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
+ }
+}
+
+/**
+ * @brief This function handles Rx Queue Level interrupt requests.
+ * @param hhcd: HCD handle
+ * @retval none
+ */
+static void HCD_RXQLVL_IRQHandler (HCD_HandleTypeDef *hhcd)
+{
+ USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
+ uint8_t channelnum =0U;
+ uint32_t pktsts;
+ uint32_t pktcnt;
+ uint32_t temp = 0U;
+ uint32_t tmpreg = 0U;
+
+ temp = hhcd->Instance->GRXSTSP;
+ channelnum = temp & USB_OTG_GRXSTSP_EPNUM;
+ pktsts = (temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U;
+ pktcnt = (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
+
+ switch (pktsts)
+ {
+ case GRXSTS_PKTSTS_IN:
+ /* Read the data into the host buffer. */
+ if ((pktcnt > 0U) && (hhcd->hc[channelnum].xfer_buff != (void *)0U))
+ {
+ USB_ReadPacket(hhcd->Instance, hhcd->hc[channelnum].xfer_buff, pktcnt);
+
+ /*manage multiple Xfer */
+ hhcd->hc[channelnum].xfer_buff += pktcnt;
+ hhcd->hc[channelnum].xfer_count += pktcnt;
+
+ if((USBx_HC(channelnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) > 0U)
+ {
+ /* re-activate the channel when more packets are expected */
+ tmpreg = USBx_HC(channelnum)->HCCHAR;
+ tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
+ tmpreg |= USB_OTG_HCCHAR_CHENA;
+ USBx_HC(channelnum)->HCCHAR = tmpreg;
+ hhcd->hc[channelnum].toggle_in ^= 1U;
+ }
+ }
+ break;
+
+ case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
+ break;
+
+ case GRXSTS_PKTSTS_IN_XFER_COMP:
+ case GRXSTS_PKTSTS_CH_HALTED:
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief This function handles Host Port interrupt requests.
+ * @param hhcd: HCD handle
+ * @retval None
+ */
+static void HCD_Port_IRQHandler (HCD_HandleTypeDef *hhcd)
+{
+ USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
+ __IO uint32_t hprt0 = 0, hprt0_dup = 0U;
+
+ /* Handle Host Port Interrupts */
+ hprt0 = USBx_HPRT0;
+ hprt0_dup = USBx_HPRT0;
+
+ hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
+ USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
+
+ /* Check whether Port Connect Detected */
+ if((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
+ {
+ if((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
+ {
+ USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
+ HAL_HCD_Connect_Callback(hhcd);
+ }
+ hprt0_dup |= USB_OTG_HPRT_PCDET;
+ }
+
+ /* Check whether Port Enable Changed */
+ if((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
+ {
+ hprt0_dup |= USB_OTG_HPRT_PENCHNG;
+
+ if((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
+ {
+ if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17U))
+ {
+ USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_6_MHZ );
+ }
+ else
+ {
+ USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ );
+ }
+ HAL_HCD_Connect_Callback(hhcd);
+ }
+ else
+ {
+ /* Cleanup HPRT */
+ USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
+ USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
+
+ USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
+ }
+ }
+
+ /* Check For an over current */
+ if((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
+ {
+ hprt0_dup |= USB_OTG_HPRT_POCCHNG;
+ }
+
+ /* Clear Port Interrupts */
+ USBx_HPRT0 = hprt0_dup;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F105xC || STM32F107xC */
+
+#endif /* HAL_HCD_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
rename to templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2s.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2s.c
new file mode 100644
index 0000000..40909cc
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2s.c
@@ -0,0 +1,1458 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_i2s.c
+ * @author MCD Application Team
+ * @brief I2S HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Integrated Interchip Sound (I2S) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral State and Errors functions
+ @verbatim
+ ===============================================================================
+ ##### How to use this driver #####
+ ===============================================================================
+ [..]
+ The I2S HAL driver can be used as follow:
+
+ (#) Declare a I2S_HandleTypeDef handle structure.
+ (#) Initialize the I2S low level resources by implement the HAL_I2S_MspInit() API:
+ (##) Enable the SPIx interface clock.
+ (##) I2S pins configuration:
+ (+++) Enable the clock for the I2S GPIOs.
+ (+++) Configure these I2S pins as alternate function.
+ (##) NVIC configuration if you need to use interrupt process (HAL_I2S_Transmit_IT()
+ and HAL_I2S_Receive_IT() APIs).
+ (+++) Configure the I2Sx interrupt priority.
+ (+++) Enable the NVIC I2S IRQ handle.
+ (##) DMA Configuration if you need to use DMA process (HAL_I2S_Transmit_DMA()
+ and HAL_I2S_Receive_DMA() APIs:
+ (+++) Declare a DMA handle structure for the Tx/Rx Channel.
+ (+++) Enable the DMAx interface clock.
+ (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
+ (+++) Configure the DMA Tx/Rx Channel.
+ (+++) Associate the initialized DMA handle to the I2S DMA Tx/Rx handle.
+ (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
+ DMA Tx/Rx Channel.
+
+ (#) Program the Mode, Standard, Data Format, MCLK Output, Audio frequency and Polarity
+ using HAL_I2S_Init() function.
+
+ -@- The specific I2S interrupts (Transmission complete interrupt,
+ RXNE interrupt and Error Interrupts) will be managed using the macros
+ __HAL_I2S_ENABLE_IT() and __HAL_I2S_DISABLE_IT() inside the transmit and receive process.
+ -@- The I2SxCLK source is the system clock (provided by the HSI, the HSE or the PLL, and sourcing the AHB clock).
+ For connectivity line devices, the I2SxCLK source can be either SYSCLK or the PLL3 VCO (2 x PLL3CLK) clock
+ in order to achieve the maximum accuracy.
+ -@- Make sure that either:
+ (+@) External clock source is configured after setting correctly
+ the define constant HSE_VALUE in the stm32f1xx_hal_conf.h file.
+
+ (#) Three operation modes are available within this driver :
+
+ *** Polling mode IO operation ***
+ =================================
+ [..]
+ (+) Send an amount of data in blocking mode using HAL_I2S_Transmit()
+ (+) Receive an amount of data in blocking mode using HAL_I2S_Receive()
+
+ *** Interrupt mode IO operation ***
+ ===================================
+ [..]
+ (+) Send an amount of data in non blocking mode using HAL_I2S_Transmit_IT()
+ (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
+ (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_I2S_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode using HAL_I2S_Receive_IT()
+ (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
+ (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_I2S_RxCpltCallback
+ (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_I2S_ErrorCallback
+
+ *** DMA mode IO operation ***
+ ==============================
+ [..]
+ (+) Send an amount of data in non blocking mode (DMA) using HAL_I2S_Transmit_DMA()
+ (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
+ (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_I2S_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode (DMA) using HAL_I2S_Receive_DMA()
+ (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
+ (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_I2S_RxCpltCallback
+ (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_I2S_ErrorCallback
+ (+) Pause the DMA Transfer using HAL_I2S_DMAPause()
+ (+) Resume the DMA Transfer using HAL_I2S_DMAResume()
+ (+) Stop the DMA Transfer using HAL_I2S_DMAStop()
+
+ *** I2S HAL driver macros list ***
+ =============================================
+ [..]
+ Below the list of most used macros in I2S HAL driver.
+
+ (+) __HAL_I2S_ENABLE: Enable the specified SPI peripheral (in I2S mode)
+ (+) __HAL_I2S_DISABLE: Disable the specified SPI peripheral (in I2S mode)
+ (+) __HAL_I2S_ENABLE_IT : Enable the specified I2S interrupts
+ (+) __HAL_I2S_DISABLE_IT : Disable the specified I2S interrupts
+ (+) __HAL_I2S_GET_FLAG: Check whether the specified I2S flag is set or not
+
+ [..]
+ (@) You can refer to the I2S HAL driver header file for more useful macros
+
+
+ *** I2C Workarounds linked to Silicon Limitation ***
+ ====================================================
+ [..]
+ (@) Only the 16-bit mode with no data extension can be used when the I2S
+ is in Master and used the PCM long synchronization mode.
+
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_I2S_MODULE_ENABLED
+#if defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
+
+/** @defgroup I2S I2S
+ * @brief I2S HAL module driver
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @addtogroup I2S_Private_Functions I2S Private Functions
+ * @{
+ */
+static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma);
+static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
+static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma);
+static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
+static void I2S_DMAError(DMA_HandleTypeDef *hdma);
+static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s);
+static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s);
+static void I2S_IRQHandler(I2S_HandleTypeDef *hi2s);
+static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, uint32_t State,
+ uint32_t Timeout);
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+/** @defgroup I2S_Exported_Functions I2S Exported Functions
+ * @{
+ */
+
+/** @defgroup I2S_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to initialize and
+ de-initialize the I2Sx peripheral in simplex mode:
+
+ (+) User must Implement HAL_I2S_MspInit() function in which he configures
+ all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
+
+ (+) Call the function HAL_I2S_Init() to configure the selected device with
+ the selected configuration:
+ (++) Mode
+ (++) Standard
+ (++) Data Format
+ (++) MCLK Output
+ (++) Audio frequency
+ (++) Polarity
+
+ (+) Call the function HAL_I2S_DeInit() to restore the default configuration
+ of the selected I2Sx peripheral.
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the I2S according to the specified parameters
+ * in the I2S_InitTypeDef and create the associated handle.
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s)
+{
+ uint32_t tmpreg = 0U, i2sdiv = 2U, i2sodd = 0U, packetlength = 16U;
+ uint32_t tmp = 0U, i2sclk = 0U;
+
+ /* Check the I2S handle allocation */
+ if(hi2s == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the I2S parameters */
+ assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
+ assert_param(IS_I2S_MODE(hi2s->Init.Mode));
+ assert_param(IS_I2S_STANDARD(hi2s->Init.Standard));
+ assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat));
+ assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput));
+ assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq));
+ assert_param(IS_I2S_CPOL(hi2s->Init.CPOL));
+
+ hi2s->State = HAL_I2S_STATE_BUSY;
+
+ /* Initialize Default I2S IrqHandler ISR */
+ hi2s->IrqHandlerISR = I2S_IRQHandler;
+
+ /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
+ HAL_I2S_MspInit(hi2s);
+
+ /*----------------------- SPIx I2SCFGR & I2SPR Configuration ---------------*/
+ /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
+ CLEAR_BIT(hi2s->Instance->I2SCFGR,(SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CKPOL | \
+ SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \
+ SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD));
+ hi2s->Instance->I2SPR = 0x0002U;
+
+ /* Get the I2SCFGR register value */
+ tmpreg = hi2s->Instance->I2SCFGR;
+
+ /* If the default frequency value has to be written, reinitialize i2sdiv and i2sodd */
+ /* If the requested audio frequency is not the default, compute the prescaler */
+ if(hi2s->Init.AudioFreq != I2S_AUDIOFREQ_DEFAULT)
+ {
+ /* Check the frame length (For the Prescaler computing) *******************/
+ /* Set I2S Packet Length value*/
+ if(hi2s->Init.DataFormat != I2S_DATAFORMAT_16B)
+ {
+ /* Packet length is 32 bits */
+ packetlength = 32U;
+ }
+ else
+ {
+ /* Packet length is 16 bits */
+ packetlength = 16U;
+ }
+
+ /* I2S standard */
+ if(hi2s->Init.Standard <= I2S_STANDARD_LSB)
+ {
+ /* In I2S standard packet lenght is multiplied by 2 */
+ packetlength = packetlength * 2U;
+ }
+
+ if(hi2s->Instance == SPI2)
+ {
+ /* Get the source clock value: based on SPI2 Instance */
+ i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2S2);
+ }
+ else if(hi2s->Instance == SPI3)
+ {
+ /* Get the source clock value: based on SPI3 Instance */
+ i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2S3);
+ }
+ else
+ {
+ /* Get the source clock value: based on System Clock value */
+ i2sclk = HAL_RCC_GetSysClockFreq();
+ }
+
+ /* Compute the Real divider depending on the MCLK output state, with a floating point */
+ if(hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE)
+ {
+ /* MCLK output is enabled */
+ if (hi2s->Init.DataFormat != I2S_DATAFORMAT_16B)
+ {
+ tmp = (uint32_t)(((((i2sclk / (packetlength*4)) * 10) / hi2s->Init.AudioFreq)) + 5);
+ }
+ else
+ {
+ tmp = (uint32_t)(((((i2sclk / (packetlength*8)) * 10) / hi2s->Init.AudioFreq)) + 5);
+ }
+ }
+ else
+ {
+ /* MCLK output is disabled */
+ tmp = (uint32_t)(((((i2sclk / packetlength) *10 ) / hi2s->Init.AudioFreq)) + 5);
+ }
+
+ /* Remove the flatting point */
+ tmp = tmp / 10U;
+
+ /* Check the parity of the divider */
+ i2sodd = (uint16_t)(tmp & (uint16_t)1U);
+
+ /* Compute the i2sdiv prescaler */
+ i2sdiv = (uint16_t)((tmp - i2sodd) / 2U);
+
+ /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
+ i2sodd = (uint32_t) (i2sodd << 8U);
+ }
+
+ /* Test if the divider is 1 or 0 or greater than 0xFF */
+ if((i2sdiv < 2U) || (i2sdiv > 0xFFU))
+ {
+ /* Set the default values */
+ i2sdiv = 2U;
+ i2sodd = 0U;
+
+ /* Set the error code and execute error callback*/
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_PRESCALER);
+ HAL_I2S_ErrorCallback(hi2s);
+ return HAL_ERROR;
+ }
+
+ /* Write to SPIx I2SPR register the computed value */
+ hi2s->Instance->I2SPR = (uint32_t)((uint32_t)i2sdiv | (uint32_t)(i2sodd | (uint32_t)hi2s->Init.MCLKOutput));
+
+ /* Configure the I2S with the I2S_InitStruct values */
+ tmpreg |= (uint16_t)((uint16_t)SPI_I2SCFGR_I2SMOD | (uint16_t)(hi2s->Init.Mode | \
+ (uint16_t)(hi2s->Init.Standard | (uint16_t)(hi2s->Init.DataFormat | \
+ (uint16_t)hi2s->Init.CPOL))));
+ /* Write to SPIx I2SCFGR */
+ WRITE_REG(hi2s->Instance->I2SCFGR,tmpreg);
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the I2S peripheral
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s)
+{
+ /* Check the I2S handle allocation */
+ if(hi2s == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ hi2s->State = HAL_I2S_STATE_BUSY;
+
+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
+ HAL_I2S_MspDeInit(hi2s);
+
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+ hi2s->State = HAL_I2S_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hi2s);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief I2S MSP Init
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+ __weak void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2s);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_I2S_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief I2S MSP DeInit
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+ __weak void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2s);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_I2S_MspDeInit could be implemented in the user file
+ */
+}
+/**
+ * @}
+ */
+
+/** @defgroup I2S_Exported_Functions_Group2 IO operation functions
+ * @brief Data transfers functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the I2S data
+ transfers.
+
+ (#) There are two modes of transfer:
+ (++) Blocking mode : The communication is performed in the polling mode.
+ The status of all data processing is returned by the same function
+ after finishing transfer.
+ (++) No-Blocking mode : The communication is performed using Interrupts
+ or DMA. These functions return the status of the transfer startup.
+ The end of the data processing will be indicated through the
+ dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
+ using DMA mode.
+
+ (#) Blocking mode functions are :
+ (++) HAL_I2S_Transmit()
+ (++) HAL_I2S_Receive()
+
+ (#) No-Blocking mode functions with Interrupt are :
+ (++) HAL_I2S_Transmit_IT()
+ (++) HAL_I2S_Receive_IT()
+
+ (#) No-Blocking mode functions with DMA are :
+ (++) HAL_I2S_Transmit_DMA()
+ (++) HAL_I2S_Receive_DMA()
+
+ (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
+ (++) HAL_I2S_TxCpltCallback()
+ (++) HAL_I2S_RxCpltCallback()
+ (++) HAL_I2S_ErrorCallback()
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Transmit an amount of data in blocking mode
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @param pData: a 16-bit pointer to data buffer.
+ * @param Size: number of data sample to be sent:
+ * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
+ * configuration phase, the Size parameter means the number of 16-bit data length
+ * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
+ * the Size parameter means the number of 16-bit data length.
+ * @param Timeout: Timeout duration
+ * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+ * between Master and Slave(example: audio streaming).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ uint32_t tmp1 = 0U;
+
+ if((pData == NULL ) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ if(hi2s->State == HAL_I2S_STATE_READY)
+ {
+ tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
+
+ if((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
+ {
+ hi2s->TxXferSize = (Size << 1U);
+ hi2s->TxXferCount = (Size << 1U);
+ }
+ else
+ {
+ hi2s->TxXferSize = Size;
+ hi2s->TxXferCount = Size;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+ hi2s->State = HAL_I2S_STATE_BUSY_TX;
+
+ /* Check if the I2S is already enabled */
+ if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
+ {
+ /* Enable I2S peripheral */
+ __HAL_I2S_ENABLE(hi2s);
+ }
+
+ while(hi2s->TxXferCount > 0U)
+ {
+ hi2s->Instance->DR = (*pData++);
+ hi2s->TxXferCount--;
+
+ /* Wait until TXE flag is set */
+ if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK)
+ {
+ /* Set the error code and execute error callback*/
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
+ HAL_I2S_ErrorCallback(hi2s);
+ return HAL_TIMEOUT;
+ }
+
+ /* Check if an underrun occurs */
+ if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
+ {
+ /* Clear underrun flag */
+ __HAL_I2S_CLEAR_UDRFLAG(hi2s);
+ /* Set the I2S State ready */
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2s);
+
+ /* Set the error code and execute error callback*/
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
+ HAL_I2S_ErrorCallback(hi2s);
+
+ return HAL_ERROR;
+ }
+ }
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2s);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive an amount of data in blocking mode
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @param pData: a 16-bit pointer to data buffer
+ * @param Size: number of data sample to be sent:
+ * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
+ * configuration phase, the Size parameter means the number of 16-bit data length
+ * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
+ * the Size parameter means the number of 16-bit data length.
+ * @param Timeout: Timeout duration
+ * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+ * between Master and Slave(example: audio streaming)
+ * @note In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
+ * in continuous way and as the I2S is not disabled at the end of the I2S transaction
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ uint32_t tmp1 = 0U;
+
+ if((pData == NULL ) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ if(hi2s->State == HAL_I2S_STATE_READY)
+ {
+ tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
+ if((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
+ {
+ hi2s->RxXferSize = (Size << 1U);
+ hi2s->RxXferCount = (Size << 1U);
+ }
+ else
+ {
+ hi2s->RxXferSize = Size;
+ hi2s->RxXferCount = Size;
+ }
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+ hi2s->State = HAL_I2S_STATE_BUSY_RX;
+
+ /* Check if the I2S is already enabled */
+ if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
+ {
+ /* Enable I2S peripheral */
+ __HAL_I2S_ENABLE(hi2s);
+ }
+
+ /* Check if Master Receiver mode is selected */
+ if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
+ {
+ /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
+ access to the SPI_SR register. */
+ __HAL_I2S_CLEAR_OVRFLAG(hi2s);
+ }
+
+ /* Receive data */
+ while(hi2s->RxXferCount > 0U)
+ {
+ /* Wait until RXNE flag is set */
+ if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout) != HAL_OK)
+ {
+ /* Set the error code and execute error callback*/
+ SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_TIMEOUT);
+ HAL_I2S_ErrorCallback(hi2s);
+ return HAL_TIMEOUT;
+ }
+
+ /* Check if an overrun occurs */
+ if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
+ {
+ /* Clear overrun flag */
+ __HAL_I2S_CLEAR_OVRFLAG(hi2s);
+
+ /* Set the I2S State ready */
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2s);
+
+ /* Set the error code and execute error callback*/
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
+ HAL_I2S_ErrorCallback(hi2s);
+
+ return HAL_ERROR;
+ }
+
+ (*pData++) = hi2s->Instance->DR;
+ hi2s->RxXferCount--;
+ }
+
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2s);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Transmit an amount of data in non-blocking mode with Interrupt
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @param pData: a 16-bit pointer to data buffer.
+ * @param Size: number of data sample to be sent:
+ * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
+ * configuration phase, the Size parameter means the number of 16-bit data length
+ * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
+ * the Size parameter means the number of 16-bit data length.
+ * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+ * between Master and Slave(example: audio streaming).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
+{
+ uint32_t tmp1 = 0U;
+
+ if(hi2s->State == HAL_I2S_STATE_READY)
+ {
+ if((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ hi2s->pTxBuffPtr = pData;
+ tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
+ if((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
+ {
+ hi2s->TxXferSize = (Size << 1U);
+ hi2s->TxXferCount = (Size << 1U);
+ }
+ else
+ {
+ hi2s->TxXferSize = Size;
+ hi2s->TxXferCount = Size;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ hi2s->State = HAL_I2S_STATE_BUSY_TX;
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+
+ /* Enable TXE and ERR interrupt */
+ __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
+
+ /* Check if the I2S is already enabled */
+ if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
+ {
+ /* Enable I2S peripheral */
+ __HAL_I2S_ENABLE(hi2s);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2s);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive an amount of data in non-blocking mode with Interrupt
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @param pData: a 16-bit pointer to the Receive data buffer.
+ * @param Size: number of data sample to be sent:
+ * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
+ * configuration phase, the Size parameter means the number of 16-bit data length
+ * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
+ * the Size parameter means the number of 16-bit data length.
+ * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+ * between Master and Slave(example: audio streaming).
+ * @note It is recommended to use DMA for the I2S receiver to avoid de-synchronisation
+ * between Master and Slave otherwise the I2S interrupt should be optimized.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
+{
+ uint32_t tmp1 = 0U;
+
+ if(hi2s->State == HAL_I2S_STATE_READY)
+ {
+ if((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ hi2s->pRxBuffPtr = pData;
+ tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
+ if((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
+ {
+ hi2s->RxXferSize = (Size << 1U);
+ hi2s->RxXferCount = (Size << 1U);
+ }
+ else
+ {
+ hi2s->RxXferSize = Size;
+ hi2s->RxXferCount = Size;
+ }
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ hi2s->State = HAL_I2S_STATE_BUSY_RX;
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+
+ /* Enable TXE and ERR interrupt */
+ __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
+
+ /* Check if the I2S is already enabled */
+ if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
+ {
+ /* Enable I2S peripheral */
+ __HAL_I2S_ENABLE(hi2s);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2s);
+
+ return HAL_OK;
+ }
+
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Transmit an amount of data in non-blocking mode with DMA
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @param pData: a 16-bit pointer to the Transmit data buffer.
+ * @param Size: number of data sample to be sent:
+ * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
+ * configuration phase, the Size parameter means the number of 16-bit data length
+ * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
+ * the Size parameter means the number of 16-bit data length.
+ * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+ * between Master and Slave(example: audio streaming).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
+{
+ uint32_t *tmp = NULL;
+ uint32_t tmp1 = 0U;
+
+ if((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ if(hi2s->State == HAL_I2S_STATE_READY)
+ {
+ hi2s->pTxBuffPtr = pData;
+ tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
+ if((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
+ {
+ hi2s->TxXferSize = (Size << 1U);
+ hi2s->TxXferCount = (Size << 1U);
+ }
+ else
+ {
+ hi2s->TxXferSize = Size;
+ hi2s->TxXferCount = Size;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+ hi2s->State = HAL_I2S_STATE_BUSY_TX;
+
+ /* Set the I2S Tx DMA Half transfer complete callback */
+ hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
+
+ /* Set the I2S Tx DMA transfer complete callback */
+ hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
+
+ /* Set the DMA error callback */
+ hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
+
+ /* Enable the Tx DMA Stream */
+ tmp = (uint32_t*)&pData;
+ HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize);
+
+ /* Check if the I2S is already enabled */
+ if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
+ {
+ /* Enable I2S peripheral */
+ __HAL_I2S_ENABLE(hi2s);
+ }
+
+ /* Check if the I2S Tx request is already enabled */
+ if((hi2s->Instance->CR2 & SPI_CR2_TXDMAEN) != SPI_CR2_TXDMAEN)
+ {
+ /* Enable Tx DMA Request */
+ SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2s);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive an amount of data in non-blocking mode with DMA
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @param pData: a 16-bit pointer to the Receive data buffer.
+ * @param Size: number of data sample to be sent:
+ * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
+ * configuration phase, the Size parameter means the number of 16-bit data length
+ * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
+ * the Size parameter means the number of 16-bit data length.
+ * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+ * between Master and Slave(example: audio streaming).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
+{
+ uint32_t *tmp = NULL;
+ uint32_t tmp1 = 0U;
+
+ if((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ if(hi2s->State == HAL_I2S_STATE_READY)
+ {
+ hi2s->pRxBuffPtr = pData;
+ tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
+ if((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
+ {
+ hi2s->RxXferSize = (Size << 1U);
+ hi2s->RxXferCount = (Size << 1U);
+ }
+ else
+ {
+ hi2s->RxXferSize = Size;
+ hi2s->RxXferCount = Size;
+ }
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ hi2s->State = HAL_I2S_STATE_BUSY_RX;
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+
+ /* Set the I2S Rx DMA Half transfer complete callback */
+ hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
+
+ /* Set the I2S Rx DMA transfer complete callback */
+ hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
+
+ /* Set the DMA error callback */
+ hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
+
+ /* Check if Master Receiver mode is selected */
+ if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
+ {
+ /* Clear the Overrun Flag by a read operation to the SPI_DR register followed by a read
+ access to the SPI_SR register. */
+ __HAL_I2S_CLEAR_OVRFLAG(hi2s);
+ }
+
+ /* Enable the Rx DMA Stream */
+ tmp = (uint32_t*)&pData;
+ HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, *(uint32_t*)tmp, hi2s->RxXferSize);
+
+ /* Check if the I2S is already enabled */
+ if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
+ {
+ /* Enable I2S peripheral */
+ __HAL_I2S_ENABLE(hi2s);
+ }
+
+ /* Check if the I2S Rx request is already enabled */
+ if((hi2s->Instance->CR2 &SPI_CR2_RXDMAEN) != SPI_CR2_RXDMAEN)
+ {
+ /* Enable Rx DMA Request */
+ SET_BIT(hi2s->Instance->CR2,SPI_CR2_RXDMAEN);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2s);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Pauses the audio channel playing from the Media.
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s)
+{
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ if(hi2s->State == HAL_I2S_STATE_BUSY_TX)
+ {
+ /* Disable the I2S DMA Tx request */
+ CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_TXDMAEN);
+ }
+ else if(hi2s->State == HAL_I2S_STATE_BUSY_RX)
+ {
+ /* Disable the I2S DMA Rx request */
+ CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_RXDMAEN);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2s);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Resumes the audio channel playing from the Media.
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s)
+{
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ if(hi2s->State == HAL_I2S_STATE_BUSY_TX)
+ {
+ /* Enable the I2S DMA Tx request */
+ SET_BIT(hi2s->Instance->CR2,SPI_CR2_TXDMAEN);
+ }
+ else if(hi2s->State == HAL_I2S_STATE_BUSY_RX)
+ {
+ /* Enable the I2S DMA Rx request */
+ SET_BIT(hi2s->Instance->CR2,SPI_CR2_RXDMAEN);
+ }
+
+ /* If the I2S peripheral is still not enabled, enable it */
+ if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) == 0U)
+ {
+ /* Enable I2S peripheral */
+ __HAL_I2S_ENABLE(hi2s);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2s);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Resumes the audio channel playing from the Media.
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
+{
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ if(hi2s->State == HAL_I2S_STATE_BUSY_TX)
+ {
+ /* Disable the I2S DMA requests */
+ CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_TXDMAEN);
+
+ /* Disable the I2S DMA Channel */
+ HAL_DMA_Abort(hi2s->hdmatx);
+ }
+ else if(hi2s->State == HAL_I2S_STATE_BUSY_RX)
+ {
+ /* Disable the I2S DMA requests */
+ CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_RXDMAEN);
+
+ /* Disable the I2S DMA Channel */
+ HAL_DMA_Abort(hi2s->hdmarx);
+ }
+ /* Disable I2S peripheral */
+ __HAL_I2S_DISABLE(hi2s);
+
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2s);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles I2S interrupt request.
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
+{
+ /* Call the IrqHandler ISR set during HAL_I2S_INIT */
+ hi2s->IrqHandlerISR(hi2s);
+}
+
+/**
+ * @brief Tx Transfer Half completed callbacks
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+ __weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2s);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_I2S_TxHalfCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Tx Transfer completed callbacks
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+ __weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2s);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_I2S_TxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer half completed callbacks
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+__weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2s);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_I2S_RxHalfCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer completed callbacks
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+__weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2s);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_I2S_RxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief I2S error callbacks
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+ __weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2s);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_I2S_ErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral State and Errors functions #####
+ ===============================================================================
+ [..]
+ This subsection permits to get in run-time the status of the peripheral
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Return the I2S state
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval HAL state
+ */
+HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s)
+{
+ return hi2s->State;
+}
+
+/**
+ * @brief Return the I2S error code
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval I2S Error Code
+ */
+uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s)
+{
+ return hi2s->ErrorCode;
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @addtogroup I2S_Private_Functions I2S Private Functions
+ * @{
+ */
+/**
+ * @brief DMA I2S transmit process complete callback
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
+{
+ I2S_HandleTypeDef* hi2s = ( I2S_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ if(HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
+ {
+ /* Disable Tx DMA Request */
+ CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_TXDMAEN);
+
+ hi2s->TxXferCount = 0U;
+ hi2s->State = HAL_I2S_STATE_READY;
+ }
+ HAL_I2S_TxCpltCallback(hi2s);
+}
+/**
+ * @brief DMA I2S transmit process half complete callback
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
+
+ HAL_I2S_TxHalfCpltCallback(hi2s);
+}
+
+/**
+ * @brief DMA I2S receive process complete callback
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
+{
+ I2S_HandleTypeDef* hi2s = ( I2S_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ if(HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
+ {
+ /* Disable Rx DMA Request */
+ CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_RXDMAEN);
+ hi2s->RxXferCount = 0U;
+ hi2s->State = HAL_I2S_STATE_READY;
+ }
+ HAL_I2S_RxCpltCallback(hi2s);
+}
+
+/**
+ * @brief DMA I2S receive process half complete callback
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
+
+ HAL_I2S_RxHalfCpltCallback(hi2s);
+}
+
+/**
+ * @brief DMA I2S communication error callback
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void I2S_DMAError(DMA_HandleTypeDef *hdma)
+{
+ I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
+
+ /* Disable Rx and Tx DMA Request */
+ CLEAR_BIT(hi2s->Instance->CR2,(SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
+ hi2s->TxXferCount = 0U;
+ hi2s->RxXferCount = 0U;
+
+ hi2s->State= HAL_I2S_STATE_READY;
+
+ SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_DMA);
+ HAL_I2S_ErrorCallback(hi2s);
+}
+
+/**
+ * @brief Transmit an amount of data in non-blocking mode with Interrupt
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval HAL status
+ */
+static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s)
+{
+ /* Transmit data */
+ hi2s->Instance->DR = (*hi2s->pTxBuffPtr++);
+ hi2s->TxXferCount--;
+
+ if(hi2s->TxXferCount == 0U)
+ {
+ /* Disable TXE and ERR interrupt */
+ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
+
+ hi2s->State = HAL_I2S_STATE_READY;
+ HAL_I2S_TxCpltCallback(hi2s);
+ }
+}
+
+/**
+ * @brief Receive an amount of data in non-blocking mode with Interrupt
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval HAL status
+ */
+static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s)
+{
+ /* Receive data */
+ (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR;
+ hi2s->RxXferCount--;
+
+ if(hi2s->RxXferCount == 0U)
+ {
+ /* Disable RXNE and ERR interrupt */
+ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
+
+ hi2s->State = HAL_I2S_STATE_READY;
+ HAL_I2S_RxCpltCallback(hi2s);
+ }
+}
+
+/**
+ * @brief This function handles I2S interrupt request.
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+static void I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
+{
+ __IO uint32_t i2ssr = hi2s->Instance->SR;
+
+ if(hi2s->State == HAL_I2S_STATE_BUSY_RX)
+ {
+ /* I2S in mode Receiver ------------------------------------------------*/
+ if(((i2ssr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_RXNE) != RESET))
+ {
+ I2S_Receive_IT(hi2s);
+ }
+
+ /* I2S Overrun error interrupt occurred -------------------------------------*/
+ if(((i2ssr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET))
+ {
+ /* Disable RXNE and ERR interrupt */
+ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
+
+ /* Clear Overrun flag */
+ __HAL_I2S_CLEAR_OVRFLAG(hi2s);
+
+ /* Set the I2S State ready */
+ hi2s->State = HAL_I2S_STATE_READY;
+
+
+ /* Set the error code and execute error callback*/
+ SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_OVR);
+ HAL_I2S_ErrorCallback(hi2s);
+ }
+ }
+
+ if(hi2s->State == HAL_I2S_STATE_BUSY_TX)
+ {
+ /* I2S in mode Transmitter -----------------------------------------------*/
+ if(((i2ssr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_TXE) != RESET))
+ {
+ I2S_Transmit_IT(hi2s);
+ }
+
+ /* I2S Underrun error interrupt occurred --------------------------------*/
+ if(((i2ssr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET))
+ {
+ /* Disable TXE and ERR interrupt */
+ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
+
+ /* Clear Underrun flag */
+ __HAL_I2S_CLEAR_UDRFLAG(hi2s);
+
+ /* Set the I2S State ready */
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Set the error code and execute error callback*/
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
+ HAL_I2S_ErrorCallback(hi2s);
+ }
+ }
+}
+
+/**
+ * @brief This function handles I2S Communication Timeout.
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @param Flag: Flag checked
+ * @param State: Value of the flag expected
+ * @param Timeout: Duration of the timeout
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, uint32_t State,
+ uint32_t Timeout)
+{
+ uint32_t tickstart = HAL_GetTick();
+
+ /* Wait until flag is set to status*/
+ while(((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
+ {
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
+ {
+ /* Set the I2S State ready */
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2s);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
+#endif /* HAL_I2S_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_irda.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_irda.c
new file mode 100644
index 0000000..697a339
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_irda.c
@@ -0,0 +1,2131 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_irda.c
+ * @author MCD Application Team
+ * @brief IRDA HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the IrDA SIR ENDEC block (IrDA):
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ * + Peripheral State and Errors functions
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The IRDA HAL driver can be used as follows:
+
+ (#) Declare a IRDA_HandleTypeDef handle structure.
+ (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API:
+ (##) Enable the USARTx interface clock.
+ (##) IRDA pins configuration:
+ (+++) Enable the clock for the IRDA GPIOs.
+ (+++) Configure the IRDA pins as alternate function pull-up.
+ (##) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT()
+ and HAL_IRDA_Receive_IT() APIs):
+ (+++) Configure the USARTx interrupt priority.
+ (+++) Enable the NVIC USART IRQ handle.
+ (##) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA()
+ and HAL_IRDA_Receive_DMA() APIs):
+ (+++) Declare a DMA handle structure for the Tx/Rx channel.
+ (+++) Enable the DMAx interface clock.
+ (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
+ (+++) Configure the DMA Tx/Rx channel.
+ (+++) Associate the initialized DMA handle to the IRDA DMA Tx/Rx handle.
+ (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
+ (+++) Configure the IRDAx interrupt priority and enable the NVIC USART IRQ handle
+ (used for last byte sending completion detection in DMA non circular mode)
+
+ (#) Program the Baud Rate, Word Length, Parity, IrDA Mode, Prescaler
+ and Mode(Receiver/Transmitter) in the hirda Init structure.
+
+ (#) Initialize the IRDA registers by calling the HAL_IRDA_Init() API:
+ (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
+ by calling the customized HAL_IRDA_MspInit() API.
+ [..]
+ (@) The specific IRDA interrupts (Transmission complete interrupt,
+ RXNE interrupt and Error Interrupts) will be managed using the macros
+ __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process.
+ [..]
+ Three operation modes are available within this driver :
+
+ *** Polling mode IO operation ***
+ =================================
+ [..]
+ (+) Send an amount of data in blocking mode using HAL_IRDA_Transmit()
+ (+) Receive an amount of data in blocking mode using HAL_IRDA_Receive()
+
+ *** Interrupt mode IO operation ***
+ ===================================
+ [..]
+ (+) Send an amount of data in non blocking mode using HAL_IRDA_Transmit_IT()
+ (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_IRDA_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode using HAL_IRDA_Receive_IT()
+ (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_IRDA_RxCpltCallback
+ (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_IRDA_ErrorCallback
+
+ *** DMA mode IO operation ***
+ ==============================
+ [..]
+ (+) Send an amount of data in non blocking mode (DMA) using HAL_IRDA_Transmit_DMA()
+ (+) At transmission end of half transfer HAL_IRDA_TxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_IRDA_TxHalfCpltCallback
+ (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_IRDA_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode (DMA) using HAL_IRDA_Receive_DMA()
+ (+) At reception end of half transfer HAL_IRDA_RxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_IRDA_RxHalfCpltCallback
+ (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_IRDA_RxCpltCallback
+ (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_IRDA_ErrorCallback
+ (+) Pause the DMA Transfer using HAL_IRDA_DMAPause()
+ (+) Resume the DMA Transfer using HAL_IRDA_DMAResume()
+ (+) Stop the DMA Transfer using HAL_IRDA_DMAStop()
+
+ *** IRDA HAL driver macros list ***
+ ====================================
+ [..]
+ Below the list of most used macros in IRDA HAL driver.
+
+ (+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral
+ (+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral
+ (+) __HAL_IRDA_GET_FLAG : Check whether the specified IRDA flag is set or not
+ (+) __HAL_IRDA_CLEAR_FLAG : Clear the specified IRDA pending flag
+ (+) __HAL_IRDA_ENABLE_IT: Enable the specified IRDA interrupt
+ (+) __HAL_IRDA_DISABLE_IT: Disable the specified IRDA interrupt
+ (+) __HAL_IRDA_GET_IT_SOURCE: Check whether the specified IRDA interrupt has occurred or not
+
+ [..]
+ (@) You can refer to the IRDA HAL driver header file for more useful macros
+ @endverbatim
+ [..]
+ (@) Additionnal remark: If the parity is enabled, then the MSB bit of the data written
+ in the data register is transmitted but is changed by the parity bit.
+ Depending on the frame length defined by the M bit (8-bits or 9-bits),
+ the possible IRDA frame formats are as listed in the following table:
+ +-------------------------------------------------------------+
+ | M bit | PCE bit | IRDA frame |
+ |---------------------|---------------------------------------|
+ | 0 | 0 | | SB | 8 bit data | 1 STB | |
+ |---------|-----------|---------------------------------------|
+ | 0 | 1 | | SB | 7 bit data | PB | 1 STB | |
+ |---------|-----------|---------------------------------------|
+ | 1 | 0 | | SB | 9 bit data | 1 STB | |
+ |---------|-----------|---------------------------------------|
+ | 1 | 1 | | SB | 8 bit data | PB | 1 STB | |
+ +-------------------------------------------------------------+
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup IRDA IRDA
+ * @brief HAL IRDA module driver
+ * @{
+ */
+#ifdef HAL_IRDA_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @addtogroup IRDA_Private_Constants
+ * @{
+ */
+/**
+ * @}
+ */
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @addtogroup IRDA_Private_Functions
+ * @{
+ */
+static void IRDA_SetConfig (IRDA_HandleTypeDef *hirda);
+static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda);
+static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda);
+static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda);
+static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma);
+static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma);
+static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
+static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma);
+static void IRDA_DMAError(DMA_HandleTypeDef *hdma);
+static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma);
+static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
+static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
+static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
+static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
+static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart,uint32_t Timeout);
+static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda);
+static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda);
+/**
+ * @}
+ */
+/* Exported functions ---------------------------------------------------------*/
+/** @defgroup IRDA_Exported_Functions IrDA Exported Functions
+ * @{
+ */
+
+/** @defgroup IRDA_Exported_Functions_Group1 IrDA Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and Configuration functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
+ in IrDA mode.
+ (+) For the asynchronous mode only these parameters can be configured:
+ (++) BaudRate
+ (++) WordLength
+ (++) Parity: If the parity is enabled, then the MSB bit of the data written
+ in the data register is transmitted but is changed by the parity bit.
+ Depending on the frame length defined by the M bit (8-bits or 9-bits),
+ please refer to Reference manual for possible IRDA frame formats.
+ (++) Prescaler: A pulse of width less than two and greater than one PSC period(s) may or may
+ not be rejected. The receiver set up time should be managed by software. The IrDA physical layer
+ specification specifies a minimum of 10 ms delay between transmission and
+ reception (IrDA is a half duplex protocol).
+ (++) Mode: Receiver/transmitter modes
+ (++) IrDAMode: the IrDA can operate in the Normal mode or in the Low power mode.
+ [..]
+ The HAL_IRDA_Init() API follows IRDA configuration procedures (details for the procedures
+ are available in reference manual).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the IRDA mode according to the specified
+ * parameters in the IRDA_InitTypeDef and create the associated handle.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda)
+{
+ /* Check the IRDA handle allocation */
+ if(hirda == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_IRDA_INSTANCE(hirda->Instance));
+
+ if(hirda->gState == HAL_IRDA_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hirda->Lock = HAL_UNLOCKED;
+ /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
+ HAL_IRDA_MspInit(hirda);
+ }
+
+ hirda->gState = HAL_IRDA_STATE_BUSY;
+
+ /* Disable the IRDA peripheral */
+ __HAL_IRDA_DISABLE(hirda);
+
+ /* Set the IRDA communication parameters */
+ IRDA_SetConfig(hirda);
+
+ /* In IrDA mode, the following bits must be kept cleared:
+ - LINEN, STOP and CLKEN bits in the USART_CR2 register,
+ - SCEN and HDSEL bits in the USART_CR3 register.*/
+ CLEAR_BIT(hirda->Instance->CR2, (USART_CR2_LINEN | USART_CR2_STOP | USART_CR2_CLKEN));
+ CLEAR_BIT(hirda->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL));
+
+ /* Enable the IRDA peripheral */
+ __HAL_IRDA_ENABLE(hirda);
+
+ /* Set the prescaler */
+ MODIFY_REG(hirda->Instance->GTPR, USART_GTPR_PSC, hirda->Init.Prescaler);
+
+ /* Configure the IrDA mode */
+ MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.IrDAMode);
+
+ /* Enable the IrDA mode by setting the IREN bit in the CR3 register */
+ SET_BIT(hirda->Instance->CR3, USART_CR3_IREN);
+
+ /* Initialize the IRDA state*/
+ hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
+ hirda->gState= HAL_IRDA_STATE_READY;
+ hirda->RxState= HAL_IRDA_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the IRDA peripheral
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda)
+{
+ /* Check the IRDA handle allocation */
+ if(hirda == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_IRDA_INSTANCE(hirda->Instance));
+
+ hirda->gState = HAL_IRDA_STATE_BUSY;
+
+ /* Disable the Peripheral */
+ __HAL_IRDA_DISABLE(hirda);
+
+ /* DeInit the low level hardware */
+ HAL_IRDA_MspDeInit(hirda);
+
+ hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
+ hirda->gState = HAL_IRDA_STATE_RESET;
+ hirda->RxState = HAL_IRDA_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hirda);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief IRDA MSP Init.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @retval None
+ */
+__weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hirda);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_IRDA_MspInit can be implemented in the user file
+ */
+}
+
+/**
+ * @brief IRDA MSP DeInit.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @retval None
+ */
+__weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hirda);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_IRDA_MspDeInit can be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup IRDA_Exported_Functions_Group2 IO operation functions
+ * @brief IRDA Transmit and Receive functions
+ *
+@verbatim
+ ==============================================================================
+ ##### IO operation functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the IRDA data transfers.
+ IrDA is a half duplex communication protocol. If the Transmitter is busy, any data
+ on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver
+ is busy, data on the TX from the USART to IrDA will not be encoded by IrDA.
+ While receiving data, transmission should be avoided as the data to be transmitted
+ could be corrupted.
+
+ (#) There are two modes of transfer:
+ (++) Blocking mode: The communication is performed in polling mode.
+ The HAL status of all data processing is returned by the same function
+ after finishing transfer.
+ (++) No-Blocking mode: The communication is performed using Interrupts
+ or DMA, these APIs return the HAL status.
+ The end of the data processing will be indicated through the
+ dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when
+ using DMA mode.
+ The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks
+ will be executed respectively at the end of the transmit or Receive process
+ The HAL_IRDA_ErrorCallback() user callback will be executed when a communication
+ error is detected
+
+ (#) Blocking mode APIs are:
+ (++) HAL_IRDA_Transmit()
+ (++) HAL_IRDA_Receive()
+
+ (#) Non Blocking mode APIs with Interrupt are:
+ (++) HAL_IRDA_Transmit_IT()
+ (++) HAL_IRDA_Receive_IT()
+ (++) HAL_IRDA_IRQHandler()
+
+ (#) Non Blocking mode functions with DMA are:
+ (++) HAL_IRDA_Transmit_DMA()
+ (++) HAL_IRDA_Receive_DMA()
+ (++) HAL_IRDA_DMAPause()
+ (++) HAL_IRDA_DMAResume()
+ (++) HAL_IRDA_DMAStop()
+
+ (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
+ (++) HAL_IRDA_TxHalfCpltCallback()
+ (++) HAL_IRDA_TxCpltCallback()
+ (++) HAL_IRDA_RxHalfCpltCallback()
+ (++) HAL_IRDA_RxCpltCallback()
+ (++) HAL_IRDA_ErrorCallback()
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sends an amount of data in blocking mode.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be sent
+ * @param Timeout: Specify timeout value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ uint16_t* tmp;
+ uint32_t tickstart = 0U;
+
+ /* Check that a Tx process is not already ongoing */
+ if(hirda->gState == HAL_IRDA_STATE_READY)
+ {
+ if((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hirda);
+
+ hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
+ hirda->gState = HAL_IRDA_STATE_BUSY_TX;
+
+ /* Init tickstart for timeout managment */
+ tickstart = HAL_GetTick();
+
+ hirda->TxXferSize = Size;
+ hirda->TxXferCount = Size;
+ while(hirda->TxXferCount > 0U)
+ {
+ hirda->TxXferCount--;
+ if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
+ {
+ if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ tmp = (uint16_t*) pData;
+ hirda->Instance->DR = (*tmp & (uint16_t)0x01FF);
+ if(hirda->Init.Parity == IRDA_PARITY_NONE)
+ {
+ pData +=2U;
+ }
+ else
+ {
+ pData +=1U;
+ }
+ }
+ else
+ {
+ if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ hirda->Instance->DR = (*pData++ & (uint8_t)0xFF);
+ }
+ }
+
+ if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+
+ /* At end of Tx process, restore hirda->gState to Ready */
+ hirda->gState = HAL_IRDA_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hirda);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive an amount of data in blocking mode.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be received
+ * @param Timeout: Specify timeout value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ uint16_t* tmp;
+ uint32_t tickstart = 0U;
+
+ /* Check that a Rx process is not already ongoing */
+ if(hirda->RxState == HAL_IRDA_STATE_READY)
+ {
+ if((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hirda);
+
+ hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
+ hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
+
+ /* Init tickstart for timeout managment */
+ tickstart = HAL_GetTick();
+
+ hirda->RxXferSize = Size;
+ hirda->RxXferCount = Size;
+
+ /* Check the remain data to be received */
+ while(hirda->RxXferCount > 0U)
+ {
+ hirda->RxXferCount--;
+ if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
+ {
+ if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ tmp = (uint16_t*)pData;
+ if(hirda->Init.Parity == IRDA_PARITY_NONE)
+ {
+ *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x01FF);
+ pData +=2U;
+ }
+ else
+ {
+ *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x00FF);
+ pData +=1U;
+ }
+ }
+ else
+ {
+ if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ if(hirda->Init.Parity == IRDA_PARITY_NONE)
+ {
+ *pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x00FF);
+ }
+ else
+ {
+ *pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x007F);
+ }
+ }
+ }
+
+ /* At end of Rx process, restore hirda->RxState to Ready */
+ hirda->RxState = HAL_IRDA_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hirda);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sends an amount of data in non blocking mode.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
+{
+ /* Check that a Tx process is not already ongoing */
+ if(hirda->gState == HAL_IRDA_STATE_READY)
+ {
+ if((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+ /* Process Locked */
+ __HAL_LOCK(hirda);
+
+ hirda->pTxBuffPtr = pData;
+ hirda->TxXferSize = Size;
+ hirda->TxXferCount = Size;
+
+ hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
+ hirda->gState = HAL_IRDA_STATE_BUSY_TX;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hirda);
+
+ /* Enable the IRDA Transmit data register empty Interrupt */
+ __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TXE);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receives an amount of data in non blocking mode.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be received
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
+{
+ /* Check that a Rx process is not already ongoing */
+ if(hirda->RxState == HAL_IRDA_STATE_READY)
+ {
+ if((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hirda);
+
+ hirda->pRxBuffPtr = pData;
+ hirda->RxXferSize = Size;
+ hirda->RxXferCount = Size;
+
+ hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
+ hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hirda);
+
+ /* Enable the IRDA Parity Error Interrupt */
+ __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_PE);
+
+ /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
+ __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_ERR);
+
+ /* Enable the IRDA Data Register not empty Interrupt */
+ __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_RXNE);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sends an amount of data in non blocking mode.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
+{
+ uint32_t *tmp;
+
+ /* Check that a Tx process is not already ongoing */
+ if(hirda->gState == HAL_IRDA_STATE_READY)
+ {
+ if((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hirda);
+
+ hirda->pTxBuffPtr = pData;
+ hirda->TxXferSize = Size;
+ hirda->TxXferCount = Size;
+
+ hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
+ hirda->gState = HAL_IRDA_STATE_BUSY_TX;
+
+ /* Set the IRDA DMA transfer complete callback */
+ hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt;
+
+ /* Set the IRDA DMA half transfer complete callback */
+ hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt;
+
+ /* Set the DMA error callback */
+ hirda->hdmatx->XferErrorCallback = IRDA_DMAError;
+
+ /* Set the DMA abort callback */
+ hirda->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the IRDA transmit DMA Channel */
+ tmp = (uint32_t*)&pData;
+ HAL_DMA_Start_IT(hirda->hdmatx, *(uint32_t*)tmp, (uint32_t)&hirda->Instance->DR, Size);
+
+ /* Clear the TC flag in the SR register by writing 0 to it */
+ __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_FLAG_TC);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hirda);
+
+ /* Enable the DMA transfer for transmit request by setting the DMAT bit
+ in the USART CR3 register */
+ SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receives an amount of data in non blocking mode.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be received
+ * @note When the IRDA parity is enabled (PCE = 1) the data received contain the parity bit.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
+{
+ uint32_t *tmp;
+
+ /* Check that a Rx process is not already ongoing */
+ if(hirda->RxState == HAL_IRDA_STATE_READY)
+ {
+ if((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hirda);
+
+ hirda->pRxBuffPtr = pData;
+ hirda->RxXferSize = Size;
+
+ hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
+ hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
+
+ /* Set the IRDA DMA transfer complete callback */
+ hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt;
+
+ /* Set the IRDA DMA half transfer complete callback */
+ hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt;
+
+ /* Set the DMA error callback */
+ hirda->hdmarx->XferErrorCallback = IRDA_DMAError;
+
+ /* Set the DMA abort callback */
+ hirda->hdmarx->XferAbortCallback = NULL;
+
+ /* Enable the DMA channel */
+ tmp = (uint32_t*)&pData;
+ HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->DR, *(uint32_t*)tmp, Size);
+
+ /* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */
+ __HAL_IRDA_CLEAR_OREFLAG(hirda);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hirda);
+
+ /* Enable the IRDA Parity Error Interrupt */
+ SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
+
+ /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
+ SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
+
+ /* Enable the DMA transfer for the receiver request by setting the DMAR bit
+ in the USART CR3 register */
+ SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Pauses the DMA Transfer.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda)
+{
+ uint32_t dmarequest = 0x00U;
+
+ /* Process Locked */
+ __HAL_LOCK(hirda);
+
+ dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT);
+ if((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest)
+ {
+ /* Disable the IRDA DMA Tx request */
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
+ }
+
+ dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
+ if((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest)
+ {
+ /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the IRDA DMA Rx request */
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hirda);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Resumes the DMA Transfer.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda)
+{
+ /* Process Locked */
+ __HAL_LOCK(hirda);
+
+ if(hirda->gState == HAL_IRDA_STATE_BUSY_TX)
+ {
+ /* Enable the IRDA DMA Tx request */
+ SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
+ }
+
+ if(hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
+ {
+ /* Clear the Overrun flag before resuming the Rx transfer */
+ __HAL_IRDA_CLEAR_OREFLAG(hirda);
+
+ /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */
+ SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
+ SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
+
+ /* Enable the IRDA DMA Rx request */
+ SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hirda);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the DMA Transfer.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda)
+{
+ uint32_t dmarequest = 0x00U;
+ /* The Lock is not implemented on this API to allow the user application
+ to call the HAL IRDA API under callbacks HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback():
+ when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
+ and the correspond call back is executed HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback()
+ */
+
+ /* Stop IRDA DMA Tx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT);
+ if((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest)
+ {
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the IRDA DMA Tx channel */
+ if(hirda->hdmatx != NULL)
+ {
+ HAL_DMA_Abort(hirda->hdmatx);
+ }
+ IRDA_EndTxTransfer(hirda);
+ }
+
+ /* Stop IRDA DMA Rx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
+ if((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest)
+ {
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the IRDA DMA Rx channel */
+ if(hirda->hdmarx != NULL)
+ {
+ HAL_DMA_Abort(hirda->hdmarx);
+ }
+ IRDA_EndRxTransfer(hirda);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing transfers (blocking mode).
+ * @param hirda IRDA handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_IRDA_Abort(IRDA_HandleTypeDef *hirda)
+{
+ /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the IRDA DMA Tx request if enabled */
+ if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
+ {
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the IRDA DMA Tx channel: use blocking DMA Abort API (no callback) */
+ if(hirda->hdmatx != NULL)
+ {
+ /* Set the IRDA DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ hirda->hdmatx->XferAbortCallback = NULL;
+
+ HAL_DMA_Abort(hirda->hdmatx);
+ }
+ }
+
+ /* Disable the IRDA DMA Rx request if enabled */
+ if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the IRDA DMA Rx channel: use blocking DMA Abort API (no callback) */
+ if(hirda->hdmarx != NULL)
+ {
+ /* Set the IRDA DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ hirda->hdmarx->XferAbortCallback = NULL;
+
+ HAL_DMA_Abort(hirda->hdmarx);
+ }
+ }
+
+ /* Reset Tx and Rx transfer counters */
+ hirda->TxXferCount = 0x00U;
+ hirda->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
+
+ /* Restore hirda->RxState and hirda->gState to Ready */
+ hirda->RxState = HAL_IRDA_STATE_READY;
+ hirda->gState = HAL_IRDA_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Transmit transfer (blocking mode).
+ * @param hirda IRDA handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef *hirda)
+{
+ /* Disable TXEIE and TCIE interrupts */
+ CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+
+ /* Disable the IRDA DMA Tx request if enabled */
+ if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
+ {
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
+ if(hirda->hdmatx != NULL)
+ {
+ /* Set the IRDA DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ hirda->hdmatx->XferAbortCallback = NULL;
+
+ HAL_DMA_Abort(hirda->hdmatx);
+ }
+ }
+
+ /* Reset Tx transfer counter */
+ hirda->TxXferCount = 0x00U;
+
+ /* Restore hirda->gState to Ready */
+ hirda->gState = HAL_IRDA_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Receive transfer (blocking mode).
+ * @param hirda IRDA handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_IRDA_AbortReceive(IRDA_HandleTypeDef *hirda)
+{
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the IRDA DMA Rx request if enabled */
+ if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
+ if(hirda->hdmarx != NULL)
+ {
+ /* Set the IRDA DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ hirda->hdmarx->XferAbortCallback = NULL;
+
+ HAL_DMA_Abort(hirda->hdmarx);
+ }
+ }
+
+ /* Reset Rx transfer counter */
+ hirda->RxXferCount = 0x00U;
+
+ /* Restore hirda->RxState to Ready */
+ hirda->RxState = HAL_IRDA_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing transfers (Interrupt mode).
+ * @param hirda IRDA handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_IRDA_Abort_IT(IRDA_HandleTypeDef *hirda)
+{
+ uint32_t AbortCplt = 0x01U;
+
+ /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
+
+ /* If DMA Tx and/or DMA Rx Handles are associated to IRDA Handle, DMA Abort complete callbacks should be initialised
+ before any call to DMA Abort functions */
+ /* DMA Tx Handle is valid */
+ if(hirda->hdmatx != NULL)
+ {
+ /* Set DMA Abort Complete callback if IRDA DMA Tx request if enabled.
+ Otherwise, set it to NULL */
+ if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
+ {
+ hirda->hdmatx->XferAbortCallback = IRDA_DMATxAbortCallback;
+ }
+ else
+ {
+ hirda->hdmatx->XferAbortCallback = NULL;
+ }
+ }
+ /* DMA Rx Handle is valid */
+ if(hirda->hdmarx != NULL)
+ {
+ /* Set DMA Abort Complete callback if IRDA DMA Rx request if enabled.
+ Otherwise, set it to NULL */
+ if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
+ {
+ hirda->hdmarx->XferAbortCallback = IRDA_DMARxAbortCallback;
+ }
+ else
+ {
+ hirda->hdmarx->XferAbortCallback = NULL;
+ }
+ }
+
+ /* Disable the IRDA DMA Tx request if enabled */
+ if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
+ {
+ /* Disable DMA Tx at IRDA level */
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */
+ if(hirda->hdmatx != NULL)
+ {
+ /* IRDA Tx DMA Abort callback has already been initialised :
+ will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
+
+ /* Abort DMA TX */
+ if(HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
+ {
+ hirda->hdmatx->XferAbortCallback = NULL;
+ }
+ else
+ {
+ AbortCplt = 0x00U;
+ }
+ }
+ }
+
+ /* Disable the IRDA DMA Rx request if enabled */
+ if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */
+ if(hirda->hdmarx != NULL)
+ {
+ /* IRDA Rx DMA Abort callback has already been initialised :
+ will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
+
+ /* Abort DMA RX */
+ if(HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
+ {
+ hirda->hdmarx->XferAbortCallback = NULL;
+ AbortCplt = 0x01U;
+ }
+ else
+ {
+ AbortCplt = 0x00U;
+ }
+ }
+ }
+
+ /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
+ if(AbortCplt == 0x01U)
+ {
+ /* Reset Tx and Rx transfer counters */
+ hirda->TxXferCount = 0x00U;
+ hirda->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
+
+ /* Restore hirda->gState and hirda->RxState to Ready */
+ hirda->gState = HAL_IRDA_STATE_READY;
+ hirda->RxState = HAL_IRDA_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+ HAL_IRDA_AbortCpltCallback(hirda);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Transmit transfer (Interrupt mode).
+ * @param hirda IRDA handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef *hirda)
+{
+ /* Disable TXEIE and TCIE interrupts */
+ CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+
+ /* Disable the IRDA DMA Tx request if enabled */
+ if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
+ {
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
+ if(hirda->hdmatx != NULL)
+ {
+ /* Set the IRDA DMA Abort callback :
+ will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
+ hirda->hdmatx->XferAbortCallback = IRDA_DMATxOnlyAbortCallback;
+
+ /* Abort DMA TX */
+ if(HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
+ {
+ /* Call Directly hirda->hdmatx->XferAbortCallback function in case of error */
+ hirda->hdmatx->XferAbortCallback(hirda->hdmatx);
+ }
+ }
+ else
+ {
+ /* Reset Tx transfer counter */
+ hirda->TxXferCount = 0x00U;
+
+ /* Restore hirda->gState to Ready */
+ hirda->gState = HAL_IRDA_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+ HAL_IRDA_AbortTransmitCpltCallback(hirda);
+ }
+ }
+ else
+ {
+ /* Reset Tx transfer counter */
+ hirda->TxXferCount = 0x00U;
+
+ /* Restore hirda->gState to Ready */
+ hirda->gState = HAL_IRDA_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+ HAL_IRDA_AbortTransmitCpltCallback(hirda);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Receive transfer (Interrupt mode).
+ * @param hirda IRDA handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef *hirda)
+{
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the IRDA DMA Rx request if enabled */
+ if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
+ if(hirda->hdmarx != NULL)
+ {
+ /* Set the IRDA DMA Abort callback :
+ will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
+ hirda->hdmarx->XferAbortCallback = IRDA_DMARxOnlyAbortCallback;
+
+ /* Abort DMA RX */
+ if(HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
+ {
+ /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */
+ hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
+ }
+ }
+ else
+ {
+ /* Reset Rx transfer counter */
+ hirda->RxXferCount = 0x00U;
+
+ /* Restore hirda->RxState to Ready */
+ hirda->RxState = HAL_IRDA_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+ HAL_IRDA_AbortReceiveCpltCallback(hirda);
+ }
+ }
+ else
+ {
+ /* Reset Rx transfer counter */
+ hirda->RxXferCount = 0x00U;
+
+ /* Restore hirda->RxState to Ready */
+ hirda->RxState = HAL_IRDA_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+ HAL_IRDA_AbortReceiveCpltCallback(hirda);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles IRDA interrupt request.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @retval None
+ */
+void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda)
+{
+ uint32_t isrflags = READ_REG(hirda->Instance->SR);
+ uint32_t cr1its = READ_REG(hirda->Instance->CR1);
+ uint32_t cr3its = READ_REG(hirda->Instance->CR3);
+ uint32_t errorflags = 0x00U;
+ uint32_t dmarequest = 0x00U;
+
+ /* If no error occurs */
+ errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
+ if(errorflags == RESET)
+ {
+ /* IRDA in mode Receiver -----------------------------------------------*/
+ if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
+ {
+ IRDA_Receive_IT(hirda);
+ return;
+ }
+ }
+
+ /* If some errors occur */
+ if((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
+ {
+ /* IRDA parity error interrupt occurred -------------------------------*/
+ if(((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
+ {
+ hirda->ErrorCode |= HAL_IRDA_ERROR_PE;
+ }
+
+ /* IRDA noise error interrupt occurred --------------------------------*/
+ if(((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
+ {
+ hirda->ErrorCode |= HAL_IRDA_ERROR_NE;
+ }
+
+ /* IRDA frame error interrupt occurred --------------------------------*/
+ if(((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
+ {
+ hirda->ErrorCode |= HAL_IRDA_ERROR_FE;
+ }
+
+ /* IRDA Over-Run interrupt occurred -----------------------------------*/
+ if(((isrflags & USART_SR_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
+ {
+ hirda->ErrorCode |= HAL_IRDA_ERROR_ORE;
+ }
+ /* Call IRDA Error Call back function if need be -----------------------*/
+ if(hirda->ErrorCode != HAL_IRDA_ERROR_NONE)
+ {
+ /* IRDA in mode Receiver ---------------------------------------------*/
+ if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
+ {
+ IRDA_Receive_IT(hirda);
+ }
+
+ /* If Overrun error occurs, or if any error occurs in DMA mode reception,
+ consider error as blocking */
+ dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
+ if(((hirda->ErrorCode & HAL_IRDA_ERROR_ORE) != RESET) || dmarequest)
+ {
+ /* Blocking error : transfer is aborted
+ Set the IRDA state ready to be able to start again the process,
+ Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
+ IRDA_EndRxTransfer(hirda);
+
+ /* Disable the IRDA DMA Rx request if enabled */
+ if(HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the IRDA DMA Rx channel */
+ if(hirda->hdmarx != NULL)
+ {
+ /* Set the IRDA DMA Abort callback :
+ will lead to call HAL_IRDA_ErrorCallback() at end of DMA abort procedure */
+ hirda->hdmarx->XferAbortCallback = IRDA_DMAAbortOnError;
+
+ if(HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
+ {
+ /* Call Directly XferAbortCallback function in case of error */
+ hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
+ }
+ }
+ else
+ {
+ /* Call user error callback */
+ HAL_IRDA_ErrorCallback(hirda);
+ }
+ }
+ else
+ {
+ /* Call user error callback */
+ HAL_IRDA_ErrorCallback(hirda);
+ }
+ }
+ else
+ {
+ /* Non Blocking error : transfer could go on.
+ Error is notified to user through user error callback */
+ HAL_IRDA_ErrorCallback(hirda);
+ hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
+ }
+ }
+ return;
+ } /* End if some error occurs */
+
+ /* IRDA in mode Transmitter ------------------------------------------------*/
+ if(((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
+ {
+ IRDA_Transmit_IT(hirda);
+ return;
+ }
+
+ /* IRDA in mode Transmitter end --------------------------------------------*/
+ if(((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
+ {
+ IRDA_EndTransmit_IT(hirda);
+ return;
+ }
+}
+
+/**
+ * @brief Tx Transfer complete callbacks.
+ * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @retval None
+ */
+__weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hirda);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_IRDA_TxCpltCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief Tx Half Transfer completed callbacks.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval None
+ */
+__weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hirda);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_IRDA_TxHalfCpltCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer complete callbacks.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @retval None
+ */
+__weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hirda);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_IRDA_RxCpltCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Half Transfer complete callbacks.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @retval None
+ */
+__weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hirda);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_IRDA_RxHalfCpltCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief IRDA error callbacks.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @retval None
+ */
+__weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hirda);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_IRDA_ErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief IRDA Abort Complete callback.
+ * @param hirda IRDA handle.
+ * @retval None
+ */
+__weak void HAL_IRDA_AbortCpltCallback(IRDA_HandleTypeDef *hirda)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hirda);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_IRDA_AbortCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @brief IRDA Abort Transmit Complete callback.
+ * @param hirda IRDA handle.
+ * @retval None
+ */
+__weak void HAL_IRDA_AbortTransmitCpltCallback(IRDA_HandleTypeDef *hirda)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hirda);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_IRDA_AbortTransmitCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @brief IRDA Abort ReceiveComplete callback.
+ * @param hirda IRDA handle.
+ * @retval None
+ */
+__weak void HAL_IRDA_AbortReceiveCpltCallback(IRDA_HandleTypeDef *hirda)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hirda);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_IRDA_AbortReceiveCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup IRDA_Exported_Functions_Group3 Peripheral State and Errors functions
+ * @brief IRDA State and Errors functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral State and Errors functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to return the State of IrDA
+ communication process and also return Peripheral Errors occurred during communication process
+ (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state of the IrDA peripheral.
+ (+) HAL_IRDA_GetError() check in run-time errors that could be occurred during communication.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns the IRDA state.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @retval HAL state
+ */
+HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda)
+{
+ uint32_t temp1 = 0x00U, temp2 = 0x00U;
+ temp1 = hirda->gState;
+ temp2 = hirda->RxState;
+
+ return (HAL_IRDA_StateTypeDef)(temp1 | temp2);
+}
+
+/**
+ * @brief Return the IRDA error code
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @retval IRDA Error Code
+ */
+uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda)
+{
+ return hirda->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @brief DMA IRDA transmit process complete callback.
+ * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma)
+{
+ IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ /* DMA Normal mode */
+ if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
+ {
+ hirda->TxXferCount = 0U;
+
+ /* Disable the DMA transfer for transmit request by setting the DMAT bit
+ in the IRDA CR3 register */
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
+
+ /* Enable the IRDA Transmit Complete Interrupt */
+ __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC);
+ }
+ /* DMA Circular mode */
+ else
+ {
+ HAL_IRDA_TxCpltCallback(hirda);
+ }
+}
+
+/**
+ * @brief DMA IRDA receive process half complete callback
+ * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ HAL_IRDA_TxHalfCpltCallback(hirda);
+}
+
+/**
+ * @brief DMA IRDA receive process complete callback.
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ /* DMA Normal mode */
+ if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
+ {
+ hirda->RxXferCount = 0U;
+
+ /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the DMA transfer for the receiver request by setting the DMAR bit
+ in the IRDA CR3 register */
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
+
+ /* At end of Rx process, restore hirda->RxState to Ready */
+ hirda->RxState = HAL_IRDA_STATE_READY;
+ }
+ HAL_IRDA_RxCpltCallback(hirda);
+}
+
+/**
+ * @brief DMA IRDA receive process half complete callback
+ * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ HAL_IRDA_RxHalfCpltCallback(hirda);
+}
+
+/**
+ * @brief DMA IRDA communication error callback.
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void IRDA_DMAError(DMA_HandleTypeDef *hdma)
+{
+ uint32_t dmarequest = 0x00U;
+ IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ /* Stop IRDA DMA Tx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT);
+ if((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest)
+ {
+ hirda->TxXferCount = 0U;
+ IRDA_EndTxTransfer(hirda);
+ }
+
+ /* Stop IRDA DMA Rx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
+ if((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest)
+ {
+ hirda->RxXferCount = 0U;
+ IRDA_EndRxTransfer(hirda);
+ }
+
+ hirda->ErrorCode |= HAL_IRDA_ERROR_DMA;
+
+ HAL_IRDA_ErrorCallback(hirda);
+}
+
+/**
+ * @brief This function handles IRDA Communication Timeout.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @param Flag: specifies the IRDA flag to check.
+ * @param Status: The new Flag status (SET or RESET).
+ * @param Tickstart: Tick start value
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
+{
+ /* Wait until flag is set */
+ while((__HAL_IRDA_GET_FLAG(hirda, Flag) ? SET : RESET) == Status)
+ {
+ /* Check for the Timeout */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout))
+ {
+ /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
+ CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
+
+ hirda->gState = HAL_IRDA_STATE_READY;
+ hirda->RxState = HAL_IRDA_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hirda);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief End ongoing Tx transfer on IRDA peripheral (following error detection or Transmit completion).
+ * @param hirda: IRDA handle.
+ * @retval None
+ */
+static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda)
+{
+ /* Disable TXEIE and TCIE interrupts */
+ CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+
+ /* At end of Tx process, restore hirda->gState to Ready */
+ hirda->gState = HAL_IRDA_STATE_READY;
+}
+
+/**
+ * @brief End ongoing Rx transfer on IRDA peripheral (following error detection or Reception completion).
+ * @param hirda: IRDA handle.
+ * @retval None
+ */
+static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda)
+{
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
+
+ /* At end of Rx process, restore hirda->RxState to Ready */
+ hirda->RxState = HAL_IRDA_STATE_READY;
+}
+
+/**
+ * @brief DMA IRDA communication abort callback, when initiated by HAL services on Error
+ * (To be called at end of DMA Abort procedure following error occurrence).
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma)
+{
+ IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ hirda->RxXferCount = 0x00U;
+ hirda->TxXferCount = 0x00U;
+
+ HAL_IRDA_ErrorCallback(hirda);
+}
+
+/**
+ * @brief DMA IRDA Tx communication abort callback, when initiated by user
+ * (To be called at end of DMA Tx Abort procedure following user abort request).
+ * @note When this callback is executed, User Abort complete call back is called only if no
+ * Abort still ongoing for Rx DMA Handle.
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ hirda->hdmatx->XferAbortCallback = NULL;
+
+ /* Check if an Abort process is still ongoing */
+ if(hirda->hdmarx != NULL)
+ {
+ if(hirda->hdmarx->XferAbortCallback != NULL)
+ {
+ return;
+ }
+ }
+
+ /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+ hirda->TxXferCount = 0x00U;
+ hirda->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
+
+ /* Restore hirda->gState and hirda->RxState to Ready */
+ hirda->gState = HAL_IRDA_STATE_READY;
+ hirda->RxState = HAL_IRDA_STATE_READY;
+
+ /* Call user Abort complete callback */
+ HAL_IRDA_AbortCpltCallback(hirda);
+}
+
+/**
+ * @brief DMA IRDA Rx communication abort callback, when initiated by user
+ * (To be called at end of DMA Rx Abort procedure following user abort request).
+ * @note When this callback is executed, User Abort complete call back is called only if no
+ * Abort still ongoing for Tx DMA Handle.
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ hirda->hdmarx->XferAbortCallback = NULL;
+
+ /* Check if an Abort process is still ongoing */
+ if(hirda->hdmatx != NULL)
+ {
+ if(hirda->hdmatx->XferAbortCallback != NULL)
+ {
+ return;
+ }
+ }
+
+ /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+ hirda->TxXferCount = 0x00U;
+ hirda->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
+
+ /* Restore hirda->gState and hirda->RxState to Ready */
+ hirda->gState = HAL_IRDA_STATE_READY;
+ hirda->RxState = HAL_IRDA_STATE_READY;
+
+ /* Call user Abort complete callback */
+ HAL_IRDA_AbortCpltCallback(hirda);
+}
+
+/**
+ * @brief DMA IRDA Tx communication abort callback, when initiated by user by a call to
+ * HAL_IRDA_AbortTransmit_IT API (Abort only Tx transfer)
+ * (This callback is executed at end of DMA Tx Abort procedure following user abort request,
+ * and leads to user Tx Abort Complete callback execution).
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ hirda->TxXferCount = 0x00U;
+
+ /* Restore hirda->gState to Ready */
+ hirda->gState = HAL_IRDA_STATE_READY;
+
+ /* Call user Abort complete callback */
+ HAL_IRDA_AbortTransmitCpltCallback(hirda);
+}
+
+/**
+ * @brief DMA IRDA Rx communication abort callback, when initiated by user by a call to
+ * HAL_IRDA_AbortReceive_IT API (Abort only Rx transfer)
+ * (This callback is executed at end of DMA Rx Abort procedure following user abort request,
+ * and leads to user Rx Abort Complete callback execution).
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ hirda->RxXferCount = 0x00U;
+
+ /* Restore hirda->RxState to Ready */
+ hirda->RxState = HAL_IRDA_STATE_READY;
+
+ /* Call user Abort complete callback */
+ HAL_IRDA_AbortReceiveCpltCallback(hirda);
+}
+
+/**
+ * @brief Send an amount of data in non blocking mode.
+ * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda)
+{
+ uint16_t* tmp;
+
+ /* Check that a Tx process is ongoing */
+ if(hirda->gState == HAL_IRDA_STATE_BUSY_TX)
+ {
+ if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
+ {
+ tmp = (uint16_t*) hirda->pTxBuffPtr;
+ hirda->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
+ if(hirda->Init.Parity == IRDA_PARITY_NONE)
+ {
+ hirda->pTxBuffPtr += 2U;
+ }
+ else
+ {
+ hirda->pTxBuffPtr += 1U;
+ }
+ }
+ else
+ {
+ hirda->Instance->DR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0x00FF);
+ }
+
+ if(--hirda->TxXferCount == 0U)
+ {
+ /* Disable the IRDA Transmit Data Register Empty Interrupt */
+ CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TXEIE);
+
+ /* Enable the IRDA Transmit Complete Interrupt */
+ SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
+ }
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Wraps up transmission in non blocking mode.
+ * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda)
+{
+ /* Disable the IRDA Transmit Complete Interrupt */
+ CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
+
+ /* Tx process is ended, restore hirda->gState to Ready */
+ hirda->gState = HAL_IRDA_STATE_READY;
+ HAL_IRDA_TxCpltCallback(hirda);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Receives an amount of data in non blocking mode.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda)
+{
+ uint16_t* tmp;
+ uint16_t uhdata;
+
+ /* Check that a Rx process is ongoing */
+ if(hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
+ {
+ uhdata = (uint16_t) READ_REG(hirda->Instance->DR);
+ if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
+ {
+ tmp = (uint16_t*) hirda->pRxBuffPtr;
+ if(hirda->Init.Parity == IRDA_PARITY_NONE)
+ {
+ *tmp = (uint16_t)(uhdata & (uint16_t)0x01FF);
+ hirda->pRxBuffPtr += 2U;
+ }
+ else
+ {
+ *tmp = (uint16_t)(uhdata & (uint16_t)0x00FF);
+ hirda->pRxBuffPtr += 1U;
+ }
+ }
+ else
+ {
+ if(hirda->Init.Parity == IRDA_PARITY_NONE)
+ {
+ *hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)0x00FF);
+ }
+ else
+ {
+ *hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)0x007F);
+ }
+ }
+
+ if(--hirda->RxXferCount == 0U)
+ {
+ /* Disable the IRDA Data Register not empty Interrupt */
+ __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE);
+
+ /* Disable the IRDA Parity Error Interrupt */
+ __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE);
+
+ /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
+ __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);
+
+ /* Rx process is completed, restore hirda->RxState to Ready */
+ hirda->RxState = HAL_IRDA_STATE_READY;
+ HAL_IRDA_RxCpltCallback(hirda);
+
+ return HAL_OK;
+ }
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Configures the IRDA peripheral.
+ * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
+ * the configuration information for the specified IRDA module.
+ * @retval None
+ */
+static void IRDA_SetConfig(IRDA_HandleTypeDef *hirda)
+{
+ /* Check the parameters */
+ assert_param(IS_IRDA_INSTANCE(hirda->Instance));
+ assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate));
+ assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength));
+ assert_param(IS_IRDA_PARITY(hirda->Init.Parity));
+ assert_param(IS_IRDA_MODE(hirda->Init.Mode));
+ assert_param(IS_IRDA_POWERMODE(hirda->Init.IrDAMode));
+
+ /*-------------------------- USART CR2 Configuration ------------------------*/
+ /* Clear STOP[13:12] bits */
+ CLEAR_BIT(hirda->Instance->CR2, USART_CR2_STOP);
+
+ /*-------------------------- USART CR1 Configuration -----------------------*/
+ /* Clear M, PCE, PS, TE and RE bits */
+ CLEAR_BIT(hirda->Instance->CR1, USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE);
+
+ /* Configure the USART Word Length, Parity and mode:
+ Set the M bits according to hirda->Init.WordLength value
+ Set PCE and PS bits according to hirda->Init.Parity value
+ Set TE and RE bits according to hirda->Init.Mode value */
+ /* Write to USART CR1 */
+ SET_BIT(hirda->Instance->CR1, (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode);
+
+ /*-------------------------- USART CR3 Configuration -----------------------*/
+ /* Clear CTSE and RTSE bits */
+ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_RTSE | USART_CR3_CTSE);
+
+ /*-------------------------- USART BRR Configuration -----------------------*/
+ if(hirda->Instance == USART1)
+ {
+ SET_BIT(hirda->Instance->BRR, IRDA_BRR(HAL_RCC_GetPCLK2Freq(), hirda->Init.BaudRate));
+ }
+ else
+ {
+ SET_BIT(hirda->Instance->BRR, IRDA_BRR(HAL_RCC_GetPCLK1Freq(), hirda->Init.BaudRate));
+ }
+}
+
+/**
+ * @}
+ */
+
+#endif /* HAL_IRDA_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_iwdg.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_iwdg.c
new file mode 100644
index 0000000..79fef5d
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_iwdg.c
@@ -0,0 +1,256 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_iwdg.c
+ * @author MCD Application Team
+ * @brief IWDG HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Independent Watchdog (IWDG) peripheral:
+ * + Initialization and Start functions
+ * + IO operation functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### IWDG Generic features #####
+ ==============================================================================
+ [..]
+ (+) The IWDG can be started by either software or hardware (configurable
+ through option byte).
+
+ (+) The IWDG is clocked by Low-Speed clock (LSI) and thus stays active even
+ if the main clock fails.
+
+ (+) Once the IWDG is started, the LSI is forced ON and both can not be
+ disabled. The counter starts counting down from the reset value (0xFFF).
+ When it reaches the end of count value (0x000) a reset signal is
+ generated (IWDG reset).
+
+ (+) Whenever the key value 0x0000 AAAA is written in the IWDG_KR register,
+ the IWDG_RLR value is reloaded in the counter and the watchdog reset is
+ prevented.
+
+ (+) The IWDG is implemented in the VDD voltage domain that is still functional
+ in STOP and STANDBY mode (IWDG reset can wake-up from STANDBY).
+ IWDGRST flag in RCC_CSR register can be used to inform when an IWDG
+ reset occurs.
+
+ (+) Debug mode : When the microcontroller enters debug mode (core halted),
+ the IWDG counter either continues to work normally or stops, depending
+ on DBG_IWDG_STOP configuration bit in DBG module, accessible through
+ __HAL_DBGMCU_FREEZE_IWDG() and __HAL_DBGMCU_UNFREEZE_IWDG() macros
+
+ [..] Min-max timeout value @32KHz (LSI): ~125us / ~32.7s
+ The IWDG timeout may vary due to LSI frequency dispersion. STM32F1xx
+ devices provide the capability to measure the LSI frequency (LSI clock
+ connected internally to TIM5 CH4 input capture). The measured value
+ can be used to have an IWDG timeout with an acceptable accuracy.
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) Use IWDG using HAL_IWDG_Init() function to :
+ (++) Enable instance by writing Start keyword in IWDG_KEY register. LSI
+ clock is forced ON and IWDG counter starts downcounting.
+ (++) Enable write access to configuration register: IWDG_PR & IWDG_RLR.
+ (++) Configure the IWDG prescaler and counter reload value. This reload
+ value will be loaded in the IWDG counter each time the watchdog is
+ reloaded, then the IWDG will start counting down from this value.
+ (++) wait for status flags to be reset"
+
+ (#) Then the application program must refresh the IWDG counter at regular
+ intervals during normal operation to prevent an MCU reset, using
+ HAL_IWDG_Refresh() function.
+
+ *** IWDG HAL driver macros list ***
+ ====================================
+ [..]
+ Below the list of most used macros in IWDG HAL driver:
+ (+) __HAL_IWDG_START: Enable the IWDG peripheral
+ (+) __HAL_IWDG_RELOAD_COUNTER: Reloads IWDG counter with value defined in
+ the reload register
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_IWDG_MODULE_ENABLED
+/** @defgroup IWDG IWDG
+ * @brief IWDG HAL module driver.
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup IWDG_Private_Defines IWDG Private Defines
+ * @{
+ */
+/* Status register need 5 RC LSI divided by prescaler clock to be updated. With
+ higher prescaler (256), and according to HSI variation, we need to wait at
+ least 6 cycles so 48 ms. */
+#define HAL_IWDG_DEFAULT_TIMEOUT 48U
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/** @addtogroup IWDG_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup IWDG_Exported_Functions_Group1
+ * @brief Initialization and Start functions.
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and Start functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Initialize the IWDG according to the specified parameters in the
+ IWDG_InitTypeDef of associated handle.
+ (+) Once initialization is performed in HAL_IWDG_Init function, Watchdog
+ is reloaded in order to exit function with correct time base.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initialize the IWDG according to the specified parameters in the
+ * IWDG_InitTypeDef and start watchdog. Before exiting function,
+ * watchdog is refreshed in order to have correct time base.
+ * @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains
+ * the configuration information for the specified IWDG module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg)
+{
+ uint32_t tickstart;
+
+ /* Check the IWDG handle allocation */
+ if (hiwdg == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_IWDG_ALL_INSTANCE(hiwdg->Instance));
+ assert_param(IS_IWDG_PRESCALER(hiwdg->Init.Prescaler));
+ assert_param(IS_IWDG_RELOAD(hiwdg->Init.Reload));
+
+ /* Enable IWDG. LSI is turned on automaticaly */
+ __HAL_IWDG_START(hiwdg);
+
+ /* Enable write access to IWDG_PR and IWDG_RLR registers by writing 0x5555 in KR */
+ IWDG_ENABLE_WRITE_ACCESS(hiwdg);
+
+ /* Write to IWDG registers the Prescaler & Reload values to work with */
+ hiwdg->Instance->PR = hiwdg->Init.Prescaler;
+ hiwdg->Instance->RLR = hiwdg->Init.Reload;
+
+ /* Check pending flag, if previous update not done, return timeout */
+ tickstart = HAL_GetTick();
+
+ /* Wait for register to be updated */
+ while (hiwdg->Instance->SR != RESET)
+ {
+ if ((HAL_GetTick() - tickstart) > HAL_IWDG_DEFAULT_TIMEOUT)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Reload IWDG counter with value defined in the reload register */
+ __HAL_IWDG_RELOAD_COUNTER(hiwdg);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @addtogroup IWDG_Exported_Functions_Group2
+ * @brief IO operation functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Refresh the IWDG.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Refresh the IWDG.
+ * @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains
+ * the configuration information for the specified IWDG module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg)
+{
+ /* Reload IWDG counter with value defined in the reload register */
+ __HAL_IWDG_RELOAD_COUNTER(hiwdg);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_IWDG_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_mmc.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_mmc.c
new file mode 100644
index 0000000..2667e18
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_mmc.c
@@ -0,0 +1,2596 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_mmc.c
+ * @author MCD Application Team
+ * @brief MMC card HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Secure Digital (MMC) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ * + MMC card Control functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ This driver implements a high level communication layer for read and write from/to
+ this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by
+ the user in HAL_MMC_MspInit() function (MSP layer).
+ Basically, the MSP layer configuration should be the same as we provide in the
+ examples.
+ You can easily tailor this configuration according to hardware resources.
+
+ [..]
+ This driver is a generic layered driver for SDMMC memories which uses the HAL
+ SDMMC driver functions to interface with MMC and eMMC cards devices.
+ It is used as follows:
+
+ (#)Initialize the SDMMC low level resources by implement the HAL_MMC_MspInit() API:
+ (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE();
+ (##) SDMMC pins configuration for MMC card
+ (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
+ (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init()
+ and according to your pin assignment;
+ (##) DMA Configuration if you need to use DMA process (HAL_MMC_ReadBlocks_DMA()
+ and HAL_MMC_WriteBlocks_DMA() APIs).
+ (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE();
+ (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled.
+ (##) NVIC configuration if you need to use interrupt process when using DMA transfer.
+ (+++) Configure the SDMMC and DMA interrupt priorities using functions
+ HAL_NVIC_SetPriority(); DMA priority is superior to SDMMC's priority
+ (+++) Enable the NVIC DMA and SDMMC IRQs using function HAL_NVIC_EnableIRQ()
+ (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
+ and __HAL_MMC_DISABLE_IT() inside the communication process.
+ (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
+ and __HAL_MMC_CLEAR_IT()
+ (##) NVIC configuration if you need to use interrupt process (HAL_MMC_ReadBlocks_IT()
+ and HAL_MMC_WriteBlocks_IT() APIs).
+ (+++) Configure the SDMMC interrupt priorities using function
+ HAL_NVIC_SetPriority();
+ (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ()
+ (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
+ and __HAL_MMC_DISABLE_IT() inside the communication process.
+ (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
+ and __HAL_MMC_CLEAR_IT()
+ (#) At this stage, you can perform MMC read/write/erase operations after MMC card initialization
+
+
+ *** MMC Card Initialization and configuration ***
+ ================================================
+ [..]
+ To initialize the MMC Card, use the HAL_MMC_Init() function. It Initializes
+ SDMMC IP (STM32 side) and the MMC Card, and put it into StandBy State (Ready for data transfer).
+ This function provide the following operations:
+
+ (#) Initialize the SDMMC peripheral interface with defaullt configuration.
+ The initialization process is done at 400KHz. You can change or adapt
+ this frequency by adjusting the "ClockDiv" field.
+ The MMC Card frequency (SDMMC_CK) is computed as follows:
+
+ SDMMC_CK = SDMMCCLK / (ClockDiv + 2)
+
+ In initialization mode and according to the MMC Card standard,
+ make sure that the SDMMC_CK frequency doesn't exceed 400KHz.
+
+ This phase of initialization is done through SDMMC_Init() and
+ SDMMC_PowerState_ON() SDMMC low level APIs.
+
+ (#) Initialize the MMC card. The API used is HAL_MMC_InitCard().
+ This phase allows the card initialization and identification
+ and check the MMC Card type (Standard Capacity or High Capacity)
+ The initialization flow is compatible with MMC standard.
+
+ This API (HAL_MMC_InitCard()) could be used also to reinitialize the card in case
+ of plug-off plug-in.
+
+ (#) Configure the MMC Card Data transfer frequency. By Default, the card transfer
+ frequency is set to 24MHz. You can change or adapt this frequency by adjusting
+ the "ClockDiv" field.
+ In transfer mode and according to the MMC Card standard, make sure that the
+ SDMMC_CK frequency doesn't exceed 25MHz and 50MHz in High-speed mode switch.
+ To be able to use a frequency higher than 24MHz, you should use the SDMMC
+ peripheral in bypass mode. Refer to the corresponding reference manual
+ for more details.
+
+ (#) Select the corresponding MMC Card according to the address read with the step 2.
+
+ (#) Configure the MMC Card in wide bus mode: 4-bits data.
+
+ *** MMC Card Read operation ***
+ ==============================
+ [..]
+ (+) You can read from MMC card in polling mode by using function HAL_MMC_ReadBlocks().
+ This function allows the read of 512 bytes blocks.
+ You can choose either one block read operation or multiple block read operation
+ by adjusting the "NumberOfBlocks" parameter.
+ After this, you have to ensure that the transfer is done correctly. The check is done
+ through HAL_MMC_GetCardState() function for MMC card state.
+
+ (+) You can read from MMC card in DMA mode by using function HAL_MMC_ReadBlocks_DMA().
+ This function allows the read of 512 bytes blocks.
+ You can choose either one block read operation or multiple block read operation
+ by adjusting the "NumberOfBlocks" parameter.
+ After this, you have to ensure that the transfer is done correctly. The check is done
+ through HAL_MMC_GetCardState() function for MMC card state.
+ You could also check the DMA transfer process through the MMC Rx interrupt event.
+
+ (+) You can read from MMC card in Interrupt mode by using function HAL_MMC_ReadBlocks_IT().
+ This function allows the read of 512 bytes blocks.
+ You can choose either one block read operation or multiple block read operation
+ by adjusting the "NumberOfBlocks" parameter.
+ After this, you have to ensure that the transfer is done correctly. The check is done
+ through HAL_MMC_GetCardState() function for MMC card state.
+ You could also check the IT transfer process through the MMC Rx interrupt event.
+
+ *** MMC Card Write operation ***
+ ===============================
+ [..]
+ (+) You can write to MMC card in polling mode by using function HAL_MMC_WriteBlocks().
+ This function allows the read of 512 bytes blocks.
+ You can choose either one block read operation or multiple block read operation
+ by adjusting the "NumberOfBlocks" parameter.
+ After this, you have to ensure that the transfer is done correctly. The check is done
+ through HAL_MMC_GetCardState() function for MMC card state.
+
+ (+) You can write to MMC card in DMA mode by using function HAL_MMC_WriteBlocks_DMA().
+ This function allows the read of 512 bytes blocks.
+ You can choose either one block read operation or multiple block read operation
+ by adjusting the "NumberOfBlocks" parameter.
+ After this, you have to ensure that the transfer is done correctly. The check is done
+ through HAL_MMC_GetCardState() function for MMC card state.
+ You could also check the DMA transfer process through the MMC Tx interrupt event.
+
+ (+) You can write to MMC card in Interrupt mode by using function HAL_MMC_WriteBlocks_IT().
+ This function allows the read of 512 bytes blocks.
+ You can choose either one block read operation or multiple block read operation
+ by adjusting the "NumberOfBlocks" parameter.
+ After this, you have to ensure that the transfer is done correctly. The check is done
+ through HAL_MMC_GetCardState() function for MMC card state.
+ You could also check the IT transfer process through the MMC Tx interrupt event.
+
+ *** MMC card status ***
+ ======================
+ [..]
+ (+) The MMC Status contains status bits that are related to the MMC Memory
+ Card proprietary features. To get MMC card status use the HAL_MMC_GetCardStatus().
+
+ *** MMC card information ***
+ ===========================
+ [..]
+ (+) To get MMC card information, you can use the function HAL_MMC_GetCardInfo().
+ It returns useful information about the MMC card such as block size, card type,
+ block number ...
+
+ *** MMC card CSD register ***
+ ============================
+ [..]
+ (+) The HAL_MMC_GetCardCSD() API allows to get the parameters of the CSD register.
+ Some of the CSD parameters are useful for card initialization and identification.
+
+ *** MMC card CID register ***
+ ============================
+ [..]
+ (+) The HAL_MMC_GetCardCID() API allows to get the parameters of the CID register.
+ Some of the CID parameters are useful for card initialization and identification.
+
+ *** MMC HAL driver macros list ***
+ ==================================
+ [..]
+ Below the list of most used macros in MMC HAL driver.
+
+ (+) __HAL_MMC_ENABLE : Enable the MMC device
+ (+) __HAL_MMC_DISABLE : Disable the MMC device
+ (+) __HAL_MMC_DMA_ENABLE: Enable the SDMMC DMA transfer
+ (+) __HAL_MMC_DMA_DISABLE: Disable the SDMMC DMA transfer
+ (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt
+ (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt
+ (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not
+ (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags
+
+ [..]
+ (@) You can refer to the MMC HAL driver header file for more useful macros
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup MMC
+ * @{
+ */
+
+#ifdef HAL_MMC_MODULE_ENABLED
+
+#if defined(STM32F103xE) || defined(STM32F103xG)
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @addtogroup MMC_Private_Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup MMC_Private_Functions MMC Private Functions
+ * @{
+ */
+static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc);
+static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc);
+static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus);
+static HAL_StatusTypeDef MMC_PowerOFF(MMC_HandleTypeDef *hmmc);
+static HAL_StatusTypeDef MMC_Write_IT(MMC_HandleTypeDef *hmmc);
+static HAL_StatusTypeDef MMC_Read_IT(MMC_HandleTypeDef *hmmc);
+static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma);
+static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
+static void MMC_DMAError(DMA_HandleTypeDef *hdma);
+static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma);
+static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma);
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup MMC_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup MMC_Exported_Functions_Group1
+ * @brief Initialization and de-initialization functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de-initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to initialize/de-initialize the MMC
+ card device to be ready for use.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the MMC according to the specified parameters in the
+ MMC_HandleTypeDef and create the associated handle.
+ * @param hmmc: Pointer to the MMC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc)
+{
+ /* Check the MMC handle allocation */
+ if(hmmc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_SDIO_ALL_INSTANCE(hmmc->Instance));
+ assert_param(IS_SDIO_CLOCK_EDGE(hmmc->Init.ClockEdge));
+ assert_param(IS_SDIO_CLOCK_BYPASS(hmmc->Init.ClockBypass));
+ assert_param(IS_SDIO_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave));
+ assert_param(IS_SDIO_BUS_WIDE(hmmc->Init.BusWide));
+ assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl));
+ assert_param(IS_SDIO_CLKDIV(hmmc->Init.ClockDiv));
+
+ if(hmmc->State == HAL_MMC_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hmmc->Lock = HAL_UNLOCKED;
+ /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
+ HAL_MMC_MspInit(hmmc);
+ }
+
+ hmmc->State = HAL_MMC_STATE_BUSY;
+
+ /* Initialize the Card parameters */
+ HAL_MMC_InitCard(hmmc);
+
+ /* Initialize the error code */
+ hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ /* Initialize the MMC operation */
+ hmmc->Context = MMC_CONTEXT_NONE;
+
+ /* Initialize the MMC state */
+ hmmc->State = HAL_MMC_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the MMC Card.
+ * @param hmmc: Pointer to MMC handle
+ * @note This function initializes the MMC card. It could be used when a card
+ re-initialization is needed.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc)
+{
+ uint32_t errorstate = HAL_MMC_ERROR_NONE;
+ MMC_InitTypeDef Init;
+
+ /* Default SDMMC peripheral configuration for MMC card initialization */
+ Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
+ Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
+ Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
+ Init.BusWide = SDIO_BUS_WIDE_1B;
+ Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
+ Init.ClockDiv = SDIO_INIT_CLK_DIV;
+
+ /* Initialize SDMMC peripheral interface with default configuration */
+ SDIO_Init(hmmc->Instance, Init);
+
+ /* Disable SDMMC Clock */
+ __HAL_MMC_DISABLE(hmmc);
+
+ /* Set Power State to ON */
+ SDIO_PowerState_ON(hmmc->Instance);
+
+ /* Enable SDMMC Clock */
+ __HAL_MMC_ENABLE(hmmc);
+
+ /* Required power up waiting time before starting the SD initialization
+ sequence */
+ HAL_Delay(2U);
+
+ /* Identify card operating voltage */
+ errorstate = MMC_PowerON(hmmc);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ hmmc->State = HAL_MMC_STATE_READY;
+ hmmc->ErrorCode |= errorstate;
+ return HAL_ERROR;
+ }
+
+ /* Card initialization */
+ errorstate = MMC_InitCard(hmmc);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ hmmc->State = HAL_MMC_STATE_READY;
+ hmmc->ErrorCode |= errorstate;
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief De-Initializes the MMC card.
+ * @param hmmc: Pointer to MMC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc)
+{
+ /* Check the MMC handle allocation */
+ if(hmmc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_SDIO_ALL_INSTANCE(hmmc->Instance));
+
+ hmmc->State = HAL_MMC_STATE_BUSY;
+
+ /* Set SD power state to off */
+ MMC_PowerOFF(hmmc);
+
+ /* De-Initialize the MSP layer */
+ HAL_MMC_MspDeInit(hmmc);
+
+ hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
+ hmmc->State = HAL_MMC_STATE_RESET;
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Initializes the MMC MSP.
+ * @param hmmc: Pointer to MMC handle
+ * @retval None
+ */
+__weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hmmc);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_MMC_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief De-Initialize MMC MSP.
+ * @param hmmc: Pointer to MMC handle
+ * @retval None
+ */
+__weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hmmc);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_MMC_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @addtogroup MMC_Exported_Functions_Group2
+ * @brief Data transfer functions
+ *
+@verbatim
+ ==============================================================================
+ ##### IO operation functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the data
+ transfer from/to MMC card.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Reads block(s) from a specified address in a card. The Data transfer
+ * is managed by polling mode.
+ * @note This API should be followed by a check on the card state through
+ * HAL_MMC_GetCardState().
+ * @param hmmc: Pointer to MMC handle
+ * @param pData: pointer to the buffer that will contain the received data
+ * @param BlockAdd: Block Address from where data is to be read
+ * @param NumberOfBlocks: Number of MMC blocks to read
+ * @param Timeout: Specify timeout value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
+{
+ SDIO_DataInitTypeDef config;
+ uint32_t errorstate = HAL_MMC_ERROR_NONE;
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t count = 0U, *tempbuff = (uint32_t *)pData;
+
+ if(NULL == pData)
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
+ return HAL_ERROR;
+ }
+
+ if(hmmc->State == HAL_MMC_STATE_READY)
+ {
+ hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
+ return HAL_ERROR;
+ }
+
+ hmmc->State = HAL_MMC_STATE_BUSY;
+
+ /* Initialize data control register */
+ hmmc->Instance->DCTRL = 0U;
+
+ /* Check the Card capacity in term of Logical number of blocks */
+ if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
+ {
+ BlockAdd *= 512U;
+ }
+
+ /* Set Block Size for Card */
+ errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Configure the MMC DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = NumberOfBlocks * BLOCKSIZE;
+ config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
+ config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_ConfigData(hmmc->Instance, &config);
+
+ /* Read block(s) in polling mode */
+ if(NumberOfBlocks > 1U)
+ {
+ hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
+
+ /* Read Multi Block command */
+ errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd);
+ }
+ else
+ {
+ hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK;
+
+ /* Read Single Block command */
+ errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd);
+ }
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Poll on SDMMC flags */
+#ifdef SDIO_STA_STBITERR
+ while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_STA_STBITERR))
+#else /* SDIO_STA_STBITERR not defined */
+ while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
+#endif /* SDIO_STA_STBITERR */
+ {
+ if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF))
+ {
+ /* Read data from SDMMC Rx FIFO */
+ for(count = 0U; count < 8U; count++)
+ {
+ *(tempbuff + count) = SDIO_ReadFIFO(hmmc->Instance);
+ }
+ tempbuff += 8U;
+ }
+
+ if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
+ hmmc->State= HAL_MMC_STATE_READY;
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Send stop transmission command in case of multiblock read */
+ if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
+ {
+ /* Send stop transmission command */
+ errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ }
+
+ /* Get error state */
+ if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Empty FIFO if there is still any data */
+ while ((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXDAVL)))
+ {
+ *tempbuff = SDIO_ReadFIFO(hmmc->Instance);
+ tempbuff++;
+
+ if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
+ hmmc->State= HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ }
+
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+
+ hmmc->State = HAL_MMC_STATE_READY;
+
+ return HAL_OK;
+ }
+ else
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Allows to write block(s) to a specified address in a card. The Data
+ * transfer is managed by polling mode.
+ * @note This API should be followed by a check on the card state through
+ * HAL_MMC_GetCardState().
+ * @param hmmc: Pointer to MMC handle
+ * @param pData: pointer to the buffer that will contain the data to transmit
+ * @param BlockAdd: Block Address where data will be written
+ * @param NumberOfBlocks: Number of MMC blocks to write
+ * @param Timeout: Specify timeout value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
+{
+ SDIO_DataInitTypeDef config;
+ uint32_t errorstate = HAL_MMC_ERROR_NONE;
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t count = 0U;
+ uint32_t *tempbuff = (uint32_t *)pData;
+
+ if(NULL == pData)
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
+ return HAL_ERROR;
+ }
+
+ if(hmmc->State == HAL_MMC_STATE_READY)
+ {
+ hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
+ return HAL_ERROR;
+ }
+
+ hmmc->State = HAL_MMC_STATE_BUSY;
+
+ /* Initialize data control register */
+ hmmc->Instance->DCTRL = 0U;
+
+ /* Check the Card capacity in term of Logical number of blocks */
+ if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
+ {
+ BlockAdd *= 512U;
+ }
+
+ /* Set Block Size for Card */
+ errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Write Blocks in Polling mode */
+ if(NumberOfBlocks > 1U)
+ {
+ hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
+
+ /* Write Multi Block command */
+ errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd);
+ }
+ else
+ {
+ hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
+
+ /* Write Single Block command */
+ errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd);
+ }
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Configure the MMC DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = NumberOfBlocks * BLOCKSIZE;
+ config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
+ config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_ConfigData(hmmc->Instance, &config);
+
+ /* Write block(s) in polling mode */
+#ifdef SDIO_STA_STBITERR
+ while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
+#else /* SDIO_STA_STBITERR not defined */
+ while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
+#endif /* SDIO_STA_STBITERR */
+ {
+ if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXFIFOHE))
+ {
+ /* Write data to SDIO Tx FIFO */
+ for(count = 0U; count < 8U; count++)
+ {
+ SDIO_WriteFIFO(hmmc->Instance, (tempbuff + count));
+ }
+ tempbuff += 8U;
+ }
+
+ if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Send stop transmission command in case of multiblock write */
+ if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
+ {
+ /* Send stop transmission command */
+ errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ }
+
+ /* Get error state */
+ if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR))
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+
+ hmmc->State = HAL_MMC_STATE_READY;
+
+ return HAL_OK;
+ }
+ else
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Reads block(s) from a specified address in a card. The Data transfer
+ * is managed in interrupt mode.
+ * @note This API should be followed by a check on the card state through
+ * HAL_MMC_GetCardState().
+ * @note You could also check the IT transfer process through the MMC Rx
+ * interrupt event.
+ * @param hmmc: Pointer to MMC handle
+ * @param pData: Pointer to the buffer that will contain the received data
+ * @param BlockAdd: Block Address from where data is to be read
+ * @param NumberOfBlocks: Number of blocks to read.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
+{
+ SDIO_DataInitTypeDef config;
+ uint32_t errorstate = HAL_MMC_ERROR_NONE;
+
+ if(NULL == pData)
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
+ return HAL_ERROR;
+ }
+
+ if(hmmc->State == HAL_MMC_STATE_READY)
+ {
+ hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
+ return HAL_ERROR;
+ }
+
+ hmmc->State = HAL_MMC_STATE_BUSY;
+
+ /* Initialize data control register */
+ hmmc->Instance->DCTRL = 0U;
+
+ hmmc->pRxBuffPtr = (uint32_t *)pData;
+ hmmc->RxXferSize = BLOCKSIZE * NumberOfBlocks;
+
+ __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF));
+
+ /* Check the Card capacity in term of Logical number of blocks */
+ if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
+ {
+ BlockAdd *= 512U;
+ }
+
+ /* Configure the MMC DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = BLOCKSIZE * NumberOfBlocks;
+ config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
+ config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_ConfigData(hmmc->Instance, &config);
+
+ /* Set Block Size for Card */
+ errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Read Blocks in IT mode */
+ if(NumberOfBlocks > 1U)
+ {
+ hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
+
+ /* Read Multi Block command */
+ errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd);
+ }
+ else
+ {
+ hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
+
+ /* Read Single Block command */
+ errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd);
+ }
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Writes block(s) to a specified address in a card. The Data transfer
+ * is managed in interrupt mode.
+ * @note This API should be followed by a check on the card state through
+ * HAL_MMC_GetCardState().
+ * @note You could also check the IT transfer process through the MMC Tx
+ * interrupt event.
+ * @param hmmc: Pointer to MMC handle
+ * @param pData: Pointer to the buffer that will contain the data to transmit
+ * @param BlockAdd: Block Address where data will be written
+ * @param NumberOfBlocks: Number of blocks to write
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
+{
+ SDIO_DataInitTypeDef config;
+ uint32_t errorstate = HAL_MMC_ERROR_NONE;
+
+ if(NULL == pData)
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
+ return HAL_ERROR;
+ }
+
+ if(hmmc->State == HAL_MMC_STATE_READY)
+ {
+ hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
+ return HAL_ERROR;
+ }
+
+ hmmc->State = HAL_MMC_STATE_BUSY;
+
+ /* Initialize data control register */
+ hmmc->Instance->DCTRL = 0U;
+
+ hmmc->pTxBuffPtr = (uint32_t *)pData;
+ hmmc->TxXferSize = BLOCKSIZE * NumberOfBlocks;
+
+ /* Enable transfer interrupts */
+ __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE));
+
+ /* Check the Card capacity in term of Logical number of blocks */
+ if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
+ {
+ BlockAdd *= 512U;
+ }
+
+ /* Set Block Size for Card */
+ errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Write Blocks in Polling mode */
+ if(NumberOfBlocks > 1U)
+ {
+ hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK| MMC_CONTEXT_IT);
+
+ /* Write Multi Block command */
+ errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd);
+ }
+ else
+ {
+ hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
+
+ /* Write Single Block command */
+ errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd);
+ }
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Configure the MMC DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = BLOCKSIZE * NumberOfBlocks;
+ config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
+ config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_ConfigData(hmmc->Instance, &config);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Reads block(s) from a specified address in a card. The Data transfer
+ * is managed by DMA mode.
+ * @note This API should be followed by a check on the card state through
+ * HAL_MMC_GetCardState().
+ * @note You could also check the DMA transfer process through the MMC Rx
+ * interrupt event.
+ * @param hmmc: Pointer MMC handle
+ * @param pData: Pointer to the buffer that will contain the received data
+ * @param BlockAdd: Block Address from where data is to be read
+ * @param NumberOfBlocks: Number of blocks to read.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
+{
+ SDIO_DataInitTypeDef config;
+ uint32_t errorstate = HAL_MMC_ERROR_NONE;
+
+ if(NULL == pData)
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
+ return HAL_ERROR;
+ }
+
+ if(hmmc->State == HAL_MMC_STATE_READY)
+ {
+ hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
+ return HAL_ERROR;
+ }
+
+ hmmc->State = HAL_MMC_STATE_BUSY;
+
+ /* Initialize data control register */
+ hmmc->Instance->DCTRL = 0U;
+
+#ifdef SDIO_STA_STBITER
+ __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_IT_STBITERR));
+#else /* SDIO_STA_STBITERR not defined */
+ __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
+#endif /* SDIO_STA_STBITERR */
+
+ /* Set the DMA transfer complete callback */
+ hmmc->hdmarx->XferCpltCallback = MMC_DMAReceiveCplt;
+
+ /* Set the DMA error callback */
+ hmmc->hdmarx->XferErrorCallback = MMC_DMAError;
+
+ /* Set the DMA Abort callback */
+ hmmc->hdmarx->XferAbortCallback = NULL;
+
+ /* Enable the DMA Channel */
+ HAL_DMA_Start_IT(hmmc->hdmarx, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)pData, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4);
+
+ /* Enable MMC DMA transfer */
+ __HAL_MMC_DMA_ENABLE(hmmc);
+
+ /* Check the Card capacity in term of Logical number of blocks */
+ if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
+ {
+ BlockAdd *= 512U;
+ }
+
+ /* Configure the MMC DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = BLOCKSIZE * NumberOfBlocks;
+ config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
+ config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_ConfigData(hmmc->Instance, &config);
+
+ /* Set Block Size for Card */
+ errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Read Blocks in DMA mode */
+ if(NumberOfBlocks > 1U)
+ {
+ hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
+
+ /* Read Multi Block command */
+ errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd);
+ }
+ else
+ {
+ hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
+
+ /* Read Single Block command */
+ errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd);
+ }
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Writes block(s) to a specified address in a card. The Data transfer
+ * is managed by DMA mode.
+ * @note This API should be followed by a check on the card state through
+ * HAL_MMC_GetCardState().
+ * @note You could also check the DMA transfer process through the MMC Tx
+ * interrupt event.
+ * @param hmmc: Pointer to MMC handle
+ * @param pData: Pointer to the buffer that will contain the data to transmit
+ * @param BlockAdd: Block Address where data will be written
+ * @param NumberOfBlocks: Number of blocks to write
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
+{
+ SDIO_DataInitTypeDef config;
+ uint32_t errorstate = HAL_MMC_ERROR_NONE;
+
+ if(NULL == pData)
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
+ return HAL_ERROR;
+ }
+
+ if(hmmc->State == HAL_MMC_STATE_READY)
+ {
+ hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
+ return HAL_ERROR;
+ }
+
+ hmmc->State = HAL_MMC_STATE_BUSY;
+
+ /* Initialize data control register */
+ hmmc->Instance->DCTRL = 0U;
+
+ /* Enable MMC Error interrupts */
+#ifdef SDIO_STA_STBITER
+ __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR));
+#else /* SDIO_STA_STBITERR not defined */
+ __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR));
+#endif /* SDIO_STA_STBITERR */
+
+ /* Set the DMA transfer complete callback */
+ hmmc->hdmatx->XferCpltCallback = MMC_DMATransmitCplt;
+
+ /* Set the DMA error callback */
+ hmmc->hdmatx->XferErrorCallback = MMC_DMAError;
+
+ /* Set the DMA Abort callback */
+ hmmc->hdmatx->XferAbortCallback = NULL;
+
+ /* Check the Card capacity in term of Logical number of blocks */
+ if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
+ {
+ BlockAdd *= 512U;
+ }
+
+ /* Set Block Size for Card */
+ errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Write Blocks in Polling mode */
+ if(NumberOfBlocks > 1U)
+ {
+ hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
+
+ /* Write Multi Block command */
+ errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd);
+ }
+ else
+ {
+ hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
+
+ /* Write Single Block command */
+ errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd);
+ }
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Enable SDIO DMA transfer */
+ __HAL_MMC_DMA_ENABLE(hmmc);
+
+ /* Enable the DMA Channel */
+ HAL_DMA_Start_IT(hmmc->hdmatx, (uint32_t)pData, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4);
+
+ /* Configure the MMC DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = BLOCKSIZE * NumberOfBlocks;
+ config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
+ config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_ConfigData(hmmc->Instance, &config);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Erases the specified memory area of the given MMC card.
+ * @note This API should be followed by a check on the card state through
+ * HAL_MMC_GetCardState().
+ * @param hmmc: Pointer to MMC handle
+ * @param BlockStartAdd: Start Block address
+ * @param BlockEndAdd: End Block address
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
+{
+ uint32_t errorstate = HAL_MMC_ERROR_NONE;
+
+ if(hmmc->State == HAL_MMC_STATE_READY)
+ {
+ hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ if(BlockEndAdd < BlockStartAdd)
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
+ return HAL_ERROR;
+ }
+
+ if(BlockEndAdd > (hmmc->MmcCard.LogBlockNbr))
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
+ return HAL_ERROR;
+ }
+
+ hmmc->State = HAL_MMC_STATE_BUSY;
+
+ /* Check if the card command class supports erase command */
+ if(((hmmc->MmcCard.Class) & SDIO_CCCC_ERASE) == 0U)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ if((SDIO_GetResponse(hmmc->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Check the Card capacity in term of Logical number of blocks */
+ if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
+ {
+ BlockStartAdd *= 512U;
+ BlockEndAdd *= 512U;
+ }
+
+ /* Send CMD35 MMC_ERASE_GRP_START with argument as addr */
+ errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, BlockStartAdd);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Send CMD36 MMC_ERASE_GRP_END with argument as addr */
+ errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, BlockEndAdd);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Send CMD38 ERASE */
+ errorstate = SDMMC_CmdErase(hmmc->Instance);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->ErrorCode |= errorstate;
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ hmmc->State = HAL_MMC_STATE_READY;
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief This function handles MMC card interrupt request.
+ * @param hmmc: Pointer to MMC handle
+ * @retval None
+ */
+void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
+{
+ uint32_t errorstate = HAL_MMC_ERROR_NONE;
+
+ /* Check for SDIO interrupt flags */
+ if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DATAEND) != RESET)
+ {
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_DATAEND);
+
+#ifdef SDIO_STA_STBITERR
+ __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
+ SDIO_IT_TXUNDERR | SDIO_IT_RXOVERR | SDIO_IT_STBITERR);
+#else /* SDIO_STA_STBITERR not defined */
+ __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
+ SDIO_IT_TXUNDERR | SDIO_IT_RXOVERR);
+#endif
+
+ if((hmmc->Context & MMC_CONTEXT_IT) != RESET)
+ {
+ if(((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != RESET) || ((hmmc->Context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != RESET))
+ {
+ errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ hmmc->ErrorCode |= errorstate;
+ HAL_MMC_ErrorCallback(hmmc);
+ }
+ }
+
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+
+ hmmc->State = HAL_MMC_STATE_READY;
+ if(((hmmc->Context & MMC_CONTEXT_READ_SINGLE_BLOCK) != RESET) || ((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != RESET))
+ {
+ HAL_MMC_RxCpltCallback(hmmc);
+ }
+ else
+ {
+ HAL_MMC_TxCpltCallback(hmmc);
+ }
+ }
+ else if((hmmc->Context & MMC_CONTEXT_DMA) != RESET)
+ {
+ if((hmmc->Context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != RESET)
+ {
+ errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ hmmc->ErrorCode |= errorstate;
+ HAL_MMC_ErrorCallback(hmmc);
+ }
+ }
+ if(((hmmc->Context & MMC_CONTEXT_READ_SINGLE_BLOCK) == RESET) && ((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) == RESET))
+ {
+ /* Disable the DMA transfer for transmit request by setting the DMAEN bit
+ in the MMC DCTRL register */
+ hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
+
+ hmmc->State = HAL_MMC_STATE_READY;
+
+ HAL_MMC_TxCpltCallback(hmmc);
+ }
+ }
+ }
+
+ else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_TXFIFOHE) != RESET)
+ {
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_TXFIFOHE);
+
+ MMC_Write_IT(hmmc);
+ }
+
+ else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_RXFIFOHF) != RESET)
+ {
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_RXFIFOHF);
+
+ MMC_Read_IT(hmmc);
+ }
+
+#ifdef SDIO_STA_STBITERR
+ else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR) != RESET)
+ {
+ /* Set Error code */
+ if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL) != RESET)
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
+ }
+ if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DTIMEOUT) != RESET)
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
+ }
+ if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_RXOVERR) != RESET)
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
+ }
+ if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_TXUNDERR) != RESET)
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
+ }
+ if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_STBITERR) != RESET)
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
+ }
+
+ /* Clear All flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS | SDIO_FLAG_STBITERR);
+
+ /* Disable all interrupts */
+ __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
+ SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR |SDIO_IT_STBITERR);
+
+ if((hmmc->Context & MMC_CONTEXT_DMA) != RESET)
+ {
+ /* Abort the MMC DMA Streams */
+ if(hmmc->hdmatx != NULL)
+ {
+ /* Set the DMA Tx abort callback */
+ hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
+ /* Abort DMA in IT mode */
+ if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
+ {
+ MMC_DMATxAbort(hmmc->hdmatx);
+ }
+ }
+ else if(hmmc->hdmarx != NULL)
+ {
+ /* Set the DMA Rx abort callback */
+ hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
+ /* Abort DMA in IT mode */
+ if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
+ {
+ MMC_DMARxAbort(hmmc->hdmarx);
+ }
+ }
+ else
+ {
+ hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
+ hmmc->State = HAL_MMC_STATE_READY;
+ HAL_MMC_AbortCallback(hmmc);
+ }
+ }
+ else if((hmmc->Context & MMC_CONTEXT_IT) != RESET)
+ {
+ /* Set the MMC state to ready to be able to start again the process */
+ hmmc->State = HAL_MMC_STATE_READY;
+ HAL_MMC_ErrorCallback(hmmc);
+ }
+ }
+#else /* SDIO_STA_STBITERR not defined */
+ else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_TXUNDERR) != RESET)
+ {
+ /* Set Error code */
+ if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL) != RESET)
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
+ }
+ if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DTIMEOUT) != RESET)
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
+ }
+ if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_RXOVERR) != RESET)
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
+ }
+ if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_TXUNDERR) != RESET)
+ {
+ hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
+ }
+
+ /* Clear All flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+
+ /* Disable all interrupts */
+ __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
+ SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
+
+ if((hmmc->Context & MMC_CONTEXT_DMA) != RESET)
+ {
+ /* Abort the MMC DMA Streams */
+ if(hmmc->hdmatx != NULL)
+ {
+ /* Set the DMA Tx abort callback */
+ hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
+ /* Abort DMA in IT mode */
+ if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
+ {
+ MMC_DMATxAbort(hmmc->hdmatx);
+ }
+ }
+ else if(hmmc->hdmarx != NULL)
+ {
+ /* Set the DMA Rx abort callback */
+ hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
+ /* Abort DMA in IT mode */
+ if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
+ {
+ MMC_DMARxAbort(hmmc->hdmarx);
+ }
+ }
+ else
+ {
+ hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
+ hmmc->State = HAL_MMC_STATE_READY;
+ HAL_MMC_AbortCallback(hmmc);
+ }
+ }
+ else if((hmmc->Context & MMC_CONTEXT_IT) != RESET)
+ {
+ /* Set the MMC state to ready to be able to start again the process */
+ hmmc->State = HAL_MMC_STATE_READY;
+ HAL_MMC_ErrorCallback(hmmc);
+ }
+ }
+#endif /* SDIO_STA_STBITERR */
+}
+
+/**
+ * @brief return the MMC state
+ * @param hmmc: Pointer to mmc handle
+ * @retval HAL state
+ */
+HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc)
+{
+ return hmmc->State;
+}
+
+/**
+* @brief Return the MMC error code
+* @param hmmc : Pointer to a MMC_HandleTypeDef structure that contains
+ * the configuration information.
+* @retval MMC Error Code
+*/
+uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc)
+{
+ return hmmc->ErrorCode;
+}
+
+/**
+ * @brief Tx Transfer completed callbacks
+ * @param hmmc: Pointer to MMC handle
+ * @retval None
+ */
+ __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hmmc);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_MMC_TxCpltCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer completed callbacks
+ * @param hmmc: Pointer MMC handle
+ * @retval None
+ */
+__weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hmmc);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_MMC_RxCpltCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief MMC error callbacks
+ * @param hmmc: Pointer MMC handle
+ * @retval None
+ */
+__weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hmmc);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_MMC_ErrorCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief MMC Abort callbacks
+ * @param hmmc: Pointer MMC handle
+ * @retval None
+ */
+__weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hmmc);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_MMC_ErrorCallback can be implemented in the user file
+ */
+}
+
+
+/**
+ * @}
+ */
+
+/** @addtogroup MMC_Exported_Functions_Group3
+ * @brief management functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the MMC card
+ operations and get the related information
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns information the information of the card which are stored on
+ * the CID register.
+ * @param hmmc: Pointer to MMC handle
+ * @param pCID: Pointer to a HAL_MMC_CIDTypedef structure that
+ * contains all CID register parameters
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
+{
+ uint32_t tmp = 0U;
+
+ /* Byte 0 */
+ tmp = (uint8_t)((hmmc->CID[0U] & 0xFF000000U) >> 24U);
+ pCID->ManufacturerID = tmp;
+
+ /* Byte 1 */
+ tmp = (uint8_t)((hmmc->CID[0U] & 0x00FF0000U) >> 16U);
+ pCID->OEM_AppliID = tmp << 8U;
+
+ /* Byte 2 */
+ tmp = (uint8_t)((hmmc->CID[0U] & 0x000000FF00U) >> 8U);
+ pCID->OEM_AppliID |= tmp;
+
+ /* Byte 3 */
+ tmp = (uint8_t)(hmmc->CID[0U] & 0x000000FFU);
+ pCID->ProdName1 = tmp << 24U;
+
+ /* Byte 4 */
+ tmp = (uint8_t)((hmmc->CID[1U] & 0xFF000000U) >> 24U);
+ pCID->ProdName1 |= tmp << 16U;
+
+ /* Byte 5 */
+ tmp = (uint8_t)((hmmc->CID[1U] & 0x00FF0000U) >> 16U);
+ pCID->ProdName1 |= tmp << 8U;
+
+ /* Byte 6 */
+ tmp = (uint8_t)((hmmc->CID[1U] & 0x0000FF00U) >> 8U);
+ pCID->ProdName1 |= tmp;
+
+ /* Byte 7 */
+ tmp = (uint8_t)(hmmc->CID[1U] & 0x000000FFU);
+ pCID->ProdName2 = tmp;
+
+ /* Byte 8 */
+ tmp = (uint8_t)((hmmc->CID[2U] & 0xFF000000U) >> 24U);
+ pCID->ProdRev = tmp;
+
+ /* Byte 9 */
+ tmp = (uint8_t)((hmmc->CID[2U] & 0x00FF0000U) >> 16U);
+ pCID->ProdSN = tmp << 24U;
+
+ /* Byte 10 */
+ tmp = (uint8_t)((hmmc->CID[2U] & 0x0000FF00U) >> 8U);
+ pCID->ProdSN |= tmp << 16U;
+
+ /* Byte 11 */
+ tmp = (uint8_t)(hmmc->CID[2U] & 0x000000FFU);
+ pCID->ProdSN |= tmp << 8U;
+
+ /* Byte 12 */
+ tmp = (uint8_t)((hmmc->CID[3U] & 0xFF000000U) >> 24U);
+ pCID->ProdSN |= tmp;
+
+ /* Byte 13 */
+ tmp = (uint8_t)((hmmc->CID[3U] & 0x00FF0000U) >> 16U);
+ pCID->Reserved1 |= (tmp & 0xF0U) >> 4U;
+ pCID->ManufactDate = (tmp & 0x0FU) << 8U;
+
+ /* Byte 14 */
+ tmp = (uint8_t)((hmmc->CID[3U] & 0x0000FF00U) >> 8U);
+ pCID->ManufactDate |= tmp;
+
+ /* Byte 15 */
+ tmp = (uint8_t)(hmmc->CID[3U] & 0x000000FFU);
+ pCID->CID_CRC = (tmp & 0xFEU) >> 1U;
+ pCID->Reserved2 = 1U;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Returns information the information of the card which are stored on
+ * the CSD register.
+ * @param hmmc: Pointer to MMC handle
+ * @param pCSD: Pointer to a HAL_MMC_CardInfoTypeDef structure that
+ * contains all CSD register parameters
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
+{
+ uint32_t tmp = 0U;
+
+ /* Byte 0 */
+ tmp = (hmmc->CSD[0U] & 0xFF000000U) >> 24U;
+ pCSD->CSDStruct = (uint8_t)((tmp & 0xC0U) >> 6U);
+ pCSD->SysSpecVersion = (uint8_t)((tmp & 0x3CU) >> 2U);
+ pCSD->Reserved1 = tmp & 0x03U;
+
+ /* Byte 1 */
+ tmp = (hmmc->CSD[0U] & 0x00FF0000U) >> 16U;
+ pCSD->TAAC = (uint8_t)tmp;
+
+ /* Byte 2 */
+ tmp = (hmmc->CSD[0U] & 0x0000FF00U) >> 8U;
+ pCSD->NSAC = (uint8_t)tmp;
+
+ /* Byte 3 */
+ tmp = hmmc->CSD[0U] & 0x000000FFU;
+ pCSD->MaxBusClkFrec = (uint8_t)tmp;
+
+ /* Byte 4 */
+ tmp = (hmmc->CSD[1U] & 0xFF000000U) >> 24U;
+ pCSD->CardComdClasses = (uint16_t)(tmp << 4U);
+
+ /* Byte 5 */
+ tmp = (hmmc->CSD[1U] & 0x00FF0000U) >> 16U;
+ pCSD->CardComdClasses |= (uint16_t)((tmp & 0xF0U) >> 4U);
+ pCSD->RdBlockLen = (uint8_t)(tmp & 0x0FU);
+
+ /* Byte 6 */
+ tmp = (hmmc->CSD[1U] & 0x0000FF00U) >> 8U;
+ pCSD->PartBlockRead = (uint8_t)((tmp & 0x80U) >> 7U);
+ pCSD->WrBlockMisalign = (uint8_t)((tmp & 0x40U) >> 6U);
+ pCSD->RdBlockMisalign = (uint8_t)((tmp & 0x20U) >> 5U);
+ pCSD->DSRImpl = (uint8_t)((tmp & 0x10U) >> 4U);
+ pCSD->Reserved2 = 0; /*!< Reserved */
+
+ pCSD->DeviceSize = (tmp & 0x03U) << 10U;
+
+ /* Byte 7 */
+ tmp = (uint8_t)(hmmc->CSD[1U] & 0x000000FFU);
+ pCSD->DeviceSize |= (tmp) << 2U;
+
+ /* Byte 8 */
+ tmp = (uint8_t)((hmmc->CSD[2U] & 0xFF000000U) >> 24U);
+ pCSD->DeviceSize |= (tmp & 0xC0U) >> 6U;
+
+ pCSD->MaxRdCurrentVDDMin = (tmp & 0x38U) >> 3U;
+ pCSD->MaxRdCurrentVDDMax = (tmp & 0x07U);
+
+ /* Byte 9 */
+ tmp = (uint8_t)((hmmc->CSD[2U] & 0x00FF0000U) >> 16U);
+ pCSD->MaxWrCurrentVDDMin = (tmp & 0xE0U) >> 5U;
+ pCSD->MaxWrCurrentVDDMax = (tmp & 0x1CU) >> 2U;
+ pCSD->DeviceSizeMul = (tmp & 0x03U) << 1U;
+ /* Byte 10 */
+ tmp = (uint8_t)((hmmc->CSD[2] & 0x0000FF00U) >> 8U);
+ pCSD->DeviceSizeMul |= (tmp & 0x80U) >> 7U;
+
+ hmmc->MmcCard.BlockNbr = (pCSD->DeviceSize + 1U) ;
+ hmmc->MmcCard.BlockNbr *= (1U << (pCSD->DeviceSizeMul + 2U));
+ hmmc->MmcCard.BlockSize = 1U << (pCSD->RdBlockLen);
+
+ hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U);
+ hmmc->MmcCard.LogBlockSize = 512U;
+
+ pCSD->EraseGrSize = (tmp & 0x40U) >> 6U;
+ pCSD->EraseGrMul = (tmp & 0x3FU) << 1U;
+
+ /* Byte 11 */
+ tmp = (uint8_t)(hmmc->CSD[2U] & 0x000000FFU);
+ pCSD->EraseGrMul |= (tmp & 0x80U) >> 7U;
+ pCSD->WrProtectGrSize = (tmp & 0x7FU);
+
+ /* Byte 12 */
+ tmp = (uint8_t)((hmmc->CSD[3U] & 0xFF000000U) >> 24U);
+ pCSD->WrProtectGrEnable = (tmp & 0x80U) >> 7U;
+ pCSD->ManDeflECC = (tmp & 0x60U) >> 5U;
+ pCSD->WrSpeedFact = (tmp & 0x1CU) >> 2U;
+ pCSD->MaxWrBlockLen = (tmp & 0x03U) << 2U;
+
+ /* Byte 13 */
+ tmp = (uint8_t)((hmmc->CSD[3U] & 0x00FF0000U) >> 16U);
+ pCSD->MaxWrBlockLen |= (tmp & 0xC0U) >> 6U;
+ pCSD->WriteBlockPaPartial = (tmp & 0x20U) >> 5U;
+ pCSD->Reserved3 = 0U;
+ pCSD->ContentProtectAppli = (tmp & 0x01U);
+
+ /* Byte 14 */
+ tmp = (uint8_t)((hmmc->CSD[3U] & 0x0000FF00U) >> 8U);
+ pCSD->FileFormatGrouop = (tmp & 0x80U) >> 7U;
+ pCSD->CopyFlag = (tmp & 0x40U) >> 6U;
+ pCSD->PermWrProtect = (tmp & 0x20U) >> 5U;
+ pCSD->TempWrProtect = (tmp & 0x10U) >> 4U;
+ pCSD->FileFormat = (tmp & 0x0CU) >> 2U;
+ pCSD->ECC = (tmp & 0x03U);
+
+ /* Byte 15 */
+ tmp = (uint8_t)(hmmc->CSD[3U] & 0x000000FFU);
+ pCSD->CSD_CRC = (tmp & 0xFEU) >> 1U;
+ pCSD->Reserved4 = 1U;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Gets the MMC card info.
+ * @param hmmc: Pointer to MMC handle
+ * @param pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
+ * will contain the MMC card status information
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
+{
+ pCardInfo->CardType = (uint32_t)(hmmc->MmcCard.CardType);
+ pCardInfo->Class = (uint32_t)(hmmc->MmcCard.Class);
+ pCardInfo->RelCardAdd = (uint32_t)(hmmc->MmcCard.RelCardAdd);
+ pCardInfo->BlockNbr = (uint32_t)(hmmc->MmcCard.BlockNbr);
+ pCardInfo->BlockSize = (uint32_t)(hmmc->MmcCard.BlockSize);
+ pCardInfo->LogBlockNbr = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
+ pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enables wide bus operation for the requested card if supported by
+ * card.
+ * @param hmmc: Pointer to MMC handle
+ * @param WideMode: Specifies the MMC card wide bus mode
+ * This parameter can be one of the following values:
+ * @arg SDIO_BUS_WIDE_8B: 8-bit data transfer
+ * @arg SDIO_BUS_WIDE_4B: 4-bit data transfer
+ * @arg SDIO_BUS_WIDE_1B: 1-bit data transfer
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
+{
+ __IO uint32_t count = 0U;
+ SDIO_InitTypeDef Init;
+ uint32_t errorstate = HAL_MMC_ERROR_NONE;
+ uint32_t response = 0U, busy = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_SDIO_BUS_WIDE(WideMode));
+
+ /* Chnage Satte */
+ hmmc->State = HAL_MMC_STATE_BUSY;
+
+ /* Update Clock for Bus mode update */
+ Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
+ Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
+ Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
+ Init.BusWide = WideMode;
+ Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
+ Init.ClockDiv = SDIO_INIT_CLK_DIV;
+ /* Initialize SDIO*/
+ SDIO_Init(hmmc->Instance, Init);
+
+ if(WideMode == SDIO_BUS_WIDE_8B)
+ {
+ errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ hmmc->ErrorCode |= errorstate;
+ }
+ }
+ else if(WideMode == SDIO_BUS_WIDE_4B)
+ {
+ errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ hmmc->ErrorCode |= errorstate;
+ }
+ }
+ else if(WideMode == SDIO_BUS_WIDE_1B)
+ {
+ errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ hmmc->ErrorCode |= errorstate;
+ }
+ }
+ else
+ {
+ /* WideMode is not a valid argument*/
+ hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
+ }
+
+ /* Check for switch error and violation of the trial number of sending CMD 13 */
+ while(busy == 0U)
+ {
+ if(count++ == SDMMC_MAX_TRIAL)
+ {
+ hmmc->State = HAL_MMC_STATE_READY;
+ hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
+ return HAL_ERROR;
+ }
+
+ /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
+ errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ hmmc->ErrorCode |= errorstate;
+ }
+
+ /* Get command response */
+ response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
+
+ /* Get operating voltage*/
+ busy = (((response >> 7U) == 1U) ? 0U : 1U);
+ }
+
+ /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
+ count = SDMMC_DATATIMEOUT;
+ while((response & 0x00000100U) == 0U)
+ {
+ if(count-- == 0U)
+ {
+ hmmc->State = HAL_MMC_STATE_READY;
+ hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
+ return HAL_ERROR;
+ }
+
+ /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
+ errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ hmmc->ErrorCode |= errorstate;
+ }
+
+ /* Get command response */
+ response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
+ }
+
+ if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+ hmmc->State = HAL_MMC_STATE_READY;
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* Configure the SDIO peripheral */
+ Init.ClockEdge = hmmc->Init.ClockEdge;
+ Init.ClockBypass = hmmc->Init.ClockBypass;
+ Init.ClockPowerSave = hmmc->Init.ClockPowerSave;
+ Init.BusWide = WideMode;
+ Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl;
+ Init.ClockDiv = hmmc->Init.ClockDiv;
+ SDIO_Init(hmmc->Instance, Init);
+ }
+
+ /* Change State */
+ hmmc->State = HAL_MMC_STATE_READY;
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Gets the current mmc card data state.
+ * @param hmmc: pointer to MMC handle
+ * @retval Card state
+ */
+HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
+{
+ HAL_MMC_CardStateTypeDef cardstate = HAL_MMC_CARD_TRANSFER;
+ uint32_t errorstate = HAL_MMC_ERROR_NONE;
+ uint32_t resp1 = 0U;
+
+ errorstate = MMC_SendStatus(hmmc, &resp1);
+ if(errorstate != HAL_OK)
+ {
+ hmmc->ErrorCode |= errorstate;
+ }
+
+ cardstate = (HAL_MMC_CardStateTypeDef)((resp1 >> 9U) & 0x0FU);
+
+ return cardstate;
+}
+
+/**
+ * @brief Abort the current transfer and disable the MMC.
+ * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
+ * the configuration information for MMC module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
+{
+ HAL_MMC_CardStateTypeDef CardState;
+
+ /* DIsable All interrupts */
+ __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
+ SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
+
+ /* Clear All flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+
+ if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
+ {
+ /* Disable the MMC DMA request */
+ hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
+
+ /* Abort the MMC DMA Tx Stream */
+ if(hmmc->hdmatx != NULL)
+ {
+ HAL_DMA_Abort(hmmc->hdmatx);
+ }
+ /* Abort the MMC DMA Rx Stream */
+ if(hmmc->hdmarx != NULL)
+ {
+ HAL_DMA_Abort(hmmc->hdmarx);
+ }
+ }
+
+ hmmc->State = HAL_MMC_STATE_READY;
+ CardState = HAL_MMC_GetCardState(hmmc);
+ if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
+ {
+ hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
+ }
+ if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
+ {
+ return HAL_ERROR;
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort the current transfer and disable the MMC (IT mode).
+ * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
+ * the configuration information for MMC module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
+{
+ HAL_MMC_CardStateTypeDef CardState;
+
+ /* DIsable All interrupts */
+ __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
+ SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
+
+ /* Clear All flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+
+ if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
+ {
+ /* Disable the MMC DMA request */
+ hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
+
+ /* Abort the MMC DMA Tx Stream */
+ if(hmmc->hdmatx != NULL)
+ {
+ hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
+ if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
+ {
+ hmmc->hdmatx = NULL;
+ }
+ }
+ /* Abort the MMC DMA Rx Stream */
+ if(hmmc->hdmarx != NULL)
+ {
+ hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
+ if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
+ {
+ hmmc->hdmarx = NULL;
+ }
+ }
+ }
+
+ /* No transfer ongoing on both DMA channels*/
+ if((hmmc->hdmatx == NULL) && (hmmc->hdmarx == NULL))
+ {
+ CardState = HAL_MMC_GetCardState(hmmc);
+ hmmc->State = HAL_MMC_STATE_READY;
+ if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
+ {
+ hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
+ }
+ if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ HAL_MMC_AbortCallback(hmmc);
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private function ----------------------------------------------------------*/
+/** @addtogroup MMC_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief DMA MMC transmit process complete callback
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma)
+{
+ MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
+
+ /* Enable DATAEND Interrupt */
+ __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DATAEND));
+}
+
+/**
+ * @brief DMA MMC receive process complete callback
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
+ uint32_t errorstate = HAL_MMC_ERROR_NONE;
+
+ /* Send stop command in multiblock write */
+ if(hmmc->Context == (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA))
+ {
+ errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ hmmc->ErrorCode |= errorstate;
+ HAL_MMC_ErrorCallback(hmmc);
+ }
+ }
+
+ /* Disable the DMA transfer for transmit request by setting the DMAEN bit
+ in the MMC DCTRL register */
+ hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
+
+ /* Clear all the static flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+
+ hmmc->State = HAL_MMC_STATE_READY;
+
+ HAL_MMC_RxCpltCallback(hmmc);
+}
+
+/**
+ * @brief DMA MMC communication error callback
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void MMC_DMAError(DMA_HandleTypeDef *hdma)
+{
+ MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
+ HAL_MMC_CardStateTypeDef CardState;
+
+ if((hmmc->hdmarx->ErrorCode == HAL_DMA_ERROR_TE) || (hmmc->hdmatx->ErrorCode == HAL_DMA_ERROR_TE))
+ {
+ /* Clear All flags */
+ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
+
+ /* Disable All interrupts */
+ __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
+ SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
+
+ hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
+ CardState = HAL_MMC_GetCardState(hmmc);
+ if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
+ {
+ hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
+ }
+
+ hmmc->State= HAL_MMC_STATE_READY;
+ }
+
+ HAL_MMC_ErrorCallback(hmmc);
+}
+
+/**
+ * @brief DMA MMC Tx Abort callback
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma)
+{
+ MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
+ HAL_MMC_CardStateTypeDef CardState;
+
+ if(hmmc->hdmatx != NULL)
+ {
+ hmmc->hdmatx = NULL;
+ }
+
+ /* All DMA channels are aborted */
+ if(hmmc->hdmarx == NULL)
+ {
+ CardState = HAL_MMC_GetCardState(hmmc);
+ hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
+ hmmc->State = HAL_MMC_STATE_READY;
+ if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
+ {
+ hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
+
+ if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
+ {
+ HAL_MMC_AbortCallback(hmmc);
+ }
+ else
+ {
+ HAL_MMC_ErrorCallback(hmmc);
+ }
+ }
+ }
+}
+
+/**
+ * @brief DMA MMC Rx Abort callback
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma)
+{
+ MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
+ HAL_MMC_CardStateTypeDef CardState;
+
+ if(hmmc->hdmarx != NULL)
+ {
+ hmmc->hdmarx = NULL;
+ }
+
+ /* All DMA channels are aborted */
+ if(hmmc->hdmatx == NULL)
+ {
+ CardState = HAL_MMC_GetCardState(hmmc);
+ hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
+ hmmc->State = HAL_MMC_STATE_READY;
+ if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
+ {
+ hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
+
+ if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
+ {
+ HAL_MMC_AbortCallback(hmmc);
+ }
+ else
+ {
+ HAL_MMC_ErrorCallback(hmmc);
+ }
+ }
+ }
+}
+
+
+/**
+ * @brief Initializes the mmc card.
+ * @param hmmc: Pointer to MMC handle
+ * @retval MMC Card error state
+ */
+static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
+{
+ HAL_MMC_CardCSDTypeDef CSD;
+ uint32_t errorstate = HAL_MMC_ERROR_NONE;
+ uint16_t mmc_rca = 1;
+
+ /* Check the power State */
+ if(SDIO_GetPowerState(hmmc->Instance) == 0U)
+ {
+ /* Power off */
+ return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
+ }
+
+ /* Send CMD2 ALL_SEND_CID */
+ errorstate = SDMMC_CmdSendCID(hmmc->Instance);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ return errorstate;
+ }
+ else
+ {
+ /* Get Card identification number data */
+ hmmc->CID[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
+ hmmc->CID[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2);
+ hmmc->CID[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3);
+ hmmc->CID[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4);
+ }
+
+ /* Send CMD3 SET_REL_ADDR with argument 0 */
+ /* MMC Card publishes its RCA. */
+ errorstate = SDMMC_CmdSetRelAdd(hmmc->Instance, &mmc_rca);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ return errorstate;
+ }
+
+ /* Get the MMC card RCA */
+ hmmc->MmcCard.RelCardAdd = mmc_rca;
+
+ /* Send CMD9 SEND_CSD with argument as card's RCA */
+ errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ return errorstate;
+ }
+ else
+ {
+ /* Get Card Specific Data */
+ hmmc->CSD[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
+ hmmc->CSD[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2);
+ hmmc->CSD[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3);
+ hmmc->CSD[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4);
+ }
+
+ /* Get the Card Class */
+ hmmc->MmcCard.Class = (SDIO_GetResponse(hmmc->Instance, SDIO_RESP2) >> 20U);
+
+ /* Get CSD parameters */
+ HAL_MMC_GetCardCSD(hmmc, &CSD);
+
+ /* Select the Card */
+ errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ return errorstate;
+ }
+
+ /* Configure SDIO peripheral interface */
+ SDIO_Init(hmmc->Instance, hmmc->Init);
+
+ /* All cards are initialized */
+ return HAL_MMC_ERROR_NONE;
+}
+
+/**
+ * @brief Enquires cards about their operating voltage and configures clock
+ * controls and stores MMC information that will be needed in future
+ * in the MMC handle.
+ * @param hmmc: Pointer to MMC handle
+ * @retval error state
+ */
+static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
+{
+ __IO uint32_t count = 0U;
+ uint32_t response = 0U, validvoltage = 0U;
+ uint32_t errorstate = HAL_MMC_ERROR_NONE;
+
+ /* CMD0: GO_IDLE_STATE */
+ errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ return errorstate;
+ }
+
+ while(validvoltage == 0U)
+ {
+ if(count++ == SDMMC_MAX_VOLT_TRIAL)
+ {
+ return HAL_MMC_ERROR_INVALID_VOLTRANGE;
+ }
+
+ /* SEND CMD1 APP_CMD with MMC_HIGH_VOLTAGE_RANGE(0xC0FF8000) as argument */
+ errorstate = SDMMC_CmdOpCondition(hmmc->Instance, eMMC_HIGH_VOLTAGE_RANGE);
+ if(errorstate != HAL_MMC_ERROR_NONE)
+ {
+ return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
+ }
+
+ /* Get command response */
+ response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
+
+ /* Get operating voltage*/
+ validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
+ }
+
+ /* When power routine is finished and command returns valid voltage */
+ if ((response & eMMC_HIGH_VOLTAGE_RANGE) == MMC_HIGH_VOLTAGE_RANGE)
+ {
+ /* When voltage range of the card is within 2.7V and 3.6V */
+ hmmc->MmcCard.CardType = MMC_HIGH_VOLTAGE_CARD;
+ }
+ else
+ {
+ /* When voltage range of the card is within 1.65V and 1.95V or 2.7V and 3.6V */
+ hmmc->MmcCard.CardType = MMC_DUAL_VOLTAGE_CARD;
+ }
+
+ return HAL_MMC_ERROR_NONE;
+}
+
+/**
+ * @brief Turns the SDIO output signals off.
+ * @param hmmc: Pointer to MMC handle
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
+{
+ /* Set Power State to OFF */
+ SDIO_PowerState_OFF(hmmc->Instance);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Returns the current card's status.
+ * @param hmmc: Pointer to MMC handle
+ * @param pCardStatus: pointer to the buffer that will contain the MMC card
+ * status (Card Status register)
+ * @retval error state
+ */
+static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
+{
+ uint32_t errorstate = HAL_MMC_ERROR_NONE;
+
+ if(pCardStatus == NULL)
+ {
+ return HAL_MMC_ERROR_PARAM;
+ }
+
+ /* Send Status command */
+ errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
+ if(errorstate != HAL_OK)
+ {
+ return errorstate;
+ }
+
+ /* Get MMC card status */
+ *pCardStatus = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
+
+ return HAL_MMC_ERROR_NONE;
+}
+
+/**
+ * @brief Wrap up reading in non-blocking mode.
+ * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
+ * the configuration information.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef MMC_Read_IT(MMC_HandleTypeDef *hmmc)
+{
+ uint32_t count = 0U;
+ uint32_t* tmp;
+
+ tmp = (uint32_t*)hmmc->pRxBuffPtr;
+
+ /* Read data from SDMMC Rx FIFO */
+ for(count = 0U; count < 8U; count++)
+ {
+ *(tmp + count) = SDIO_ReadFIFO(hmmc->Instance);
+ }
+
+ hmmc->pRxBuffPtr += 8U;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Wrap up writing in non-blocking mode.
+ * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
+ * the configuration information.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef MMC_Write_IT(MMC_HandleTypeDef *hmmc)
+{
+ uint32_t count = 0U;
+ uint32_t* tmp;
+
+ tmp = (uint32_t*)hmmc->pTxBuffPtr;
+
+ /* Write data to SDMMC Tx FIFO */
+ for(count = 0U; count < 8U; count++)
+ {
+ SDIO_WriteFIFO(hmmc->Instance, (tmp + count));
+ }
+
+ hmmc->pTxBuffPtr += 8U;
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+#endif /* STM32F103xE || STM32F103xG */
+
+#endif /* HAL_MMC_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_msp_template.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_msp_template.c
new file mode 100644
index 0000000..3087239
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_msp_template.c
@@ -0,0 +1,109 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_msp_template.c
+ * @author MCD Application Team
+ * @brief HAL BSP module.
+ * This file template is located in the HAL folder and should be copied
+ * to the user folder.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup HAL_MSP HAL_MSP
+ * @brief HAL MSP module.
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup HAL_MSP_Exported_Functions HAL MSP Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes the Global MSP.
+ * @retval None
+ */
+void HAL_MspInit(void)
+{
+
+}
+
+/**
+ * @brief DeInitializes the Global MSP.
+ * @retval None
+ */
+void HAL_MspDeInit(void)
+{
+
+}
+
+/**
+ * @brief Initializes the PPP MSP.
+ * @retval None
+ */
+void HAL_PPP_MspInit(void)
+{
+
+}
+
+/**
+ * @brief DeInitializes the PPP MSP.
+ * @retval None
+ */
+void HAL_PPP_MspDeInit(void)
+{
+
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_nand.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_nand.c
new file mode 100644
index 0000000..c32abe8
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_nand.c
@@ -0,0 +1,1802 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_nand.c
+ * @author MCD Application Team
+ * @brief NAND HAL module driver.
+ * This file provides a generic firmware to drive NAND memories mounted
+ * as external device.
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ This driver is a generic layered driver which contains a set of APIs used to
+ control NAND flash memories. It uses the FSMC layer functions to interface
+ with NAND devices. This driver is used as follows:
+
+ (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
+ with control and timing parameters for both common and attribute spaces.
+
+ (+) Read NAND flash memory maker and device IDs using the function
+ HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef
+ structure declared by the function caller.
+
+ (+) Access NAND flash memory by read/write operations using the functions
+ HAL_NAND_Read_Page_8b()/HAL_NAND_Read_SpareArea_8b(),
+ HAL_NAND_Write_Page_8b()/HAL_NAND_Write_SpareArea_8b(),
+ HAL_NAND_Read_Page_16b()/HAL_NAND_Read_SpareArea_16b(),
+ HAL_NAND_Write_Page_16b()/HAL_NAND_Write_SpareArea_16b()
+ to read/write page(s)/spare area(s). These functions use specific device
+ information (Block, page size..) predefined by the user in the NAND_DeviceConfigTypeDef
+ structure. The read/write address information is contained by the Nand_Address_Typedef
+ structure passed as parameter.
+
+ (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
+
+ (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
+ The erase block address information is contained in the Nand_Address_Typedef
+ structure passed as parameter.
+
+ (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
+
+ (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
+ HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
+ feature or the function HAL_NAND_GetECC() to get the ECC correction code.
+
+ (+) You can monitor the NAND device HAL state by calling the function
+ HAL_NAND_GetState()
+
+ [..]
+ (@) This driver is a set of generic APIs which handle standard NAND flash operations.
+ If a NAND flash device contains different operations and/or implementations,
+ it should be implemented separately.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_NAND_MODULE_ENABLED
+
+#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG)
+
+/** @defgroup NAND NAND
+ * @brief NAND HAL module driver
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup NAND_Private_Constants NAND Private Constants
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/** @defgroup NAND_Private_Macros NAND Private Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup NAND_Exported_Functions NAND Exported Functions
+ * @{
+ */
+
+/** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### NAND Initialization and de-initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to initialize/de-initialize
+ the NAND memory
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Perform NAND memory Initialization sequence
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param ComSpace_Timing: pointer to Common space timing structure
+ * @param AttSpace_Timing: pointer to Attribute space timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FSMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FSMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
+{
+ /* Check the NAND handle state */
+ if(hnand == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if(hnand->State == HAL_NAND_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hnand->Lock = HAL_UNLOCKED;
+ /* Initialize the low level hardware (MSP) */
+ HAL_NAND_MspInit(hnand);
+ }
+
+ /* Initialize NAND control Interface */
+ FSMC_NAND_Init(hnand->Instance, &(hnand->Init));
+
+ /* Initialize NAND common space timing Interface */
+ FSMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
+
+ /* Initialize NAND attribute space timing Interface */
+ FSMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
+
+ /* Enable the NAND device */
+ __FSMC_NAND_ENABLE(hnand->Instance, hnand->Init.NandBank);
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Perform NAND memory De-Initialization sequence
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
+{
+ /* Initialize the low level hardware (MSP) */
+ HAL_NAND_MspDeInit(hnand);
+
+ /* Configure the NAND registers with their reset values */
+ FSMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
+
+ /* Reset the NAND controller state */
+ hnand->State = HAL_NAND_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief NAND MSP Init
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval None
+ */
+__weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hnand);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_NAND_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief NAND MSP DeInit
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval None
+ */
+__weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hnand);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_NAND_MspDeInit could be implemented in the user file
+ */
+}
+
+
+/**
+ * @brief This function handles NAND device interrupt request.
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval HAL status
+*/
+void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
+{
+ /* Check NAND interrupt Rising edge flag */
+ if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_RISING_EDGE))
+ {
+ /* NAND interrupt callback*/
+ HAL_NAND_ITCallback(hnand);
+
+ /* Clear NAND interrupt Rising edge pending bit */
+ __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_RISING_EDGE);
+ }
+
+ /* Check NAND interrupt Level flag */
+ if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_LEVEL))
+ {
+ /* NAND interrupt callback*/
+ HAL_NAND_ITCallback(hnand);
+
+ /* Clear NAND interrupt Level pending bit */
+ __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_LEVEL);
+ }
+
+ /* Check NAND interrupt Falling edge flag */
+ if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FALLING_EDGE))
+ {
+ /* NAND interrupt callback*/
+ HAL_NAND_ITCallback(hnand);
+
+ /* Clear NAND interrupt Falling edge pending bit */
+ __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FALLING_EDGE);
+ }
+
+ /* Check NAND interrupt FIFO empty flag */
+ if(__FSMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FEMPT))
+ {
+ /* NAND interrupt callback*/
+ HAL_NAND_ITCallback(hnand);
+
+ /* Clear NAND interrupt FIFO empty pending bit */
+ __FSMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FSMC_FLAG_FEMPT);
+ }
+}
+
+/**
+ * @brief NAND interrupt feature callback
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval None
+ */
+__weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hnand);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_NAND_ITCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
+ * @brief Input Output and memory control functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### NAND Input and Output functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to use and control the NAND
+ memory
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Read the NAND memory electronic signature
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pNAND_ID: NAND ID structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
+{
+ __IO uint32_t data = 0U;
+ __IO uint32_t data1 = 0U;
+ uint32_t deviceaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Check the NAND controller state */
+ if(hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Identify the device address */
+ if(hnand->Init.NandBank == FSMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Send Read ID command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_READID;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+
+ /* Read the electronic signature from NAND flash */
+ if (hnand->Init.MemoryDataWidth == FSMC_NAND_PCC_MEM_BUS_WIDTH_8)
+ {
+ data = *(__IO uint32_t *)deviceaddress;
+
+ /* Return the data read */
+ pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
+ pNAND_ID->Device_Id = ADDR_2ND_CYCLE(data);
+ pNAND_ID->Third_Id = ADDR_3RD_CYCLE(data);
+ pNAND_ID->Fourth_Id = ADDR_4TH_CYCLE(data);
+ }
+ else
+ {
+ data = *(__IO uint32_t *)deviceaddress;
+ data1 = *((__IO uint32_t *)deviceaddress + 4U);
+
+ /* Return the data read */
+ pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
+ pNAND_ID->Device_Id = ADDR_3RD_CYCLE(data);
+ pNAND_ID->Third_Id = ADDR_1ST_CYCLE(data1);
+ pNAND_ID->Fourth_Id = ADDR_3RD_CYCLE(data1);
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief NAND memory reset
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
+{
+ uint32_t deviceaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Check the NAND controller state */
+ if(hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Identify the device address */
+ if(hnand->Init.NandBank == FSMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Send NAND reset command */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = 0xFF;
+
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_OK;
+
+}
+
+/**
+ * @brief Configure the device: Enter the physical parameters of the device
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pDeviceConfig : pointer to NAND_DeviceConfigTypeDef structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig)
+{
+ hnand->Config.PageSize = pDeviceConfig->PageSize;
+ hnand->Config.SpareAreaSize = pDeviceConfig->SpareAreaSize;
+ hnand->Config.BlockSize = pDeviceConfig->BlockSize;
+ hnand->Config.BlockNbr = pDeviceConfig->BlockNbr;
+ hnand->Config.PlaneSize = pDeviceConfig->PlaneSize;
+ hnand->Config.PlaneNbr = pDeviceConfig->PlaneNbr;
+ hnand->Config.ExtraCommandEnable = pDeviceConfig->ExtraCommandEnable;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Read Page(s) from NAND memory block (8-bits addressing)
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress : pointer to NAND address structure
+ * @param pBuffer : pointer to destination read buffer
+ * @param NumPageToRead : number of pages to read from block
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
+{
+ __IO uint32_t index = 0U;
+ uint32_t tickstart = 0U;
+ uint32_t deviceaddress = 0U, size = 0U, numPagesRead = 0U, nandaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Check the NAND controller state */
+ if(hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Identify the device address */
+ if(hnand->Init.NandBank == FSMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* NAND raw address calculation */
+ nandaddress = ARRAY_ADDRESS(pAddress, hnand);
+
+ /* Page(s) read loop */
+ while((NumPageToRead != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
+ {
+ /* update the buffer size */
+ size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
+
+ /* Send read page command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
+
+ /* Cards with page size <= 512 bytes */
+ if((hnand->Config.PageSize) <= 512U)
+ {
+ if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ }
+ }
+ else /* (hnand->Config.PageSize) > 512 */
+ {
+ if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ }
+ }
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
+
+ /* Check if an extra command is needed for reading pages */
+ if(hnand->Config.ExtraCommandEnable == ENABLE)
+ {
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Read status until NAND is ready */
+ while(HAL_NAND_Read_Status(hnand) != NAND_READY)
+ {
+ if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Go back to read mode */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
+ }
+
+ /* Get Data into Buffer */
+ for(; index < size; index++)
+ {
+ *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
+ }
+
+ /* Increment read pages number */
+ numPagesRead++;
+
+ /* Decrement pages to read */
+ NumPageToRead--;
+
+ /* Increment the NAND address */
+ nandaddress = (uint32_t)(nandaddress + 1U);
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Read Page(s) from NAND memory block (16-bits addressing)
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress : pointer to NAND address structure
+ * @param pBuffer : pointer to destination read buffer. pBuffer should be 16bits aligned
+ * @param NumPageToRead : number of pages to read from block
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToRead)
+{
+ __IO uint32_t index = 0U;
+ uint32_t tickstart = 0U;
+ uint32_t deviceaddress = 0U, size = 0U, numPagesRead = 0U, nandaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Check the NAND controller state */
+ if(hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Identify the device address */
+ if(hnand->Init.NandBank == FSMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* NAND raw address calculation */
+ nandaddress = ARRAY_ADDRESS(pAddress, hnand);
+
+ /* Page(s) read loop */
+ while((NumPageToRead != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
+ {
+ /* update the buffer size */
+ size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
+
+ /* Send read page command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
+
+ /* Cards with page size <= 512 bytes */
+ if((hnand->Config.PageSize) <= 512U)
+ {
+ if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ }
+ }
+ else /* (hnand->Config.PageSize) > 512 */
+ {
+ if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ }
+ }
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
+
+ if(hnand->Config.ExtraCommandEnable == ENABLE)
+ {
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Read status until NAND is ready */
+ while(HAL_NAND_Read_Status(hnand) != NAND_READY)
+ {
+ if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Go back to read mode */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
+ }
+
+ /* Get Data into Buffer */
+ for(; index < size; index++)
+ {
+ *(uint16_t *)pBuffer++ = *(uint16_t *)deviceaddress;
+ }
+
+ /* Increment read pages number */
+ numPagesRead++;
+
+ /* Decrement pages to read */
+ NumPageToRead--;
+
+ /* Increment the NAND address */
+ nandaddress = (uint32_t)(nandaddress + 1U);
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Write Page(s) to NAND memory block (8-bits addressing)
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress : pointer to NAND address structure
+ * @param pBuffer : pointer to source buffer to write
+ * @param NumPageToWrite : number of pages to write to block
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
+{
+ __IO uint32_t index = 0U;
+ uint32_t tickstart = 0U;
+ uint32_t deviceaddress = 0U, size = 0U, numPagesWritten = 0U, nandaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Check the NAND controller state */
+ if(hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Identify the device address */
+ if(hnand->Init.NandBank == FSMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* NAND raw address calculation */
+ nandaddress = ARRAY_ADDRESS(pAddress, hnand);
+
+ /* Page(s) write loop */
+ while((NumPageToWrite != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
+ {
+ /* update the buffer size */
+ size = hnand->Config.PageSize + ((hnand->Config.PageSize) * numPagesWritten);
+
+ /* Send write page command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
+
+ /* Cards with page size <= 512 bytes */
+ if((hnand->Config.PageSize) <= 512U)
+ {
+ if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ }
+ }
+ else /* (hnand->Config.PageSize) > 512 */
+ {
+ if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ }
+ }
+
+
+ /* Write data to memory */
+ for(; index < size; index++)
+ {
+ *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
+ }
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
+
+ /* Read status until NAND is ready */
+ while(HAL_NAND_Read_Status(hnand) != NAND_READY)
+ {
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Increment written pages number */
+ numPagesWritten++;
+
+ /* Decrement pages to write */
+ NumPageToWrite--;
+
+ /* Increment the NAND address */
+ nandaddress = (uint32_t)(nandaddress + 1U);
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Write Page(s) to NAND memory block (16-bits addressing)
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress : pointer to NAND address structure
+ * @param pBuffer : pointer to source buffer to write. pBuffer should be 16bits aligned
+ * @param NumPageToWrite : number of pages to write to block
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToWrite)
+{
+ __IO uint32_t index = 0U;
+ uint32_t tickstart = 0U;
+ uint32_t deviceaddress = 0U, size = 0U, numPagesWritten = 0U, nandaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Check the NAND controller state */
+ if(hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Identify the device address */
+ if(hnand->Init.NandBank == FSMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* NAND raw address calculation */
+ nandaddress = ARRAY_ADDRESS(pAddress, hnand);
+
+ /* Page(s) write loop */
+ while((NumPageToWrite != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
+ {
+ /* update the buffer size */
+ size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesWritten);
+
+ /* Send write page command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
+
+ /* Cards with page size <= 512 bytes */
+ if((hnand->Config.PageSize) <= 512U)
+ {
+ if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ }
+ }
+ else /* (hnand->Config.PageSize) > 512 */
+ {
+ if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ }
+ }
+
+ /* Write data to memory */
+ for(; index < size; index++)
+ {
+ *(__IO uint16_t *)deviceaddress = *(uint16_t *)pBuffer++;
+ }
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
+
+ /* Read status until NAND is ready */
+ while(HAL_NAND_Read_Status(hnand) != NAND_READY)
+ {
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Increment written pages number */
+ numPagesWritten++;
+
+ /* Decrement pages to write */
+ NumPageToWrite--;
+
+ /* Increment the NAND address */
+ nandaddress = (uint32_t)(nandaddress + 1U);
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Read Spare area(s) from NAND memory (8-bits addressing)
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress : pointer to NAND address structure
+ * @param pBuffer: pointer to source buffer to write
+ * @param NumSpareAreaToRead: Number of spare area to read
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
+{
+ __IO uint32_t index = 0U;
+ uint32_t tickstart = 0U;
+ uint32_t deviceaddress = 0U, size = 0U, numSpareAreaRead = 0U, nandaddress = 0U, columnaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Check the NAND controller state */
+ if(hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Identify the device address */
+ if(hnand->Init.NandBank == FSMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* NAND raw address calculation */
+ nandaddress = ARRAY_ADDRESS(pAddress, hnand);
+
+ /* Column in page address */
+ columnaddress = COLUMN_ADDRESS(hnand);
+
+ /* Spare area(s) read loop */
+ while((NumSpareAreaToRead != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
+ {
+ /* update the buffer size */
+ size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead);
+
+ /* Cards with page size <= 512 bytes */
+ if((hnand->Config.PageSize) <= 512U)
+ {
+ /* Send read spare area command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
+
+ if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ }
+ }
+ else /* (hnand->Config.PageSize) > 512 */
+ {
+ /* Send read spare area command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
+
+ if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ }
+ }
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
+
+ if(hnand->Config.ExtraCommandEnable == ENABLE)
+ {
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Read status until NAND is ready */
+ while(HAL_NAND_Read_Status(hnand) != NAND_READY)
+ {
+ if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Go back to read mode */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
+ }
+
+ /* Get Data into Buffer */
+ for(; index < size; index++)
+ {
+ *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
+ }
+
+ /* Increment read spare areas number */
+ numSpareAreaRead++;
+
+ /* Decrement spare areas to read */
+ NumSpareAreaToRead--;
+
+ /* Increment the NAND address */
+ nandaddress = (uint32_t)(nandaddress + 1U);
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Read Spare area(s) from NAND memory (16-bits addressing)
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress : pointer to NAND address structure
+ * @param pBuffer: pointer to source buffer to write. pBuffer should be 16bits aligned.
+ * @param NumSpareAreaToRead: Number of spare area to read
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaToRead)
+{
+ __IO uint32_t index = 0U;
+ uint32_t tickstart = 0U;
+ uint32_t deviceaddress = 0U, size = 0U, numSpareAreaRead = 0U, nandaddress = 0U, columnaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Check the NAND controller state */
+ if(hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Identify the device address */
+ if(hnand->Init.NandBank == FSMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* NAND raw address calculation */
+ nandaddress = ARRAY_ADDRESS(pAddress, hnand);
+
+ /* Column in page address */
+ columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2U);
+
+ /* Spare area(s) read loop */
+ while((NumSpareAreaToRead != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
+ {
+ /* update the buffer size */
+ size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead);
+
+ /* Cards with page size <= 512 bytes */
+ if((hnand->Config.PageSize) <= 512U)
+ {
+ /* Send read spare area command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
+
+ if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ }
+ }
+ else /* (hnand->Config.PageSize) > 512 */
+ {
+ /* Send read spare area command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
+
+ if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ }
+ }
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
+
+ if(hnand->Config.ExtraCommandEnable == ENABLE)
+ {
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Read status until NAND is ready */
+ while(HAL_NAND_Read_Status(hnand) != NAND_READY)
+ {
+ if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Go back to read mode */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
+ }
+
+ /* Get Data into Buffer */
+ for(; index < size; index++)
+ {
+ *(uint16_t *)pBuffer++ = *(uint16_t *)deviceaddress;
+ }
+
+ /* Increment read spare areas number */
+ numSpareAreaRead++;
+
+ /* Decrement spare areas to read */
+ NumSpareAreaToRead--;
+
+ /* Increment the NAND address */
+ nandaddress = (uint32_t)(nandaddress + 1U);
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Write Spare area(s) to NAND memory (8-bits addressing)
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress : pointer to NAND address structure
+ * @param pBuffer : pointer to source buffer to write
+ * @param NumSpareAreaTowrite : number of spare areas to write to block
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
+{
+ __IO uint32_t index = 0U;
+ uint32_t tickstart = 0U;
+ uint32_t deviceaddress = 0U, size = 0U, numSpareAreaWritten = 0U, nandaddress = 0U, columnaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Check the NAND controller state */
+ if(hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Identify the device address */
+ if(hnand->Init.NandBank == FSMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+
+ /* Update the FSMC_NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Page address calculation */
+ nandaddress = ARRAY_ADDRESS(pAddress, hnand);
+
+ /* Column in page address */
+ columnaddress = COLUMN_ADDRESS(hnand);
+
+ /* Spare area(s) write loop */
+ while((NumSpareAreaTowrite != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
+ {
+ /* update the buffer size */
+ size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten);
+
+ /* Cards with page size <= 512 bytes */
+ if((hnand->Config.PageSize) <= 512U)
+ {
+ /* Send write Spare area command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
+
+ if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ }
+ }
+ else /* (hnand->Config.PageSize) > 512 */
+ {
+ /* Send write Spare area command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
+
+ if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ }
+ }
+
+ /* Write data to memory */
+ for(; index < size; index++)
+ {
+ *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
+ }
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Read status until NAND is ready */
+ while(HAL_NAND_Read_Status(hnand) != NAND_READY)
+ {
+ if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Increment written spare areas number */
+ numSpareAreaWritten++;
+
+ /* Decrement spare areas to write */
+ NumSpareAreaTowrite--;
+
+ /* Increment the NAND address */
+ nandaddress = (uint32_t)(nandaddress + 1U);
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Write Spare area(s) to NAND memory (16-bits addressing)
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress : pointer to NAND address structure
+ * @param pBuffer : pointer to source buffer to write. pBuffer should be 16bits aligned.
+ * @param NumSpareAreaTowrite : number of spare areas to write to block
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaTowrite)
+{
+ __IO uint32_t index = 0U;
+ uint32_t tickstart = 0U;
+ uint32_t deviceaddress = 0U, size = 0U, numSpareAreaWritten = 0U, nandaddress = 0U, columnaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Check the NAND controller state */
+ if(hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Identify the device address */
+ if(hnand->Init.NandBank == FSMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+
+ /* Update the FSMC_NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* NAND raw address calculation */
+ nandaddress = ARRAY_ADDRESS(pAddress, hnand);
+
+ /* Column in page address */
+ columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2U);
+
+ /* Spare area(s) write loop */
+ while((NumSpareAreaTowrite != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
+ {
+ /* update the buffer size */
+ size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten);
+
+ /* Cards with page size <= 512 bytes */
+ if((hnand->Config.PageSize) <= 512U)
+ {
+ /* Send write Spare area command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
+
+ if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ }
+ }
+ else /* (hnand->Config.PageSize) > 512 */
+ {
+ /* Send write Spare area command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
+
+ if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535U)
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ }
+ else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
+ {
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
+ }
+ }
+
+ /* Write data to memory */
+ for(; index < size; index++)
+ {
+ *(__IO uint16_t *)deviceaddress = *(uint16_t *)pBuffer++;
+ }
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
+
+ /* Read status until NAND is ready */
+ while(HAL_NAND_Read_Status(hnand) != NAND_READY)
+ {
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Increment written spare areas number */
+ numSpareAreaWritten++;
+
+ /* Decrement spare areas to write */
+ NumSpareAreaTowrite--;
+
+ /* Increment the NAND address */
+ nandaddress = (uint32_t)(nandaddress + 1U);
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief NAND memory Block erase
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress : pointer to NAND address structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
+{
+ uint32_t deviceaddress = 0U;
+ uint32_t tickstart = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnand);
+
+ /* Check the NAND controller state */
+ if(hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Identify the device address */
+ if(hnand->Init.NandBank == FSMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Send Erase block command sequence */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0;
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
+
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1;
+
+ /* Update the NAND controller state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Read status until NAND is ready */
+ while(HAL_NAND_Read_Status(hnand) != NAND_READY)
+ {
+ if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnand);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief NAND memory read status
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval NAND status
+ */
+uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
+{
+ uint32_t data = 0U;
+ uint32_t deviceaddress = 0U;
+
+ /* Identify the device address */
+ if(hnand->Init.NandBank == FSMC_NAND_BANK2)
+ {
+ deviceaddress = NAND_DEVICE1;
+ }
+ else
+ {
+ deviceaddress = NAND_DEVICE2;
+ }
+
+ /* Send Read status operation command */
+ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS;
+
+ /* Read status register data */
+ data = *(__IO uint8_t *)deviceaddress;
+
+ /* Return the status */
+ if((data & NAND_ERROR) == NAND_ERROR)
+ {
+ return NAND_ERROR;
+ }
+ else if((data & NAND_READY) == NAND_READY)
+ {
+ return NAND_READY;
+ }
+
+ return NAND_BUSY;
+}
+
+/**
+ * @brief Increment the NAND memory address
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param pAddress: pointer to NAND address structure
+ * @retval The new status of the increment address operation. It can be:
+ * - NAND_VALID_ADDRESS: When the new address is valid address
+ * - NAND_INVALID_ADDRESS: When the new address is invalid address
+ */
+uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
+{
+ uint32_t status = NAND_VALID_ADDRESS;
+
+ /* Increment page address */
+ pAddress->Page++;
+
+ /* Check NAND address is valid */
+ if(pAddress->Page == hnand->Config.BlockSize)
+ {
+ pAddress->Page = 0U;
+ pAddress->Block++;
+
+ if(pAddress->Block == hnand->Config.PlaneSize)
+ {
+ pAddress->Block = 0U;
+ pAddress->Plane++;
+
+ if(pAddress->Plane == (hnand->Config.PlaneNbr))
+ {
+ status = NAND_INVALID_ADDRESS;
+ }
+ }
+ }
+
+ return (status);
+}
+/**
+ * @}
+ */
+
+/** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
+ * @brief management functions
+ *
+@verbatim
+ ==============================================================================
+ ##### NAND Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control dynamically
+ the NAND interface.
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Enables dynamically NAND ECC feature.
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
+{
+ /* Check the NAND controller state */
+ if(hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Update the NAND state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Enable ECC feature */
+ FSMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
+
+ /* Update the NAND state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically FSMC_NAND ECC feature.
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
+{
+ /* Check the NAND controller state */
+ if(hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Update the NAND state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Disable ECC feature */
+ FSMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
+
+ /* Update the NAND state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically NAND ECC feature.
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @param ECCval: pointer to ECC value
+ * @param Timeout: maximum timeout to wait
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the NAND controller state */
+ if(hnand->State == HAL_NAND_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Update the NAND state */
+ hnand->State = HAL_NAND_STATE_BUSY;
+
+ /* Get NAND ECC value */
+ status = FSMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
+
+ /* Update the NAND state */
+ hnand->State = HAL_NAND_STATE_READY;
+
+ return status;
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ==============================================================================
+ ##### NAND State functions #####
+ ==============================================================================
+ [..]
+ This subsection permits to get in run-time the status of the NAND controller
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief return the NAND state
+ * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
+ * the configuration information for NAND module.
+ * @retval HAL state
+ */
+HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
+{
+ return hnand->State;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+#endif /* HAL_NAND_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_nor.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_nor.c
new file mode 100644
index 0000000..d8607ca
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_nor.c
@@ -0,0 +1,1058 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_nor.c
+ * @author MCD Application Team
+ * @brief NOR HAL module driver.
+ * This file provides a generic firmware to drive NOR memories mounted
+ * as external device.
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ This driver is a generic layered driver which contains a set of APIs used to
+ control NOR flash memories. It uses the FSMC layer functions to interface
+ with NOR devices. This driver is used as follows:
+
+ (+) NOR flash memory configuration sequence using the function HAL_NOR_Init()
+ with control and timing parameters for both normal and extended mode.
+
+ (+) Read NOR flash memory manufacturer code and device IDs using the function
+ HAL_NOR_Read_ID(). The read information is stored in the NOR_ID_TypeDef
+ structure declared by the function caller.
+
+ (+) Access NOR flash memory by read/write data unit operations using the functions
+ HAL_NOR_Read(), HAL_NOR_Program().
+
+ (+) Perform NOR flash erase block/chip operations using the functions
+ HAL_NOR_Erase_Block() and HAL_NOR_Erase_Chip().
+
+ (+) Read the NOR flash CFI (common flash interface) IDs using the function
+ HAL_NOR_Read_CFI(). The read information is stored in the NOR_CFI_TypeDef
+ structure declared by the function caller.
+
+ (+) You can also control the NOR device by calling the control APIs HAL_NOR_WriteOperation_Enable()/
+ HAL_NOR_WriteOperation_Disable() to respectively enable/disable the NOR write operation
+
+ (+) You can monitor the NOR device HAL state by calling the function
+ HAL_NOR_GetState()
+ [..]
+ (@) This driver is a set of generic APIs which handle standard NOR flash operations.
+ If a NOR flash device contains different operations and/or implementations,
+ it should be implemented separately.
+
+ *** NOR HAL driver macros list ***
+ =============================================
+ [..]
+ Below the list of most used macros in NOR HAL driver.
+
+ (+) NOR_WRITE : NOR memory write data to specified address
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_NOR_MODULE_ENABLED
+#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG) || defined(STM32F100xE)
+
+/** @defgroup NOR NOR
+ * @brief NOR driver modules
+ * @{
+ */
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup NOR_Private_Constants NOR Private Constants
+ * @{
+ */
+
+/* Constants to define address to set to write a command */
+#define NOR_CMD_ADDRESS_FIRST (uint16_t)0x0555
+#define NOR_CMD_ADDRESS_FIRST_CFI (uint16_t)0x0055
+#define NOR_CMD_ADDRESS_SECOND (uint16_t)0x02AA
+#define NOR_CMD_ADDRESS_THIRD (uint16_t)0x0555
+#define NOR_CMD_ADDRESS_FOURTH (uint16_t)0x0555
+#define NOR_CMD_ADDRESS_FIFTH (uint16_t)0x02AA
+#define NOR_CMD_ADDRESS_SIXTH (uint16_t)0x0555
+
+/* Constants to define data to program a command */
+#define NOR_CMD_DATA_READ_RESET (uint16_t)0x00F0
+#define NOR_CMD_DATA_FIRST (uint16_t)0x00AA
+#define NOR_CMD_DATA_SECOND (uint16_t)0x0055
+#define NOR_CMD_DATA_AUTO_SELECT (uint16_t)0x0090
+#define NOR_CMD_DATA_PROGRAM (uint16_t)0x00A0
+#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD (uint16_t)0x0080
+#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH (uint16_t)0x00AA
+#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH (uint16_t)0x0055
+#define NOR_CMD_DATA_CHIP_ERASE (uint16_t)0x0010
+#define NOR_CMD_DATA_CFI (uint16_t)0x0098
+
+#define NOR_CMD_DATA_BUFFER_AND_PROG (uint8_t)0x25
+#define NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM (uint8_t)0x29
+#define NOR_CMD_DATA_BLOCK_ERASE (uint8_t)0x30
+
+/* Mask on NOR STATUS REGISTER */
+#define NOR_MASK_STATUS_DQ5 (uint16_t)0x0020
+#define NOR_MASK_STATUS_DQ6 (uint16_t)0x0040
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/** @defgroup NOR_Private_Macros NOR Private Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+
+/** @defgroup NOR_Private_Variables NOR Private Variables
+ * @{
+ */
+
+static uint32_t uwNORMemoryDataWidth = NOR_MEMORY_8B;
+
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup NOR_Exported_Functions NOR Exported Functions
+ * @{
+ */
+
+/** @defgroup NOR_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### NOR Initialization and de_initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to initialize/de-initialize
+ the NOR memory
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Perform the NOR memory Initialization sequence
+ * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param Timing: pointer to NOR control timing structure
+ * @param ExtTiming: pointer to NOR extended mode timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_Init(NOR_HandleTypeDef *hnor, FSMC_NORSRAM_TimingTypeDef *Timing, FSMC_NORSRAM_TimingTypeDef *ExtTiming)
+{
+ /* Check the NOR handle parameter */
+ if(hnor == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if(hnor->State == HAL_NOR_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hnor->Lock = HAL_UNLOCKED;
+
+ /* Initialize the low level hardware (MSP) */
+ HAL_NOR_MspInit(hnor);
+ }
+
+ /* Initialize NOR control Interface */
+ FSMC_NORSRAM_Init(hnor->Instance, &(hnor->Init));
+
+ /* Initialize NOR timing Interface */
+ FSMC_NORSRAM_Timing_Init(hnor->Instance, Timing, hnor->Init.NSBank);
+
+ /* Initialize NOR extended mode timing Interface */
+ FSMC_NORSRAM_Extended_Timing_Init(hnor->Extended, ExtTiming, hnor->Init.NSBank, hnor->Init.ExtendedMode);
+
+ /* Enable the NORSRAM device */
+ __FSMC_NORSRAM_ENABLE(hnor->Instance, hnor->Init.NSBank);
+
+ /* Initialize NOR Memory Data Width*/
+ if (hnor->Init.MemoryDataWidth == FSMC_NORSRAM_MEM_BUS_WIDTH_8)
+ {
+ uwNORMemoryDataWidth = NOR_MEMORY_8B;
+ }
+ else
+ {
+ uwNORMemoryDataWidth = NOR_MEMORY_16B;
+ }
+
+ /* Check the NOR controller state */
+ hnor->State = HAL_NOR_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Perform NOR memory De-Initialization sequence
+ * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_DeInit(NOR_HandleTypeDef *hnor)
+{
+ /* De-Initialize the low level hardware (MSP) */
+ HAL_NOR_MspDeInit(hnor);
+
+ /* Configure the NOR registers with their reset values */
+ FSMC_NORSRAM_DeInit(hnor->Instance, hnor->Extended, hnor->Init.NSBank);
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hnor);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief NOR MSP Init
+ * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @retval None
+ */
+__weak void HAL_NOR_MspInit(NOR_HandleTypeDef *hnor)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hnor);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_NOR_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief NOR MSP DeInit
+ * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @retval None
+ */
+__weak void HAL_NOR_MspDeInit(NOR_HandleTypeDef *hnor)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hnor);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_NOR_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief NOR MSP Wait fro Ready/Busy signal
+ * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param Timeout: Maximum timeout value
+ * @retval None
+ */
+__weak void HAL_NOR_MspWait(NOR_HandleTypeDef *hnor, uint32_t Timeout)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hnor);
+ UNUSED(Timeout);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_NOR_MspWait could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup NOR_Exported_Functions_Group2 Input and Output functions
+ * @brief Input Output and memory control functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### NOR Input and Output functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to use and control the NOR memory
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Read NOR flash IDs
+ * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param pNOR_ID : pointer to NOR ID structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_Read_ID(NOR_HandleTypeDef *hnor, NOR_IDTypeDef *pNOR_ID)
+{
+ uint32_t deviceaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Check the NOR controller state */
+ if(hnor->State == HAL_NOR_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FSMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Send read ID command */
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_AUTO_SELECT);
+
+ /* Read the NOR IDs */
+ pNOR_ID->Manufacturer_Code = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, MC_ADDRESS);
+ pNOR_ID->Device_Code1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE1_ADDR);
+ pNOR_ID->Device_Code2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE2_ADDR);
+ pNOR_ID->Device_Code3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE3_ADDR);
+
+ /* Check the NOR controller state */
+ hnor->State = HAL_NOR_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Returns the NOR memory to Read mode.
+ * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_ReturnToReadMode(NOR_HandleTypeDef *hnor)
+{
+ uint32_t deviceaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Check the NOR controller state */
+ if(hnor->State == HAL_NOR_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FSMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ NOR_WRITE(deviceaddress, NOR_CMD_DATA_READ_RESET);
+
+ /* Check the NOR controller state */
+ hnor->State = HAL_NOR_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Read data from NOR memory
+ * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param pAddress: pointer to Device address
+ * @param pData : pointer to read data
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_Read(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData)
+{
+ uint32_t deviceaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Check the NOR controller state */
+ if(hnor->State == HAL_NOR_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FSMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Send read data command */
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
+ NOR_WRITE((uint32_t)pAddress, NOR_CMD_DATA_READ_RESET);
+
+ /* Read the data */
+ *pData = *(__IO uint32_t *)(uint32_t)pAddress;
+
+ /* Check the NOR controller state */
+ hnor->State = HAL_NOR_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Program data to NOR memory
+ * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param pAddress: Device address
+ * @param pData : pointer to the data to write
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_Program(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData)
+{
+ uint32_t deviceaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Check the NOR controller state */
+ if(hnor->State == HAL_NOR_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FSMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Send program data command */
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_PROGRAM);
+
+ /* Write the data */
+ NOR_WRITE(pAddress, *pData);
+
+ /* Check the NOR controller state */
+ hnor->State = HAL_NOR_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Reads a block of data from the FSMC NOR memory.
+ * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param uwAddress: NOR memory internal address to read from.
+ * @param pData: pointer to the buffer that receives the data read from the
+ * NOR memory.
+ * @param uwBufferSize : number of Half word to read.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_ReadBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize)
+{
+ uint32_t deviceaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Check the NOR controller state */
+ if(hnor->State == HAL_NOR_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FSMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Send read data command */
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
+ NOR_WRITE(uwAddress, NOR_CMD_DATA_READ_RESET);
+
+ /* Read buffer */
+ while( uwBufferSize > 0U)
+ {
+ *pData++ = *(__IO uint16_t *)uwAddress;
+ uwAddress += 2U;
+ uwBufferSize--;
+ }
+
+ /* Check the NOR controller state */
+ hnor->State = HAL_NOR_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Writes a half-word buffer to the FSMC NOR memory. This function
+ * must be used only with S29GL128P NOR memory.
+ * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param uwAddress: NOR memory internal address from which the data
+ * @note Some NOR memory need Address aligned to xx bytes (can be aligned to
+ * 64 bytes boundary for example).
+ * @param pData: pointer to source data buffer.
+ * @param uwBufferSize: number of Half words to write.
+ * @note The maximum buffer size allowed is NOR memory dependent
+ * (can be 64 Bytes max for example).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_ProgramBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize)
+{
+ uint16_t * p_currentaddress = (uint16_t *)NULL;
+ uint16_t * p_endaddress = (uint16_t *)NULL;
+ uint32_t lastloadedaddress = 0U, deviceaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Check the NOR controller state */
+ if(hnor->State == HAL_NOR_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FSMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Initialize variables */
+ p_currentaddress = (uint16_t*)((uint32_t)(uwAddress));
+ p_endaddress = p_currentaddress + (uwBufferSize-1U);
+ lastloadedaddress = (uint32_t)(uwAddress);
+
+ /* Issue unlock command sequence */
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
+
+ /* Write Buffer Load Command */
+ NOR_WRITE((uint32_t)(p_currentaddress), NOR_CMD_DATA_BUFFER_AND_PROG);
+ NOR_WRITE((uint32_t)(p_currentaddress), (uwBufferSize-1U));
+
+ /* Load Data into NOR Buffer */
+ while(p_currentaddress <= p_endaddress)
+ {
+ /* Store last loaded address & data value (for polling) */
+ lastloadedaddress = (uint32_t)p_currentaddress;
+
+ NOR_WRITE(p_currentaddress, *pData++);
+
+ p_currentaddress++;
+ }
+
+ NOR_WRITE((uint32_t)(lastloadedaddress), NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM);
+
+ /* Check the NOR controller state */
+ hnor->State = HAL_NOR_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+
+ return HAL_OK;
+
+}
+
+/**
+ * @brief Erase the specified block of the NOR memory
+ * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param BlockAddress : Block to erase address
+ * @param Address: Device address
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_Erase_Block(NOR_HandleTypeDef *hnor, uint32_t BlockAddress, uint32_t Address)
+{
+ uint32_t deviceaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Check the NOR controller state */
+ if(hnor->State == HAL_NOR_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FSMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Send block erase command sequence */
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);
+ NOR_WRITE((uint32_t)(BlockAddress + Address), NOR_CMD_DATA_BLOCK_ERASE);
+
+ /* Check the NOR memory status and update the controller state */
+ hnor->State = HAL_NOR_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+
+ return HAL_OK;
+
+}
+
+/**
+ * @brief Erase the entire NOR chip.
+ * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param Address : Device address
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_Erase_Chip(NOR_HandleTypeDef *hnor, uint32_t Address)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(Address);
+
+ uint32_t deviceaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Check the NOR controller state */
+ if(hnor->State == HAL_NOR_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FSMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Send NOR chip erase command sequence */
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SIXTH), NOR_CMD_DATA_CHIP_ERASE);
+
+ /* Check the NOR memory status and update the controller state */
+ hnor->State = HAL_NOR_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Read NOR flash CFI IDs
+ * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param pNOR_CFI : pointer to NOR CFI IDs structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_Read_CFI(NOR_HandleTypeDef *hnor, NOR_CFITypeDef *pNOR_CFI)
+{
+ uint32_t deviceaddress = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Check the NOR controller state */
+ if(hnor->State == HAL_NOR_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Select the NOR device address */
+ if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS1;
+ }
+ else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS2;
+ }
+ else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
+ {
+ deviceaddress = NOR_MEMORY_ADRESS3;
+ }
+ else /* FSMC_NORSRAM_BANK4 */
+ {
+ deviceaddress = NOR_MEMORY_ADRESS4;
+ }
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Send read CFI query command */
+ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI), NOR_CMD_DATA_CFI);
+
+ /* read the NOR CFI information */
+ pNOR_CFI->CFI_1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI1_ADDRESS);
+ pNOR_CFI->CFI_2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI2_ADDRESS);
+ pNOR_CFI->CFI_3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI3_ADDRESS);
+ pNOR_CFI->CFI_4 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI4_ADDRESS);
+
+ /* Check the NOR controller state */
+ hnor->State = HAL_NOR_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup NOR_Exported_Functions_Group3 Control functions
+ * @brief management functions
+ *
+@verbatim
+ ==============================================================================
+ ##### NOR Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control dynamically
+ the NOR interface.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables dynamically NOR write operation.
+ * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_WriteOperation_Enable(NOR_HandleTypeDef *hnor)
+{
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Enable write operation */
+ FSMC_NORSRAM_WriteOperation_Enable(hnor->Instance, hnor->Init.NSBank);
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically NOR write operation.
+ * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_NOR_WriteOperation_Disable(NOR_HandleTypeDef *hnor)
+{
+ /* Process Locked */
+ __HAL_LOCK(hnor);
+
+ /* Update the SRAM controller state */
+ hnor->State = HAL_NOR_STATE_BUSY;
+
+ /* Disable write operation */
+ FSMC_NORSRAM_WriteOperation_Disable(hnor->Instance, hnor->Init.NSBank);
+
+ /* Update the NOR controller state */
+ hnor->State = HAL_NOR_STATE_PROTECTED;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hnor);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup NOR_Exported_Functions_Group4 State functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ==============================================================================
+ ##### NOR State functions #####
+ ==============================================================================
+ [..]
+ This subsection permits to get in run-time the status of the NOR controller
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief return the NOR controller state
+ * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @retval NOR controller state
+ */
+HAL_NOR_StateTypeDef HAL_NOR_GetState(NOR_HandleTypeDef *hnor)
+{
+ return hnor->State;
+}
+
+/**
+ * @brief Returns the NOR operation status.
+ * @param hnor: pointer to a NOR_HandleTypeDef structure that contains
+ * the configuration information for NOR module.
+ * @param Address: Device address
+ * @param Timeout: NOR progamming Timeout
+ * @retval NOR_Status: The returned value can be: HAL_NOR_STATUS_SUCCESS, HAL_NOR_STATUS_ERROR
+ * or HAL_NOR_STATUS_TIMEOUT
+ */
+HAL_NOR_StatusTypeDef HAL_NOR_GetStatus(NOR_HandleTypeDef *hnor, uint32_t Address, uint32_t Timeout)
+{
+ HAL_NOR_StatusTypeDef status = HAL_NOR_STATUS_ONGOING;
+ uint16_t tmp_sr1 = 0, tmp_sr2 = 0;
+ uint32_t tickstart = 0U;
+
+ /* Poll on NOR memory Ready/Busy signal ------------------------------------*/
+ HAL_NOR_MspWait(hnor, Timeout);
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+ while((status != HAL_NOR_STATUS_SUCCESS) && (status != HAL_NOR_STATUS_TIMEOUT))
+ {
+ /* Check for the Timeout */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
+ {
+ status = HAL_NOR_STATUS_TIMEOUT;
+ }
+ }
+
+ /* Read NOR status register (DQ6 and DQ5) */
+ tmp_sr1 = *(__IO uint16_t *)Address;
+ tmp_sr2 = *(__IO uint16_t *)Address;
+
+ /* If DQ6 did not toggle between the two reads then return NOR_Success */
+ if((tmp_sr1 & NOR_MASK_STATUS_DQ6) == (tmp_sr2 & NOR_MASK_STATUS_DQ6))
+ {
+ return HAL_NOR_STATUS_SUCCESS;
+ }
+
+ if((tmp_sr1 & NOR_MASK_STATUS_DQ5) != NOR_MASK_STATUS_DQ5)
+ {
+ status = HAL_NOR_STATUS_ONGOING;
+ }
+
+ tmp_sr1 = *(__IO uint16_t *)Address;
+ tmp_sr2 = *(__IO uint16_t *)Address;
+
+ /* If DQ6 did not toggle between the two reads then return NOR_Success */
+ if((tmp_sr1 & NOR_MASK_STATUS_DQ6) == (tmp_sr2 & NOR_MASK_STATUS_DQ6))
+ {
+ return HAL_NOR_STATUS_SUCCESS;
+ }
+ else if((tmp_sr1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5)
+ {
+ return HAL_NOR_STATUS_ERROR;
+ }
+ }
+
+ /* Return the operation status */
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/**
+ * @}
+ */
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG || STM32F100xE */
+#endif /* HAL_NOR_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pccard.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pccard.c
new file mode 100644
index 0000000..0cf076d
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pccard.c
@@ -0,0 +1,746 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_pccard.c
+ * @author MCD Application Team
+ * @brief PCCARD HAL module driver.
+ * This file provides a generic firmware to drive PCCARD memories mounted
+ * as external device.
+ *
+ @verbatim
+ ===============================================================================
+ ##### How to use this driver #####
+ ===============================================================================
+ [..]
+ This driver is a generic layered driver which contains a set of APIs used to
+ control PCCARD/compact flash memories. It uses the FSMC/FSMC layer functions
+ to interface with PCCARD devices. This driver is used for:
+
+ (+) PCCARD/compact flash memory configuration sequence using the function
+ HAL_PCCARD_Init() with control and timing parameters for both common and
+ attribute spaces.
+
+ (+) Read PCCARD/compact flash memory maker and device IDs using the function
+ HAL_PCCARD_Read_ID(). The read information is stored in the CompactFlash_ID
+ structure declared by the function caller.
+
+ (+) Access PCCARD/compact flash memory by read/write operations using the functions
+ HAL_PCCARD_Read_Sector()/HAL_PCCARD_Write_Sector(), to read/write sector.
+
+ (+) Perform PCCARD/compact flash Reset chip operation using the function HAL_PCCARD_Reset().
+
+ (+) Perform PCCARD/compact flash erase sector operation using the function
+ HAL_PCCARD_Erase_Sector().
+
+ (+) Read the PCCARD/compact flash status operation using the function HAL_PCCARD_ReadStatus().
+
+ (+) You can monitor the PCCARD/compact flash device HAL state by calling the function
+ HAL_PCCARD_GetState()
+
+ [..]
+ (@) This driver is a set of generic APIs which handle standard PCCARD/compact flash
+ operations. If a PCCARD/compact flash device contains different operations
+ and/or implementations, it should be implemented separately.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_PCCARD_MODULE_ENABLED
+#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG)
+
+/** @defgroup PCCARD PCCARD
+ * @brief PCCARD HAL module driver
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup PCCARD_Private_Constants PCCARD Private Constants
+ * @{
+ */
+
+#define PCCARD_TIMEOUT_READ_ID 0x0000FFFFU
+#define PCCARD_TIMEOUT_SECTOR 0x0000FFFFU
+#define PCCARD_TIMEOUT_STATUS 0x01000000U
+
+#define PCCARD_STATUS_OK (uint8_t)0x58
+#define PCCARD_STATUS_WRITE_OK (uint8_t)0x50
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions ---------------------------------------------------------*/
+
+/** @defgroup PCCARD_Exported_Functions PCCARD Exported Functions
+ * @{
+ */
+
+/** @defgroup PCCARD_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### PCCARD Initialization and de-initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to initialize/de-initialize
+ the PCCARD memory
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Perform the PCCARD memory Initialization sequence
+ * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @param ComSpaceTiming: Common space timing structure
+ * @param AttSpaceTiming: Attribute space timing structure
+ * @param IOSpaceTiming: IO space timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCCARD_Init(PCCARD_HandleTypeDef *hpccard, FSMC_NAND_PCC_TimingTypeDef *ComSpaceTiming, FSMC_NAND_PCC_TimingTypeDef *AttSpaceTiming, FSMC_NAND_PCC_TimingTypeDef *IOSpaceTiming)
+{
+ /* Check the PCCARD controller state */
+ if(hpccard == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if(hpccard->State == HAL_PCCARD_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hpccard->Lock = HAL_UNLOCKED;
+
+ /* Initialize the low level hardware (MSP) */
+ HAL_PCCARD_MspInit(hpccard);
+ }
+
+ /* Initialize the PCCARD state */
+ hpccard->State = HAL_PCCARD_STATE_BUSY;
+
+ /* Initialize PCCARD control Interface */
+ FSMC_PCCARD_Init(hpccard->Instance, &(hpccard->Init));
+
+ /* Init PCCARD common space timing Interface */
+ FSMC_PCCARD_CommonSpace_Timing_Init(hpccard->Instance, ComSpaceTiming);
+
+ /* Init PCCARD attribute space timing Interface */
+ FSMC_PCCARD_AttributeSpace_Timing_Init(hpccard->Instance, AttSpaceTiming);
+
+ /* Init PCCARD IO space timing Interface */
+ FSMC_PCCARD_IOSpace_Timing_Init(hpccard->Instance, IOSpaceTiming);
+
+ /* Enable the PCCARD device */
+ __FSMC_PCCARD_ENABLE(hpccard->Instance);
+
+ /* Update the PCCARD state */
+ hpccard->State = HAL_PCCARD_STATE_READY;
+
+ return HAL_OK;
+
+}
+
+/**
+ * @brief Perform the PCCARD memory De-initialization sequence
+ * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCCARD_DeInit(PCCARD_HandleTypeDef *hpccard)
+{
+ /* De-Initialize the low level hardware (MSP) */
+ HAL_PCCARD_MspDeInit(hpccard);
+
+ /* Configure the PCCARD registers with their reset values */
+ FSMC_PCCARD_DeInit(hpccard->Instance);
+
+ /* Update the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hpccard);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief PCCARD MSP Init
+ * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @retval None
+ */
+__weak void HAL_PCCARD_MspInit(PCCARD_HandleTypeDef *hpccard)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpccard);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_PCCARD_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief PCCARD MSP DeInit
+ * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @retval None
+ */
+__weak void HAL_PCCARD_MspDeInit(PCCARD_HandleTypeDef *hpccard)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpccard);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_PCCARD_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup PCCARD_Exported_Functions_Group2 Input Output and memory functions
+ * @brief Input Output and memory control functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### PCCARD Input Output and memory functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to use and control the PCCARD memory
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Read Compact Flash's ID.
+ * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @param CompactFlash_ID: Compact flash ID structure.
+ * @param pStatus: pointer to compact flash status
+ * @retval HAL status
+ *
+ */
+HAL_StatusTypeDef HAL_PCCARD_Read_ID(PCCARD_HandleTypeDef *hpccard, uint8_t CompactFlash_ID[], uint8_t *pStatus)
+{
+ uint32_t timeout = PCCARD_TIMEOUT_READ_ID, index = 0U;
+ uint8_t status = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hpccard);
+
+ /* Check the PCCARD controller state */
+ if(hpccard->State == HAL_PCCARD_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Update the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_BUSY;
+
+ /* Initialize the CF status */
+ *pStatus = PCCARD_READY;
+
+ /* Send the Identify Command */
+ *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD) = 0xECECU;
+
+ /* Read CF IDs and timeout treatment */
+ do
+ {
+ /* Read the CF status */
+ status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+
+ timeout--;
+ }while((status != PCCARD_STATUS_OK) && timeout);
+
+ if(timeout == 0U)
+ {
+ *pStatus = PCCARD_TIMEOUT_ERROR;
+ }
+ else
+ {
+ /* Read CF ID bytes */
+ for(index = 0U; index < 16U; index++)
+ {
+ CompactFlash_ID[index] = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_DATA);
+ }
+ }
+
+ /* Update the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hpccard);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Read sector from PCCARD memory
+ * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @param pBuffer: pointer to destination read buffer
+ * @param SectorAddress: Sector address to read
+ * @param pStatus: pointer to CF status
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCCARD_Read_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress, uint8_t *pStatus)
+{
+ uint32_t timeout = PCCARD_TIMEOUT_SECTOR, index = 0U;
+ uint8_t status = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hpccard);
+
+ /* Check the PCCARD controller state */
+ if(hpccard->State == HAL_PCCARD_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Update the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_BUSY;
+
+ /* Initialize CF status */
+ *pStatus = PCCARD_READY;
+
+ /* Set the parameters to write a sector */
+ *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_HIGH) = (uint16_t)0x00;
+ *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_COUNT) = ((uint16_t)0x0100) | ((uint16_t)SectorAddress);
+ *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD) = (uint16_t)0xE4A0;
+
+ do
+ {
+ /* wait till the Status = 0x80 */
+ status = *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+ timeout--;
+ }while((status == 0x80U) && timeout);
+
+ if(timeout == 0U)
+ {
+ *pStatus = PCCARD_TIMEOUT_ERROR;
+ }
+
+ timeout = 0xFFFFU;
+
+ do
+ {
+ /* wait till the Status = PCCARD_STATUS_OK */
+ status = *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+ timeout--;
+ }while((status != PCCARD_STATUS_OK) && timeout);
+
+ if(timeout == 0U)
+ {
+ *pStatus = PCCARD_TIMEOUT_ERROR;
+ }
+
+ /* Read bytes */
+ for(; index < PCCARD_SECTOR_SIZE; index++)
+ {
+ *(uint16_t *)pBuffer++ = *(uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR);
+ }
+
+ /* Update the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hpccard);
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Write sector to PCCARD memory
+ * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @param pBuffer: pointer to source write buffer
+ * @param SectorAddress: Sector address to write
+ * @param pStatus: pointer to CF status
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCCARD_Write_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress, uint8_t *pStatus)
+{
+ uint32_t timeout = PCCARD_TIMEOUT_SECTOR, index = 0U;
+ uint8_t status = 0U;
+
+ /* Process Locked */
+ __HAL_LOCK(hpccard);
+
+ /* Check the PCCARD controller state */
+ if(hpccard->State == HAL_PCCARD_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Update the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_BUSY;
+
+ /* Initialize CF status */
+ *pStatus = PCCARD_READY;
+
+ /* Set the parameters to write a sector */
+ *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_HIGH) = (uint16_t)0x00;
+ *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_COUNT) = ((uint16_t)0x0100) | ((uint16_t)SectorAddress);
+ *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD) = (uint16_t)0x30A0;
+
+ do
+ {
+ /* Wait till the Status = PCCARD_STATUS_OK */
+ status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+ timeout--;
+ }while((status != PCCARD_STATUS_OK) && timeout);
+
+ if(timeout == 0U)
+ {
+ *pStatus = PCCARD_TIMEOUT_ERROR;
+ }
+
+ /* Write bytes */
+ for(; index < PCCARD_SECTOR_SIZE; index++)
+ {
+ *(uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR) = *(uint16_t *)pBuffer++;
+ }
+
+ do
+ {
+ /* Wait till the Status = PCCARD_STATUS_WRITE_OK */
+ status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+ timeout--;
+ }while((status != PCCARD_STATUS_WRITE_OK) && timeout);
+
+ if(timeout == 0U)
+ {
+ *pStatus = PCCARD_TIMEOUT_ERROR;
+ }
+
+ /* Update the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hpccard);
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Erase sector from PCCARD memory
+ * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @param SectorAddress: Sector address to erase
+ * @param pStatus: pointer to CF status
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCCARD_Erase_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t SectorAddress, uint8_t *pStatus)
+{
+ uint32_t timeout = 0x400U;
+ uint8_t status = 0;
+
+ /* Process Locked */
+ __HAL_LOCK(hpccard);
+
+ /* Check the PCCARD controller state */
+ if(hpccard->State == HAL_PCCARD_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Update the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_BUSY;
+
+ /* Initialize CF status */
+ *pStatus = PCCARD_READY;
+
+ /* Set the parameters to write a sector */
+ *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_LOW) = 0x00;
+ *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_HIGH) = 0x00;
+ *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_NUMBER) = SectorAddress;
+ *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_COUNT) = 0x01;
+ *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CARD_HEAD) = 0xA0;
+ *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD) = ATA_ERASE_SECTOR_CMD;
+
+ /* wait till the CF is ready */
+ status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+
+ while((status != PCCARD_STATUS_WRITE_OK) && timeout)
+ {
+ status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+ timeout--;
+ }
+
+ if(timeout == 0U)
+ {
+ *pStatus = PCCARD_TIMEOUT_ERROR;
+ }
+
+ /* Check the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hpccard);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Reset the PCCARD memory
+ * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCCARD_Reset(PCCARD_HandleTypeDef *hpccard)
+{
+ /* Process Locked */
+ __HAL_LOCK(hpccard);
+
+ /* Check the PCCARD controller state */
+ if(hpccard->State == HAL_PCCARD_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Provide an SW reset and Read and verify the:
+ - CF Configuration Option Register at address 0x98000200 --> 0x80
+ - Card Configuration and Status Register at address 0x98000202 --> 0x00
+ - Pin Replacement Register at address 0x98000204 --> 0x0C
+ - Socket and Copy Register at address 0x98000206 --> 0x00
+ */
+
+ /* Check the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_BUSY;
+
+ *(__IO uint8_t *)(PCCARD_ATTRIBUTE_SPACE_ADDRESS | ATA_CARD_CONFIGURATION) = 0x01;
+
+ /* Check the PCCARD controller state */
+ hpccard->State = HAL_PCCARD_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hpccard);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles PCCARD device interrupt request.
+ * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @retval HAL status
+*/
+void HAL_PCCARD_IRQHandler(PCCARD_HandleTypeDef *hpccard)
+{
+ /* Check PCCARD interrupt Rising edge flag */
+ if(__FSMC_PCCARD_GET_FLAG(hpccard->Instance, FSMC_FLAG_RISING_EDGE))
+ {
+ /* PCCARD interrupt callback*/
+ HAL_PCCARD_ITCallback(hpccard);
+
+ /* Clear PCCARD interrupt Rising edge pending bit */
+ __FSMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FSMC_FLAG_RISING_EDGE);
+ }
+
+ /* Check PCCARD interrupt Level flag */
+ if(__FSMC_PCCARD_GET_FLAG(hpccard->Instance, FSMC_FLAG_LEVEL))
+ {
+ /* PCCARD interrupt callback*/
+ HAL_PCCARD_ITCallback(hpccard);
+
+ /* Clear PCCARD interrupt Level pending bit */
+ __FSMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FSMC_FLAG_LEVEL);
+ }
+
+ /* Check PCCARD interrupt Falling edge flag */
+ if(__FSMC_PCCARD_GET_FLAG(hpccard->Instance, FSMC_FLAG_FALLING_EDGE))
+ {
+ /* PCCARD interrupt callback*/
+ HAL_PCCARD_ITCallback(hpccard);
+
+ /* Clear PCCARD interrupt Falling edge pending bit */
+ __FSMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FSMC_FLAG_FALLING_EDGE);
+ }
+
+ /* Check PCCARD interrupt FIFO empty flag */
+ if(__FSMC_PCCARD_GET_FLAG(hpccard->Instance, FSMC_FLAG_FEMPT))
+ {
+ /* PCCARD interrupt callback*/
+ HAL_PCCARD_ITCallback(hpccard);
+
+ /* Clear PCCARD interrupt FIFO empty pending bit */
+ __FSMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FSMC_FLAG_FEMPT);
+ }
+
+}
+
+/**
+ * @brief PCCARD interrupt feature callback
+ * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @retval None
+ */
+__weak void HAL_PCCARD_ITCallback(PCCARD_HandleTypeDef *hpccard)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpccard);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_PCCARD_ITCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup PCCARD_Exported_Functions_Group3 Peripheral State functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ==============================================================================
+ ##### PCCARD Peripheral State functions #####
+ ==============================================================================
+ [..]
+ This subsection permits to get in run-time the status of the PCCARD controller
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief return the PCCARD controller state
+ * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @retval HAL state
+ */
+HAL_PCCARD_StateTypeDef HAL_PCCARD_GetState(PCCARD_HandleTypeDef *hpccard)
+{
+ return hpccard->State;
+}
+
+/**
+ * @brief Get the compact flash memory status
+ * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @retval New status of the CF operation. This parameter can be:
+ * - CompactFlash_TIMEOUT_ERROR: when the previous operation generate
+ * a Timeout error
+ * - CompactFlash_READY: when memory is ready for the next operation
+ *
+ */
+HAL_PCCARD_StatusTypeDef HAL_PCCARD_GetStatus(PCCARD_HandleTypeDef *hpccard)
+{
+ uint32_t timeout = PCCARD_TIMEOUT_STATUS, status_cf = 0;
+
+ /* Check the PCCARD controller state */
+ if(hpccard->State == HAL_PCCARD_STATE_BUSY)
+ {
+ return HAL_PCCARD_STATUS_ONGOING;
+ }
+
+ status_cf = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+
+ while((status_cf == PCCARD_BUSY) && timeout)
+ {
+ status_cf = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+ timeout--;
+ }
+
+ if(timeout == 0U)
+ {
+ status_cf = PCCARD_TIMEOUT_ERROR;
+ }
+
+ /* Return the operation status */
+ return (HAL_PCCARD_StatusTypeDef) status_cf;
+}
+
+/**
+ * @brief Reads the Compact Flash memory status using the Read status command
+ * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains
+ * the configuration information for PCCARD module.
+ * @retval The status of the Compact Flash memory. This parameter can be:
+ * - CompactFlash_BUSY: when memory is busy
+ * - CompactFlash_READY: when memory is ready for the next operation
+ * - CompactFlash_ERROR: when the previous operation gererates error
+ */
+HAL_PCCARD_StatusTypeDef HAL_PCCARD_ReadStatus(PCCARD_HandleTypeDef *hpccard)
+{
+ uint8_t data = 0U, status_cf = PCCARD_BUSY;
+
+ /* Check the PCCARD controller state */
+ if(hpccard->State == HAL_PCCARD_STATE_BUSY)
+ {
+ return HAL_PCCARD_STATUS_ONGOING;
+ }
+
+ /* Read status operation */
+ data = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE);
+
+ if((data & PCCARD_TIMEOUT_ERROR) == PCCARD_TIMEOUT_ERROR)
+ {
+ status_cf = PCCARD_TIMEOUT_ERROR;
+ }
+ else if((data & PCCARD_READY) == PCCARD_READY)
+ {
+ status_cf = PCCARD_READY;
+ }
+
+ return (HAL_PCCARD_StatusTypeDef) status_cf;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/**
+ * @}
+ */
+
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+#endif /* HAL_PCCARD_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd.c
new file mode 100644
index 0000000..ca32983
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd.c
@@ -0,0 +1,1424 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_pcd.c
+ * @author MCD Application Team
+ * @brief PCD HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the USB Peripheral Controller:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ * + Peripheral State functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The PCD HAL driver can be used as follows:
+
+ (#) Declare a PCD_HandleTypeDef handle structure, for example:
+ PCD_HandleTypeDef hpcd;
+
+ (#) Fill parameters of Init structure in HCD handle
+
+ (#) Call HAL_PCD_Init() API to initialize the HCD peripheral (Core, Device core, ...)
+
+ (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:
+ (##) Enable the PCD/USB Low Level interface clock using the following macro
+ (+++) __HAL_RCC_USB_CLK_ENABLE(); For USB Device FS peripheral available
+ on STM32F102xx and STM32F103xx devices
+ (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); For USB OTG FS peripheral available
+ on STM32F105xx and STM32F107xx devices
+
+ (##) Initialize the related GPIO clocks
+ (##) Configure PCD pin-out
+ (##) Configure PCD NVIC interrupt
+
+ (#)Associate the Upper USB device stack to the HAL PCD Driver:
+ (##) hpcd.pData = pdev;
+
+ (#)Enable HCD transmission and reception:
+ (##) HAL_PCD_Start();
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+
+
+#ifdef HAL_PCD_MODULE_ENABLED
+
+#if defined(STM32F102x6) || defined(STM32F102xB) || \
+ defined(STM32F103x6) || defined(STM32F103xB) || \
+ defined(STM32F103xE) || defined(STM32F103xG) || \
+ defined(STM32F105xC) || defined(STM32F107xC)
+
+/** @defgroup PCD PCD
+ * @brief PCD HAL module driver
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup PCD_Private_Macros PCD Private Macros
+ * @{
+ */
+#define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b))
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup PCD_Private_Functions PCD Private Functions
+ * @{
+ */
+#if defined (USB_OTG_FS)
+static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
+#endif /* USB_OTG_FS */
+
+#if defined (USB)
+static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
+#endif /* USB */
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup PCD_Exported_Functions PCD Exported Functions
+ * @{
+ */
+
+/** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the PCD according to the specified
+ * parameters in the PCD_InitTypeDef and create the associated handle.
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
+{
+ uint32_t index = 0U;
+
+ /* Check the PCD handle allocation */
+ if(hpcd == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
+
+ if(hpcd->State == HAL_PCD_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hpcd->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware : GPIO, CLOCK, NVIC... */
+ HAL_PCD_MspInit(hpcd);
+ }
+
+ hpcd->State = HAL_PCD_STATE_BUSY;
+
+ /* Disable the Interrupts */
+ __HAL_PCD_DISABLE(hpcd);
+
+ /*Init the Core (common init.) */
+ USB_CoreInit(hpcd->Instance, hpcd->Init);
+
+ /* Force Device Mode*/
+ USB_SetCurrentMode(hpcd->Instance , USB_DEVICE_MODE);
+
+ /* Init endpoints structures */
+ for (index = 0U; index < 15U ; index++)
+ {
+ /* Init ep structure */
+ hpcd->IN_ep[index].is_in = 1U;
+ hpcd->IN_ep[index].num = index;
+ hpcd->IN_ep[index].tx_fifo_num = index;
+ /* Control until ep is actvated */
+ hpcd->IN_ep[index].type = EP_TYPE_CTRL;
+ hpcd->IN_ep[index].maxpacket = 0U;
+ hpcd->IN_ep[index].xfer_buff = 0U;
+ hpcd->IN_ep[index].xfer_len = 0U;
+ }
+
+ for (index = 0U; index < 15U ; index++)
+ {
+ hpcd->OUT_ep[index].is_in = 0U;
+ hpcd->OUT_ep[index].num = index;
+ hpcd->IN_ep[index].tx_fifo_num = index;
+ /* Control until ep is activated */
+ hpcd->OUT_ep[index].type = EP_TYPE_CTRL;
+ hpcd->OUT_ep[index].maxpacket = 0U;
+ hpcd->OUT_ep[index].xfer_buff = 0U;
+ hpcd->OUT_ep[index].xfer_len = 0U;
+ }
+
+ /* Init Device */
+ USB_DevInit(hpcd->Instance, hpcd->Init);
+
+ hpcd->USB_Address = 0U;
+ hpcd->State= HAL_PCD_STATE_READY;
+
+ USB_DevDisconnect (hpcd->Instance);
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the PCD peripheral
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
+{
+ /* Check the PCD handle allocation */
+ if(hpcd == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ hpcd->State = HAL_PCD_STATE_BUSY;
+
+ /* Stop Device */
+ HAL_PCD_Stop(hpcd);
+
+ /* DeInit the low level hardware */
+ HAL_PCD_MspDeInit(hpcd);
+
+ hpcd->State = HAL_PCD_STATE_RESET;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the PCD MSP.
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+__weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes PCD MSP.
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+__weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup PCD_Exported_Functions_Group2 IO operation functions
+ * @brief Data transfers functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the PCD data
+ transfers.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Start The USB Device.
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
+{
+ __HAL_LOCK(hpcd);
+ HAL_PCDEx_SetConnectionState (hpcd, 1);
+ USB_DevConnect (hpcd->Instance);
+ __HAL_PCD_ENABLE(hpcd);
+ __HAL_UNLOCK(hpcd);
+ return HAL_OK;
+}
+
+/**
+ * @brief Stop The USB Device.
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
+{
+ __HAL_LOCK(hpcd);
+ __HAL_PCD_DISABLE(hpcd);
+ USB_StopDevice(hpcd->Instance);
+ USB_DevDisconnect (hpcd->Instance);
+ __HAL_UNLOCK(hpcd);
+ return HAL_OK;
+}
+
+#if defined (USB_OTG_FS)
+/**
+ * @brief This function handles PCD interrupt request.
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
+{
+ USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
+ uint32_t index = 0U, ep_intr = 0U, epint = 0U, epnum = 0U;
+ uint32_t fifoemptymsk = 0U, temp = 0U;
+ USB_OTG_EPTypeDef *ep = NULL;
+
+ /* ensure that we are in device mode */
+ if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
+ {
+ /* avoid spurious interrupt */
+ if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
+ {
+ return;
+ }
+
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
+ {
+ /* incorrect mode, acknowledge the interrupt */
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
+ }
+
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
+ {
+ epnum = 0U;
+
+ /* Read in the device interrupt bits */
+ ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
+
+ while ( ep_intr )
+ {
+ if (ep_intr & 0x1U)
+ {
+ epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum);
+
+ if(( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
+ {
+ CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
+
+ HAL_PCD_DataOutStageCallback(hpcd, epnum);
+ }
+
+ if(( epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
+ {
+ /* Inform the upper layer that a setup packet is available */
+ HAL_PCD_SetupStageCallback(hpcd);
+ CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
+ }
+
+ if(( epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
+ {
+ CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
+ }
+ }
+ epnum++;
+ ep_intr >>= 1U;
+ }
+ }
+
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
+ {
+ /* Read in the device interrupt bits */
+ ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
+
+ epnum = 0U;
+
+ while ( ep_intr )
+ {
+ if (ep_intr & 0x1U) /* In ITR */
+ {
+ epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum);
+
+ if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
+ {
+ fifoemptymsk = 0x1U << epnum;
+ USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
+
+ CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
+
+ HAL_PCD_DataInStageCallback(hpcd, epnum);
+ }
+ if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
+ {
+ CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
+ }
+ if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
+ {
+ CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
+ }
+ if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
+ {
+ CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
+ }
+ if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
+ {
+ CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
+ }
+ if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
+ {
+ PCD_WriteEmptyTxFifo(hpcd , epnum);
+ }
+ }
+ epnum++;
+ ep_intr >>= 1U;
+ }
+ }
+
+ /* Handle Resume Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
+ {
+ /* Clear the Remote Wake-up signalling */
+ USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
+
+ HAL_PCD_ResumeCallback(hpcd);
+
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
+ }
+
+ /* Handle Suspend Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
+ {
+ if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
+ {
+
+ HAL_PCD_SuspendCallback(hpcd);
+ }
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
+ }
+
+ /* Handle Reset Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
+ {
+ USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
+ USB_FlushTxFifo(hpcd->Instance , 0x10U);
+
+ for (index = 0U; index < hpcd->Init.dev_endpoints ; index++)
+ {
+ USBx_INEP(index)->DIEPINT = 0xFFU;
+ USBx_OUTEP(index)->DOEPINT = 0xFFU;
+ }
+ USBx_DEVICE->DAINT = 0xFFFFFFFFU;
+ USBx_DEVICE->DAINTMSK |= 0x10001U;
+
+ USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
+ USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
+
+ /* Set Default Address to 0 */
+ USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
+
+ /* setup EP0 to receive SETUP packets */
+ USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
+
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
+ }
+
+ /* Handle Enumeration done Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
+ {
+ USB_ActivateSetup(hpcd->Instance);
+ hpcd->Instance->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
+
+ hpcd->Init.speed = USB_OTG_SPEED_FULL;
+ hpcd->Init.ep0_mps = USB_OTG_FS_MAX_PACKET_SIZE ;
+ hpcd->Instance->GUSBCFG |= (uint32_t)((USBD_FS_TRDT_VALUE << 10U) & USB_OTG_GUSBCFG_TRDT);
+
+ HAL_PCD_ResetCallback(hpcd);
+
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
+ }
+
+ /* Handle RxQLevel Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
+ {
+ USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
+ temp = USBx->GRXSTSP;
+ ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
+
+ if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) == STS_DATA_UPDT)
+ {
+ if((temp & USB_OTG_GRXSTSP_BCNT) != 0U)
+ {
+ USB_ReadPacket(USBx, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4U);
+ ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
+ ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
+ }
+ }
+ else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) == STS_SETUP_UPDT)
+ {
+ USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
+ ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
+ }
+ USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
+ }
+
+ /* Handle SOF Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
+ {
+ HAL_PCD_SOFCallback(hpcd);
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
+ }
+
+ /* Handle Incomplete ISO IN Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
+ {
+ HAL_PCD_ISOINIncompleteCallback(hpcd, epnum);
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
+ }
+
+ /* Handle Incomplete ISO OUT Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
+ {
+ HAL_PCD_ISOOUTIncompleteCallback(hpcd, epnum);
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
+ }
+
+ /* Handle Connection event Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
+ {
+ HAL_PCD_ConnectCallback(hpcd);
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
+ }
+
+ /* Handle Disconnection event Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
+ {
+ temp = hpcd->Instance->GOTGINT;
+
+ if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
+ {
+ HAL_PCD_DisconnectCallback(hpcd);
+ }
+ hpcd->Instance->GOTGINT |= temp;
+ }
+ }
+}
+#endif /* USB_OTG_FS */
+
+#if defined (USB)
+/**
+ * @brief This function handles PCD interrupt request.
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
+{
+ if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_CTR))
+ {
+ /* servicing of the endpoint correct transfer interrupt */
+ /* clear of the CTR flag into the sub */
+ PCD_EP_ISR_Handler(hpcd);
+ }
+
+ if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_RESET))
+ {
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
+ HAL_PCD_ResetCallback(hpcd);
+ HAL_PCD_SetAddress(hpcd, 0U);
+ }
+
+ if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_PMAOVR))
+ {
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
+ }
+ if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ERR))
+ {
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
+ }
+
+ if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP))
+ {
+ hpcd->Instance->CNTR &= ~(USB_CNTR_LP_MODE);
+ hpcd->Instance->CNTR &= ~(USB_CNTR_FSUSP);
+
+ HAL_PCD_ResumeCallback(hpcd);
+
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
+ }
+
+ if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SUSP))
+ {
+ /* Force low-power mode in the macrocell */
+ hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
+
+ /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
+
+ hpcd->Instance->CNTR |= USB_CNTR_LP_MODE;
+ if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP) == 0U)
+ {
+ HAL_PCD_SuspendCallback(hpcd);
+ }
+ }
+
+ if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SOF))
+ {
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
+ HAL_PCD_SOFCallback(hpcd);
+ }
+
+ if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ESOF))
+ {
+ /* clear ESOF flag in ISTR */
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
+ }
+}
+#endif /* USB */
+
+/**
+ * @brief Data out stage callbacks
+ * @param hpcd: PCD handle
+ * @param epnum: endpoint number
+ * @retval None
+ */
+ __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ UNUSED(epnum);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_DataOutStageCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Data IN stage callbacks
+ * @param hpcd: PCD handle
+ * @param epnum: endpoint number
+ * @retval None
+ */
+ __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ UNUSED(epnum);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_DataInStageCallback could be implemented in the user file
+ */
+}
+/**
+ * @brief Setup stage callback
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+ __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_SetupStageCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief USB Start Of Frame callbacks
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+ __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_SOFCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief USB Reset callbacks
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+ __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_ResetCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Suspend event callbacks
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+ __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_SuspendCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Resume event callbacks
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+ __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_ResumeCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Incomplete ISO OUT callbacks
+ * @param hpcd: PCD handle
+ * @param epnum: endpoint number
+ * @retval None
+ */
+ __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ UNUSED(epnum);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Incomplete ISO IN callbacks
+ * @param hpcd: PCD handle
+ * @param epnum: endpoint number
+ * @retval None
+ */
+ __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ UNUSED(epnum);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Connection event callbacks
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+ __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_ConnectCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Disconnection event callbacks
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+ __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_DisconnectCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
+ * @brief management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the PCD data
+ transfers.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Connect the USB device
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
+{
+ __HAL_LOCK(hpcd);
+ HAL_PCDEx_SetConnectionState (hpcd, 1);
+ USB_DevConnect(hpcd->Instance);
+ __HAL_UNLOCK(hpcd);
+ return HAL_OK;
+}
+
+/**
+ * @brief Disconnect the USB device
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
+{
+ __HAL_LOCK(hpcd);
+ HAL_PCDEx_SetConnectionState (hpcd, 0U);
+ USB_DevDisconnect(hpcd->Instance);
+ __HAL_UNLOCK(hpcd);
+ return HAL_OK;
+}
+
+/**
+ * @brief Set the USB Device address
+ * @param hpcd: PCD handle
+ * @param address: new device address
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
+{
+ __HAL_LOCK(hpcd);
+ hpcd->USB_Address = address;
+ USB_SetDevAddress(hpcd->Instance, address);
+ __HAL_UNLOCK(hpcd);
+ return HAL_OK;
+}
+/**
+ * @brief Open and configure an endpoint
+ * @param hpcd: PCD handle
+ * @param ep_addr: endpoint address
+ * @param ep_mps: endpoint max packet size
+ * @param ep_type: endpoint type
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
+{
+ HAL_StatusTypeDef ret = HAL_OK;
+ PCD_EPTypeDef *ep = NULL;
+
+ if ((ep_addr & 0x80U) == 0x80U)
+ {
+ ep = &hpcd->IN_ep[ep_addr & 0x7FU];
+ }
+ else
+ {
+ ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
+ }
+ ep->num = ep_addr & 0x7FU;
+
+ ep->is_in = (0x80U & ep_addr) != 0U;
+ ep->maxpacket = ep_mps;
+ ep->type = ep_type;
+
+ __HAL_LOCK(hpcd);
+ USB_ActivateEndpoint(hpcd->Instance , ep);
+ __HAL_UNLOCK(hpcd);
+ return ret;
+}
+
+/**
+ * @brief Deactivate an endpoint
+ * @param hpcd: PCD handle
+ * @param ep_addr: endpoint address
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
+{
+ PCD_EPTypeDef *ep = NULL;
+
+ if ((ep_addr & 0x80U) == 0x80U)
+ {
+ ep = &hpcd->IN_ep[ep_addr & 0x7FU];
+ }
+ else
+ {
+ ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
+ }
+ ep->num = ep_addr & 0x7FU;
+
+ ep->is_in = (0x80U & ep_addr) != 0U;
+
+ __HAL_LOCK(hpcd);
+ USB_DeactivateEndpoint(hpcd->Instance , ep);
+ __HAL_UNLOCK(hpcd);
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Receive an amount of data
+ * @param hpcd: PCD handle
+ * @param ep_addr: endpoint address
+ * @param pBuf: pointer to the reception buffer
+ * @param len: amount of data to be received
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
+{
+ PCD_EPTypeDef *ep = NULL;
+
+ ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
+
+ /*setup and start the Xfer */
+ ep->xfer_buff = pBuf;
+ ep->xfer_len = len;
+ ep->xfer_count = 0U;
+ ep->is_in = 0U;
+ ep->num = ep_addr & 0x7FU;
+
+ if ((ep_addr & 0x7FU) == 0U)
+ {
+ USB_EP0StartXfer(hpcd->Instance , ep);
+ }
+ else
+ {
+ USB_EPStartXfer(hpcd->Instance , ep);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Get Received Data Size
+ * @param hpcd: PCD handle
+ * @param ep_addr: endpoint address
+ * @retval Data Size
+ */
+uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
+{
+ return hpcd->OUT_ep[ep_addr & 0xF].xfer_count;
+}
+/**
+ * @brief Send an amount of data
+ * @param hpcd: PCD handle
+ * @param ep_addr: endpoint address
+ * @param pBuf: pointer to the transmission buffer
+ * @param len: amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
+{
+ PCD_EPTypeDef *ep = NULL;
+
+ ep = &hpcd->IN_ep[ep_addr & 0x7FU];
+
+ /*setup and start the Xfer */
+ ep->xfer_buff = pBuf;
+ ep->xfer_len = len;
+ ep->xfer_count = 0U;
+ ep->is_in = 1U;
+ ep->num = ep_addr & 0x7FU;
+
+ if ((ep_addr & 0x7FU) == 0U)
+ {
+ USB_EP0StartXfer(hpcd->Instance , ep);
+ }
+ else
+ {
+ USB_EPStartXfer(hpcd->Instance , ep);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Set a STALL condition over an endpoint
+ * @param hpcd: PCD handle
+ * @param ep_addr: endpoint address
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
+{
+ PCD_EPTypeDef *ep = NULL;
+
+ if ((0x80U & ep_addr) == 0x80U)
+ {
+ ep = &hpcd->IN_ep[ep_addr & 0x7FU];
+ }
+ else
+ {
+ ep = &hpcd->OUT_ep[ep_addr];
+ }
+
+ ep->is_stall = 1U;
+ ep->num = ep_addr & 0x7FU;
+ ep->is_in = ((ep_addr & 0x80U) == 0x80U);
+
+ __HAL_LOCK(hpcd);
+ USB_EPSetStall(hpcd->Instance , ep);
+ if((ep_addr & 0x7FU) == 0U)
+ {
+ USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
+ }
+ __HAL_UNLOCK(hpcd);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Clear a STALL condition over in an endpoint
+ * @param hpcd: PCD handle
+ * @param ep_addr: endpoint address
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
+{
+ PCD_EPTypeDef *ep = NULL;
+
+ if ((0x80U & ep_addr) == 0x80U)
+ {
+ ep = &hpcd->IN_ep[ep_addr & 0x7FU];
+ }
+ else
+ {
+ ep = &hpcd->OUT_ep[ep_addr];
+ }
+
+ ep->is_stall = 0U;
+ ep->num = ep_addr & 0x7FU;
+ ep->is_in = ((ep_addr & 0x80U) == 0x80U);
+
+ __HAL_LOCK(hpcd);
+ USB_EPClearStall(hpcd->Instance , ep);
+ __HAL_UNLOCK(hpcd);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Flush an endpoint
+ * @param hpcd: PCD handle
+ * @param ep_addr: endpoint address
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
+{
+ __HAL_LOCK(hpcd);
+
+ if ((ep_addr & 0x80U) == 0x80U)
+ {
+ USB_FlushTxFifo(hpcd->Instance, ep_addr & 0x7FU);
+ }
+ else
+ {
+ USB_FlushRxFifo(hpcd->Instance);
+ }
+
+ __HAL_UNLOCK(hpcd);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief HAL_PCD_ActivateRemoteWakeup : active remote wakeup signalling
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
+{
+ return(USB_ActivateRemoteWakeup(hpcd->Instance));
+}
+
+/**
+ * @brief HAL_PCD_DeActivateRemoteWakeup : de-active remote wakeup signalling
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
+{
+ return(USB_DeActivateRemoteWakeup(hpcd->Instance));
+}
+/**
+ * @}
+ */
+
+/** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral State functions #####
+ ===============================================================================
+ [..]
+ This subsection permits to get in run-time the status of the peripheral
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Return the PCD state
+ * @param hpcd: PCD handle
+ * @retval HAL state
+ */
+PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
+{
+ return hpcd->State;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup PCD_Private_Functions
+ * @{
+ */
+#if defined (USB_OTG_FS)
+/**
+ * @brief DCD_WriteEmptyTxFifo
+ * check FIFO for the next packet to be loaded
+ * @param hpcd: PCD handle
+ * @param epnum : endpoint number
+ * This parameter can be a value from 0 to 15
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
+{
+ USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
+ USB_OTG_EPTypeDef *ep = NULL;
+ int32_t len = 0;
+ uint32_t len32b = 0U;
+ uint32_t fifoemptymsk = 0U;
+
+ ep = &hpcd->IN_ep[epnum];
+ len = ep->xfer_len - ep->xfer_count;
+
+ if (len > ep->maxpacket)
+ {
+ len = ep->maxpacket;
+ }
+
+ len32b = (len + 3U) / 4U;
+
+ while ((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b &&
+ ep->xfer_count < ep->xfer_len &&
+ ep->xfer_len != 0U)
+ {
+ /* Write the FIFO */
+ len = ep->xfer_len - ep->xfer_count;
+
+ if ((uint32_t)len > ep->maxpacket)
+ {
+ len = ep->maxpacket;
+ }
+ len32b = (len + 3U) / 4U;
+
+ USB_WritePacket(USBx, ep->xfer_buff, epnum, len);
+
+ ep->xfer_buff += len;
+ ep->xfer_count += len;
+ }
+
+ if(len <= 0)
+ {
+ fifoemptymsk = 0x01U << epnum;
+ USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
+
+ }
+
+ return HAL_OK;
+}
+#endif /* USB_OTG_FS */
+
+#if defined (USB)
+/**
+ * @brief This function handles PCD Endpoint interrupt request.
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
+{
+ PCD_EPTypeDef *ep = NULL;
+ uint16_t count = 0;
+ uint8_t epindex = 0;
+ __IO uint16_t wIstr = 0;
+ __IO uint16_t wEPVal = 0;
+
+ /* stay in loop while pending interrupts */
+ while (((wIstr = hpcd->Instance->ISTR) & USB_ISTR_CTR) != 0)
+ {
+ /* extract highest priority endpoint number */
+ epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
+
+ if (epindex == 0)
+ {
+ /* Decode and service control endpoint interrupt */
+
+ /* DIR bit = origin of the interrupt */
+ if ((wIstr & USB_ISTR_DIR) == 0)
+ {
+ /* DIR = 0 */
+
+ /* DIR = 0 => IN int */
+ /* DIR = 0 implies that (EP_CTR_TX = 1) always */
+ PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
+ ep = &hpcd->IN_ep[0];
+
+ ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
+ ep->xfer_buff += ep->xfer_count;
+
+ /* TX COMPLETE */
+ HAL_PCD_DataInStageCallback(hpcd, 0U);
+
+
+ if((hpcd->USB_Address > 0U)&& ( ep->xfer_len == 0U))
+ {
+ hpcd->Instance->DADDR = (hpcd->USB_Address | USB_DADDR_EF);
+ hpcd->USB_Address = 0U;
+ }
+
+ }
+ else
+ {
+ /* DIR = 1 */
+
+ /* DIR = 1 & CTR_RX => SETUP or OUT int */
+ /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
+ ep = &hpcd->OUT_ep[0U];
+ wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
+
+ if ((wEPVal & USB_EP_SETUP) != 0U)
+ {
+ /* Get SETUP Packet*/
+ ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
+ USB_ReadPMA(hpcd->Instance, (uint8_t*)hpcd->Setup ,ep->pmaadress , ep->xfer_count);
+ /* SETUP bit kept frozen while CTR_RX = 1*/
+ PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
+
+ /* Process SETUP Packet*/
+ HAL_PCD_SetupStageCallback(hpcd);
+ }
+
+ else if ((wEPVal & USB_EP_CTR_RX) != 0U)
+ {
+ PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
+ /* Get Control Data OUT Packet*/
+ ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
+
+ if (ep->xfer_count != 0U)
+ {
+ USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, ep->xfer_count);
+ ep->xfer_buff+=ep->xfer_count;
+ }
+
+ /* Process Control Data OUT Packet*/
+ HAL_PCD_DataOutStageCallback(hpcd, 0U);
+
+ PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
+ PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
+ }
+ }
+ }
+ else
+ {
+ /* Decode and service non control endpoints interrupt */
+
+ /* process related endpoint register */
+ wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
+ if ((wEPVal & USB_EP_CTR_RX) != 0U)
+ {
+ /* clear int flag */
+ PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
+ ep = &hpcd->OUT_ep[epindex];
+
+ /* OUT double Buffering*/
+ if (ep->doublebuffer == 0U)
+ {
+ count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
+ if (count != 0U)
+ {
+ USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
+ }
+ }
+ else
+ {
+ if (PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX)
+ {
+ /*read from endpoint BUF0Addr buffer*/
+ count = PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
+ if (count != 0U)
+ {
+ USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
+ }
+ }
+ else
+ {
+ /*read from endpoint BUF1Addr buffer*/
+ count = PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
+ if (count != 0U)
+ {
+ USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
+ }
+ }
+ PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_OUT);
+ }
+ /*multi-packet on the NON control OUT endpoint*/
+ ep->xfer_count+=count;
+ ep->xfer_buff+=count;
+
+ if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
+ {
+ /* RX COMPLETE */
+ HAL_PCD_DataOutStageCallback(hpcd, ep->num);
+ }
+ else
+ {
+ HAL_PCD_EP_Receive(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
+ }
+
+ } /* if((wEPVal & EP_CTR_RX) */
+
+ if ((wEPVal & USB_EP_CTR_TX) != 0U)
+ {
+ ep = &hpcd->IN_ep[epindex];
+
+ /* clear int flag */
+ PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
+
+ /* IN double Buffering*/
+ if (ep->doublebuffer == 0U)
+ {
+ ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
+ if (ep->xfer_count != 0U)
+ {
+ USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, ep->xfer_count);
+ }
+ }
+ else
+ {
+ if (PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_TX)
+ {
+ /*read from endpoint BUF0Addr buffer*/
+ ep->xfer_count = PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
+ if (ep->xfer_count != 0U)
+ {
+ USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, ep->xfer_count);
+ }
+ }
+ else
+ {
+ /*read from endpoint BUF1Addr buffer*/
+ ep->xfer_count = PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
+ if (ep->xfer_count != 0U)
+ {
+ USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, ep->xfer_count);
+ }
+ }
+ PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_IN);
+ }
+ /*multi-packet on the NON control IN endpoint*/
+ ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
+ ep->xfer_buff+=ep->xfer_count;
+
+ /* Zero Length Packet? */
+ if (ep->xfer_len == 0U)
+ {
+ /* TX COMPLETE */
+ HAL_PCD_DataInStageCallback(hpcd, ep->num);
+ }
+ else
+ {
+ HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
+ }
+ }
+ }
+ }
+ return HAL_OK;
+}
+#endif /* USB */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F102x6 || STM32F102xB || */
+ /* STM32F103x6 || STM32F103xB || */
+ /* STM32F103xE || STM32F103xG || */
+ /* STM32F105xC || STM32F107xC */
+
+#endif /* HAL_PCD_MODULE_ENABLED */
+
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd_ex.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd_ex.c
new file mode 100644
index 0000000..fb8013e
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd_ex.c
@@ -0,0 +1,250 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_pcd_ex.c
+ * @author MCD Application Team
+ * @brief Extended PCD HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the USB Peripheral Controller:
+ * + Extended features functions: Update FIFO configuration,
+ * PMA configuration for EPs
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_PCD_MODULE_ENABLED
+
+#if defined(STM32F102x6) || defined(STM32F102xB) || \
+ defined(STM32F103x6) || defined(STM32F103xB) || \
+ defined(STM32F103xE) || defined(STM32F103xG) || \
+ defined(STM32F105xC) || defined(STM32F107xC)
+
+
+/** @defgroup PCDEx PCDEx
+ * @brief PCD Extended HAL module driver
+ * @{
+ */
+
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup PCDEx_Exported_Functions PCDEx Exported Functions
+ * @{
+ */
+
+/** @defgroup PCDEx_Exported_Functions_Group1 Peripheral Control functions
+ * @brief PCDEx control functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Extended Peripheral Control functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Update FIFO (USB_OTG_FS)
+ (+) Update PMA configuration (USB)
+
+@endverbatim
+ * @{
+ */
+
+#if defined (USB_OTG_FS)
+/**
+ * @brief Set Tx FIFO
+ * @param hpcd: PCD handle
+ * @param fifo: The number of Tx fifo
+ * @param size: Fifo size
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size)
+{
+ uint8_t index = 0;
+ uint32_t Tx_Offset = 0U;
+
+ /* TXn min size = 16 words. (n : Transmit FIFO index)
+ When a TxFIFO is not used, the Configuration should be as follows:
+ case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes)
+ --> Txm can use the space allocated for Txn.
+ case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes)
+ --> Txn should be configured with the minimum space of 16 words
+ The FIFO is used optimally when used TxFIFOs are allocated in the top
+ of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
+ When DMA is used 3n * FIFO locations should be reserved for internal DMA registers */
+
+ Tx_Offset = hpcd->Instance->GRXFSIZ;
+
+ if(fifo == 0U)
+ {
+ hpcd->Instance->DIEPTXF0_HNPTXFSIZ = (size << 16U) | Tx_Offset;
+ }
+ else
+ {
+ Tx_Offset += (hpcd->Instance->DIEPTXF0_HNPTXFSIZ) >> 16U;
+ for(index = 0; index < (fifo - 1); index++)
+ {
+ Tx_Offset += (hpcd->Instance->DIEPTXF[index] >> 16U);
+ }
+
+ /* Multiply Tx_Size by 2 to get higher performance */
+ hpcd->Instance->DIEPTXF[fifo - 1U] = (size << 16U) | Tx_Offset;
+
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Set Rx FIFO
+ * @param hpcd: PCD handle
+ * @param size: Size of Rx fifo
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size)
+{
+ hpcd->Instance->GRXFSIZ = size;
+ return HAL_OK;
+}
+#endif /* USB_OTG_FS */
+
+#if defined (USB)
+/**
+ * @brief Configure PMA for EP
+ * @param hpcd : Device instance
+ * @param ep_addr: endpoint address
+ * @param ep_kind: endpoint Kind
+ * USB_SNG_BUF: Single Buffer used
+ * USB_DBL_BUF: Double Buffer used
+ * @param pmaadress: EP address in The PMA: In case of single buffer endpoint
+ * this parameter is 16-bit value providing the address
+ * in PMA allocated to endpoint.
+ * In case of double buffer endpoint this parameter
+ * is a 32-bit value providing the endpoint buffer 0 address
+ * in the LSB part of 32-bit value and endpoint buffer 1 address
+ * in the MSB part of 32-bit value.
+ * @retval HAL status
+ */
+
+HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd,
+ uint16_t ep_addr,
+ uint16_t ep_kind,
+ uint32_t pmaadress)
+
+{
+ PCD_EPTypeDef *ep = NULL;
+
+ /* initialize ep structure*/
+ if ((ep_addr & 0x80U) == 0x80U)
+ {
+ ep = &hpcd->IN_ep[ep_addr & 0x7FU];
+ }
+ else
+ {
+ ep = &hpcd->OUT_ep[ep_addr];
+ }
+
+ /* Here we check if the endpoint is single or double Buffer*/
+ if (ep_kind == PCD_SNG_BUF)
+ {
+ /*Single Buffer*/
+ ep->doublebuffer = 0U;
+ /*Configure te PMA*/
+ ep->pmaadress = (uint16_t)pmaadress;
+ }
+ else /*USB_DBL_BUF*/
+ {
+ /*Double Buffer Endpoint*/
+ ep->doublebuffer = 1U;
+ /*Configure the PMA*/
+ ep->pmaaddr0 = pmaadress & 0x0000FFFFU;
+ ep->pmaaddr1 = (pmaadress & 0xFFFF0000U) >> 16U;
+ }
+
+ return HAL_OK;
+}
+#endif /* USB */
+/**
+ * @}
+ */
+
+/** @defgroup PCDEx_Exported_Functions_Group2 Peripheral State functions
+ * @brief Manage device connection state
+ * @{
+ */
+/**
+ * @brief Software Device Connection,
+ * this function is not required by USB OTG FS peripheral, it is used
+ * only by USB Device FS peripheral.
+ * @param hpcd: PCD handle
+ * @param state: connection state (0 : disconnected / 1: connected)
+ * @retval None
+ */
+__weak void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ UNUSED(state);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_PCDEx_SetConnectionState could be implemented in the user file
+ */
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F102x6 || STM32F102xB || */
+ /* STM32F103x6 || STM32F103xB || */
+ /* STM32F103xE || STM32F103xG || */
+ /* STM32F105xC || STM32F107xC */
+
+#endif /* HAL_PCD_MODULE_ENABLED */
+
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c
new file mode 100644
index 0000000..44d6613
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c
@@ -0,0 +1,637 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_pwr.c
+ * @author MCD Application Team
+ * @brief PWR HAL module driver.
+ *
+ * This file provides firmware functions to manage the following
+ * functionalities of the Power Controller (PWR) peripheral:
+ * + Initialization/de-initialization functions
+ * + Peripheral Control functions
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup PWR PWR
+ * @brief PWR HAL module driver
+ * @{
+ */
+
+#ifdef HAL_PWR_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/** @defgroup PWR_Private_Constants PWR Private Constants
+ * @{
+ */
+
+/** @defgroup PWR_PVD_Mode_Mask PWR PVD Mode Mask
+ * @{
+ */
+#define PVD_MODE_IT 0x00010000U
+#define PVD_MODE_EVT 0x00020000U
+#define PVD_RISING_EDGE 0x00000001U
+#define PVD_FALLING_EDGE 0x00000002U
+/**
+ * @}
+ */
+
+
+/** @defgroup PWR_register_alias_address PWR Register alias address
+ * @{
+ */
+/* ------------- PWR registers bit address in the alias region ---------------*/
+#define PWR_OFFSET (PWR_BASE - PERIPH_BASE)
+#define PWR_CR_OFFSET 0x00U
+#define PWR_CSR_OFFSET 0x04U
+#define PWR_CR_OFFSET_BB (PWR_OFFSET + PWR_CR_OFFSET)
+#define PWR_CSR_OFFSET_BB (PWR_OFFSET + PWR_CSR_OFFSET)
+/**
+ * @}
+ */
+
+/** @defgroup PWR_CR_register_alias PWR CR Register alias address
+ * @{
+ */
+/* --- CR Register ---*/
+/* Alias word address of LPSDSR bit */
+#define LPSDSR_BIT_NUMBER PWR_CR_LPDS_Pos
+#define CR_LPSDSR_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32U) + (LPSDSR_BIT_NUMBER * 4U)))
+
+/* Alias word address of DBP bit */
+#define DBP_BIT_NUMBER PWR_CR_DBP_Pos
+#define CR_DBP_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32U) + (DBP_BIT_NUMBER * 4U)))
+
+/* Alias word address of PVDE bit */
+#define PVDE_BIT_NUMBER PWR_CR_PVDE_Pos
+#define CR_PVDE_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32U) + (PVDE_BIT_NUMBER * 4U)))
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_CSR_register_alias PWR CSR Register alias address
+ * @{
+ */
+
+/* --- CSR Register ---*/
+/* Alias word address of EWUP1 bit */
+#define CSR_EWUP_BB(VAL) ((uint32_t)(PERIPH_BB_BASE + (PWR_CSR_OFFSET_BB * 32U) + (POSITION_VAL(VAL) * 4U)))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup PWR_Private_Functions PWR Private Functions
+ * brief WFE cortex command overloaded for HAL_PWR_EnterSTOPMode usage only (see Workaround section)
+ * @{
+ */
+static void PWR_OverloadWfe(void);
+
+/* Private functions ---------------------------------------------------------*/
+__NOINLINE
+static void PWR_OverloadWfe(void)
+{
+ __asm volatile( "wfe" );
+ __asm volatile( "nop" );
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup PWR_Exported_Functions PWR Exported Functions
+ * @{
+ */
+
+/** @defgroup PWR_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and de-initialization functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..]
+ After reset, the backup domain (RTC registers, RTC backup data
+ registers) is protected against possible unwanted
+ write accesses.
+ To enable access to the RTC Domain and RTC registers, proceed as follows:
+ (+) Enable the Power Controller (PWR) APB1 interface clock using the
+ __HAL_RCC_PWR_CLK_ENABLE() macro.
+ (+) Enable access to RTC domain using the HAL_PWR_EnableBkUpAccess() function.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the PWR peripheral registers to their default reset values.
+ * @retval None
+ */
+void HAL_PWR_DeInit(void)
+{
+ __HAL_RCC_PWR_FORCE_RESET();
+ __HAL_RCC_PWR_RELEASE_RESET();
+}
+
+/**
+ * @brief Enables access to the backup domain (RTC registers, RTC
+ * backup data registers ).
+ * @note If the HSE divided by 128 is used as the RTC clock, the
+ * Backup Domain Access should be kept enabled.
+ * @retval None
+ */
+void HAL_PWR_EnableBkUpAccess(void)
+{
+ /* Enable access to RTC and backup registers */
+ *(__IO uint32_t *) CR_DBP_BB = (uint32_t)ENABLE;
+}
+
+/**
+ * @brief Disables access to the backup domain (RTC registers, RTC
+ * backup data registers).
+ * @note If the HSE divided by 128 is used as the RTC clock, the
+ * Backup Domain Access should be kept enabled.
+ * @retval None
+ */
+void HAL_PWR_DisableBkUpAccess(void)
+{
+ /* Disable access to RTC and backup registers */
+ *(__IO uint32_t *) CR_DBP_BB = (uint32_t)DISABLE;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_Exported_Functions_Group2 Peripheral Control functions
+ * @brief Low Power modes configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+
+ *** PVD configuration ***
+ =========================
+ [..]
+ (+) The PVD is used to monitor the VDD power supply by comparing it to a
+ threshold selected by the PVD Level (PLS[2:0] bits in the PWR_CR).
+
+ (+) A PVDO flag is available to indicate if VDD/VDDA is higher or lower
+ than the PVD threshold. This event is internally connected to the EXTI
+ line16 and can generate an interrupt if enabled. This is done through
+ __HAL_PVD_EXTI_ENABLE_IT() macro.
+ (+) The PVD is stopped in Standby mode.
+
+ *** WakeUp pin configuration ***
+ ================================
+ [..]
+ (+) WakeUp pin is used to wake up the system from Standby mode. This pin is
+ forced in input pull-down configuration and is active on rising edges.
+ (+) There is one WakeUp pin:
+ WakeUp Pin 1 on PA.00.
+
+ [..]
+
+ *** Low Power modes configuration ***
+ =====================================
+ [..]
+ The device features 3 low-power modes:
+ (+) Sleep mode: CPU clock off, all peripherals including Cortex-M3 core peripherals like
+ NVIC, SysTick, etc. are kept running
+ (+) Stop mode: All clocks are stopped
+ (+) Standby mode: 1.8V domain powered off
+
+
+ *** Sleep mode ***
+ ==================
+ [..]
+ (+) Entry:
+ The Sleep mode is entered by using the HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFx)
+ functions with
+ (++) PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction
+ (++) PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction
+
+ (+) Exit:
+ (++) WFI entry mode, Any peripheral interrupt acknowledged by the nested vectored interrupt
+ controller (NVIC) can wake up the device from Sleep mode.
+ (++) WFE entry mode, Any wakeup event can wake up the device from Sleep mode.
+ (+++) Any peripheral interrupt w/o NVIC configuration & SEVONPEND bit set in the Cortex (HAL_PWR_EnableSEVOnPend)
+ (+++) Any EXTI Line (Internal or External) configured in Event mode
+
+ *** Stop mode ***
+ =================
+ [..]
+ The Stop mode is based on the Cortex-M3 deepsleep mode combined with peripheral
+ clock gating. The voltage regulator can be configured either in normal or low-power mode.
+ In Stop mode, all clocks in the 1.8 V domain are stopped, the PLL, the HSI and the HSE RC
+ oscillators are disabled. SRAM and register contents are preserved.
+ In Stop mode, all I/O pins keep the same state as in Run mode.
+
+ (+) Entry:
+ The Stop mode is entered using the HAL_PWR_EnterSTOPMode(PWR_REGULATOR_VALUE, PWR_SLEEPENTRY_WFx )
+ function with:
+ (++) PWR_REGULATOR_VALUE= PWR_MAINREGULATOR_ON: Main regulator ON.
+ (++) PWR_REGULATOR_VALUE= PWR_LOWPOWERREGULATOR_ON: Low Power regulator ON.
+ (++) PWR_SLEEPENTRY_WFx= PWR_SLEEPENTRY_WFI: enter STOP mode with WFI instruction
+ (++) PWR_SLEEPENTRY_WFx= PWR_SLEEPENTRY_WFE: enter STOP mode with WFE instruction
+ (+) Exit:
+ (++) WFI entry mode, Any EXTI Line (Internal or External) configured in Interrupt mode with NVIC configured
+ (++) WFE entry mode, Any EXTI Line (Internal or External) configured in Event mode.
+
+ *** Standby mode ***
+ ====================
+ [..]
+ The Standby mode allows to achieve the lowest power consumption. It is based on the
+ Cortex-M3 deepsleep mode, with the voltage regulator disabled. The 1.8 V domain is
+ consequently powered off. The PLL, the HSI oscillator and the HSE oscillator are also
+ switched off. SRAM and register contents are lost except for registers in the Backup domain
+ and Standby circuitry
+
+ (+) Entry:
+ (++) The Standby mode is entered using the HAL_PWR_EnterSTANDBYMode() function.
+ (+) Exit:
+ (++) WKUP pin rising edge, RTC alarm event rising edge, external Reset in
+ NRSTpin, IWDG Reset
+
+ *** Auto-wakeup (AWU) from low-power mode ***
+ =============================================
+ [..]
+
+ (+) The MCU can be woken up from low-power mode by an RTC Alarm event,
+ without depending on an external interrupt (Auto-wakeup mode).
+
+ (+) RTC auto-wakeup (AWU) from the Stop and Standby modes
+
+ (++) To wake up from the Stop mode with an RTC alarm event, it is necessary to
+ configure the RTC to generate the RTC alarm using the HAL_RTC_SetAlarm_IT() function.
+
+ *** PWR Workarounds linked to Silicon Limitation ***
+ ====================================================
+ [..]
+ Below the list of all silicon limitations known on STM32F1xx prouct.
+
+ (#)Workarounds Implemented inside PWR HAL Driver
+ (##)Debugging Stop mode with WFE entry - overloaded the WFE by an internal function
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD).
+ * @param sConfigPVD: pointer to an PWR_PVDTypeDef structure that contains the configuration
+ * information for the PVD.
+ * @note Refer to the electrical characteristics of your device datasheet for
+ * more details about the voltage threshold corresponding to each
+ * detection level.
+ * @retval None
+ */
+void HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD)
+{
+ /* Check the parameters */
+ assert_param(IS_PWR_PVD_LEVEL(sConfigPVD->PVDLevel));
+ assert_param(IS_PWR_PVD_MODE(sConfigPVD->Mode));
+
+ /* Set PLS[7:5] bits according to PVDLevel value */
+ MODIFY_REG(PWR->CR, PWR_CR_PLS, sConfigPVD->PVDLevel);
+
+ /* Clear any previous config. Keep it clear if no event or IT mode is selected */
+ __HAL_PWR_PVD_EXTI_DISABLE_EVENT();
+ __HAL_PWR_PVD_EXTI_DISABLE_IT();
+ __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE();
+ __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();
+
+ /* Configure interrupt mode */
+ if((sConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT)
+ {
+ __HAL_PWR_PVD_EXTI_ENABLE_IT();
+ }
+
+ /* Configure event mode */
+ if((sConfigPVD->Mode & PVD_MODE_EVT) == PVD_MODE_EVT)
+ {
+ __HAL_PWR_PVD_EXTI_ENABLE_EVENT();
+ }
+
+ /* Configure the edge */
+ if((sConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE)
+ {
+ __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE();
+ }
+
+ if((sConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE)
+ {
+ __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE();
+ }
+}
+
+/**
+ * @brief Enables the Power Voltage Detector(PVD).
+ * @retval None
+ */
+void HAL_PWR_EnablePVD(void)
+{
+ /* Enable the power voltage detector */
+ *(__IO uint32_t *) CR_PVDE_BB = (uint32_t)ENABLE;
+}
+
+/**
+ * @brief Disables the Power Voltage Detector(PVD).
+ * @retval None
+ */
+void HAL_PWR_DisablePVD(void)
+{
+ /* Disable the power voltage detector */
+ *(__IO uint32_t *) CR_PVDE_BB = (uint32_t)DISABLE;
+}
+
+/**
+ * @brief Enables the WakeUp PINx functionality.
+ * @param WakeUpPinx: Specifies the Power Wake-Up pin to enable.
+ * This parameter can be one of the following values:
+ * @arg PWR_WAKEUP_PIN1
+ * @retval None
+ */
+void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinx)
+{
+ /* Check the parameter */
+ assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
+ /* Enable the EWUPx pin */
+ *(__IO uint32_t *) CSR_EWUP_BB(WakeUpPinx) = (uint32_t)ENABLE;
+}
+
+/**
+ * @brief Disables the WakeUp PINx functionality.
+ * @param WakeUpPinx: Specifies the Power Wake-Up pin to disable.
+ * This parameter can be one of the following values:
+ * @arg PWR_WAKEUP_PIN1
+ * @retval None
+ */
+void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)
+{
+ /* Check the parameter */
+ assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
+ /* Disable the EWUPx pin */
+ *(__IO uint32_t *) CSR_EWUP_BB(WakeUpPinx) = (uint32_t)DISABLE;
+}
+
+/**
+ * @brief Enters Sleep mode.
+ * @note In Sleep mode, all I/O pins keep the same state as in Run mode.
+ * @param Regulator: Regulator state as no effect in SLEEP mode - allows to support portability from legacy software
+ * @param SLEEPEntry: Specifies if SLEEP mode is entered with WFI or WFE instruction.
+ * When WFI entry is used, tick interrupt have to be disabled if not desired as
+ * the interrupt wake up source.
+ * This parameter can be one of the following values:
+ * @arg PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction
+ * @arg PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction
+ * @retval None
+ */
+void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
+{
+ /* Check the parameters */
+ /* No check on Regulator because parameter not used in SLEEP mode */
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(Regulator);
+
+ assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry));
+
+ /* Clear SLEEPDEEP bit of Cortex System Control Register */
+ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
+
+ /* Select SLEEP mode entry -------------------------------------------------*/
+ if(SLEEPEntry == PWR_SLEEPENTRY_WFI)
+ {
+ /* Request Wait For Interrupt */
+ __WFI();
+ }
+ else
+ {
+ /* Request Wait For Event */
+ __SEV();
+ __WFE();
+ __WFE();
+ }
+}
+
+/**
+ * @brief Enters Stop mode.
+ * @note In Stop mode, all I/O pins keep the same state as in Run mode.
+ * @note When exiting Stop mode by using an interrupt or a wakeup event,
+ * HSI RC oscillator is selected as system clock.
+ * @note When the voltage regulator operates in low power mode, an additional
+ * startup delay is incurred when waking up from Stop mode.
+ * By keeping the internal regulator ON during Stop mode, the consumption
+ * is higher although the startup time is reduced.
+ * @param Regulator: Specifies the regulator state in Stop mode.
+ * This parameter can be one of the following values:
+ * @arg PWR_MAINREGULATOR_ON: Stop mode with regulator ON
+ * @arg PWR_LOWPOWERREGULATOR_ON: Stop mode with low power regulator ON
+ * @param STOPEntry: Specifies if Stop mode in entered with WFI or WFE instruction.
+ * This parameter can be one of the following values:
+ * @arg PWR_STOPENTRY_WFI: Enter Stop mode with WFI instruction
+ * @arg PWR_STOPENTRY_WFE: Enter Stop mode with WFE instruction
+ * @retval None
+ */
+void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
+{
+ /* Check the parameters */
+ assert_param(IS_PWR_REGULATOR(Regulator));
+ assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
+
+ /* Clear PDDS bit in PWR register to specify entering in STOP mode when CPU enter in Deepsleep */
+ CLEAR_BIT(PWR->CR, PWR_CR_PDDS);
+
+ /* Select the voltage regulator mode by setting LPDS bit in PWR register according to Regulator parameter value */
+ MODIFY_REG(PWR->CR, PWR_CR_LPDS, Regulator);
+
+ /* Set SLEEPDEEP bit of Cortex System Control Register */
+ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
+
+ /* Select Stop mode entry --------------------------------------------------*/
+ if(STOPEntry == PWR_STOPENTRY_WFI)
+ {
+ /* Request Wait For Interrupt */
+ __WFI();
+ }
+ else
+ {
+ /* Request Wait For Event */
+ __SEV();
+ PWR_OverloadWfe(); /* WFE redefine locally */
+ PWR_OverloadWfe(); /* WFE redefine locally */
+ }
+ /* Reset SLEEPDEEP bit of Cortex System Control Register */
+ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
+}
+
+/**
+ * @brief Enters Standby mode.
+ * @note In Standby mode, all I/O pins are high impedance except for:
+ * - Reset pad (still available)
+ * - TAMPER pin if configured for tamper or calibration out.
+ * - WKUP pin (PA0) if enabled.
+ * @retval None
+ */
+void HAL_PWR_EnterSTANDBYMode(void)
+{
+ /* Select Standby mode */
+ SET_BIT(PWR->CR, PWR_CR_PDDS);
+
+ /* Set SLEEPDEEP bit of Cortex System Control Register */
+ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
+
+ /* This option is used to ensure that store operations are completed */
+#if defined ( __CC_ARM)
+ __force_stores();
+#endif
+ /* Request Wait For Interrupt */
+ __WFI();
+}
+
+
+/**
+ * @brief Indicates Sleep-On-Exit when returning from Handler mode to Thread mode.
+ * @note Set SLEEPONEXIT bit of SCR register. When this bit is set, the processor
+ * re-enters SLEEP mode when an interruption handling is over.
+ * Setting this bit is useful when the processor is expected to run only on
+ * interruptions handling.
+ * @retval None
+ */
+void HAL_PWR_EnableSleepOnExit(void)
+{
+ /* Set SLEEPONEXIT bit of Cortex System Control Register */
+ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
+}
+
+
+/**
+ * @brief Disables Sleep-On-Exit feature when returning from Handler mode to Thread mode.
+ * @note Clears SLEEPONEXIT bit of SCR register. When this bit is set, the processor
+ * re-enters SLEEP mode when an interruption handling is over.
+ * @retval None
+ */
+void HAL_PWR_DisableSleepOnExit(void)
+{
+ /* Clear SLEEPONEXIT bit of Cortex System Control Register */
+ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
+}
+
+
+/**
+ * @brief Enables CORTEX M3 SEVONPEND bit.
+ * @note Sets SEVONPEND bit of SCR register. When this bit is set, this causes
+ * WFE to wake up when an interrupt moves from inactive to pended.
+ * @retval None
+ */
+void HAL_PWR_EnableSEVOnPend(void)
+{
+ /* Set SEVONPEND bit of Cortex System Control Register */
+ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
+}
+
+
+/**
+ * @brief Disables CORTEX M3 SEVONPEND bit.
+ * @note Clears SEVONPEND bit of SCR register. When this bit is set, this causes
+ * WFE to wake up when an interrupt moves from inactive to pended.
+ * @retval None
+ */
+void HAL_PWR_DisableSEVOnPend(void)
+{
+ /* Clear SEVONPEND bit of Cortex System Control Register */
+ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
+}
+
+
+
+/**
+ * @brief This function handles the PWR PVD interrupt request.
+ * @note This API should be called under the PVD_IRQHandler().
+ * @retval None
+ */
+void HAL_PWR_PVD_IRQHandler(void)
+{
+ /* Check PWR exti flag */
+ if(__HAL_PWR_PVD_EXTI_GET_FLAG() != RESET)
+ {
+ /* PWR PVD interrupt user callback */
+ HAL_PWR_PVDCallback();
+
+ /* Clear PWR Exti pending bit */
+ __HAL_PWR_PVD_EXTI_CLEAR_FLAG();
+ }
+}
+
+/**
+ * @brief PWR PVD interrupt callback
+ * @retval None
+ */
+__weak void HAL_PWR_PVDCallback(void)
+{
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_PWR_PVDCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_PWR_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c
new file mode 100644
index 0000000..e146d9b
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c
@@ -0,0 +1,1416 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_rcc.c
+ * @author MCD Application Team
+ * @brief RCC HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Reset and Clock Control (RCC) peripheral:
+ * + Initialization and de-initialization functions
+ * + Peripheral Control functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### RCC specific features #####
+ ==============================================================================
+ [..]
+ After reset the device is running from Internal High Speed oscillator
+ (HSI 8MHz) with Flash 0 wait state, Flash prefetch buffer is enabled,
+ and all peripherals are off except internal SRAM, Flash and JTAG.
+ (+) There is no prescaler on High speed (AHB) and Low speed (APB) buses;
+ all peripherals mapped on these buses are running at HSI speed.
+ (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
+ (+) All GPIOs are in input floating state, except the JTAG pins which
+ are assigned to be used for debug purpose.
+ [..] Once the device started from reset, the user application has to:
+ (+) Configure the clock source to be used to drive the System clock
+ (if the application needs higher frequency/performance)
+ (+) Configure the System clock frequency and Flash settings
+ (+) Configure the AHB and APB buses prescalers
+ (+) Enable the clock for the peripheral(s) to be used
+ (+) Configure the clock source(s) for peripherals whose clocks are not
+ derived from the System clock (I2S, RTC, ADC, USB OTG FS)
+
+ ##### RCC Limitations #####
+ ==============================================================================
+ [..]
+ A delay between an RCC peripheral clock enable and the effective peripheral
+ enabling should be taken into account in order to manage the peripheral read/write
+ from/to registers.
+ (+) This delay depends on the peripheral mapping.
+ (++) AHB & APB peripherals, 1 dummy read is necessary
+
+ [..]
+ Workarounds:
+ (#) For AHB & APB peripherals, a dummy read to the peripheral register has been
+ inserted in each __HAL_RCC_PPP_CLK_ENABLE() macro.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup RCC RCC
+* @brief RCC HAL module driver
+ * @{
+ */
+
+#ifdef HAL_RCC_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup RCC_Private_Constants RCC Private Constants
+ * @{
+ */
+/**
+ * @}
+ */
+/* Private macro -------------------------------------------------------------*/
+/** @defgroup RCC_Private_Macros RCC Private Macros
+ * @{
+ */
+
+#define MCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define MCO1_GPIO_PORT GPIOA
+#define MCO1_PIN GPIO_PIN_8
+
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/** @defgroup RCC_Private_Variables RCC Private Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+static void RCC_Delay(uint32_t mdelay);
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup RCC_Exported_Functions RCC Exported Functions
+ * @{
+ */
+
+/** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+ @verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..]
+ This section provides functions allowing to configure the internal/external oscillators
+ (HSE, HSI, LSE, LSI, PLL, CSS and MCO) and the System buses clocks (SYSCLK, AHB, APB1
+ and APB2).
+
+ [..] Internal/external clock and PLL configuration
+ (#) HSI (high-speed internal), 8 MHz factory-trimmed RC used directly or through
+ the PLL as System clock source.
+ (#) LSI (low-speed internal), ~40 KHz low consumption RC used as IWDG and/or RTC
+ clock source.
+
+ (#) HSE (high-speed external), 4 to 24 MHz (STM32F100xx) or 4 to 16 MHz (STM32F101x/STM32F102x/STM32F103x) or 3 to 25 MHz (STM32F105x/STM32F107x) crystal oscillator used directly or
+ through the PLL as System clock source. Can be used also as RTC clock source.
+
+ (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source.
+
+ (#) PLL (clocked by HSI or HSE), featuring different output clocks:
+ (++) The first output is used to generate the high speed system clock (up to 72 MHz for STM32F10xxx or up to 24 MHz for STM32F100xx)
+ (++) The second output is used to generate the clock for the USB OTG FS (48 MHz)
+
+ (#) CSS (Clock security system), once enable using the macro __HAL_RCC_CSS_ENABLE()
+ and if a HSE clock failure occurs(HSE used directly or through PLL as System
+ clock source), the System clocks automatically switched to HSI and an interrupt
+ is generated if enabled. The interrupt is linked to the Cortex-M3 NMI
+ (Non-Maskable Interrupt) exception vector.
+
+ (#) MCO1 (microcontroller clock output), used to output SYSCLK, HSI,
+ HSE or PLL clock (divided by 2) on PA8 pin + PLL2CLK, PLL3CLK/2, PLL3CLK and XTI for STM32F105x/STM32F107x
+
+ [..] System, AHB and APB buses clocks configuration
+ (#) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
+ HSE and PLL.
+ The AHB clock (HCLK) is derived from System clock through configurable
+ prescaler and used to clock the CPU, memory and peripherals mapped
+ on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
+ from AHB clock through configurable prescalers and used to clock
+ the peripherals mapped on these buses. You can use
+ "@ref HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
+
+ -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
+ (+@) RTC: RTC clock can be derived either from the LSI, LSE or HSE clock
+ divided by 128.
+ (+@) USB OTG FS and RTC: USB OTG FS require a frequency equal to 48 MHz
+ to work correctly. This clock is derived of the main PLL through PLL Multiplier.
+ (+@) I2S interface on STM32F105x/STM32F107x can be derived from PLL3CLK
+ (+@) IWDG clock which is always the LSI clock.
+
+ (#) For STM32F10xxx, the maximum frequency of the SYSCLK and HCLK/PCLK2 is 72 MHz, PCLK1 36 MHz.
+ For STM32F100xx, the maximum frequency of the SYSCLK and HCLK/PCLK1/PCLK2 is 24 MHz.
+ Depending on the SYSCLK frequency, the flash latency should be adapted accordingly.
+ @endverbatim
+ * @{
+ */
+
+/*
+ Additional consideration on the SYSCLK based on Latency settings:
+ +-----------------------------------------------+
+ | Latency | SYSCLK clock frequency (MHz) |
+ |---------------|-------------------------------|
+ |0WS(1CPU cycle)| 0 < SYSCLK <= 24 |
+ |---------------|-------------------------------|
+ |1WS(2CPU cycle)| 24 < SYSCLK <= 48 |
+ |---------------|-------------------------------|
+ |2WS(3CPU cycle)| 48 < SYSCLK <= 72 |
+ +-----------------------------------------------+
+ */
+
+/**
+ * @brief Resets the RCC clock configuration to the default reset state.
+ * @note The default reset state of the clock configuration is given below:
+ * - HSI ON and used as system clock source
+ * - HSE, PLL, PLL2 and PLL3 are OFF
+ * - AHB, APB1 and APB2 prescaler set to 1.
+ * - CSS and MCO1 OFF
+ * - All interrupts disabled
+ * - All flags are cleared
+ * @note This function does not modify the configuration of the
+ * - Peripheral clocks
+ * - LSI, LSE and RTC clocks
+ * @retval HAL_StatusTypeDef
+ */
+HAL_StatusTypeDef HAL_RCC_DeInit(void)
+{
+ uint32_t tickstart;
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Set HSION bit */
+ SET_BIT(RCC->CR, RCC_CR_HSION);
+
+ /* Wait till HSI is ready */
+ while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET)
+ {
+ if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Set HSITRIM bits to the reset value */
+ MODIFY_REG(RCC->CR, RCC_CR_HSITRIM, (0x10U << RCC_CR_HSITRIM_Pos));
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Reset CFGR register */
+ CLEAR_REG(RCC->CFGR);
+
+ /* Wait till clock switch is ready */
+ while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RESET)
+ {
+ if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Update the SystemCoreClock global variable */
+ SystemCoreClock = HSI_VALUE;
+
+ /* Adapt Systick interrupt period */
+ if(HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Second step is to clear PLLON bit */
+ CLEAR_BIT(RCC->CR, RCC_CR_PLLON);
+
+ /* Wait till PLL is disabled */
+ while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET)
+ {
+ if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Ensure to reset PLLSRC and PLLMUL bits */
+ CLEAR_REG(RCC->CFGR);
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Reset HSEON & CSSON bits */
+ CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_CSSON);
+
+ /* Wait till HSE is disabled */
+ while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != RESET)
+ {
+ if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Reset HSEBYP bit */
+ CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
+
+#if defined(RCC_PLL2_SUPPORT)
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Clear PLL2ON bit */
+ CLEAR_BIT(RCC->CR, RCC_CR_PLL2ON);
+
+ /* Wait till PLL2 is disabled */
+ while (READ_BIT(RCC->CR, RCC_CR_PLL2RDY) != RESET)
+ {
+ if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+#endif /* RCC_PLL2_SUPPORT */
+
+#if defined(RCC_PLLI2S_SUPPORT)
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Clear PLL3ON bit */
+ CLEAR_BIT(RCC->CR, RCC_CR_PLL3ON);
+
+ /* Wait till PLL3 is disabled */
+ while (READ_BIT(RCC->CR, RCC_CR_PLL3RDY) != RESET)
+ {
+ if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+#endif /* RCC_PLLI2S_SUPPORT */
+
+#if defined(RCC_CFGR2_PREDIV1)
+ /* Reset CFGR2 register */
+ CLEAR_REG(RCC->CFGR2);
+#endif /* RCC_CFGR2_PREDIV1 */
+
+ /* Reset all CSR flags */
+ SET_BIT(RCC->CSR, RCC_CSR_RMVF);
+
+ /* Disable all interrupts */
+ CLEAR_REG(RCC->CIR);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the RCC Oscillators according to the specified parameters in the
+ * RCC_OscInitTypeDef.
+ * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
+ * contains the configuration information for the RCC Oscillators.
+ * @note The PLL is not disabled when used as system clock.
+ * @note The PLL is not disabled when USB OTG FS clock is enabled (specific to devices with USB FS)
+ * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
+ * supported by this macro. User should request a transition to LSE Off
+ * first and then LSE On or LSE Bypass.
+ * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
+ * supported by this macro. User should request a transition to HSE Off
+ * first and then HSE On or HSE Bypass.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
+{
+ uint32_t tickstart = 0U;
+
+ /* Check the parameters */
+ assert_param(RCC_OscInitStruct != NULL);
+ assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
+
+ /*------------------------------- HSE Configuration ------------------------*/
+ if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
+
+ /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
+ if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE)
+ || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE)))
+ {
+ if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
+ {
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ /* Set the new HSE configuration ---------------------------------------*/
+ __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
+
+
+ /* Check the HSE State */
+ if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
+ {
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till HSE is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ else
+ {
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till HSE is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+ }
+ /*----------------------------- HSI Configuration --------------------------*/
+ if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
+ assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
+
+ /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
+ if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI)
+ || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI_DIV2)))
+ {
+ /* When HSI is used as system clock it will not disabled */
+ if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON))
+ {
+ return HAL_ERROR;
+ }
+ /* Otherwise, just the calibration is allowed */
+ else
+ {
+ /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
+ __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
+ }
+ }
+ else
+ {
+ /* Check the HSI State */
+ if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
+ {
+ /* Enable the Internal High Speed oscillator (HSI). */
+ __HAL_RCC_HSI_ENABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till HSI is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
+ __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
+ }
+ else
+ {
+ /* Disable the Internal High Speed oscillator (HSI). */
+ __HAL_RCC_HSI_DISABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till HSI is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+ }
+ /*------------------------------ LSI Configuration -------------------------*/
+ if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
+
+ /* Check the LSI State */
+ if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
+ {
+ /* Enable the Internal Low Speed oscillator (LSI). */
+ __HAL_RCC_LSI_ENABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till LSI is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ /* To have a fully stabilized clock in the specified range, a software delay of 1ms
+ should be added.*/
+ RCC_Delay(1);
+ }
+ else
+ {
+ /* Disable the Internal Low Speed oscillator (LSI). */
+ __HAL_RCC_LSI_DISABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till LSI is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+ /*------------------------------ LSE Configuration -------------------------*/
+ if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
+ {
+ FlagStatus pwrclkchanged = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
+
+ /* Update LSE configuration in Backup Domain control register */
+ /* Requires to enable write access to Backup Domain of necessary */
+ if(__HAL_RCC_PWR_IS_CLK_DISABLED())
+ {
+ __HAL_RCC_PWR_CLK_ENABLE();
+ pwrclkchanged = SET;
+ }
+
+ if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
+ {
+ /* Enable write access to Backup domain */
+ SET_BIT(PWR->CR, PWR_CR_DBP);
+
+ /* Wait for Backup domain Write protection disable */
+ tickstart = HAL_GetTick();
+
+ while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
+ {
+ if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* Set the new LSE configuration -----------------------------------------*/
+ __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
+ /* Check the LSE State */
+ if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
+ {
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till LSE is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ else
+ {
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till LSE is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* Require to disable power clock if necessary */
+ if(pwrclkchanged == SET)
+ {
+ __HAL_RCC_PWR_CLK_DISABLE();
+ }
+ }
+
+#if defined(RCC_CR_PLL2ON)
+ /*-------------------------------- PLL2 Configuration -----------------------*/
+ /* Check the parameters */
+ assert_param(IS_RCC_PLL2(RCC_OscInitStruct->PLL2.PLL2State));
+ if ((RCC_OscInitStruct->PLL2.PLL2State) != RCC_PLL2_NONE)
+ {
+ /* This bit can not be cleared if the PLL2 clock is used indirectly as system
+ clock (i.e. it is used as PLL clock entry that is used as system clock). */
+ if((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
+ (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
+ ((READ_BIT(RCC->CFGR2,RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ if((RCC_OscInitStruct->PLL2.PLL2State) == RCC_PLL2_ON)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_PLL2_MUL(RCC_OscInitStruct->PLL2.PLL2MUL));
+ assert_param(IS_RCC_HSE_PREDIV2(RCC_OscInitStruct->PLL2.HSEPrediv2Value));
+
+ /* Prediv2 can be written only when the PLLI2S is disabled. */
+ /* Return an error only if new value is different from the programmed value */
+ if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLL3ON) && \
+ (__HAL_RCC_HSE_GET_PREDIV2() != RCC_OscInitStruct->PLL2.HSEPrediv2Value))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Disable the main PLL2. */
+ __HAL_RCC_PLL2_DISABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLL2 is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Configure the HSE prediv2 factor --------------------------------*/
+ __HAL_RCC_HSE_PREDIV2_CONFIG(RCC_OscInitStruct->PLL2.HSEPrediv2Value);
+
+ /* Configure the main PLL2 multiplication factors. */
+ __HAL_RCC_PLL2_CONFIG(RCC_OscInitStruct->PLL2.PLL2MUL);
+
+ /* Enable the main PLL2. */
+ __HAL_RCC_PLL2_ENABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLL2 is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ else
+ {
+ /* Set PREDIV1 source to HSE */
+ CLEAR_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC);
+
+ /* Disable the main PLL2. */
+ __HAL_RCC_PLL2_DISABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLL2 is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+ }
+
+#endif /* RCC_CR_PLL2ON */
+ /*-------------------------------- PLL Configuration -----------------------*/
+ /* Check the parameters */
+ assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
+ if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
+ {
+ /* Check if the PLL is used as system clock or not */
+ if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
+ {
+ if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
+ assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL));
+
+ /* Disable the main PLL. */
+ __HAL_RCC_PLL_DISABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLL is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Configure the HSE prediv factor --------------------------------*/
+ /* It can be written only when the PLL is disabled. Not used in PLL source is different than HSE */
+ if(RCC_OscInitStruct->PLL.PLLSource == RCC_PLLSOURCE_HSE)
+ {
+ /* Check the parameter */
+ assert_param(IS_RCC_HSE_PREDIV(RCC_OscInitStruct->HSEPredivValue));
+#if defined(RCC_CFGR2_PREDIV1SRC)
+ assert_param(IS_RCC_PREDIV1_SOURCE(RCC_OscInitStruct->Prediv1Source));
+
+ /* Set PREDIV1 source */
+ SET_BIT(RCC->CFGR2, RCC_OscInitStruct->Prediv1Source);
+#endif /* RCC_CFGR2_PREDIV1SRC */
+
+ /* Set PREDIV1 Value */
+ __HAL_RCC_HSE_PREDIV_CONFIG(RCC_OscInitStruct->HSEPredivValue);
+ }
+
+ /* Configure the main PLL clock source and multiplication factors. */
+ __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
+ RCC_OscInitStruct->PLL.PLLMUL);
+ /* Enable the main PLL. */
+ __HAL_RCC_PLL_ENABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLL is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ else
+ {
+ /* Disable the main PLL. */
+ __HAL_RCC_PLL_DISABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLL is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the CPU, AHB and APB buses clocks according to the specified
+ * parameters in the RCC_ClkInitStruct.
+ * @param RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that
+ * contains the configuration information for the RCC peripheral.
+ * @param FLatency FLASH Latency
+ * The value of this parameter depend on device used within the same series
+ * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
+ * and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function
+ *
+ * @note The HSI is used (enabled by hardware) as system clock source after
+ * start-up from Reset, wake-up from STOP and STANDBY mode, or in case
+ * of failure of the HSE used directly or indirectly as system clock
+ * (if the Clock Security System CSS is enabled).
+ *
+ * @note A switch from one clock source to another occurs only if the target
+ * clock source is ready (clock stable after start-up delay or PLL locked).
+ * If a clock source which is not yet ready is selected, the switch will
+ * occur when the clock source will be ready.
+ * You can use @ref HAL_RCC_GetClockConfig() function to know which clock is
+ * currently used as system clock source.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
+{
+ uint32_t tickstart = 0U;
+
+ /* Check the parameters */
+ assert_param(RCC_ClkInitStruct != NULL);
+ assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
+ assert_param(IS_FLASH_LATENCY(FLatency));
+
+ /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
+ must be correctly programmed according to the frequency of the CPU clock
+ (HCLK) of the device. */
+
+#if defined(FLASH_ACR_LATENCY)
+ /* Increasing the number of wait states because of higher CPU frequency */
+ if(FLatency > (FLASH->ACR & FLASH_ACR_LATENCY))
+ {
+ /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
+ __HAL_FLASH_SET_LATENCY(FLatency);
+
+ /* Check that the new number of wait states is taken into account to access the Flash
+ memory by reading the FLASH_ACR register */
+ if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
+ {
+ return HAL_ERROR;
+ }
+ }
+
+#endif /* FLASH_ACR_LATENCY */
+ /*-------------------------- HCLK Configuration --------------------------*/
+ if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
+ {
+ /* Set the highest APBx dividers in order to ensure that we do not go through
+ a non-spec phase whatever we decrease or increase HCLK. */
+ if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
+ {
+ MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_HCLK_DIV16);
+ }
+
+ if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
+ {
+ MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, (RCC_HCLK_DIV16 << 3));
+ }
+
+ /* Set the new HCLK clock divider */
+ assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
+ MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
+ }
+
+ /*------------------------- SYSCLK Configuration ---------------------------*/
+ if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
+ {
+ assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
+
+ /* HSE is selected as System Clock Source */
+ if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
+ {
+ /* Check the HSE ready flag */
+ if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
+ {
+ return HAL_ERROR;
+ }
+ }
+ /* PLL is selected as System Clock Source */
+ else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
+ {
+ /* Check the PLL ready flag */
+ if(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
+ {
+ return HAL_ERROR;
+ }
+ }
+ /* HSI is selected as System Clock Source */
+ else
+ {
+ /* Check the HSI ready flag */
+ if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
+ {
+ return HAL_ERROR;
+ }
+ }
+ __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource);
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
+ {
+ while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSE)
+ {
+ if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
+ {
+ while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
+ {
+ if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ else
+ {
+ while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI)
+ {
+ if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+#if defined(FLASH_ACR_LATENCY)
+ /* Decreasing the number of wait states because of lower CPU frequency */
+ if(FLatency < (FLASH->ACR & FLASH_ACR_LATENCY))
+ {
+ /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
+ __HAL_FLASH_SET_LATENCY(FLatency);
+
+ /* Check that the new number of wait states is taken into account to access the Flash
+ memory by reading the FLASH_ACR register */
+ if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
+ {
+ return HAL_ERROR;
+ }
+ }
+#endif /* FLASH_ACR_LATENCY */
+
+ /*-------------------------- PCLK1 Configuration ---------------------------*/
+ if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
+ {
+ assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
+ MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
+ }
+
+ /*-------------------------- PCLK2 Configuration ---------------------------*/
+ if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
+ {
+ assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
+ MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3));
+ }
+
+ /* Update the SystemCoreClock global variable */
+ SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE)>> RCC_CFGR_HPRE_Pos];
+
+ /* Configure the source of time base considering new system clocks settings*/
+ HAL_InitTick (TICK_INT_PRIORITY);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
+ * @brief RCC clocks control functions
+ *
+ @verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the RCC Clocks
+ frequencies.
+
+ @endverbatim
+ * @{
+ */
+
+/**
+ * @brief Selects the clock source to output on MCO pin.
+ * @note MCO pin should be configured in alternate function mode.
+ * @param RCC_MCOx specifies the output direction for the clock source.
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8).
+ * @param RCC_MCOSource specifies the clock source to output.
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected as MCO clock
+ * @arg @ref RCC_MCO1SOURCE_SYSCLK System clock selected as MCO clock
+ * @arg @ref RCC_MCO1SOURCE_HSI HSI selected as MCO clock
+ * @arg @ref RCC_MCO1SOURCE_HSE HSE selected as MCO clock
+ @if STM32F105xC
+ * @arg @ref RCC_MCO1SOURCE_PLLCLK PLL clock divided by 2 selected as MCO source
+ * @arg @ref RCC_MCO1SOURCE_PLL2CLK PLL2 clock selected as MCO source
+ * @arg @ref RCC_MCO1SOURCE_PLL3CLK_DIV2 PLL3 clock divided by 2 selected as MCO source
+ * @arg @ref RCC_MCO1SOURCE_EXT_HSE XT1 external 3-25 MHz oscillator clock selected as MCO source
+ * @arg @ref RCC_MCO1SOURCE_PLL3CLK PLL3 clock selected as MCO source
+ @endif
+ @if STM32F107xC
+ * @arg @ref RCC_MCO1SOURCE_PLLCLK PLL clock divided by 2 selected as MCO source
+ * @arg @ref RCC_MCO1SOURCE_PLL2CLK PLL2 clock selected as MCO source
+ * @arg @ref RCC_MCO1SOURCE_PLL3CLK_DIV2 PLL3 clock divided by 2 selected as MCO source
+ * @arg @ref RCC_MCO1SOURCE_EXT_HSE XT1 external 3-25 MHz oscillator clock selected as MCO source
+ * @arg @ref RCC_MCO1SOURCE_PLL3CLK PLL3 clock selected as MCO source
+ @endif
+ * @param RCC_MCODiv specifies the MCO DIV.
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_MCODIV_1 no division applied to MCO clock
+ * @retval None
+ */
+void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
+{
+ GPIO_InitTypeDef gpio = {0U};
+
+ /* Check the parameters */
+ assert_param(IS_RCC_MCO(RCC_MCOx));
+ assert_param(IS_RCC_MCODIV(RCC_MCODiv));
+ assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
+
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(RCC_MCOx);
+ UNUSED(RCC_MCODiv);
+
+ /* Configure the MCO1 pin in alternate function mode */
+ gpio.Mode = GPIO_MODE_AF_PP;
+ gpio.Speed = GPIO_SPEED_FREQ_HIGH;
+ gpio.Pull = GPIO_NOPULL;
+ gpio.Pin = MCO1_PIN;
+
+ /* MCO1 Clock Enable */
+ MCO1_CLK_ENABLE();
+
+ HAL_GPIO_Init(MCO1_GPIO_PORT, &gpio);
+
+ /* Configure the MCO clock source */
+ __HAL_RCC_MCO1_CONFIG(RCC_MCOSource, RCC_MCODiv);
+}
+
+/**
+ * @brief Enables the Clock Security System.
+ * @note If a failure is detected on the HSE oscillator clock, this oscillator
+ * is automatically disabled and an interrupt is generated to inform the
+ * software about the failure (Clock Security System Interrupt, CSSI),
+ * allowing the MCU to perform rescue operations. The CSSI is linked to
+ * the Cortex-M3 NMI (Non-Maskable Interrupt) exception vector.
+ * @retval None
+ */
+void HAL_RCC_EnableCSS(void)
+{
+ *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)ENABLE;
+}
+
+/**
+ * @brief Disables the Clock Security System.
+ * @retval None
+ */
+void HAL_RCC_DisableCSS(void)
+{
+ *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)DISABLE;
+}
+
+/**
+ * @brief Returns the SYSCLK frequency
+ * @note The system frequency computed by this function is not the real
+ * frequency in the chip. It is calculated based on the predefined
+ * constant and the selected clock source:
+ * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
+ * @note If SYSCLK source is HSE, function returns a value based on HSE_VALUE
+ * divided by PREDIV factor(**)
+ * @note If SYSCLK source is PLL, function returns a value based on HSE_VALUE
+ * divided by PREDIV factor(**) or HSI_VALUE(*) multiplied by the PLL factor.
+ * @note (*) HSI_VALUE is a constant defined in stm32f1xx_hal_conf.h file (default value
+ * 8 MHz) but the real value may vary depending on the variations
+ * in voltage and temperature.
+ * @note (**) HSE_VALUE is a constant defined in stm32f1xx_hal_conf.h file (default value
+ * 8 MHz), user has to ensure that HSE_VALUE is same as the real
+ * frequency of the crystal used. Otherwise, this function may
+ * have wrong result.
+ *
+ * @note The result of this function could be not correct when using fractional
+ * value for HSE crystal.
+ *
+ * @note This function can be used by the user application to compute the
+ * baud-rate for the communication peripherals or configure other parameters.
+ *
+ * @note Each time SYSCLK changes, this function must be called to update the
+ * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
+ *
+ * @retval SYSCLK frequency
+ */
+uint32_t HAL_RCC_GetSysClockFreq(void)
+{
+#if defined(RCC_CFGR2_PREDIV1SRC)
+ const uint8_t aPLLMULFactorTable[14] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 13};
+ const uint8_t aPredivFactorTable[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+#else
+ const uint8_t aPLLMULFactorTable[16] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16};
+#if defined(RCC_CFGR2_PREDIV1)
+ const uint8_t aPredivFactorTable[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+#else
+ const uint8_t aPredivFactorTable[2] = {1, 2};
+#endif /*RCC_CFGR2_PREDIV1*/
+
+#endif
+ uint32_t tmpreg = 0U, prediv = 0U, pllclk = 0U, pllmul = 0U;
+ uint32_t sysclockfreq = 0U;
+#if defined(RCC_CFGR2_PREDIV1SRC)
+ uint32_t prediv2 = 0U, pll2mul = 0U;
+#endif /*RCC_CFGR2_PREDIV1SRC*/
+
+ tmpreg = RCC->CFGR;
+
+ /* Get SYSCLK source -------------------------------------------------------*/
+ switch (tmpreg & RCC_CFGR_SWS)
+ {
+ case RCC_SYSCLKSOURCE_STATUS_HSE: /* HSE used as system clock */
+ {
+ sysclockfreq = HSE_VALUE;
+ break;
+ }
+ case RCC_SYSCLKSOURCE_STATUS_PLLCLK: /* PLL used as system clock */
+ {
+ pllmul = aPLLMULFactorTable[(uint32_t)(tmpreg & RCC_CFGR_PLLMULL) >> RCC_CFGR_PLLMULL_Pos];
+ if ((tmpreg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
+ {
+#if defined(RCC_CFGR2_PREDIV1)
+ prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV1) >> RCC_CFGR2_PREDIV1_Pos];
+#else
+ prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR & RCC_CFGR_PLLXTPRE) >> RCC_CFGR_PLLXTPRE_Pos];
+#endif /*RCC_CFGR2_PREDIV1*/
+#if defined(RCC_CFGR2_PREDIV1SRC)
+
+ if(HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC))
+ {
+ /* PLL2 selected as Prediv1 source */
+ /* PLLCLK = PLL2CLK / PREDIV1 * PLLMUL with PLL2CLK = HSE/PREDIV2 * PLL2MUL */
+ prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
+ pll2mul = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> RCC_CFGR2_PLL2MUL_Pos) + 2;
+ pllclk = (uint32_t)(((uint64_t)HSE_VALUE * (uint64_t)pll2mul * (uint64_t)pllmul) / ((uint64_t)prediv2 * (uint64_t)prediv));
+ }
+ else
+ {
+ /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
+ pllclk = (uint32_t)((HSE_VALUE * pllmul) / prediv);
+ }
+
+ /* If PLLMUL was set to 13 means that it was to cover the case PLLMUL 6.5 (avoid using float) */
+ /* In this case need to divide pllclk by 2 */
+ if (pllmul == aPLLMULFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> RCC_CFGR_PLLMULL_Pos])
+ {
+ pllclk = pllclk / 2;
+ }
+#else
+ /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
+ pllclk = (uint32_t)((HSE_VALUE * pllmul) / prediv);
+#endif /*RCC_CFGR2_PREDIV1SRC*/
+ }
+ else
+ {
+ /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */
+ pllclk = (uint32_t)((HSI_VALUE >> 1) * pllmul);
+ }
+ sysclockfreq = pllclk;
+ break;
+ }
+ case RCC_SYSCLKSOURCE_STATUS_HSI: /* HSI used as system clock source */
+ default: /* HSI used as system clock */
+ {
+ sysclockfreq = HSI_VALUE;
+ break;
+ }
+ }
+ return sysclockfreq;
+}
+
+/**
+ * @brief Returns the HCLK frequency
+ * @note Each time HCLK changes, this function must be called to update the
+ * right HCLK value. Otherwise, any configuration based on this function will be incorrect.
+ *
+ * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
+ * and updated within this function
+ * @retval HCLK frequency
+ */
+uint32_t HAL_RCC_GetHCLKFreq(void)
+{
+ return SystemCoreClock;
+}
+
+/**
+ * @brief Returns the PCLK1 frequency
+ * @note Each time PCLK1 changes, this function must be called to update the
+ * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
+ * @retval PCLK1 frequency
+ */
+uint32_t HAL_RCC_GetPCLK1Freq(void)
+{
+ /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
+ return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos]);
+}
+
+/**
+ * @brief Returns the PCLK2 frequency
+ * @note Each time PCLK2 changes, this function must be called to update the
+ * right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
+ * @retval PCLK2 frequency
+ */
+uint32_t HAL_RCC_GetPCLK2Freq(void)
+{
+ /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
+ return (HAL_RCC_GetHCLKFreq()>> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos]);
+}
+
+/**
+ * @brief Configures the RCC_OscInitStruct according to the internal
+ * RCC configuration registers.
+ * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
+ * will be configured.
+ * @retval None
+ */
+void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
+{
+ /* Check the parameters */
+ assert_param(RCC_OscInitStruct != NULL);
+
+ /* Set all possible values for the Oscillator type parameter ---------------*/
+ RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI \
+ | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
+
+#if defined(RCC_CFGR2_PREDIV1SRC)
+ /* Get the Prediv1 source --------------------------------------------------*/
+ RCC_OscInitStruct->Prediv1Source = READ_BIT(RCC->CFGR2,RCC_CFGR2_PREDIV1SRC);
+#endif /* RCC_CFGR2_PREDIV1SRC */
+
+ /* Get the HSE configuration -----------------------------------------------*/
+ if((RCC->CR &RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
+ {
+ RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
+ }
+ else if((RCC->CR &RCC_CR_HSEON) == RCC_CR_HSEON)
+ {
+ RCC_OscInitStruct->HSEState = RCC_HSE_ON;
+ }
+ else
+ {
+ RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
+ }
+ RCC_OscInitStruct->HSEPredivValue = __HAL_RCC_HSE_GET_PREDIV();
+
+ /* Get the HSI configuration -----------------------------------------------*/
+ if((RCC->CR &RCC_CR_HSION) == RCC_CR_HSION)
+ {
+ RCC_OscInitStruct->HSIState = RCC_HSI_ON;
+ }
+ else
+ {
+ RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
+ }
+
+ RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR & RCC_CR_HSITRIM) >> RCC_CR_HSITRIM_Pos);
+
+ /* Get the LSE configuration -----------------------------------------------*/
+ if((RCC->BDCR &RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
+ {
+ RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
+ }
+ else if((RCC->BDCR &RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
+ {
+ RCC_OscInitStruct->LSEState = RCC_LSE_ON;
+ }
+ else
+ {
+ RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
+ }
+
+ /* Get the LSI configuration -----------------------------------------------*/
+ if((RCC->CSR &RCC_CSR_LSION) == RCC_CSR_LSION)
+ {
+ RCC_OscInitStruct->LSIState = RCC_LSI_ON;
+ }
+ else
+ {
+ RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
+ }
+
+
+ /* Get the PLL configuration -----------------------------------------------*/
+ if((RCC->CR &RCC_CR_PLLON) == RCC_CR_PLLON)
+ {
+ RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
+ }
+ else
+ {
+ RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
+ }
+ RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLSRC);
+ RCC_OscInitStruct->PLL.PLLMUL = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLMULL);
+#if defined(RCC_CR_PLL2ON)
+ /* Get the PLL2 configuration -----------------------------------------------*/
+ if((RCC->CR &RCC_CR_PLL2ON) == RCC_CR_PLL2ON)
+ {
+ RCC_OscInitStruct->PLL2.PLL2State = RCC_PLL2_ON;
+ }
+ else
+ {
+ RCC_OscInitStruct->PLL2.PLL2State = RCC_PLL2_OFF;
+ }
+ RCC_OscInitStruct->PLL2.HSEPrediv2Value = __HAL_RCC_HSE_GET_PREDIV2();
+ RCC_OscInitStruct->PLL2.PLL2MUL = (uint32_t)(RCC->CFGR2 & RCC_CFGR2_PLL2MUL);
+#endif /* RCC_CR_PLL2ON */
+}
+
+/**
+ * @brief Get the RCC_ClkInitStruct according to the internal
+ * RCC configuration registers.
+ * @param RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that
+ * contains the current clock configuration.
+ * @param pFLatency Pointer on the Flash Latency.
+ * @retval None
+ */
+void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency)
+{
+ /* Check the parameters */
+ assert_param(RCC_ClkInitStruct != NULL);
+ assert_param(pFLatency != NULL);
+
+ /* Set all possible values for the Clock type parameter --------------------*/
+ RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
+
+ /* Get the SYSCLK configuration --------------------------------------------*/
+ RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW);
+
+ /* Get the HCLK configuration ----------------------------------------------*/
+ RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE);
+
+ /* Get the APB1 configuration ----------------------------------------------*/
+ RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE1);
+
+ /* Get the APB2 configuration ----------------------------------------------*/
+ RCC_ClkInitStruct->APB2CLKDivider = (uint32_t)((RCC->CFGR & RCC_CFGR_PPRE2) >> 3);
+
+#if defined(FLASH_ACR_LATENCY)
+ /* Get the Flash Wait State (Latency) configuration ------------------------*/
+ *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
+#else
+ /* For VALUE lines devices, only LATENCY_0 can be set*/
+ *pFLatency = (uint32_t)FLASH_LATENCY_0;
+#endif
+}
+
+/**
+ * @brief This function handles the RCC CSS interrupt request.
+ * @note This API should be called under the NMI_Handler().
+ * @retval None
+ */
+void HAL_RCC_NMI_IRQHandler(void)
+{
+ /* Check RCC CSSF flag */
+ if(__HAL_RCC_GET_IT(RCC_IT_CSS))
+ {
+ /* RCC Clock Security System interrupt user callback */
+ HAL_RCC_CSSCallback();
+
+ /* Clear RCC CSS pending bit */
+ __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
+ }
+}
+
+/**
+ * @brief This function provides delay (in milliseconds) based on CPU cycles method.
+ * @param mdelay: specifies the delay time length, in milliseconds.
+ * @retval None
+ */
+static void RCC_Delay(uint32_t mdelay)
+{
+ __IO uint32_t Delay = mdelay * (SystemCoreClock / 8U / 1000U);
+ do
+ {
+ __NOP();
+ }
+ while (Delay --);
+}
+
+/**
+ * @brief RCC Clock Security System interrupt callback
+ * @retval none
+ */
+__weak void HAL_RCC_CSSCallback(void)
+{
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_RCC_CSSCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_RCC_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c
new file mode 100644
index 0000000..65db17b
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c
@@ -0,0 +1,879 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_rcc_ex.c
+ * @author MCD Application Team
+ * @brief Extended RCC HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities RCC extension peripheral:
+ * + Extended Peripheral Control functions
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_RCC_MODULE_ENABLED
+
+/** @defgroup RCCEx RCCEx
+ * @brief RCC Extension HAL module driver.
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup RCCEx_Private_Constants RCCEx Private Constants
+ * @{
+ */
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/** @defgroup RCCEx_Private_Macros RCCEx Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
+ * @{
+ */
+
+/** @defgroup RCCEx_Exported_Functions_Group1 Peripheral Control functions
+ * @brief Extended Peripheral Control functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Extended Peripheral Control functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the RCC Clocks
+ frequencies.
+ [..]
+ (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
+ select the RTC clock source; in this case the Backup domain will be reset in
+ order to modify the RTC Clock source, as consequence RTC registers (including
+ the backup registers) are set to their reset values.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the
+ * RCC_PeriphCLKInitTypeDef.
+ * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
+ * contains the configuration information for the Extended Peripherals clocks(RTC clock).
+ *
+ * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
+ * the RTC clock source; in this case the Backup domain will be reset in
+ * order to modify the RTC Clock source, as consequence RTC registers (including
+ * the backup registers) are set to their reset values.
+ *
+ * @note In case of STM32F105xC or STM32F107xC devices, PLLI2S will be enabled if requested on
+ * one of 2 I2S interfaces. When PLLI2S is enabled, you need to call HAL_RCCEx_DisablePLLI2S to
+ * manually disable it.
+ *
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
+{
+ uint32_t tickstart = 0U, temp_reg = 0U;
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ uint32_t pllactive = 0U;
+#endif /* STM32F105xC || STM32F107xC */
+
+ /* Check the parameters */
+ assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
+
+ /*------------------------------- RTC/LCD Configuration ------------------------*/
+ if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC))
+ {
+ /* check for RTC Parameters used to output RTCCLK */
+ assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
+
+ FlagStatus pwrclkchanged = RESET;
+
+ /* As soon as function is called to change RTC clock source, activation of the
+ power domain is done. */
+ /* Requires to enable write access to Backup Domain of necessary */
+ if(__HAL_RCC_PWR_IS_CLK_DISABLED())
+ {
+ __HAL_RCC_PWR_CLK_ENABLE();
+ pwrclkchanged = SET;
+ }
+
+ if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
+ {
+ /* Enable write access to Backup domain */
+ SET_BIT(PWR->CR, PWR_CR_DBP);
+
+ /* Wait for Backup domain Write protection disable */
+ tickstart = HAL_GetTick();
+
+ while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
+ {
+ if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
+ temp_reg = (RCC->BDCR & RCC_BDCR_RTCSEL);
+ if((temp_reg != 0x00000000U) && (temp_reg != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
+ {
+ /* Store the content of BDCR register before the reset of Backup Domain */
+ temp_reg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
+ /* RTC Clock selection can be changed only if the Backup Domain is reset */
+ __HAL_RCC_BACKUPRESET_FORCE();
+ __HAL_RCC_BACKUPRESET_RELEASE();
+ /* Restore the Content of BDCR register */
+ RCC->BDCR = temp_reg;
+
+ /* Wait for LSERDY if LSE was enabled */
+ if (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSEON))
+ {
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till LSE is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+ __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
+
+ /* Require to disable power clock if necessary */
+ if(pwrclkchanged == SET)
+ {
+ __HAL_RCC_PWR_CLK_DISABLE();
+ }
+ }
+
+ /*------------------------------ ADC clock Configuration ------------------*/
+ if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_ADCPLLCLK_DIV(PeriphClkInit->AdcClockSelection));
+
+ /* Configure the ADC clock source */
+ __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
+ }
+
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ /*------------------------------ I2S2 Configuration ------------------------*/
+ if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S2) == RCC_PERIPHCLK_I2S2)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_I2S2CLKSOURCE(PeriphClkInit->I2s2ClockSelection));
+
+ /* Configure the I2S2 clock source */
+ __HAL_RCC_I2S2_CONFIG(PeriphClkInit->I2s2ClockSelection);
+ }
+
+ /*------------------------------ I2S3 Configuration ------------------------*/
+ if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S3) == RCC_PERIPHCLK_I2S3)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_I2S3CLKSOURCE(PeriphClkInit->I2s3ClockSelection));
+
+ /* Configure the I2S3 clock source */
+ __HAL_RCC_I2S3_CONFIG(PeriphClkInit->I2s3ClockSelection);
+ }
+
+ /*------------------------------ PLL I2S Configuration ----------------------*/
+ /* Check that PLLI2S need to be enabled */
+ if (HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_I2S2SRC) || HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
+ {
+ /* Update flag to indicate that PLL I2S should be active */
+ pllactive = 1;
+ }
+
+ /* Check if PLL I2S need to be enabled */
+ if (pllactive == 1)
+ {
+ /* Enable PLL I2S only if not active */
+ if (HAL_IS_BIT_CLR(RCC->CR, RCC_CR_PLL3ON))
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_PLLI2S_MUL(PeriphClkInit->PLLI2S.PLLI2SMUL));
+ assert_param(IS_RCC_HSE_PREDIV2(PeriphClkInit->PLLI2S.HSEPrediv2Value));
+
+ /* Prediv2 can be written only when the PLL2 is disabled. */
+ /* Return an error only if new value is different from the programmed value */
+ if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLL2ON) && \
+ (__HAL_RCC_HSE_GET_PREDIV2() != PeriphClkInit->PLLI2S.HSEPrediv2Value))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Configure the HSE prediv2 factor --------------------------------*/
+ __HAL_RCC_HSE_PREDIV2_CONFIG(PeriphClkInit->PLLI2S.HSEPrediv2Value);
+
+ /* Configure the main PLLI2S multiplication factors. */
+ __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SMUL);
+
+ /* Enable the main PLLI2S. */
+ __HAL_RCC_PLLI2S_ENABLE();
+
+ /* Get Start Tick*/
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLLI2S is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ else
+ {
+ /* Return an error only if user wants to change the PLLI2SMUL whereas PLLI2S is active */
+ if (READ_BIT(RCC->CFGR2, RCC_CFGR2_PLL3MUL) != PeriphClkInit->PLLI2S.PLLI2SMUL)
+ {
+ return HAL_ERROR;
+ }
+ }
+ }
+#endif /* STM32F105xC || STM32F107xC */
+
+#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
+ || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
+ || defined(STM32F105xC) || defined(STM32F107xC)
+ /*------------------------------ USB clock Configuration ------------------*/
+ if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_USBPLLCLK_DIV(PeriphClkInit->UsbClockSelection));
+
+ /* Configure the USB clock source */
+ __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
+ }
+#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Get the PeriphClkInit according to the internal
+ * RCC configuration registers.
+ * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
+ * returns the configuration information for the Extended Peripherals clocks(RTC, I2S, ADC clocks).
+ * @retval None
+ */
+void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
+{
+ uint32_t srcclk = 0U;
+
+ /* Set all possible values for the extended clock type parameter------------*/
+ PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_RTC;
+
+ /* Get the RTC configuration -----------------------------------------------*/
+ srcclk = __HAL_RCC_GET_RTC_SOURCE();
+ /* Source clock is LSE or LSI*/
+ PeriphClkInit->RTCClockSelection = srcclk;
+
+ /* Get the ADC clock configuration -----------------------------------------*/
+ PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_ADC;
+ PeriphClkInit->AdcClockSelection = __HAL_RCC_GET_ADC_SOURCE();
+
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ /* Get the I2S2 clock configuration -----------------------------------------*/
+ PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S2;
+ PeriphClkInit->I2s2ClockSelection = __HAL_RCC_GET_I2S2_SOURCE();
+
+ /* Get the I2S3 clock configuration -----------------------------------------*/
+ PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S3;
+ PeriphClkInit->I2s3ClockSelection = __HAL_RCC_GET_I2S3_SOURCE();
+
+#endif /* STM32F105xC || STM32F107xC */
+
+#if defined(STM32F103xE) || defined(STM32F103xG)
+ /* Get the I2S2 clock configuration -----------------------------------------*/
+ PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S2;
+ PeriphClkInit->I2s2ClockSelection = RCC_I2S2CLKSOURCE_SYSCLK;
+
+ /* Get the I2S3 clock configuration -----------------------------------------*/
+ PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S3;
+ PeriphClkInit->I2s3ClockSelection = RCC_I2S3CLKSOURCE_SYSCLK;
+
+#endif /* STM32F103xE || STM32F103xG */
+
+#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
+ || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
+ || defined(STM32F105xC) || defined(STM32F107xC)
+ /* Get the USB clock configuration -----------------------------------------*/
+ PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
+ PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
+#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
+}
+
+/**
+ * @brief Returns the peripheral clock frequency
+ * @note Returns 0 if peripheral clock is unknown
+ * @param PeriphClk Peripheral clock identifier
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock
+ * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock
+ @if STM32F103xE
+ * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ @endif
+ @if STM32F103xG
+ * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
+ @endif
+ @if STM32F105xC
+ * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
+ @endif
+ @if STM32F107xC
+ * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
+ @endif
+ @if STM32F102xx
+ * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
+ @endif
+ @if STM32F103xx
+ * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
+ @endif
+ * @retval Frequency in Hz (0: means that no available frequency for the peripheral)
+ */
+uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
+{
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ const uint8_t aPLLMULFactorTable[14] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 13};
+ const uint8_t aPredivFactorTable[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+
+ uint32_t prediv1 = 0U, pllclk = 0U, pllmul = 0U;
+ uint32_t pll2mul = 0U, pll3mul = 0U, prediv2 = 0U;
+#endif /* STM32F105xC || STM32F107xC */
+#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6) || \
+ defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)
+ const uint8_t aPLLMULFactorTable[16] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16};
+ const uint8_t aPredivFactorTable[2] = {1, 2};
+
+ uint32_t prediv1 = 0U, pllclk = 0U, pllmul = 0U;
+#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG */
+ uint32_t temp_reg = 0U, frequency = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
+
+ switch (PeriphClk)
+ {
+#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
+ || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
+ || defined(STM32F105xC) || defined(STM32F107xC)
+ case RCC_PERIPHCLK_USB:
+ {
+ /* Get RCC configuration ------------------------------------------------------*/
+ temp_reg = RCC->CFGR;
+
+ /* Check if PLL is enabled */
+ if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLLON))
+ {
+ pllmul = aPLLMULFactorTable[(uint32_t)(temp_reg & RCC_CFGR_PLLMULL) >> RCC_CFGR_PLLMULL_Pos];
+ if ((temp_reg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
+ {
+#if defined(STM32F105xC) || defined(STM32F107xC) || defined(STM32F100xB)\
+ || defined(STM32F100xE)
+ prediv1 = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV1) >> RCC_CFGR2_PREDIV1_Pos];
+#else
+ prediv1 = aPredivFactorTable[(uint32_t)(RCC->CFGR & RCC_CFGR_PLLXTPRE) >> RCC_CFGR_PLLXTPRE_Pos];
+#endif /* STM32F105xC || STM32F107xC || STM32F100xB || STM32F100xE */
+
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ if(HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC))
+ {
+ /* PLL2 selected as Prediv1 source */
+ /* PLLCLK = PLL2CLK / PREDIV1 * PLLMUL with PLL2CLK = HSE/PREDIV2 * PLL2MUL */
+ prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
+ pll2mul = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> RCC_CFGR2_PLL2MUL_Pos) + 2;
+ pllclk = (uint32_t)((((HSE_VALUE / prediv2) * pll2mul) / prediv1) * pllmul);
+ }
+ else
+ {
+ /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
+ pllclk = (uint32_t)((HSE_VALUE / prediv1) * pllmul);
+ }
+
+ /* If PLLMUL was set to 13 means that it was to cover the case PLLMUL 6.5 (avoid using float) */
+ /* In this case need to divide pllclk by 2 */
+ if (pllmul == aPLLMULFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> RCC_CFGR_PLLMULL_Pos])
+ {
+ pllclk = pllclk / 2;
+ }
+#else
+ if ((temp_reg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
+ {
+ /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
+ pllclk = (uint32_t)((HSE_VALUE / prediv1) * pllmul);
+ }
+#endif /* STM32F105xC || STM32F107xC */
+ }
+ else
+ {
+ /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */
+ pllclk = (uint32_t)((HSI_VALUE >> 1) * pllmul);
+ }
+
+ /* Calcul of the USB frequency*/
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ /* USBCLK = PLLVCO = (2 x PLLCLK) / USB prescaler */
+ if (__HAL_RCC_GET_USB_SOURCE() == RCC_USBCLKSOURCE_PLL_DIV2)
+ {
+ /* Prescaler of 2 selected for USB */
+ frequency = pllclk;
+ }
+ else
+ {
+ /* Prescaler of 3 selected for USB */
+ frequency = (2 * pllclk) / 3;
+ }
+#else
+ /* USBCLK = PLLCLK / USB prescaler */
+ if (__HAL_RCC_GET_USB_SOURCE() == RCC_USBCLKSOURCE_PLL)
+ {
+ /* No prescaler selected for USB */
+ frequency = pllclk;
+ }
+ else
+ {
+ /* Prescaler of 1.5 selected for USB */
+ frequency = (pllclk * 2) / 3;
+ }
+#endif
+ }
+ break;
+ }
+#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
+#if defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
+ case RCC_PERIPHCLK_I2S2:
+ {
+#if defined(STM32F103xE) || defined(STM32F103xG)
+ /* SYSCLK used as source clock for I2S2 */
+ frequency = HAL_RCC_GetSysClockFreq();
+#else
+ if (__HAL_RCC_GET_I2S2_SOURCE() == RCC_I2S2CLKSOURCE_SYSCLK)
+ {
+ /* SYSCLK used as source clock for I2S2 */
+ frequency = HAL_RCC_GetSysClockFreq();
+ }
+ else
+ {
+ /* Check if PLLI2S is enabled */
+ if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON))
+ {
+ /* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */
+ prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
+ pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 2;
+ frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul));
+ }
+ }
+#endif /* STM32F103xE || STM32F103xG */
+ break;
+ }
+ case RCC_PERIPHCLK_I2S3:
+ {
+#if defined(STM32F103xE) || defined(STM32F103xG)
+ /* SYSCLK used as source clock for I2S3 */
+ frequency = HAL_RCC_GetSysClockFreq();
+#else
+ if (__HAL_RCC_GET_I2S3_SOURCE() == RCC_I2S3CLKSOURCE_SYSCLK)
+ {
+ /* SYSCLK used as source clock for I2S3 */
+ frequency = HAL_RCC_GetSysClockFreq();
+ }
+ else
+ {
+ /* Check if PLLI2S is enabled */
+ if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON))
+ {
+ /* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */
+ prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
+ pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 2;
+ frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul));
+ }
+ }
+#endif /* STM32F103xE || STM32F103xG */
+ break;
+ }
+#endif /* STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
+ case RCC_PERIPHCLK_RTC:
+ {
+ /* Get RCC BDCR configuration ------------------------------------------------------*/
+ temp_reg = RCC->BDCR;
+
+ /* Check if LSE is ready if RTC clock selection is LSE */
+ if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSERDY)))
+ {
+ frequency = LSE_VALUE;
+ }
+ /* Check if LSI is ready if RTC clock selection is LSI */
+ else if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)))
+ {
+ frequency = LSI_VALUE;
+ }
+ else if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_HSE_DIV128) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)))
+ {
+ frequency = HSE_VALUE / 128U;
+ }
+ /* Clock not enabled for RTC*/
+ else
+ {
+ frequency = 0U;
+ }
+ break;
+ }
+ case RCC_PERIPHCLK_ADC:
+ {
+ frequency = HAL_RCC_GetPCLK2Freq() / (((__HAL_RCC_GET_ADC_SOURCE() >> RCC_CFGR_ADCPRE_Pos) + 1) * 2);
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ return(frequency);
+}
+
+/**
+ * @}
+ */
+
+#if defined(STM32F105xC) || defined(STM32F107xC)
+/** @defgroup RCCEx_Exported_Functions_Group2 PLLI2S Management function
+ * @brief PLLI2S Management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Extended PLLI2S Management functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the PLLI2S
+ activation or deactivation
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enable PLLI2S
+ * @param PLLI2SInit pointer to an RCC_PLLI2SInitTypeDef structure that
+ * contains the configuration information for the PLLI2S
+ * @note The PLLI2S configuration not modified if used by I2S2 or I2S3 Interface.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef *PLLI2SInit)
+{
+ uint32_t tickstart = 0U;
+
+ /* Check that PLL I2S has not been already enabled by I2S2 or I2S3*/
+ if (HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S2SRC) && HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_PLLI2S_MUL(PLLI2SInit->PLLI2SMUL));
+ assert_param(IS_RCC_HSE_PREDIV2(PLLI2SInit->HSEPrediv2Value));
+
+ /* Prediv2 can be written only when the PLL2 is disabled. */
+ /* Return an error only if new value is different from the programmed value */
+ if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLL2ON) && \
+ (__HAL_RCC_HSE_GET_PREDIV2() != PLLI2SInit->HSEPrediv2Value))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Disable the main PLLI2S. */
+ __HAL_RCC_PLLI2S_DISABLE();
+
+ /* Get Start Tick*/
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLLI2S is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Configure the HSE prediv2 factor --------------------------------*/
+ __HAL_RCC_HSE_PREDIV2_CONFIG(PLLI2SInit->HSEPrediv2Value);
+
+
+ /* Configure the main PLLI2S multiplication factors. */
+ __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SMUL);
+
+ /* Enable the main PLLI2S. */
+ __HAL_RCC_PLLI2S_ENABLE();
+
+ /* Get Start Tick*/
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLLI2S is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ else
+ {
+ /* PLLI2S cannot be modified as already used by I2S2 or I2S3 */
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disable PLLI2S
+ * @note PLLI2S is not disabled if used by I2S2 or I2S3 Interface.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RCCEx_DisablePLLI2S(void)
+{
+ uint32_t tickstart = 0U;
+
+ /* Disable PLL I2S as not requested by I2S2 or I2S3*/
+ if (HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S2SRC) && HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
+ {
+ /* Disable the main PLLI2S. */
+ __HAL_RCC_PLLI2S_DISABLE();
+
+ /* Get Start Tick*/
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLLI2S is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ else
+ {
+ /* PLLI2S is currently used by I2S2 or I2S3. Cannot be disabled.*/
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RCCEx_Exported_Functions_Group3 PLL2 Management function
+ * @brief PLL2 Management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Extended PLL2 Management functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the PLL2
+ activation or deactivation
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enable PLL2
+ * @param PLL2Init pointer to an RCC_PLL2InitTypeDef structure that
+ * contains the configuration information for the PLL2
+ * @note The PLL2 configuration not modified if used indirectly as system clock.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RCCEx_EnablePLL2(RCC_PLL2InitTypeDef *PLL2Init)
+{
+ uint32_t tickstart = 0U;
+
+ /* This bit can not be cleared if the PLL2 clock is used indirectly as system
+ clock (i.e. it is used as PLL clock entry that is used as system clock). */
+ if((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
+ (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
+ ((READ_BIT(RCC->CFGR2,RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_PLL2_MUL(PLL2Init->PLL2MUL));
+ assert_param(IS_RCC_HSE_PREDIV2(PLL2Init->HSEPrediv2Value));
+
+ /* Prediv2 can be written only when the PLLI2S is disabled. */
+ /* Return an error only if new value is different from the programmed value */
+ if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLL3ON) && \
+ (__HAL_RCC_HSE_GET_PREDIV2() != PLL2Init->HSEPrediv2Value))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Disable the main PLL2. */
+ __HAL_RCC_PLL2_DISABLE();
+
+ /* Get Start Tick*/
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLL2 is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Configure the HSE prediv2 factor --------------------------------*/
+ __HAL_RCC_HSE_PREDIV2_CONFIG(PLL2Init->HSEPrediv2Value);
+
+ /* Configure the main PLL2 multiplication factors. */
+ __HAL_RCC_PLL2_CONFIG(PLL2Init->PLL2MUL);
+
+ /* Enable the main PLL2. */
+ __HAL_RCC_PLL2_ENABLE();
+
+ /* Get Start Tick*/
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLL2 is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disable PLL2
+ * @note PLL2 is not disabled if used indirectly as system clock.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RCCEx_DisablePLL2(void)
+{
+ uint32_t tickstart = 0U;
+
+ /* This bit can not be cleared if the PLL2 clock is used indirectly as system
+ clock (i.e. it is used as PLL clock entry that is used as system clock). */
+ if((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
+ (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
+ ((READ_BIT(RCC->CFGR2,RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* Disable the main PLL2. */
+ __HAL_RCC_PLL2_DISABLE();
+
+ /* Get Start Tick*/
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLL2 is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+#endif /* STM32F105xC || STM32F107xC */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_RCC_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc.c
new file mode 100644
index 0000000..bf6f9da
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc.c
@@ -0,0 +1,1718 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_rtc.c
+ * @author MCD Application Team
+ * @brief RTC HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Real Time Clock (RTC) peripheral:
+ * + Initialization and de-initialization functions
+ * + RTC Time and Date functions
+ * + RTC Alarm functions
+ * + Peripheral Control functions
+ * + Peripheral State functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==================================================================
+ [..]
+ (+) Enable the RTC domain access (see description in the section above).
+ (+) Configure the RTC Prescaler (Asynchronous prescaler to generate RTC 1Hz time base)
+ using the HAL_RTC_Init() function.
+
+ *** Time and Date configuration ***
+ ===================================
+ [..]
+ (+) To configure the RTC Calendar (Time and Date) use the HAL_RTC_SetTime()
+ and HAL_RTC_SetDate() functions.
+ (+) To read the RTC Calendar, use the HAL_RTC_GetTime() and HAL_RTC_GetDate() functions.
+
+ *** Alarm configuration ***
+ ===========================
+ [..]
+ (+) To configure the RTC Alarm use the HAL_RTC_SetAlarm() function.
+ You can also configure the RTC Alarm with interrupt mode using the HAL_RTC_SetAlarm_IT() function.
+ (+) To read the RTC Alarm, use the HAL_RTC_GetAlarm() function.
+
+ *** Tamper configuration ***
+ ============================
+ [..]
+ (+) Enable the RTC Tamper and configure the Tamper Level using the
+ HAL_RTCEx_SetTamper() function. You can configure RTC Tamper with interrupt
+ mode using HAL_RTCEx_SetTamper_IT() function.
+ (+) The TAMPER1 alternate function can be mapped to PC13
+
+ *** Backup Data Registers configuration ***
+ ===========================================
+ [..]
+ (+) To write to the RTC Backup Data registers, use the HAL_RTCEx_BKUPWrite()
+ function.
+ (+) To read the RTC Backup Data registers, use the HAL_RTCEx_BKUPRead()
+ function.
+
+ ##### WARNING: Drivers Restrictions #####
+ ==================================================================
+ [..] RTC version used on STM32F1 families is version V1. All the features supported by V2
+ (other families) will be not supported on F1.
+ [..] As on V2, main RTC features are managed by HW. But on F1, date feature is completely
+ managed by SW.
+ [..] Then, there are some restrictions compared to other families:
+ (+) Only format 24 hours supported in HAL (format 12 hours not supported)
+ (+) Date is saved in SRAM. Then, when MCU is in STOP or STANDBY mode, date will be lost.
+ User should implement a way to save date before entering in low power mode (an
+ example is provided with firmware package based on backup registers)
+ (+) Date is automatically updated each time a HAL_RTC_GetTime or HAL_RTC_GetDate is called.
+ (+) Alarm detection is limited to 1 day. It will expire only 1 time (no alarm repetition, need
+ to program a new alarm)
+
+ ##### Backup Domain Operating Condition #####
+ ==============================================================================
+ [..] The real-time clock (RTC) and the RTC backup registers can be powered
+ from the VBAT voltage when the main VDD supply is powered off.
+ To retain the content of the RTC backup registers and supply the RTC
+ when VDD is turned off, VBAT pin can be connected to an optional
+ standby voltage supplied by a battery or by another source.
+
+ [..] To allow the RTC operating even when the main digital supply (VDD) is turned
+ off, the VBAT pin powers the following blocks:
+ (+) The RTC
+ (+) The LSE oscillator
+ (+) PC13 I/O
+
+ [..] When the backup domain is supplied by VDD (analog switch connected to VDD),
+ the following pins are available:
+ (+) PC13 can be used as a Tamper pin
+
+ [..] When the backup domain is supplied by VBAT (analog switch connected to VBAT
+ because VDD is not present), the following pins are available:
+ (+) PC13 can be used as the Tamper pin
+
+ ##### Backup Domain Reset #####
+ ==================================================================
+ [..] The backup domain reset sets all RTC registers and the RCC_BDCR register
+ to their reset values.
+ [..] A backup domain reset is generated when one of the following events occurs:
+ (#) Software reset, triggered by setting the BDRST bit in the
+ RCC Backup domain control register (RCC_BDCR).
+ (#) VDD or VBAT power on, if both supplies have previously been powered off.
+ (#) Tamper detection event resets all data backup registers.
+
+ ##### Backup Domain Access #####
+ ==================================================================
+ [..] After reset, the backup domain (RTC registers, RTC backup data
+ registers and backup SRAM) is protected against possible unwanted write
+ accesses.
+ [..] To enable access to the RTC Domain and RTC registers, proceed as follows:
+ (+) Call the function HAL_RCCEx_PeriphCLKConfig in using RCC_PERIPHCLK_RTC for
+ PeriphClockSelection and select RTCClockSelection (LSE, LSI or HSE)
+ (+) Enable the BKP clock in using __HAL_RCC_BKP_CLK_ENABLE()
+
+ ##### RTC and low power modes #####
+ ==================================================================
+ [..] The MCU can be woken up from a low power mode by an RTC alternate
+ function.
+ [..] The RTC alternate functions are the RTC alarms (Alarm A),
+ and RTC tamper event detection.
+ These RTC alternate functions can wake up the system from the Stop and
+ Standby low power modes.
+ [..] The system can also wake up from low power modes without depending
+ on an external interrupt (Auto-wakeup mode), by using the RTC alarm.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup RTC RTC
+ * @brief RTC HAL module driver
+ * @{
+ */
+
+#ifdef HAL_RTC_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup RTC_Private_Constants RTC Private Constants
+ * @{
+ */
+#define RTC_ALARM_RESETVALUE_REGISTER (uint16_t)0xFFFF
+#define RTC_ALARM_RESETVALUE 0xFFFFFFFFU
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/** @defgroup RTC_Private_Macros RTC Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup RTC_Private_Functions RTC Private Functions
+ * @{
+ */
+static uint32_t RTC_ReadTimeCounter(RTC_HandleTypeDef* hrtc);
+static HAL_StatusTypeDef RTC_WriteTimeCounter(RTC_HandleTypeDef* hrtc, uint32_t TimeCounter);
+static uint32_t RTC_ReadAlarmCounter(RTC_HandleTypeDef* hrtc);
+static HAL_StatusTypeDef RTC_WriteAlarmCounter(RTC_HandleTypeDef* hrtc, uint32_t AlarmCounter);
+static HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef* hrtc);
+static HAL_StatusTypeDef RTC_ExitInitMode(RTC_HandleTypeDef* hrtc);
+static uint8_t RTC_ByteToBcd2(uint8_t Value);
+static uint8_t RTC_Bcd2ToByte(uint8_t Value);
+static uint8_t RTC_IsLeapYear(uint16_t nYear);
+static void RTC_DateUpdate(RTC_HandleTypeDef* hrtc, uint32_t DayElapsed);
+static uint8_t RTC_WeekDayNum(uint32_t nYear, uint8_t nMonth, uint8_t nDay);
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup RTC_Exported_Functions RTC Exported Functions
+ * @{
+ */
+
+/** @defgroup RTC_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to initialize and configure the
+ RTC Prescaler (Asynchronous), disable RTC registers Write protection,
+ enter and exit the RTC initialization mode,
+ RTC registers synchronization check and reference clock detection enable.
+ (#) The RTC Prescaler should be programmed to generate the RTC 1Hz time base.
+ (#) All RTC registers are Write protected. Writing to the RTC registers
+ is enabled by setting the CNF bit in the RTC_CRL register.
+ (#) To read the calendar after wakeup from low power modes (Standby or Stop)
+ the software must first wait for the RSF bit (Register Synchronized Flag)
+ in the RTC_CRL register to be set by hardware.
+ The HAL_RTC_WaitForSynchro() function implements the above software
+ sequence (RSF clear and RSF check).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the RTC peripheral
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc)
+{
+ uint32_t prescaler = 0U;
+ /* Check input parameters */
+ if(hrtc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance));
+ assert_param(IS_RTC_CALIB_OUTPUT(hrtc->Init.OutPut));
+ assert_param(IS_RTC_ASYNCH_PREDIV(hrtc->Init.AsynchPrediv));
+
+ if(hrtc->State == HAL_RTC_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hrtc->Lock = HAL_UNLOCKED;
+
+ /* Initialize RTC MSP */
+ HAL_RTC_MspInit(hrtc);
+ }
+
+ /* Set RTC state */
+ hrtc->State = HAL_RTC_STATE_BUSY;
+
+ /* Waiting for synchro */
+ if(HAL_RTC_WaitForSynchro(hrtc) != HAL_OK)
+ {
+ /* Set RTC state */
+ hrtc->State = HAL_RTC_STATE_ERROR;
+
+ return HAL_ERROR;
+ }
+
+ /* Set Initialization mode */
+ if(RTC_EnterInitMode(hrtc) != HAL_OK)
+ {
+ /* Set RTC state */
+ hrtc->State = HAL_RTC_STATE_ERROR;
+
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* Clear Flags Bits */
+ CLEAR_BIT(hrtc->Instance->CRL, (RTC_FLAG_OW | RTC_FLAG_ALRAF | RTC_FLAG_SEC));
+
+ if(hrtc->Init.OutPut != RTC_OUTPUTSOURCE_NONE)
+ {
+ /* Disable the selected Tamper pin */
+ CLEAR_BIT(BKP->CR, BKP_CR_TPE);
+ }
+
+ /* Set the signal which will be routed to RTC Tamper pin*/
+ MODIFY_REG(BKP->RTCCR, (BKP_RTCCR_CCO | BKP_RTCCR_ASOE | BKP_RTCCR_ASOS), hrtc->Init.OutPut);
+
+ if (hrtc->Init.AsynchPrediv != RTC_AUTO_1_SECOND)
+ {
+ /* RTC Prescaler provided directly by end-user*/
+ prescaler = hrtc->Init.AsynchPrediv;
+ }
+ else
+ {
+ /* RTC Prescaler will be automatically calculated to get 1 second timebase */
+ /* Get the RTCCLK frequency */
+ prescaler = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_RTC);
+
+ /* Check that RTC clock is enabled*/
+ if (prescaler == 0U)
+ {
+ /* Should not happen. Frequency is not available*/
+ hrtc->State = HAL_RTC_STATE_ERROR;
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* RTC period = RTCCLK/(RTC_PR + 1) */
+ prescaler = prescaler - 1U;
+ }
+ }
+
+ /* Configure the RTC_PRLH / RTC_PRLL */
+ MODIFY_REG(hrtc->Instance->PRLH, RTC_PRLH_PRL, (prescaler >> 16U));
+ MODIFY_REG(hrtc->Instance->PRLL, RTC_PRLL_PRL, (prescaler & RTC_PRLL_PRL));
+
+ /* Wait for synchro */
+ if(RTC_ExitInitMode(hrtc) != HAL_OK)
+ {
+ hrtc->State = HAL_RTC_STATE_ERROR;
+
+ return HAL_ERROR;
+ }
+
+ /* Initialize date to 1st of January 2000 */
+ hrtc->DateToUpdate.Year = 0x00U;
+ hrtc->DateToUpdate.Month = RTC_MONTH_JANUARY;
+ hrtc->DateToUpdate.Date = 0x01U;
+
+ /* Set RTC state */
+ hrtc->State = HAL_RTC_STATE_READY;
+
+ return HAL_OK;
+ }
+}
+
+/**
+ * @brief DeInitializes the RTC peripheral
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @note This function does not reset the RTC Backup Data registers.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTC_DeInit(RTC_HandleTypeDef *hrtc)
+{
+ /* Check input parameters */
+ if(hrtc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance));
+
+ /* Set RTC state */
+ hrtc->State = HAL_RTC_STATE_BUSY;
+
+ /* Set Initialization mode */
+ if(RTC_EnterInitMode(hrtc) != HAL_OK)
+ {
+ /* Set RTC state */
+ hrtc->State = HAL_RTC_STATE_ERROR;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_ERROR;
+ }
+ else
+ {
+ CLEAR_REG(hrtc->Instance->CNTL);
+ CLEAR_REG(hrtc->Instance->CNTH);
+ WRITE_REG(hrtc->Instance->PRLL, 0x00008000U);
+ CLEAR_REG(hrtc->Instance->PRLH);
+
+ /* Reset All CRH/CRL bits */
+ CLEAR_REG(hrtc->Instance->CRH);
+ CLEAR_REG(hrtc->Instance->CRL);
+
+ if(RTC_ExitInitMode(hrtc) != HAL_OK)
+ {
+ hrtc->State = HAL_RTC_STATE_ERROR;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_ERROR;
+ }
+ }
+
+ /* Wait for synchro*/
+ HAL_RTC_WaitForSynchro(hrtc);
+
+ /* Clear RSF flag */
+ CLEAR_BIT(hrtc->Instance->CRL, RTC_FLAG_RSF);
+
+ /* De-Initialize RTC MSP */
+ HAL_RTC_MspDeInit(hrtc);
+
+ hrtc->State = HAL_RTC_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the RTC MSP.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @retval None
+ */
+__weak void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hrtc);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_RTC_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes the RTC MSP.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @retval None
+ */
+__weak void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hrtc);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_RTC_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Exported_Functions_Group2 Time and Date functions
+ * @brief RTC Time and Date functions
+ *
+@verbatim
+ ===============================================================================
+ ##### RTC Time and Date functions #####
+ ===============================================================================
+
+ [..] This section provides functions allowing to configure Time and Date features
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sets RTC current time.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @param sTime: Pointer to Time structure
+ * @param Format: Specifies the format of the entered parameters.
+ * This parameter can be one of the following values:
+ * @arg RTC_FORMAT_BIN: Binary data format
+ * @arg RTC_FORMAT_BCD: BCD data format
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
+{
+ uint32_t counter_time = 0U, counter_alarm = 0U;
+
+ /* Check input parameters */
+ if((hrtc == NULL) || (sTime == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_RTC_FORMAT(Format));
+
+ /* Process Locked */
+ __HAL_LOCK(hrtc);
+
+ hrtc->State = HAL_RTC_STATE_BUSY;
+
+ if(Format == RTC_FORMAT_BIN)
+ {
+ assert_param(IS_RTC_HOUR24(sTime->Hours));
+ assert_param(IS_RTC_MINUTES(sTime->Minutes));
+ assert_param(IS_RTC_SECONDS(sTime->Seconds));
+
+ counter_time = (uint32_t)(((uint32_t)sTime->Hours * 3600U) + \
+ ((uint32_t)sTime->Minutes * 60U) + \
+ ((uint32_t)sTime->Seconds));
+ }
+ else
+ {
+ assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sTime->Hours)));
+ assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sTime->Minutes)));
+ assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sTime->Seconds)));
+
+ counter_time = (((uint32_t)(RTC_Bcd2ToByte(sTime->Hours)) * 3600U) + \
+ ((uint32_t)(RTC_Bcd2ToByte(sTime->Minutes)) * 60U) + \
+ ((uint32_t)(RTC_Bcd2ToByte(sTime->Seconds))));
+ }
+
+ /* Write time counter in RTC registers */
+ if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
+ {
+ /* Set RTC state */
+ hrtc->State = HAL_RTC_STATE_ERROR;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* Clear Second and overflow flags */
+ CLEAR_BIT(hrtc->Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW));
+
+ /* Read current Alarm counter in RTC registers */
+ counter_alarm = RTC_ReadAlarmCounter(hrtc);
+
+ /* Set again alarm to match with new time if enabled */
+ if (counter_alarm != RTC_ALARM_RESETVALUE)
+ {
+ if(counter_alarm < counter_time)
+ {
+ /* Add 1 day to alarm counter*/
+ counter_alarm += (uint32_t)(24U * 3600U);
+
+ /* Write new Alarm counter in RTC registers */
+ if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
+ {
+ /* Set RTC state */
+ hrtc->State = HAL_RTC_STATE_ERROR;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_ERROR;
+ }
+ }
+ }
+
+ hrtc->State = HAL_RTC_STATE_READY;
+
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_OK;
+ }
+}
+
+/**
+ * @brief Gets RTC current time.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @param sTime: Pointer to Time structure
+ * @param Format: Specifies the format of the entered parameters.
+ * This parameter can be one of the following values:
+ * @arg RTC_FORMAT_BIN: Binary data format
+ * @arg RTC_FORMAT_BCD: BCD data format
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
+{
+ uint32_t counter_time = 0U, counter_alarm = 0U, days_elapsed = 0U, hours = 0U;
+
+ /* Check input parameters */
+ if((hrtc == NULL) || (sTime == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_RTC_FORMAT(Format));
+
+ /* Check if counter overflow occurred */
+ if (__HAL_RTC_OVERFLOW_GET_FLAG(hrtc, RTC_FLAG_OW))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Read the time counter*/
+ counter_time = RTC_ReadTimeCounter(hrtc);
+
+ /* Fill the structure fields with the read parameters */
+ hours = counter_time / 3600U;
+ sTime->Minutes = (uint8_t)((counter_time % 3600U) / 60U);
+ sTime->Seconds = (uint8_t)((counter_time % 3600U) % 60U);
+
+ if (hours >= 24U)
+ {
+ /* Get number of days elapsed from last calculation */
+ days_elapsed = (hours / 24U);
+
+ /* Set Hours in RTC_TimeTypeDef structure*/
+ sTime->Hours = (hours % 24U);
+
+ /* Read Alarm counter in RTC registers */
+ counter_alarm = RTC_ReadAlarmCounter(hrtc);
+
+ /* Calculate remaining time to reach alarm (only if set and not yet expired)*/
+ if ((counter_alarm != RTC_ALARM_RESETVALUE) && (counter_alarm > counter_time))
+ {
+ counter_alarm -= counter_time;
+ }
+ else
+ {
+ /* In case of counter_alarm < counter_time */
+ /* Alarm expiration already occurred but alarm not deactivated */
+ counter_alarm = RTC_ALARM_RESETVALUE;
+ }
+
+ /* Set updated time in decreasing counter by number of days elapsed */
+ counter_time -= (days_elapsed * 24U * 3600U);
+
+ /* Write time counter in RTC registers */
+ if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Set updated alarm to be set */
+ if (counter_alarm != RTC_ALARM_RESETVALUE)
+ {
+ counter_alarm += counter_time;
+
+ /* Write time counter in RTC registers */
+ if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ /* Alarm already occurred. Set it to reset values to avoid unexpected expiration */
+ if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+ }
+
+ /* Update date */
+ RTC_DateUpdate(hrtc, days_elapsed);
+ }
+ else
+ {
+ sTime->Hours = hours;
+ }
+
+ /* Check the input parameters format */
+ if(Format != RTC_FORMAT_BIN)
+ {
+ /* Convert the time structure parameters to BCD format */
+ sTime->Hours = (uint8_t)RTC_ByteToBcd2(sTime->Hours);
+ sTime->Minutes = (uint8_t)RTC_ByteToBcd2(sTime->Minutes);
+ sTime->Seconds = (uint8_t)RTC_ByteToBcd2(sTime->Seconds);
+ }
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Sets RTC current date.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @param sDate: Pointer to date structure
+ * @param Format: specifies the format of the entered parameters.
+ * This parameter can be one of the following values:
+ * @arg RTC_FORMAT_BIN: Binary data format
+ * @arg RTC_FORMAT_BCD: BCD data format
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
+{
+ uint32_t counter_time = 0U, counter_alarm = 0U, hours = 0U;
+
+ /* Check input parameters */
+ if((hrtc == NULL) || (sDate == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_RTC_FORMAT(Format));
+
+ /* Process Locked */
+ __HAL_LOCK(hrtc);
+
+ hrtc->State = HAL_RTC_STATE_BUSY;
+
+ if(Format == RTC_FORMAT_BIN)
+ {
+ assert_param(IS_RTC_YEAR(sDate->Year));
+ assert_param(IS_RTC_MONTH(sDate->Month));
+ assert_param(IS_RTC_DATE(sDate->Date));
+
+ /* Change the current date */
+ hrtc->DateToUpdate.Year = sDate->Year;
+ hrtc->DateToUpdate.Month = sDate->Month;
+ hrtc->DateToUpdate.Date = sDate->Date;
+ }
+ else
+ {
+ assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(sDate->Year)));
+ assert_param(IS_RTC_MONTH(RTC_Bcd2ToByte(sDate->Month)));
+ assert_param(IS_RTC_DATE(RTC_Bcd2ToByte(sDate->Date)));
+
+ /* Change the current date */
+ hrtc->DateToUpdate.Year = RTC_Bcd2ToByte(sDate->Year);
+ hrtc->DateToUpdate.Month = RTC_Bcd2ToByte(sDate->Month);
+ hrtc->DateToUpdate.Date = RTC_Bcd2ToByte(sDate->Date);
+ }
+
+ /* WeekDay set by user can be ignored because automatically calculated */
+ hrtc->DateToUpdate.WeekDay = RTC_WeekDayNum(hrtc->DateToUpdate.Year, hrtc->DateToUpdate.Month, hrtc->DateToUpdate.Date);
+ sDate->WeekDay = hrtc->DateToUpdate.WeekDay;
+
+ /* Reset time to be aligned on the same day */
+ /* Read the time counter*/
+ counter_time = RTC_ReadTimeCounter(hrtc);
+
+ /* Fill the structure fields with the read parameters */
+ hours = counter_time / 3600U;
+ if (hours > 24U)
+ {
+ /* Set updated time in decreasing counter by number of days elapsed */
+ counter_time -= ((hours / 24U) * 24U * 3600U);
+ /* Write time counter in RTC registers */
+ if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
+ {
+ /* Set RTC state */
+ hrtc->State = HAL_RTC_STATE_ERROR;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_ERROR;
+ }
+
+ /* Read current Alarm counter in RTC registers */
+ counter_alarm = RTC_ReadAlarmCounter(hrtc);
+
+ /* Set again alarm to match with new time if enabled */
+ if (counter_alarm != RTC_ALARM_RESETVALUE)
+ {
+ if(counter_alarm < counter_time)
+ {
+ /* Add 1 day to alarm counter*/
+ counter_alarm += (uint32_t)(24U * 3600U);
+
+ /* Write new Alarm counter in RTC registers */
+ if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
+ {
+ /* Set RTC state */
+ hrtc->State = HAL_RTC_STATE_ERROR;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_ERROR;
+ }
+ }
+ }
+
+
+ }
+
+ hrtc->State = HAL_RTC_STATE_READY ;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Gets RTC current date.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @param sDate: Pointer to Date structure
+ * @param Format: Specifies the format of the entered parameters.
+ * This parameter can be one of the following values:
+ * @arg RTC_FORMAT_BIN: Binary data format
+ * @arg RTC_FORMAT_BCD: BCD data format
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
+{
+ RTC_TimeTypeDef stime = {0U};
+
+ /* Check input parameters */
+ if((hrtc == NULL) || (sDate == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_RTC_FORMAT(Format));
+
+ /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
+ if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Fill the structure fields with the read parameters */
+ sDate->WeekDay = hrtc->DateToUpdate.WeekDay;
+ sDate->Year = hrtc->DateToUpdate.Year;
+ sDate->Month = hrtc->DateToUpdate.Month;
+ sDate->Date = hrtc->DateToUpdate.Date;
+
+ /* Check the input parameters format */
+ if(Format != RTC_FORMAT_BIN)
+ {
+ /* Convert the date structure parameters to BCD format */
+ sDate->Year = (uint8_t)RTC_ByteToBcd2(sDate->Year);
+ sDate->Month = (uint8_t)RTC_ByteToBcd2(sDate->Month);
+ sDate->Date = (uint8_t)RTC_ByteToBcd2(sDate->Date);
+ }
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Exported_Functions_Group3 Alarm functions
+ * @brief RTC Alarm functions
+ *
+@verbatim
+ ===============================================================================
+ ##### RTC Alarm functions #####
+ ===============================================================================
+
+ [..] This section provides functions allowing to configure Alarm feature
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sets the specified RTC Alarm.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @param sAlarm: Pointer to Alarm structure
+ * @param Format: Specifies the format of the entered parameters.
+ * This parameter can be one of the following values:
+ * @arg RTC_FORMAT_BIN: Binary data format
+ * @arg RTC_FORMAT_BCD: BCD data format
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
+{
+ uint32_t counter_alarm = 0U, counter_time;
+ RTC_TimeTypeDef stime = {0U};
+
+ /* Check input parameters */
+ if((hrtc == NULL) || (sAlarm == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_RTC_FORMAT(Format));
+ assert_param(IS_RTC_ALARM(sAlarm->Alarm));
+
+ /* Process Locked */
+ __HAL_LOCK(hrtc);
+
+ hrtc->State = HAL_RTC_STATE_BUSY;
+
+ /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
+ if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Convert time in seconds */
+ counter_time = (uint32_t)(((uint32_t)stime.Hours * 3600U) + \
+ ((uint32_t)stime.Minutes * 60U) + \
+ ((uint32_t)stime.Seconds));
+
+ if(Format == RTC_FORMAT_BIN)
+ {
+ assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours));
+ assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes));
+ assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds));
+
+ counter_alarm = (uint32_t)(((uint32_t)sAlarm->AlarmTime.Hours * 3600U) + \
+ ((uint32_t)sAlarm->AlarmTime.Minutes * 60U) + \
+ ((uint32_t)sAlarm->AlarmTime.Seconds));
+ }
+ else
+ {
+ assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
+ assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)));
+ assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
+
+ counter_alarm = (((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)) * 3600U) + \
+ ((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)) * 60U) + \
+ ((uint32_t)RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
+ }
+
+ /* Check that requested alarm should expire in the same day (otherwise add 1 day) */
+ if (counter_alarm < counter_time)
+ {
+ /* Add 1 day to alarm counter*/
+ counter_alarm += (uint32_t)(24U * 3600U);
+ }
+
+ /* Write Alarm counter in RTC registers */
+ if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
+ {
+ /* Set RTC state */
+ hrtc->State = HAL_RTC_STATE_ERROR;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_ERROR;
+ }
+ else
+ {
+ hrtc->State = HAL_RTC_STATE_READY;
+
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_OK;
+ }
+}
+
+/**
+ * @brief Sets the specified RTC Alarm with Interrupt
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @param sAlarm: Pointer to Alarm structure
+ * @param Format: Specifies the format of the entered parameters.
+ * This parameter can be one of the following values:
+ * @arg RTC_FORMAT_BIN: Binary data format
+ * @arg RTC_FORMAT_BCD: BCD data format
+ * @note The HAL_RTC_SetTime() must be called before enabling the Alarm feature.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
+{
+ uint32_t counter_alarm = 0U, counter_time;
+ RTC_TimeTypeDef stime = {0U};
+
+ /* Check input parameters */
+ if((hrtc == NULL) || (sAlarm == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_RTC_FORMAT(Format));
+ assert_param(IS_RTC_ALARM(sAlarm->Alarm));
+
+ /* Process Locked */
+ __HAL_LOCK(hrtc);
+
+ hrtc->State = HAL_RTC_STATE_BUSY;
+
+ /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
+ if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Convert time in seconds */
+ counter_time = (uint32_t)(((uint32_t)stime.Hours * 3600U) + \
+ ((uint32_t)stime.Minutes * 60U) + \
+ ((uint32_t)stime.Seconds));
+
+ if(Format == RTC_FORMAT_BIN)
+ {
+ assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours));
+ assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes));
+ assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds));
+
+ counter_alarm = (uint32_t)(((uint32_t)sAlarm->AlarmTime.Hours * 3600U) + \
+ ((uint32_t)sAlarm->AlarmTime.Minutes * 60U) + \
+ ((uint32_t)sAlarm->AlarmTime.Seconds));
+ }
+ else
+ {
+ assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
+ assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)));
+ assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
+
+ counter_alarm = (((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)) * 3600U) + \
+ ((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)) * 60U) + \
+ ((uint32_t)RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
+ }
+
+ /* Check that requested alarm should expire in the same day (otherwise add 1 day) */
+ if (counter_alarm < counter_time)
+ {
+ /* Add 1 day to alarm counter*/
+ counter_alarm += (uint32_t)(24U * 3600U);
+ }
+
+ /* Write alarm counter in RTC registers */
+ if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
+ {
+ /* Set RTC state */
+ hrtc->State = HAL_RTC_STATE_ERROR;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* Clear flag alarm A */
+ __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
+
+ /* Configure the Alarm interrupt */
+ __HAL_RTC_ALARM_ENABLE_IT(hrtc,RTC_IT_ALRA);
+
+ /* RTC Alarm Interrupt Configuration: EXTI configuration */
+ __HAL_RTC_ALARM_EXTI_ENABLE_IT();
+
+ __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE();
+
+ hrtc->State = HAL_RTC_STATE_READY;
+
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_OK;
+ }
+}
+
+/**
+ * @brief Gets the RTC Alarm value and masks.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @param sAlarm: Pointer to Date structure
+ * @param Alarm: Specifies the Alarm.
+ * This parameter can be one of the following values:
+ * @arg RTC_ALARM_A: Alarm
+ * @param Format: Specifies the format of the entered parameters.
+ * This parameter can be one of the following values:
+ * @arg RTC_FORMAT_BIN: Binary data format
+ * @arg RTC_FORMAT_BCD: BCD data format
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTC_GetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Alarm, uint32_t Format)
+{
+ uint32_t counter_alarm = 0U;
+
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(Alarm);
+
+ /* Check input parameters */
+ if((hrtc == NULL) || (sAlarm == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_RTC_FORMAT(Format));
+ assert_param(IS_RTC_ALARM(Alarm));
+
+ /* Read Alarm counter in RTC registers */
+ counter_alarm = RTC_ReadAlarmCounter(hrtc);
+
+ /* Fill the structure with the read parameters */
+ /* Set hours in a day range (between 0 to 24)*/
+ sAlarm->AlarmTime.Hours = (uint32_t)((counter_alarm / 3600U) % 24U);
+ sAlarm->AlarmTime.Minutes = (uint32_t)((counter_alarm % 3600U) / 60U);
+ sAlarm->AlarmTime.Seconds = (uint32_t)((counter_alarm % 3600U) % 60U);
+
+ if(Format != RTC_FORMAT_BIN)
+ {
+ sAlarm->AlarmTime.Hours = RTC_ByteToBcd2(sAlarm->AlarmTime.Hours);
+ sAlarm->AlarmTime.Minutes = RTC_ByteToBcd2(sAlarm->AlarmTime.Minutes);
+ sAlarm->AlarmTime.Seconds = RTC_ByteToBcd2(sAlarm->AlarmTime.Seconds);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Deactive the specified RTC Alarm
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @param Alarm: Specifies the Alarm.
+ * This parameter can be one of the following values:
+ * @arg RTC_ALARM_A: AlarmA
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef *hrtc, uint32_t Alarm)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(Alarm);
+
+ /* Check the parameters */
+ assert_param(IS_RTC_ALARM(Alarm));
+
+ /* Check input parameters */
+ if(hrtc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hrtc);
+
+ hrtc->State = HAL_RTC_STATE_BUSY;
+
+ /* In case of interrupt mode is used, the interrupt source must disabled */
+ __HAL_RTC_ALARM_DISABLE_IT(hrtc, RTC_IT_ALRA);
+
+ /* Set Initialization mode */
+ if(RTC_EnterInitMode(hrtc) != HAL_OK)
+ {
+ /* Set RTC state */
+ hrtc->State = HAL_RTC_STATE_ERROR;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* Clear flag alarm A */
+ __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
+
+ /* Set to default values ALRH & ALRL registers */
+ WRITE_REG(hrtc->Instance->ALRH, RTC_ALARM_RESETVALUE_REGISTER);
+ WRITE_REG(hrtc->Instance->ALRL, RTC_ALARM_RESETVALUE_REGISTER);
+
+ /* RTC Alarm Interrupt Configuration: Disable EXTI configuration */
+ __HAL_RTC_ALARM_EXTI_DISABLE_IT();
+
+ /* Wait for synchro */
+ if(RTC_ExitInitMode(hrtc) != HAL_OK)
+ {
+ hrtc->State = HAL_RTC_STATE_ERROR;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_ERROR;
+ }
+ }
+ hrtc->State = HAL_RTC_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles Alarm interrupt request.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @retval None
+ */
+void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef* hrtc)
+{
+ if(__HAL_RTC_ALARM_GET_IT_SOURCE(hrtc, RTC_IT_ALRA))
+ {
+ /* Get the status of the Interrupt */
+ if(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) != (uint32_t)RESET)
+ {
+ /* AlarmA callback */
+ HAL_RTC_AlarmAEventCallback(hrtc);
+
+ /* Clear the Alarm interrupt pending bit */
+ __HAL_RTC_ALARM_CLEAR_FLAG(hrtc,RTC_FLAG_ALRAF);
+ }
+ }
+
+ /* Clear the EXTI's line Flag for RTC Alarm */
+ __HAL_RTC_ALARM_EXTI_CLEAR_FLAG();
+
+ /* Change RTC state */
+ hrtc->State = HAL_RTC_STATE_READY;
+}
+
+/**
+ * @brief Alarm A callback.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @retval None
+ */
+__weak void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hrtc);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_RTC_AlarmAEventCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief This function handles AlarmA Polling request.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout)
+{
+ uint32_t tickstart = HAL_GetTick();
+
+ /* Check input parameters */
+ if(hrtc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) == RESET)
+ {
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
+ {
+ hrtc->State = HAL_RTC_STATE_TIMEOUT;
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* Clear the Alarm interrupt pending bit */
+ __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
+
+ /* Change RTC state */
+ hrtc->State = HAL_RTC_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Exported_Functions_Group4 Peripheral State functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral State functions #####
+ ===============================================================================
+ [..]
+ This subsection provides functions allowing to
+ (+) Get RTC state
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Returns the RTC state.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @retval HAL state
+ */
+HAL_RTCStateTypeDef HAL_RTC_GetState(RTC_HandleTypeDef* hrtc)
+{
+ return hrtc->State;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Exported_Functions_Group5 Peripheral Control functions
+ * @brief Peripheral Control functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..]
+ This subsection provides functions allowing to
+ (+) Wait for RTC Time and Date Synchronization
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Waits until the RTC registers (RTC_CNT, RTC_ALR and RTC_PRL)
+ * are synchronized with RTC APB clock.
+ * @note This function must be called before any read operation after an APB reset
+ * or an APB clock stop.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTC_WaitForSynchro(RTC_HandleTypeDef* hrtc)
+{
+ uint32_t tickstart = 0U;
+
+ /* Check input parameters */
+ if(hrtc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Clear RSF flag */
+ CLEAR_BIT(hrtc->Instance->CRL, RTC_FLAG_RSF);
+
+ tickstart = HAL_GetTick();
+
+ /* Wait the registers to be synchronised */
+ while((hrtc->Instance->CRL & RTC_FLAG_RSF) == (uint32_t)RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/** @addtogroup RTC_Private_Functions
+ * @{
+ */
+
+
+/**
+ * @brief Read the time counter available in RTC_CNT registers.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @retval Time counter
+ */
+static uint32_t RTC_ReadTimeCounter(RTC_HandleTypeDef* hrtc)
+{
+ uint16_t high1 = 0U, high2 = 0U, low = 0U;
+ uint32_t timecounter = 0U;
+
+ high1 = READ_REG(hrtc->Instance->CNTH & RTC_CNTH_RTC_CNT);
+ low = READ_REG(hrtc->Instance->CNTL & RTC_CNTL_RTC_CNT);
+ high2 = READ_REG(hrtc->Instance->CNTH & RTC_CNTH_RTC_CNT);
+
+ if (high1 != high2)
+ { /* In this case the counter roll over during reading of CNTL and CNTH registers,
+ read again CNTL register then return the counter value */
+ timecounter = (((uint32_t) high2 << 16U) | READ_REG(hrtc->Instance->CNTL & RTC_CNTL_RTC_CNT));
+ }
+ else
+ { /* No counter roll over during reading of CNTL and CNTH registers, counter
+ value is equal to first value of CNTL and CNTH */
+ timecounter = (((uint32_t) high1 << 16U) | low);
+ }
+
+ return timecounter;
+}
+
+/**
+ * @brief Write the time counter in RTC_CNT registers.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @param TimeCounter: Counter to write in RTC_CNT registers
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef RTC_WriteTimeCounter(RTC_HandleTypeDef* hrtc, uint32_t TimeCounter)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Set Initialization mode */
+ if(RTC_EnterInitMode(hrtc) != HAL_OK)
+ {
+ status = HAL_ERROR;
+ }
+ else
+ {
+ /* Set RTC COUNTER MSB word */
+ WRITE_REG(hrtc->Instance->CNTH, (TimeCounter >> 16U));
+ /* Set RTC COUNTER LSB word */
+ WRITE_REG(hrtc->Instance->CNTL, (TimeCounter & RTC_CNTL_RTC_CNT));
+
+ /* Wait for synchro */
+ if(RTC_ExitInitMode(hrtc) != HAL_OK)
+ {
+ status = HAL_ERROR;
+ }
+ }
+
+ return status;
+}
+
+/**
+ * @brief Read the time counter available in RTC_ALR registers.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @retval Time counter
+ */
+static uint32_t RTC_ReadAlarmCounter(RTC_HandleTypeDef* hrtc)
+{
+ uint16_t high1 = 0U, low = 0U;
+
+ high1 = READ_REG(hrtc->Instance->ALRH & RTC_CNTH_RTC_CNT);
+ low = READ_REG(hrtc->Instance->ALRL & RTC_CNTL_RTC_CNT);
+
+ return (((uint32_t) high1 << 16U) | low);
+}
+
+/**
+ * @brief Write the time counter in RTC_ALR registers.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @param AlarmCounter: Counter to write in RTC_ALR registers
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef RTC_WriteAlarmCounter(RTC_HandleTypeDef* hrtc, uint32_t AlarmCounter)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Set Initialization mode */
+ if(RTC_EnterInitMode(hrtc) != HAL_OK)
+ {
+ status = HAL_ERROR;
+ }
+ else
+ {
+ /* Set RTC COUNTER MSB word */
+ WRITE_REG(hrtc->Instance->ALRH, (AlarmCounter >> 16U));
+ /* Set RTC COUNTER LSB word */
+ WRITE_REG(hrtc->Instance->ALRL, (AlarmCounter & RTC_ALRL_RTC_ALR));
+
+ /* Wait for synchro */
+ if(RTC_ExitInitMode(hrtc) != HAL_OK)
+ {
+ status = HAL_ERROR;
+ }
+ }
+
+ return status;
+}
+
+/**
+ * @brief Enters the RTC Initialization mode.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef* hrtc)
+{
+ uint32_t tickstart = 0U;
+
+ tickstart = HAL_GetTick();
+ /* Wait till RTC is in INIT state and if Time out is reached exit */
+ while((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
+ {
+ if((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Disable the write protection for RTC registers */
+ __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
+
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Exit the RTC Initialization mode.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef RTC_ExitInitMode(RTC_HandleTypeDef* hrtc)
+{
+ uint32_t tickstart = 0U;
+
+ /* Disable the write protection for RTC registers */
+ __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
+
+ tickstart = HAL_GetTick();
+ /* Wait till RTC is in INIT state and if Time out is reached exit */
+ while((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
+ {
+ if((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Converts a 2 digit decimal to BCD format.
+ * @param Value: Byte to be converted
+ * @retval Converted byte
+ */
+static uint8_t RTC_ByteToBcd2(uint8_t Value)
+{
+ uint32_t bcdhigh = 0U;
+
+ while(Value >= 10U)
+ {
+ bcdhigh++;
+ Value -= 10U;
+ }
+
+ return ((uint8_t)(bcdhigh << 4U) | Value);
+}
+
+/**
+ * @brief Converts from 2 digit BCD to Binary.
+ * @param Value: BCD value to be converted
+ * @retval Converted word
+ */
+static uint8_t RTC_Bcd2ToByte(uint8_t Value)
+{
+ uint32_t tmp = 0U;
+ tmp = ((uint8_t)(Value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10U;
+ return (tmp + (Value & (uint8_t)0x0F));
+}
+
+/**
+ * @brief Updates date when time is 23:59:59.
+ * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @param DayElapsed: Number of days elapsed from last date update
+ * @retval None
+ */
+static void RTC_DateUpdate(RTC_HandleTypeDef* hrtc, uint32_t DayElapsed)
+{
+ uint32_t year = 0U, month = 0U, day = 0U;
+ uint32_t loop = 0U;
+
+ /* Get the current year*/
+ year = hrtc->DateToUpdate.Year;
+
+ /* Get the current month and day */
+ month = hrtc->DateToUpdate.Month;
+ day = hrtc->DateToUpdate.Date;
+
+ for (loop = 0U; loop < DayElapsed; loop++)
+ {
+ if((month == 1U) || (month == 3U) || (month == 5U) || (month == 7U) || \
+ (month == 8U) || (month == 10U) || (month == 12U))
+ {
+ if(day < 31U)
+ {
+ day++;
+ }
+ /* Date structure member: day = 31 */
+ else
+ {
+ if(month != 12U)
+ {
+ month++;
+ day = 1U;
+ }
+ /* Date structure member: day = 31 & month =12 */
+ else
+ {
+ month = 1U;
+ day = 1U;
+ year++;
+ }
+ }
+ }
+ else if((month == 4U) || (month == 6U) || (month == 9U) || (month == 11U))
+ {
+ if(day < 30U)
+ {
+ day++;
+ }
+ /* Date structure member: day = 30 */
+ else
+ {
+ month++;
+ day = 1U;
+ }
+ }
+ else if(month == 2U)
+ {
+ if(day < 28U)
+ {
+ day++;
+ }
+ else if(day == 28U)
+ {
+ /* Leap year */
+ if(RTC_IsLeapYear(year))
+ {
+ day++;
+ }
+ else
+ {
+ month++;
+ day = 1U;
+ }
+ }
+ else if(day == 29U)
+ {
+ month++;
+ day = 1U;
+ }
+ }
+ }
+
+ /* Update year */
+ hrtc->DateToUpdate.Year = year;
+
+ /* Update day and month */
+ hrtc->DateToUpdate.Month = month;
+ hrtc->DateToUpdate.Date = day;
+
+ /* Update day of the week */
+ hrtc->DateToUpdate.WeekDay = RTC_WeekDayNum(year, month, day);
+}
+
+/**
+ * @brief Check whether the passed year is Leap or not.
+ * @param nYear year to check
+ * @retval 1: leap year
+ * 0: not leap year
+ */
+static uint8_t RTC_IsLeapYear(uint16_t nYear)
+{
+ if((nYear % 4U) != 0U)
+ {
+ return 0U;
+ }
+
+ if((nYear % 100U) != 0U)
+ {
+ return 1U;
+ }
+
+ if((nYear % 400U) == 0U)
+ {
+ return 1U;
+ }
+ else
+ {
+ return 0U;
+ }
+}
+
+/**
+ * @brief Determines the week number, the day number and the week day number.
+ * @param nYear year to check
+ * @param nMonth Month to check
+ * @param nDay Day to check
+ * @note Day is calculated with hypothesis that year > 2000
+ * @retval Value which can take one of the following parameters:
+ * @arg RTC_WEEKDAY_MONDAY
+ * @arg RTC_WEEKDAY_TUESDAY
+ * @arg RTC_WEEKDAY_WEDNESDAY
+ * @arg RTC_WEEKDAY_THURSDAY
+ * @arg RTC_WEEKDAY_FRIDAY
+ * @arg RTC_WEEKDAY_SATURDAY
+ * @arg RTC_WEEKDAY_SUNDAY
+ */
+static uint8_t RTC_WeekDayNum(uint32_t nYear, uint8_t nMonth, uint8_t nDay)
+{
+ uint32_t year = 0U, weekday = 0U;
+
+ year = 2000U + nYear;
+
+ if(nMonth < 3U)
+ {
+ /*D = { [(23 x month)/9] + day + 4 + year + [(year-1)/4] - [(year-1)/100] + [(year-1)/400] } mod 7*/
+ weekday = (((23U * nMonth)/9U) + nDay + 4U + year + ((year-1U)/4U) - ((year-1U)/100U) + ((year-1U)/400U)) % 7U;
+ }
+ else
+ {
+ /*D = { [(23 x month)/9] + day + 4 + year + [year/4] - [year/100] + [year/400] - 2 } mod 7*/
+ weekday = (((23U * nMonth)/9U) + nDay + 4U + year + (year/4U) - (year/100U) + (year/400U) - 2U ) % 7U;
+ }
+
+ return (uint8_t)weekday;
+}
+
+/**
+ * @}
+ */
+
+#endif /* HAL_RTC_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc_ex.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc_ex.c
new file mode 100644
index 0000000..4f42b81
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc_ex.c
@@ -0,0 +1,591 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_rtc_ex.c
+ * @author MCD Application Team
+ * @brief Extended RTC HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Real Time Clock (RTC) Extension peripheral:
+ * + RTC Tamper functions
+ * + Extension Control functions
+ * + Extension RTC features functions
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_RTC_MODULE_ENABLED
+
+/** @defgroup RTCEx RTCEx
+ * @brief RTC Extended HAL module driver
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/** @defgroup RTCEx_Private_Macros RTCEx Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup RTCEx_Exported_Functions RTCEx Exported Functions
+ * @{
+ */
+
+/** @defgroup RTCEx_Exported_Functions_Group1 RTC Tamper functions
+ * @brief RTC Tamper functions
+ *
+@verbatim
+ ===============================================================================
+ ##### RTC Tamper functions #####
+ ===============================================================================
+
+ [..] This section provides functions allowing to configure Tamper feature
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sets Tamper
+ * @note By calling this API we disable the tamper interrupt for all tampers.
+ * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @param sTamper: Pointer to Tamper Structure.
+ * @note Tamper can be enabled only if ASOE and CCO bit are reset
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTCEx_SetTamper(RTC_HandleTypeDef *hrtc, RTC_TamperTypeDef* sTamper)
+{
+ /* Check input parameters */
+ if((hrtc == NULL) || (sTamper == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_RTC_TAMPER(sTamper->Tamper));
+ assert_param(IS_RTC_TAMPER_TRIGGER(sTamper->Trigger));
+
+ /* Process Locked */
+ __HAL_LOCK(hrtc);
+
+ hrtc->State = HAL_RTC_STATE_BUSY;
+
+ if (HAL_IS_BIT_SET(BKP->RTCCR,(BKP_RTCCR_CCO | BKP_RTCCR_ASOE)))
+ {
+ hrtc->State = HAL_RTC_STATE_ERROR;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_ERROR;
+ }
+
+ MODIFY_REG(BKP->CR, (BKP_CR_TPE | BKP_CR_TPAL), (sTamper->Tamper | (sTamper->Trigger)));
+
+ hrtc->State = HAL_RTC_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Sets Tamper with interrupt.
+ * @note By calling this API we force the tamper interrupt for all tampers.
+ * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @param sTamper: Pointer to RTC Tamper.
+ * @note Tamper can be enabled only if ASOE and CCO bit are reset
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTCEx_SetTamper_IT(RTC_HandleTypeDef *hrtc, RTC_TamperTypeDef* sTamper)
+{
+ /* Check input parameters */
+ if((hrtc == NULL) || (sTamper == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_RTC_TAMPER(sTamper->Tamper));
+ assert_param(IS_RTC_TAMPER_TRIGGER(sTamper->Trigger));
+
+ /* Process Locked */
+ __HAL_LOCK(hrtc);
+
+ hrtc->State = HAL_RTC_STATE_BUSY;
+
+ if (HAL_IS_BIT_SET(BKP->RTCCR,(BKP_RTCCR_CCO | BKP_RTCCR_ASOE)))
+ {
+ hrtc->State = HAL_RTC_STATE_ERROR;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_ERROR;
+ }
+
+ MODIFY_REG(BKP->CR, (BKP_CR_TPE | BKP_CR_TPAL), (sTamper->Tamper | (sTamper->Trigger)));
+
+ /* Configure the Tamper Interrupt in the BKP->CSR */
+ __HAL_RTC_TAMPER_ENABLE_IT(hrtc, RTC_IT_TAMP1);
+
+ hrtc->State = HAL_RTC_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Deactivates Tamper.
+ * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @param Tamper: Selected tamper pin.
+ * This parameter can be a value of @ref RTCEx_Tamper_Pins_Definitions
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTCEx_DeactivateTamper(RTC_HandleTypeDef *hrtc, uint32_t Tamper)
+{
+ /* Check input parameters */
+ if(hrtc == NULL)
+ {
+ return HAL_ERROR;
+ }
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(Tamper);
+
+ assert_param(IS_RTC_TAMPER(Tamper));
+
+ /* Process Locked */
+ __HAL_LOCK(hrtc);
+
+ hrtc->State = HAL_RTC_STATE_BUSY;
+
+ /* Disable the selected Tamper pin */
+ CLEAR_BIT(BKP->CR, BKP_CR_TPE);
+
+ /* Disable the Tamper Interrupt in the BKP->CSR */
+ /* Configure the Tamper Interrupt in the BKP->CSR */
+ __HAL_RTC_TAMPER_DISABLE_IT(hrtc, RTC_IT_TAMP1);
+
+ /* Clear the Tamper interrupt pending bit */
+ __HAL_RTC_TAMPER_CLEAR_FLAG(hrtc, RTC_FLAG_TAMP1F);
+ SET_BIT(BKP->CSR, BKP_CSR_CTE);
+
+ hrtc->State = HAL_RTC_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles Tamper interrupt request.
+ * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @retval None
+ */
+void HAL_RTCEx_TamperIRQHandler(RTC_HandleTypeDef *hrtc)
+{
+ /* Get the status of the Interrupt */
+ if(__HAL_RTC_TAMPER_GET_IT_SOURCE(hrtc, RTC_IT_TAMP1))
+ {
+ /* Get the TAMPER Interrupt enable bit and pending bit */
+ if(__HAL_RTC_TAMPER_GET_FLAG(hrtc, RTC_FLAG_TAMP1F) != (uint32_t)RESET)
+ {
+ /* Tamper callback */
+ HAL_RTCEx_Tamper1EventCallback(hrtc);
+
+ /* Clear the Tamper interrupt pending bit */
+ __HAL_RTC_TAMPER_CLEAR_FLAG(hrtc,RTC_FLAG_TAMP1F);
+ }
+ }
+
+ /* Change RTC state */
+ hrtc->State = HAL_RTC_STATE_READY;
+}
+
+/**
+ * @brief Tamper 1 callback.
+ * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @retval None
+ */
+__weak void HAL_RTCEx_Tamper1EventCallback(RTC_HandleTypeDef *hrtc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hrtc);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_RTCEx_Tamper1EventCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief This function handles Tamper1 Polling.
+ * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTCEx_PollForTamper1Event(RTC_HandleTypeDef *hrtc, uint32_t Timeout)
+{
+ uint32_t tickstart = HAL_GetTick();
+
+ /* Check input parameters */
+ if(hrtc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Get the status of the Interrupt */
+ while(__HAL_RTC_TAMPER_GET_FLAG(hrtc,RTC_FLAG_TAMP1F)== RESET)
+ {
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
+ {
+ hrtc->State = HAL_RTC_STATE_TIMEOUT;
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* Clear the Tamper Flag */
+ __HAL_RTC_TAMPER_CLEAR_FLAG(hrtc,RTC_FLAG_TAMP1F);
+
+ /* Change RTC state */
+ hrtc->State = HAL_RTC_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTCEx_Exported_Functions_Group2 RTC Second functions
+ * @brief RTC Second functions
+ *
+@verbatim
+ ===============================================================================
+ ##### RTC Second functions #####
+ ===============================================================================
+
+ [..] This section provides functions implementing second interupt handlers
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sets Interrupt for second
+ * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTCEx_SetSecond_IT(RTC_HandleTypeDef *hrtc)
+{
+ /* Check input parameters */
+ if(hrtc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hrtc);
+
+ hrtc->State = HAL_RTC_STATE_BUSY;
+
+ /* Enable Second interuption */
+ __HAL_RTC_SECOND_ENABLE_IT(hrtc, RTC_IT_SEC);
+
+ hrtc->State = HAL_RTC_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Deactivates Second.
+ * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTCEx_DeactivateSecond(RTC_HandleTypeDef *hrtc)
+{
+ /* Check input parameters */
+ if(hrtc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hrtc);
+
+ hrtc->State = HAL_RTC_STATE_BUSY;
+
+ /* Deactivate Second interuption*/
+ __HAL_RTC_SECOND_DISABLE_IT(hrtc, RTC_IT_SEC);
+
+ hrtc->State = HAL_RTC_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles second interrupt request.
+ * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @retval None
+ */
+void HAL_RTCEx_RTCIRQHandler(RTC_HandleTypeDef* hrtc)
+{
+ if(__HAL_RTC_SECOND_GET_IT_SOURCE(hrtc, RTC_IT_SEC))
+ {
+ /* Get the status of the Interrupt */
+ if(__HAL_RTC_SECOND_GET_FLAG(hrtc, RTC_FLAG_SEC))
+ {
+ /* Check if Overrun occurred */
+ if (__HAL_RTC_SECOND_GET_FLAG(hrtc, RTC_FLAG_OW))
+ {
+ /* Second error callback */
+ HAL_RTCEx_RTCEventErrorCallback(hrtc);
+
+ /* Clear flag Second */
+ __HAL_RTC_OVERFLOW_CLEAR_FLAG(hrtc, RTC_FLAG_OW);
+
+ /* Change RTC state */
+ hrtc->State = HAL_RTC_STATE_ERROR;
+ }
+ else
+ {
+ /* Second callback */
+ HAL_RTCEx_RTCEventCallback(hrtc);
+
+ /* Change RTC state */
+ hrtc->State = HAL_RTC_STATE_READY;
+ }
+
+ /* Clear flag Second */
+ __HAL_RTC_SECOND_CLEAR_FLAG(hrtc, RTC_FLAG_SEC);
+ }
+ }
+}
+
+/**
+ * @brief Second event callback.
+ * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @retval None
+ */
+__weak void HAL_RTCEx_RTCEventCallback(RTC_HandleTypeDef *hrtc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hrtc);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_RTCEx_RTCEventCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Second event error callback.
+ * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @retval None
+ */
+__weak void HAL_RTCEx_RTCEventErrorCallback(RTC_HandleTypeDef *hrtc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hrtc);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_RTCEx_RTCEventErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTCEx_Exported_Functions_Group3 Extended Peripheral Control functions
+ * @brief Extended Peripheral Control functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Extension Peripheral Control functions #####
+ ===============================================================================
+ [..]
+ This subsection provides functions allowing to
+ (+) Writes a data in a specified RTC Backup data register
+ (+) Read a data in a specified RTC Backup data register
+ (+) Sets the Smooth calibration parameters.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Writes a data in a specified RTC Backup data register.
+ * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @param BackupRegister: RTC Backup data Register number.
+ * This parameter can be: RTC_BKP_DRx where x can be from 1 to 10 (or 42) to
+ * specify the register (depending devices).
+ * @param Data: Data to be written in the specified RTC Backup data register.
+ * @retval None
+ */
+void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data)
+{
+ uint32_t tmp = 0U;
+
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hrtc);
+
+ /* Check the parameters */
+ assert_param(IS_RTC_BKP(BackupRegister));
+
+ tmp = (uint32_t)BKP_BASE;
+ tmp += (BackupRegister * 4U);
+
+ *(__IO uint32_t *) tmp = (Data & BKP_DR1_D);
+}
+
+/**
+ * @brief Reads data from the specified RTC Backup data Register.
+ * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
+ * the configuration information for RTC.
+ * @param BackupRegister: RTC Backup data Register number.
+ * This parameter can be: RTC_BKP_DRx where x can be from 1 to 10 (or 42) to
+ * specify the register (depending devices).
+ * @retval Read value
+ */
+uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister)
+{
+ uint32_t backupregister = 0U;
+ uint32_t pvalue = 0U;
+
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hrtc);
+
+ /* Check the parameters */
+ assert_param(IS_RTC_BKP(BackupRegister));
+
+ backupregister = (uint32_t)BKP_BASE;
+ backupregister += (BackupRegister * 4U);
+
+ pvalue = (*(__IO uint32_t *)(backupregister)) & BKP_DR1_D;
+
+ /* Read the specified register */
+ return pvalue;
+}
+
+
+/**
+ * @brief Sets the Smooth calibration parameters.
+ * @param hrtc: RTC handle
+ * @param SmoothCalibPeriod: Not used (only present for compatibility with another families)
+ * @param SmoothCalibPlusPulses: Not used (only present for compatibility with another families)
+ * @param SmouthCalibMinusPulsesValue: specifies the RTC Clock Calibration value.
+ * This parameter must be a number between 0 and 0x7F.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RTCEx_SetSmoothCalib(RTC_HandleTypeDef* hrtc, uint32_t SmoothCalibPeriod, uint32_t SmoothCalibPlusPulses, uint32_t SmouthCalibMinusPulsesValue)
+{
+ /* Check input parameters */
+ if(hrtc == NULL)
+ {
+ return HAL_ERROR;
+ }
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(SmoothCalibPeriod);
+ UNUSED(SmoothCalibPlusPulses);
+
+ /* Check the parameters */
+ assert_param(IS_RTC_SMOOTH_CALIB_MINUS(SmouthCalibMinusPulsesValue));
+
+ /* Process Locked */
+ __HAL_LOCK(hrtc);
+
+ hrtc->State = HAL_RTC_STATE_BUSY;
+
+ /* Sets RTC Clock Calibration value.*/
+ MODIFY_REG(BKP->RTCCR, BKP_RTCCR_CAL, SmouthCalibMinusPulsesValue);
+
+ /* Change RTC state */
+ hrtc->State = HAL_RTC_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrtc);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_RTC_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sd.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sd.c
new file mode 100644
index 0000000..fd28df5
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sd.c
@@ -0,0 +1,2922 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_sd.c
+ * @author MCD Application Team
+ * @brief SD card HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Secure Digital (SD) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ * + SD card Control functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ This driver implements a high level communication layer for read and write from/to
+ this memory. The needed STM32 hardware resources (SDIO and GPIO) are performed by
+ the user in HAL_SD_MspInit() function (MSP layer).
+ Basically, the MSP layer configuration should be the same as we provide in the
+ examples.
+ You can easily tailor this configuration according to hardware resources.
+
+ [..]
+ This driver is a generic layered driver for SDIO memories which uses the HAL
+ SDIO driver functions to interface with SD and uSD cards devices.
+ It is used as follows:
+
+ (#)Initialize the SDIO low level resources by implement the HAL_SD_MspInit() API:
+ (##) Enable the SDIO interface clock using __HAL_RCC_SDIO_CLK_ENABLE();
+ (##) SDIO pins configuration for SD card
+ (+++) Enable the clock for the SDIO GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
+ (+++) Configure these SDIO pins as alternate function pull-up using HAL_GPIO_Init()
+ and according to your pin assignment;
+ (##) DMA Configuration if you need to use DMA process (HAL_SD_ReadBlocks_DMA()
+ and HAL_SD_WriteBlocks_DMA() APIs).
+ (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE();
+ (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled.
+ (##) NVIC configuration if you need to use interrupt process when using DMA transfer.
+ (+++) Configure the SDIO and DMA interrupt priorities using functions
+ HAL_NVIC_SetPriority(); DMA priority is superior to SDIO's priority
+ (+++) Enable the NVIC DMA and SDIO IRQs using function HAL_NVIC_EnableIRQ()
+ (+++) SDIO interrupts are managed using the macros __HAL_SD_ENABLE_IT()
+ and __HAL_SD_DISABLE_IT() inside the communication process.
+ (+++) SDIO interrupts pending bits are managed using the macros __HAL_SD_GET_IT()
+ and __HAL_SD_CLEAR_IT()
+ (##) NVIC configuration if you need to use interrupt process (HAL_SD_ReadBlocks_IT()
+ and HAL_SD_WriteBlocks_IT() APIs).
+ (+++) Configure the SDIO interrupt priorities using function
+ HAL_NVIC_SetPriority();
+ (+++) Enable the NVIC SDIO IRQs using function HAL_NVIC_EnableIRQ()
+ (+++) SDIO interrupts are managed using the macros __HAL_SD_ENABLE_IT()
+ and __HAL_SD_DISABLE_IT() inside the communication process.
+ (+++) SDIO interrupts pending bits are managed using the macros __HAL_SD_GET_IT()
+ and __HAL_SD_CLEAR_IT()
+ (#) At this stage, you can perform SD read/write/erase operations after SD card initialization
+
+
+ *** SD Card Initialization and configuration ***
+ ================================================
+ [..]
+ To initialize the SD Card, use the HAL_SD_Init() function. It Initializes
+ SDIO IP(STM32 side) and the SD Card, and put it into StandBy State (Ready for data transfer).
+ This function provide the following operations:
+
+ (#) Initialize the SDIO peripheral interface with defaullt configuration.
+ The initialization process is done at 400KHz. You can change or adapt
+ this frequency by adjusting the "ClockDiv" field.
+ The SD Card frequency (SDIO_CK) is computed as follows:
+
+ SDIO_CK = SDIOCLK / (ClockDiv + 2)
+
+ In initialization mode and according to the SD Card standard,
+ make sure that the SDIO_CK frequency doesn't exceed 400KHz.
+
+ This phase of initialization is done through SDIO_Init() and
+ SDIO_PowerState_ON() SDIO low level APIs.
+
+ (#) Initialize the SD card. The API used is HAL_SD_InitCard().
+ This phase allows the card initialization and identification
+ and check the SD Card type (Standard Capacity or High Capacity)
+ The initialization flow is compatible with SD standard.
+
+ This API (HAL_SD_InitCard()) could be used also to reinitialize the card in case
+ of plug-off plug-in.
+
+ (#) Configure the SD Card Data transfer frequency. By Default, the card transfer
+ frequency is set to 24MHz. You can change or adapt this frequency by adjusting
+ the "ClockDiv" field.
+ In transfer mode and according to the SD Card standard, make sure that the
+ SDIO_CK frequency doesn't exceed 25MHz and 50MHz in High-speed mode switch.
+ To be able to use a frequency higher than 24MHz, you should use the SDIO
+ peripheral in bypass mode. Refer to the corresponding reference manual
+ for more details.
+
+ (#) Select the corresponding SD Card according to the address read with the step 2.
+
+ (#) Configure the SD Card in wide bus mode: 4-bits data.
+
+ *** SD Card Read operation ***
+ ==============================
+ [..]
+ (+) You can read from SD card in polling mode by using function HAL_SD_ReadBlocks().
+ This function allows the read of 512 bytes blocks.
+ You can choose either one block read operation or multiple block read operation
+ by adjusting the "NumberOfBlocks" parameter.
+ After this, you have to ensure that the transfer is done correctly. The check is done
+ through HAL_SD_GetCardState() function for SD card state.
+
+ (+) You can read from SD card in DMA mode by using function HAL_SD_ReadBlocks_DMA().
+ This function allows the read of 512 bytes blocks.
+ You can choose either one block read operation or multiple block read operation
+ by adjusting the "NumberOfBlocks" parameter.
+ After this, you have to ensure that the transfer is done correctly. The check is done
+ through HAL_SD_GetCardState() function for SD card state.
+ You could also check the DMA transfer process through the SD Rx interrupt event.
+
+ (+) You can read from SD card in Interrupt mode by using function HAL_SD_ReadBlocks_IT().
+ This function allows the read of 512 bytes blocks.
+ You can choose either one block read operation or multiple block read operation
+ by adjusting the "NumberOfBlocks" parameter.
+ After this, you have to ensure that the transfer is done correctly. The check is done
+ through HAL_SD_GetCardState() function for SD card state.
+ You could also check the IT transfer process through the SD Rx interrupt event.
+
+ *** SD Card Write operation ***
+ ===============================
+ [..]
+ (+) You can write to SD card in polling mode by using function HAL_SD_WriteBlocks().
+ This function allows the read of 512 bytes blocks.
+ You can choose either one block read operation or multiple block read operation
+ by adjusting the "NumberOfBlocks" parameter.
+ After this, you have to ensure that the transfer is done correctly. The check is done
+ through HAL_SD_GetCardState() function for SD card state.
+
+ (+) You can write to SD card in DMA mode by using function HAL_SD_WriteBlocks_DMA().
+ This function allows the read of 512 bytes blocks.
+ You can choose either one block read operation or multiple block read operation
+ by adjusting the "NumberOfBlocks" parameter.
+ After this, you have to ensure that the transfer is done correctly. The check is done
+ through HAL_SD_GetCardState() function for SD card state.
+ You could also check the DMA transfer process through the SD Tx interrupt event.
+
+ (+) You can write to SD card in Interrupt mode by using function HAL_SD_WriteBlocks_IT().
+ This function allows the read of 512 bytes blocks.
+ You can choose either one block read operation or multiple block read operation
+ by adjusting the "NumberOfBlocks" parameter.
+ After this, you have to ensure that the transfer is done correctly. The check is done
+ through HAL_SD_GetCardState() function for SD card state.
+ You could also check the IT transfer process through the SD Tx interrupt event.
+
+ *** SD card status ***
+ ======================
+ [..]
+ (+) The SD Status contains status bits that are related to the SD Memory
+ Card proprietary features. To get SD card status use the HAL_SD_GetCardStatus().
+
+ *** SD card information ***
+ ===========================
+ [..]
+ (+) To get SD card information, you can use the function HAL_SD_GetCardInfo().
+ It returns useful information about the SD card such as block size, card type,
+ block number ...
+
+ *** SD card CSD register ***
+ ============================
+ [..]
+ (+) The HAL_SD_GetCardCSD() API allows to get the parameters of the CSD register.
+ Some of the CSD parameters are useful for card initialization and identification.
+
+ *** SD card CID register ***
+ ============================
+ [..]
+ (+) The HAL_SD_GetCardCID() API allows to get the parameters of the CID register.
+ Some of the CSD parameters are useful for card initialization and identification.
+
+ *** SD HAL driver macros list ***
+ ==================================
+ [..]
+ Below the list of most used macros in SD HAL driver.
+
+ (+) __HAL_SD_ENABLE : Enable the SD device
+ (+) __HAL_SD_DISABLE : Disable the SD device
+ (+) __HAL_SD_DMA_ENABLE: Enable the SDIO DMA transfer
+ (+) __HAL_SD_DMA_DISABLE: Disable the SDIO DMA transfer
+ (+) __HAL_SD_ENABLE_IT: Enable the SD device interrupt
+ (+) __HAL_SD_DISABLE_IT: Disable the SD device interrupt
+ (+) __HAL_SD_GET_FLAG:Check whether the specified SD flag is set or not
+ (+) __HAL_SD_CLEAR_FLAG: Clear the SD's pending flags
+
+ [..]
+ (@) You can refer to the SD HAL driver header file for more useful macros
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+#if defined(STM32F103xE) || defined(STM32F103xG)
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup SD
+ * @{
+ */
+#ifdef HAL_SD_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @addtogroup SD_Private_Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup SD_Private_Functions SD Private Functions
+ * @{
+ */
+static uint32_t SD_InitCard(SD_HandleTypeDef *hsd);
+static uint32_t SD_PowerON(SD_HandleTypeDef *hsd);
+static uint32_t SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus);
+static uint32_t SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus);
+static uint32_t SD_WideBus_Enable(SD_HandleTypeDef *hsd);
+static uint32_t SD_WideBus_Disable(SD_HandleTypeDef *hsd);
+static uint32_t SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR);
+static HAL_StatusTypeDef SD_PowerOFF(SD_HandleTypeDef *hsd);
+static HAL_StatusTypeDef SD_Write_IT(SD_HandleTypeDef *hsd);
+static HAL_StatusTypeDef SD_Read_IT(SD_HandleTypeDef *hsd);
+static void SD_DMATransmitCplt(DMA_HandleTypeDef *hdma);
+static void SD_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
+static void SD_DMAError(DMA_HandleTypeDef *hdma);
+static void SD_DMATxAbort(DMA_HandleTypeDef *hdma);
+static void SD_DMARxAbort(DMA_HandleTypeDef *hdma);
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup SD_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup SD_Exported_Functions_Group1
+ * @brief Initialization and de-initialization functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de-initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to initialize/de-initialize the SD
+ card device to be ready for use.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the SD according to the specified parameters in the
+ SD_HandleTypeDef and create the associated handle.
+ * @param hsd: Pointer to the SD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SD_Init(SD_HandleTypeDef *hsd)
+{
+ /* Check the SD handle allocation */
+ if(hsd == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_SDIO_ALL_INSTANCE(hsd->Instance));
+ assert_param(IS_SDIO_CLOCK_EDGE(hsd->Init.ClockEdge));
+ assert_param(IS_SDIO_CLOCK_BYPASS(hsd->Init.ClockBypass));
+ assert_param(IS_SDIO_CLOCK_POWER_SAVE(hsd->Init.ClockPowerSave));
+ assert_param(IS_SDIO_BUS_WIDE(hsd->Init.BusWide));
+ assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(hsd->Init.HardwareFlowControl));
+ assert_param(IS_SDIO_CLKDIV(hsd->Init.ClockDiv));
+
+ if(hsd->State == HAL_SD_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hsd->Lock = HAL_UNLOCKED;
+ /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
+ HAL_SD_MspInit(hsd);
+ }
+
+ hsd->State = HAL_SD_STATE_BUSY;
+
+ /* Initialize the Card parameters */
+ HAL_SD_InitCard(hsd);
+
+ /* Initialize the error code */
+ hsd->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ /* Initialize the SD operation */
+ hsd->Context = SD_CONTEXT_NONE;
+
+ /* Initialize the SD state */
+ hsd->State = HAL_SD_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the SD Card.
+ * @param hsd: Pointer to SD handle
+ * @note This function initializes the SD card. It could be used when a card
+ re-initialization is needed.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SD_InitCard(SD_HandleTypeDef *hsd)
+{
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+ SD_InitTypeDef Init;
+
+ /* Default SDIO peripheral configuration for SD card initialization */
+ Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
+ Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
+ Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
+ Init.BusWide = SDIO_BUS_WIDE_1B;
+ Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
+ Init.ClockDiv = SDIO_INIT_CLK_DIV;
+
+ /* Initialize SDIO peripheral interface with default configuration */
+ SDIO_Init(hsd->Instance, Init);
+
+ /* Disable SDIO Clock */
+ __HAL_SD_DISABLE(hsd);
+
+ /* Set Power State to ON */
+ SDIO_PowerState_ON(hsd->Instance);
+
+ /* Enable SDIO Clock */
+ __HAL_SD_ENABLE(hsd);
+
+ /* Required power up waiting time before starting the SD initialization
+ sequence */
+ HAL_Delay(2U);
+
+ /* Identify card operating voltage */
+ errorstate = SD_PowerON(hsd);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ hsd->State = HAL_SD_STATE_READY;
+ hsd->ErrorCode |= errorstate;
+ return HAL_ERROR;
+ }
+
+ /* Card initialization */
+ errorstate = SD_InitCard(hsd);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ hsd->State = HAL_SD_STATE_READY;
+ hsd->ErrorCode |= errorstate;
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief De-Initializes the SD card.
+ * @param hsd: Pointer to SD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SD_DeInit(SD_HandleTypeDef *hsd)
+{
+ /* Check the SD handle allocation */
+ if(hsd == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_SDIO_ALL_INSTANCE(hsd->Instance));
+
+ hsd->State = HAL_SD_STATE_BUSY;
+
+ /* Set SD power state to off */
+ SD_PowerOFF(hsd);
+
+ /* De-Initialize the MSP layer */
+ HAL_SD_MspDeInit(hsd);
+
+ hsd->ErrorCode = HAL_SD_ERROR_NONE;
+ hsd->State = HAL_SD_STATE_RESET;
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Initializes the SD MSP.
+ * @param hsd: Pointer to SD handle
+ * @retval None
+ */
+__weak void HAL_SD_MspInit(SD_HandleTypeDef *hsd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsd);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SD_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief De-Initialize SD MSP.
+ * @param hsd: Pointer to SD handle
+ * @retval None
+ */
+__weak void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsd);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SD_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @addtogroup SD_Exported_Functions_Group2
+ * @brief Data transfer functions
+ *
+@verbatim
+ ==============================================================================
+ ##### IO operation functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the data
+ transfer from/to SD card.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Reads block(s) from a specified address in a card. The Data transfer
+ * is managed by polling mode.
+ * @note This API should be followed by a check on the card state through
+ * HAL_SD_GetCardState().
+ * @param hsd: Pointer to SD handle
+ * @param pData: pointer to the buffer that will contain the received data
+ * @param BlockAdd: Block Address from where data is to be read
+ * @param NumberOfBlocks: Number of SD blocks to read
+ * @param Timeout: Specify timeout value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
+{
+ SDIO_DataInitTypeDef config;
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t count = 0U, *tempbuff = (uint32_t *)pData;
+
+ if(NULL == pData)
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
+ return HAL_ERROR;
+ }
+
+ if(hsd->State == HAL_SD_STATE_READY)
+ {
+ hsd->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ if((BlockAdd + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
+ return HAL_ERROR;
+ }
+
+ hsd->State = HAL_SD_STATE_BUSY;
+
+ /* Initialize data control register */
+ hsd->Instance->DCTRL = 0U;
+
+ if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
+ {
+ BlockAdd *= 512U;
+ }
+
+ /* Set Block Size for Card */
+ errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Configure the SD DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = NumberOfBlocks * BLOCKSIZE;
+ config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
+ config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_ConfigData(hsd->Instance, &config);
+
+ /* Read block(s) in polling mode */
+ if(NumberOfBlocks > 1U)
+ {
+ hsd->Context = SD_CONTEXT_READ_MULTIPLE_BLOCK;
+
+ /* Read Multi Block command */
+ errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, BlockAdd);
+ }
+ else
+ {
+ hsd->Context = SD_CONTEXT_READ_SINGLE_BLOCK;
+
+ /* Read Single Block command */
+ errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, BlockAdd);
+ }
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Poll on SDIO flags */
+ while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_STA_STBITERR))
+ {
+ if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF))
+ {
+ /* Read data from SDIO Rx FIFO */
+ for(count = 0U; count < 8U; count++)
+ {
+ *(tempbuff + count) = SDIO_ReadFIFO(hsd->Instance);
+ }
+ tempbuff += 8U;
+ }
+
+ if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= HAL_SD_ERROR_TIMEOUT;
+ hsd->State= HAL_SD_STATE_READY;
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Send stop transmission command in case of multiblock read */
+ if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
+ {
+ if(hsd->SdCard.CardType != CARD_SECURED)
+ {
+ /* Send stop transmission command */
+ errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+ }
+ }
+
+ /* Get error state */
+ if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+ else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+ else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= HAL_SD_ERROR_RX_OVERRUN;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Empty FIFO if there is still any data */
+ while ((__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXDAVL)))
+ {
+ *tempbuff = SDIO_ReadFIFO(hsd->Instance);
+ tempbuff++;
+
+ if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= HAL_SD_ERROR_TIMEOUT;
+ hsd->State= HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+ }
+
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ hsd->State = HAL_SD_STATE_READY;
+
+ return HAL_OK;
+ }
+ else
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_BUSY;
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Allows to write block(s) to a specified address in a card. The Data
+ * transfer is managed by polling mode.
+ * @note This API should be followed by a check on the card state through
+ * HAL_SD_GetCardState().
+ * @param hsd: Pointer to SD handle
+ * @param pData: pointer to the buffer that will contain the data to transmit
+ * @param BlockAdd: Block Address where data will be written
+ * @param NumberOfBlocks: Number of SD blocks to write
+ * @param Timeout: Specify timeout value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
+{
+ SDIO_DataInitTypeDef config;
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t count = 0U;
+ uint32_t *tempbuff = (uint32_t *)pData;
+
+ if(NULL == pData)
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
+ return HAL_ERROR;
+ }
+
+ if(hsd->State == HAL_SD_STATE_READY)
+ {
+ hsd->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ if((BlockAdd + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
+ return HAL_ERROR;
+ }
+
+ hsd->State = HAL_SD_STATE_BUSY;
+
+ /* Initialize data control register */
+ hsd->Instance->DCTRL = 0U;
+
+ if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
+ {
+ BlockAdd *= 512U;
+ }
+
+ /* Set Block Size for Card */
+ errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Write Blocks in Polling mode */
+ if(NumberOfBlocks > 1U)
+ {
+ hsd->Context = SD_CONTEXT_WRITE_MULTIPLE_BLOCK;
+
+ /* Write Multi Block command */
+ errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, BlockAdd);
+ }
+ else
+ {
+ hsd->Context = SD_CONTEXT_WRITE_SINGLE_BLOCK;
+
+ /* Write Single Block command */
+ errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, BlockAdd);
+ }
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Configure the SD DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = NumberOfBlocks * BLOCKSIZE;
+ config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
+ config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_ConfigData(hsd->Instance, &config);
+
+ /* Write block(s) in polling mode */
+ while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
+ {
+ if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXFIFOHE))
+ {
+ /* Write data to SDIO Tx FIFO */
+ for(count = 0U; count < 8U; count++)
+ {
+ SDIO_WriteFIFO(hsd->Instance, (tempbuff + count));
+ }
+ tempbuff += 8U;
+ }
+
+ if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Send stop transmission command in case of multiblock write */
+ if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
+ {
+ if(hsd->SdCard.CardType != CARD_SECURED)
+ {
+ /* Send stop transmission command */
+ errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+ }
+ }
+
+ /* Get error state */
+ if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+ else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+ else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR))
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= HAL_SD_ERROR_TX_UNDERRUN;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ hsd->State = HAL_SD_STATE_READY;
+
+ return HAL_OK;
+ }
+ else
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_BUSY;
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Reads block(s) from a specified address in a card. The Data transfer
+ * is managed in interrupt mode.
+ * @note This API should be followed by a check on the card state through
+ * HAL_SD_GetCardState().
+ * @note You could also check the IT transfer process through the SD Rx
+ * interrupt event.
+ * @param hsd: Pointer to SD handle
+ * @param pData: Pointer to the buffer that will contain the received data
+ * @param BlockAdd: Block Address from where data is to be read
+ * @param NumberOfBlocks: Number of blocks to read.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SD_ReadBlocks_IT(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
+{
+ SDIO_DataInitTypeDef config;
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+
+ if(NULL == pData)
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
+ return HAL_ERROR;
+ }
+
+ if(hsd->State == HAL_SD_STATE_READY)
+ {
+ hsd->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ if((BlockAdd + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
+ return HAL_ERROR;
+ }
+
+ hsd->State = HAL_SD_STATE_BUSY;
+
+ /* Initialize data control register */
+ hsd->Instance->DCTRL = 0U;
+
+ hsd->pRxBuffPtr = (uint32_t *)pData;
+ hsd->RxXferSize = BLOCKSIZE * NumberOfBlocks;
+
+ __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF | SDIO_IT_STBITERR));
+
+ if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
+ {
+ BlockAdd *= 512U;
+ }
+
+ /* Configure the SD DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = BLOCKSIZE * NumberOfBlocks;
+ config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
+ config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_ConfigData(hsd->Instance, &config);
+
+ /* Set Block Size for Card */
+ errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Read Blocks in IT mode */
+ if(NumberOfBlocks > 1U)
+ {
+ hsd->Context = (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_IT);
+
+ /* Read Multi Block command */
+ errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, BlockAdd);
+ }
+ else
+ {
+ hsd->Context = (SD_CONTEXT_READ_SINGLE_BLOCK | SD_CONTEXT_IT);
+
+ /* Read Single Block command */
+ errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, BlockAdd);
+ }
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Writes block(s) to a specified address in a card. The Data transfer
+ * is managed in interrupt mode.
+ * @note This API should be followed by a check on the card state through
+ * HAL_SD_GetCardState().
+ * @note You could also check the IT transfer process through the SD Tx
+ * interrupt event.
+ * @param hsd: Pointer to SD handle
+ * @param pData: Pointer to the buffer that will contain the data to transmit
+ * @param BlockAdd: Block Address where data will be written
+ * @param NumberOfBlocks: Number of blocks to write
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SD_WriteBlocks_IT(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
+{
+ SDIO_DataInitTypeDef config;
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+
+ if(NULL == pData)
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
+ return HAL_ERROR;
+ }
+
+ if(hsd->State == HAL_SD_STATE_READY)
+ {
+ hsd->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ if((BlockAdd + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
+ return HAL_ERROR;
+ }
+
+ hsd->State = HAL_SD_STATE_BUSY;
+
+ /* Initialize data control register */
+ hsd->Instance->DCTRL = 0U;
+
+ hsd->pTxBuffPtr = (uint32_t *)pData;
+ hsd->TxXferSize = BLOCKSIZE * NumberOfBlocks;
+
+ /* Enable transfer interrupts */
+ __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE | SDIO_IT_STBITERR));
+
+ if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
+ {
+ BlockAdd *= 512U;
+ }
+
+ /* Set Block Size for Card */
+ errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Write Blocks in Polling mode */
+ if(NumberOfBlocks > 1U)
+ {
+ hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK| SD_CONTEXT_IT);
+
+ /* Write Multi Block command */
+ errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, BlockAdd);
+ }
+ else
+ {
+ hsd->Context = (SD_CONTEXT_WRITE_SINGLE_BLOCK | SD_CONTEXT_IT);
+
+ /* Write Single Block command */
+ errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, BlockAdd);
+ }
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Configure the SD DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = BLOCKSIZE * NumberOfBlocks;
+ config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
+ config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_ConfigData(hsd->Instance, &config);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Reads block(s) from a specified address in a card. The Data transfer
+ * is managed by DMA mode.
+ * @note This API should be followed by a check on the card state through
+ * HAL_SD_GetCardState().
+ * @note You could also check the DMA transfer process through the SD Rx
+ * interrupt event.
+ * @param hsd: Pointer SD handle
+ * @param pData: Pointer to the buffer that will contain the received data
+ * @param BlockAdd: Block Address from where data is to be read
+ * @param NumberOfBlocks: Number of blocks to read.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
+{
+ SDIO_DataInitTypeDef config;
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+
+ if(NULL == pData)
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
+ return HAL_ERROR;
+ }
+
+ if(hsd->State == HAL_SD_STATE_READY)
+ {
+ hsd->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ if((BlockAdd + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
+ return HAL_ERROR;
+ }
+
+ hsd->State = HAL_SD_STATE_BUSY;
+
+ /* Initialize data control register */
+ hsd->Instance->DCTRL = 0U;
+
+ __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_IT_STBITERR));
+
+ /* Set the DMA transfer complete callback */
+ hsd->hdmarx->XferCpltCallback = SD_DMAReceiveCplt;
+
+ /* Set the DMA error callback */
+ hsd->hdmarx->XferErrorCallback = SD_DMAError;
+
+ /* Set the DMA Abort callback */
+ hsd->hdmarx->XferAbortCallback = NULL;
+
+ /* Enable the DMA Channel */
+ HAL_DMA_Start_IT(hsd->hdmarx, (uint32_t)&hsd->Instance->FIFO, (uint32_t)pData, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4);
+
+ /* Enable SD DMA transfer */
+ __HAL_SD_DMA_ENABLE(hsd);
+
+ if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
+ {
+ BlockAdd *= 512U;
+ }
+
+ /* Configure the SD DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = BLOCKSIZE * NumberOfBlocks;
+ config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
+ config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_ConfigData(hsd->Instance, &config);
+
+ /* Set Block Size for Card */
+ errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Read Blocks in DMA mode */
+ if(NumberOfBlocks > 1U)
+ {
+ hsd->Context = (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_DMA);
+
+ /* Read Multi Block command */
+ errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, BlockAdd);
+ }
+ else
+ {
+ hsd->Context = (SD_CONTEXT_READ_SINGLE_BLOCK | SD_CONTEXT_DMA);
+
+ /* Read Single Block command */
+ errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, BlockAdd);
+ }
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Writes block(s) to a specified address in a card. The Data transfer
+ * is managed by DMA mode.
+ * @note This API should be followed by a check on the card state through
+ * HAL_SD_GetCardState().
+ * @note You could also check the DMA transfer process through the SD Tx
+ * interrupt event.
+ * @param hsd: Pointer to SD handle
+ * @param pData: Pointer to the buffer that will contain the data to transmit
+ * @param BlockAdd: Block Address where data will be written
+ * @param NumberOfBlocks: Number of blocks to write
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
+{
+ SDIO_DataInitTypeDef config;
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+
+ if(NULL == pData)
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
+ return HAL_ERROR;
+ }
+
+ if(hsd->State == HAL_SD_STATE_READY)
+ {
+ hsd->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ if((BlockAdd + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
+ return HAL_ERROR;
+ }
+
+ hsd->State = HAL_SD_STATE_BUSY;
+
+ /* Initialize data control register */
+ hsd->Instance->DCTRL = 0U;
+
+ /* Enable SD Error interrupts */
+ __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR));
+
+ /* Set the DMA transfer complete callback */
+ hsd->hdmatx->XferCpltCallback = SD_DMATransmitCplt;
+
+ /* Set the DMA error callback */
+ hsd->hdmatx->XferErrorCallback = SD_DMAError;
+
+ /* Set the DMA Abort callback */
+ hsd->hdmatx->XferAbortCallback = NULL;
+
+ if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
+ {
+ BlockAdd *= 512U;
+ }
+
+ /* Set Block Size for Card */
+ errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Write Blocks in Polling mode */
+ if(NumberOfBlocks > 1U)
+ {
+ hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK | SD_CONTEXT_DMA);
+
+ /* Write Multi Block command */
+ errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, BlockAdd);
+ }
+ else
+ {
+ hsd->Context = (SD_CONTEXT_WRITE_SINGLE_BLOCK | SD_CONTEXT_DMA);
+
+ /* Write Single Block command */
+ errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, BlockAdd);
+ }
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Enable SDIO DMA transfer */
+ __HAL_SD_DMA_ENABLE(hsd);
+
+ /* Enable the DMA Channel */
+ HAL_DMA_Start_IT(hsd->hdmatx, (uint32_t)pData, (uint32_t)&hsd->Instance->FIFO, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4);
+
+ /* Configure the SD DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = BLOCKSIZE * NumberOfBlocks;
+ config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
+ config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
+ config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_ConfigData(hsd->Instance, &config);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Erases the specified memory area of the given SD card.
+ * @note This API should be followed by a check on the card state through
+ * HAL_SD_GetCardState().
+ * @param hsd: Pointer to SD handle
+ * @param BlockStartAdd: Start Block address
+ * @param BlockEndAdd: End Block address
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
+{
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+
+ if(hsd->State == HAL_SD_STATE_READY)
+ {
+ hsd->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ if(BlockEndAdd < BlockStartAdd)
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
+ return HAL_ERROR;
+ }
+
+ if(BlockEndAdd > (hsd->SdCard.LogBlockNbr))
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
+ return HAL_ERROR;
+ }
+
+ hsd->State = HAL_SD_STATE_BUSY;
+
+ /* Check if the card command class supports erase command */
+ if(((hsd->SdCard.Class) & SDIO_CCCC_ERASE) == 0U)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= HAL_SD_ERROR_LOCK_UNLOCK_FAILED;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Get start and end block for high capacity cards */
+ if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
+ {
+ BlockStartAdd *= 512U;
+ BlockEndAdd *= 512U;
+ }
+
+ /* According to sd-card spec 1.0 ERASE_GROUP_START (CMD32) and erase_group_end(CMD33) */
+ if(hsd->SdCard.CardType != CARD_SECURED)
+ {
+ /* Send CMD32 SD_ERASE_GRP_START with argument as addr */
+ errorstate = SDMMC_CmdSDEraseStartAdd(hsd->Instance, BlockStartAdd);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ /* Send CMD33 SD_ERASE_GRP_END with argument as addr */
+ errorstate = SDMMC_CmdSDEraseEndAdd(hsd->Instance, BlockEndAdd);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+ }
+
+ /* Send CMD38 ERASE */
+ errorstate = SDMMC_CmdErase(hsd->Instance);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ hsd->State = HAL_SD_STATE_READY;
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief This function handles SD card interrupt request.
+ * @param hsd: Pointer to SD handle
+ * @retval None
+ */
+void HAL_SD_IRQHandler(SD_HandleTypeDef *hsd)
+{
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+
+ /* Check for SDIO interrupt flags */
+ if(__HAL_SD_GET_FLAG(hsd, SDIO_IT_DATAEND) != RESET)
+ {
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_DATAEND);
+
+ __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
+ SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR | SDIO_IT_STBITERR);
+
+ if((hsd->Context & SD_CONTEXT_IT) != RESET)
+ {
+ if(((hsd->Context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != RESET) || ((hsd->Context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != RESET))
+ {
+ errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ hsd->ErrorCode |= errorstate;
+ HAL_SD_ErrorCallback(hsd);
+ }
+ }
+
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ hsd->State = HAL_SD_STATE_READY;
+ if(((hsd->Context & SD_CONTEXT_READ_SINGLE_BLOCK) != RESET) || ((hsd->Context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != RESET))
+ {
+ HAL_SD_RxCpltCallback(hsd);
+ }
+ else
+ {
+ HAL_SD_TxCpltCallback(hsd);
+ }
+ }
+ else if((hsd->Context & SD_CONTEXT_DMA) != RESET)
+ {
+ if((hsd->Context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != RESET)
+ {
+ errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ hsd->ErrorCode |= errorstate;
+ HAL_SD_ErrorCallback(hsd);
+ }
+ }
+ if(((hsd->Context & SD_CONTEXT_READ_SINGLE_BLOCK) == RESET) && ((hsd->Context & SD_CONTEXT_READ_MULTIPLE_BLOCK) == RESET))
+ {
+ /* Disable the DMA transfer for transmit request by setting the DMAEN bit
+ in the SD DCTRL register */
+ hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
+
+ hsd->State = HAL_SD_STATE_READY;
+
+ HAL_SD_TxCpltCallback(hsd);
+ }
+ }
+ }
+
+ else if(__HAL_SD_GET_FLAG(hsd, SDIO_IT_TXFIFOHE) != RESET)
+ {
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_TXFIFOHE);
+
+ SD_Write_IT(hsd);
+ }
+
+ else if(__HAL_SD_GET_FLAG(hsd, SDIO_IT_RXFIFOHF) != RESET)
+ {
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_RXFIFOHF);
+
+ SD_Read_IT(hsd);
+ }
+
+ else if(__HAL_SD_GET_FLAG(hsd, SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR) != RESET)
+ {
+ /* Set Error code */
+ if(__HAL_SD_GET_FLAG(hsd, SDIO_IT_DCRCFAIL) != RESET)
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL;
+ }
+ if(__HAL_SD_GET_FLAG(hsd, SDIO_IT_DTIMEOUT) != RESET)
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT;
+ }
+ if(__HAL_SD_GET_FLAG(hsd, SDIO_IT_RXOVERR) != RESET)
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_RX_OVERRUN;
+ }
+ if(__HAL_SD_GET_FLAG(hsd, SDIO_IT_TXUNDERR) != RESET)
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_TX_UNDERRUN;
+ }
+ if(__HAL_SD_GET_FLAG(hsd, SDIO_IT_STBITERR) != RESET)
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT;
+ }
+
+ /* Clear All flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS | SDIO_FLAG_STBITERR);
+
+ /* Disable all interrupts */
+ __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
+ SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR |SDIO_IT_STBITERR);
+
+ if((hsd->Context & SD_CONTEXT_DMA) != RESET)
+ {
+ /* Abort the SD DMA Streams */
+ if(hsd->hdmatx != NULL)
+ {
+ /* Set the DMA Tx abort callback */
+ hsd->hdmatx->XferAbortCallback = SD_DMATxAbort;
+ /* Abort DMA in IT mode */
+ if(HAL_DMA_Abort_IT(hsd->hdmatx) != HAL_OK)
+ {
+ SD_DMATxAbort(hsd->hdmatx);
+ }
+ }
+ else if(hsd->hdmarx != NULL)
+ {
+ /* Set the DMA Rx abort callback */
+ hsd->hdmarx->XferAbortCallback = SD_DMARxAbort;
+ /* Abort DMA in IT mode */
+ if(HAL_DMA_Abort_IT(hsd->hdmarx) != HAL_OK)
+ {
+ SD_DMARxAbort(hsd->hdmarx);
+ }
+ }
+ else
+ {
+ hsd->ErrorCode = HAL_SD_ERROR_NONE;
+ hsd->State = HAL_SD_STATE_READY;
+ HAL_SD_AbortCallback(hsd);
+ }
+ }
+ else if((hsd->Context & SD_CONTEXT_IT) != RESET)
+ {
+ /* Set the SD state to ready to be able to start again the process */
+ hsd->State = HAL_SD_STATE_READY;
+ HAL_SD_ErrorCallback(hsd);
+ }
+ }
+}
+
+/**
+ * @brief return the SD state
+ * @param hsd: Pointer to sd handle
+ * @retval HAL state
+ */
+HAL_SD_StateTypeDef HAL_SD_GetState(SD_HandleTypeDef *hsd)
+{
+ return hsd->State;
+}
+
+/**
+* @brief Return the SD error code
+* @param hsd : Pointer to a SD_HandleTypeDef structure that contains
+ * the configuration information.
+* @retval SD Error Code
+*/
+uint32_t HAL_SD_GetError(SD_HandleTypeDef *hsd)
+{
+ return hsd->ErrorCode;
+}
+
+/**
+ * @brief Tx Transfer completed callbacks
+ * @param hsd: Pointer to SD handle
+ * @retval None
+ */
+ __weak void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsd);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SD_TxCpltCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer completed callbacks
+ * @param hsd: Pointer SD handle
+ * @retval None
+ */
+__weak void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsd);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SD_RxCpltCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief SD error callbacks
+ * @param hsd: Pointer SD handle
+ * @retval None
+ */
+__weak void HAL_SD_ErrorCallback(SD_HandleTypeDef *hsd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsd);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SD_ErrorCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief SD Abort callbacks
+ * @param hsd: Pointer SD handle
+ * @retval None
+ */
+__weak void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsd);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SD_ErrorCallback can be implemented in the user file
+ */
+}
+
+
+/**
+ * @}
+ */
+
+/** @addtogroup SD_Exported_Functions_Group3
+ * @brief management functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the SD card
+ operations and get the related information
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns information the information of the card which are stored on
+ * the CID register.
+ * @param hsd: Pointer to SD handle
+ * @param pCID: Pointer to a HAL_SD_CIDTypeDef structure that
+ * contains all CID register parameters
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SD_GetCardCID(SD_HandleTypeDef *hsd, HAL_SD_CardCIDTypeDef *pCID)
+{
+ uint32_t tmp = 0U;
+
+ /* Byte 0 */
+ tmp = (uint8_t)((hsd->CID[0U] & 0xFF000000U) >> 24U);
+ pCID->ManufacturerID = tmp;
+
+ /* Byte 1 */
+ tmp = (uint8_t)((hsd->CID[0U] & 0x00FF0000U) >> 16U);
+ pCID->OEM_AppliID = tmp << 8U;
+
+ /* Byte 2 */
+ tmp = (uint8_t)((hsd->CID[0U] & 0x000000FF00U) >> 8U);
+ pCID->OEM_AppliID |= tmp;
+
+ /* Byte 3 */
+ tmp = (uint8_t)(hsd->CID[0U] & 0x000000FFU);
+ pCID->ProdName1 = tmp << 24U;
+
+ /* Byte 4 */
+ tmp = (uint8_t)((hsd->CID[1U] & 0xFF000000U) >> 24U);
+ pCID->ProdName1 |= tmp << 16;
+
+ /* Byte 5 */
+ tmp = (uint8_t)((hsd->CID[1U] & 0x00FF0000U) >> 16U);
+ pCID->ProdName1 |= tmp << 8U;
+
+ /* Byte 6 */
+ tmp = (uint8_t)((hsd->CID[1U] & 0x0000FF00U) >> 8U);
+ pCID->ProdName1 |= tmp;
+
+ /* Byte 7 */
+ tmp = (uint8_t)(hsd->CID[1U] & 0x000000FFU);
+ pCID->ProdName2 = tmp;
+
+ /* Byte 8 */
+ tmp = (uint8_t)((hsd->CID[2U] & 0xFF000000U) >> 24U);
+ pCID->ProdRev = tmp;
+
+ /* Byte 9 */
+ tmp = (uint8_t)((hsd->CID[2U] & 0x00FF0000U) >> 16U);
+ pCID->ProdSN = tmp << 24U;
+
+ /* Byte 10 */
+ tmp = (uint8_t)((hsd->CID[2U] & 0x0000FF00U) >> 8U);
+ pCID->ProdSN |= tmp << 16U;
+
+ /* Byte 11 */
+ tmp = (uint8_t)(hsd->CID[2U] & 0x000000FFU);
+ pCID->ProdSN |= tmp << 8U;
+
+ /* Byte 12 */
+ tmp = (uint8_t)((hsd->CID[3U] & 0xFF000000U) >> 24U);
+ pCID->ProdSN |= tmp;
+
+ /* Byte 13 */
+ tmp = (uint8_t)((hsd->CID[3U] & 0x00FF0000U) >> 16U);
+ pCID->Reserved1 |= (tmp & 0xF0U) >> 4U;
+ pCID->ManufactDate = (tmp & 0x0FU) << 8U;
+
+ /* Byte 14 */
+ tmp = (uint8_t)((hsd->CID[3U] & 0x0000FF00U) >> 8U);
+ pCID->ManufactDate |= tmp;
+
+ /* Byte 15 */
+ tmp = (uint8_t)(hsd->CID[3U] & 0x000000FFU);
+ pCID->CID_CRC = (tmp & 0xFEU) >> 1U;
+ pCID->Reserved2 = 1U;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Returns information the information of the card which are stored on
+ * the CSD register.
+ * @param hsd: Pointer to SD handle
+ * @param pCSD: Pointer to a HAL_SD_CardCSDTypeDef structure that
+ * contains all CSD register parameters
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SD_GetCardCSD(SD_HandleTypeDef *hsd, HAL_SD_CardCSDTypeDef *pCSD)
+{
+ uint32_t tmp = 0U;
+
+ /* Byte 0 */
+ tmp = (hsd->CSD[0U] & 0xFF000000U) >> 24U;
+ pCSD->CSDStruct = (uint8_t)((tmp & 0xC0U) >> 6U);
+ pCSD->SysSpecVersion = (uint8_t)((tmp & 0x3CU) >> 2U);
+ pCSD->Reserved1 = tmp & 0x03U;
+
+ /* Byte 1 */
+ tmp = (hsd->CSD[0U] & 0x00FF0000U) >> 16U;
+ pCSD->TAAC = (uint8_t)tmp;
+
+ /* Byte 2 */
+ tmp = (hsd->CSD[0U] & 0x0000FF00U) >> 8U;
+ pCSD->NSAC = (uint8_t)tmp;
+
+ /* Byte 3 */
+ tmp = hsd->CSD[0U] & 0x000000FFU;
+ pCSD->MaxBusClkFrec = (uint8_t)tmp;
+
+ /* Byte 4 */
+ tmp = (hsd->CSD[1U] & 0xFF000000U) >> 24U;
+ pCSD->CardComdClasses = (uint16_t)(tmp << 4U);
+
+ /* Byte 5 */
+ tmp = (hsd->CSD[1U] & 0x00FF0000U) >> 16U;
+ pCSD->CardComdClasses |= (uint16_t)((tmp & 0xF0U) >> 4U);
+ pCSD->RdBlockLen = (uint8_t)(tmp & 0x0FU);
+
+ /* Byte 6 */
+ tmp = (hsd->CSD[1U] & 0x0000FF00U) >> 8U;
+ pCSD->PartBlockRead = (uint8_t)((tmp & 0x80U) >> 7U);
+ pCSD->WrBlockMisalign = (uint8_t)((tmp & 0x40U) >> 6U);
+ pCSD->RdBlockMisalign = (uint8_t)((tmp & 0x20U) >> 5U);
+ pCSD->DSRImpl = (uint8_t)((tmp & 0x10U) >> 4U);
+ pCSD->Reserved2 = 0U; /*!< Reserved */
+
+ if(hsd->SdCard.CardType == CARD_SDSC)
+ {
+ pCSD->DeviceSize = (tmp & 0x03U) << 10U;
+
+ /* Byte 7 */
+ tmp = (uint8_t)(hsd->CSD[1U] & 0x000000FFU);
+ pCSD->DeviceSize |= (tmp) << 2U;
+
+ /* Byte 8 */
+ tmp = (uint8_t)((hsd->CSD[2U] & 0xFF000000U) >> 24U);
+ pCSD->DeviceSize |= (tmp & 0xC0U) >> 6U;
+
+ pCSD->MaxRdCurrentVDDMin = (tmp & 0x38U) >> 3U;
+ pCSD->MaxRdCurrentVDDMax = (tmp & 0x07U);
+
+ /* Byte 9 */
+ tmp = (uint8_t)((hsd->CSD[2U] & 0x00FF0000U) >> 16U);
+ pCSD->MaxWrCurrentVDDMin = (tmp & 0xE0U) >> 5U;
+ pCSD->MaxWrCurrentVDDMax = (tmp & 0x1CU) >> 2U;
+ pCSD->DeviceSizeMul = (tmp & 0x03U) << 1U;
+ /* Byte 10 */
+ tmp = (uint8_t)((hsd->CSD[2U] & 0x0000FF00U) >> 8U);
+ pCSD->DeviceSizeMul |= (tmp & 0x80U) >> 7U;
+
+ hsd->SdCard.BlockNbr = (pCSD->DeviceSize + 1U) ;
+ hsd->SdCard.BlockNbr *= (1U << (pCSD->DeviceSizeMul + 2U));
+ hsd->SdCard.BlockSize = 1U << (pCSD->RdBlockLen);
+
+ hsd->SdCard.LogBlockNbr = (hsd->SdCard.BlockNbr) * ((hsd->SdCard.BlockSize) / 512U);
+ hsd->SdCard.LogBlockSize = 512U;
+ }
+ else if(hsd->SdCard.CardType == CARD_SDHC_SDXC)
+ {
+ /* Byte 7 */
+ tmp = (uint8_t)(hsd->CSD[1U] & 0x000000FFU);
+ pCSD->DeviceSize = (tmp & 0x3FU) << 16U;
+
+ /* Byte 8 */
+ tmp = (uint8_t)((hsd->CSD[2U] & 0xFF000000U) >> 24U);
+
+ pCSD->DeviceSize |= (tmp << 8U);
+
+ /* Byte 9 */
+ tmp = (uint8_t)((hsd->CSD[2U] & 0x00FF0000U) >> 16U);
+
+ pCSD->DeviceSize |= (tmp);
+
+ /* Byte 10 */
+ tmp = (uint8_t)((hsd->CSD[2U] & 0x0000FF00U) >> 8U);
+
+ hsd->SdCard.LogBlockNbr = hsd->SdCard.BlockNbr = (((uint64_t)pCSD->DeviceSize + 1U) * 1024U);
+ hsd->SdCard.LogBlockSize = hsd->SdCard.BlockSize = 512U;
+ }
+ else
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+
+ pCSD->EraseGrSize = (tmp & 0x40U) >> 6U;
+ pCSD->EraseGrMul = (tmp & 0x3FU) << 1U;
+
+ /* Byte 11 */
+ tmp = (uint8_t)(hsd->CSD[2U] & 0x000000FFU);
+ pCSD->EraseGrMul |= (tmp & 0x80U) >> 7U;
+ pCSD->WrProtectGrSize = (tmp & 0x7FU);
+
+ /* Byte 12 */
+ tmp = (uint8_t)((hsd->CSD[3U] & 0xFF000000U) >> 24U);
+ pCSD->WrProtectGrEnable = (tmp & 0x80U) >> 7U;
+ pCSD->ManDeflECC = (tmp & 0x60U) >> 5U;
+ pCSD->WrSpeedFact = (tmp & 0x1CU) >> 2U;
+ pCSD->MaxWrBlockLen = (tmp & 0x03U) << 2U;
+
+ /* Byte 13 */
+ tmp = (uint8_t)((hsd->CSD[3U] & 0x00FF0000U) >> 16U);
+ pCSD->MaxWrBlockLen |= (tmp & 0xC0U) >> 6U;
+ pCSD->WriteBlockPaPartial = (tmp & 0x20U) >> 5U;
+ pCSD->Reserved3 = 0U;
+ pCSD->ContentProtectAppli = (tmp & 0x01U);
+
+ /* Byte 14 */
+ tmp = (uint8_t)((hsd->CSD[3U] & 0x0000FF00U) >> 8U);
+ pCSD->FileFormatGrouop = (tmp & 0x80U) >> 7U;
+ pCSD->CopyFlag = (tmp & 0x40U) >> 6U;
+ pCSD->PermWrProtect = (tmp & 0x20U) >> 5U;
+ pCSD->TempWrProtect = (tmp & 0x10U) >> 4U;
+ pCSD->FileFormat = (tmp & 0x0CU) >> 2U;
+ pCSD->ECC = (tmp & 0x03U);
+
+ /* Byte 15 */
+ tmp = (uint8_t)(hsd->CSD[3U] & 0x000000FFU);
+ pCSD->CSD_CRC = (tmp & 0xFEU) >> 1U;
+ pCSD->Reserved4 = 1U;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Gets the SD status info.
+ * @param hsd: Pointer to SD handle
+ * @param pStatus: Pointer to the HAL_SD_CardStatusTypeDef structure that
+ * will contain the SD card status information
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypeDef *pStatus)
+{
+ uint32_t tmp = 0U;
+ uint32_t sd_status[16U];
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+
+ errorstate = SD_SendSDStatus(hsd, sd_status);
+ if(errorstate != HAL_OK)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->ErrorCode |= errorstate;
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* Byte 0 */
+ tmp = (sd_status[0U] & 0xC0U) >> 6U;
+ pStatus->DataBusWidth = (uint8_t)tmp;
+
+ /* Byte 0 */
+ tmp = (sd_status[0U] & 0x20U) >> 5U;
+ pStatus->SecuredMode = (uint8_t)tmp;
+
+ /* Byte 2 */
+ tmp = (sd_status[0U] & 0x00FF0000U) >> 16U;
+ pStatus->CardType = (uint16_t)(tmp << 8U);
+
+ /* Byte 3 */
+ tmp = (sd_status[0U] & 0xFF000000U) >> 24U;
+ pStatus->CardType |= (uint16_t)tmp;
+
+ /* Byte 4 */
+ tmp = (sd_status[1U] & 0xFFU);
+ pStatus->ProtectedAreaSize = (uint32_t)(tmp << 24U);
+
+ /* Byte 5 */
+ tmp = (sd_status[1U] & 0xFF00U) >> 8U;
+ pStatus->ProtectedAreaSize |= (uint32_t)(tmp << 16U);
+
+ /* Byte 6 */
+ tmp = (sd_status[1U] & 0xFF0000U) >> 16U;
+ pStatus->ProtectedAreaSize |= (uint32_t)(tmp << 8U);
+
+ /* Byte 7 */
+ tmp = (sd_status[1U] & 0xFF000000U) >> 24U;
+ pStatus->ProtectedAreaSize |= (uint32_t)tmp;
+
+ /* Byte 8 */
+ tmp = (sd_status[2U] & 0xFFU);
+ pStatus->SpeedClass = (uint8_t)tmp;
+
+ /* Byte 9 */
+ tmp = (sd_status[2U] & 0xFF00U) >> 8U;
+ pStatus->PerformanceMove = (uint8_t)tmp;
+
+ /* Byte 10 */
+ tmp = (sd_status[2U] & 0xF00000U) >> 20U;
+ pStatus->AllocationUnitSize = (uint8_t)tmp;
+
+ /* Byte 11 */
+ tmp = (sd_status[2U] & 0xFF000000U) >> 24U;
+ pStatus->EraseSize = (uint16_t)(tmp << 8U);
+
+ /* Byte 12 */
+ tmp = (sd_status[3U] & 0xFFU);
+ pStatus->EraseSize |= (uint16_t)tmp;
+
+ /* Byte 13 */
+ tmp = (sd_status[3U] & 0xFC00U) >> 10U;
+ pStatus->EraseTimeout = (uint8_t)tmp;
+
+ /* Byte 13 */
+ tmp = (sd_status[3U] & 0x0300U) >> 8U;
+ pStatus->EraseOffset = (uint8_t)tmp;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Gets the SD card info.
+ * @param hsd: Pointer to SD handle
+ * @param pCardInfo: Pointer to the HAL_SD_CardInfoTypeDef structure that
+ * will contain the SD card status information
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SD_GetCardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypeDef *pCardInfo)
+{
+ pCardInfo->CardType = (uint32_t)(hsd->SdCard.CardType);
+ pCardInfo->CardVersion = (uint32_t)(hsd->SdCard.CardVersion);
+ pCardInfo->Class = (uint32_t)(hsd->SdCard.Class);
+ pCardInfo->RelCardAdd = (uint32_t)(hsd->SdCard.RelCardAdd);
+ pCardInfo->BlockNbr = (uint32_t)(hsd->SdCard.BlockNbr);
+ pCardInfo->BlockSize = (uint32_t)(hsd->SdCard.BlockSize);
+ pCardInfo->LogBlockNbr = (uint32_t)(hsd->SdCard.LogBlockNbr);
+ pCardInfo->LogBlockSize = (uint32_t)(hsd->SdCard.LogBlockSize);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enables wide bus operation for the requested card if supported by
+ * card.
+ * @param hsd: Pointer to SD handle
+ * @param WideMode: Specifies the SD card wide bus mode
+ * This parameter can be one of the following values:
+ * @arg SDIO_BUS_WIDE_8B: 8-bit data transfer
+ * @arg SDIO_BUS_WIDE_4B: 4-bit data transfer
+ * @arg SDIO_BUS_WIDE_1B: 1-bit data transfer
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SD_ConfigWideBusOperation(SD_HandleTypeDef *hsd, uint32_t WideMode)
+{
+ SDIO_InitTypeDef Init;
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+
+ /* Check the parameters */
+ assert_param(IS_SDIO_BUS_WIDE(WideMode));
+
+ /* Chnage Satte */
+ hsd->State = HAL_SD_STATE_BUSY;
+
+ if(hsd->SdCard.CardType != CARD_SECURED)
+ {
+ if(WideMode == SDIO_BUS_WIDE_8B)
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
+ }
+ else if(WideMode == SDIO_BUS_WIDE_4B)
+ {
+ errorstate = SD_WideBus_Enable(hsd);
+
+ hsd->ErrorCode |= errorstate;
+ }
+ else if(WideMode == SDIO_BUS_WIDE_1B)
+ {
+ errorstate = SD_WideBus_Disable(hsd);
+
+ hsd->ErrorCode |= errorstate;
+ }
+ else
+ {
+ /* WideMode is not a valid argument*/
+ hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
+ }
+ }
+ else
+ {
+ /* MMC Card does not support this feature */
+ hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
+ }
+
+ if(hsd->ErrorCode != HAL_SD_ERROR_NONE)
+ {
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+ hsd->State = HAL_SD_STATE_READY;
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* Configure the SDIO peripheral */
+ Init.ClockEdge = hsd->Init.ClockEdge;
+ Init.ClockBypass = hsd->Init.ClockBypass;
+ Init.ClockPowerSave = hsd->Init.ClockPowerSave;
+ Init.BusWide = WideMode;
+ Init.HardwareFlowControl = hsd->Init.HardwareFlowControl;
+ Init.ClockDiv = hsd->Init.ClockDiv;
+ SDIO_Init(hsd->Instance, Init);
+ }
+
+ /* Change State */
+ hsd->State = HAL_SD_STATE_READY;
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Gets the current sd card data state.
+ * @param hsd: pointer to SD handle
+ * @retval Card state
+ */
+HAL_SD_CardStateTypeDef HAL_SD_GetCardState(SD_HandleTypeDef *hsd)
+{
+ HAL_SD_CardStateTypeDef cardstate = HAL_SD_CARD_TRANSFER;
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+ uint32_t resp1 = 0;
+
+ errorstate = SD_SendStatus(hsd, &resp1);
+ if(errorstate != HAL_OK)
+ {
+ hsd->ErrorCode |= errorstate;
+ }
+
+ cardstate = (HAL_SD_CardStateTypeDef)((resp1 >> 9U) & 0x0FU);
+
+ return cardstate;
+}
+
+/**
+ * @brief Abort the current transfer and disable the SD.
+ * @param hsd: pointer to a SD_HandleTypeDef structure that contains
+ * the configuration information for SD module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SD_Abort(SD_HandleTypeDef *hsd)
+{
+ HAL_SD_CardStateTypeDef CardState;
+
+ /* DIsable All interrupts */
+ __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
+ SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
+
+ /* Clear All flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ if((hsd->hdmatx != NULL) || (hsd->hdmarx != NULL))
+ {
+ /* Disable the SD DMA request */
+ hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
+
+ /* Abort the SD DMA Tx Stream */
+ if(hsd->hdmatx != NULL)
+ {
+ HAL_DMA_Abort(hsd->hdmatx);
+ }
+ /* Abort the SD DMA Rx Stream */
+ if(hsd->hdmarx != NULL)
+ {
+ HAL_DMA_Abort(hsd->hdmarx);
+ }
+ }
+
+ hsd->State = HAL_SD_STATE_READY;
+ CardState = HAL_SD_GetCardState(hsd);
+ if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
+ {
+ hsd->ErrorCode = SDMMC_CmdStopTransfer(hsd->Instance);
+ }
+ if(hsd->ErrorCode != HAL_SD_ERROR_NONE)
+ {
+ return HAL_ERROR;
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort the current transfer and disable the SD (IT mode).
+ * @param hsd: pointer to a SD_HandleTypeDef structure that contains
+ * the configuration information for SD module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SD_Abort_IT(SD_HandleTypeDef *hsd)
+{
+ HAL_SD_CardStateTypeDef CardState;
+
+ /* DIsable All interrupts */
+ __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
+ SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
+
+ /* Clear All flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ if((hsd->hdmatx != NULL) || (hsd->hdmarx != NULL))
+ {
+ /* Disable the SD DMA request */
+ hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
+
+ /* Abort the SD DMA Tx Stream */
+ if(hsd->hdmatx != NULL)
+ {
+ hsd->hdmatx->XferAbortCallback = SD_DMATxAbort;
+ if(HAL_DMA_Abort_IT(hsd->hdmatx) != HAL_OK)
+ {
+ hsd->hdmatx = NULL;
+ }
+ }
+ /* Abort the SD DMA Rx Stream */
+ if(hsd->hdmarx != NULL)
+ {
+ hsd->hdmarx->XferAbortCallback = SD_DMARxAbort;
+ if(HAL_DMA_Abort_IT(hsd->hdmarx) != HAL_OK)
+ {
+ hsd->hdmarx = NULL;
+ }
+ }
+ }
+
+ /* No transfer ongoing on both DMA channels*/
+ if((hsd->hdmatx == NULL) && (hsd->hdmarx == NULL))
+ {
+ CardState = HAL_SD_GetCardState(hsd);
+ hsd->State = HAL_SD_STATE_READY;
+ if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
+ {
+ hsd->ErrorCode = SDMMC_CmdStopTransfer(hsd->Instance);
+ }
+ if(hsd->ErrorCode != HAL_SD_ERROR_NONE)
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ HAL_SD_AbortCallback(hsd);
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private function ----------------------------------------------------------*/
+/** @addtogroup SD_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief DMA SD transmit process complete callback
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void SD_DMATransmitCplt(DMA_HandleTypeDef *hdma)
+{
+ SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
+
+ /* Enable DATAEND Interrupt */
+ __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DATAEND));
+}
+
+/**
+ * @brief DMA SD receive process complete callback
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void SD_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+
+ /* Send stop command in multiblock write */
+ if(hsd->Context == (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_DMA))
+ {
+ errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ hsd->ErrorCode |= errorstate;
+ HAL_SD_ErrorCallback(hsd);
+ }
+ }
+
+ /* Disable the DMA transfer for transmit request by setting the DMAEN bit
+ in the SD DCTRL register */
+ hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
+
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ hsd->State = HAL_SD_STATE_READY;
+
+ HAL_SD_RxCpltCallback(hsd);
+}
+
+/**
+ * @brief DMA SD communication error callback
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void SD_DMAError(DMA_HandleTypeDef *hdma)
+{
+ SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
+ HAL_SD_CardStateTypeDef CardState;
+
+ if((hsd->hdmarx->ErrorCode == HAL_DMA_ERROR_TE) || (hsd->hdmatx->ErrorCode == HAL_DMA_ERROR_TE))
+ {
+ /* Clear All flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ /* Disable All interrupts */
+ __HAL_SD_DISABLE_IT(hsd, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
+ SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
+
+ hsd->ErrorCode |= HAL_SD_ERROR_DMA;
+ CardState = HAL_SD_GetCardState(hsd);
+ if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
+ {
+ hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance);
+ }
+
+ hsd->State= HAL_SD_STATE_READY;
+ }
+
+ HAL_SD_ErrorCallback(hsd);
+}
+
+/**
+ * @brief DMA SD Tx Abort callback
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void SD_DMATxAbort(DMA_HandleTypeDef *hdma)
+{
+ SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
+ HAL_SD_CardStateTypeDef CardState;
+
+ if(hsd->hdmatx != NULL)
+ {
+ hsd->hdmatx = NULL;
+ }
+
+ /* All DMA channels are aborted */
+ if(hsd->hdmarx == NULL)
+ {
+ CardState = HAL_SD_GetCardState(hsd);
+ hsd->ErrorCode = HAL_SD_ERROR_NONE;
+ hsd->State = HAL_SD_STATE_READY;
+ if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
+ {
+ hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance);
+
+ if(hsd->ErrorCode != HAL_SD_ERROR_NONE)
+ {
+ HAL_SD_AbortCallback(hsd);
+ }
+ else
+ {
+ HAL_SD_ErrorCallback(hsd);
+ }
+ }
+ }
+}
+
+/**
+ * @brief DMA SD Rx Abort callback
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void SD_DMARxAbort(DMA_HandleTypeDef *hdma)
+{
+ SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
+ HAL_SD_CardStateTypeDef CardState;
+
+ if(hsd->hdmarx != NULL)
+ {
+ hsd->hdmarx = NULL;
+ }
+
+ /* All DMA channels are aborted */
+ if(hsd->hdmatx == NULL)
+ {
+ CardState = HAL_SD_GetCardState(hsd);
+ hsd->ErrorCode = HAL_SD_ERROR_NONE;
+ hsd->State = HAL_SD_STATE_READY;
+ if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING))
+ {
+ hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance);
+
+ if(hsd->ErrorCode != HAL_SD_ERROR_NONE)
+ {
+ HAL_SD_AbortCallback(hsd);
+ }
+ else
+ {
+ HAL_SD_ErrorCallback(hsd);
+ }
+ }
+ }
+}
+
+
+/**
+ * @brief Initializes the sd card.
+ * @param hsd: Pointer to SD handle
+ * @retval SD Card error state
+ */
+static uint32_t SD_InitCard(SD_HandleTypeDef *hsd)
+{
+ HAL_SD_CardCSDTypeDef CSD;
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+ uint16_t sd_rca = 1U;
+
+ /* Check the power State */
+ if(SDIO_GetPowerState(hsd->Instance) == 0U)
+ {
+ /* Power off */
+ return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;
+ }
+
+ if(hsd->SdCard.CardType != CARD_SECURED)
+ {
+ /* Send CMD2 ALL_SEND_CID */
+ errorstate = SDMMC_CmdSendCID(hsd->Instance);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ return errorstate;
+ }
+ else
+ {
+ /* Get Card identification number data */
+ hsd->CID[0U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
+ hsd->CID[1U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP2);
+ hsd->CID[2U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP3);
+ hsd->CID[3U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP4);
+ }
+ }
+
+ if(hsd->SdCard.CardType != CARD_SECURED)
+ {
+ /* Send CMD3 SET_REL_ADDR with argument 0 */
+ /* SD Card publishes its RCA. */
+ errorstate = SDMMC_CmdSetRelAdd(hsd->Instance, &sd_rca);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ return errorstate;
+ }
+ }
+ if(hsd->SdCard.CardType != CARD_SECURED)
+ {
+ /* Get the SD card RCA */
+ hsd->SdCard.RelCardAdd = sd_rca;
+
+ /* Send CMD9 SEND_CSD with argument as card's RCA */
+ errorstate = SDMMC_CmdSendCSD(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ return errorstate;
+ }
+ else
+ {
+ /* Get Card Specific Data */
+ hsd->CSD[0U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
+ hsd->CSD[1U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP2);
+ hsd->CSD[2U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP3);
+ hsd->CSD[3U] = SDIO_GetResponse(hsd->Instance, SDIO_RESP4);
+ }
+ }
+
+ /* Get the Card Class */
+ hsd->SdCard.Class = (SDIO_GetResponse(hsd->Instance, SDIO_RESP2) >> 20U);
+
+ /* Get CSD parameters */
+ HAL_SD_GetCardCSD(hsd, &CSD);
+
+ /* Select the Card */
+ errorstate = SDMMC_CmdSelDesel(hsd->Instance, (uint32_t)(((uint32_t)hsd->SdCard.RelCardAdd) << 16U));
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ return errorstate;
+ }
+
+ /* Configure SDIO peripheral interface */
+ SDIO_Init(hsd->Instance, hsd->Init);
+
+ /* All cards are initialized */
+ return HAL_SD_ERROR_NONE;
+}
+
+/**
+ * @brief Enquires cards about their operating voltage and configures clock
+ * controls and stores SD information that will be needed in future
+ * in the SD handle.
+ * @param hsd: Pointer to SD handle
+ * @retval error state
+ */
+static uint32_t SD_PowerON(SD_HandleTypeDef *hsd)
+{
+ __IO uint32_t count = 0U;
+ uint32_t response = 0U, validvoltage = 0U;
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+
+ /* CMD0: GO_IDLE_STATE */
+ errorstate = SDMMC_CmdGoIdleState(hsd->Instance);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ return errorstate;
+ }
+
+ /* CMD8: SEND_IF_COND: Command available only on V2.0 cards */
+ errorstate = SDMMC_CmdOperCond(hsd->Instance);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ hsd->SdCard.CardVersion = CARD_V1_X;
+
+ /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */
+ while(validvoltage == 0U)
+ {
+ if(count++ == SDMMC_MAX_VOLT_TRIAL)
+ {
+ return HAL_SD_ERROR_INVALID_VOLTRANGE;
+ }
+
+ /* SEND CMD55 APP_CMD with RCA as 0 */
+ errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0U);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ return HAL_SD_ERROR_UNSUPPORTED_FEATURE;
+ }
+
+ /* Send CMD41 */
+ errorstate = SDMMC_CmdAppOperCommand(hsd->Instance, SDMMC_STD_CAPACITY);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ return HAL_SD_ERROR_UNSUPPORTED_FEATURE;
+ }
+
+ /* Get command response */
+ response = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
+
+ /* Get operating voltage*/
+ validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
+ }
+ /* Card type is SDSC */
+ hsd->SdCard.CardType = CARD_SDSC;
+ }
+ else
+ {
+ hsd->SdCard.CardVersion = CARD_V2_X;
+
+ /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */
+ while(validvoltage == 0U)
+ {
+ if(count++ == SDMMC_MAX_VOLT_TRIAL)
+ {
+ return HAL_SD_ERROR_INVALID_VOLTRANGE;
+ }
+
+ /* SEND CMD55 APP_CMD with RCA as 0 */
+ errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0U);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ return errorstate;
+ }
+
+ /* Send CMD41 */
+ errorstate = SDMMC_CmdAppOperCommand(hsd->Instance, SDMMC_HIGH_CAPACITY);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ return errorstate;
+ }
+
+ /* Get command response */
+ response = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
+
+ /* Get operating voltage*/
+ validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
+ }
+
+ if((response & SDMMC_HIGH_CAPACITY) == SDMMC_HIGH_CAPACITY) /* (response &= SD_HIGH_CAPACITY) */
+ {
+ hsd->SdCard.CardType = CARD_SDHC_SDXC;
+ }
+ else
+ {
+ hsd->SdCard.CardType = CARD_SDSC;
+ }
+ }
+
+ return HAL_SD_ERROR_NONE;
+}
+
+/**
+ * @brief Turns the SDIO output signals off.
+ * @param hsd: Pointer to SD handle
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef SD_PowerOFF(SD_HandleTypeDef *hsd)
+{
+ /* Set Power State to OFF */
+ SDIO_PowerState_OFF(hsd->Instance);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Send Status info command.
+ * @param hsd: pointer to SD handle
+ * @param pSDstatus: Pointer to the buffer that will contain the SD card status
+ * SD Status register)
+ * @retval error state
+ */
+static uint32_t SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus)
+{
+ SDIO_DataInitTypeDef config;
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t count = 0U;
+
+ /* Check SD response */
+ if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
+ {
+ return HAL_SD_ERROR_LOCK_UNLOCK_FAILED;
+ }
+
+ /* Set block size for card if it is not equal to current block size for card */
+ errorstate = SDMMC_CmdBlockLength(hsd->Instance, 64U);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_NONE;
+ return errorstate;
+ }
+
+ /* Send CMD55 */
+ errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_NONE;
+ return errorstate;
+ }
+
+ /* Configure the SD DPSM (Data Path State Machine) */
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = 64U;
+ config.DataBlockSize = SDIO_DATABLOCK_SIZE_64B;
+ config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
+ config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_ConfigData(hsd->Instance, &config);
+
+ /* Send ACMD13 (SD_APP_STAUS) with argument as card's RCA */
+ errorstate = SDMMC_CmdStatusRegister(hsd->Instance);
+ if(errorstate != HAL_SD_ERROR_NONE)
+ {
+ hsd->ErrorCode |= HAL_SD_ERROR_NONE;
+ return errorstate;
+ }
+
+ /* Get status data */
+ while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND))
+ {
+ if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF))
+ {
+ for(count = 0U; count < 8U; count++)
+ {
+ *(pSDstatus + count) = SDIO_ReadFIFO(hsd->Instance);
+ }
+
+ pSDstatus += 8U;
+ }
+
+ if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT)
+ {
+ return HAL_SD_ERROR_TIMEOUT;
+ }
+ }
+
+ if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
+ {
+ return HAL_SD_ERROR_DATA_TIMEOUT;
+ }
+ else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
+ {
+ return HAL_SD_ERROR_DATA_CRC_FAIL;
+ }
+ else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))
+ {
+ return HAL_SD_ERROR_RX_OVERRUN;
+ }
+
+ while ((__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXDAVL)))
+ {
+ *pSDstatus = SDIO_ReadFIFO(hsd->Instance);
+ pSDstatus++;
+
+ if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT)
+ {
+ return HAL_SD_ERROR_TIMEOUT;
+ }
+ }
+
+ /* Clear all the static status flags*/
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ return HAL_SD_ERROR_NONE;
+}
+
+/**
+ * @brief Returns the current card's status.
+ * @param hsd: Pointer to SD handle
+ * @param pCardStatus: pointer to the buffer that will contain the SD card
+ * status (Card Status register)
+ * @retval error state
+ */
+static uint32_t SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus)
+{
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+
+ if(pCardStatus == NULL)
+ {
+ return HAL_SD_ERROR_PARAM;
+ }
+
+ /* Send Status command */
+ errorstate = SDMMC_CmdSendStatus(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
+ if(errorstate != HAL_OK)
+ {
+ return errorstate;
+ }
+
+ /* Get SD card status */
+ *pCardStatus = SDIO_GetResponse(hsd->Instance, SDIO_RESP1);
+
+ return HAL_SD_ERROR_NONE;
+}
+
+/**
+ * @brief Enables the SDIO wide bus mode.
+ * @param hsd: pointer to SD handle
+ * @retval error state
+ */
+static uint32_t SD_WideBus_Enable(SD_HandleTypeDef *hsd)
+{
+ uint32_t scr[2U] = {0U, 0U};
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+
+ if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
+ {
+ return HAL_SD_ERROR_LOCK_UNLOCK_FAILED;
+ }
+
+ /* Get SCR Register */
+ errorstate = SD_FindSCR(hsd, scr);
+ if(errorstate != HAL_OK)
+ {
+ return errorstate;
+ }
+
+ /* If requested card supports wide bus operation */
+ if((scr[1U] & SDMMC_WIDE_BUS_SUPPORT) != SDMMC_ALLZERO)
+ {
+ /* Send CMD55 APP_CMD with argument as card's RCA.*/
+ errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
+ if(errorstate != HAL_OK)
+ {
+ return errorstate;
+ }
+
+ /* Send ACMD6 APP_CMD with argument as 2 for wide bus mode */
+ errorstate = SDMMC_CmdBusWidth(hsd->Instance, 2U);
+ if(errorstate != HAL_OK)
+ {
+ return errorstate;
+ }
+
+ return HAL_SD_ERROR_NONE;
+ }
+ else
+ {
+ return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;
+ }
+}
+
+/**
+ * @brief Disables the SDIO wide bus mode.
+ * @param hsd: Pointer to SD handle
+ * @retval error state
+ */
+static uint32_t SD_WideBus_Disable(SD_HandleTypeDef *hsd)
+{
+ uint32_t scr[2U] = {0U, 0U};
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+
+ if((SDIO_GetResponse(hsd->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
+ {
+ return HAL_SD_ERROR_LOCK_UNLOCK_FAILED;
+ }
+
+ /* Get SCR Register */
+ errorstate = SD_FindSCR(hsd, scr);
+ if(errorstate != HAL_OK)
+ {
+ return errorstate;
+ }
+
+ /* If requested card supports 1 bit mode operation */
+ if((scr[1U] & SDMMC_SINGLE_BUS_SUPPORT) != SDMMC_ALLZERO)
+ {
+ /* Send CMD55 APP_CMD with argument as card's RCA */
+ errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U));
+ if(errorstate != HAL_OK)
+ {
+ return errorstate;
+ }
+
+ /* Send ACMD6 APP_CMD with argument as 0 for single bus mode */
+ errorstate = SDMMC_CmdBusWidth(hsd->Instance, 0U);
+ if(errorstate != HAL_OK)
+ {
+ return errorstate;
+ }
+
+ return HAL_SD_ERROR_NONE;
+ }
+ else
+ {
+ return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;
+ }
+}
+
+
+/**
+ * @brief Finds the SD card SCR register value.
+ * @param hsd: Pointer to SD handle
+ * @param pSCR: pointer to the buffer that will contain the SCR value
+ * @retval error state
+ */
+static uint32_t SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR)
+{
+ SDIO_DataInitTypeDef config;
+ uint32_t errorstate = HAL_SD_ERROR_NONE;
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t index = 0U;
+ uint32_t tempscr[2U] = {0U, 0U};
+
+ /* Set Block Size To 8 Bytes */
+ errorstate = SDMMC_CmdBlockLength(hsd->Instance, 8U);
+ if(errorstate != HAL_OK)
+ {
+ return errorstate;
+ }
+
+ /* Send CMD55 APP_CMD with argument as card's RCA */
+ errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)((hsd->SdCard.RelCardAdd) << 16U));
+ if(errorstate != HAL_OK)
+ {
+ return errorstate;
+ }
+
+ config.DataTimeOut = SDMMC_DATATIMEOUT;
+ config.DataLength = 8U;
+ config.DataBlockSize = SDIO_DATABLOCK_SIZE_8B;
+ config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
+ config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
+ config.DPSM = SDIO_DPSM_ENABLE;
+ SDIO_ConfigData(hsd->Instance, &config);
+
+ /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */
+ errorstate = SDMMC_CmdSendSCR(hsd->Instance);
+ if(errorstate != HAL_OK)
+ {
+ return errorstate;
+ }
+
+ while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND))
+ {
+ if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXDAVL))
+ {
+ *(tempscr + index) = SDIO_ReadFIFO(hsd->Instance);
+ index++;
+ }
+
+ if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT)
+ {
+ return HAL_SD_ERROR_TIMEOUT;
+ }
+ }
+
+ if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT))
+ {
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT);
+
+ return HAL_SD_ERROR_DATA_TIMEOUT;
+ }
+ else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL))
+ {
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL);
+
+ return HAL_SD_ERROR_DATA_CRC_FAIL;
+ }
+ else if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_RXOVERR))
+ {
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR);
+
+ return HAL_SD_ERROR_RX_OVERRUN;
+ }
+ else
+ {
+ /* No error flag set */
+ /* Clear all the static flags */
+ __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
+
+ *(pSCR + 1U) = ((tempscr[0U] & SDMMC_0TO7BITS) << 24U) | ((tempscr[0U] & SDMMC_8TO15BITS) << 8U) |\
+ ((tempscr[0U] & SDMMC_16TO23BITS) >> 8U) | ((tempscr[0U] & SDMMC_24TO31BITS) >> 24U);
+
+ *(pSCR) = ((tempscr[1U] & SDMMC_0TO7BITS) << 24U) | ((tempscr[1U] & SDMMC_8TO15BITS) << 8U) |\
+ ((tempscr[1U] & SDMMC_16TO23BITS) >> 8U) | ((tempscr[1U] & SDMMC_24TO31BITS) >> 24U);
+ }
+
+ return HAL_SD_ERROR_NONE;
+}
+
+/**
+ * @brief Wrap up reading in non-blocking mode.
+ * @param hsd: pointer to a SD_HandleTypeDef structure that contains
+ * the configuration information.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef SD_Read_IT(SD_HandleTypeDef *hsd)
+{
+ uint32_t count = 0U;
+ uint32_t* tmp;
+
+ tmp = (uint32_t*)hsd->pRxBuffPtr;
+
+ /* Read data from SDIO Rx FIFO */
+ for(count = 0U; count < 8U; count++)
+ {
+ *(tmp + count) = SDIO_ReadFIFO(hsd->Instance);
+ }
+
+ hsd->pRxBuffPtr += 8U;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Wrap up writing in non-blocking mode.
+ * @param hsd: pointer to a SD_HandleTypeDef structure that contains
+ * the configuration information.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef SD_Write_IT(SD_HandleTypeDef *hsd)
+{
+ uint32_t count = 0U;
+ uint32_t* tmp;
+
+ tmp = (uint32_t*)hsd->pTxBuffPtr;
+
+ /* Write data to SDIO Tx FIFO */
+ for(count = 0U; count < 8U; count++)
+ {
+ SDIO_WriteFIFO(hsd->Instance, (tmp + count));
+ }
+
+ hsd->pTxBuffPtr += 8U;
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+#endif /* STM32F103xE || STM32F103xG */
+
+#endif /* HAL_SD_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_smartcard.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_smartcard.c
new file mode 100644
index 0000000..12369ad
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_smartcard.c
@@ -0,0 +1,1900 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_smartcard.c
+ * @author MCD Application Team
+ * @brief SMARTCARD HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the SMARTCARD peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ * + Peripheral State and Errors functions
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The SMARTCARD HAL driver can be used as follows:
+
+ (#) Declare a SMARTCARD_HandleTypeDef handle structure.
+ (#) Initialize the SMARTCARD low level resources by implementing the HAL_SMARTCARD_MspInit() API:
+ (##) Enable the USARTx interface clock.
+ (##) SMARTCARD pins configuration:
+ (+++) Enable the clock for the SMARTCARD GPIOs.
+ (+++) Configure the SMARTCARD pins as alternate function pull-up.
+ (##) NVIC configuration if you need to use interrupt process (HAL_SMARTCARD_Transmit_IT()
+ and HAL_SMARTCARD_Receive_IT() APIs):
+ (+++) Configure the USARTx interrupt priority.
+ (+++) Enable the NVIC USART IRQ handle.
+ (##) DMA Configuration if you need to use DMA process (HAL_SMARTCARD_Transmit_DMA()
+ and HAL_SMARTCARD_Receive_DMA() APIs):
+ (+++) Declare a DMA handle structure for the Tx/Rx channel.
+ (+++) Enable the DMAx interface clock.
+ (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
+ (+++) Configure the DMA Tx/Rx channel.
+ (+++) Associate the initialized DMA handle to the SMARTCARD DMA Tx/Rx handle.
+ (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
+ (+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
+ (used for last byte sending completion detection in DMA non circular mode)
+
+ (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
+ flow control and Mode(Receiver/Transmitter) in the SMARTCARD Init structure.
+
+ (#) Initialize the SMARTCARD registers by calling the HAL_SMARTCARD_Init() API:
+ (++) These APIs configure also the low level Hardware GPIO, CLOCK, CORTEX...etc)
+ by calling the customized HAL_SMARTCARD_MspInit() API.
+ [..]
+ (@)The specific SMARTCARD interrupts (Transmission complete interrupt,
+ RXNE interrupt and Error Interrupts) will be managed using the macros
+ __HAL_SMARTCARD_ENABLE_IT() and __HAL_SMARTCARD_DISABLE_IT() inside the transmit and receive process.
+
+ [..]
+ Three operation modes are available within this driver:
+
+ *** Polling mode IO operation ***
+ =================================
+ [..]
+ (+) Send an amount of data in blocking mode using HAL_SMARTCARD_Transmit()
+ (+) Receive an amount of data in blocking mode using HAL_SMARTCARD_Receive()
+ *** Interrupt mode IO operation ***
+ ===================================
+ [..]
+ (+) Send an amount of data in non blocking mode using HAL_SMARTCARD_Transmit_IT()
+ (+) At transmission end of transfer HAL_SMARTCARD_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_SMARTCARD_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode using HAL_SMARTCARD_Receive_IT()
+ (+) At reception end of transfer HAL_SMARTCARD_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_SMARTCARD_RxCpltCallback
+ (+) In case of transfer Error, HAL_SMARTCARD_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_SMARTCARD_ErrorCallback
+
+ *** DMA mode IO operation ***
+ ==============================
+ [..]
+ (+) Send an amount of data in non blocking mode (DMA) using HAL_SMARTCARD_Transmit_DMA()
+ (+) At transmission end of transfer HAL_SMARTCARD_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_SMARTCARD_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode (DMA) using HAL_SMARTCARD_Receive_DMA()
+ (+) At reception end of transfer HAL_SMARTCARD_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_SMARTCARD_RxCpltCallback
+ (+) In case of transfer Error, HAL_SMARTCARD_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_SMARTCARD_ErrorCallback
+
+ *** SMARTCARD HAL driver macros list ***
+ =============================================
+ [..]
+ Below the list of most used macros in SMARTCARD HAL driver.
+
+ (+) __HAL_SMARTCARD_ENABLE: Enable the SMARTCARD peripheral
+ (+) __HAL_SMARTCARD_DISABLE: Disable the SMARTCARD peripheral
+ (+) __HAL_SMARTCARD_GET_FLAG : Check whether the specified SMARTCARD flag is set or not
+ (+) __HAL_SMARTCARD_CLEAR_FLAG : Clear the specified SMARTCARD pending flag
+ (+) __HAL_SMARTCARD_ENABLE_IT: Enable the specified SMARTCARD interrupt
+ (+) __HAL_SMARTCARD_DISABLE_IT: Disable the specified SMARTCARD interrupt
+
+ [..]
+ (@) You can refer to the SMARTCARD HAL driver header file for more useful macros
+
+ @endverbatim
+ [..]
+ (@) Additionnal remark: If the parity is enabled, then the MSB bit of the data written
+ in the data register is transmitted but is changed by the parity bit.
+ Depending on the frame length defined by the M bit (8-bits or 9-bits),
+ the possible SMARTCARD frame formats are as listed in the following table:
+ +-------------------------------------------------------------+
+ | M bit | PCE bit | SMARTCARD frame |
+ |---------------------|---------------------------------------|
+ | 1 | 1 | | SB | 8 bit data | PB | STB | |
+ +-------------------------------------------------------------+
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup SMARTCARD SMARTCARD
+ * @brief HAL SMARTCARD module driver
+ * @{
+ */
+#ifdef HAL_SMARTCARD_MODULE_ENABLED
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @addtogroup SMARTCARD_Private_Constants
+ * @{
+ */
+/**
+ * @}
+ */
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @addtogroup SMARTCARD_Private_Functions
+ * @{
+ */
+static void SMARTCARD_EndTxTransfer(SMARTCARD_HandleTypeDef *hsc);
+static void SMARTCARD_EndRxTransfer(SMARTCARD_HandleTypeDef *hsc);
+static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc);
+static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc);
+static HAL_StatusTypeDef SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard);
+static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc);
+static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma);
+static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
+static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma);
+static void SMARTCARD_DMAAbortOnError(DMA_HandleTypeDef *hdma);
+static void SMARTCARD_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
+static void SMARTCARD_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
+static void SMARTCARD_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
+static void SMARTCARD_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
+static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout);
+/**
+ * @}
+ */
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup SMARTCARD_Exported_Functions SMARTCARD Exported Functions
+ * @{
+ */
+
+/** @defgroup SMARTCARD_Exported_Functions_Group1 SmartCard Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and Configuration functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to initialize the USART
+ in Smartcard mode.
+ [..]
+ The Smartcard interface is designed to support asynchronous protocol Smartcards as
+ defined in the ISO 7816-3 standard.
+ [..]
+ The USART can provide a clock to the smartcard through the SCLK output.
+ In smartcard mode, SCLK is not associated to the communication but is simply derived
+ from the internal peripheral input clock through a 5-bit prescaler.
+ [..]
+ (+) For the Smartcard mode only these parameters can be configured:
+ (++) Baud Rate
+ (++) Word Length => Should be 9 bits (8 bits + parity)
+ (++) Stop Bit
+ (++) Parity: => Should be enabled
+ (++) USART polarity
+ (++) USART phase
+ (++) USART LastBit
+ (++) Receiver/transmitter modes
+ (++) Prescaler
+ (++) GuardTime
+ (++) NACKState: The Smartcard NACK state
+
+ (+) Recommended SmartCard interface configuration to get the Answer to Reset from the Card:
+ (++) Word Length = 9 Bits
+ (++) 1.5 Stop Bit
+ (++) Even parity
+ (++) BaudRate = 12096 baud
+ (++) Tx and Rx enabled
+ [..]
+ Please refer to the ISO 7816-3 specification for more details.
+
+ [..]
+ (@) It is also possible to choose 0.5 stop bit for receiving but it is recommended
+ to use 1.5 stop bits for both transmitting and receiving to avoid switching
+ between the two configurations.
+ [..]
+ The HAL_SMARTCARD_Init() function follows the USART SmartCard configuration
+ procedure (details for the procedure are available in reference manual (RM0329)).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the SmartCard mode according to the specified
+ * parameters in the SMARTCARD_InitTypeDef and create the associated handle.
+ * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for SMARTCARD module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* Check the SMARTCARD handle allocation */
+ if (hsc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
+
+
+ if (hsc->gState == HAL_SMARTCARD_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hsc->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
+ HAL_SMARTCARD_MspInit(hsc);
+ }
+
+ hsc->gState = HAL_SMARTCARD_STATE_BUSY;
+
+ /* Set the Prescaler */
+ MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_PSC, hsc->Init.Prescaler);
+
+ /* Set the Guard Time */
+ MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_GT, ((hsc->Init.GuardTime) << 8U));
+
+ /* Set the Smartcard Communication parameters */
+ SMARTCARD_SetConfig(hsc);
+
+ /* In SmartCard mode, the following bits must be kept cleared:
+ - LINEN bit in the USART_CR2 register
+ - HDSEL and IREN bits in the USART_CR3 register.*/
+ CLEAR_BIT(hsc->Instance->CR2, USART_CR2_LINEN);
+ CLEAR_BIT(hsc->Instance->CR3, (USART_CR3_IREN | USART_CR3_HDSEL));
+
+ /* Enable the SMARTCARD Parity Error Interrupt */
+ SET_BIT(hsc->Instance->CR1, USART_CR1_PEIE);
+
+ /* Enable the SMARTCARD Framing Error Interrupt */
+ SET_BIT(hsc->Instance->CR3, USART_CR3_EIE);
+
+ /* Enable the Peripheral */
+ __HAL_SMARTCARD_ENABLE(hsc);
+
+ /* Configure the Smartcard NACK state */
+ MODIFY_REG(hsc->Instance->CR3, USART_CR3_NACK, hsc->Init.NACKState);
+
+ /* Enable the SC mode by setting the SCEN bit in the CR3 register */
+ hsc->Instance->CR3 |= (USART_CR3_SCEN);
+
+ /* Initialize the SMARTCARD state*/
+ hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
+ hsc->gState = HAL_SMARTCARD_STATE_READY;
+ hsc->RxState = HAL_SMARTCARD_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the USART SmartCard peripheral
+ * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for SMARTCARD module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* Check the SMARTCARD handle allocation */
+ if (hsc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
+
+ hsc->gState = HAL_SMARTCARD_STATE_BUSY;
+
+ /* DeInit the low level hardware */
+ HAL_SMARTCARD_MspDeInit(hsc);
+
+ hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
+ hsc->gState = HAL_SMARTCARD_STATE_RESET;
+ hsc->RxState = HAL_SMARTCARD_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hsc);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief SMARTCARD MSP Init.
+ * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for SMARTCARD module.
+ * @retval None
+ */
+__weak void HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsc);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_SMARTCARD_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief SMARTCARD MSP DeInit
+ * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for SMARTCARD module.
+ * @retval None
+ */
+__weak void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsc);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_SMARTCARD_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SMARTCARD_Exported_Functions_Group2 IO operation functions
+ * @brief SMARTCARD Transmit and Receive functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the SMARTCARD data transfers.
+
+ [..]
+ (#) Smartcard is a single wire half duplex communication protocol.
+ The Smartcard interface is designed to support asynchronous protocol Smartcards as
+ defined in the ISO 7816-3 standard.
+ (#) The USART should be configured as:
+ (++) 8 bits plus parity: where M=1 and PCE=1 in the USART_CR1 register
+ (++) 1.5 stop bits when transmitting and receiving: where STOP=11 in the USART_CR2 register.
+
+ (#) There are two modes of transfer:
+ (++) Blocking mode: The communication is performed in polling mode.
+ The HAL status of all data processing is returned by the same function
+ after finishing transfer.
+ (++) Non Blocking mode: The communication is performed using Interrupts
+ or DMA, These APIs return the HAL status.
+ The end of the data processing will be indicated through the
+ dedicated SMARTCARD IRQ when using Interrupt mode or the DMA IRQ when
+ using DMA mode.
+ The HAL_SMARTCARD_TxCpltCallback(), HAL_SMARTCARD_RxCpltCallback() user callbacks
+ will be executed respectively at the end of the Transmit or Receive process
+ The HAL_SMARTCARD_ErrorCallback() user callback will be executed when a communication error is detected
+
+ (#) Blocking mode APIs are :
+ (++) HAL_SMARTCARD_Transmit()
+ (++) HAL_SMARTCARD_Receive()
+
+ (#) Non Blocking mode APIs with Interrupt are :
+ (++) HAL_SMARTCARD_Transmit_IT()
+ (++) HAL_SMARTCARD_Receive_IT()
+ (++) HAL_SMARTCARD_IRQHandler()
+
+ (#) Non Blocking mode functions with DMA are :
+ (++) HAL_SMARTCARD_Transmit_DMA()
+ (++) HAL_SMARTCARD_Receive_DMA()
+
+ (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
+ (++) HAL_SMARTCARD_TxCpltCallback()
+ (++) HAL_SMARTCARD_RxCpltCallback()
+ (++) HAL_SMARTCARD_ErrorCallback()
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Send an amount of data in blocking mode
+ * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for SMARTCARD module.
+ * @param pData: pointer to data buffer
+ * @param Size: amount of data to be sent
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ uint32_t tickstart = 0U;
+
+ if (hsc->gState == HAL_SMARTCARD_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hsc);
+
+ hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
+ hsc->gState = HAL_SMARTCARD_STATE_BUSY_TX;
+
+ /* Init tickstart for timeout managment */
+ tickstart = HAL_GetTick();
+
+ hsc->TxXferSize = Size;
+ hsc->TxXferCount = Size;
+ while (hsc->TxXferCount > 0U)
+ {
+ hsc->TxXferCount--;
+ if (SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ hsc->Instance->DR = *(uint8_t *) pData;
+ pData += 1U;
+ }
+
+ if (SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+
+ /* At end of Tx process, restore hsc->gState to Ready */
+ hsc->gState = HAL_SMARTCARD_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hsc);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive an amount of data in blocking mode
+ * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for SMARTCARD module.
+ * @param pData: pointer to data buffer
+ * @param Size: amount of data to be received
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ uint32_t tickstart = 0U;
+
+ if (hsc->RxState == HAL_SMARTCARD_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hsc);
+
+ hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
+ hsc->RxState = HAL_SMARTCARD_STATE_BUSY_RX;
+
+ /* Init tickstart for timeout managment */
+ tickstart = HAL_GetTick();
+
+ hsc->RxXferSize = Size;
+ hsc->RxXferCount = Size;
+
+ /* Check the remain data to be received */
+ while (hsc->RxXferCount > 0U)
+ {
+ hsc->RxXferCount--;
+ if (SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ *(uint8_t *) pData = (uint8_t)hsc->Instance->DR;
+ pData += 1U;
+ }
+
+ /* At end of Rx process, restore hsc->RxState to Ready */
+ hsc->RxState = HAL_SMARTCARD_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hsc);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Send an amount of data in non blocking mode
+ * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for SMARTCARD module.
+ * @param pData: pointer to data buffer
+ * @param Size: amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
+{
+ /* Check that a Tx process is not already ongoing */
+ if (hsc->gState == HAL_SMARTCARD_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+ /* Process Locked */
+ __HAL_LOCK(hsc);
+
+ hsc->pTxBuffPtr = pData;
+ hsc->TxXferSize = Size;
+ hsc->TxXferCount = Size;
+
+ hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
+ hsc->gState = HAL_SMARTCARD_STATE_BUSY_TX;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hsc);
+
+ /* Enable the SMARTCARD Parity Error Interrupt */
+ SET_BIT(hsc->Instance->CR1, USART_CR1_PEIE);
+
+ /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
+
+ /* Enable the SMARTCARD Transmit data register empty Interrupt */
+ SET_BIT(hsc->Instance->CR1, USART_CR1_TXEIE);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive an amount of data in non blocking mode
+ * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for SMARTCARD module.
+ * @param pData: pointer to data buffer
+ * @param Size: amount of data to be received
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
+{
+ /* Check that a Rx process is not already ongoing */
+ if (hsc->RxState == HAL_SMARTCARD_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hsc);
+
+ hsc->pRxBuffPtr = pData;
+ hsc->RxXferSize = Size;
+ hsc->RxXferCount = Size;
+
+ hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
+ hsc->RxState = HAL_SMARTCARD_STATE_BUSY_RX;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hsc);
+
+ /* Enable the SMARTCARD Parity Error and Data Register not empty Interrupts */
+ SET_BIT(hsc->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
+
+ /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
+ SET_BIT(hsc->Instance->CR3, USART_CR3_EIE);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Send an amount of data in non blocking mode
+ * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for SMARTCARD module.
+ * @param pData: pointer to data buffer
+ * @param Size: amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
+{
+ uint32_t *tmp;
+
+ /* Check that a Tx process is not already ongoing */
+ if (hsc->gState == HAL_SMARTCARD_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hsc);
+
+ hsc->pTxBuffPtr = pData;
+ hsc->TxXferSize = Size;
+ hsc->TxXferCount = Size;
+
+ hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
+ hsc->gState = HAL_SMARTCARD_STATE_BUSY_TX;
+
+ /* Set the SMARTCARD DMA transfer complete callback */
+ hsc->hdmatx->XferCpltCallback = SMARTCARD_DMATransmitCplt;
+
+ /* Set the DMA error callback */
+ hsc->hdmatx->XferErrorCallback = SMARTCARD_DMAError;
+
+ /* Set the DMA abort callback */
+ hsc->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the SMARTCARD transmit DMA Channel */
+ tmp = (uint32_t *)&pData;
+ HAL_DMA_Start_IT(hsc->hdmatx, *(uint32_t *)tmp, (uint32_t)&hsc->Instance->DR, Size);
+
+ /* Clear the TC flag in the SR register by writing 0 to it */
+ __HAL_SMARTCARD_CLEAR_FLAG(hsc, SMARTCARD_FLAG_TC);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hsc);
+
+ /* Enable the DMA transfer for transmit request by setting the DMAT bit
+ in the SMARTCARD CR3 register */
+ SET_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive an amount of data in non blocking mode
+ * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for SMARTCARD module.
+ * @param pData: pointer to data buffer
+ * @param Size: amount of data to be received
+ * @note When the SMARTCARD parity is enabled (PCE = 1) the data received contain the parity bit.s
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
+{
+ uint32_t *tmp;
+
+ /* Check that a Rx process is not already ongoing */
+ if (hsc->RxState == HAL_SMARTCARD_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hsc);
+
+ hsc->pRxBuffPtr = pData;
+ hsc->RxXferSize = Size;
+
+ hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
+ hsc->RxState = HAL_SMARTCARD_STATE_BUSY_RX;
+
+ /* Set the SMARTCARD DMA transfer complete callback */
+ hsc->hdmarx->XferCpltCallback = SMARTCARD_DMAReceiveCplt;
+
+ /* Set the DMA error callback */
+ hsc->hdmarx->XferErrorCallback = SMARTCARD_DMAError;
+
+ /* Set the DMA abort callback */
+ hsc->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the DMA Channel */
+ tmp = (uint32_t *)&pData;
+ HAL_DMA_Start_IT(hsc->hdmarx, (uint32_t)&hsc->Instance->DR, *(uint32_t *)tmp, Size);
+
+ /* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */
+ __HAL_SMARTCARD_CLEAR_OREFLAG(hsc);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hsc);
+
+ /* Enable the SMARTCARD Parity Error Interrupt */
+ SET_BIT(hsc->Instance->CR1, USART_CR1_PEIE);
+
+ /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
+ SET_BIT(hsc->Instance->CR3, USART_CR3_EIE);
+
+ /* Enable the DMA transfer for the receiver request by setting the DMAR bit
+ in the SMARTCARD CR3 register */
+ SET_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Abort ongoing transfers (blocking mode).
+ * @param hsc SMARTCARD handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_SMARTCARD_Abort(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the SMARTCARD DMA Tx request if enabled */
+ if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT))
+ {
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the SMARTCARD DMA Tx channel: use blocking DMA Abort API (no callback) */
+ if (hsc->hdmatx != NULL)
+ {
+ /* Set the SMARTCARD DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ hsc->hdmatx->XferAbortCallback = NULL;
+
+ HAL_DMA_Abort(hsc->hdmatx);
+ }
+ }
+
+ /* Disable the SMARTCARD DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the SMARTCARD DMA Rx channel: use blocking DMA Abort API (no callback) */
+ if (hsc->hdmarx != NULL)
+ {
+ /* Set the SMARTCARD DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ hsc->hdmarx->XferAbortCallback = NULL;
+
+ HAL_DMA_Abort(hsc->hdmarx);
+ }
+ }
+
+ /* Reset Tx and Rx transfer counters */
+ hsc->TxXferCount = 0x00U;
+ hsc->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
+
+ /* Restore hsc->RxState and hsc->gState to Ready */
+ hsc->RxState = HAL_SMARTCARD_STATE_READY;
+ hsc->gState = HAL_SMARTCARD_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Transmit transfer (blocking mode).
+ * @param hsc SMARTCARD handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* Disable TXEIE and TCIE interrupts */
+ CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+
+ /* Disable the SMARTCARD DMA Tx request if enabled */
+ if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT))
+ {
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the SMARTCARD DMA Tx channel: use blocking DMA Abort API (no callback) */
+ if (hsc->hdmatx != NULL)
+ {
+ /* Set the SMARTCARD DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ hsc->hdmatx->XferAbortCallback = NULL;
+
+ HAL_DMA_Abort(hsc->hdmatx);
+ }
+ }
+
+ /* Reset Tx transfer counter */
+ hsc->TxXferCount = 0x00U;
+
+ /* Restore hsc->gState to Ready */
+ hsc->gState = HAL_SMARTCARD_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Receive transfer (blocking mode).
+ * @param hsc SMARTCARD handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the SMARTCARD DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the SMARTCARD DMA Rx channel: use blocking DMA Abort API (no callback) */
+ if (hsc->hdmarx != NULL)
+ {
+ /* Set the SMARTCARD DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ hsc->hdmarx->XferAbortCallback = NULL;
+
+ HAL_DMA_Abort(hsc->hdmarx);
+ }
+ }
+
+ /* Reset Rx transfer counter */
+ hsc->RxXferCount = 0x00U;
+
+ /* Restore hsc->RxState to Ready */
+ hsc->RxState = HAL_SMARTCARD_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing transfers (Interrupt mode).
+ * @param hsc SMARTCARD handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_SMARTCARD_Abort_IT(SMARTCARD_HandleTypeDef *hsc)
+{
+ uint32_t AbortCplt = 0x01U;
+
+ /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
+
+ /* If DMA Tx and/or DMA Rx Handles are associated to SMARTCARD Handle, DMA Abort complete callbacks should be initialised
+ before any call to DMA Abort functions */
+ /* DMA Tx Handle is valid */
+ if (hsc->hdmatx != NULL)
+ {
+ /* Set DMA Abort Complete callback if SMARTCARD DMA Tx request if enabled.
+ Otherwise, set it to NULL */
+ if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT))
+ {
+ hsc->hdmatx->XferAbortCallback = SMARTCARD_DMATxAbortCallback;
+ }
+ else
+ {
+ hsc->hdmatx->XferAbortCallback = NULL;
+ }
+ }
+ /* DMA Rx Handle is valid */
+ if (hsc->hdmarx != NULL)
+ {
+ /* Set DMA Abort Complete callback if SMARTCARD DMA Rx request if enabled.
+ Otherwise, set it to NULL */
+ if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
+ {
+ hsc->hdmarx->XferAbortCallback = SMARTCARD_DMARxAbortCallback;
+ }
+ else
+ {
+ hsc->hdmarx->XferAbortCallback = NULL;
+ }
+ }
+
+ /* Disable the SMARTCARD DMA Tx request if enabled */
+ if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT))
+ {
+ /* Disable DMA Tx at SMARTCARD level */
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the SMARTCARD DMA Tx channel : use non blocking DMA Abort API (callback) */
+ if (hsc->hdmatx != NULL)
+ {
+ /* SMARTCARD Tx DMA Abort callback has already been initialised :
+ will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */
+
+ /* Abort DMA TX */
+ if (HAL_DMA_Abort_IT(hsc->hdmatx) != HAL_OK)
+ {
+ hsc->hdmatx->XferAbortCallback = NULL;
+ }
+ else
+ {
+ AbortCplt = 0x00U;
+ }
+ }
+ }
+
+ /* Disable the SMARTCARD DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the SMARTCARD DMA Rx channel : use non blocking DMA Abort API (callback) */
+ if (hsc->hdmarx != NULL)
+ {
+ /* SMARTCARD Rx DMA Abort callback has already been initialised :
+ will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */
+
+ /* Abort DMA RX */
+ if (HAL_DMA_Abort_IT(hsc->hdmarx) != HAL_OK)
+ {
+ hsc->hdmarx->XferAbortCallback = NULL;
+ AbortCplt = 0x01U;
+ }
+ else
+ {
+ AbortCplt = 0x00U;
+ }
+ }
+ }
+
+ /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
+ if (AbortCplt == 0x01U)
+ {
+ /* Reset Tx and Rx transfer counters */
+ hsc->TxXferCount = 0x00U;
+ hsc->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
+
+ /* Restore hsc->gState and hsc->RxState to Ready */
+ hsc->gState = HAL_SMARTCARD_STATE_READY;
+ hsc->RxState = HAL_SMARTCARD_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+ HAL_SMARTCARD_AbortCpltCallback(hsc);
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Transmit transfer (Interrupt mode).
+ * @param hsc SMARTCARD handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit_IT(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* Disable TXEIE and TCIE interrupts */
+ CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+
+ /* Disable the SMARTCARD DMA Tx request if enabled */
+ if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT))
+ {
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the SMARTCARD DMA Tx channel : use blocking DMA Abort API (no callback) */
+ if (hsc->hdmatx != NULL)
+ {
+ /* Set the SMARTCARD DMA Abort callback :
+ will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */
+ hsc->hdmatx->XferAbortCallback = SMARTCARD_DMATxOnlyAbortCallback;
+
+ /* Abort DMA TX */
+ if (HAL_DMA_Abort_IT(hsc->hdmatx) != HAL_OK)
+ {
+ /* Call Directly hsc->hdmatx->XferAbortCallback function in case of error */
+ hsc->hdmatx->XferAbortCallback(hsc->hdmatx);
+ }
+ }
+ else
+ {
+ /* Reset Tx transfer counter */
+ hsc->TxXferCount = 0x00U;
+
+ /* Restore hsc->gState to Ready */
+ hsc->gState = HAL_SMARTCARD_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+ HAL_SMARTCARD_AbortTransmitCpltCallback(hsc);
+ }
+ }
+ else
+ {
+ /* Reset Tx transfer counter */
+ hsc->TxXferCount = 0x00U;
+
+ /* Restore hsc->gState to Ready */
+ hsc->gState = HAL_SMARTCARD_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+ HAL_SMARTCARD_AbortTransmitCpltCallback(hsc);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Receive transfer (Interrupt mode).
+ * @param hsc SMARTCARD handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive_IT(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the SMARTCARD DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the SMARTCARD DMA Rx channel : use blocking DMA Abort API (no callback) */
+ if (hsc->hdmarx != NULL)
+ {
+ /* Set the SMARTCARD DMA Abort callback :
+ will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */
+ hsc->hdmarx->XferAbortCallback = SMARTCARD_DMARxOnlyAbortCallback;
+
+ /* Abort DMA RX */
+ if (HAL_DMA_Abort_IT(hsc->hdmarx) != HAL_OK)
+ {
+ /* Call Directly hsc->hdmarx->XferAbortCallback function in case of error */
+ hsc->hdmarx->XferAbortCallback(hsc->hdmarx);
+ }
+ }
+ else
+ {
+ /* Reset Rx transfer counter */
+ hsc->RxXferCount = 0x00U;
+
+ /* Restore hsc->RxState to Ready */
+ hsc->RxState = HAL_SMARTCARD_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+ HAL_SMARTCARD_AbortReceiveCpltCallback(hsc);
+ }
+ }
+ else
+ {
+ /* Reset Rx transfer counter */
+ hsc->RxXferCount = 0x00U;
+
+ /* Restore hsc->RxState to Ready */
+ hsc->RxState = HAL_SMARTCARD_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+ HAL_SMARTCARD_AbortReceiveCpltCallback(hsc);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles SMARTCARD interrupt request.
+ * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for SMARTCARD module.
+ * @retval None
+ */
+void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc)
+{
+ uint32_t isrflags = READ_REG(hsc->Instance->SR);
+ uint32_t cr1its = READ_REG(hsc->Instance->CR1);
+ uint32_t cr3its = READ_REG(hsc->Instance->CR3);
+ uint32_t dmarequest = 0x00U;
+ uint32_t errorflags = 0x00U;
+
+ /* If no error occurs */
+ errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
+ if (errorflags == RESET)
+ {
+ /* SMARTCARD in mode Receiver -------------------------------------------------*/
+ if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
+ {
+ SMARTCARD_Receive_IT(hsc);
+ return;
+ }
+ }
+
+ /* If some errors occur */
+ if ((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
+ {
+ /* SMARTCARD parity error interrupt occurred ---------------------------*/
+ if (((isrflags & SMARTCARD_FLAG_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
+ {
+ hsc->ErrorCode |= HAL_SMARTCARD_ERROR_PE;
+ }
+
+ /* SMARTCARD noise error interrupt occurred ----------------------------*/
+ if (((isrflags & SMARTCARD_FLAG_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
+ {
+ hsc->ErrorCode |= HAL_SMARTCARD_ERROR_NE;
+ }
+
+ /* SMARTCARD frame error interrupt occurred ----------------------------*/
+ if (((isrflags & SMARTCARD_FLAG_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
+ {
+ hsc->ErrorCode |= HAL_SMARTCARD_ERROR_FE;
+ }
+
+ /* SMARTCARD Over-Run interrupt occurred -------------------------------*/
+ if (((isrflags & SMARTCARD_FLAG_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
+ {
+ hsc->ErrorCode |= HAL_SMARTCARD_ERROR_ORE;
+ }
+
+ /* Call SMARTCARD Error Call back function if need be ------------------*/
+ if (hsc->ErrorCode != HAL_SMARTCARD_ERROR_NONE)
+ {
+ /* SMARTCARD in mode Receiver ----------------------------------------*/
+ if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
+ {
+ SMARTCARD_Receive_IT(hsc);
+ }
+
+ /* If Overrun error occurs, or if any error occurs in DMA mode reception,
+ consider error as blocking */
+ dmarequest = HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR);
+ if (((hsc->ErrorCode & HAL_SMARTCARD_ERROR_ORE) != RESET) || dmarequest)
+ {
+ /* Blocking error : transfer is aborted
+ Set the SMARTCARD state ready to be able to start again the process,
+ Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
+ SMARTCARD_EndRxTransfer(hsc);
+
+ /* Disable the SMARTCARD DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the SMARTCARD DMA Rx channel */
+ if (hsc->hdmarx != NULL)
+ {
+ /* Set the SMARTCARD DMA Abort callback :
+ will lead to call HAL_SMARTCARD_ErrorCallback() at end of DMA abort procedure */
+ hsc->hdmarx->XferAbortCallback = SMARTCARD_DMAAbortOnError;
+ if (HAL_DMA_Abort_IT(hsc->hdmarx) != HAL_OK)
+ {
+ /* Call Directly XferAbortCallback function in case of error */
+ hsc->hdmarx->XferAbortCallback(hsc->hdmarx);
+ }
+ }
+ else
+ {
+ /* Call user error callback */
+ HAL_SMARTCARD_ErrorCallback(hsc);
+ }
+ }
+ else
+ {
+ /* Call user error callback */
+ HAL_SMARTCARD_ErrorCallback(hsc);
+ }
+ }
+ else
+ {
+ /* Non Blocking error : transfer could go on.
+ Error is notified to user through user error callback */
+ HAL_SMARTCARD_ErrorCallback(hsc);
+ hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
+ }
+ }
+ return;
+ } /* End if some error occurs */
+
+ /* SMARTCARD in mode Transmitter -------------------------------------------*/
+ if (((isrflags & SMARTCARD_FLAG_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
+ {
+ SMARTCARD_Transmit_IT(hsc);
+ return;
+ }
+
+ /* SMARTCARD in mode Transmitter (transmission end) ------------------------*/
+ if (((isrflags & SMARTCARD_FLAG_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
+ {
+ SMARTCARD_EndTransmit_IT(hsc);
+ return;
+ }
+}
+
+/**
+ * @brief Tx Transfer completed callbacks
+ * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for SMARTCARD module.
+ * @retval None
+ */
+__weak void HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsc);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SMARTCARD_TxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer completed callbacks
+ * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for SMARTCARD module.
+ * @retval None
+ */
+__weak void HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsc);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SMARTCARD_RxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief SMARTCARD error callbacks
+ * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for SMARTCARD module.
+ * @retval None
+ */
+__weak void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsc);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SMARTCARD_ErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief SMARTCARD Abort Complete callback.
+ * @param hsc SMARTCARD handle.
+ * @retval None
+ */
+__weak void HAL_SMARTCARD_AbortCpltCallback(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsc);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SMARTCARD_AbortCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @brief SMARTCARD Abort Transmit Complete callback.
+ * @param hsc SMARTCARD handle.
+ * @retval None
+ */
+__weak void HAL_SMARTCARD_AbortTransmitCpltCallback(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsc);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SMARTCARD_AbortTransmitCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @brief SMARTCARD Abort ReceiveComplete callback.
+ * @param hsc SMARTCARD handle.
+ * @retval None
+ */
+__weak void HAL_SMARTCARD_AbortReceiveCpltCallback(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsc);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SMARTCARD_AbortReceiveCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SMARTCARD_Exported_Functions_Group3 Peripheral State and Errors functions
+ * @brief SMARTCARD State and Errors functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral State and Errors functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the SmartCard.
+ (+) HAL_SMARTCARD_GetState() API can be helpful to check in run-time the state of the SmartCard peripheral.
+ (+) HAL_SMARTCARD_GetError() check in run-time errors that could be occurred during communication.
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief return the SMARTCARD state
+ * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for SMARTCARD module.
+ * @retval HAL state
+ */
+HAL_SMARTCARD_StateTypeDef HAL_SMARTCARD_GetState(SMARTCARD_HandleTypeDef *hsc)
+{
+ uint32_t temp1 = 0x00U, temp2 = 0x00U;
+ temp1 = hsc->gState;
+ temp2 = hsc->RxState;
+
+ return (HAL_SMARTCARD_StateTypeDef)(temp1 | temp2);
+}
+
+/**
+ * @brief Return the SMARTCARD error code
+ * @param hsc : pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for the specified SMARTCARD.
+ * @retval SMARTCARD Error Code
+ */
+uint32_t HAL_SMARTCARD_GetError(SMARTCARD_HandleTypeDef *hsc)
+{
+ return hsc->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @brief DMA SMARTCARD transmit process complete callback
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma)
+{
+ SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ hsc->TxXferCount = 0U;
+
+ /* Disable the DMA transfer for transmit request by setting the DMAT bit
+ in the USART CR3 register */
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
+
+ /* Enable the SMARTCARD Transmit Complete Interrupt */
+ SET_BIT(hsc->Instance->CR1, USART_CR1_TCIE);
+}
+
+/**
+ * @brief DMA SMARTCARD receive process complete callback
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ hsc->RxXferCount = 0U;
+
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the DMA transfer for the receiver request by setting the DMAR bit
+ in the USART CR3 register */
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
+
+ /* At end of Rx process, restore hsc->RxState to Ready */
+ hsc->RxState = HAL_SMARTCARD_STATE_READY;
+
+ HAL_SMARTCARD_RxCpltCallback(hsc);
+}
+
+/**
+ * @brief DMA SMARTCARD communication error callback
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma)
+{
+ uint32_t dmarequest = 0x00U;
+ SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+ hsc->RxXferCount = 0U;
+ hsc->TxXferCount = 0U;
+ hsc->ErrorCode = HAL_SMARTCARD_ERROR_DMA;
+
+ /* Stop SMARTCARD DMA Tx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT);
+ if ((hsc->gState == HAL_SMARTCARD_STATE_BUSY_TX) && dmarequest)
+ {
+ SMARTCARD_EndTxTransfer(hsc);
+ }
+
+ /* Stop SMARTCARD DMA Rx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR);
+ if ((hsc->RxState == HAL_SMARTCARD_STATE_BUSY_RX) && dmarequest)
+ {
+ SMARTCARD_EndRxTransfer(hsc);
+ }
+
+ HAL_SMARTCARD_ErrorCallback(hsc);
+}
+
+/**
+ * @brief This function handles SMARTCARD Communication Timeout.
+ * @param hsc: SMARTCARD handle
+ * @param Flag: specifies the SMARTCARD flag to check.
+ * @param Status: The new Flag status (SET or RESET).
+ * @param Timeout: Timeout duration
+ * @param Tickstart: tick start value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
+{
+ /* Wait until flag is set */
+ while ((__HAL_SMARTCARD_GET_FLAG(hsc, Flag) ? SET : RESET) == Status)
+ {
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
+ {
+ /* Disable TXE and RXNE interrupts for the interrupt process */
+ CLEAR_BIT(hsc->Instance->CR1, USART_CR1_TXEIE);
+ CLEAR_BIT(hsc->Instance->CR1, USART_CR1_RXNEIE);
+
+ hsc->gState = HAL_SMARTCARD_STATE_READY;
+ hsc->RxState = HAL_SMARTCARD_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hsc);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief End ongoing Tx transfer on SMARTCARD peripheral (following error detection or Transmit completion).
+ * @param hsc: SMARTCARD handle.
+ * @retval None
+ */
+static void SMARTCARD_EndTxTransfer(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* At end of Tx process, restore hsc->gState to Ready */
+ hsc->gState = HAL_SMARTCARD_STATE_READY;
+
+ /* Disable TXEIE and TCIE interrupts */
+ CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+}
+
+
+/**
+ * @brief End ongoing Rx transfer on SMARTCARD peripheral (following error detection or Reception completion).
+ * @param hsc: SMARTCARD handle.
+ * @retval None
+ */
+static void SMARTCARD_EndRxTransfer(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* At end of Rx process, restore hsc->RxState to Ready */
+ hsc->RxState = HAL_SMARTCARD_STATE_READY;
+
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
+}
+
+
+
+/**
+ * @brief DMA SMARTCARD communication abort callback, when initiated by HAL services on Error
+ * (To be called at end of DMA Abort procedure following error occurrence).
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void SMARTCARD_DMAAbortOnError(DMA_HandleTypeDef *hdma)
+{
+ SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+ hsc->RxXferCount = 0x00U;
+ hsc->TxXferCount = 0x00U;
+
+ HAL_SMARTCARD_ErrorCallback(hsc);
+}
+
+/**
+ * @brief DMA SMARTCARD Tx communication abort callback, when initiated by user
+ * (To be called at end of DMA Tx Abort procedure following user abort request).
+ * @note When this callback is executed, User Abort complete call back is called only if no
+ * Abort still ongoing for Rx DMA Handle.
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void SMARTCARD_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ hsc->hdmatx->XferAbortCallback = NULL;
+
+ /* Check if an Abort process is still ongoing */
+ if (hsc->hdmarx != NULL)
+ {
+ if (hsc->hdmarx->XferAbortCallback != NULL)
+ {
+ return;
+ }
+ }
+
+ /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+ hsc->TxXferCount = 0x00U;
+ hsc->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
+
+ /* Restore hsc->gState and hsc->RxState to Ready */
+ hsc->gState = HAL_SMARTCARD_STATE_READY;
+ hsc->RxState = HAL_SMARTCARD_STATE_READY;
+
+ /* Call user Abort complete callback */
+ HAL_SMARTCARD_AbortCpltCallback(hsc);
+}
+
+/**
+ * @brief DMA SMARTCARD Rx communication abort callback, when initiated by user
+ * (To be called at end of DMA Rx Abort procedure following user abort request).
+ * @note When this callback is executed, User Abort complete call back is called only if no
+ * Abort still ongoing for Tx DMA Handle.
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void SMARTCARD_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ hsc->hdmarx->XferAbortCallback = NULL;
+
+ /* Check if an Abort process is still ongoing */
+ if (hsc->hdmatx != NULL)
+ {
+ if (hsc->hdmatx->XferAbortCallback != NULL)
+ {
+ return;
+ }
+ }
+
+ /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+ hsc->TxXferCount = 0x00U;
+ hsc->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
+
+ /* Restore hsc->gState and hsc->RxState to Ready */
+ hsc->gState = HAL_SMARTCARD_STATE_READY;
+ hsc->RxState = HAL_SMARTCARD_STATE_READY;
+
+ /* Call user Abort complete callback */
+ HAL_SMARTCARD_AbortCpltCallback(hsc);
+}
+
+/**
+ * @brief DMA SMARTCARD Tx communication abort callback, when initiated by user by a call to
+ * HAL_SMARTCARD_AbortTransmit_IT API (Abort only Tx transfer)
+ * (This callback is executed at end of DMA Tx Abort procedure following user abort request,
+ * and leads to user Tx Abort Complete callback execution).
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void SMARTCARD_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ hsc->TxXferCount = 0x00U;
+
+ /* Restore hsc->gState to Ready */
+ hsc->gState = HAL_SMARTCARD_STATE_READY;
+
+ /* Call user Abort complete callback */
+ HAL_SMARTCARD_AbortTransmitCpltCallback(hsc);
+}
+
+/**
+ * @brief DMA SMARTCARD Rx communication abort callback, when initiated by user by a call to
+ * HAL_SMARTCARD_AbortReceive_IT API (Abort only Rx transfer)
+ * (This callback is executed at end of DMA Rx Abort procedure following user abort request,
+ * and leads to user Rx Abort Complete callback execution).
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void SMARTCARD_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ hsc->RxXferCount = 0x00U;
+
+ /* Restore hsc->RxState to Ready */
+ hsc->RxState = HAL_SMARTCARD_STATE_READY;
+
+ /* Call user Abort complete callback */
+ HAL_SMARTCARD_AbortReceiveCpltCallback(hsc);
+}
+
+/**
+ * @brief Send an amount of data in non blocking mode
+ * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for SMARTCARD module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* Check that a Tx process is ongoing */
+ if (hsc->gState == HAL_SMARTCARD_STATE_BUSY_TX)
+ {
+ hsc->Instance->DR = *(uint8_t *) hsc->pTxBuffPtr;
+ hsc->pTxBuffPtr += 1U;
+
+ if (--hsc->TxXferCount == 0U)
+ {
+ /* Disable the SMARTCARD Transmit data register empty Interrupt */
+ CLEAR_BIT(hsc->Instance->CR1, USART_CR1_TXEIE);
+
+ /* Enable the SMARTCARD Transmit Complete Interrupt */
+ SET_BIT(hsc->Instance->CR1, USART_CR1_TCIE);
+ }
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Wraps up transmission in non blocking mode.
+ * @param hsmartcard: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for the specified SMARTCARD module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard)
+{
+ /* Disable the SMARTCARD Transmit Complete Interrupt */
+ CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_TCIE);
+
+ /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
+ CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE);
+
+ /* Tx process is ended, restore hsmartcard->gState to Ready */
+ hsmartcard->gState = HAL_SMARTCARD_STATE_READY;
+
+ HAL_SMARTCARD_TxCpltCallback(hsmartcard);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Receive an amount of data in non blocking mode
+ * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for SMARTCARD module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc)
+{
+ /* Check that a Rx process is ongoing */
+ if (hsc->RxState == HAL_SMARTCARD_STATE_BUSY_RX)
+ {
+ *(uint8_t *) hsc->pRxBuffPtr = (uint8_t)hsc->Instance->DR;
+ hsc->pRxBuffPtr += 1U;
+
+ if (--hsc->RxXferCount == 0U)
+ {
+ CLEAR_BIT(hsc->Instance->CR1, USART_CR1_RXNEIE);
+
+ /* Disable the SMARTCARD Parity Error Interrupt */
+ CLEAR_BIT(hsc->Instance->CR1, USART_CR1_PEIE);
+
+ /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
+ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
+
+ /* Rx process is completed, restore hsc->RxState to Ready */
+ hsc->RxState = HAL_SMARTCARD_STATE_READY;
+
+ HAL_SMARTCARD_RxCpltCallback(hsc);
+
+ return HAL_OK;
+ }
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Configure the SMARTCARD peripheral
+ * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
+ * the configuration information for SMARTCARD module.
+ * @retval None
+ */
+static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc)
+{
+ uint32_t tmpreg = 0x00U;
+
+ /* Check the parameters */
+ assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
+ assert_param(IS_SMARTCARD_POLARITY(hsc->Init.CLKPolarity));
+ assert_param(IS_SMARTCARD_PHASE(hsc->Init.CLKPhase));
+ assert_param(IS_SMARTCARD_LASTBIT(hsc->Init.CLKLastBit));
+ assert_param(IS_SMARTCARD_BAUDRATE(hsc->Init.BaudRate));
+ assert_param(IS_SMARTCARD_WORD_LENGTH(hsc->Init.WordLength));
+ assert_param(IS_SMARTCARD_STOPBITS(hsc->Init.StopBits));
+ assert_param(IS_SMARTCARD_PARITY(hsc->Init.Parity));
+ assert_param(IS_SMARTCARD_MODE(hsc->Init.Mode));
+ assert_param(IS_SMARTCARD_NACK_STATE(hsc->Init.NACKState));
+
+
+ /* The LBCL, CPOL and CPHA bits have to be selected when both the transmitter and the
+ receiver are disabled (TE=RE=0) to ensure that the clock pulses function correctly. */
+ CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
+
+ /*---------------------------- USART CR2 Configuration ---------------------*/
+ tmpreg = hsc->Instance->CR2;
+ /* Clear CLKEN, CPOL, CPHA and LBCL bits */
+ tmpreg &= (uint32_t)~((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_LBCL));
+ /* Configure the SMARTCARD Clock, CPOL, CPHA and LastBit -----------------------*/
+ /* Set CPOL bit according to hsc->Init.CLKPolarity value */
+ /* Set CPHA bit according to hsc->Init.CLKPhase value */
+ /* Set LBCL bit according to hsc->Init.CLKLastBit value */
+ /* Set Stop Bits: Set STOP[13:12] bits according to hsc->Init.StopBits value */
+ tmpreg |= (uint32_t)(USART_CR2_CLKEN | hsc->Init.CLKPolarity |
+ hsc->Init.CLKPhase | hsc->Init.CLKLastBit | hsc->Init.StopBits);
+ /* Write to USART CR2 */
+ WRITE_REG(hsc->Instance->CR2, (uint32_t)tmpreg);
+
+ tmpreg = hsc->Instance->CR2;
+
+ /* Clear STOP[13:12] bits */
+ tmpreg &= (uint32_t)~((uint32_t)USART_CR2_STOP);
+
+ /* Set Stop Bits: Set STOP[13:12] bits according to hsc->Init.StopBits value */
+ tmpreg |= (uint32_t)(hsc->Init.StopBits);
+
+ /* Write to USART CR2 */
+ WRITE_REG(hsc->Instance->CR2, (uint32_t)tmpreg);
+
+ /*-------------------------- USART CR1 Configuration -----------------------*/
+ tmpreg = hsc->Instance->CR1;
+
+ /* Clear M, PCE, PS, TE and RE bits */
+ tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \
+ USART_CR1_RE));
+
+ /* Configure the SMARTCARD Word Length, Parity and mode:
+ Set the M bits according to hsc->Init.WordLength value
+ Set PCE and PS bits according to hsc->Init.Parity value
+ Set TE and RE bits according to hsc->Init.Mode value */
+ tmpreg |= (uint32_t)hsc->Init.WordLength | hsc->Init.Parity | hsc->Init.Mode;
+
+ /* Write to USART CR1 */
+ WRITE_REG(hsc->Instance->CR1, (uint32_t)tmpreg);
+
+ /*-------------------------- USART CR3 Configuration -----------------------*/
+ /* Clear CTSE and RTSE bits */
+ CLEAR_BIT(hsc->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE));
+
+ /*-------------------------- USART BRR Configuration -----------------------*/
+
+ if (hsc->Instance == USART1)
+ {
+ hsc->Instance->BRR = SMARTCARD_BRR(HAL_RCC_GetPCLK2Freq(), hsc->Init.BaudRate);
+ }
+ else
+ {
+ hsc->Instance->BRR = SMARTCARD_BRR(HAL_RCC_GetPCLK1Freq(), hsc->Init.BaudRate);
+ }
+}
+
+/**
+ * @}
+ */
+
+#endif /* HAL_SMARTCARD_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c
new file mode 100644
index 0000000..af8e357
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c
@@ -0,0 +1,3264 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_spi.c
+ * @author MCD Application Team
+ * @brief SPI HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Serial Peripheral Interface (SPI) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ * + Peripheral State functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The SPI HAL driver can be used as follows:
+
+ (#) Declare a SPI_HandleTypeDef handle structure, for example:
+ SPI_HandleTypeDef hspi;
+
+ (#)Initialize the SPI low level resources by implementing the HAL_SPI_MspInit() API:
+ (##) Enable the SPIx interface clock
+ (##) SPI pins configuration
+ (+++) Enable the clock for the SPI GPIOs
+ (+++) Configure these SPI pins as alternate function push-pull
+ (##) NVIC configuration if you need to use interrupt process
+ (+++) Configure the SPIx interrupt priority
+ (+++) Enable the NVIC SPI IRQ handle
+ (##) DMA Configuration if you need to use DMA process
+ (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive Channel
+ (+++) Enable the DMAx clock
+ (+++) Configure the DMA handle parameters
+ (+++) Configure the DMA Tx or Rx Channel
+ (+++) Associate the initilalized hdma_tx(or _rx) handle to the hspi DMA Tx (or Rx) handle
+ (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx or Rx Channel
+
+ (#) Program the Mode, BidirectionalMode , Data size, Baudrate Prescaler, NSS
+ management, Clock polarity and phase, FirstBit and CRC configuration in the hspi Init structure.
+
+ (#) Initialize the SPI registers by calling the HAL_SPI_Init() API:
+ (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
+ by calling the customized HAL_SPI_MspInit() API.
+ [..]
+ Circular mode restriction:
+ (#) The DMA circular mode cannot be used when the SPI is configured in these modes:
+ (##) Master 2Lines RxOnly
+ (##) Master 1Line Rx
+ (#) The CRC feature is not managed when the DMA circular mode is enabled
+ (#) When the SPI DMA Pause/Stop features are used, we must use the following APIs
+ the HAL_SPI_DMAPause()/ HAL_SPI_DMAStop() only under the SPI callbacks
+ [..]
+ Master Receive mode restriction:
+ (#) In Master unidirectional receive-only mode (MSTR =1, BIDIMODE=0, RXONLY=0) or
+ bidirectional receive mode (MSTR=1, BIDIMODE=1, BIDIOE=0), to ensure that the SPI
+ does not initiate a new transfer the following procedure has to be respected:
+ (##) HAL_SPI_DeInit()
+ (##) HAL_SPI_Init()
+
+ @endverbatim
+
+ Using the HAL it is not possible to reach all supported SPI frequency with the differents SPI Modes,
+ the following tables resume the max SPI frequency reached with data size 8bits/16bits,
+ according to frequency used on APBx Peripheral Clock (fPCLK) used by the SPI instance :
+
+ DataSize = SPI_DATASIZE_8BIT:
+ +--------------------------------------------------------------------------------------------------+
+ | | | 2Lines Fullduplex | 2Lines RxOnly | 1Line |
+ | Process | Tranfert mode |-----------------------|-----------------------|-----------------------|
+ | | | Master | Slave | Master | Slave | Master | Slave |
+ |==================================================================================================|
+ | T | Polling | fPCLK/2 | fPCLK/16 | NA | NA | NA | NA |
+ | X |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
+ | / | Interrupt | fPCLK/8 | fPCLK/32 | NA | NA | NA | NA |
+ | R |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
+ | X | DMA | fPCLK/2 | fPCLK/4 | NA | NA | NA | NA |
+ |=========|================|===========|===========|===========|===========|===========|===========|
+ | | Polling | fPCLK/4 | fPCLK/8 | fPCLK/8 | fPCLK/16 | fPCLK/64 | fPCLK/2 |
+ | |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
+ | R | Interrupt | fPCLK/8 | fPCLK/16 | fPCLK/32 | fPCLK/16 | fPCLK/64 | fPCLK/4 |
+ | X |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
+ | | DMA | fPCLK/2 | fPCLK/16 | fPCLK/8 | fPCLK/16 | fPCLK/64 | fPCLK/2 |
+ |=========|================|===========|===========|===========|===========|===========|===========|
+ | | Polling | fPCLK/2 | fPCLK/2 | NA | NA | fPCLK/2 | fPCLK/32 |
+ | |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
+ | T | Interrupt | fPCLK/8 | fPCLK/16 | NA | NA | fPCLK/2 | fPCLK/64 |
+ | X |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
+ | | DMA | fPCLK/2 | fPCLK/4 | NA | NA | fPCLK/2 | fPCLK/32 |
+ +--------------------------------------------------------------------------------------------------+
+
+ DataSize = SPI_DATASIZE_16BIT:
+ +--------------------------------------------------------------------------------------------------+
+ | | | 2Lines Fullduplex | 2Lines RxOnly | 1Line |
+ | Process | Tranfert mode |-----------------------|-----------------------|-----------------------|
+ | | | Master | Slave | Master | Slave | Master | Slave |
+ |==================================================================================================|
+ | T | Polling | fPCLK/4 | fPCLK/4 | NA | NA | NA | NA |
+ | X |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
+ | / | Interrupt | fPCLK/8 | fPCLK/16 | NA | NA | NA | NA |
+ | R |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
+ | X | DMA | fPCLK/2 | fPCLK/4 | NA | NA | NA | NA |
+ |=========|================|===========|===========|===========|===========|===========|===========|
+ | | Polling | fPCLK/4 | fPCLK/8 | fPCLK/4 | fPCLK/8 | fPCLK/64 | fPCLK/2 |
+ | |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
+ | R | Interrupt | fPCLK/8 | fPCLK/8 | fPCLK/128 | fPCLK/8 | fPCLK/128 | fPCLK/4 |
+ | X |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
+ | | DMA | fPCLK/2 | fPCLK/2 | fPCLK/128 | fPCLK/16 | fPCLK/64 | fPCLK/2 |
+ |=========|================|===========|===========|===========|===========|===========|===========|
+ | | Polling | fPCLK/2 | fPCLK/4 | NA | NA | fPCLK/4 | fPCLK/8 |
+ | |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
+ | T | Interrupt | fPCLK/4 | fPCLK/8 | NA | NA | fPCLK/4 | fPCLK/4 |
+ | X |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
+ | | DMA | fPCLK/2 | fPCLK/2 | NA | NA | fPCLK/4 | fPCLK/8 |
+ +--------------------------------------------------------------------------------------------------+
+ [..]
+ (@) The max SPI frequency depend on SPI data size (8bits, 16bits),
+ SPI mode(2 Lines fullduplex, 2 lines RxOnly, 1 line TX/RX) and Process mode (Polling, IT, DMA).
+ (@)
+ (+@) TX/RX processes are HAL_SPI_TransmitReceive(), HAL_SPI_TransmitReceive_IT() and HAL_SPI_TransmitReceive_DMA()
+ (+@) RX processes are HAL_SPI_Receive(), HAL_SPI_Receive_IT() and HAL_SPI_Receive_DMA()
+ (+@) TX processes are HAL_SPI_Transmit(), HAL_SPI_Transmit_IT() and HAL_SPI_Transmit_DMA()
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+/** @defgroup SPI SPI
+ * @brief SPI HAL module driver
+ * @{
+ */
+#ifdef HAL_SPI_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+/** @defgroup SPI_Private_Constants SPI Private Constants
+ * @{
+ */
+#define SPI_DEFAULT_TIMEOUT 100U
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @addtogroup SPI_Private_Functions
+ * @{
+ */
+static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
+static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
+static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma);
+static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma);
+static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma);
+static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma);
+static void SPI_DMAError(DMA_HandleTypeDef *hdma);
+static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma);
+static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
+static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
+static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, uint32_t State, uint32_t Timeout, uint32_t Tickstart);
+static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
+static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
+static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
+static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
+static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
+static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
+static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
+static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
+#if (USE_SPI_CRC != 0U)
+static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi);
+static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi);
+static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi);
+static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi);
+#endif /* USE_SPI_CRC */
+static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi);
+static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi);
+static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi);
+static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi);
+static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi);
+static HAL_StatusTypeDef SPI_CheckFlag_BSY(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart);
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup SPI_Exported_Functions SPI Exported Functions
+ * @{
+ */
+
+/** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to initialize and
+ de-initialize the SPIx peripheral:
+
+ (+) User must implement HAL_SPI_MspInit() function in which he configures
+ all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
+
+ (+) Call the function HAL_SPI_Init() to configure the selected device with
+ the selected configuration:
+ (++) Mode
+ (++) Direction
+ (++) Data Size
+ (++) Clock Polarity and Phase
+ (++) NSS Management
+ (++) BaudRate Prescaler
+ (++) FirstBit
+ (++) TIMode
+ (++) CRC Calculation
+ (++) CRC Polynomial if CRC enabled
+
+ (+) Call the function HAL_SPI_DeInit() to restore the default configuration
+ of the selected SPIx peripheral.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initialize the SPI according to the specified parameters
+ * in the SPI_InitTypeDef and initialize the associated handle.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval HAL status
+ */
+__weak HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
+{
+ /* Check the SPI handle allocation */
+ if(hspi == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
+ assert_param(IS_SPI_MODE(hspi->Init.Mode));
+ assert_param(IS_SPI_DIRECTION(hspi->Init.Direction));
+ assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize));
+ assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity));
+ assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase));
+ assert_param(IS_SPI_NSS(hspi->Init.NSS));
+ assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
+ assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit));
+
+#if (USE_SPI_CRC != 0U)
+ assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation));
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial));
+ }
+#else
+ hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
+#endif /* USE_SPI_CRC */
+
+ if(hspi->State == HAL_SPI_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hspi->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware : GPIO, CLOCK, NVIC... */
+ HAL_SPI_MspInit(hspi);
+ }
+
+ hspi->State = HAL_SPI_STATE_BUSY;
+
+ /* Disable the selected SPI peripheral */
+ __HAL_SPI_DISABLE(hspi);
+
+ /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/
+ /* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management,
+ Communication speed, First bit and CRC calculation state */
+ WRITE_REG(hspi->Instance->CR1, (hspi->Init.Mode | hspi->Init.Direction | hspi->Init.DataSize |
+ hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) |
+ hspi->Init.BaudRatePrescaler | hspi->Init.FirstBit | hspi->Init.CRCCalculation) );
+
+ /* Configure : NSS management */
+ WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) | hspi->Init.TIMode));
+
+#if (USE_SPI_CRC != 0U)
+ /*---------------------------- SPIx CRCPOLY Configuration ------------------*/
+ /* Configure : CRC Polynomial */
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ WRITE_REG(hspi->Instance->CRCPR, hspi->Init.CRCPolynomial);
+ }
+#endif /* USE_SPI_CRC */
+
+#if defined(SPI_I2SCFGR_I2SMOD)
+ /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */
+ CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD);
+#endif /* SPI_I2SCFGR_I2SMOD */
+
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->State = HAL_SPI_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief De Initialize the SPI peripheral.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi)
+{
+ /* Check the SPI handle allocation */
+ if(hspi == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check SPI Instance parameter */
+ assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
+
+ hspi->State = HAL_SPI_STATE_BUSY;
+
+ /* Disable the SPI Peripheral Clock */
+ __HAL_SPI_DISABLE(hspi);
+
+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
+ HAL_SPI_MspDeInit(hspi);
+
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->State = HAL_SPI_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hspi);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initialize the SPI MSP.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+__weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_MspInit should be implemented in the user file
+ */
+}
+
+/**
+ * @brief De-Initialize the SPI MSP.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+__weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_MspDeInit should be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Exported_Functions_Group2 IO operation functions
+ * @brief Data transfers functions
+ *
+@verbatim
+ ==============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the SPI
+ data transfers.
+
+ [..] The SPI supports master and slave mode :
+
+ (#) There are two modes of transfer:
+ (++) Blocking mode: The communication is performed in polling mode.
+ The HAL status of all data processing is returned by the same function
+ after finishing transfer.
+ (++) No-Blocking mode: The communication is performed using Interrupts
+ or DMA, These APIs return the HAL status.
+ The end of the data processing will be indicated through the
+ dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when
+ using DMA mode.
+ The HAL_SPI_TxCpltCallback(), HAL_SPI_RxCpltCallback() and HAL_SPI_TxRxCpltCallback() user callbacks
+ will be executed respectively at the end of the transmit or Receive process
+ The HAL_SPI_ErrorCallback()user callback will be executed when a communication error is detected
+
+ (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA)
+ exist for 1Line (simplex) and 2Lines (full duplex) modes.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Transmit an amount of data in blocking mode.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param pData: pointer to data buffer
+ * @param Size: amount of data to be sent
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ uint32_t tickstart = 0U;
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ /* Check Direction parameter */
+ assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
+
+ /* Process Locked */
+ __HAL_LOCK(hspi);
+
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+
+ if(hspi->State != HAL_SPI_STATE_READY)
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if((pData == NULL ) || (Size == 0U))
+ {
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+
+ /* Set the transaction information */
+ hspi->State = HAL_SPI_STATE_BUSY_TX;
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->pTxBuffPtr = (uint8_t *)pData;
+ hspi->TxXferSize = Size;
+ hspi->TxXferCount = Size;
+
+ /*Init field not used in handle to zero */
+ hspi->pRxBuffPtr = (uint8_t *)NULL;
+ hspi->RxXferSize = 0U;
+ hspi->RxXferCount = 0U;
+ hspi->TxISR = NULL;
+ hspi->RxISR = NULL;
+
+ /* Configure communication direction : 1Line */
+ if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
+ {
+ SPI_1LINE_TX(hspi);
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Reset CRC Calculation */
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Check if the SPI is already enabled */
+ if((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
+ {
+ /* Enable SPI peripheral */
+ __HAL_SPI_ENABLE(hspi);
+ }
+
+ /* Transmit data in 16 Bit mode */
+ if(hspi->Init.DataSize == SPI_DATASIZE_16BIT)
+ {
+ if((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01))
+ {
+ hspi->Instance->DR = *((uint16_t *)pData);
+ pData += sizeof(uint16_t);
+ hspi->TxXferCount--;
+ }
+ /* Transmit data in 16 Bit mode */
+ while (hspi->TxXferCount > 0U)
+ {
+ /* Wait until TXE flag is set to send data */
+ if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
+ {
+ hspi->Instance->DR = *((uint16_t *)pData);
+ pData += sizeof(uint16_t);
+ hspi->TxXferCount--;
+ }
+ else
+ {
+ /* Timeout management */
+ if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout)))
+ {
+ errorcode = HAL_TIMEOUT;
+ goto error;
+ }
+ }
+ }
+ }
+ /* Transmit data in 8 Bit mode */
+ else
+ {
+ if((hspi->Init.Mode == SPI_MODE_SLAVE)|| (hspi->TxXferCount == 0x01))
+ {
+ *((__IO uint8_t*)&hspi->Instance->DR) = (*pData);
+ pData += sizeof(uint8_t);
+ hspi->TxXferCount--;
+ }
+ while (hspi->TxXferCount > 0U)
+ {
+ /* Wait until TXE flag is set to send data */
+ if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
+ {
+ *((__IO uint8_t*)&hspi->Instance->DR) = (*pData);
+ pData += sizeof(uint8_t);
+ hspi->TxXferCount--;
+ }
+ else
+ {
+ /* Timeout management */
+ if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout)))
+ {
+ errorcode = HAL_TIMEOUT;
+ goto error;
+ }
+ }
+ }
+ }
+
+ /* Wait until TXE flag */
+ if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_TXE, SET, Timeout, tickstart) != HAL_OK)
+ {
+ errorcode = HAL_TIMEOUT;
+ goto error;
+ }
+
+ /* Check Busy flag */
+ if(SPI_CheckFlag_BSY(hspi, Timeout, tickstart) != HAL_OK)
+ {
+ errorcode = HAL_ERROR;
+ hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
+ goto error;
+ }
+
+ /* Clear overrun flag in 2 Lines communication mode because received is not read */
+ if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
+ {
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+ }
+#if (USE_SPI_CRC != 0U)
+ /* Enable CRC Transmission */
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ }
+#endif /* USE_SPI_CRC */
+
+ if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+ {
+ errorcode = HAL_ERROR;
+ }
+
+error:
+ hspi->State = HAL_SPI_STATE_READY;
+ /* Process Unlocked */
+ __HAL_UNLOCK(hspi);
+ return errorcode;
+}
+
+/**
+ * @brief Receive an amount of data in blocking mode.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param pData: pointer to data buffer
+ * @param Size: amount of data to be received
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+#if (USE_SPI_CRC != 0U)
+ __IO uint16_t tmpreg = 0U;
+#endif /* USE_SPI_CRC */
+ uint32_t tickstart = 0U;
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ if((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES))
+ {
+ hspi->State = HAL_SPI_STATE_BUSY_RX;
+ /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
+ return HAL_SPI_TransmitReceive(hspi,pData,pData,Size,Timeout);
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hspi);
+
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+
+ if(hspi->State != HAL_SPI_STATE_READY)
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if((pData == NULL ) || (Size == 0U))
+ {
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+
+ /* Set the transaction information */
+ hspi->State = HAL_SPI_STATE_BUSY_RX;
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->pRxBuffPtr = (uint8_t *)pData;
+ hspi->RxXferSize = Size;
+ hspi->RxXferCount = Size;
+
+ /*Init field not used in handle to zero */
+ hspi->pTxBuffPtr = (uint8_t *)NULL;
+ hspi->TxXferSize = 0U;
+ hspi->TxXferCount = 0U;
+ hspi->RxISR = NULL;
+ hspi->TxISR = NULL;
+
+#if (USE_SPI_CRC != 0U)
+ /* Reset CRC Calculation */
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ /* this is done to handle the CRCNEXT before the latest data */
+ hspi->RxXferCount--;
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Configure communication direction: 1Line */
+ if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
+ {
+ SPI_1LINE_RX(hspi);
+ }
+
+ /* Check if the SPI is already enabled */
+ if((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
+ {
+ /* Enable SPI peripheral */
+ __HAL_SPI_ENABLE(hspi);
+ }
+
+ /* Receive data in 8 Bit mode */
+ if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)
+ {
+ /* Transfer loop */
+ while(hspi->RxXferCount > 0U)
+ {
+ /* Check the RXNE flag */
+ if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))
+ {
+ /* read the received data */
+ (* (uint8_t *)pData)= *(__IO uint8_t *)&hspi->Instance->DR;
+ pData += sizeof(uint8_t);
+ hspi->RxXferCount--;
+ }
+ else
+ {
+ /* Timeout management */
+ if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout)))
+ {
+ errorcode = HAL_TIMEOUT;
+ goto error;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Transfer loop */
+ while(hspi->RxXferCount > 0U)
+ {
+ /* Check the RXNE flag */
+ if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))
+ {
+ *((uint16_t*)pData) = hspi->Instance->DR;
+ pData += sizeof(uint16_t);
+ hspi->RxXferCount--;
+ }
+ else
+ {
+ /* Timeout management */
+ if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout)))
+ {
+ errorcode = HAL_TIMEOUT;
+ goto error;
+ }
+ }
+ }
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Handle the CRC Transmission */
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ /* freeze the CRC before the latest data */
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+
+ /* Read the latest data */
+ if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
+ {
+ /* the latest data has not been received */
+ errorcode = HAL_TIMEOUT;
+ goto error;
+ }
+
+ /* Receive last data in 16 Bit mode */
+ if(hspi->Init.DataSize == SPI_DATASIZE_16BIT)
+ {
+ *((uint16_t*)pData) = hspi->Instance->DR;
+ }
+ /* Receive last data in 8 Bit mode */
+ else
+ {
+ (*(uint8_t *)pData) = *(__IO uint8_t *)&hspi->Instance->DR;
+ }
+
+ /* Wait the CRC data */
+ if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+ errorcode = HAL_TIMEOUT;
+ goto error;
+ }
+
+ /* Read CRC to Flush DR and RXNE flag */
+ tmpreg = hspi->Instance->DR;
+ /* To avoid GCC warning */
+ UNUSED(tmpreg);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Check the end of the transaction */
+ if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
+ {
+ /* Disable SPI peripheral */
+ __HAL_SPI_DISABLE(hspi);
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Check if CRC error occurred */
+ if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
+ {
+ /* Check if CRC error is valid or not (workaround to be applied or not) */
+ if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+
+ /* Reset CRC Calculation */
+ SPI_RESET_CRC(hspi);
+ }
+ else
+ {
+ __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
+ }
+ }
+#endif /* USE_SPI_CRC */
+
+ if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+ {
+ errorcode = HAL_ERROR;
+ }
+
+error :
+ hspi->State = HAL_SPI_STATE_READY;
+ __HAL_UNLOCK(hspi);
+ return errorcode;
+}
+
+/**
+ * @brief Transmit and Receive an amount of data in blocking mode.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param pTxData: pointer to transmission data buffer
+ * @param pRxData: pointer to reception data buffer
+ * @param Size: amount of data to be sent and received
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
+{
+ uint32_t tmp = 0U, tmp1 = 0U;
+#if (USE_SPI_CRC != 0U)
+ __IO uint16_t tmpreg1 = 0U;
+#endif /* USE_SPI_CRC */
+ uint32_t tickstart = 0U;
+ /* Variable used to alternate Rx and Tx during transfer */
+ uint32_t txallowed = 1U;
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ /* Check Direction parameter */
+ assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
+
+ /* Process Locked */
+ __HAL_LOCK(hspi);
+
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+
+ tmp = hspi->State;
+ tmp1 = hspi->Init.Mode;
+
+ if(!((tmp == HAL_SPI_STATE_READY) || \
+ ((tmp1 == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp == HAL_SPI_STATE_BUSY_RX))))
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
+ {
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+
+ /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
+ if(hspi->State == HAL_SPI_STATE_READY)
+ {
+ hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
+ }
+
+ /* Set the transaction information */
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->pRxBuffPtr = (uint8_t *)pRxData;
+ hspi->RxXferCount = Size;
+ hspi->RxXferSize = Size;
+ hspi->pTxBuffPtr = (uint8_t *)pTxData;
+ hspi->TxXferCount = Size;
+ hspi->TxXferSize = Size;
+
+ /*Init field not used in handle to zero */
+ hspi->RxISR = NULL;
+ hspi->TxISR = NULL;
+
+#if (USE_SPI_CRC != 0U)
+ /* Reset CRC Calculation */
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Check if the SPI is already enabled */
+ if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
+ {
+ /* Enable SPI peripheral */
+ __HAL_SPI_ENABLE(hspi);
+ }
+
+ /* Transmit and Receive data in 16 Bit mode */
+ if(hspi->Init.DataSize == SPI_DATASIZE_16BIT)
+ {
+ if((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01U))
+ {
+ hspi->Instance->DR = *((uint16_t *)pTxData);
+ pTxData += sizeof(uint16_t);
+ hspi->TxXferCount--;
+ }
+ while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
+ {
+ /* Check TXE flag */
+ if(txallowed && (hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)))
+ {
+ hspi->Instance->DR = *((uint16_t *)pTxData);
+ pTxData += sizeof(uint16_t);
+ hspi->TxXferCount--;
+ /* Next Data is a reception (Rx). Tx not allowed */
+ txallowed = 0U;
+
+#if (USE_SPI_CRC != 0U)
+ /* Enable CRC Transmission */
+ if((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
+ {
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ }
+#endif /* USE_SPI_CRC */
+ }
+
+ /* Check RXNE flag */
+ if((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)))
+ {
+ *((uint16_t *)pRxData) = hspi->Instance->DR;
+ pRxData += sizeof(uint16_t);
+ hspi->RxXferCount--;
+ /* Next Data is a Transmission (Tx). Tx is allowed */
+ txallowed = 1U;
+ }
+ if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout))
+ {
+ errorcode = HAL_TIMEOUT;
+ goto error;
+ }
+ }
+ }
+ /* Transmit and Receive data in 8 Bit mode */
+ else
+ {
+ if((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01U))
+ {
+ *((__IO uint8_t*)&hspi->Instance->DR) = (*pTxData);
+ pTxData += sizeof(uint8_t);
+ hspi->TxXferCount--;
+ }
+ while((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
+ {
+ /* check TXE flag */
+ if(txallowed && (hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)))
+ {
+ *(__IO uint8_t *)&hspi->Instance->DR = (*pTxData++);
+ hspi->TxXferCount--;
+ /* Next Data is a reception (Rx). Tx not allowed */
+ txallowed = 0U;
+
+#if (USE_SPI_CRC != 0U)
+ /* Enable CRC Transmission */
+ if((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
+ {
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ }
+#endif /* USE_SPI_CRC */
+ }
+
+ /* Wait until RXNE flag is reset */
+ if((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)))
+ {
+ (*(uint8_t *)pRxData++) = hspi->Instance->DR;
+ hspi->RxXferCount--;
+ /* Next Data is a Transmission (Tx). Tx is allowed */
+ txallowed = 1U;
+ }
+ if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout))
+ {
+ errorcode = HAL_TIMEOUT;
+ goto error;
+ }
+ }
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Read CRC from DR to close CRC calculation process */
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ /* Wait until TXE flag */
+ if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
+ {
+ /* Error on the CRC reception */
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+ errorcode = HAL_TIMEOUT;
+ goto error;
+ }
+ /* Read CRC */
+ tmpreg1 = hspi->Instance->DR;
+ /* To avoid GCC warning */
+ UNUSED(tmpreg1);
+ }
+
+ /* Check if CRC error occurred */
+ if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
+ {
+ /* Check if CRC error is valid or not (workaround to be applied or not) */
+ if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+
+ /* Reset CRC Calculation */
+ SPI_RESET_CRC(hspi);
+
+ errorcode = HAL_ERROR;
+ }
+ else
+ {
+ __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
+ }
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Wait until TXE flag */
+ if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_TXE, SET, Timeout, tickstart) != HAL_OK)
+ {
+ errorcode = HAL_TIMEOUT;
+ goto error;
+ }
+
+ /* Check Busy flag */
+ if(SPI_CheckFlag_BSY(hspi, Timeout, tickstart) != HAL_OK)
+ {
+ errorcode = HAL_ERROR;
+ hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
+ goto error;
+ }
+
+ /* Clear overrun flag in 2 Lines communication mode because received is not read */
+ if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
+ {
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+ }
+
+error :
+ hspi->State = HAL_SPI_STATE_READY;
+ __HAL_UNLOCK(hspi);
+ return errorcode;
+}
+
+/**
+ * @brief Transmit an amount of data in non-blocking mode with Interrupt.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param pData: pointer to data buffer
+ * @param Size: amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
+{
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ /* Check Direction parameter */
+ assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
+
+ /* Process Locked */
+ __HAL_LOCK(hspi);
+
+ if((pData == NULL) || (Size == 0U))
+ {
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+
+ if(hspi->State != HAL_SPI_STATE_READY)
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ /* Set the transaction information */
+ hspi->State = HAL_SPI_STATE_BUSY_TX;
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->pTxBuffPtr = (uint8_t *)pData;
+ hspi->TxXferSize = Size;
+ hspi->TxXferCount = Size;
+
+ /* Init field not used in handle to zero */
+ hspi->pRxBuffPtr = (uint8_t *)NULL;
+ hspi->RxXferSize = 0U;
+ hspi->RxXferCount = 0U;
+ hspi->RxISR = NULL;
+
+ /* Set the function for IT treatment */
+ if(hspi->Init.DataSize > SPI_DATASIZE_8BIT )
+ {
+ hspi->TxISR = SPI_TxISR_16BIT;
+ }
+ else
+ {
+ hspi->TxISR = SPI_TxISR_8BIT;
+ }
+
+ /* Configure communication direction : 1Line */
+ if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
+ {
+ SPI_1LINE_TX(hspi);
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Reset CRC Calculation */
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ }
+#endif /* USE_SPI_CRC */
+
+ if (hspi->Init.Direction == SPI_DIRECTION_2LINES)
+ {
+ /* Enable TXE interrupt */
+ __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE));
+ }
+ else
+ {
+ /* Enable TXE and ERR interrupt */
+ __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR));
+ }
+
+ /* Check if the SPI is already enabled */
+ if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
+ {
+ /* Enable SPI peripheral */
+ __HAL_SPI_ENABLE(hspi);
+ }
+
+error :
+ __HAL_UNLOCK(hspi);
+ return errorcode;
+}
+
+/**
+ * @brief Receive an amount of data in non-blocking mode with Interrupt.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param pData: pointer to data buffer
+ * @param Size: amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
+{
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ if((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER))
+ {
+ hspi->State = HAL_SPI_STATE_BUSY_RX;
+ /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
+ return HAL_SPI_TransmitReceive_IT(hspi, pData, pData, Size);
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hspi);
+
+ if(hspi->State != HAL_SPI_STATE_READY)
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if((pData == NULL) || (Size == 0U))
+ {
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+
+ /* Set the transaction information */
+ hspi->State = HAL_SPI_STATE_BUSY_RX;
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->pRxBuffPtr = (uint8_t *)pData;
+ hspi->RxXferSize = Size;
+ hspi->RxXferCount = Size;
+
+ /* Init field not used in handle to zero */
+ hspi->pTxBuffPtr = (uint8_t *)NULL;
+ hspi->TxXferSize = 0U;
+ hspi->TxXferCount = 0U;
+ hspi->TxISR = NULL;
+
+ /* Set the function for IT treatment */
+ if(hspi->Init.DataSize > SPI_DATASIZE_8BIT )
+ {
+ hspi->RxISR = SPI_RxISR_16BIT;
+ }
+ else
+ {
+ hspi->RxISR = SPI_RxISR_8BIT;
+ }
+
+ /* Configure communication direction : 1Line */
+ if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
+ {
+ SPI_1LINE_RX(hspi);
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Reset CRC Calculation */
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Enable TXE and ERR interrupt */
+ __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
+
+ /* Note : The SPI must be enabled after unlocking current process
+ to avoid the risk of SPI interrupt handle execution before current
+ process unlock */
+
+ /* Check if the SPI is already enabled */
+ if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
+ {
+ /* Enable SPI peripheral */
+ __HAL_SPI_ENABLE(hspi);
+ }
+
+error :
+ /* Process Unlocked */
+ __HAL_UNLOCK(hspi);
+ return errorcode;
+}
+
+/**
+ * @brief Transmit and Receive an amount of data in non-blocking mode with Interrupt.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param pTxData: pointer to transmission data buffer
+ * @param pRxData: pointer to reception data buffer
+ * @param Size: amount of data to be sent and received
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
+{
+ uint32_t tmp = 0U, tmp1 = 0U;
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ /* Check Direction parameter */
+ assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
+
+ /* Process locked */
+ __HAL_LOCK(hspi);
+
+ tmp = hspi->State;
+ tmp1 = hspi->Init.Mode;
+
+ if(!((tmp == HAL_SPI_STATE_READY) || \
+ ((tmp1 == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp == HAL_SPI_STATE_BUSY_RX))))
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0U))
+ {
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+
+ /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
+ if(hspi->State == HAL_SPI_STATE_READY)
+ {
+ hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
+ }
+
+ /* Set the transaction information */
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->pTxBuffPtr = (uint8_t *)pTxData;
+ hspi->TxXferSize = Size;
+ hspi->TxXferCount = Size;
+ hspi->pRxBuffPtr = (uint8_t *)pRxData;
+ hspi->RxXferSize = Size;
+ hspi->RxXferCount = Size;
+
+ /* Set the function for IT treatment */
+ if(hspi->Init.DataSize > SPI_DATASIZE_8BIT )
+ {
+ hspi->RxISR = SPI_2linesRxISR_16BIT;
+ hspi->TxISR = SPI_2linesTxISR_16BIT;
+ }
+ else
+ {
+ hspi->RxISR = SPI_2linesRxISR_8BIT;
+ hspi->TxISR = SPI_2linesTxISR_8BIT;
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Reset CRC Calculation */
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Enable TXE, RXNE and ERR interrupt */
+ __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
+
+ /* Check if the SPI is already enabled */
+ if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
+ {
+ /* Enable SPI peripheral */
+ __HAL_SPI_ENABLE(hspi);
+ }
+
+error :
+ /* Process Unlocked */
+ __HAL_UNLOCK(hspi);
+ return errorcode;
+}
+
+/**
+ * @brief Transmit an amount of data in non-blocking mode with DMA.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param pData: pointer to data buffer
+ * @param Size: amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
+{
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ /* Check Direction parameter */
+ assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
+
+ /* Process Locked */
+ __HAL_LOCK(hspi);
+
+ if(hspi->State != HAL_SPI_STATE_READY)
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if((pData == NULL) || (Size == 0U))
+ {
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+
+ /* Set the transaction information */
+ hspi->State = HAL_SPI_STATE_BUSY_TX;
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->pTxBuffPtr = (uint8_t *)pData;
+ hspi->TxXferSize = Size;
+ hspi->TxXferCount = Size;
+
+ /* Init field not used in handle to zero */
+ hspi->pRxBuffPtr = (uint8_t *)NULL;
+ hspi->TxISR = NULL;
+ hspi->RxISR = NULL;
+ hspi->RxXferSize = 0U;
+ hspi->RxXferCount = 0U;
+
+ /* Configure communication direction : 1Line */
+ if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
+ {
+ SPI_1LINE_TX(hspi);
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Reset CRC Calculation */
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Set the SPI TxDMA Half transfer complete callback */
+ hspi->hdmatx->XferHalfCpltCallback = SPI_DMAHalfTransmitCplt;
+
+ /* Set the SPI TxDMA transfer complete callback */
+ hspi->hdmatx->XferCpltCallback = SPI_DMATransmitCplt;
+
+ /* Set the DMA error callback */
+ hspi->hdmatx->XferErrorCallback = SPI_DMAError;
+
+ /* Set the DMA AbortCpltCallback */
+ hspi->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the Tx DMA Stream */
+ HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, hspi->TxXferCount);
+
+ /* Check if the SPI is already enabled */
+ if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
+ {
+ /* Enable SPI peripheral */
+ __HAL_SPI_ENABLE(hspi);
+ }
+
+ /* Enable the SPI Error Interrupt Bit */
+ SET_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
+
+ /* Enable Tx DMA Request */
+ SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
+
+error :
+ /* Process Unlocked */
+ __HAL_UNLOCK(hspi);
+ return errorcode;
+}
+
+/**
+ * @brief Receive an amount of data in non-blocking mode with DMA.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param pData: pointer to data buffer
+ * @note When the CRC feature is enabled the pData Length must be Size + 1.
+ * @param Size: amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
+{
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ if((hspi->Init.Direction == SPI_DIRECTION_2LINES)&&(hspi->Init.Mode == SPI_MODE_MASTER))
+ {
+ hspi->State = HAL_SPI_STATE_BUSY_RX;
+ /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
+ return HAL_SPI_TransmitReceive_DMA(hspi, pData, pData, Size);
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hspi);
+
+ if(hspi->State != HAL_SPI_STATE_READY)
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if((pData == NULL) || (Size == 0U))
+ {
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+
+ /* Set the transaction information */
+ hspi->State = HAL_SPI_STATE_BUSY_RX;
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->pRxBuffPtr = (uint8_t *)pData;
+ hspi->RxXferSize = Size;
+ hspi->RxXferCount = Size;
+
+ /*Init field not used in handle to zero */
+ hspi->RxISR = NULL;
+ hspi->TxISR = NULL;
+ hspi->TxXferSize = 0U;
+ hspi->TxXferCount = 0U;
+
+ /* Configure communication direction : 1Line */
+ if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
+ {
+ SPI_1LINE_RX(hspi);
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Reset CRC Calculation */
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Set the SPI RxDMA Half transfer complete callback */
+ hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
+
+ /* Set the SPI Rx DMA transfer complete callback */
+ hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;
+
+ /* Set the DMA error callback */
+ hspi->hdmarx->XferErrorCallback = SPI_DMAError;
+
+ /* Set the DMA AbortCpltCallback */
+ hspi->hdmarx->XferAbortCallback = NULL;
+
+ /* Enable the Rx DMA Stream */
+ HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount);
+
+ /* Check if the SPI is already enabled */
+ if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
+ {
+ /* Enable SPI peripheral */
+ __HAL_SPI_ENABLE(hspi);
+ }
+
+ /* Enable the SPI Error Interrupt Bit */
+ SET_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
+
+ /* Enable Rx DMA Request */
+ SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
+
+error:
+ /* Process Unlocked */
+ __HAL_UNLOCK(hspi);
+ return errorcode;
+}
+
+/**
+ * @brief Transmit and Receive an amount of data in non-blocking mode with DMA.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param pTxData: pointer to transmission data buffer
+ * @param pRxData: pointer to reception data buffer
+ * @note When the CRC feature is enabled the pRxData Length must be Size + 1
+ * @param Size: amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
+{
+ uint32_t tmp = 0U, tmp1 = 0U;
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ /* Check Direction parameter */
+ assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
+
+ /* Process locked */
+ __HAL_LOCK(hspi);
+
+ tmp = hspi->State;
+ tmp1 = hspi->Init.Mode;
+ if(!((tmp == HAL_SPI_STATE_READY) ||
+ ((tmp1 == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp == HAL_SPI_STATE_BUSY_RX))))
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0U))
+ {
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+
+ /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
+ if(hspi->State == HAL_SPI_STATE_READY)
+ {
+ hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
+ }
+
+ /* Set the transaction information */
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->pTxBuffPtr = (uint8_t*)pTxData;
+ hspi->TxXferSize = Size;
+ hspi->TxXferCount = Size;
+ hspi->pRxBuffPtr = (uint8_t*)pRxData;
+ hspi->RxXferSize = Size;
+ hspi->RxXferCount = Size;
+
+ /* Init field not used in handle to zero */
+ hspi->RxISR = NULL;
+ hspi->TxISR = NULL;
+
+#if (USE_SPI_CRC != 0U)
+ /* Reset CRC Calculation */
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Check if we are in Rx only or in Rx/Tx Mode and configure the DMA transfer complete callback */
+ if(hspi->State == HAL_SPI_STATE_BUSY_RX)
+ {
+ /* Set the SPI Rx DMA Half transfer complete callback */
+ hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
+ hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;
+ }
+ else
+ {
+ /* Set the SPI Tx/Rx DMA Half transfer complete callback */
+ hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt;
+ hspi->hdmarx->XferCpltCallback = SPI_DMATransmitReceiveCplt;
+ }
+
+ /* Set the DMA error callback */
+ hspi->hdmarx->XferErrorCallback = SPI_DMAError;
+
+ /* Set the DMA AbortCpltCallback */
+ hspi->hdmarx->XferAbortCallback = NULL;
+
+ /* Enable the Rx DMA Stream */
+ HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount);
+
+ /* Enable Rx DMA Request */
+ SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
+
+ /* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing
+ is performed in DMA reception complete callback */
+ hspi->hdmatx->XferHalfCpltCallback = NULL;
+ hspi->hdmatx->XferCpltCallback = NULL;
+ hspi->hdmatx->XferErrorCallback = NULL;
+ hspi->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the Tx DMA Stream */
+ HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, hspi->TxXferCount);
+
+ /* Check if the SPI is already enabled */
+ if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
+ {
+ /* Enable SPI peripheral */
+ __HAL_SPI_ENABLE(hspi);
+ }
+ /* Enable the SPI Error Interrupt Bit */
+ SET_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
+
+ /* Enable Tx DMA Request */
+ SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
+
+error :
+ /* Process Unlocked */
+ __HAL_UNLOCK(hspi);
+ return errorcode;
+}
+
+/**
+ * @brief Abort ongoing transfer (blocking mode).
+ * @param hspi SPI handle.
+ * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx),
+ * started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable SPI Interrupts (depending of transfer direction)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @note Once transfer is aborted, the __HAL_SPI_CLEAR_OVRFLAG() macro must be called in user application
+ * before starting new SPI receive process.
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi)
+{
+ __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
+
+ /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */
+ if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE))
+ {
+ hspi->TxISR = SPI_AbortTx_ISR;
+ }
+
+ if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE))
+ {
+ hspi->RxISR = SPI_AbortRx_ISR;
+ }
+
+ /* Clear ERRIE interrupts in case of DMA Mode */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
+
+ /* Disable the SPI DMA Tx or SPI DMA Rx request if enabled */
+ if ((HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN)) || (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN)))
+ {
+ /* Abort the SPI DMA Tx channel : use blocking DMA Abort API (no callback) */
+ if(hspi->hdmatx != NULL)
+ {
+ /* Set the SPI DMA Abort callback :
+ will lead to call HAL_SPI_AbortCpltCallback() at end of DMA abort procedure */
+ hspi->hdmatx->XferAbortCallback = NULL;
+
+ /* Abort DMA Tx Handle linked to SPI Peripheral */
+ HAL_DMA_Abort(hspi->hdmatx);
+
+ /* Disable Tx DMA Request */
+ CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN));
+
+ /* Wait until TXE flag is set */
+ do
+ {
+ if(count-- == 0U)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ break;
+ }
+ }
+ while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
+ }
+ /* Abort the SPI DMA Rx channel : use blocking DMA Abort API (no callback) */
+ if(hspi->hdmarx != NULL)
+ {
+ /* Set the SPI DMA Abort callback :
+ will lead to call HAL_SPI_AbortCpltCallback() at end of DMA abort procedure */
+ hspi->hdmarx->XferAbortCallback = NULL;
+
+ /* Abort DMA Rx Handle linked to SPI Peripheral */
+ HAL_DMA_Abort(hspi->hdmarx);
+
+ /* Disable peripheral */
+ __HAL_SPI_DISABLE(hspi);
+
+ /* Disable Rx DMA Request */
+ CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_RXDMAEN));
+
+ }
+ }
+ /* Reset Tx and Rx transfer counters */
+ hspi->RxXferCount = 0U;
+ hspi->TxXferCount = 0U;
+
+ /* Reset errorCode */
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+
+ /* Clear the Error flags in the SR register */
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+
+ /* Restore hspi->state to ready */
+ hspi->State = HAL_SPI_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing transfer (Interrupt mode).
+ * @param hspi SPI handle.
+ * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx),
+ * started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable SPI Interrupts (depending of transfer direction)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @note Once transfer is aborted, the __HAL_SPI_CLEAR_OVRFLAG() macro must be called in user application
+ * before starting new SPI receive process.
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi)
+{
+ uint32_t abortcplt;
+
+ /* Change Rx and Tx Irq Handler to Disable TXEIE, RXNEIE and ERRIE interrupts */
+ if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE))
+ {
+ hspi->TxISR = SPI_AbortTx_ISR;
+ }
+
+ if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE))
+ {
+ hspi->RxISR = SPI_AbortRx_ISR;
+ }
+
+ /* Clear ERRIE interrupts in case of DMA Mode */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
+
+ abortcplt = 1U;
+
+ /* If DMA Tx and/or DMA Rx Handles are associated to SPI Handle, DMA Abort complete callbacks should be initialised
+ before any call to DMA Abort functions */
+ /* DMA Tx Handle is valid */
+ if(hspi->hdmatx != NULL)
+ {
+ /* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
+ Otherwise, set it to NULL */
+ if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN))
+ {
+ hspi->hdmatx->XferAbortCallback = SPI_DMATxAbortCallback;
+ }
+ else
+ {
+ hspi->hdmatx->XferAbortCallback = NULL;
+ }
+ }
+ /* DMA Rx Handle is valid */
+ if(hspi->hdmarx != NULL)
+ {
+ /* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
+ Otherwise, set it to NULL */
+ if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN))
+ {
+ hspi->hdmarx->XferAbortCallback = SPI_DMARxAbortCallback;
+ }
+ else
+ {
+ hspi->hdmarx->XferAbortCallback = NULL;
+ }
+ }
+
+ /* Disable the SPI DMA Tx or the SPI Rx request if enabled */
+ if((HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN)) && (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN)))
+ {
+ /* Abort the SPI DMA Tx channel */
+ if(hspi->hdmatx != NULL)
+ {
+ /* Abort DMA Tx Handle linked to SPI Peripheral */
+ if(HAL_DMA_Abort_IT(hspi->hdmatx) != HAL_OK)
+ {
+ hspi->hdmatx->XferAbortCallback = NULL;
+ }
+ else
+ {
+ abortcplt = 0U;
+ }
+ }
+ /* Abort the SPI DMA Rx channel */
+ if(hspi->hdmarx != NULL)
+ {
+ /* Abort DMA Rx Handle linked to SPI Peripheral */
+ if(HAL_DMA_Abort_IT(hspi->hdmarx)!= HAL_OK)
+ {
+ hspi->hdmarx->XferAbortCallback = NULL;
+ abortcplt = 1U;
+ }
+ else
+ {
+ abortcplt = 0U;
+ }
+ }
+ }
+
+ /* Disable the SPI DMA Tx or the SPI Rx request if enabled */
+ if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN))
+ {
+ /* Abort the SPI DMA Tx channel */
+ if(hspi->hdmatx != NULL)
+ {
+ /* Abort DMA Tx Handle linked to SPI Peripheral */
+ if(HAL_DMA_Abort_IT(hspi->hdmatx) != HAL_OK)
+ {
+ hspi->hdmatx->XferAbortCallback = NULL;
+ }
+ else
+ {
+ abortcplt = 0U;
+ }
+ }
+ }
+ /* Disable the SPI DMA Tx or the SPI Rx request if enabled */
+ if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN))
+ {
+ /* Abort the SPI DMA Rx channel */
+ if(hspi->hdmarx != NULL)
+ {
+ /* Abort DMA Rx Handle linked to SPI Peripheral */
+ if(HAL_DMA_Abort_IT(hspi->hdmarx)!= HAL_OK)
+ {
+ hspi->hdmarx->XferAbortCallback = NULL;
+ }
+ else
+ {
+ abortcplt = 0U;
+ }
+ }
+ }
+
+ if(abortcplt == 1U)
+ {
+ /* Reset Tx and Rx transfer counters */
+ hspi->RxXferCount = 0U;
+ hspi->TxXferCount = 0U;
+
+ /* Reset errorCode */
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+
+ /* Clear the Error flags in the SR register */
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+
+ /* Restore hspi->State to Ready */
+ hspi->State = HAL_SPI_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+ HAL_SPI_AbortCpltCallback(hspi);
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief Pause the DMA Transfer.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for the specified SPI module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi)
+{
+ /* Process Locked */
+ __HAL_LOCK(hspi);
+
+ /* Disable the SPI DMA Tx & Rx requests */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hspi);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Resume the DMA Transfer.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for the specified SPI module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi)
+{
+ /* Process Locked */
+ __HAL_LOCK(hspi);
+
+ /* Enable the SPI DMA Tx & Rx requests */
+ SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hspi);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Stop the DMA Transfer.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for the specified SPI module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi)
+{
+ /* The Lock is not implemented on this API to allow the user application
+ to call the HAL SPI API under callbacks HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback():
+ when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
+ and the correspond call back is executed HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback()
+ */
+
+ /* Abort the SPI DMA tx Stream */
+ if(hspi->hdmatx != NULL)
+ {
+ HAL_DMA_Abort(hspi->hdmatx);
+ }
+ /* Abort the SPI DMA rx Stream */
+ if(hspi->hdmarx != NULL)
+ {
+ HAL_DMA_Abort(hspi->hdmarx);
+ }
+
+ /* Disable the SPI DMA Tx & Rx requests */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
+ hspi->State = HAL_SPI_STATE_READY;
+ return HAL_OK;
+}
+
+/**
+ * @brief Handle SPI interrupt request.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for the specified SPI module.
+ * @retval None
+ */
+void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
+{
+ uint32_t itsource = hspi->Instance->CR2;
+ uint32_t itflag = hspi->Instance->SR;
+
+ /* SPI in mode Receiver ----------------------------------------------------*/
+ if(((itflag & SPI_FLAG_OVR) == RESET) &&
+ ((itflag & SPI_FLAG_RXNE) != RESET) && ((itsource & SPI_IT_RXNE) != RESET))
+ {
+ hspi->RxISR(hspi);
+ return;
+ }
+
+ /* SPI in mode Transmitter -------------------------------------------------*/
+ if(((itflag & SPI_FLAG_TXE) != RESET) && ((itsource & SPI_IT_TXE) != RESET))
+ {
+ hspi->TxISR(hspi);
+ return;
+ }
+
+ /* SPI in Error Treatment --------------------------------------------------*/
+ if(((itflag & (SPI_FLAG_MODF | SPI_FLAG_OVR)) != RESET) && ((itsource & SPI_IT_ERR) != RESET))
+ {
+ /* SPI Overrun error interrupt occurred ----------------------------------*/
+ if((itflag & SPI_FLAG_OVR) != RESET)
+ {
+ if(hspi->State != HAL_SPI_STATE_BUSY_TX)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR);
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+ }
+ else
+ {
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+ return;
+ }
+ }
+
+ /* SPI Mode Fault error interrupt occurred -------------------------------*/
+ if((itflag & SPI_FLAG_MODF) != RESET)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF);
+ __HAL_SPI_CLEAR_MODFFLAG(hspi);
+ }
+
+ if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+ {
+ /* Disable all interrupts */
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE | SPI_IT_TXE | SPI_IT_ERR);
+
+ hspi->State = HAL_SPI_STATE_READY;
+ /* Disable the SPI DMA requests if enabled */
+ if ((HAL_IS_BIT_SET(itsource, SPI_CR2_TXDMAEN))||(HAL_IS_BIT_SET(itsource, SPI_CR2_RXDMAEN)))
+ {
+ CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN));
+
+ /* Abort the SPI DMA Rx channel */
+ if(hspi->hdmarx != NULL)
+ {
+ /* Set the SPI DMA Abort callback :
+ will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
+ hspi->hdmarx->XferAbortCallback = SPI_DMAAbortOnError;
+ HAL_DMA_Abort_IT(hspi->hdmarx);
+ }
+ /* Abort the SPI DMA Tx channel */
+ if(hspi->hdmatx != NULL)
+ {
+ /* Set the SPI DMA Abort callback :
+ will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
+ hspi->hdmatx->XferAbortCallback = SPI_DMAAbortOnError;
+ HAL_DMA_Abort_IT(hspi->hdmatx);
+ }
+ }
+ else
+ {
+ /* Call user error callback */
+ HAL_SPI_ErrorCallback(hspi);
+ }
+ }
+ return;
+ }
+}
+
+/**
+ * @brief Tx Transfer completed callback.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+__weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_TxCpltCallback should be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer completed callback.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+__weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_RxCpltCallback should be implemented in the user file
+ */
+}
+
+/**
+ * @brief Tx and Rx Transfer completed callback.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+__weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_TxRxCpltCallback should be implemented in the user file
+ */
+}
+
+/**
+ * @brief Tx Half Transfer completed callback.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+__weak void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_TxHalfCpltCallback should be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Half Transfer completed callback.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+__weak void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_RxHalfCpltCallback() should be implemented in the user file
+ */
+}
+
+/**
+ * @brief Tx and Rx Half Transfer callback.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+__weak void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_TxRxHalfCpltCallback() should be implemented in the user file
+ */
+}
+
+/**
+ * @brief SPI error callback.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+ __weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_ErrorCallback should be implemented in the user file
+ */
+ /* NOTE : The ErrorCode parameter in the hspi handle is updated by the SPI processes
+ and user can use HAL_SPI_GetError() API to check the latest error occurred
+ */
+}
+
+/**
+ * @brief SPI Abort Complete callback.
+ * @param hspi SPI handle.
+ * @retval None
+ */
+__weak void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_AbortCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions
+ * @brief SPI control functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral State and Errors functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the SPI.
+ (+) HAL_SPI_GetState() API can be helpful to check in run-time the state of the SPI peripheral
+ (+) HAL_SPI_GetError() check in run-time Errors occurring during communication
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Return the SPI handle state.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval SPI state
+ */
+HAL_SPI_StateTypeDef HAL_SPI_GetState(SPI_HandleTypeDef *hspi)
+{
+ /* Return SPI handle state */
+ return hspi->State;
+}
+
+/**
+ * @brief Return the SPI error code.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval SPI error code in bitmap format
+ */
+uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi)
+{
+ /* Return SPI ErrorCode */
+ return hspi->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup SPI_Private_Functions
+ * @brief Private functions
+ * @{
+ */
+
+/**
+ * @brief DMA SPI transmit process complete callback.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ uint32_t tickstart = 0U;
+
+ /* Init tickstart for timeout managment*/
+ tickstart = HAL_GetTick();
+
+ /* DMA Normal Mode */
+ if((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC)
+ {
+ /* Disable Tx DMA Request */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
+
+ /* Check the end of the transaction */
+ if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ }
+
+ /* Clear overrun flag in 2 Lines communication mode because received data is not read */
+ if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
+ {
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+ }
+
+ hspi->TxXferCount = 0U;
+ hspi->State = HAL_SPI_STATE_READY;
+
+ if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+ {
+ HAL_SPI_ErrorCallback(hspi);
+ return;
+ }
+ }
+ HAL_SPI_TxCpltCallback(hspi);
+}
+
+/**
+ * @brief DMA SPI receive process complete callback.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+#if (USE_SPI_CRC != 0U)
+ uint32_t tickstart = 0U;
+ __IO uint16_t tmpreg = 0U;
+
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+#endif /* USE_SPI_CRC */
+
+ if((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC)
+ {
+#if (USE_SPI_CRC != 0U)
+ /* CRC handling */
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ /* Wait until RXNE flag */
+ if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SPI_FLAG_RXNE, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
+ {
+ /* Error on the CRC reception */
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+ }
+ /* Read CRC */
+ tmpreg = hspi->Instance->DR;
+ /* To avoid GCC warning */
+ UNUSED(tmpreg);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Disable Rx/Tx DMA Request (done by default to handle the case master rx direction 2 lines) */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
+
+ /* Check the end of the transaction */
+ if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
+ {
+ /* Disable SPI peripheral */
+ __HAL_SPI_DISABLE(hspi);
+ }
+
+ hspi->RxXferCount = 0U;
+ hspi->State = HAL_SPI_STATE_READY;
+
+#if (USE_SPI_CRC != 0U)
+ /* Check if CRC error occurred */
+ if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
+ {
+ /* Check if CRC error is valid or not (workaround to be applied or not) */
+ if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+
+ /* Reset CRC Calculation */
+ SPI_RESET_CRC(hspi);
+ }
+ else
+ {
+ __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
+ }
+ }
+#endif /* USE_SPI_CRC */
+
+ if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+ {
+ HAL_SPI_ErrorCallback(hspi);
+ return;
+ }
+ }
+ HAL_SPI_RxCpltCallback(hspi);
+}
+
+/**
+ * @brief DMA SPI transmit receive process complete callback.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ uint32_t tickstart = 0U;
+#if (USE_SPI_CRC != 0U)
+ __IO int16_t tmpreg = 0U;
+#endif /* USE_SPI_CRC */
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+
+ if((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC)
+ {
+#if (USE_SPI_CRC != 0U)
+ /* CRC handling */
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ /* Wait the CRC data */
+ if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+ }
+ /* Read CRC to Flush DR and RXNE flag */
+ tmpreg = hspi->Instance->DR;
+ /* To avoid GCC warning */
+ UNUSED(tmpreg);
+ }
+#endif /* USE_SPI_CRC */
+ /* Check the end of the transaction */
+ if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ }
+
+ /* Disable Rx/Tx DMA Request */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
+
+ hspi->TxXferCount = 0U;
+ hspi->RxXferCount = 0U;
+ hspi->State = HAL_SPI_STATE_READY;
+
+#if (USE_SPI_CRC != 0U)
+ /* Check if CRC error occurred */
+ if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
+ {
+ /* Check if CRC error is valid or not (workaround to be applied or not) */
+ if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+
+ /* Reset CRC Calculation */
+ SPI_RESET_CRC(hspi);
+ }
+ else
+ {
+ __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
+ }
+ }
+#endif /* USE_SPI_CRC */
+
+ if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+ {
+ HAL_SPI_ErrorCallback(hspi);
+ return;
+ }
+ }
+ HAL_SPI_TxRxCpltCallback(hspi);
+}
+
+/**
+ * @brief DMA SPI half transmit process complete callback.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ HAL_SPI_TxHalfCpltCallback(hspi);
+}
+
+/**
+ * @brief DMA SPI half receive process complete callback
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ HAL_SPI_RxHalfCpltCallback(hspi);
+}
+
+/**
+ * @brief DMA SPI half transmit receive process complete callback.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ HAL_SPI_TxRxHalfCpltCallback(hspi);
+}
+
+/**
+ * @brief DMA SPI communication error callback.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SPI_DMAError(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef* hspi = (SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+/* Stop the disable DMA transfer on SPI side */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
+
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
+ hspi->State = HAL_SPI_STATE_READY;
+ HAL_SPI_ErrorCallback(hspi);
+}
+
+/**
+ * @brief DMA SPI communication abort callback, when initiated by HAL services on Error
+ * (To be called at end of DMA Abort procedure following error occurrence).
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ hspi->RxXferCount = 0U;
+ hspi->TxXferCount = 0U;
+
+ HAL_SPI_ErrorCallback(hspi);
+}
+
+/**
+ * @brief DMA SPI Tx communication abort callback, when initiated by user
+ * (To be called at end of DMA Tx Abort procedure following user abort request).
+ * @note When this callback is executed, User Abort complete call back is called only if no
+ * Abort still ongoing for Rx DMA Handle.
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
+ SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ hspi->hdmatx->XferAbortCallback = NULL;
+
+ /* Disable Tx DMA Request */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN );
+
+ /* Wait until TXE flag is set */
+ do
+ {
+ if(count-- == 0U)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ break;
+ }
+ }
+ while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
+
+ /* Check if an Abort process is still ongoing */
+ if(hspi->hdmarx != NULL)
+ {
+ if(hspi->hdmarx->XferAbortCallback != NULL)
+ {
+ return;
+ }
+ }
+
+ /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+ hspi->RxXferCount = 0U;
+ hspi->TxXferCount = 0U;
+
+ /* Reset errorCode */
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+
+ /* Restore hspi->State to Ready */
+ hspi->State = HAL_SPI_STATE_READY;
+
+ /* Call user Abort complete callback */
+ HAL_SPI_AbortCpltCallback(hspi);
+}
+
+/**
+ * @brief DMA SPI Rx communication abort callback, when initiated by user
+ * (To be called at end of DMA Rx Abort procedure following user abort request).
+ * @note When this callback is executed, User Abort complete call back is called only if no
+ * Abort still ongoing for Tx DMA Handle.
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ /* Disable SPI Peripheral */
+ __HAL_SPI_DISABLE(hspi);
+
+ hspi->hdmarx->XferAbortCallback = NULL;
+
+ /* Disable Rx DMA Request */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
+
+ /* Check if an Abort process is still ongoing */
+ if(hspi->hdmatx != NULL)
+ {
+ if(hspi->hdmatx->XferAbortCallback != NULL)
+ {
+ return;
+ }
+ }
+
+ /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+ hspi->RxXferCount = 0U;
+ hspi->TxXferCount = 0U;
+
+ /* Reset errorCode */
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+
+ /* Clear the Error flags in the SR register */
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+
+ /* Restore hspi->State to Ready */
+ hspi->State = HAL_SPI_STATE_READY;
+
+ /* Call user Abort complete callback */
+ HAL_SPI_AbortCpltCallback(hspi);
+}
+
+/**
+ * @brief Rx 8-bit handler for Transmit and Receive in Interrupt mode.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
+{
+ /* Receive data in 8bit mode */
+ *hspi->pRxBuffPtr++ = *((__IO uint8_t *)&hspi->Instance->DR);
+ hspi->RxXferCount--;
+
+ /* check end of the reception */
+ if(hspi->RxXferCount == 0U)
+ {
+#if (USE_SPI_CRC != 0U)
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ hspi->RxISR = SPI_2linesRxISR_8BITCRC;
+ return;
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Disable RXNE interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
+
+ if(hspi->TxXferCount == 0U)
+ {
+ SPI_CloseRxTx_ISR(hspi);
+ }
+ }
+}
+
+#if (USE_SPI_CRC != 0U)
+/**
+ * @brief Rx 8-bit handler for Transmit and Receive in Interrupt mode.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi)
+{
+ __IO uint8_t tmpreg = 0U;
+
+ /* Read data register to flush CRC */
+ tmpreg = *((__IO uint8_t *)&hspi->Instance->DR);
+
+ /* To avoid GCC warning */
+
+ UNUSED(tmpreg);
+
+ /* Disable RXNE interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
+
+ if(hspi->TxXferCount == 0U)
+ {
+ SPI_CloseRxTx_ISR(hspi);
+ }
+}
+#endif /* USE_SPI_CRC */
+
+/**
+ * @brief Tx 8-bit handler for Transmit and Receive in Interrupt mode.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
+{
+ *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr++);
+ hspi->TxXferCount--;
+
+ /* check the end of the transmission */
+ if(hspi->TxXferCount == 0U)
+ {
+#if (USE_SPI_CRC != 0U)
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
+ return;
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Disable TXE interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
+
+ if(hspi->RxXferCount == 0U)
+ {
+ SPI_CloseRxTx_ISR(hspi);
+ }
+ }
+}
+
+/**
+ * @brief Rx 16-bit handler for Transmit and Receive in Interrupt mode.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
+{
+ /* Receive data in 16 Bit mode */
+ *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;
+ hspi->pRxBuffPtr += sizeof(uint16_t);
+ hspi->RxXferCount--;
+
+ if(hspi->RxXferCount == 0U)
+ {
+#if (USE_SPI_CRC != 0U)
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ hspi->RxISR = SPI_2linesRxISR_16BITCRC;
+ return;
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Disable RXNE interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE);
+
+ if(hspi->TxXferCount == 0U)
+ {
+ SPI_CloseRxTx_ISR(hspi);
+ }
+ }
+}
+
+#if (USE_SPI_CRC != 0U)
+/**
+ * @brief Manage the CRC 16-bit receive for Transmit and Receive in Interrupt mode.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi)
+{
+ /* Receive data in 16 Bit mode */
+ __IO uint16_t tmpreg = 0U;
+
+ /* Read data register to flush CRC */
+ tmpreg = hspi->Instance->DR;
+
+ /* To avoid GCC warning */
+ UNUSED(tmpreg);
+
+ /* Disable RXNE interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE);
+
+ SPI_CloseRxTx_ISR(hspi);
+}
+#endif /* USE_SPI_CRC */
+
+/**
+ * @brief Tx 16-bit handler for Transmit and Receive in Interrupt mode.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
+{
+ /* Transmit data in 16 Bit mode */
+ hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
+ hspi->pTxBuffPtr += sizeof(uint16_t);
+ hspi->TxXferCount--;
+
+ /* Enable CRC Transmission */
+ if(hspi->TxXferCount == 0U)
+ {
+#if (USE_SPI_CRC != 0U)
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
+ return;
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Disable TXE interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
+
+ if(hspi->RxXferCount == 0U)
+ {
+ SPI_CloseRxTx_ISR(hspi);
+ }
+ }
+}
+
+#if (USE_SPI_CRC != 0U)
+/**
+ * @brief Manage the CRC 8-bit receive in Interrupt context.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi)
+{
+ __IO uint8_t tmpreg = 0U;
+
+ /* Read data register to flush CRC */
+ tmpreg = *((__IO uint8_t*)&hspi->Instance->DR);
+
+ /* To avoid GCC warning */
+ UNUSED(tmpreg);
+
+ SPI_CloseRx_ISR(hspi);
+}
+#endif /* USE_SPI_CRC */
+
+/**
+ * @brief Manage the receive 8-bit in Interrupt context.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
+{
+ *hspi->pRxBuffPtr++ = (*(__IO uint8_t *)&hspi->Instance->DR);
+ hspi->RxXferCount--;
+
+#if (USE_SPI_CRC != 0U)
+ /* Enable CRC Transmission */
+ if((hspi->RxXferCount == 1U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
+ {
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ }
+#endif /* USE_SPI_CRC */
+
+ if(hspi->RxXferCount == 0U)
+ {
+#if (USE_SPI_CRC != 0U)
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ hspi->RxISR = SPI_RxISR_8BITCRC;
+ return;
+ }
+#endif /* USE_SPI_CRC */
+ SPI_CloseRx_ISR(hspi);
+ }
+}
+
+#if (USE_SPI_CRC != 0U)
+/**
+ * @brief Manage the CRC 16-bit receive in Interrupt context.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi)
+{
+ __IO uint16_t tmpreg = 0U;
+
+ /* Read data register to flush CRC */
+ tmpreg = hspi->Instance->DR;
+
+ /* To avoid GCC warning */
+ UNUSED(tmpreg);
+
+ /* Disable RXNE and ERR interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
+
+ SPI_CloseRx_ISR(hspi);
+}
+#endif /* USE_SPI_CRC */
+
+/**
+ * @brief Manage the 16-bit receive in Interrupt context.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
+{
+ *((uint16_t *)hspi->pRxBuffPtr) = hspi->Instance->DR;
+ hspi->pRxBuffPtr += sizeof(uint16_t);
+ hspi->RxXferCount--;
+
+#if (USE_SPI_CRC != 0U)
+ /* Enable CRC Transmission */
+ if((hspi->RxXferCount == 1U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
+ {
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ }
+#endif /* USE_SPI_CRC */
+
+ if(hspi->RxXferCount == 0U)
+ {
+#if (USE_SPI_CRC != 0U)
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ hspi->RxISR = SPI_RxISR_16BITCRC;
+ return;
+ }
+#endif /* USE_SPI_CRC */
+ SPI_CloseRx_ISR(hspi);
+ }
+}
+
+/**
+ * @brief Handle the data 8-bit transmit in Interrupt mode.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
+{
+ *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr++);
+ hspi->TxXferCount--;
+
+ if(hspi->TxXferCount == 0U)
+ {
+#if (USE_SPI_CRC != 0U)
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ /* Enable CRC Transmission */
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ }
+#endif /* USE_SPI_CRC */
+ SPI_CloseTx_ISR(hspi);
+ }
+}
+
+/**
+ * @brief Handle the data 16-bit transmit in Interrupt mode.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
+{
+ /* Transmit data in 16 Bit mode */
+ hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
+ hspi->pTxBuffPtr += sizeof(uint16_t);
+ hspi->TxXferCount--;
+
+ if(hspi->TxXferCount == 0U)
+ {
+#if (USE_SPI_CRC != 0U)
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ /* Enable CRC Transmission */
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ }
+#endif /* USE_SPI_CRC */
+ SPI_CloseTx_ISR(hspi);
+ }
+}
+
+/**
+ * @brief Handle SPI Communication Timeout.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param Flag: SPI flag to check
+ * @param State: flag state to check
+ * @param Timeout: Timeout duration
+ * @param Tickstart: tick start value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, uint32_t State, uint32_t Timeout, uint32_t Tickstart)
+{
+ while((((hspi->Instance->SR & Flag) == (Flag)) ? SET : RESET) != State)
+ {
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) >= Timeout))
+ {
+ /* Disable the SPI and reset the CRC: the CRC value should be cleared
+ on both master and slave sides in order to resynchronize the master
+ and slave for their respective CRC calculation */
+
+ /* Disable TXE, RXNE and ERR interrupts for the interrupt process */
+ __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
+
+ if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
+ {
+ /* Disable SPI peripheral */
+ __HAL_SPI_DISABLE(hspi);
+ }
+
+ /* Reset CRC Calculation */
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ }
+
+ hspi->State= HAL_SPI_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hspi);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ return HAL_OK;
+}
+/**
+ * @brief Handle to check BSY flag before start a new transaction.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param Timeout: Timeout duration
+ * @param Tickstart: tick start value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef SPI_CheckFlag_BSY(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart)
+{
+ /* Control the BSY flag */
+ if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, Timeout, Tickstart) != HAL_OK)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ return HAL_TIMEOUT;
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief Handle the end of the RXTX transaction.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi)
+{
+ uint32_t tickstart = 0U;
+ __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
+ /* Init tickstart for timeout managment*/
+ tickstart = HAL_GetTick();
+
+ /* Disable ERR interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR);
+
+ /* Wait until TXE flag is set */
+ do
+ {
+ if(count-- == 0U)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ break;
+ }
+ }
+ while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
+
+ /* Check the end of the transaction */
+ if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart)!=HAL_OK)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ }
+
+ /* Clear overrun flag in 2 Lines communication mode because received is not read */
+ if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
+ {
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Check if CRC error occurred */
+ if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
+ {
+ /* Check if CRC error is valid or not (workaround to be applied or not) */
+ if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
+ {
+ hspi->State = HAL_SPI_STATE_READY;
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+
+ /* Reset CRC Calculation */
+ SPI_RESET_CRC(hspi);
+
+ HAL_SPI_ErrorCallback(hspi);
+ }
+ else
+ {
+ __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
+ }
+ }
+ else
+ {
+#endif /* USE_SPI_CRC */
+ if(hspi->ErrorCode == HAL_SPI_ERROR_NONE)
+ {
+ if(hspi->State == HAL_SPI_STATE_BUSY_RX)
+ {
+ hspi->State = HAL_SPI_STATE_READY;
+ HAL_SPI_RxCpltCallback(hspi);
+ }
+ else
+ {
+ hspi->State = HAL_SPI_STATE_READY;
+ HAL_SPI_TxRxCpltCallback(hspi);
+ }
+ }
+ else
+ {
+ hspi->State = HAL_SPI_STATE_READY;
+ HAL_SPI_ErrorCallback(hspi);
+ }
+#if (USE_SPI_CRC != 0U)
+ }
+#endif /* USE_SPI_CRC */
+}
+
+/**
+ * @brief Handle the end of the RX transaction.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi)
+{
+ /* Disable RXNE and ERR interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
+
+ /* Check the end of the transaction */
+ if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
+ {
+ /* Disable SPI peripheral */
+ __HAL_SPI_DISABLE(hspi);
+ }
+
+ /* Clear overrun flag in 2 Lines communication mode because received is not read */
+ if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
+ {
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+ }
+ hspi->State = HAL_SPI_STATE_READY;
+
+#if (USE_SPI_CRC != 0U)
+ /* Check if CRC error occurred */
+ if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
+ {
+ /* Check if CRC error is valid or not (workaround to be applied or not) */
+ if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+
+ /* Reset CRC Calculation */
+ SPI_RESET_CRC(hspi);
+
+ HAL_SPI_ErrorCallback(hspi);
+ }
+ else
+ {
+ __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
+ }
+ }
+ else
+ {
+#endif /* USE_SPI_CRC */
+ if(hspi->ErrorCode == HAL_SPI_ERROR_NONE)
+ {
+ HAL_SPI_RxCpltCallback(hspi);
+ }
+ else
+ {
+ HAL_SPI_ErrorCallback(hspi);
+ }
+#if (USE_SPI_CRC != 0U)
+ }
+#endif /* USE_SPI_CRC */
+}
+
+/**
+ * @brief Handle the end of the TX transaction.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi)
+{
+ uint32_t tickstart = 0U;
+ __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
+
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+
+ /* Wait until TXE flag is set */
+ do
+ {
+ if(count-- == 0U)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ break;
+ }
+ }
+ while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
+
+ /* Disable TXE and ERR interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR));
+
+ /* Check Busy flag */
+ if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ }
+
+ /* Clear overrun flag in 2 Lines communication mode because received is not read */
+ if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
+ {
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+ }
+
+ hspi->State = HAL_SPI_STATE_READY;
+ if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+ {
+ HAL_SPI_ErrorCallback(hspi);
+ }
+ else
+ {
+ HAL_SPI_TxCpltCallback(hspi);
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @brief Handle abort a Tx or Rx transaction.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi)
+{
+ __IO uint32_t tmpreg = 0U;
+ __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
+
+ /* Wait until TXE flag is set */
+ do
+ {
+ if(count-- == 0U)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ break;
+ }
+ }
+ while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
+
+ /* Disable SPI Peripheral */
+ __HAL_SPI_DISABLE(hspi);
+
+ /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */
+ CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXEIE | SPI_CR2_RXNEIE | SPI_CR2_ERRIE));
+
+ /* Flush DR Register */
+ tmpreg = (*(__IO uint32_t *)&hspi->Instance->DR);
+
+ /* To avoid GCC warning */
+ UNUSED(tmpreg);
+}
+
+/**
+ * @brief Handle abort a Tx or Rx transaction.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi)
+{
+ /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */
+ CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXEIE | SPI_CR2_RXNEIE | SPI_CR2_ERRIE));
+
+ /* Disable SPI Peripheral */
+ __HAL_SPI_DISABLE(hspi);
+}
+
+/**
+ * @brief Checks if encountered CRC error could be corresponding to wrongly detected errors
+ * according to SPI instance, Device type, and revision ID.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval CRC error validity (SPI_INVALID_CRC_ERROR or SPI_VALID_CRC_ERROR).
+*/
+__weak uint8_t SPI_ISCRCErrorValid(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+
+ return (SPI_VALID_CRC_ERROR);
+}
+/**
+ * @}
+ */
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi_ex.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi_ex.c
new file mode 100644
index 0000000..86cab57
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi_ex.c
@@ -0,0 +1,231 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_spi_ex.c
+ * @author MCD Application Team
+ * @brief Extended SPI HAL module driver.
+ *
+ * This file provides firmware functions to manage the following
+ * functionalities SPI extension peripheral:
+ * + Extended Peripheral Control functions
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup SPI
+ * @{
+ */
+#ifdef HAL_SPI_MODULE_ENABLED
+
+/** @defgroup SPI_Private_Variables SPI Private Variables
+ * @{
+ */
+#if (USE_SPI_CRC != 0U)
+/* Variable used to determine if device is impacted by implementation of workaround
+ related to wrong CRC errors detection on SPI2. Conditions in which this workaround has to be applied, are:
+ - STM32F101CDE/STM32F103CDE
+ - Revision ID : Z
+ - SPI2
+ - In receive only mode, with CRC calculation enabled, at the end of the CRC reception,
+ the software needs to check the CRCERR flag. If it is found set, read back the SPI_RXCRC:
+ + If the value is 0, the complete data transfer is successful.
+ + Otherwise, one or more errors have been detected during the data transfer by CPU or DMA.
+ If CRCERR is found reset, the complete data transfer is considered successful.
+*/
+uint8_t uCRCErrorWorkaroundCheck = 0U;
+#endif /* USE_SPI_CRC */
+/**
+ * @}
+ */
+
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @addtogroup SPI_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup SPI_Exported_Functions_Group1
+ *
+ * @{
+ */
+
+/**
+ * @brief Initializes the SPI according to the specified parameters
+ * in the SPI_InitTypeDef and create the associated handle.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
+{
+ /* Check the SPI handle allocation */
+ if(hspi == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
+ assert_param(IS_SPI_MODE(hspi->Init.Mode));
+ assert_param(IS_SPI_DIRECTION(hspi->Init.Direction));
+ assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize));
+ assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity));
+ assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase));
+ assert_param(IS_SPI_NSS(hspi->Init.NSS));
+ assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
+ assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit));
+
+#if (USE_SPI_CRC != 0U)
+ assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation));
+ if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial));
+ }
+#else
+ hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
+#endif /* USE_SPI_CRC */
+
+ if(hspi->State == HAL_SPI_STATE_RESET)
+ {
+ /* Init the low level hardware : GPIO, CLOCK, NVIC... */
+ HAL_SPI_MspInit(hspi);
+ }
+
+ hspi->State = HAL_SPI_STATE_BUSY;
+
+ /* Disble the selected SPI peripheral */
+ __HAL_SPI_DISABLE(hspi);
+
+ /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/
+ /* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management,
+ Communication speed, First bit and CRC calculation state */
+ WRITE_REG(hspi->Instance->CR1, (hspi->Init.Mode | hspi->Init.Direction | hspi->Init.DataSize |
+ hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) |
+ hspi->Init.BaudRatePrescaler | hspi->Init.FirstBit | hspi->Init.CRCCalculation) );
+
+ /* Configure : NSS management */
+ WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) | hspi->Init.TIMode));
+
+ /*---------------------------- SPIx CRCPOLY Configuration ------------------*/
+ /* Configure : CRC Polynomial */
+ WRITE_REG(hspi->Instance->CRCPR, hspi->Init.CRCPolynomial);
+
+#if defined(SPI_I2SCFGR_I2SMOD)
+ /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */
+ CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD);
+#endif /* SPI_I2SCFGR_I2SMOD */
+
+#if (USE_SPI_CRC != 0U)
+#if defined (STM32F101xE) || defined (STM32F103xE)
+ /* Check RevisionID value for identifying if Device is Rev Z (0x0001) in order to enable workaround for
+ CRC errors wrongly detected */
+ /* Pb is that ES_STM32F10xxCDE also identify an issue in Debug registers access while not in Debug mode.
+ Revision ID information is only available in Debug mode, so Workaround could not be implemented
+ to distinguish Rev Z devices (issue present) from more recent version (issue fixed).
+ So, in case of Revison Z F101 or F103 devices, below variable should be assigned to 1 */
+ uCRCErrorWorkaroundCheck = 0U;
+#else
+ uCRCErrorWorkaroundCheck = 0U;
+#endif /* STM32F101xE || STM32F103xE */
+#endif /* USE_SPI_CRC */
+
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->State = HAL_SPI_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup SPI_Private_Functions
+ * @{
+ */
+#if (USE_SPI_CRC != 0U)
+/**
+ * @brief Checks if encountered CRC error could be corresponding to wrongly detected errors
+ * according to SPI instance, Device type, and revision ID.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval CRC error validity (SPI_INVALID_CRC_ERROR or SPI_VALID_CRC_ERROR).
+*/
+uint8_t SPI_ISCRCErrorValid(SPI_HandleTypeDef *hspi)
+{
+#if defined(STM32F101xE) || defined(STM32F103xE)
+ /* Check how to handle this CRC error (workaround to be applied or not) */
+ /* If CRC errors could be wrongly detected (issue 2.15.2 in STM32F10xxC/D/E silicon limitations ES (DocID14732 Rev 13) */
+ if((uCRCErrorWorkaroundCheck != 0U) && (hspi->Instance == SPI2))
+ {
+ if(hspi->Instance->RXCRCR == 0U)
+ {
+ return (SPI_INVALID_CRC_ERROR);
+ }
+ }
+ return (SPI_VALID_CRC_ERROR);
+#else
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+
+ return (SPI_VALID_CRC_ERROR);
+#endif
+}
+#endif /* USE_SPI_CRC */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_SPI_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sram.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sram.c
new file mode 100644
index 0000000..dc861cc
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sram.c
@@ -0,0 +1,690 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_sram.c
+ * @author MCD Application Team
+ * @brief SRAM HAL module driver.
+ * This file provides a generic firmware to drive SRAM memories
+ * mounted as external device.
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ This driver is a generic layered driver which contains a set of APIs used to
+ control SRAM memories. It uses the FSMC layer functions to interface
+ with SRAM devices.
+ The following sequence should be followed to configure the FSMC to interface
+ with SRAM/PSRAM memories:
+
+ (#) Declare a SRAM_HandleTypeDef handle structure, for example:
+ SRAM_HandleTypeDef hsram; and:
+
+ (++) Fill the SRAM_HandleTypeDef handle "Init" field with the allowed
+ values of the structure member.
+
+ (++) Fill the SRAM_HandleTypeDef handle "Instance" field with a predefined
+ base register instance for NOR or SRAM device
+
+ (++) Fill the SRAM_HandleTypeDef handle "Extended" field with a predefined
+ base register instance for NOR or SRAM extended mode
+
+ (#) Declare two FSMC_NORSRAM_TimingTypeDef structures, for both normal and extended
+ mode timings; for example:
+ FSMC_NORSRAM_TimingTypeDef Timing and FSMC_NORSRAM_TimingTypeDef ExTiming;
+ and fill its fields with the allowed values of the structure member.
+
+ (#) Initialize the SRAM Controller by calling the function HAL_SRAM_Init(). This function
+ performs the following sequence:
+
+ (##) MSP hardware layer configuration using the function HAL_SRAM_MspInit()
+ (##) Control register configuration using the FSMC NORSRAM interface function
+ FSMC_NORSRAM_Init()
+ (##) Timing register configuration using the FSMC NORSRAM interface function
+ FSMC_NORSRAM_Timing_Init()
+ (##) Extended mode Timing register configuration using the FSMC NORSRAM interface function
+ FSMC_NORSRAM_Extended_Timing_Init()
+ (##) Enable the SRAM device using the macro __FSMC_NORSRAM_ENABLE()
+
+ (#) At this stage you can perform read/write accesses from/to the memory connected
+ to the NOR/SRAM Bank. You can perform either polling or DMA transfer using the
+ following APIs:
+ (++) HAL_SRAM_Read()/HAL_SRAM_Write() for polling read/write access
+ (++) HAL_SRAM_Read_DMA()/HAL_SRAM_Write_DMA() for DMA read/write transfer
+
+ (#) You can also control the SRAM device by calling the control APIs HAL_SRAM_WriteOperation_Enable()/
+ HAL_SRAM_WriteOperation_Disable() to respectively enable/disable the SRAM write operation
+
+ (#) You can continuously monitor the SRAM device HAL state by calling the function
+ HAL_SRAM_GetState()
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_SRAM_MODULE_ENABLED
+
+#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG) || defined(STM32F100xE)
+
+/** @defgroup SRAM SRAM
+ * @brief SRAM driver modules
+ * @{
+ */
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup SRAM_Exported_Functions SRAM Exported Functions
+ * @{
+ */
+
+/** @defgroup SRAM_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions.
+ *
+ @verbatim
+ ==============================================================================
+ ##### SRAM Initialization and de_initialization functions #####
+ ==============================================================================
+ [..] This section provides functions allowing to initialize/de-initialize
+ the SRAM memory
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Performs the SRAM device initialization sequence
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param Timing: Pointer to SRAM control timing structure
+ * @param ExtTiming: Pointer to SRAM extended mode timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Init(SRAM_HandleTypeDef *hsram, FSMC_NORSRAM_TimingTypeDef *Timing, FSMC_NORSRAM_TimingTypeDef *ExtTiming)
+{
+ /* Check the SRAM handle parameter */
+ if(hsram == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ if(hsram->State == HAL_SRAM_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hsram->Lock = HAL_UNLOCKED;
+
+ /* Initialize the low level hardware (MSP) */
+ HAL_SRAM_MspInit(hsram);
+ }
+
+ /* Initialize SRAM control Interface */
+ FSMC_NORSRAM_Init(hsram->Instance, &(hsram->Init));
+
+ /* Initialize SRAM timing Interface */
+ FSMC_NORSRAM_Timing_Init(hsram->Instance, Timing, hsram->Init.NSBank);
+
+ /* Initialize SRAM extended mode timing Interface */
+ FSMC_NORSRAM_Extended_Timing_Init(hsram->Extended, ExtTiming, hsram->Init.NSBank, hsram->Init.ExtendedMode);
+
+ /* Enable the NORSRAM device */
+ __FSMC_NORSRAM_ENABLE(hsram->Instance, hsram->Init.NSBank);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Performs the SRAM device De-initialization sequence.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_DeInit(SRAM_HandleTypeDef *hsram)
+{
+ /* De-Initialize the low level hardware (MSP) */
+ HAL_SRAM_MspDeInit(hsram);
+
+ /* Configure the SRAM registers with their reset values */
+ FSMC_NORSRAM_DeInit(hsram->Instance, hsram->Extended, hsram->Init.NSBank);
+
+ hsram->State = HAL_SRAM_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief SRAM MSP Init.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval None
+ */
+__weak void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsram);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SRAM_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief SRAM MSP DeInit.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval None
+ */
+__weak void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef *hsram)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsram);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SRAM_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DMA transfer complete callback.
+ * @param hdma: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval None
+ */
+__weak void HAL_SRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdma);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SRAM_DMA_XferCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DMA transfer complete error callback.
+ * @param hdma: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval None
+ */
+__weak void HAL_SRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hdma);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SRAM_DMA_XferErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SRAM_Exported_Functions_Group2 Input Output and memory control functions
+ * @brief Input Output and memory control functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### SRAM Input and Output functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to use and control the SRAM memory
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Reads 8-bit buffer from SRAM memory.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress: Pointer to read start address
+ * @param pDstBuffer: Pointer to destination buffer
+ * @param BufferSize: Size of the buffer to read from memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Read_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pDstBuffer, uint32_t BufferSize)
+{
+ __IO uint8_t * psramaddress = (uint8_t *)pAddress;
+
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Read data from memory */
+ for(; BufferSize != 0U; BufferSize--)
+ {
+ *pDstBuffer = *(__IO uint8_t *)psramaddress;
+ pDstBuffer++;
+ psramaddress++;
+ }
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Writes 8-bit buffer to SRAM memory.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress: Pointer to write start address
+ * @param pSrcBuffer: Pointer to source buffer to write
+ * @param BufferSize: Size of the buffer to write to memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Write_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pSrcBuffer, uint32_t BufferSize)
+{
+ __IO uint8_t * psramaddress = (uint8_t *)pAddress;
+
+ /* Check the SRAM controller state */
+ if(hsram->State == HAL_SRAM_STATE_PROTECTED)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Write data to memory */
+ for(; BufferSize != 0U; BufferSize--)
+ {
+ *(__IO uint8_t *)psramaddress = *pSrcBuffer;
+ pSrcBuffer++;
+ psramaddress++;
+ }
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Reads 16-bit buffer from SRAM memory.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress: Pointer to read start address
+ * @param pDstBuffer: Pointer to destination buffer
+ * @param BufferSize: Size of the buffer to read from memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Read_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pDstBuffer, uint32_t BufferSize)
+{
+ __IO uint16_t * psramaddress = (uint16_t *)pAddress;
+
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Read data from memory */
+ for(; BufferSize != 0U; BufferSize--)
+ {
+ *pDstBuffer = *(__IO uint16_t *)psramaddress;
+ pDstBuffer++;
+ psramaddress++;
+ }
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Writes 16-bit buffer to SRAM memory.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress: Pointer to write start address
+ * @param pSrcBuffer: Pointer to source buffer to write
+ * @param BufferSize: Size of the buffer to write to memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Write_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pSrcBuffer, uint32_t BufferSize)
+{
+ __IO uint16_t * psramaddress = (uint16_t *)pAddress;
+
+ /* Check the SRAM controller state */
+ if(hsram->State == HAL_SRAM_STATE_PROTECTED)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Write data to memory */
+ for(; BufferSize != 0U; BufferSize--)
+ {
+ *(__IO uint16_t *)psramaddress = *pSrcBuffer;
+ pSrcBuffer++;
+ psramaddress++;
+ }
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Reads 32-bit buffer from SRAM memory.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress: Pointer to read start address
+ * @param pDstBuffer: Pointer to destination buffer
+ * @param BufferSize: Size of the buffer to read from memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Read_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize)
+{
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Read data from memory */
+ for(; BufferSize != 0U; BufferSize--)
+ {
+ *pDstBuffer = *(__IO uint32_t *)pAddress;
+ pDstBuffer++;
+ pAddress++;
+ }
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Writes 32-bit buffer to SRAM memory.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress: Pointer to write start address
+ * @param pSrcBuffer: Pointer to source buffer to write
+ * @param BufferSize: Size of the buffer to write to memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Write_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize)
+{
+ /* Check the SRAM controller state */
+ if(hsram->State == HAL_SRAM_STATE_PROTECTED)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Write data to memory */
+ for(; BufferSize != 0U; BufferSize--)
+ {
+ *(__IO uint32_t *)pAddress = *pSrcBuffer;
+ pSrcBuffer++;
+ pAddress++;
+ }
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Reads a Words data from the SRAM memory using DMA transfer.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress: Pointer to read start address
+ * @param pDstBuffer: Pointer to destination buffer
+ * @param BufferSize: Size of the buffer to read from memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Read_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize)
+{
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Configure DMA user callbacks */
+ hsram->hdma->XferCpltCallback = HAL_SRAM_DMA_XferCpltCallback;
+ hsram->hdma->XferErrorCallback = HAL_SRAM_DMA_XferErrorCallback;
+
+ /* Enable the DMA Channel */
+ HAL_DMA_Start_IT(hsram->hdma, (uint32_t)pAddress, (uint32_t)pDstBuffer, (uint32_t)BufferSize);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Writes a Words data buffer to SRAM memory using DMA transfer.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @param pAddress: Pointer to write start address
+ * @param pSrcBuffer: Pointer to source buffer to write
+ * @param BufferSize: Size of the buffer to write to memory
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_Write_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize)
+{
+ /* Check the SRAM controller state */
+ if(hsram->State == HAL_SRAM_STATE_PROTECTED)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Configure DMA user callbacks */
+ hsram->hdma->XferCpltCallback = HAL_SRAM_DMA_XferCpltCallback;
+ hsram->hdma->XferErrorCallback = HAL_SRAM_DMA_XferErrorCallback;
+
+ /* Enable the DMA Channel */
+ HAL_DMA_Start_IT(hsram->hdma, (uint32_t)pSrcBuffer, (uint32_t)pAddress, (uint32_t)BufferSize);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SRAM_Exported_Functions_Group3 Control functions
+ * @brief Control functions
+ *
+@verbatim
+ ==============================================================================
+ ##### SRAM Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control dynamically
+ the SRAM interface.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables dynamically SRAM write operation.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_WriteOperation_Enable(SRAM_HandleTypeDef *hsram)
+{
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Enable write operation */
+ FSMC_NORSRAM_WriteOperation_Enable(hsram->Instance, hsram->Init.NSBank);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically SRAM write operation.
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SRAM_WriteOperation_Disable(SRAM_HandleTypeDef *hsram)
+{
+ /* Process Locked */
+ __HAL_LOCK(hsram);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_BUSY;
+
+ /* Disable write operation */
+ FSMC_NORSRAM_WriteOperation_Disable(hsram->Instance, hsram->Init.NSBank);
+
+ /* Update the SRAM controller state */
+ hsram->State = HAL_SRAM_STATE_PROTECTED;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hsram);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SRAM_Exported_Functions_Group4 Peripheral State functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ==============================================================================
+ ##### SRAM State functions #####
+ ==============================================================================
+ [..]
+ This subsection permits to get in run-time the status of the SRAM controller
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns the SRAM controller state
+ * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains
+ * the configuration information for SRAM module.
+ * @retval HAL state
+ */
+HAL_SRAM_StateTypeDef HAL_SRAM_GetState(SRAM_HandleTypeDef *hsram)
+{
+ return hsram->State;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG || STM32F100xE */
+#endif /* HAL_SRAM_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c
similarity index 100%
rename from assets/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c
rename to templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c
new file mode 100644
index 0000000..8bf9926
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c
@@ -0,0 +1,1773 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_tim_ex.c
+ * @author MCD Application Team
+ * @brief TIM HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Timer Extended peripheral:
+ * + Time Hall Sensor Interface Initialization
+ * + Time Hall Sensor Interface Start
+ * + Time Complementary signal bread and dead time configuration
+ * + Time Master and Slave synchronization configuration
+ * + Timer remapping capabilities configuration
+ @verbatim
+ ==============================================================================
+ ##### TIMER Extended features #####
+ ==============================================================================
+ [..]
+ The Timer Extended features include:
+ (#) Complementary outputs with programmable dead-time for :
+ (++) Output Compare
+ (++) PWM generation (Edge and Center-aligned Mode)
+ (++) One-pulse mode output
+ (#) Synchronization circuit to control the timer with external signals and to
+ interconnect several timers together.
+ (#) Break input to put the timer output signals in reset state or in a known state.
+ (#) Supports incremental (quadrature) encoder and hall-sensor circuitry for
+ positioning purposes
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) Initialize the TIM low level resources by implementing the following functions
+ depending from feature used :
+ (++) Complementary Output Compare : HAL_TIM_OC_MspInit()
+ (++) Complementary PWM generation : HAL_TIM_PWM_MspInit()
+ (++) Complementary One-pulse mode output : HAL_TIM_OnePulse_MspInit()
+ (++) Hall Sensor output : HAL_TIMEx_HallSensor_MspInit()
+
+ (#) Initialize the TIM low level resources :
+ (##) Enable the TIM interface clock using __HAL_RCC_TIMx_CLK_ENABLE();
+ (##) TIM pins configuration
+ (+++) Enable the clock for the TIM GPIOs using the following function:
+ __HAL_RCC_GPIOx_CLK_ENABLE();
+ (+++) Configure these TIM pins in Alternate function mode using HAL_GPIO_Init();
+
+ (#) The external Clock can be configured, if needed (the default clock is the
+ internal clock from the APBx), using the following function:
+ HAL_TIM_ConfigClockSource, the clock configuration should be done before
+ any start function.
+
+ (#) Configure the TIM in the desired functioning mode using one of the
+ initialization function of this driver:
+ (++) HAL_TIMEx_HallSensor_Init and HAL_TIMEx_ConfigCommutationEvent: to use the
+ Timer Hall Sensor Interface and the commutation event with the corresponding
+ Interrupt and DMA request if needed (Note that One Timer is used to interface
+ with the Hall sensor Interface and another Timer should be used to use
+ the commutation event).
+
+ (#) Activate the TIM peripheral using one of the start functions:
+ (++) Complementary Output Compare : HAL_TIMEx_OCN_Start(), HAL_TIMEx_OCN_Start_DMA(), HAL_TIMEx_OCN_Start_IT()
+ (++) Complementary PWM generation : HAL_TIMEx_PWMN_Start(), HAL_TIMEx_PWMN_Start_DMA(), HAL_TIMEx_PWMN_Start_IT()
+ (++) Complementary One-pulse mode output : HAL_TIMEx_OnePulseN_Start(), HAL_TIMEx_OnePulseN_Start_IT()
+ (++) Hall Sensor output : HAL_TIMEx_HallSensor_Start(), HAL_TIMEx_HallSensor_Start_DMA(), HAL_TIMEx_HallSensor_Start_IT().
+
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup TIMEx TIMEx
+ * @brief TIM Extended HAL module driver
+ * @{
+ */
+
+#ifdef HAL_TIM_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+
+#if defined (STM32F100xB) || defined (STM32F100xE) || \
+ defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
+ defined (STM32F105xC) || defined (STM32F107xC)
+/** @defgroup TIMEx_Private_Functions TIMEx Private Functions
+ * @{
+ */
+static void TIM_CCxNChannelCmd(TIM_TypeDef* TIMx, uint32_t Channel, uint32_t ChannelNState);
+/**
+ * @}
+ */
+#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
+ /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
+ /* defined(STM32F105xC) || defined(STM32F107xC) */
+
+/* Exported functions ---------------------------------------------------------*/
+
+/** @defgroup TIMEx_Exported_Functions TIMEx Exported Functions
+ * @{
+ */
+
+
+/** @defgroup TIMEx_Exported_Functions_Group1 Timer Hall Sensor functions
+ * @brief Timer Hall Sensor functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Timer Hall Sensor functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure TIM HAL Sensor.
+ (+) De-initialize TIM HAL Sensor.
+ (+) Start the Hall Sensor Interface.
+ (+) Stop the Hall Sensor Interface.
+ (+) Start the Hall Sensor Interface and enable interrupts.
+ (+) Stop the Hall Sensor Interface and disable interrupts.
+ (+) Start the Hall Sensor Interface and enable DMA transfers.
+ (+) Stop the Hall Sensor Interface and disable DMA transfers.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Initializes the TIM Hall Sensor Interface and create the associated handle.
+ * @param htim : TIM Encoder Interface handle
+ * @param sConfig : TIM Hall Sensor configuration structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, TIM_HallSensor_InitTypeDef* sConfig)
+{
+ TIM_OC_InitTypeDef OC_Config;
+
+ /* Check the TIM handle allocation */
+ if(htim == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
+ assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
+ assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload));
+ assert_param(IS_TIM_IC_POLARITY(sConfig->IC1Polarity));
+ assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler));
+ assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter));
+
+ if(htim->State == HAL_TIM_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ htim->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
+ HAL_TIMEx_HallSensor_MspInit(htim);
+ }
+
+ /* Set the TIM state */
+ htim->State= HAL_TIM_STATE_BUSY;
+
+ /* Configure the Time base in the Encoder Mode */
+ TIM_Base_SetConfig(htim->Instance, &htim->Init);
+
+ /* Configure the Channel 1 as Input Channel to interface with the three Outputs of the Hall sensor */
+ TIM_TI1_SetConfig(htim->Instance, sConfig->IC1Polarity, TIM_ICSELECTION_TRC, sConfig->IC1Filter);
+
+ /* Reset the IC1PSC Bits */
+ htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC;
+ /* Set the IC1PSC value */
+ htim->Instance->CCMR1 |= sConfig->IC1Prescaler;
+
+ /* Enable the Hall sensor interface (XOR function of the three inputs) */
+ htim->Instance->CR2 |= TIM_CR2_TI1S;
+
+ /* Select the TIM_TS_TI1F_ED signal as Input trigger for the TIM */
+ htim->Instance->SMCR &= ~TIM_SMCR_TS;
+ htim->Instance->SMCR |= TIM_TS_TI1F_ED;
+
+ /* Use the TIM_TS_TI1F_ED signal to reset the TIM counter each edge detection */
+ htim->Instance->SMCR &= ~TIM_SMCR_SMS;
+ htim->Instance->SMCR |= TIM_SLAVEMODE_RESET;
+
+ /* Program channel 2 in PWM 2 mode with the desired Commutation_Delay*/
+ OC_Config.OCFastMode = TIM_OCFAST_DISABLE;
+ OC_Config.OCIdleState = TIM_OCIDLESTATE_RESET;
+ OC_Config.OCMode = TIM_OCMODE_PWM2;
+ OC_Config.OCNIdleState = TIM_OCNIDLESTATE_RESET;
+ OC_Config.OCNPolarity = TIM_OCNPOLARITY_HIGH;
+ OC_Config.OCPolarity = TIM_OCPOLARITY_HIGH;
+ OC_Config.Pulse = sConfig->Commutation_Delay;
+
+ TIM_OC2_SetConfig(htim->Instance, &OC_Config);
+
+ /* Select OC2REF as trigger output on TRGO: write the MMS bits in the TIMx_CR2
+ register to 101 */
+ htim->Instance->CR2 &= ~TIM_CR2_MMS;
+ htim->Instance->CR2 |= TIM_TRGO_OC2REF;
+
+ /* Initialize the TIM state*/
+ htim->State= HAL_TIM_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the TIM Hall Sensor interface
+ * @param htim : TIM Hall Sensor handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ /* Disable the TIM Peripheral Clock */
+ __HAL_TIM_DISABLE(htim);
+
+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
+ HAL_TIMEx_HallSensor_MspDeInit(htim);
+
+ /* Change TIM state */
+ htim->State = HAL_TIM_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the TIM Hall Sensor MSP.
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIMEx_HallSensor_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes TIM Hall Sensor MSP.
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIMEx_HallSensor_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Starts the TIM Hall Sensor Interface.
+ * @param htim : TIM Hall Sensor handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
+
+ /* Enable the Input Capture channel 1
+ (in the Hall Sensor Interface the 3 possible channels that are used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Hall sensor Interface.
+ * @param htim : TIM Hall Sensor handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
+
+ /* Disable the Input Capture channel 1
+ (in the Hall Sensor Interface the 3 possible channels that are used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM Hall Sensor Interface in interrupt mode.
+ * @param htim : TIM Hall Sensor handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
+
+ /* Enable the capture compare Interrupts 1 event */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
+
+ /* Enable the Input Capture channel 1
+ (in the Hall Sensor Interface the 3 possible channels that are used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Hall Sensor Interface in interrupt mode.
+ * @param htim : TIM handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
+
+ /* Disable the Input Capture channel 1
+ (in the Hall Sensor Interface the 3 possible channels that are used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
+
+ /* Disable the capture compare Interrupts event */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM Hall Sensor Interface in DMA mode.
+ * @param htim : TIM Hall Sensor handle
+ * @param pData : The destination Buffer address.
+ * @param Length : The length of data to be transferred from TIM peripheral to memory.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
+
+ if((htim->State == HAL_TIM_STATE_BUSY))
+ {
+ return HAL_BUSY;
+ }
+ else if((htim->State == HAL_TIM_STATE_READY))
+ {
+ if(((uint32_t)pData == 0U) && (Length > 0U))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ htim->State = HAL_TIM_STATE_BUSY;
+ }
+ }
+ /* Enable the Input Capture channel 1
+ (in the Hall Sensor Interface the 3 possible channels that are used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
+
+ /* Set the DMA Input Capture 1 Callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt;
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel for Capture 1*/
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData, Length);
+
+ /* Enable the capture compare 1 Interrupt */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Hall Sensor Interface in DMA mode.
+ * @param htim : TIM handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
+
+ /* Disable the Input Capture channel 1
+ (in the Hall Sensor Interface the 3 possible channels that are used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
+
+
+ /* Disable the capture compare Interrupts 1 event */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+#if defined (STM32F100xB) || defined (STM32F100xE) || \
+ defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
+ defined (STM32F105xC) || defined (STM32F107xC)
+
+/** @defgroup TIMEx_Exported_Functions_Group2 Timer Complementary Output Compare functions
+ * @brief Timer Complementary Output Compare functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Timer Complementary Output Compare functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Start the Complementary Output Compare/PWM.
+ (+) Stop the Complementary Output Compare/PWM.
+ (+) Start the Complementary Output Compare/PWM and enable interrupts.
+ (+) Stop the Complementary Output Compare/PWM and disable interrupts.
+ (+) Start the Complementary Output Compare/PWM and enable DMA transfers.
+ (+) Stop the Complementary Output Compare/PWM and disable DMA transfers.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Starts the TIM Output Compare signal generation on the complementary
+ * output.
+ * @param htim : TIM Output Compare handle
+ * @param Channel : TIM Channel to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ /* Enable the Capture compare channel N */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
+
+ /* Enable the Main Ouput */
+ __HAL_TIM_MOE_ENABLE(htim);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Output Compare signal generation on the complementary
+ * output.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ /* Disable the Capture compare channel N */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
+
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM Output Compare signal generation in interrupt mode
+ * on the complementary output.
+ * @param htim : TIM OC handle
+ * @param Channel : TIM Channel to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Enable the TIM Output Compare interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Enable the TIM Output Compare interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Enable the TIM Output Compare interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Enable the TIM Break interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK);
+
+ /* Enable the Capture compare channel N */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
+
+ /* Enable the Main Ouput */
+ __HAL_TIM_MOE_ENABLE(htim);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Output Compare signal generation in interrupt mode
+ * on the complementary output.
+ * @param htim : TIM Output Compare handle
+ * @param Channel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ uint32_t tmpccer = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Disable the TIM Output Compare interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Disable the TIM Output Compare interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Disable the TIM Output Compare interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Disable the Capture compare channel N */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
+
+ /* Disable the TIM Break interrupt (only if no more channel is active) */
+ tmpccer = htim->Instance->CCER;
+ if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == RESET)
+ {
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK);
+ }
+
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM Output Compare signal generation in DMA mode
+ * on the complementary output.
+ * @param htim : TIM Output Compare handle
+ * @param Channel : TIM Channel to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @param pData : The source Buffer address.
+ * @param Length : The length of data to be transferred from memory to TIM peripheral
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ if((htim->State == HAL_TIM_STATE_BUSY))
+ {
+ return HAL_BUSY;
+ }
+ else if((htim->State == HAL_TIM_STATE_READY))
+ {
+ if(((uint32_t)pData == 0U) && (Length > 0U))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ htim->State = HAL_TIM_STATE_BUSY;
+ }
+ }
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length);
+
+ /* Enable the TIM Output Compare DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length);
+
+ /* Enable the TIM Output Compare DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,Length);
+
+ /* Enable the TIM Output Compare DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Enable the Capture compare channel N */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
+
+ /* Enable the Main Ouput */
+ __HAL_TIM_MOE_ENABLE(htim);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Output Compare signal generation in DMA mode
+ * on the complementary output.
+ * @param htim : TIM Output Compare handle
+ * @param Channel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Disable the TIM Output Compare DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Disable the TIM Output Compare DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Disable the TIM Output Compare DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Disable the Capture compare channel N */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
+
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Change the htim state */
+ htim->State = HAL_TIM_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIMEx_Exported_Functions_Group3 Timer Complementary PWM functions
+ * @brief Timer Complementary PWM functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Timer Complementary PWM functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Start the Complementary PWM.
+ (+) Stop the Complementary PWM.
+ (+) Start the Complementary PWM and enable interrupts.
+ (+) Stop the Complementary PWM and disable interrupts.
+ (+) Start the Complementary PWM and enable DMA transfers.
+ (+) Stop the Complementary PWM and disable DMA transfers.
+ (+) Start the Complementary Input Capture measurement.
+ (+) Stop the Complementary Input Capture.
+ (+) Start the Complementary Input Capture and enable interrupts.
+ (+) Stop the Complementary Input Capture and disable interrupts.
+ (+) Start the Complementary Input Capture and enable DMA transfers.
+ (+) Stop the Complementary Input Capture and disable DMA transfers.
+ (+) Start the Complementary One Pulse generation.
+ (+) Stop the Complementary One Pulse.
+ (+) Start the Complementary One Pulse and enable interrupts.
+ (+) Stop the Complementary One Pulse and disable interrupts.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Starts the PWM signal generation on the complementary output.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channel to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ /* Enable the complementary PWM output */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
+
+ /* Enable the Main Ouput */
+ __HAL_TIM_MOE_ENABLE(htim);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the PWM signal generation on the complementary output.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ /* Disable the complementary PWM output */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
+
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the PWM signal generation in interrupt mode on the
+ * complementary output.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Enable the TIM Capture/Compare 1 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Enable the TIM Capture/Compare 2 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Enable the TIM Capture/Compare 3 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Enable the TIM Break interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK);
+
+ /* Enable the complementary PWM output */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
+
+ /* Enable the Main Ouput */
+ __HAL_TIM_MOE_ENABLE(htim);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the PWM signal generation in interrupt mode on the
+ * complementary output.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ uint32_t tmpccer = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Disable the TIM Capture/Compare 1 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Disable the TIM Capture/Compare 2 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Disable the TIM Capture/Compare 3 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Disable the complementary PWM output */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
+
+ /* Disable the TIM Break interrupt (only if no more channel is active) */
+ tmpccer = htim->Instance->CCER;
+ if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == RESET)
+ {
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK);
+ }
+
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM PWM signal generation in DMA mode on the
+ * complementary output
+ * @param htim : TIM handle
+ * @param Channel : TIM Channel to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @param pData : The source Buffer address.
+ * @param Length : The length of data to be transferred from memory to TIM peripheral
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ if((htim->State == HAL_TIM_STATE_BUSY))
+ {
+ return HAL_BUSY;
+ }
+ else if((htim->State == HAL_TIM_STATE_READY))
+ {
+ if(((uint32_t)pData == 0U) && (Length > 0U))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ htim->State = HAL_TIM_STATE_BUSY;
+ }
+ }
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length);
+
+ /* Enable the TIM Capture/Compare 1 DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length);
+
+ /* Enable the TIM Capture/Compare 2 DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,Length);
+
+ /* Enable the TIM Capture/Compare 3 DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Enable the complementary PWM output */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
+
+ /* Enable the Main Ouput */
+ __HAL_TIM_MOE_ENABLE(htim);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM PWM signal generation in DMA mode on the complementary
+ * output
+ * @param htim : TIM handle
+ * @param Channel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Disable the TIM Capture/Compare 1 DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Disable the TIM Capture/Compare 2 DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Disable the TIM Capture/Compare 3 DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Disable the complementary PWM output */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
+
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Change the htim state */
+ htim->State = HAL_TIM_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIMEx_Exported_Functions_Group4 Timer Complementary One Pulse functions
+ * @brief Timer Complementary One Pulse functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Timer Complementary One Pulse functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Start the Complementary One Pulse generation.
+ (+) Stop the Complementary One Pulse.
+ (+) Start the Complementary One Pulse and enable interrupts.
+ (+) Stop the Complementary One Pulse and disable interrupts.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Starts the TIM One Pulse signal generation on the complemetary
+ * output.
+ * @param htim : TIM One Pulse handle
+ * @param OutputChannel : TIM Channel to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
+
+ /* Enable the complementary One Pulse output */
+ TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE);
+
+ /* Enable the Main Ouput */
+ __HAL_TIM_MOE_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM One Pulse signal generation on the complementary
+ * output.
+ * @param htim : TIM One Pulse handle
+ * @param OutputChannel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
+{
+
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
+
+ /* Disable the complementary One Pulse output */
+ TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE);
+
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM One Pulse signal generation in interrupt mode on the
+ * complementary channel.
+ * @param htim : TIM One Pulse handle
+ * @param OutputChannel : TIM Channel to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
+
+ /* Enable the TIM Capture/Compare 1 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
+
+ /* Enable the TIM Capture/Compare 2 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
+
+ /* Enable the complementary One Pulse output */
+ TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE);
+
+ /* Enable the Main Ouput */
+ __HAL_TIM_MOE_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM One Pulse signal generation in interrupt mode on the
+ * complementary channel.
+ * @param htim : TIM One Pulse handle
+ * @param OutputChannel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
+
+ /* Disable the TIM Capture/Compare 1 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
+
+ /* Disable the TIM Capture/Compare 2 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
+
+ /* Disable the complementary One Pulse output */
+ TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE);
+
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
+ /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
+ /* defined(STM32F105xC) || defined(STM32F107xC) */
+
+/** @defgroup TIMEx_Exported_Functions_Group5 Peripheral Control functions
+ * @brief Peripheral Control functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral Control functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Configure the commutation event in case of use of the Hall sensor interface.
+ (+) Configure Complementary channels, break features and dead time.
+ (+) Configure Master synchronization.
+
+@endverbatim
+ * @{
+ */
+
+#if defined (STM32F100xB) || defined (STM32F100xE) || \
+ defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
+ defined (STM32F105xC) || defined (STM32F107xC)
+
+/**
+ * @brief Configure the TIM commutation event sequence.
+ * @note: this function is mandatory to use the commutation event in order to
+ * update the configuration at each commutation detection on the TRGI input of the Timer,
+ * the typical use of this feature is with the use of another Timer(interface Timer)
+ * configured in Hall sensor interface, this interface Timer will generate the
+ * commutation at its TRGO output (connected to Timer used in this function) each time
+ * the TI1 of the Interface Timer detect a commutation at its input TI1.
+ * @param htim : TIM handle
+ * @param InputTrigger : the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
+ * This parameter can be one of the following values:
+ * @arg TIM_TS_ITR0: Internal trigger 0 selected
+ * @arg TIM_TS_ITR1: Internal trigger 1 selected
+ * @arg TIM_TS_ITR2: Internal trigger 2 selected
+ * @arg TIM_TS_ITR3: Internal trigger 3 selected
+ * @arg TIM_TS_NONE: No trigger is needed
+ * @param CommutationSource : the Commutation Event source
+ * This parameter can be one of the following values:
+ * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
+ * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
+
+ __HAL_LOCK(htim);
+
+ if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
+ (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
+ {
+ /* Select the Input trigger */
+ htim->Instance->SMCR &= ~TIM_SMCR_TS;
+ htim->Instance->SMCR |= InputTrigger;
+ }
+
+ /* Select the Capture Compare preload feature */
+ htim->Instance->CR2 |= TIM_CR2_CCPC;
+ /* Select the Commutation event source */
+ htim->Instance->CR2 &= ~TIM_CR2_CCUS;
+ htim->Instance->CR2 |= CommutationSource;
+
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Configure the TIM commutation event sequence with interrupt.
+ * @note: this function is mandatory to use the commutation event in order to
+ * update the configuration at each commutation detection on the TRGI input of the Timer,
+ * the typical use of this feature is with the use of another Timer(interface Timer)
+ * configured in Hall sensor interface, this interface Timer will generate the
+ * commutation at its TRGO output (connected to Timer used in this function) each time
+ * the TI1 of the Interface Timer detect a commutation at its input TI1.
+ * @param htim : TIM handle
+ * @param InputTrigger : the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
+ * This parameter can be one of the following values:
+ * @arg TIM_TS_ITR0: Internal trigger 0 selected
+ * @arg TIM_TS_ITR1: Internal trigger 1 selected
+ * @arg TIM_TS_ITR2: Internal trigger 2 selected
+ * @arg TIM_TS_ITR3: Internal trigger 3 selected
+ * @arg TIM_TS_NONE: No trigger is needed
+ * @param CommutationSource : the Commutation Event source
+ * This parameter can be one of the following values:
+ * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
+ * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent_IT(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
+
+ __HAL_LOCK(htim);
+
+ if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
+ (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
+ {
+ /* Select the Input trigger */
+ htim->Instance->SMCR &= ~TIM_SMCR_TS;
+ htim->Instance->SMCR |= InputTrigger;
+ }
+
+ /* Select the Capture Compare preload feature */
+ htim->Instance->CR2 |= TIM_CR2_CCPC;
+ /* Select the Commutation event source */
+ htim->Instance->CR2 &= ~TIM_CR2_CCUS;
+ htim->Instance->CR2 |= CommutationSource;
+
+ /* Enable the Commutation Interrupt Request */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_COM);
+
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Configure the TIM commutation event sequence with DMA.
+ * @note: this function is mandatory to use the commutation event in order to
+ * update the configuration at each commutation detection on the TRGI input of the Timer,
+ * the typical use of this feature is with the use of another Timer(interface Timer)
+ * configured in Hall sensor interface, this interface Timer will generate the
+ * commutation at its TRGO output (connected to Timer used in this function) each time
+ * the TI1 of the Interface Timer detect a commutation at its input TI1.
+ * @note: The user should configure the DMA in his own software, in This function only the COMDE bit is set
+ * @param htim : TIM handle
+ * @param InputTrigger : the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
+ * This parameter can be one of the following values:
+ * @arg TIM_TS_ITR0: Internal trigger 0 selected
+ * @arg TIM_TS_ITR1: Internal trigger 1 selected
+ * @arg TIM_TS_ITR2: Internal trigger 2 selected
+ * @arg TIM_TS_ITR3: Internal trigger 3 selected
+ * @arg TIM_TS_NONE: No trigger is needed
+ * @param CommutationSource : the Commutation Event source
+ * This parameter can be one of the following values:
+ * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
+ * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent_DMA(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
+
+ __HAL_LOCK(htim);
+
+ if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
+ (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
+ {
+ /* Select the Input trigger */
+ htim->Instance->SMCR &= ~TIM_SMCR_TS;
+ htim->Instance->SMCR |= InputTrigger;
+ }
+
+ /* Select the Capture Compare preload feature */
+ htim->Instance->CR2 |= TIM_CR2_CCPC;
+ /* Select the Commutation event source */
+ htim->Instance->CR2 &= ~TIM_CR2_CCUS;
+ htim->Instance->CR2 |= CommutationSource;
+
+ /* Enable the Commutation DMA Request */
+ /* Set the DMA Commutation Callback */
+ htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt;
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError;
+
+ /* Enable the Commutation DMA Request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_COM);
+
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Configures the Break feature, dead time, Lock level, OSSI/OSSR State
+ * and the AOE(automatic output enable).
+ * @param htim : TIM handle
+ * @param sBreakDeadTimeConfig : pointer to a TIM_ConfigBreakDeadConfigTypeDef structure that
+ * contains the BDTR Register configuration information for the TIM peripheral.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim,
+ TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig)
+{
+ uint32_t tmpbdtr = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_OSSR_STATE(sBreakDeadTimeConfig->OffStateRunMode));
+ assert_param(IS_TIM_OSSI_STATE(sBreakDeadTimeConfig->OffStateIDLEMode));
+ assert_param(IS_TIM_LOCK_LEVEL(sBreakDeadTimeConfig->LockLevel));
+ assert_param(IS_TIM_DEADTIME(sBreakDeadTimeConfig->DeadTime));
+ assert_param(IS_TIM_BREAK_STATE(sBreakDeadTimeConfig->BreakState));
+ assert_param(IS_TIM_BREAK_POLARITY(sBreakDeadTimeConfig->BreakPolarity));
+ assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(sBreakDeadTimeConfig->AutomaticOutput));
+
+ /* Process Locked */
+ __HAL_LOCK(htim);
+
+ /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State,
+ the OSSI State, the dead time value and the Automatic Output Enable Bit */
+
+ /* Set the BDTR bits */
+ MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, sBreakDeadTimeConfig->DeadTime);
+ MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, sBreakDeadTimeConfig->LockLevel);
+ MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, sBreakDeadTimeConfig->OffStateIDLEMode);
+ MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, sBreakDeadTimeConfig->OffStateRunMode);
+ MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, sBreakDeadTimeConfig->BreakState);
+ MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, sBreakDeadTimeConfig->BreakPolarity);
+ MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, sBreakDeadTimeConfig->AutomaticOutput);
+ MODIFY_REG(tmpbdtr, TIM_BDTR_MOE, sBreakDeadTimeConfig->AutomaticOutput);
+
+ /* Set TIMx_BDTR */
+ htim->Instance->BDTR = tmpbdtr;
+
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
+ /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
+ /* defined(STM32F105xC) || defined(STM32F107xC) */
+
+/**
+ * @brief Configures the TIM in master mode.
+ * @param htim : TIM handle.
+ * @param sMasterConfig : pointer to a TIM_MasterConfigTypeDef structure that
+ * contains the selected trigger output (TRGO) and the Master/Slave
+ * mode.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim, TIM_MasterConfigTypeDef * sMasterConfig)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_MASTER_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_TRGO_SOURCE(sMasterConfig->MasterOutputTrigger));
+ assert_param(IS_TIM_MSM_STATE(sMasterConfig->MasterSlaveMode));
+
+ __HAL_LOCK(htim);
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ /* Reset the MMS Bits */
+ htim->Instance->CR2 &= ~TIM_CR2_MMS;
+ /* Select the TRGO source */
+ htim->Instance->CR2 |= sMasterConfig->MasterOutputTrigger;
+
+ /* Reset the MSM Bit */
+ htim->Instance->SMCR &= ~TIM_SMCR_MSM;
+ /* Set or Reset the MSM Bit */
+ htim->Instance->SMCR |= sMasterConfig->MasterSlaveMode;
+
+ htim->State = HAL_TIM_STATE_READY;
+
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIMEx_Exported_Functions_Group6 Extension Callbacks functions
+ * @brief Extension Callbacks functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Extension Callbacks functions #####
+ ==============================================================================
+ [..]
+ This section provides Extension TIM callback functions:
+ (+) Timer Commutation callback
+ (+) Timer Break callback
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Hall commutation changed callback in non blocking mode
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIMEx_CommutationCallback(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIMEx_CommutationCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Hall Break detection callback in non blocking mode
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIMEx_BreakCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief TIM DMA Commutation callback.
+ * @param hdma : pointer to DMA handle.
+ * @retval None
+ */
+void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma)
+{
+ TIM_HandleTypeDef* htim = ( TIM_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ htim->State= HAL_TIM_STATE_READY;
+
+ HAL_TIMEx_CommutationCallback(htim);
+}
+
+/**
+ * @}
+ */
+
+#if defined (STM32F100xB) || defined (STM32F100xE) || \
+ defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
+ defined (STM32F105xC) || defined (STM32F107xC)
+
+/** @defgroup TIMEx_Exported_Functions_Group7 Extension Peripheral State functions
+ * @brief Extension Peripheral State functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Extension Peripheral State functions #####
+ ==============================================================================
+ [..]
+ This subsection permit to get in run-time the status of the peripheral
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Return the TIM Hall Sensor interface state
+ * @param htim : TIM Hall Sensor handle
+ * @retval HAL state
+ */
+HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(TIM_HandleTypeDef *htim)
+{
+ return htim->State;
+}
+
+/**
+ * @}
+ */
+#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
+ /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
+ /* defined(STM32F105xC) || defined(STM32F107xC) */
+
+/**
+ * @}
+ */
+
+#if defined (STM32F100xB) || defined (STM32F100xE) || \
+ defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
+ defined (STM32F105xC) || defined (STM32F107xC)
+
+/** @addtogroup TIMEx_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the TIM Capture Compare Channel xN.
+ * @param TIMx to select the TIM peripheral
+ * @param 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 ChannelNState : specifies the TIM Channel CCxNE bit new state.
+ * This parameter can be: TIM_CCxN_ENABLE or TIM_CCxN_Disable.
+ * @retval None
+ */
+static void TIM_CCxNChannelCmd(TIM_TypeDef* TIMx, uint32_t Channel, uint32_t ChannelNState)
+{
+ uint32_t tmp = 0U;
+
+ tmp = TIM_CCER_CC1NE << Channel;
+
+ /* Reset the CCxNE Bit */
+ TIMx->CCER &= ~tmp;
+
+ /* Set or reset the CCxNE Bit */
+ TIMx->CCER |= (uint32_t)(ChannelNState << Channel);
+}
+
+/**
+ * @}
+ */
+
+#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
+ /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
+ /* defined(STM32F105xC) || defined(STM32F107xC) */
+
+#endif /* HAL_TIM_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_rtc_alarm_template.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_rtc_alarm_template.c
new file mode 100644
index 0000000..8c1d856
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_rtc_alarm_template.c
@@ -0,0 +1,305 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_timebase_rtc_alarm_template.c
+ * @author MCD Application Team
+ * @brief HAL time base based on the hardware RTC_ALARM.
+ *
+ * This file override the native HAL time base functions (defined as weak)
+ * to use the RTC ALARM for time base generation:
+ * + Intializes the RTC peripheral to increment the seconds registers each 1ms
+ * + The alarm is configured to assert an interrupt when the RTC reaches 1ms
+ * + HAL_IncTick is called at each Alarm event and the time is reset to 00:00:00
+ * + HSE (default), LSE or LSI can be selected as RTC clock source
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ This file must be copied to the application folder and modified as follows:
+ (#) Rename it to 'stm32f1xx_hal_timebase_rtc_alarm.c'
+ (#) Add this file and the RTC HAL drivers to your project and uncomment
+ HAL_RTC_MODULE_ENABLED define in stm32f1xx_hal_conf.h
+
+ [..]
+ (@) HAL RTC alarm and HAL RTC wakeup drivers can’t be used with low power modes:
+ The wake up capability of the RTC may be intrusive in case of prior low power mode
+ configuration requiring different wake up sources.
+ Application/Example behavior is no more guaranteed
+ (@) The stm32f1xx_hal_timebase_tim use is recommended for the Applications/Examples
+ requiring low power modes
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup HAL_TimeBase_RTC_Alarm_Template HAL TimeBase RTC Alarm Template
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/* Uncomment the line below to select the appropriate RTC Clock source for your application:
+ + RTC_CLOCK_SOURCE_HSE: can be selected for applications requiring timing precision.
+ + RTC_CLOCK_SOURCE_LSE: can be selected for applications with low constraint on timing
+ precision.
+ + RTC_CLOCK_SOURCE_LSI: can be selected for applications with low constraint on timing
+ precision.
+ */
+#define RTC_CLOCK_SOURCE_HSE
+/* #define RTC_CLOCK_SOURCE_LSE */
+/* #define RTC_CLOCK_SOURCE_LSI */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+RTC_HandleTypeDef hRTC_Handle;
+/* Private function prototypes -----------------------------------------------*/
+void RTC_Alarm_IRQHandler(void);
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @brief This function configures the RTC_ALARMA as a time base source.
+ * The time source is configured to have 1ms time base with a dedicated
+ * Tick interrupt priority.
+ * @note This function is called automatically at the beginning of program after
+ * reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
+ * @param TickPriority: Tick interrupt priority.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
+{
+ __IO uint32_t counter = 0U;
+
+ RCC_OscInitTypeDef RCC_OscInitStruct;
+ RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
+
+#ifdef RTC_CLOCK_SOURCE_LSE
+ /* Configue LSE as RTC clock soucre */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
+ RCC_OscInitStruct.LSEState = RCC_LSE_ON;
+ PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
+#elif defined (RTC_CLOCK_SOURCE_LSI)
+ /* Configue LSI as RTC clock soucre */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
+ RCC_OscInitStruct.LSIState = RCC_LSI_ON;
+ PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
+#elif defined (RTC_CLOCK_SOURCE_HSE)
+ /* Configue HSE as RTC clock soucre */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
+ RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+ PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV128;
+#else
+#error Please select the RTC Clock source
+#endif /* RTC_CLOCK_SOURCE_LSE */
+
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK)
+ {
+ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) == HAL_OK)
+ {
+ /* Enable RTC Clock */
+ __HAL_RCC_RTC_ENABLE();
+
+ hRTC_Handle.Instance = RTC;
+ /* Configure RTC time base to 10Khz */
+ hRTC_Handle.Init.AsynchPrediv = (HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_RTC) / 10000) - 1;
+ hRTC_Handle.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
+ HAL_RTC_Init(&hRTC_Handle);
+
+ /* Disable the write protection for RTC registers */
+ __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle);
+
+ /* Clear flag alarm A */
+ __HAL_RTC_ALARM_CLEAR_FLAG(&hRTC_Handle, RTC_FLAG_ALRAF);
+
+ counter = 0U;
+ /* Wait till RTC ALRAF flag is set and if Time out is reached exit */
+ while (__HAL_RTC_ALARM_GET_FLAG(&hRTC_Handle, RTC_FLAG_ALRAF) != RESET)
+ {
+ if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
+ {
+ return HAL_ERROR;
+ }
+ }
+
+ /* Set RTC COUNTER MSB word */
+ hRTC_Handle.Instance->ALRH = 0x00U;
+ /* Set RTC COUNTER LSB word */
+ hRTC_Handle.Instance->ALRL = 0x09U;
+
+ /* RTC Alarm Interrupt Configuration: EXTI configuration */
+ __HAL_RTC_ALARM_EXTI_ENABLE_IT();
+ __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE();
+
+ /* Clear Second and overflow flags */
+ CLEAR_BIT(hRTC_Handle.Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW));
+
+ /* Set RTC COUNTER MSB word */
+ hRTC_Handle.Instance->CNTH = 0x00U;
+ /* Set RTC COUNTER LSB word */
+ hRTC_Handle.Instance->CNTL = 0x00U;
+
+ /* Configure the Alarm interrupt */
+ __HAL_RTC_ALARM_ENABLE_IT(&hRTC_Handle, RTC_IT_ALRA);
+
+ /* Enable the write protection for RTC registers */
+ __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle);
+
+ /* Wait till RTC is in INIT state and if Time out is reached exit */
+ counter = 0U;
+ while ((hRTC_Handle.Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
+ {
+ if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
+ {
+ return HAL_ERROR;
+ }
+ }
+
+ HAL_NVIC_SetPriority(RTC_Alarm_IRQn, TickPriority, 0U);
+ HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
+ return HAL_OK;
+ }
+ }
+ return HAL_ERROR;
+}
+
+/**
+ * @brief Suspend Tick increment.
+ * @note Disable the tick increment by disabling RTC ALARM interrupt.
+ * @param None
+ * @retval None
+ */
+void HAL_SuspendTick(void)
+{
+ /* Disable RTC ALARM update Interrupt */
+ __HAL_RTC_ALARM_DISABLE_IT(&hRTC_Handle, RTC_IT_ALRA);
+}
+
+/**
+ * @brief Resume Tick increment.
+ * @note Enable the tick increment by Enabling RTC ALARM interrupt.
+ * @param None
+ * @retval None
+ */
+void HAL_ResumeTick(void)
+{
+ __IO uint32_t counter = 0U;
+
+ /* Disable the write protection for RTC registers */
+ __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle);
+
+ /* Set RTC COUNTER MSB word */
+ hRTC_Handle.Instance->CNTH = 0x00U;
+ /* Set RTC COUNTER LSB word */
+ hRTC_Handle.Instance->CNTL = 0x00U;
+
+ /* Clear Second and overflow flags */
+ CLEAR_BIT(hRTC_Handle.Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW | RTC_FLAG_ALRAF));
+
+ /* Enable RTC ALARM Update interrupt */
+ __HAL_RTC_ALARM_ENABLE_IT(&hRTC_Handle, RTC_IT_ALRA);
+
+ /* Enable the write protection for RTC registers */
+ __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle);
+
+ /* Wait till RTC is in INIT state and if Time out is reached exit */
+ while ((hRTC_Handle.Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
+ {
+ if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
+ {
+ break;
+ }
+ }
+}
+
+/**
+ * @brief ALARM A Event Callback in non blocking mode
+ * @note This function is called when RTC_ALARM interrupt took place, inside
+ * RTC_ALARM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
+ * a global variable "uwTick" used as application time base.
+ * @param hrtc : RTC handle
+ * @retval None
+ */
+void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
+{
+ __IO uint32_t counter = 0U;
+
+ HAL_IncTick();
+
+ __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
+
+ /* Set RTC COUNTER MSB word */
+ WRITE_REG(hrtc->Instance->CNTH, 0x00U);
+ /* Set RTC COUNTER LSB word */
+ WRITE_REG(hrtc->Instance->CNTL, 0x00U);
+
+ /* Clear Second and overflow flags */
+ CLEAR_BIT(hrtc->Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW));
+
+ /* Enable the write protection for RTC registers */
+ __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
+
+ /* Wait till RTC is in INIT state and if Time out is reached exit */
+ while ((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
+ {
+ if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
+ {
+ break;
+ }
+ }
+}
+
+/**
+ * @brief This function handles RTC ALARM interrupt request.
+ * @retval None
+ */
+void RTC_Alarm_IRQHandler(void)
+{
+ HAL_RTC_AlarmIRQHandler(&hRTC_Handle);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_tim_template.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_tim_template.c
new file mode 100644
index 0000000..e3dbd2d
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_timebase_tim_template.c
@@ -0,0 +1,182 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_timebase_tim_template.c
+ * @author MCD Application Team
+ * @brief HAL time base based on the hardware TIM Template.
+ *
+ * This file overrides the native HAL time base functions (defined as weak)
+ * the TIM time base:
+ * + Intializes the TIM peripheral generate a Period elapsed Event each 1ms
+ * + HAL_IncTick is called inside HAL_TIM_PeriodElapsedCallback ie each 1ms
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup HAL_TimeBase_TIM
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+TIM_HandleTypeDef TimHandle;
+/* Private function prototypes -----------------------------------------------*/
+void TIM2_IRQHandler(void);
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @brief This function configures the TIM2 as a time base source.
+ * The time source is configured to have 1ms time base with a dedicated
+ * Tick interrupt priority.
+ * @note This function is called automatically at the beginning of program after
+ * reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
+ * @param TickPriority: Tick interrupt priority.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
+{
+ RCC_ClkInitTypeDef clkconfig;
+ uint32_t uwTimclock, uwAPB1Prescaler = 0U;
+ uint32_t uwPrescalerValue = 0U;
+ uint32_t pFLatency;
+
+ /*Configure the TIM2 IRQ priority */
+ HAL_NVIC_SetPriority(TIM2_IRQn, TickPriority, 0U);
+
+ /* Enable the TIM2 global Interrupt */
+ HAL_NVIC_EnableIRQ(TIM2_IRQn);
+
+ /* Enable TIM2 clock */
+ __HAL_RCC_TIM2_CLK_ENABLE();
+
+ /* Get clock configuration */
+ HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
+
+ /* Get APB1 prescaler */
+ uwAPB1Prescaler = clkconfig.APB1CLKDivider;
+
+ /* Compute TIM2 clock */
+ if (uwAPB1Prescaler == RCC_HCLK_DIV1)
+ {
+ uwTimclock = HAL_RCC_GetPCLK1Freq();
+ }
+ else
+ {
+ uwTimclock = 2 * HAL_RCC_GetPCLK1Freq();
+ }
+
+ /* Compute the prescaler value to have TIM2 counter clock equal to 1MHz */
+ uwPrescalerValue = (uint32_t)((uwTimclock / 1000000U) - 1U);
+
+ /* Initialize TIM2 */
+ TimHandle.Instance = TIM2;
+
+ /* Initialize TIMx peripheral as follow:
+ + Period = [(TIM2CLK/1000) - 1]. to have a (1/1000) s time base.
+ + Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
+ + ClockDivision = 0
+ + Counter direction = Up
+ */
+ TimHandle.Init.Period = (1000000U / 1000U) - 1U;
+ TimHandle.Init.Prescaler = uwPrescalerValue;
+ TimHandle.Init.ClockDivision = 0U;
+ TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
+ TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
+ if (HAL_TIM_Base_Init(&TimHandle) == HAL_OK)
+ {
+ /* Start the TIM time Base generation in interrupt mode */
+ return HAL_TIM_Base_Start_IT(&TimHandle);
+ }
+
+ /* Return function status */
+ return HAL_ERROR;
+}
+
+/**
+ * @brief Suspend Tick increment.
+ * @note Disable the tick increment by disabling TIM2 update interrupt.
+ * @retval None
+ */
+void HAL_SuspendTick(void)
+{
+ /* Disable TIM2 update Interrupt */
+ __HAL_TIM_DISABLE_IT(&TimHandle, TIM_IT_UPDATE);
+}
+
+/**
+ * @brief Resume Tick increment.
+ * @note Enable the tick increment by Enabling TIM2 update interrupt.
+ * @retval None
+ */
+void HAL_ResumeTick(void)
+{
+ /* Enable TIM2 Update interrupt */
+ __HAL_TIM_ENABLE_IT(&TimHandle, TIM_IT_UPDATE);
+}
+
+/**
+ * @brief Period elapsed callback in non blocking mode
+ * @note This function is called when TIM2 interrupt took place, inside
+ * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
+ * a global variable "uwTick" used as application time base.
+ * @param htim : TIM handle
+ * @retval None
+ */
+void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
+{
+ HAL_IncTick();
+}
+
+/**
+ * @brief This function handles TIM interrupt request.
+ * @retval None
+ */
+void TIM2_IRQHandler(void)
+{
+ HAL_TIM_IRQHandler(&TimHandle);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c
new file mode 100644
index 0000000..ef18d11
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c
@@ -0,0 +1,2556 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_uart.c
+ * @author MCD Application Team
+ * @brief UART HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Universal Asynchronous Receiver Transmitter (UART) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ * + Peripheral State and Errors functions
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The UART HAL driver can be used as follows:
+
+ (#) Declare a UART_HandleTypeDef handle structure.
+ (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API:
+ (##) Enable the USARTx interface clock.
+ (##) UART pins configuration:
+ (+++) Enable the clock for the UART GPIOs.
+ (+++) Configure the UART pins (TX as alternate function pull-up, RX as alternate function Input).
+ (##) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT()
+ and HAL_UART_Receive_IT() APIs):
+ (+++) Configure the USARTx interrupt priority.
+ (+++) Enable the NVIC USART IRQ handle.
+ (##) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
+ and HAL_UART_Receive_DMA() APIs):
+ (+++) Declare a DMA handle structure for the Tx/Rx channel.
+ (+++) Enable the DMAx interface clock.
+ (+++) Configure the declared DMA handle structure with the required
+ Tx/Rx parameters.
+ (+++) Configure the DMA Tx/Rx channel.
+ (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle.
+ (+++) Configure the priority and enable the NVIC for the transfer complete
+ interrupt on the DMA Tx/Rx channel.
+ (+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
+ (used for last byte sending completion detection in DMA non circular mode)
+
+ (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
+ flow control and Mode(Receiver/Transmitter) in the huart Init structure.
+
+ (#) For the UART asynchronous mode, initialize the UART registers by calling
+ the HAL_UART_Init() API.
+
+ (#) For the UART Half duplex mode, initialize the UART registers by calling
+ the HAL_HalfDuplex_Init() API.
+
+ (#) For the LIN mode, initialize the UART registers by calling the HAL_LIN_Init() API.
+
+ (#) For the Multi-Processor mode, initialize the UART registers by calling
+ the HAL_MultiProcessor_Init() API.
+
+ [..]
+ (@) The specific UART interrupts (Transmission complete interrupt,
+ RXNE interrupt and Error Interrupts) will be managed using the macros
+ __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit
+ and receive process.
+
+ [..]
+ (@) These APIs (HAL_UART_Init() and HAL_HalfDuplex_Init()) configure also the
+ low level Hardware GPIO, CLOCK, CORTEX...etc) by calling the customized
+ HAL_UART_MspInit() API.
+
+ [..]
+ Three operation modes are available within this driver:
+
+ *** Polling mode IO operation ***
+ =================================
+ [..]
+ (+) Send an amount of data in blocking mode using HAL_UART_Transmit()
+ (+) Receive an amount of data in blocking mode using HAL_UART_Receive()
+
+ *** Interrupt mode IO operation ***
+ ===================================
+ [..]
+ (+) Send an amount of data in non blocking mode using HAL_UART_Transmit_IT()
+ (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode using HAL_UART_Receive_IT()
+ (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_RxCpltCallback
+ (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_UART_ErrorCallback
+
+ *** DMA mode IO operation ***
+ ==============================
+ [..]
+ (+) Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA()
+ (+) At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback
+ (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode (DMA) using HAL_UART_Receive_DMA()
+ (+) At reception end of half transfer HAL_UART_RxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_RxHalfCpltCallback
+ (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_RxCpltCallback
+ (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_UART_ErrorCallback
+ (+) Pause the DMA Transfer using HAL_UART_DMAPause()
+ (+) Resume the DMA Transfer using HAL_UART_DMAResume()
+ (+) Stop the DMA Transfer using HAL_UART_DMAStop()
+
+ *** UART HAL driver macros list ***
+ =============================================
+ [..]
+ Below the list of most used macros in UART HAL driver.
+
+ (+) __HAL_UART_ENABLE: Enable the UART peripheral
+ (+) __HAL_UART_DISABLE: Disable the UART peripheral
+ (+) __HAL_UART_GET_FLAG : Check whether the specified UART flag is set or not
+ (+) __HAL_UART_CLEAR_FLAG : Clear the specified UART pending flag
+ (+) __HAL_UART_ENABLE_IT: Enable the specified UART interrupt
+ (+) __HAL_UART_DISABLE_IT: Disable the specified UART interrupt
+ (+) __HAL_UART_GET_IT_SOURCE: Check whether the specified UART interrupt has occurred or not
+
+ [..]
+ (@) You can refer to the UART HAL driver header file for more useful macros
+ @endverbatim
+ [..]
+ (@) Additionnal remark: If the parity is enabled, then the MSB bit of the data written
+ in the data register is transmitted but is changed by the parity bit.
+ Depending on the frame length defined by the M bit (8-bits or 9-bits),
+ the possible UART frame formats are as listed in the following table:
+ +-------------------------------------------------------------+
+ | M bit | PCE bit | UART frame |
+ |---------------------|---------------------------------------|
+ | 0 | 0 | | SB | 8 bit data | STB | |
+ |---------|-----------|---------------------------------------|
+ | 0 | 1 | | SB | 7 bit data | PB | STB | |
+ |---------|-----------|---------------------------------------|
+ | 1 | 0 | | SB | 9 bit data | STB | |
+ |---------|-----------|---------------------------------------|
+ | 1 | 1 | | SB | 8 bit data | PB | STB | |
+ +-------------------------------------------------------------+
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup UART UART
+ * @brief HAL UART module driver
+ * @{
+ */
+#ifdef HAL_UART_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @addtogroup UART_Private_Constants
+ * @{
+ */
+/**
+ * @}
+ */
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @addtogroup UART_Private_Functions
+ * @{
+ */
+static void UART_EndTxTransfer(UART_HandleTypeDef *huart);
+static void UART_EndRxTransfer(UART_HandleTypeDef *huart);
+static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMAError(DMA_HandleTypeDef *hdma);
+static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
+static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
+static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
+static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
+static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
+static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart);
+static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart);
+static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart);
+static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout);
+static void UART_SetConfig (UART_HandleTypeDef *huart);
+/**
+ * @}
+ */
+/* Exported functions ---------------------------------------------------------*/
+/** @defgroup UART_Exported_Functions UART Exported Functions
+ * @{
+ */
+
+/** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and Configuration functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
+ in asynchronous mode.
+ (+) For the asynchronous mode only these parameters can be configured:
+ (++) Baud Rate
+ (++) Word Length
+ (++) Stop Bit
+ (++) Parity: If the parity is enabled, then the MSB bit of the data written
+ in the data register is transmitted but is changed by the parity bit.
+ Depending on the frame length defined by the M bit (8-bits or 9-bits),
+ please refer to Reference manual for possible UART frame formats.
+ (++) Hardware flow control
+ (++) Receiver/transmitter modes
+ (++) Over Sampling Method
+ [..]
+ The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init() and HAL_MultiProcessor_Init() APIs
+ follow respectively the UART asynchronous, UART Half duplex, LIN and Multi-Processor
+ configuration procedures (details for the procedures are available in reference manuals
+ (RM0008 for STM32F10Xxx MCUs and RM0041 for STM32F100xx MCUs)).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the UART mode according to the specified parameters in
+ * the UART_InitTypeDef and create the associated handle.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
+{
+ /* Check the UART handle allocation */
+ if(huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ if(huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
+ {
+ /* The hardware flow control is available only for USART1, USART2, USART3 */
+ assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
+ assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
+ }
+ else
+ {
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+ }
+ assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
+#if defined(USART_CR1_OVER8)
+ assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
+#endif /* USART_CR1_OVER8 */
+
+ if(huart->gState == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware */
+ HAL_UART_MspInit(huart);
+ }
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In asynchronous mode, the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register,
+ - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState= HAL_UART_STATE_READY;
+ huart->RxState= HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the half-duplex mode according to the specified
+ * parameters in the UART_InitTypeDef and create the associated handle.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
+{
+ /* Check the UART handle allocation */
+ if(huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
+ assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
+#if defined(USART_CR1_OVER8)
+ assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
+#endif /* USART_CR1_OVER8 */
+ if(huart->gState == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+ /* Init the low level hardware */
+ HAL_UART_MspInit(huart);
+ }
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In half-duplex mode, the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register,
+ - SCEN and IREN bits in the USART_CR3 register.*/
+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN));
+
+ /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
+ SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state*/
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState= HAL_UART_STATE_READY;
+ huart->RxState= HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the LIN mode according to the specified
+ * parameters in the UART_InitTypeDef and create the associated handle.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param BreakDetectLength: Specifies the LIN break detection length.
+ * This parameter can be one of the following values:
+ * @arg UART_LINBREAKDETECTLENGTH_10B: 10-bit break detection
+ * @arg UART_LINBREAKDETECTLENGTH_11B: 11-bit break detection
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength)
+{
+ /* Check the UART handle allocation */
+ if(huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the LIN UART instance */
+ assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
+ /* Check the Break detection length parameter */
+ assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength));
+ assert_param(IS_UART_LIN_WORD_LENGTH(huart->Init.WordLength));
+#if defined(USART_CR1_OVER8)
+ assert_param(IS_UART_LIN_OVERSAMPLING(huart->Init.OverSampling));
+#endif /* USART_CR1_OVER8 */
+
+ if(huart->gState == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+ /* Init the low level hardware */
+ HAL_UART_MspInit(huart);
+ }
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In LIN mode, the following bits must be kept cleared:
+ - CLKEN bits in the USART_CR2 register,
+ - SCEN and IREN bits in the USART_CR3 register.*/
+ CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN);
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN));
+
+ /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
+ SET_BIT(huart->Instance->CR2, USART_CR2_LINEN);
+
+ /* Set the USART LIN Break detection length. */
+ MODIFY_REG(huart->Instance->CR2, USART_CR2_LBDL, BreakDetectLength);
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state*/
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState= HAL_UART_STATE_READY;
+ huart->RxState= HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the Multi-Processor mode according to the specified
+ * parameters in the UART_InitTypeDef and create the associated handle.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param Address: USART address
+ * @param WakeUpMethod: specifies the USART wake-up method.
+ * This parameter can be one of the following values:
+ * @arg UART_WAKEUPMETHOD_IDLELINE: Wake-up by an idle line detection
+ * @arg UART_WAKEUPMETHOD_ADDRESSMARK: Wake-up by an address mark
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
+{
+ /* Check the UART handle allocation */
+ if(huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check UART instance capabilities */
+ assert_param(IS_UART_MULTIPROCESSOR_INSTANCE(huart->Instance));
+
+ /* Check the Address & wake up method parameters */
+ assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
+ assert_param(IS_UART_ADDRESS(Address));
+ assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
+#if defined(USART_CR1_OVER8)
+ assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
+#endif /* USART_CR1_OVER8 */
+
+ if(huart->gState == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+ /* Init the low level hardware */
+ HAL_UART_MspInit(huart);
+ }
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In Multi-Processor mode, the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register,
+ - SCEN, HDSEL and IREN bits in the USART_CR3 register */
+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
+
+ /* Set the USART address node */
+ MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, Address);
+
+ /* Set the wake up method by setting the WAKE bit in the CR1 register */
+ MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod);
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the UART peripheral.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
+{
+ /* Check the UART handle allocation */
+ if(huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* DeInit the low level hardware */
+ HAL_UART_MspDeInit(huart);
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_RESET;
+ huart->RxState = HAL_UART_STATE_RESET;
+
+ /* Process Unlock */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief UART MSP Init.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief UART MSP DeInit.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Exported_Functions_Group2 IO operation functions
+ * @brief UART Transmit and Receive functions
+ *
+@verbatim
+ ==============================================================================
+ ##### IO operation functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the UART asynchronous
+ and Half duplex data transfers.
+
+ (#) There are two modes of transfer:
+ (++) Blocking mode: The communication is performed in polling mode.
+ The HAL status of all data processing is returned by the same function
+ after finishing transfer.
+ (++) Non blocking mode: The communication is performed using Interrupts
+ or DMA, these APIs return the HAL status.
+ The end of the data processing will be indicated through the
+ dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
+ using DMA mode.
+ The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
+ will be executed respectively at the end of the transmit or receive process.
+ The HAL_UART_ErrorCallback() user callback will be executed when
+ a communication error is detected.
+
+ (#) Blocking mode APIs are:
+ (++) HAL_UART_Transmit()
+ (++) HAL_UART_Receive()
+
+ (#) Non Blocking mode APIs with Interrupt are:
+ (++) HAL_UART_Transmit_IT()
+ (++) HAL_UART_Receive_IT()
+ (++) HAL_UART_IRQHandler()
+
+ (#) Non Blocking mode functions with DMA are:
+ (++) HAL_UART_Transmit_DMA()
+ (++) HAL_UART_Receive_DMA()
+ (++) HAL_UART_DMAPause()
+ (++) HAL_UART_DMAResume()
+ (++) HAL_UART_DMAStop()
+
+ (#) A set of Transfer Complete Callbacks are provided in non blocking mode:
+ (++) HAL_UART_TxHalfCpltCallback()
+ (++) HAL_UART_TxCpltCallback()
+ (++) HAL_UART_RxHalfCpltCallback()
+ (++) HAL_UART_RxCpltCallback()
+ (++) HAL_UART_ErrorCallback()
+
+ [..]
+ (@) In the Half duplex communication, it is forbidden to run the transmit
+ and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX
+ can't be useful.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sends an amount of data in blocking mode.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be sent
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ uint16_t* tmp;
+ uint32_t tickstart = 0U;
+
+ /* Check that a Tx process is not already ongoing */
+ if(huart->gState == HAL_UART_STATE_READY)
+ {
+ if((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_BUSY_TX;
+
+ /* Init tickstart for timeout managment */
+ tickstart = HAL_GetTick();
+
+ huart->TxXferSize = Size;
+ huart->TxXferCount = Size;
+ while(huart->TxXferCount > 0U)
+ {
+ huart->TxXferCount--;
+ if(huart->Init.WordLength == UART_WORDLENGTH_9B)
+ {
+ if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ tmp = (uint16_t*) pData;
+ huart->Instance->DR = (*tmp & (uint16_t)0x01FF);
+ if(huart->Init.Parity == UART_PARITY_NONE)
+ {
+ pData +=2U;
+ }
+ else
+ {
+ pData +=1U;
+ }
+ }
+ else
+ {
+ if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ huart->Instance->DR = (*pData++ & (uint8_t)0xFF);
+ }
+ }
+
+ if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+
+ /* At end of Tx process, restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive an amount of data in blocking mode.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be received
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ uint16_t* tmp;
+ uint32_t tickstart = 0U;
+
+ /* Check that a Rx process is not already ongoing */
+ if(huart->RxState == HAL_UART_STATE_READY)
+ {
+ if((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->RxState = HAL_UART_STATE_BUSY_RX;
+
+ /* Init tickstart for timeout managment */
+ tickstart = HAL_GetTick();
+
+ huart->RxXferSize = Size;
+ huart->RxXferCount = Size;
+
+ /* Check the remain data to be received */
+ while(huart->RxXferCount > 0U)
+ {
+ huart->RxXferCount--;
+ if(huart->Init.WordLength == UART_WORDLENGTH_9B)
+ {
+ if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ tmp = (uint16_t*)pData;
+ if(huart->Init.Parity == UART_PARITY_NONE)
+ {
+ *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
+ pData +=2U;
+ }
+ else
+ {
+ *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
+ pData +=1U;
+ }
+
+ }
+ else
+ {
+ if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ if(huart->Init.Parity == UART_PARITY_NONE)
+ {
+ *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
+ }
+ else
+ {
+ *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
+ }
+
+ }
+ }
+
+ /* At end of Rx process, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sends an amount of data in non blocking mode.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ /* Check that a Tx process is not already ongoing */
+ if(huart->gState == HAL_UART_STATE_READY)
+ {
+ if((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->pTxBuffPtr = pData;
+ huart->TxXferSize = Size;
+ huart->TxXferCount = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_BUSY_TX;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ /* Enable the UART Transmit data register empty Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_TXE);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receives an amount of data in non blocking mode.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be received
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ /* Check that a Rx process is not already ongoing */
+ if(huart->RxState == HAL_UART_STATE_READY)
+ {
+ if((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->pRxBuffPtr = pData;
+ huart->RxXferSize = Size;
+ huart->RxXferCount = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->RxState = HAL_UART_STATE_BUSY_RX;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ /* Enable the UART Parity Error Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_PE);
+
+ /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_ERR);
+
+ /* Enable the UART Data Register not empty Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sends an amount of data in non blocking mode.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ uint32_t *tmp;
+
+ /* Check that a Tx process is not already ongoing */
+ if(huart->gState == HAL_UART_STATE_READY)
+ {
+ if((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->pTxBuffPtr = pData;
+ huart->TxXferSize = Size;
+ huart->TxXferCount = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_BUSY_TX;
+
+ /* Set the UART DMA transfer complete callback */
+ huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
+
+ /* Set the UART DMA Half transfer complete callback */
+ huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
+
+ /* Set the DMA error callback */
+ huart->hdmatx->XferErrorCallback = UART_DMAError;
+
+ /* Set the DMA abort callback */
+ huart->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the UART transmit DMA channel */
+ tmp = (uint32_t*)&pData;
+ HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->DR, Size);
+
+ /* Clear the TC flag in the SR register by writing 0 to it */
+ __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ /* Enable the DMA transfer for transmit request by setting the DMAT bit
+ in the UART CR3 register */
+ SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receives an amount of data in non blocking mode.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be received
+ * @note When the UART parity is enabled (PCE = 1) the data received contain the parity bit.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ uint32_t *tmp;
+
+ /* Check that a Rx process is not already ongoing */
+ if(huart->RxState == HAL_UART_STATE_READY)
+ {
+ if((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->pRxBuffPtr = pData;
+ huart->RxXferSize = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->RxState = HAL_UART_STATE_BUSY_RX;
+
+ /* Set the UART DMA transfer complete callback */
+ huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
+
+ /* Set the UART DMA Half transfer complete callback */
+ huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
+
+ /* Set the DMA error callback */
+ huart->hdmarx->XferErrorCallback = UART_DMAError;
+
+ /* Set the DMA abort callback */
+ huart->hdmarx->XferAbortCallback = NULL;
+
+ /* Enable the DMA channel */
+ tmp = (uint32_t*)&pData;
+ HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->DR, *(uint32_t*)tmp, Size);
+
+ /* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */
+ __HAL_UART_CLEAR_OREFLAG(huart);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ /* Enable the UART Parity Error Interrupt */
+ SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+
+ /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Enable the DMA transfer for the receiver request by setting the DMAR bit
+ in the UART CR3 register */
+ SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Pauses the DMA Transfer.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
+{
+ uint32_t dmarequest = 0x00U;
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
+ if((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
+ {
+ /* Disable the UART DMA Tx request */
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+ }
+
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
+ if((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
+ {
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the UART DMA Rx request */
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Resumes the DMA Transfer.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
+{
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ if(huart->gState == HAL_UART_STATE_BUSY_TX)
+ {
+ /* Enable the UART DMA Tx request */
+ SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+ }
+
+ if(huart->RxState == HAL_UART_STATE_BUSY_RX)
+ {
+ /* Clear the Overrun flag before resuming the Rx transfer*/
+ __HAL_UART_CLEAR_OREFLAG(huart);
+
+ /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */
+ SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+ SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Enable the UART DMA Rx request */
+ SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the DMA Transfer.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
+{
+ uint32_t dmarequest = 0x00U;
+ /* The Lock is not implemented on this API to allow the user application
+ to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback():
+ when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
+ and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback()
+ */
+
+ /* Stop UART DMA Tx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
+ if((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx channel */
+ if(huart->hdmatx != NULL)
+ {
+ HAL_DMA_Abort(huart->hdmatx);
+ }
+ UART_EndTxTransfer(huart);
+ }
+
+ /* Stop UART DMA Rx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
+ if((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx channel */
+ if(huart->hdmarx != NULL)
+ {
+ HAL_DMA_Abort(huart->hdmarx);
+ }
+ UART_EndRxTransfer(huart);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing transfers (blocking mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart)
+{
+ /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the UART DMA Tx request if enabled */
+ if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx channel: use blocking DMA Abort API (no callback) */
+ if(huart->hdmatx != NULL)
+ {
+ /* Set the UART DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ huart->hdmatx->XferAbortCallback = NULL;
+
+ HAL_DMA_Abort(huart->hdmatx);
+ }
+ }
+
+ /* Disable the UART DMA Rx request if enabled */
+ if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx channel: use blocking DMA Abort API (no callback) */
+ if(huart->hdmarx != NULL)
+ {
+ /* Set the UART DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ huart->hdmarx->XferAbortCallback = NULL;
+
+ HAL_DMA_Abort(huart->hdmarx);
+ }
+ }
+
+ /* Reset Tx and Rx transfer counters */
+ huart->TxXferCount = 0x00U;
+ huart->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+ /* Restore huart->RxState and huart->gState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->gState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Transmit transfer (blocking mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart)
+{
+ /* Disable TXEIE and TCIE interrupts */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+
+ /* Disable the UART DMA Tx request if enabled */
+ if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
+ if(huart->hdmatx != NULL)
+ {
+ /* Set the UART DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ huart->hdmatx->XferAbortCallback = NULL;
+
+ HAL_DMA_Abort(huart->hdmatx);
+ }
+ }
+
+ /* Reset Tx transfer counter */
+ huart->TxXferCount = 0x00U;
+
+ /* Restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Receive transfer (blocking mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart)
+{
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the UART DMA Rx request if enabled */
+ if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
+ if(huart->hdmarx != NULL)
+ {
+ /* Set the UART DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ huart->hdmarx->XferAbortCallback = NULL;
+
+ HAL_DMA_Abort(huart->hdmarx);
+ }
+ }
+
+ /* Reset Rx transfer counter */
+ huart->RxXferCount = 0x00U;
+
+ /* Restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing transfers (Interrupt mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart)
+{
+ uint32_t AbortCplt = 0x01U;
+
+ /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised
+ before any call to DMA Abort functions */
+ /* DMA Tx Handle is valid */
+ if(huart->hdmatx != NULL)
+ {
+ /* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
+ Otherwise, set it to NULL */
+ if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback;
+ }
+ else
+ {
+ huart->hdmatx->XferAbortCallback = NULL;
+ }
+ }
+ /* DMA Rx Handle is valid */
+ if(huart->hdmarx != NULL)
+ {
+ /* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
+ Otherwise, set it to NULL */
+ if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback;
+ }
+ else
+ {
+ huart->hdmarx->XferAbortCallback = NULL;
+ }
+ }
+
+ /* Disable the UART DMA Tx request if enabled */
+ if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ /* Disable DMA Tx at UART level */
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
+ if(huart->hdmatx != NULL)
+ {
+ /* UART Tx DMA Abort callback has already been initialised :
+ will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+
+ /* Abort DMA TX */
+ if(HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
+ {
+ huart->hdmatx->XferAbortCallback = NULL;
+ }
+ else
+ {
+ AbortCplt = 0x00U;
+ }
+ }
+ }
+
+ /* Disable the UART DMA Rx request if enabled */
+ if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
+ if(huart->hdmarx != NULL)
+ {
+ /* UART Rx DMA Abort callback has already been initialised :
+ will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+
+ /* Abort DMA RX */
+ if(HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
+ {
+ huart->hdmarx->XferAbortCallback = NULL;
+ AbortCplt = 0x01U;
+ }
+ else
+ {
+ AbortCplt = 0x00U;
+ }
+ }
+ }
+
+ /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
+ if(AbortCplt == 0x01U)
+ {
+ /* Reset Tx and Rx transfer counters */
+ huart->TxXferCount = 0x00U;
+ huart->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+ /* Restore huart->gState and huart->RxState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+ HAL_UART_AbortCpltCallback(huart);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Transmit transfer (Interrupt mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart)
+{
+ /* Disable TXEIE and TCIE interrupts */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+
+ /* Disable the UART DMA Tx request if enabled */
+ if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
+ if(huart->hdmatx != NULL)
+ {
+ /* Set the UART DMA Abort callback :
+ will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+ huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback;
+
+ /* Abort DMA TX */
+ if(HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
+ {
+ /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */
+ huart->hdmatx->XferAbortCallback(huart->hdmatx);
+ }
+ }
+ else
+ {
+ /* Reset Tx transfer counter */
+ huart->TxXferCount = 0x00U;
+
+ /* Restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+ HAL_UART_AbortTransmitCpltCallback(huart);
+ }
+ }
+ else
+ {
+ /* Reset Tx transfer counter */
+ huart->TxXferCount = 0x00U;
+
+ /* Restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+ HAL_UART_AbortTransmitCpltCallback(huart);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Receive transfer (Interrupt mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart)
+{
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the UART DMA Rx request if enabled */
+ if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
+ if(huart->hdmarx != NULL)
+ {
+ /* Set the UART DMA Abort callback :
+ will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+ huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback;
+
+ /* Abort DMA RX */
+ if(HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
+ {
+ /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
+ huart->hdmarx->XferAbortCallback(huart->hdmarx);
+ }
+ }
+ else
+ {
+ /* Reset Rx transfer counter */
+ huart->RxXferCount = 0x00U;
+
+ /* Restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+ HAL_UART_AbortReceiveCpltCallback(huart);
+ }
+ }
+ else
+ {
+ /* Reset Rx transfer counter */
+ huart->RxXferCount = 0x00U;
+
+ /* Restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+ HAL_UART_AbortReceiveCpltCallback(huart);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles UART interrupt request.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
+{
+ uint32_t isrflags = READ_REG(huart->Instance->SR);
+ uint32_t cr1its = READ_REG(huart->Instance->CR1);
+ uint32_t cr3its = READ_REG(huart->Instance->CR3);
+ uint32_t errorflags = 0x00U;
+ uint32_t dmarequest = 0x00U;
+
+ /* If no error occurs */
+ errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
+ if(errorflags == RESET)
+ {
+ /* UART in mode Receiver -------------------------------------------------*/
+ if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
+ {
+ UART_Receive_IT(huart);
+ return;
+ }
+ }
+
+ /* If some errors occur */
+ if((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
+ {
+ /* UART parity error interrupt occurred ----------------------------------*/
+ if(((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_PE;
+ }
+
+ /* UART noise error interrupt occurred -----------------------------------*/
+ if(((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_NE;
+ }
+
+ /* UART frame error interrupt occurred -----------------------------------*/
+ if(((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_FE;
+ }
+
+ /* UART Over-Run interrupt occurred --------------------------------------*/
+ if(((isrflags & USART_SR_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_ORE;
+ }
+
+ /* Call UART Error Call back function if need be --------------------------*/
+ if(huart->ErrorCode != HAL_UART_ERROR_NONE)
+ {
+ /* UART in mode Receiver -----------------------------------------------*/
+ if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
+ {
+ UART_Receive_IT(huart);
+ }
+
+ /* If Overrun error occurs, or if any error occurs in DMA mode reception,
+ consider error as blocking */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
+ if(((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) || dmarequest)
+ {
+ /* Blocking error : transfer is aborted
+ Set the UART state ready to be able to start again the process,
+ Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
+ UART_EndRxTransfer(huart);
+
+ /* Disable the UART DMA Rx request if enabled */
+ if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx channel */
+ if(huart->hdmarx != NULL)
+ {
+ /* Set the UART DMA Abort callback :
+ will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
+ huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
+ if(HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
+ {
+ /* Call Directly XferAbortCallback function in case of error */
+ huart->hdmarx->XferAbortCallback(huart->hdmarx);
+ }
+ }
+ else
+ {
+ /* Call user error callback */
+ HAL_UART_ErrorCallback(huart);
+ }
+ }
+ else
+ {
+ /* Call user error callback */
+ HAL_UART_ErrorCallback(huart);
+ }
+ }
+ else
+ {
+ /* Non Blocking error : transfer could go on.
+ Error is notified to user through user error callback */
+ HAL_UART_ErrorCallback(huart);
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ }
+ }
+ return;
+ } /* End if some error occurs */
+
+ /* UART in mode Transmitter ------------------------------------------------*/
+ if(((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
+ {
+ UART_Transmit_IT(huart);
+ return;
+ }
+
+ /* UART in mode Transmitter end --------------------------------------------*/
+ if(((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
+ {
+ UART_EndTransmit_IT(huart);
+ return;
+ }
+}
+
+/**
+ * @brief Tx Transfer completed callbacks.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+ __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function Should not be modified, when the callback is needed,
+ the HAL_UART_TxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Tx Half Transfer completed callbacks.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+ __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function Should not be modified, when the callback is needed,
+ the HAL_UART_TxHalfCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer completed callbacks.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function Should not be modified, when the callback is needed,
+ the HAL_UART_RxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Half Transfer completed callbacks.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function Should not be modified, when the callback is needed,
+ the HAL_UART_RxHalfCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief UART error callbacks.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+ __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function Should not be modified, when the callback is needed,
+ the HAL_UART_ErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief UART Abort Complete callback.
+ * @param huart UART handle.
+ * @retval None
+ */
+__weak void HAL_UART_AbortCpltCallback (UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_UART_AbortCpltCallback can be implemented in the user file.
+ */
+}
+/**
+ * @brief UART Abort Complete callback.
+ * @param huart UART handle.
+ * @retval None
+ */
+__weak void HAL_UART_AbortTransmitCpltCallback (UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @brief UART Abort Receive Complete callback.
+ * @param huart UART handle.
+ * @retval None
+ */
+__weak void HAL_UART_AbortReceiveCpltCallback (UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
+ * @brief UART control functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the UART:
+ (+) HAL_LIN_SendBreak() API can be helpful to transmit the break character.
+ (+) HAL_MultiProcessor_EnterMuteMode() API can be helpful to enter the UART in mute mode.
+ (+) HAL_MultiProcessor_ExitMuteMode() API can be helpful to exit the UART mute mode by software.
+ (+) HAL_HalfDuplex_EnableTransmitter() API to enable the UART transmitter and disables the UART receiver in Half Duplex mode
+ (+) HAL_HalfDuplex_EnableReceiver() API to enable the UART receiver and disables the UART transmitter in Half Duplex mode
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Transmits break characters.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Send break characters */
+ SET_BIT(huart->Instance->CR1, USART_CR1_SBK);
+
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enters the UART in mute mode.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Enable the USART mute mode by setting the RWU bit in the CR1 register */
+ SET_BIT(huart->Instance->CR1, USART_CR1_RWU);
+
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Exits the UART mute mode: wake up software.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef *huart)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */
+ CLEAR_BIT(huart->Instance->CR1, USART_CR1_RWU);
+
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enables the UART transmitter and disables the UART receiver.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
+{
+ uint32_t tmpreg = 0x00U;
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /*-------------------------- USART CR1 Configuration -----------------------*/
+ tmpreg = huart->Instance->CR1;
+
+ /* Clear TE and RE bits */
+ tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE));
+
+ /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
+ tmpreg |= (uint32_t)USART_CR1_TE;
+
+ /* Write to USART CR1 */
+ WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg);
+
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enables the UART receiver and disables the UART transmitter.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
+{
+ uint32_t tmpreg = 0x00U;
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /*-------------------------- USART CR1 Configuration -----------------------*/
+ tmpreg = huart->Instance->CR1;
+
+ /* Clear TE and RE bits */
+ tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE));
+
+ /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
+ tmpreg |= (uint32_t)USART_CR1_RE;
+
+ /* Write to USART CR1 */
+ WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg);
+
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Exported_Functions_Group4 Peripheral State and Errors functions
+ * @brief UART State and Errors functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral State and Errors functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to return the State of
+ UART communication process, return Peripheral Errors occurred during communication
+ process
+ (+) HAL_UART_GetState() API can be helpful to check in run-time the state of the UART peripheral.
+ (+) HAL_UART_GetError() check in run-time errors that could be occurred during communication.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns the UART state.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL state
+ */
+HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart)
+{
+ uint32_t temp1= 0x00U, temp2 = 0x00U;
+ temp1 = huart->gState;
+ temp2 = huart->RxState;
+
+ return (HAL_UART_StateTypeDef)(temp1 | temp2);
+}
+
+/**
+ * @brief Return the UART error code
+ * @param huart : pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART.
+ * @retval UART Error Code
+ */
+uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart)
+{
+ return huart->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @brief DMA UART transmit process complete callback.
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ /* DMA Normal mode*/
+ if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
+ {
+ huart->TxXferCount = 0U;
+
+ /* Disable the DMA transfer for transmit request by setting the DMAT bit
+ in the UART CR3 register */
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Enable the UART Transmit Complete Interrupt */
+ SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
+
+ }
+ /* DMA Circular mode */
+ else
+ {
+ HAL_UART_TxCpltCallback(huart);
+ }
+}
+
+/**
+ * @brief DMA UART transmit process half complete callback
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
+
+ HAL_UART_TxHalfCpltCallback(huart);
+}
+
+/**
+ * @brief DMA UART receive process complete callback.
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ /* DMA Normal mode*/
+ if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
+ {
+ huart->RxXferCount = 0U;
+
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the DMA transfer for the receiver request by setting the DMAR bit
+ in the UART CR3 register */
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* At end of Rx process, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ }
+ HAL_UART_RxCpltCallback(huart);
+}
+
+/**
+ * @brief DMA UART receive process half complete callback
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
+ HAL_UART_RxHalfCpltCallback(huart);
+}
+
+/**
+ * @brief DMA UART communication error callback.
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void UART_DMAError(DMA_HandleTypeDef *hdma)
+{
+ uint32_t dmarequest = 0x00U;
+ UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ /* Stop UART DMA Tx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
+ if((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
+ {
+ huart->TxXferCount = 0U;
+ UART_EndTxTransfer(huart);
+ }
+
+ /* Stop UART DMA Rx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
+ if((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
+ {
+ huart->RxXferCount = 0U;
+ UART_EndRxTransfer(huart);
+ }
+
+ huart->ErrorCode |= HAL_UART_ERROR_DMA;
+ HAL_UART_ErrorCallback(huart);
+}
+
+/**
+ * @brief This function handles UART Communication Timeout.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param Flag: specifies the UART flag to check.
+ * @param Status: The new Flag status (SET or RESET).
+ * @param Tickstart Tick start value
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
+{
+ /* Wait until flag is set */
+ while((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status)
+ {
+ /* Check for the Timeout */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout))
+ {
+ /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion).
+ * @param huart: UART handle.
+ * @retval None
+ */
+static void UART_EndTxTransfer(UART_HandleTypeDef *huart)
+{
+ /* Disable TXEIE and TCIE interrupts */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+
+ /* At end of Tx process, restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+}
+
+/**
+ * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
+ * @param huart: UART handle.
+ * @retval None
+ */
+static void UART_EndRxTransfer(UART_HandleTypeDef *huart)
+{
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* At end of Rx process, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+}
+
+/**
+ * @brief DMA UART communication abort callback, when initiated by HAL services on Error
+ * (To be called at end of DMA Abort procedure following error occurrence).
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ huart->RxXferCount = 0x00U;
+ huart->TxXferCount = 0x00U;
+
+ HAL_UART_ErrorCallback(huart);
+}
+
+/**
+ * @brief DMA UART Tx communication abort callback, when initiated by user
+ * (To be called at end of DMA Tx Abort procedure following user abort request).
+ * @note When this callback is executed, User Abort complete call back is called only if no
+ * Abort still ongoing for Rx DMA Handle.
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ huart->hdmatx->XferAbortCallback = NULL;
+
+ /* Check if an Abort process is still ongoing */
+ if(huart->hdmarx != NULL)
+ {
+ if(huart->hdmarx->XferAbortCallback != NULL)
+ {
+ return;
+ }
+ }
+
+ /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+ huart->TxXferCount = 0x00U;
+ huart->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+ /* Restore huart->gState and huart->RxState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+
+ /* Call user Abort complete callback */
+ HAL_UART_AbortCpltCallback(huart);
+}
+
+/**
+ * @brief DMA UART Rx communication abort callback, when initiated by user
+ * (To be called at end of DMA Rx Abort procedure following user abort request).
+ * @note When this callback is executed, User Abort complete call back is called only if no
+ * Abort still ongoing for Tx DMA Handle.
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ huart->hdmarx->XferAbortCallback = NULL;
+
+ /* Check if an Abort process is still ongoing */
+ if(huart->hdmatx != NULL)
+ {
+ if(huart->hdmatx->XferAbortCallback != NULL)
+ {
+ return;
+ }
+ }
+
+ /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+ huart->TxXferCount = 0x00U;
+ huart->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+ /* Restore huart->gState and huart->RxState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+
+ /* Call user Abort complete callback */
+ HAL_UART_AbortCpltCallback(huart);
+}
+
+/**
+ * @brief DMA UART Tx communication abort callback, when initiated by user by a call to
+ * HAL_UART_AbortTransmit_IT API (Abort only Tx transfer)
+ * (This callback is executed at end of DMA Tx Abort procedure following user abort request,
+ * and leads to user Tx Abort Complete callback execution).
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ huart->TxXferCount = 0x00U;
+
+ /* Restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Call user Abort complete callback */
+ HAL_UART_AbortTransmitCpltCallback(huart);
+}
+
+/**
+ * @brief DMA UART Rx communication abort callback, when initiated by user by a call to
+ * HAL_UART_AbortReceive_IT API (Abort only Rx transfer)
+ * (This callback is executed at end of DMA Rx Abort procedure following user abort request,
+ * and leads to user Rx Abort Complete callback execution).
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ huart->RxXferCount = 0x00U;
+
+ /* Restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ /* Call user Abort complete callback */
+ HAL_UART_AbortReceiveCpltCallback(huart);
+}
+
+/**
+ * @brief Sends an amount of data in non blocking mode.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart)
+{
+ uint16_t* tmp;
+
+ /* Check that a Tx process is ongoing */
+ if(huart->gState == HAL_UART_STATE_BUSY_TX)
+ {
+ if(huart->Init.WordLength == UART_WORDLENGTH_9B)
+ {
+ tmp = (uint16_t*) huart->pTxBuffPtr;
+ huart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
+ if(huart->Init.Parity == UART_PARITY_NONE)
+ {
+ huart->pTxBuffPtr += 2U;
+ }
+ else
+ {
+ huart->pTxBuffPtr += 1U;
+ }
+ }
+ else
+ {
+ huart->Instance->DR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0x00FF);
+ }
+
+ if(--huart->TxXferCount == 0U)
+ {
+ /* Disable the UART Transmit Complete Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
+
+ /* Enable the UART Transmit Complete Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_TC);
+ }
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Wraps up transmission in non blocking mode.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart)
+{
+ /* Disable the UART Transmit Complete Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_TC);
+
+ /* Tx process is ended, restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+ HAL_UART_TxCpltCallback(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Receives an amount of data in non blocking mode
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
+{
+ uint16_t* tmp;
+
+ /* Check that a Rx process is ongoing */
+ if(huart->RxState == HAL_UART_STATE_BUSY_RX)
+ {
+ if(huart->Init.WordLength == UART_WORDLENGTH_9B)
+ {
+ tmp = (uint16_t*) huart->pRxBuffPtr;
+ if(huart->Init.Parity == UART_PARITY_NONE)
+ {
+ *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
+ huart->pRxBuffPtr += 2U;
+ }
+ else
+ {
+ *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
+ huart->pRxBuffPtr += 1U;
+ }
+ }
+ else
+ {
+ if(huart->Init.Parity == UART_PARITY_NONE)
+ {
+ *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
+ }
+ else
+ {
+ *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
+ }
+ }
+
+ if(--huart->RxXferCount == 0U)
+ {
+ /* Disable the IRDA Data Register not empty Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
+
+ /* Disable the UART Parity Error Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
+ /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
+
+ /* Rx process is completed, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ HAL_UART_RxCpltCallback(huart);
+
+ return HAL_OK;
+ }
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Configures the UART peripheral.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+static void UART_SetConfig(UART_HandleTypeDef *huart)
+{
+ uint32_t tmpreg = 0x00U;
+
+ /* Check the parameters */
+ assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
+ assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
+ assert_param(IS_UART_PARITY(huart->Init.Parity));
+ assert_param(IS_UART_MODE(huart->Init.Mode));
+
+ /*------- UART-associated USART registers setting : CR2 Configuration ------*/
+ /* Configure the UART Stop Bits: Set STOP[13:12] bits according
+ * to huart->Init.StopBits value */
+ MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
+
+ /*------- UART-associated USART registers setting : CR1 Configuration ------*/
+ /* Configure the UART Word Length, Parity and mode:
+ Set the M bits according to huart->Init.WordLength value
+ Set PCE and PS bits according to huart->Init.Parity value
+ Set TE and RE bits according to huart->Init.Mode value
+ Set OVER8 bit according to huart->Init.OverSampling value */
+
+#if defined(USART_CR1_OVER8)
+ tmpreg |= (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling;
+ MODIFY_REG(huart->Instance->CR1,
+ (uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8),
+ tmpreg);
+#else
+ tmpreg |= (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode;
+ MODIFY_REG(huart->Instance->CR1,
+ (uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE),
+ tmpreg);
+#endif /* USART_CR1_OVER8 */
+
+ /*------- UART-associated USART registers setting : CR3 Configuration ------*/
+ /* Configure the UART HFC: Set CTSE and RTSE bits according to huart->Init.HwFlowCtl value */
+ MODIFY_REG(huart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE), huart->Init.HwFlowCtl);
+
+#if defined(USART_CR1_OVER8)
+ /* Check the Over Sampling */
+ if(huart->Init.OverSampling == UART_OVERSAMPLING_8)
+ {
+ /*-------------------------- USART BRR Configuration ---------------------*/
+ if(huart->Instance == USART1)
+ {
+ huart->Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate);
+ }
+ else
+ {
+ huart->Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate);
+ }
+ }
+ else
+ {
+ /*-------------------------- USART BRR Configuration ---------------------*/
+ if(huart->Instance == USART1)
+ {
+ huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate);
+ }
+ else
+ {
+ huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate);
+ }
+ }
+#else
+ /*-------------------------- USART BRR Configuration ---------------------*/
+ if(huart->Instance == USART1)
+ {
+ huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate);
+ }
+ else
+ {
+ huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate);
+ }
+#endif /* USART_CR1_OVER8 */
+}
+
+/**
+ * @}
+ */
+
+#endif /* HAL_UART_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_usart.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_usart.c
new file mode 100644
index 0000000..268a4c7
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_usart.c
@@ -0,0 +1,2308 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_usart.c
+ * @author MCD Application Team
+ * @brief USART HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Universal Synchronous Asynchronous Receiver Transmitter (USART) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The USART HAL driver can be used as follows:
+
+ (#) Declare a USART_HandleTypeDef handle structure.
+ (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit () API:
+ (##) Enable the USARTx interface clock.
+ (##) USART pins configuration:
+ (+++) Enable the clock for the USART GPIOs.
+ (+++) Configure the USART pins (TX as alternate function pull-up, RX as alternate function Input).
+ (##) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
+ HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
+ (+++) Configure the USARTx interrupt priority.
+ (+++) Enable the NVIC USART IRQ handle.
+ (##) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
+ HAL_USART_Receive_DMA() and HAL_USART_TransmitReceive_DMA() APIs):
+ (+++) Declare a DMA handle structure for the Tx/Rx channel.
+ (+++) Enable the DMAx interface clock.
+ (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
+ (+++) Configure the DMA Tx/Rx channel.
+ (+++) Associate the initialized DMA handle to the USART DMA Tx/Rx handle.
+ (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
+ (+++) Configure the priority and enable the NVIC for the transfer complete
+ interrupt on the DMA Tx/Rx channel.
+ (+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
+ (used for last byte sending completion detection in DMA non circular mode)
+
+ (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
+ flow control and Mode(Receiver/Transmitter) in the husart Init structure.
+
+ (#) Initialize the USART registers by calling the HAL_USART_Init() API:
+ (++) These APIs configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
+ by calling the customized HAL_USART_MspInit(&husart) API.
+
+ -@@- The specific USART interrupts (Transmission complete interrupt,
+ RXNE interrupt and Error Interrupts) will be managed using the macros
+ __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
+
+ (#) Three operation modes are available within this driver :
+
+ *** Polling mode IO operation ***
+ =================================
+ [..]
+ (+) Send an amount of data in blocking mode using HAL_USART_Transmit()
+ (+) Receive an amount of data in blocking mode using HAL_USART_Receive()
+
+ *** Interrupt mode IO operation ***
+ ===================================
+ [..]
+ (+) Send an amount of data in non blocking mode using HAL_USART_Transmit_IT()
+ (+) At transmission end of transfer HAL_USART_TxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_USART_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode using HAL_USART_Receive_IT()
+ (+) At reception end of transfer HAL_USART_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_USART_RxCpltCallback
+ (+) In case of transfer Error, HAL_USART_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_USART_ErrorCallback
+
+ *** DMA mode IO operation ***
+ ==============================
+ [..]
+ (+) Send an amount of data in non blocking mode (DMA) using HAL_USART_Transmit_DMA()
+ (+) At transmission end of half transfer HAL_USART_TxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_USART_TxHalfCpltCallback
+ (+) At transmission end of transfer HAL_USART_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_USART_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode (DMA) using HAL_USART_Receive_DMA()
+ (+) At reception end of half transfer HAL_USART_RxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_USART_RxHalfCpltCallback
+ (+) At reception end of transfer HAL_USART_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_USART_RxCpltCallback
+ (+) In case of transfer Error, HAL_USART_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_USART_ErrorCallback
+ (+) Pause the DMA Transfer using HAL_USART_DMAPause()
+ (+) Resume the DMA Transfer using HAL_USART_DMAResume()
+ (+) Stop the DMA Transfer using HAL_USART_DMAStop()
+
+ *** USART HAL driver macros list ***
+ =============================================
+ [..]
+ Below the list of most used macros in USART HAL driver.
+
+ (+) __HAL_USART_ENABLE: Enable the USART peripheral
+ (+) __HAL_USART_DISABLE: Disable the USART peripheral
+ (+) __HAL_USART_GET_FLAG : Check whether the specified USART flag is set or not
+ (+) __HAL_USART_CLEAR_FLAG : Clear the specified USART pending flag
+ (+) __HAL_USART_ENABLE_IT: Enable the specified USART interrupt
+ (+) __HAL_USART_DISABLE_IT: Disable the specified USART interrupt
+
+ [..]
+ (@) You can refer to the USART HAL driver header file for more useful macros
+
+ @endverbatim
+ [..]
+ (@) Additionnal remark: If the parity is enabled, then the MSB bit of the data written
+ in the data register is transmitted but is changed by the parity bit.
+ Depending on the frame length defined by the M bit (8-bits or 9-bits),
+ the possible USART frame formats are as listed in the following table:
+ +-------------------------------------------------------------+
+ | M bit | PCE bit | USART frame |
+ |---------------------|---------------------------------------|
+ | 0 | 0 | | SB | 8 bit data | STB | |
+ |---------|-----------|---------------------------------------|
+ | 0 | 1 | | SB | 7 bit data | PB | STB | |
+ |---------|-----------|---------------------------------------|
+ | 1 | 0 | | SB | 9 bit data | STB | |
+ |---------|-----------|---------------------------------------|
+ | 1 | 1 | | SB | 8 bit data | PB | STB | |
+ +-------------------------------------------------------------+
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup USART USART
+ * @brief HAL USART Synchronous module driver
+ * @{
+ */
+#ifdef HAL_USART_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @addtogroup USART_Private_Constants
+ * @{
+ */
+#define DUMMY_DATA 0xFFFFU
+#define USART_TIMEOUT_VALUE 22000U
+/**
+ * @}
+ */
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/** @addtogroup USART_Private_Functions
+ * @{
+ */
+static void USART_EndTxTransfer(USART_HandleTypeDef *husart);
+static void USART_EndRxTransfer(USART_HandleTypeDef *husart);
+static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart);
+static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart);
+static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart);
+static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart);
+static void USART_SetConfig (USART_HandleTypeDef *husart);
+static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
+static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
+static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
+static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
+static void USART_DMAError(DMA_HandleTypeDef *hdma);
+static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
+static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
+static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
+
+static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout);
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup USART_Exported_Functions USART Exported Functions
+ * @{
+ */
+
+/** @defgroup USART_Exported_Functions_Group1 USART Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and Configuration functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to initialize the USART
+ in asynchronous and in synchronous modes.
+ (+) For the asynchronous mode only these parameters can be configured:
+ (++) Baud Rate
+ (++) Word Length
+ (++) Stop Bit
+ (++) Parity: If the parity is enabled, then the MSB bit of the data written
+ in the data register is transmitted but is changed by the parity bit.
+ Depending on the frame length defined by the M bit (8-bits or 9-bits),
+ please refer to Reference manual for possible USART frame formats.
+ (++) USART polarity
+ (++) USART phase
+ (++) USART LastBit
+ (++) Receiver/transmitter modes
+
+ [..]
+ The HAL_USART_Init() function follows the USART synchronous configuration
+ procedure (details for the procedure are available in reference manuals
+ (RM0008 for STM32F10Xxx MCUs and RM0041 for STM32F100xx MCUs)).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the USART mode according to the specified
+ * parameters in the USART_InitTypeDef and create the associated handle.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
+{
+ /* Check the USART handle allocation */
+ if(husart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_USART_INSTANCE(husart->Instance));
+
+ if(husart->State == HAL_USART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ husart->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware */
+ HAL_USART_MspInit(husart);
+ }
+
+ husart->State = HAL_USART_STATE_BUSY;
+
+ /* Set the USART Communication parameters */
+ USART_SetConfig(husart);
+
+ /* In USART mode, the following bits must be kept cleared:
+ - LINEN bit in the USART_CR2 register
+ - HDSEL, SCEN and IREN bits in the USART_CR3 register */
+ CLEAR_BIT(husart->Instance->CR2, USART_CR2_LINEN);
+ CLEAR_BIT(husart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
+
+ /* Enable the Peripheral */
+ __HAL_USART_ENABLE(husart);
+
+ /* Initialize the USART state */
+ husart->ErrorCode = HAL_USART_ERROR_NONE;
+ husart->State= HAL_USART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the USART peripheral.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
+{
+ /* Check the USART handle allocation */
+ if(husart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_USART_INSTANCE(husart->Instance));
+
+ husart->State = HAL_USART_STATE_BUSY;
+
+ /* DeInit the low level hardware */
+ HAL_USART_MspDeInit(husart);
+
+ husart->ErrorCode = HAL_USART_ERROR_NONE;
+ husart->State = HAL_USART_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(husart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USART MSP Init.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval None
+ */
+__weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(husart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_USART_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief USART MSP DeInit.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval None
+ */
+__weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(husart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_USART_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Exported_Functions_Group2 IO operation functions
+ * @brief USART Transmit and Receive functions
+ *
+@verbatim
+ ==============================================================================
+ ##### IO operation functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the USART synchronous
+ data transfers.
+
+ [..]
+ The USART supports master mode only: it cannot receive or send data related to an input
+ clock (SCLK is always an output).
+
+ (#) There are two modes of transfer:
+ (++) Blocking mode: The communication is performed in polling mode.
+ The HAL status of all data processing is returned by the same function
+ after finishing transfer.
+ (++) No-Blocking mode: The communication is performed using Interrupts
+ or DMA, These API's return the HAL status.
+ The end of the data processing will be indicated through the
+ dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
+ using DMA mode.
+ The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback()
+ user callbacks
+ will be executed respectively at the end of the transmit or Receive process
+ The HAL_USART_ErrorCallback() user callback will be executed when a communication
+ error is detected
+
+ (#) Blocking mode APIs are :
+ (++) HAL_USART_Transmit() in simplex mode
+ (++) HAL_USART_Receive() in full duplex receive only
+ (++) HAL_USART_TransmitReceive() in full duplex mode
+
+ (#) Non Blocking mode APIs with Interrupt are :
+ (++) HAL_USART_Transmit_IT()in simplex mode
+ (++) HAL_USART_Receive_IT() in full duplex receive only
+ (++) HAL_USART_TransmitReceive_IT() in full duplex mode
+ (++) HAL_USART_IRQHandler()
+
+ (#) Non Blocking mode functions with DMA are :
+ (++) HAL_USART_Transmit_DMA()in simplex mode
+ (++) HAL_USART_Receive_DMA() in full duplex receive only
+ (++) HAL_USART_TransmitReceive_DMA() in full duplex mode
+ (++) HAL_USART_DMAPause()
+ (++) HAL_USART_DMAResume()
+ (++) HAL_USART_DMAStop()
+
+ (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
+ (++) HAL_USART_TxHalfCpltCallback()
+ (++) HAL_USART_TxCpltCallback()
+ (++) HAL_USART_RxHalfCpltCallback()
+ (++) HAL_USART_RxCpltCallback()
+ (++) HAL_USART_ErrorCallback()
+ (++) HAL_USART_TxRxCpltCallback()
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Simplex Send an amount of data in blocking mode.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @param pTxData: Pointer to data buffer
+ * @param Size: Amount of data to be sent
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout)
+{
+ uint16_t* tmp;
+ uint32_t tickstart = 0U;
+
+ if(husart->State == HAL_USART_STATE_READY)
+ {
+ if((pTxData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(husart);
+
+ husart->ErrorCode = HAL_USART_ERROR_NONE;
+ husart->State = HAL_USART_STATE_BUSY_TX;
+
+ /* Init tickstart for timeout managment */
+ tickstart = HAL_GetTick();
+
+ husart->TxXferSize = Size;
+ husart->TxXferCount = Size;
+ while(husart->TxXferCount > 0U)
+ {
+ husart->TxXferCount--;
+ if(husart->Init.WordLength == USART_WORDLENGTH_9B)
+ {
+ /* Wait for TC flag in order to write data in DR */
+ if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ tmp = (uint16_t*) pTxData;
+ WRITE_REG(husart->Instance->DR, (*tmp & (uint16_t)0x01FF));
+ if(husart->Init.Parity == USART_PARITY_NONE)
+ {
+ pTxData += 2U;
+ }
+ else
+ {
+ pTxData += 1U;
+ }
+ }
+ else
+ {
+ if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ WRITE_REG(husart->Instance->DR, (*pTxData++ & (uint8_t)0xFF));
+ }
+ }
+
+ if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+
+ husart->State = HAL_USART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(husart);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Full-Duplex Receive an amount of data in blocking mode.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @param pRxData: Pointer to data buffer
+ * @param Size: Amount of data to be received
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
+{
+ uint16_t* tmp;
+ uint32_t tickstart = 0U;
+
+ if(husart->State == HAL_USART_STATE_READY)
+ {
+ if((pRxData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+ /* Process Locked */
+ __HAL_LOCK(husart);
+
+ husart->ErrorCode = HAL_USART_ERROR_NONE;
+ husart->State = HAL_USART_STATE_BUSY_RX;
+
+ /* Init tickstart for timeout managment */
+ tickstart = HAL_GetTick();
+
+ husart->RxXferSize = Size;
+ husart->RxXferCount = Size;
+ /* Check the remain data to be received */
+ while(husart->RxXferCount > 0U)
+ {
+ husart->RxXferCount--;
+ if(husart->Init.WordLength == USART_WORDLENGTH_9B)
+ {
+ /* Wait until TXE flag is set to send dummy byte in order to generate the clock for the slave to send data */
+ if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ /* Send dummy byte in order to generate clock */
+ WRITE_REG(husart->Instance->DR, (DUMMY_DATA & (uint16_t)0x01FF));
+
+ /* Wait for RXNE Flag */
+ if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ tmp = (uint16_t*) pRxData ;
+ if(husart->Init.Parity == USART_PARITY_NONE)
+ {
+ *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
+ pRxData +=2U;
+ }
+ else
+ {
+ *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
+ pRxData +=1U;
+ }
+ }
+ else
+ {
+ /* Wait until TXE flag is set to send dummy byte in order to generate the clock for the slave to send data */
+ if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+
+ /* Send Dummy Byte in order to generate clock */
+ WRITE_REG(husart->Instance->DR, (DUMMY_DATA & (uint16_t)0x00FF));
+
+ /* Wait until RXNE flag is set to receive the byte */
+ if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ if(husart->Init.Parity == USART_PARITY_NONE)
+ {
+ /* Receive data */
+ *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
+ }
+ else
+ {
+ /* Receive data */
+ *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
+ }
+
+ }
+ }
+
+ husart->State = HAL_USART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(husart);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Full-Duplex Send receive an amount of data in full-duplex mode (blocking mode).
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @param pTxData: Pointer to data transmitted buffer
+ * @param pRxData: Pointer to data received buffer
+ * @param Size: Amount of data to be sent
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
+{
+ uint16_t* tmp;
+ uint32_t tickstart = 0U;
+
+ if(husart->State == HAL_USART_STATE_READY)
+ {
+ if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+ /* Process Locked */
+ __HAL_LOCK(husart);
+
+ husart->ErrorCode = HAL_USART_ERROR_NONE;
+ husart->State = HAL_USART_STATE_BUSY_RX;
+
+ /* Init tickstart for timeout managment */
+ tickstart = HAL_GetTick();
+
+ husart->RxXferSize = Size;
+ husart->TxXferSize = Size;
+ husart->TxXferCount = Size;
+ husart->RxXferCount = Size;
+
+ /* Check the remain data to be received */
+ while(husart->TxXferCount > 0U)
+ {
+ husart->TxXferCount--;
+ husart->RxXferCount--;
+ if(husart->Init.WordLength == USART_WORDLENGTH_9B)
+ {
+ /* Wait for TC flag in order to write data in DR */
+ if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ tmp = (uint16_t*) pTxData;
+ WRITE_REG(husart->Instance->DR, (*tmp & (uint16_t)0x01FF));
+ if(husart->Init.Parity == USART_PARITY_NONE)
+ {
+ pTxData += 2U;
+ }
+ else
+ {
+ pTxData += 1U;
+ }
+
+ /* Wait for RXNE Flag */
+ if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ tmp = (uint16_t*) pRxData ;
+ if(husart->Init.Parity == USART_PARITY_NONE)
+ {
+ *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
+ pRxData += 2U;
+ }
+ else
+ {
+ *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
+ pRxData += 1U;
+ }
+ }
+ else
+ {
+ /* Wait for TC flag in order to write data in DR */
+ if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ WRITE_REG(husart->Instance->DR, (*pTxData++ & (uint8_t)0x00FF));
+
+ /* Wait for RXNE Flag */
+ if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ if(husart->Init.Parity == USART_PARITY_NONE)
+ {
+ /* Receive data */
+ *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
+ }
+ else
+ {
+ /* Receive data */
+ *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
+ }
+ }
+ }
+
+ husart->State = HAL_USART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(husart);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Simplex Send an amount of data in non-blocking mode.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @param pTxData: Pointer to data buffer
+ * @param Size: Amount of data to be sent
+ * @retval HAL status
+ * @note The USART errors are not managed to avoid the overrun error.
+ */
+HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
+{
+ /* Check that a Tx process is not already ongoing */
+ if(husart->State == HAL_USART_STATE_READY)
+ {
+ if((pTxData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+ /* Process Locked */
+ __HAL_LOCK(husart);
+
+ husart->pTxBuffPtr = pTxData;
+ husart->TxXferSize = Size;
+ husart->TxXferCount = Size;
+
+ husart->ErrorCode = HAL_USART_ERROR_NONE;
+ husart->State = HAL_USART_STATE_BUSY_TX;
+
+ /* The USART Error Interrupts: (Frame error, Noise error, Overrun error)
+ are not managed by the USART transmit process to avoid the overrun interrupt
+ when the USART mode is configured for transmit and receive "USART_MODE_TX_RX"
+ to benefit for the frame error and noise interrupts the USART mode should be
+ configured only for transmit "USART_MODE_TX"
+ The __HAL_USART_ENABLE_IT(husart, USART_IT_ERR) can be used to enable the Frame error,
+ Noise error interrupt */
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(husart);
+
+ /* Enable the USART Transmit Data Register Empty Interrupt */
+ __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Simplex Receive an amount of data in non-blocking mode.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @param pRxData: Pointer to data buffer
+ * @param Size: Amount of data to be received
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
+{
+ if(husart->State == HAL_USART_STATE_READY)
+ {
+ if((pRxData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+ /* Process Locked */
+ __HAL_LOCK(husart);
+
+ husart->pRxBuffPtr = pRxData;
+ husart->RxXferSize = Size;
+ husart->RxXferCount = Size;
+
+ husart->ErrorCode = HAL_USART_ERROR_NONE;
+ husart->State = HAL_USART_STATE_BUSY_RX;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(husart);
+
+ /* Enable the USART Data Register not empty Interrupt */
+ __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE);
+
+ /* Enable the USART Parity Error Interrupt */
+ __HAL_USART_ENABLE_IT(husart, USART_IT_PE);
+
+ /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
+ __HAL_USART_ENABLE_IT(husart, USART_IT_ERR);
+
+ /* Send dummy byte in order to generate the clock for the slave to send data */
+ WRITE_REG(husart->Instance->DR, (DUMMY_DATA & (uint16_t)0x01FF));
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @param pTxData: Pointer to data transmitted buffer
+ * @param pRxData: Pointer to data received buffer
+ * @param Size: Amount of data to be received
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
+{
+ if(husart->State == HAL_USART_STATE_READY)
+ {
+ if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+ /* Process Locked */
+ __HAL_LOCK(husart);
+
+ husart->pRxBuffPtr = pRxData;
+ husart->RxXferSize = Size;
+ husart->RxXferCount = Size;
+ husart->pTxBuffPtr = pTxData;
+ husart->TxXferSize = Size;
+ husart->TxXferCount = Size;
+
+ husart->ErrorCode = HAL_USART_ERROR_NONE;
+ husart->State = HAL_USART_STATE_BUSY_TX_RX;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(husart);
+
+ /* Enable the USART Data Register not empty Interrupt */
+ __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE);
+
+ /* Enable the USART Parity Error Interrupt */
+ __HAL_USART_ENABLE_IT(husart, USART_IT_PE);
+
+ /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
+ __HAL_USART_ENABLE_IT(husart, USART_IT_ERR);
+
+ /* Enable the USART Transmit Data Register Empty Interrupt */
+ __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Simplex Send an amount of data in non-blocking mode.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @param pTxData: Pointer to data buffer
+ * @param Size: Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
+{
+ uint32_t *tmp;
+
+ if(husart->State == HAL_USART_STATE_READY)
+ {
+ if((pTxData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+ /* Process Locked */
+ __HAL_LOCK(husart);
+
+ husart->pTxBuffPtr = pTxData;
+ husart->TxXferSize = Size;
+ husart->TxXferCount = Size;
+
+ husart->ErrorCode = HAL_USART_ERROR_NONE;
+ husart->State = HAL_USART_STATE_BUSY_TX;
+
+ /* Set the USART DMA transfer complete callback */
+ husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
+
+ /* Set the USART DMA Half transfer complete callback */
+ husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
+
+ /* Set the DMA error callback */
+ husart->hdmatx->XferErrorCallback = USART_DMAError;
+
+ /* Set the DMA abort callback */
+ husart->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the USART transmit DMA channel */
+ tmp = (uint32_t*)&pTxData;
+ HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->DR, Size);
+
+ /* Clear the TC flag in the SR register by writing 0 to it */
+ __HAL_USART_CLEAR_FLAG(husart, USART_FLAG_TC);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(husart);
+
+ /* Enable the DMA transfer for transmit request by setting the DMAT bit
+ in the USART CR3 register */
+ SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Full-Duplex Receive an amount of data in non-blocking mode.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @param pRxData: Pointer to data buffer
+ * @param Size: Amount of data to be received
+ * @retval HAL status
+ * @note The USART DMA transmit channel must be configured in order to generate the clock for the slave.
+ * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
+ */
+HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
+{
+ uint32_t *tmp;
+
+ if(husart->State == HAL_USART_STATE_READY)
+ {
+ if((pRxData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(husart);
+
+ husart->pRxBuffPtr = pRxData;
+ husart->RxXferSize = Size;
+ husart->pTxBuffPtr = pRxData;
+ husart->TxXferSize = Size;
+
+ husart->ErrorCode = HAL_USART_ERROR_NONE;
+ husart->State = HAL_USART_STATE_BUSY_RX;
+
+ /* Set the USART DMA Rx transfer complete callback */
+ husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
+
+ /* Set the USART DMA Half transfer complete callback */
+ husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
+
+ /* Set the USART DMA Rx transfer error callback */
+ husart->hdmarx->XferErrorCallback = USART_DMAError;
+
+ /* Set the DMA abort callback */
+ husart->hdmarx->XferAbortCallback = NULL;
+
+ /* Set the USART Tx DMA transfer complete callback as NULL because the communication closing
+ is performed in DMA reception complete callback */
+ husart->hdmatx->XferHalfCpltCallback = NULL;
+ husart->hdmatx->XferCpltCallback = NULL;
+
+ /* Set the DMA error callback */
+ husart->hdmatx->XferErrorCallback = USART_DMAError;
+
+ /* Set the DMA AbortCpltCallback */
+ husart->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the USART receive DMA channel */
+ tmp = (uint32_t*)&pRxData;
+ HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->DR, *(uint32_t*)tmp, Size);
+
+ /* Enable the USART transmit DMA channel: the transmit channel is used in order
+ to generate in the non-blocking mode the clock to the slave device,
+ this mode isn't a simplex receive mode but a full-duplex receive one */
+ HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->DR, Size);
+
+ /* Clear the Overrun flag just before enabling the DMA Rx request: mandatory for the second transfer */
+ __HAL_USART_CLEAR_OREFLAG(husart);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(husart);
+
+ /* Enable the USART Parity Error Interrupt */
+ SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
+
+ /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
+ SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
+
+ /* Enable the DMA transfer for the receiver request by setting the DMAR bit
+ in the USART CR3 register */
+ SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Enable the DMA transfer for transmit request by setting the DMAT bit
+ in the USART CR3 register */
+ SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Full-Duplex Transmit Receive an amount of data in non-blocking mode.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @param pTxData: Pointer to data transmitted buffer
+ * @param pRxData: Pointer to data received buffer
+ * @param Size: Amount of data to be received
+ * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
+{
+ uint32_t *tmp;
+
+ if(husart->State == HAL_USART_STATE_READY)
+ {
+ if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+ /* Process Locked */
+ __HAL_LOCK(husart);
+
+ husart->pRxBuffPtr = pRxData;
+ husart->RxXferSize = Size;
+ husart->pTxBuffPtr = pTxData;
+ husart->TxXferSize = Size;
+
+ husart->ErrorCode = HAL_USART_ERROR_NONE;
+ husart->State = HAL_USART_STATE_BUSY_TX_RX;
+
+ /* Set the USART DMA Rx transfer complete callback */
+ husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
+
+ /* Set the USART DMA Half transfer complete callback */
+ husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
+
+ /* Set the USART DMA Tx transfer complete callback */
+ husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
+
+ /* Set the USART DMA Half transfer complete callback */
+ husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
+
+ /* Set the USART DMA Tx transfer error callback */
+ husart->hdmatx->XferErrorCallback = USART_DMAError;
+
+ /* Set the USART DMA Rx transfer error callback */
+ husart->hdmarx->XferErrorCallback = USART_DMAError;
+
+ /* Set the DMA abort callback */
+ husart->hdmarx->XferAbortCallback = NULL;
+
+ /* Enable the USART receive DMA channel */
+ tmp = (uint32_t*)&pRxData;
+ HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->DR, *(uint32_t*)tmp, Size);
+
+ /* Enable the USART transmit DMA channel */
+ tmp = (uint32_t*)&pTxData;
+ HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->DR, Size);
+
+ /* Clear the TC flag in the SR register by writing 0 to it */
+ __HAL_USART_CLEAR_FLAG(husart, USART_FLAG_TC);
+
+ /* Clear the Overrun flag: mandatory for the second transfer in circular mode */
+ __HAL_USART_CLEAR_OREFLAG(husart);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(husart);
+
+ /* Enable the USART Parity Error Interrupt */
+ SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
+
+ /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
+ SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
+
+ /* Enable the DMA transfer for the receiver request by setting the DMAR bit
+ in the USART CR3 register */
+ SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Enable the DMA transfer for transmit request by setting the DMAT bit
+ in the USART CR3 register */
+ SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Pauses the DMA Transfer.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
+{
+ /* Process Locked */
+ __HAL_LOCK(husart);
+
+ /* Disable the USART DMA Tx request */
+ CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(husart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Resumes the DMA Transfer.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
+{
+ /* Process Locked */
+ __HAL_LOCK(husart);
+
+ /* Enable the USART DMA Tx request */
+ SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(husart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the DMA Transfer.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
+{
+ uint32_t dmarequest = 0x00U;
+ /* The Lock is not implemented on this API to allow the user application
+ to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback():
+ when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
+ and the correspond call back is executed HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback()
+ */
+
+ /* Stop USART DMA Tx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT);
+ if((husart->State == HAL_USART_STATE_BUSY_TX) && dmarequest)
+ {
+ USART_EndTxTransfer(husart);
+
+ /* Abort the USART DMA Tx channel */
+ if(husart->hdmatx != NULL)
+ {
+ HAL_DMA_Abort(husart->hdmatx);
+ }
+
+ /* Disable the USART Tx DMA request */
+ CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+ }
+
+ /* Stop USART DMA Rx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR);
+ if((husart->State == HAL_USART_STATE_BUSY_RX) && dmarequest)
+ {
+ USART_EndRxTransfer(husart);
+
+ /* Abort the USART DMA Rx channel */
+ if(husart->hdmarx != NULL)
+ {
+ HAL_DMA_Abort(husart->hdmarx);
+ }
+
+ /* Disable the USART Rx DMA request */
+ CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing transfer (blocking mode).
+ * @param husart USART handle.
+ * @note This procedure could be used for aborting any ongoing transfer (either Tx or Rx,
+ * as described by TransferType parameter) started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts (depending of transfer direction)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_USART_Abort(USART_HandleTypeDef *husart)
+{
+ /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
+ CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the USART DMA Tx request if enabled */
+ if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
+ {
+ CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the USART DMA Tx channel : use blocking DMA Abort API (no callback) */
+ if(husart->hdmatx != NULL)
+ {
+ /* Set the USART DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ husart->hdmatx->XferAbortCallback = NULL;
+
+ HAL_DMA_Abort(husart->hdmatx);
+ }
+ }
+
+ /* Disable the USART DMA Rx request if enabled */
+ if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the USART DMA Rx channel : use blocking DMA Abort API (no callback) */
+ if(husart->hdmarx != NULL)
+ {
+ /* Set the USART DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ husart->hdmarx->XferAbortCallback = NULL;
+
+ HAL_DMA_Abort(husart->hdmarx);
+ }
+ }
+
+ /* Reset Tx and Rx transfer counters */
+ husart->TxXferCount = 0x00U;
+ husart->RxXferCount = 0x00U;
+
+ /* Restore husart->State to Ready */
+ husart->State = HAL_USART_STATE_READY;
+
+ /* Reset Handle ErrorCode to No Error */
+ husart->ErrorCode = HAL_USART_ERROR_NONE;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing transfer (Interrupt mode).
+ * @param husart USART handle.
+ * @note This procedure could be used for aborting any ongoing transfer (either Tx or Rx,
+ * as described by TransferType parameter) started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable PPP Interrupts (depending of transfer direction)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_USART_Abort_IT(USART_HandleTypeDef *husart)
+{
+ uint32_t AbortCplt = 0x01U;
+
+ /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
+ CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
+
+ /* If DMA Tx and/or DMA Rx Handles are associated to USART Handle, DMA Abort complete callbacks should be initialised
+ before any call to DMA Abort functions */
+ /* DMA Tx Handle is valid */
+ if(husart->hdmatx != NULL)
+ {
+ /* Set DMA Abort Complete callback if USART DMA Tx request if enabled.
+ Otherwise, set it to NULL */
+ if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
+ {
+ husart->hdmatx->XferAbortCallback = USART_DMATxAbortCallback;
+ }
+ else
+ {
+ husart->hdmatx->XferAbortCallback = NULL;
+ }
+ }
+ /* DMA Rx Handle is valid */
+ if(husart->hdmarx != NULL)
+ {
+ /* Set DMA Abort Complete callback if USART DMA Rx request if enabled.
+ Otherwise, set it to NULL */
+ if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
+ {
+ husart->hdmarx->XferAbortCallback = USART_DMARxAbortCallback;
+ }
+ else
+ {
+ husart->hdmarx->XferAbortCallback = NULL;
+ }
+ }
+
+ /* Disable the USART DMA Tx request if enabled */
+ if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
+ {
+ /* Disable DMA Tx at USART level */
+ CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the USART DMA Tx channel : use non blocking DMA Abort API (callback) */
+ if(husart->hdmatx != NULL)
+ {
+ /* USART Tx DMA Abort callback has already been initialised :
+ will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
+
+ /* Abort DMA TX */
+ if(HAL_DMA_Abort_IT(husart->hdmatx) != HAL_OK)
+ {
+ husart->hdmatx->XferAbortCallback = NULL;
+ }
+ else
+ {
+ AbortCplt = 0x00U;
+ }
+ }
+ }
+
+ /* Disable the USART DMA Rx request if enabled */
+ if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the USART DMA Rx channel : use non blocking DMA Abort API (callback) */
+ if(husart->hdmarx != NULL)
+ {
+ /* USART Rx DMA Abort callback has already been initialised :
+ will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
+
+ /* Abort DMA RX */
+ if(HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
+ {
+ husart->hdmarx->XferAbortCallback = NULL;
+ AbortCplt = 0x01U;
+ }
+ else
+ {
+ AbortCplt = 0x00U;
+ }
+ }
+ }
+
+ /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
+ if(AbortCplt == 0x01U)
+ {
+ /* Reset Tx and Rx transfer counters */
+ husart->TxXferCount = 0x00U;
+ husart->RxXferCount = 0x00U;
+
+ /* Reset errorCode */
+ husart->ErrorCode = HAL_USART_ERROR_NONE;
+
+ /* Restore husart->State to Ready */
+ husart->State = HAL_USART_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+ HAL_USART_AbortCpltCallback(husart);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles USART interrupt request.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval None
+ */
+void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
+{
+ uint32_t isrflags = READ_REG(husart->Instance->SR);
+ uint32_t cr1its = READ_REG(husart->Instance->CR1);
+ uint32_t cr3its = READ_REG(husart->Instance->CR3);
+ uint32_t errorflags = 0x00U;
+ uint32_t dmarequest = 0x00U;
+
+ /* If no error occurs */
+ errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
+ if(errorflags == RESET)
+ {
+ /* USART in mode Receiver -------------------------------------------------*/
+ if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
+ {
+ if(husart->State == HAL_USART_STATE_BUSY_RX)
+ {
+ USART_Receive_IT(husart);
+ }
+ else
+ {
+ USART_TransmitReceive_IT(husart);
+ }
+ return;
+ }
+ }
+ /* If some errors occur */
+ if((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
+ {
+ /* USART parity error interrupt occurred ----------------------------------*/
+ if(((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
+ {
+ husart->ErrorCode |= HAL_USART_ERROR_PE;
+ }
+
+ /* USART noise error interrupt occurred --------------------------------*/
+ if(((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
+ {
+ husart->ErrorCode |= HAL_USART_ERROR_NE;
+ }
+
+ /* USART frame error interrupt occurred --------------------------------*/
+ if(((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
+ {
+ husart->ErrorCode |= HAL_USART_ERROR_FE;
+ }
+
+ /* USART Over-Run interrupt occurred -----------------------------------*/
+ if(((isrflags & USART_SR_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
+ {
+ husart->ErrorCode |= HAL_USART_ERROR_ORE;
+ }
+
+ if(husart->ErrorCode != HAL_USART_ERROR_NONE)
+ {
+ /* USART in mode Receiver -----------------------------------------------*/
+ if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
+ {
+ if(husart->State == HAL_USART_STATE_BUSY_RX)
+ {
+ USART_Receive_IT(husart);
+ }
+ else
+ {
+ USART_TransmitReceive_IT(husart);
+ }
+ }
+ /* If Overrun error occurs, or if any error occurs in DMA mode reception,
+ consider error as blocking */
+ dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR);
+ if(((husart->ErrorCode & HAL_USART_ERROR_ORE) != RESET) || dmarequest)
+ {
+ /* Set the USART state ready to be able to start again the process,
+ Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
+ USART_EndRxTransfer(husart);
+
+ /* Disable the USART DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
+ {
+ CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the USART DMA Rx channel */
+ if(husart->hdmarx != NULL)
+ {
+ /* Set the USART DMA Abort callback :
+ will lead to call HAL_USART_ErrorCallback() at end of DMA abort procedure */
+ husart->hdmarx->XferAbortCallback = USART_DMAAbortOnError;
+
+ if(HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
+ {
+ /* Call Directly XferAbortCallback function in case of error */
+ husart->hdmarx->XferAbortCallback(husart->hdmarx);
+ }
+ }
+ else
+ {
+ /* Call user error callback */
+ HAL_USART_ErrorCallback(husart);
+ }
+ }
+ else
+ {
+ /* Call user error callback */
+ HAL_USART_ErrorCallback(husart);
+ }
+ }
+ else
+ {
+ /* Call user error callback */
+ HAL_USART_ErrorCallback(husart);
+ husart->ErrorCode = HAL_USART_ERROR_NONE;
+ }
+ }
+ return;
+ }
+
+ /* USART in mode Transmitter -----------------------------------------------*/
+ if(((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
+ {
+ if(husart->State == HAL_USART_STATE_BUSY_TX)
+ {
+ USART_Transmit_IT(husart);
+ }
+ else
+ {
+ USART_TransmitReceive_IT(husart);
+ }
+ return;
+ }
+
+ /* USART in mode Transmitter (transmission end) ----------------------------*/
+ if(((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
+ {
+ USART_EndTransmit_IT(husart);
+ return;
+ }
+}
+
+/**
+ * @brief Tx Transfer completed callbacks.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval None
+ */
+__weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(husart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_USART_TxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Tx Half Transfer completed callbacks.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval None
+ */
+__weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(husart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_USART_TxHalfCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer completed callbacks.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval None
+ */
+__weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(husart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_USART_RxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Half Transfer completed callbacks.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval None
+ */
+__weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(husart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_USART_RxHalfCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Tx/Rx Transfers completed callback for the non-blocking process.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval None
+ */
+__weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(husart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_USART_TxRxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief USART error callbacks.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval None
+ */
+__weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(husart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_USART_ErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief USART Abort Complete callback.
+ * @param husart USART handle.
+ * @retval None
+ */
+__weak void HAL_USART_AbortCpltCallback (USART_HandleTypeDef *husart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(husart);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_USART_AbortCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Exported_Functions_Group3 Peripheral State and Errors functions
+ * @brief USART State and Errors functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral State and Errors functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to return the State of
+ USART communication
+ process, return Peripheral Errors occurred during communication process
+ (+) HAL_USART_GetState() API can be helpful to check in run-time the state
+ of the USART peripheral.
+ (+) HAL_USART_GetError() check in run-time errors that could be occurred during
+ communication.
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns the USART state.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval HAL state
+ */
+HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart)
+{
+ return husart->State;
+}
+
+/**
+ * @brief Return the USART error code
+ * @param husart : pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART.
+ * @retval USART Error Code
+ */
+uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart)
+{
+ return husart->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Private_Functions USART Private Functions
+ * @brief USART Private functions
+ * @{
+ */
+/**
+ * @brief DMA USART transmit process complete callback.
+ * @param hdma: DMA handle
+ * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
+{
+ USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ /* DMA Normal mode */
+ if(HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
+ {
+ husart->TxXferCount = 0U;
+ if(husart->State == HAL_USART_STATE_BUSY_TX)
+ {
+ /* Disable the DMA transfer for transmit request by resetting the DMAT bit
+ in the USART CR3 register */
+ CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Enable the USART Transmit Complete Interrupt */
+ __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
+ }
+ }
+ /* DMA Circular mode */
+ else
+ {
+ if(husart->State == HAL_USART_STATE_BUSY_TX)
+ {
+ HAL_USART_TxCpltCallback(husart);
+ }
+ }
+}
+
+/**
+ * @brief DMA USART transmit process half complete callback
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
+
+ HAL_USART_TxHalfCpltCallback(husart);
+}
+
+/**
+ * @brief DMA USART receive process complete callback.
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ /* DMA Normal mode */
+ if(HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
+ {
+ husart->RxXferCount = 0x00U;
+
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
+ CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
+
+ if(husart->State == HAL_USART_STATE_BUSY_RX)
+ {
+ /* Disable the DMA transfer for the Transmit/Receiver requests by setting the DMAT/DMAR bit
+ in the USART CR3 register */
+ CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
+
+ husart->State= HAL_USART_STATE_READY;
+ HAL_USART_RxCpltCallback(husart);
+ }
+ /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
+ else
+ {
+ /* Disable the DMA transfer for the Transmit/receiver requests by setting the DMAT/DMAR bit
+ in the USART CR3 register */
+ CLEAR_BIT(husart->Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
+
+ husart->State= HAL_USART_STATE_READY;
+ HAL_USART_TxRxCpltCallback(husart);
+ }
+ }
+ /* DMA circular mode */
+ else
+ {
+ if(husart->State == HAL_USART_STATE_BUSY_RX)
+ {
+ HAL_USART_RxCpltCallback(husart);
+ }
+ /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
+ else
+ {
+ HAL_USART_TxRxCpltCallback(husart);
+ }
+ }
+}
+
+/**
+ * @brief DMA USART receive process half complete callback
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
+
+ HAL_USART_RxHalfCpltCallback(husart);
+}
+
+/**
+ * @brief DMA USART communication error callback.
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void USART_DMAError(DMA_HandleTypeDef *hdma)
+{
+ uint32_t dmarequest = 0x00U;
+ USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ husart->RxXferCount = 0x00U;
+ husart->TxXferCount = 0x00U;
+
+ /* Stop USART DMA Tx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT);
+ if((husart->State == HAL_USART_STATE_BUSY_TX) && dmarequest)
+ {
+ USART_EndTxTransfer(husart);
+ }
+
+ /* Stop USART DMA Rx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR);
+ if((husart->State == HAL_USART_STATE_BUSY_RX) && dmarequest)
+ {
+ USART_EndRxTransfer(husart);
+ }
+
+ husart->ErrorCode |= HAL_USART_ERROR_DMA;
+ husart->State= HAL_USART_STATE_READY;
+
+ HAL_USART_ErrorCallback(husart);
+}
+
+/**
+ * @brief This function handles USART Communication Timeout.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @param Flag: specifies the USART flag to check.
+ * @param Status: The new Flag status (SET or RESET).
+ * @param Tickstart: Tick start value.
+ * @param Timeout: Timeout duration.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
+{
+ /* Wait until flag is set */
+ while((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status)
+ {
+ /* Check for the Timeout */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout))
+ {
+ /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
+ __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
+ __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
+ __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
+ __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
+
+ husart->State= HAL_USART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(husart);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief End ongoing Tx transfer on USART peripheral (following error detection or Transmit completion).
+ * @param husart: USART handle.
+ * @retval None
+ */
+static void USART_EndTxTransfer(USART_HandleTypeDef *husart)
+{
+ /* Disable TXEIE and TCIE interrupts */
+ CLEAR_BIT(husart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+
+ /* At end of Tx process, restore husart->State to Ready */
+ husart->State = HAL_USART_STATE_READY;
+}
+
+/**
+ * @brief End ongoing Rx transfer on USART peripheral (following error detection or Reception completion).
+ * @param husart: USART handle.
+ * @retval None
+ */
+static void USART_EndRxTransfer(USART_HandleTypeDef *husart)
+{
+ /* Disable RXNE, PE and ERR interrupts */
+ CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
+
+ /* At end of Rx process, restore husart->State to Ready */
+ husart->State = HAL_USART_STATE_READY;
+}
+
+/**
+ * @brief DMA USART communication abort callback, when initiated by HAL services on Error
+ * (To be called at end of DMA Abort procedure following error occurrence).
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
+{
+ USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ husart->RxXferCount = 0x00U;
+ husart->TxXferCount = 0x00U;
+
+ HAL_USART_ErrorCallback(husart);
+}
+
+/**
+ * @brief DMA USART Tx communication abort callback, when initiated by user
+ * (To be called at end of DMA Tx Abort procedure following user abort request).
+ * @note When this callback is executed, User Abort complete call back is called only if no
+ * Abort still ongoing for Rx DMA Handle.
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ husart->hdmatx->XferAbortCallback = NULL;
+
+ /* Check if an Abort process is still ongoing */
+ if(husart->hdmarx != NULL)
+ {
+ if(husart->hdmarx->XferAbortCallback != NULL)
+ {
+ return;
+ }
+ }
+
+ /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+ husart->TxXferCount = 0x00U;
+ husart->RxXferCount = 0x00U;
+
+ /* Reset errorCode */
+ husart->ErrorCode = HAL_USART_ERROR_NONE;
+
+ /* Restore husart->State to Ready */
+ husart->State = HAL_USART_STATE_READY;
+
+ /* Call user Abort complete callback */
+ HAL_USART_AbortCpltCallback(husart);
+}
+
+/**
+ * @brief DMA USART Rx communication abort callback, when initiated by user
+ * (To be called at end of DMA Rx Abort procedure following user abort request).
+ * @note When this callback is executed, User Abort complete call back is called only if no
+ * Abort still ongoing for Tx DMA Handle.
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ husart->hdmarx->XferAbortCallback = NULL;
+
+ /* Check if an Abort process is still ongoing */
+ if(husart->hdmatx != NULL)
+ {
+ if(husart->hdmatx->XferAbortCallback != NULL)
+ {
+ return;
+ }
+ }
+
+ /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+ husart->TxXferCount = 0x00U;
+ husart->RxXferCount = 0x00U;
+
+ /* Reset errorCode */
+ husart->ErrorCode = HAL_USART_ERROR_NONE;
+
+ /* Restore husart->State to Ready */
+ husart->State = HAL_USART_STATE_READY;
+
+ /* Call user Abort complete callback */
+ HAL_USART_AbortCpltCallback(husart);
+}
+
+/**
+ * @brief Simplex Send an amount of data in non-blocking mode.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval HAL status
+ * @note The USART errors are not managed to avoid the overrun error.
+ */
+static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart)
+{
+ uint16_t* tmp;
+
+ if(husart->State == HAL_USART_STATE_BUSY_TX)
+ {
+ if(husart->Init.WordLength == USART_WORDLENGTH_9B)
+ {
+ tmp = (uint16_t*) husart->pTxBuffPtr;
+ WRITE_REG(husart->Instance->DR, (uint16_t)(*tmp & (uint16_t)0x01FF));
+ if(husart->Init.Parity == USART_PARITY_NONE)
+ {
+ husart->pTxBuffPtr += 2U;
+ }
+ else
+ {
+ husart->pTxBuffPtr += 1U;
+ }
+ }
+ else
+ {
+ WRITE_REG(husart->Instance->DR, (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0x00FF));
+ }
+
+ if(--husart->TxXferCount == 0U)
+ {
+ /* Disable the USART Transmit data register empty Interrupt */
+ __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
+
+ /* Enable the USART Transmit Complete Interrupt */
+ __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
+ }
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Wraps up transmission in non blocking mode.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart)
+{
+ /* Disable the USART Transmit Complete Interrupt */
+ __HAL_USART_DISABLE_IT(husart, USART_IT_TC);
+
+ /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
+ __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
+
+ husart->State = HAL_USART_STATE_READY;
+
+ HAL_USART_TxCpltCallback(husart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Simplex Receive an amount of data in non-blocking mode.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart)
+{
+ uint16_t* tmp;
+ if(husart->State == HAL_USART_STATE_BUSY_RX)
+ {
+ if(husart->Init.WordLength == USART_WORDLENGTH_9B)
+ {
+ tmp = (uint16_t*) husart->pRxBuffPtr;
+ if(husart->Init.Parity == USART_PARITY_NONE)
+ {
+ *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
+ husart->pRxBuffPtr += 2U;
+ }
+ else
+ {
+ *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
+ husart->pRxBuffPtr += 1U;
+ }
+ if(--husart->RxXferCount != 0x00U)
+ {
+ /* Send dummy byte in order to generate the clock for the slave to send the next data */
+ WRITE_REG(husart->Instance->DR, (DUMMY_DATA & (uint16_t)0x01FF));
+ }
+ }
+ else
+ {
+ if(husart->Init.Parity == USART_PARITY_NONE)
+ {
+ *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
+ }
+ else
+ {
+ *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
+ }
+
+ if(--husart->RxXferCount != 0x00U)
+ {
+ /* Send dummy byte in order to generate the clock for the slave to send the next data */
+ WRITE_REG(husart->Instance->DR, (DUMMY_DATA & (uint16_t)0x00FF));
+ }
+ }
+
+ if(husart->RxXferCount == 0U)
+ {
+ /* Disable the USART RXNE Interrupt */
+ CLEAR_BIT(husart->Instance->CR1, USART_CR1_RXNEIE);
+
+ /* Disable the USART Parity Error Interrupt */
+ CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
+
+ /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
+ CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
+
+ husart->State = HAL_USART_STATE_READY;
+ HAL_USART_RxCpltCallback(husart);
+
+ return HAL_OK;
+ }
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart)
+{
+ uint16_t* tmp;
+
+ if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
+ {
+ if(husart->TxXferCount != 0x00U)
+ {
+ if(__HAL_USART_GET_FLAG(husart, USART_FLAG_TXE) != RESET)
+ {
+ if(husart->Init.WordLength == USART_WORDLENGTH_9B)
+ {
+ tmp = (uint16_t*) husart->pTxBuffPtr;
+ WRITE_REG(husart->Instance->DR, (uint16_t)(*tmp & (uint16_t)0x01FF));
+ if(husart->Init.Parity == USART_PARITY_NONE)
+ {
+ husart->pTxBuffPtr += 2U;
+ }
+ else
+ {
+ husart->pTxBuffPtr += 1U;
+ }
+ }
+ else
+ {
+ WRITE_REG(husart->Instance->DR, (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0x00FF));
+ }
+ husart->TxXferCount--;
+
+ /* Check the latest data transmitted */
+ if(husart->TxXferCount == 0U)
+ {
+ CLEAR_BIT(husart->Instance->CR1, USART_CR1_TXEIE);
+ }
+ }
+ }
+
+ if(husart->RxXferCount != 0x00U)
+ {
+ if(__HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE) != RESET)
+ {
+ if(husart->Init.WordLength == USART_WORDLENGTH_9B)
+ {
+ tmp = (uint16_t*) husart->pRxBuffPtr;
+ if(husart->Init.Parity == USART_PARITY_NONE)
+ {
+ *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
+ husart->pRxBuffPtr += 2U;
+ }
+ else
+ {
+ *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
+ husart->pRxBuffPtr += 1U;
+ }
+ }
+ else
+ {
+ if(husart->Init.Parity == USART_PARITY_NONE)
+ {
+ *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
+ }
+ else
+ {
+ *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
+ }
+ }
+ husart->RxXferCount--;
+ }
+ }
+
+ /* Check the latest data received */
+ if(husart->RxXferCount == 0U)
+ {
+ /* Disable the USART RXNE Interrupt */
+ CLEAR_BIT(husart->Instance->CR1, USART_CR1_RXNEIE);
+
+ /* Disable the USART Parity Error Interrupt */
+ CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
+
+ /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
+ CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
+
+ husart->State = HAL_USART_STATE_READY;
+
+ HAL_USART_TxRxCpltCallback(husart);
+
+ return HAL_OK;
+ }
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Configures the USART pferipheral.
+ * @param husart: pointer to a USART_HandleTypeDef structure that contains
+ * the configuration information for the specified USART module.
+ * @retval None
+ */
+static void USART_SetConfig(USART_HandleTypeDef *husart)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
+ assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
+ assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
+ assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));
+ assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
+ assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
+ assert_param(IS_USART_PARITY(husart->Init.Parity));
+ assert_param(IS_USART_MODE(husart->Init.Mode));
+
+ /* The LBCL, CPOL and CPHA bits have to be selected when both the transmitter and the
+ receiver are disabled (TE=RE=0) to ensure that the clock pulses function correctly. */
+ CLEAR_BIT(husart->Instance->CR1, ((uint32_t)(USART_CR1_TE | USART_CR1_RE)));
+
+ /*---------------------------- USART CR2 Configuration ---------------------*/
+ /* Configure the USART Clock, CPOL, CPHA and LastBit -----------------------*/
+ /* Set CPOL bit according to husart->Init.CLKPolarity value */
+ /* Set CPHA bit according to husart->Init.CLKPhase value */
+ /* Set LBCL bit according to husart->Init.CLKLastBit value */
+ /* Set Stop Bits: Set STOP[13:12] bits according to husart->Init.StopBits value */
+ /* Write to USART CR2 */
+ MODIFY_REG(husart->Instance->CR2,
+ (uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP),
+ ((uint32_t)(USART_CLOCK_ENABLE| husart->Init.CLKPolarity | husart->Init.CLKPhase| husart->Init.CLKLastBit | husart->Init.StopBits)));
+
+ /*-------------------------- USART CR1 Configuration -----------------------*/
+ /* Configure the USART Word Length, Parity and mode:
+ Set the M bits according to husart->Init.WordLength value
+ Set PCE and PS bits according to husart->Init.Parity value
+ Set TE and RE bits according to husart->Init.Mode value */
+ MODIFY_REG(husart->Instance->CR1,
+ (uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE),
+ (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode);
+
+ /*-------------------------- USART CR3 Configuration -----------------------*/
+ /* Clear CTSE and RTSE bits */
+ CLEAR_BIT(husart->Instance->CR3, (uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE));
+
+ /*-------------------------- USART BRR Configuration -----------------------*/
+ if((husart->Instance == USART1))
+ {
+ husart->Instance->BRR = USART_BRR(HAL_RCC_GetPCLK2Freq(), husart->Init.BaudRate);
+ }
+ else
+ {
+ husart->Instance->BRR = USART_BRR(HAL_RCC_GetPCLK1Freq(), husart->Init.BaudRate);
+ }
+}
+
+/**
+ * @}
+ */
+
+#endif /* HAL_USART_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_wwdg.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_wwdg.c
new file mode 100644
index 0000000..4f2cdca
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_wwdg.c
@@ -0,0 +1,312 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_wwdg.c
+ * @author MCD Application Team
+ * @brief WWDG HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Window Watchdog (WWDG) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral State functions
+ @verbatim
+ ==============================================================================
+ ##### WWDG specific features #####
+ ==============================================================================
+ [..]
+ Once enabled the WWDG generates a system reset on expiry of a programmed
+ time period, unless the program refreshes the counter (downcounter)
+ before reaching 0x3F value (i.e. a reset is generated when the counter
+ value rolls over from 0x40 to 0x3F).
+
+ (+) An MCU reset is also generated if the counter value is refreshed
+ before the counter has reached the refresh window value. This
+ implies that the counter must be refreshed in a limited window.
+ (+) Once enabled the WWDG cannot be disabled except by a system reset.
+ (+) WWDGRST flag in RCC_CSR register can be used to inform when a WWDG
+ reset occurs.
+ (+) The WWDG counter input clock is derived from the APB clock divided
+ by a programmable prescaler.
+ (+) WWDG clock (Hz) = PCLK1 / (4096 * Prescaler)
+ (+) WWDG timeout (mS) = 1000 * Counter / WWDG clock
+ (+) WWDG Counter refresh is allowed between the following limits :
+ (++) min time (mS) = 1000 * (Counter _ Window) / WWDG clock
+ (++) max time (mS) = 1000 * (Counter _ 0x40) / WWDG clock
+
+ (+) Min-max timeout value at 36 MHz(PCLK1): 910 us / 58.25 ms
+
+ (+) The Early Wakeup Interrupt (EWI) can be used if specific safety
+ operations or data logging must be performed before the actual reset is
+ generated. When the downcounter reaches the value 0x40, an EWI interrupt
+ is generated and the corresponding interrupt service routine (ISR) can
+ be used to trigger specific actions (such as communications or data
+ logging), before resetting the device.
+ In some applications, the EWI interrupt can be used to manage a software
+ system check and/or system recovery/graceful degradation, without
+ generating a WWDG reset. In this case, the corresponding interrupt
+ service routine (ISR) should reload the WWDG counter to avoid the WWDG
+ reset, then trigger the required actions.
+ Note:When the EWI interrupt cannot be served, e.g. due to a system lock
+ in a higher priority task, the WWDG reset will eventually be generated.
+
+ (+) Debug mode : When the microcontroller enters debug mode (core halted),
+ the WWDG counter either continues to work normally or stops, depending
+ on DBG_WWDG_STOP configuration bit in DBG module, accessible through
+ __HAL_DBGMCU_FREEZE_WWDG() and __HAL_DBGMCU_UNFREEZE_WWDG() macros
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (+) Enable WWDG APB1 clock using __HAL_RCC_WWDG_CLK_ENABLE().
+
+ (+) Set the WWDG prescaler, refresh window, counter value and Early Wakeup
+ Interrupt mode using using HAL_WWDG_Init() function.
+ This enables WWDG peripheral and the downcounter starts downcounting
+ from given counter value.
+ Init function can be called again to modify all watchdog parameters,
+ however if EWI mode has been set once, it can't be clear until next
+ reset.
+
+ (+) The application program must refresh the WWDG counter at regular
+ intervals during normal operation to prevent an MCU reset using
+ HAL_WWDG_Refresh() function. This operation must occur only when
+ the counter is lower than the window value already programmed.
+
+ (+) if Early Wakeup Interrupt mode is enable an interrupt is generated when
+ the counter reaches 0x40. User can add his own code in weak function
+ HAL_WWDG_EarlyWakeupCallback().
+
+ *** WWDG HAL driver macros list ***
+ ==================================
+ [..]
+ Below the list of most used macros in WWDG HAL driver.
+
+ (+) __HAL_WWDG_GET_IT_SOURCE: Check the selected WWDG's interrupt source.
+ (+) __HAL_WWDG_GET_FLAG: Get the selected WWDG's flag status.
+ (+) __HAL_WWDG_CLEAR_FLAG: Clear the WWDG's pending flags.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_WWDG_MODULE_ENABLED
+/** @defgroup WWDG WWDG
+ * @brief WWDG HAL module driver.
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup WWDG_Exported_Functions WWDG Exported Functions
+ * @{
+ */
+
+/** @defgroup WWDG_Exported_Functions_Group1 Initialization and Configuration functions
+ * @brief Initialization and Configuration functions.
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and Configuration functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and start the WWDG according to the specified parameters
+ in the WWDG_InitTypeDef of associated handle.
+ (+) Initialize the WWDG MSP.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initialize the WWDG according to the specified.
+ * parameters in the WWDG_InitTypeDef of associated handle.
+ * @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains
+ * the configuration information for the specified WWDG module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg)
+{
+ /* Check the WWDG handle allocation */
+ if (hwwdg == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_WWDG_ALL_INSTANCE(hwwdg->Instance));
+ assert_param(IS_WWDG_PRESCALER(hwwdg->Init.Prescaler));
+ assert_param(IS_WWDG_WINDOW(hwwdg->Init.Window));
+ assert_param(IS_WWDG_COUNTER(hwwdg->Init.Counter));
+ assert_param(IS_WWDG_EWI_MODE(hwwdg->Init.EWIMode));
+
+ /* Init the low level hardware */
+ HAL_WWDG_MspInit(hwwdg);
+
+ /* Set WWDG Counter */
+ WRITE_REG(hwwdg->Instance->CR, (WWDG_CR_WDGA | hwwdg->Init.Counter));
+
+ /* Set WWDG Prescaler and Window */
+ WRITE_REG(hwwdg->Instance->CFR, (hwwdg->Init.EWIMode | hwwdg->Init.Prescaler | hwwdg->Init.Window));
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Initialize the WWDG MSP.
+ * @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains
+ * the configuration information for the specified WWDG module.
+ * @note When rewriting this function in user file, mechanism may be added
+ * to avoid multiple initialize when HAL_WWDG_Init function is called
+ * again to change parameters.
+ * @retval None
+ */
+__weak void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hwwdg);
+
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_WWDG_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup WWDG_Exported_Functions_Group2 IO operation functions
+ * @brief IO operation functions
+ *
+@verbatim
+ ==============================================================================
+ ##### IO operation functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Refresh the WWDG.
+ (+) Handle WWDG interrupt request and associated function callback.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Refresh the WWDG.
+ * @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains
+ * the configuration information for the specified WWDG module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg)
+{
+ /* Write to WWDG CR the WWDG Counter value to refresh with */
+ WRITE_REG(hwwdg->Instance->CR, (hwwdg->Init.Counter));
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Handle WWDG interrupt request.
+ * @note The Early Wakeup Interrupt (EWI) can be used if specific safety operations
+ * or data logging must be performed before the actual reset is generated.
+ * The EWI interrupt is enabled by calling HAL_WWDG_Init function with
+ * EWIMode set to WWDG_EWI_ENABLE.
+ * When the downcounter reaches the value 0x40, and EWI interrupt is
+ * generated and the corresponding Interrupt Service Routine (ISR) can
+ * be used to trigger specific actions (such as communications or data
+ * logging), before resetting the device.
+ * @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains
+ * the configuration information for the specified WWDG module.
+ * @retval None
+ */
+void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg)
+{
+ /* Check if Early Wakeup Interrupt is enable */
+ if (__HAL_WWDG_GET_IT_SOURCE(hwwdg, WWDG_IT_EWI) != RESET)
+ {
+ /* Check if WWDG Early Wakeup Interrupt occurred */
+ if (__HAL_WWDG_GET_FLAG(hwwdg, WWDG_FLAG_EWIF) != RESET)
+ {
+ /* Clear the WWDG Early Wakeup flag */
+ __HAL_WWDG_CLEAR_FLAG(hwwdg, WWDG_FLAG_EWIF);
+
+ /* Early Wakeup callback */
+ HAL_WWDG_EarlyWakeupCallback(hwwdg);
+ }
+ }
+}
+
+/**
+ * @brief WWDG Early Wakeup callback.
+ * @param hwwdg : pointer to a WWDG_HandleTypeDef structure that contains
+ * the configuration information for the specified WWDG module.
+ * @retval None
+ */
+__weak void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hwwdg);
+
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_WWDG_EarlyWakeupCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_WWDG_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_adc.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_adc.c
new file mode 100644
index 0000000..e382d99
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_adc.c
@@ -0,0 +1,901 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_adc.c
+ * @author MCD Application Team
+ * @brief ADC LL module driver
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+#if defined(USE_FULL_LL_DRIVER)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_adc.h"
+#include "stm32f1xx_ll_bus.h"
+
+#ifdef USE_FULL_ASSERT
+ #include "stm32_assert.h"
+#else
+ #define assert_param(expr) ((void)0U)
+#endif
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (ADC1) || defined (ADC2) || defined (ADC3)
+
+/** @addtogroup ADC_LL ADC
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+
+/** @addtogroup ADC_LL_Private_Macros
+ * @{
+ */
+
+/* Check of parameters for configuration of ADC hierarchical scope: */
+/* common to several ADC instances. */
+/* Check of parameters for configuration of ADC hierarchical scope: */
+/* ADC instance. */
+#define IS_LL_ADC_DATA_ALIGN(__DATA_ALIGN__) \
+ ( ((__DATA_ALIGN__) == LL_ADC_DATA_ALIGN_RIGHT) \
+ || ((__DATA_ALIGN__) == LL_ADC_DATA_ALIGN_LEFT) \
+ )
+
+#define IS_LL_ADC_SCAN_SELECTION(__SCAN_SELECTION__) \
+ ( ((__SCAN_SELECTION__) == LL_ADC_SEQ_SCAN_DISABLE) \
+ || ((__SCAN_SELECTION__) == LL_ADC_SEQ_SCAN_ENABLE) \
+ )
+
+#define IS_LL_ADC_SEQ_SCAN_MODE(__SEQ_SCAN_MODE__) \
+ ( ((__SCAN_MODE__) == LL_ADC_SEQ_SCAN_DISABLE) \
+ || ((__SCAN_MODE__) == LL_ADC_SEQ_SCAN_ENABLE) \
+ )
+
+/* Check of parameters for configuration of ADC hierarchical scope: */
+/* ADC group regular */
+#if defined(ADC3)
+#define IS_LL_ADC_REG_TRIG_SOURCE(__ADC_INSTANCE__, __REG_TRIG_SOURCE__) \
+ ((((__ADC_INSTANCE__) == ADC1) || ((__ADC_INSTANCE__) == ADC2)) \
+ ? ( ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_SOFTWARE) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH3) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH1) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH2) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_CH2) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM3_TRGO) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM4_CH4) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_EXTI_LINE11) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM8_TRGO) \
+ ) \
+ : \
+ ( ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_SOFTWARE) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH3) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM3_CH1) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_CH3) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM8_CH1) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM8_TRGO_ADC3) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM5_CH1) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM5_CH3) \
+ ) \
+ )
+#else
+#if defined (STM32F101xE) || defined (STM32F105xC) || defined (STM32F107xC)
+#define IS_LL_ADC_REG_TRIG_SOURCE(__REG_TRIG_SOURCE__) \
+ ( ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_SOFTWARE) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH3) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH1) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH2) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_CH2) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM3_TRGO) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM4_CH4) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_EXTI_LINE11) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM8_TRGO) \
+ )
+#else
+#define IS_LL_ADC_REG_TRIG_SOURCE(__REG_TRIG_SOURCE__) \
+ ( ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_SOFTWARE) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH3) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH1) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH2) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_CH2) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM3_TRGO) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM4_CH4) \
+ || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_EXTI_LINE11) \
+ )
+#endif
+#endif
+#define IS_LL_ADC_REG_CONTINUOUS_MODE(__REG_CONTINUOUS_MODE__) \
+ ( ((__REG_CONTINUOUS_MODE__) == LL_ADC_REG_CONV_SINGLE) \
+ || ((__REG_CONTINUOUS_MODE__) == LL_ADC_REG_CONV_CONTINUOUS) \
+ )
+
+#define IS_LL_ADC_REG_DMA_TRANSFER(__REG_DMA_TRANSFER__) \
+ ( ((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_NONE) \
+ || ((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_UNLIMITED) \
+ )
+
+#define IS_LL_ADC_REG_SEQ_SCAN_LENGTH(__REG_SEQ_SCAN_LENGTH__) \
+ ( ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_DISABLE) \
+ || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_2RANKS) \
+ || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_3RANKS) \
+ || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_4RANKS) \
+ || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_5RANKS) \
+ || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_6RANKS) \
+ || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_7RANKS) \
+ || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_8RANKS) \
+ || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_9RANKS) \
+ || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_10RANKS) \
+ || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_11RANKS) \
+ || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_12RANKS) \
+ || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_13RANKS) \
+ || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_14RANKS) \
+ || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_15RANKS) \
+ || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_16RANKS) \
+ )
+
+#define IS_LL_ADC_REG_SEQ_SCAN_DISCONT_MODE(__REG_SEQ_DISCONT_MODE__) \
+ ( ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_DISABLE) \
+ || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_1RANK) \
+ || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_2RANKS) \
+ || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_3RANKS) \
+ || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_4RANKS) \
+ || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_5RANKS) \
+ || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_6RANKS) \
+ || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_7RANKS) \
+ || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_8RANKS) \
+ )
+
+/* Check of parameters for configuration of ADC hierarchical scope: */
+/* ADC group injected */
+#if defined(ADC3)
+#define IS_LL_ADC_INJ_TRIG_SOURCE(__ADC_INSTANCE__, __INJ_TRIG_SOURCE__) \
+ ((((__ADC_INSTANCE__) == ADC1) || ((__ADC_INSTANCE__) == ADC2)) \
+ ? ( ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_SOFTWARE) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_TRGO) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_CH4) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_TRGO) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_CH1) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM3_CH4) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM4_TRGO) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_EXTI_LINE15) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM8_CH4) \
+ ) \
+ : \
+ ( ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_SOFTWARE) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_TRGO) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_CH4) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM4_CH3) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM8_CH2) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM8_CH4_ADC3) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM5_TRGO) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM5_CH4) \
+ ) \
+ )
+#else
+#if defined (STM32F101xE) || defined (STM32F105xC) || defined (STM32F107xC)
+#define IS_LL_ADC_INJ_TRIG_SOURCE(__INJ_TRIG_SOURCE__) \
+ ( ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_SOFTWARE) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_TRGO) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_CH4) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_TRGO) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_CH1) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM3_CH4) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM4_TRGO) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_EXTI_LINE15) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM8_CH4) \
+ )
+#else
+#define IS_LL_ADC_INJ_TRIG_SOURCE(__INJ_TRIG_SOURCE__) \
+ ( ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_SOFTWARE) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_TRGO) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_CH4) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_TRGO) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_CH1) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM3_CH4) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM4_TRGO) \
+ || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_EXTI_LINE15) \
+ )
+#endif
+#endif
+#define IS_LL_ADC_INJ_TRIG_AUTO(__INJ_TRIG_AUTO__) \
+ ( ((__INJ_TRIG_AUTO__) == LL_ADC_INJ_TRIG_INDEPENDENT) \
+ || ((__INJ_TRIG_AUTO__) == LL_ADC_INJ_TRIG_FROM_GRP_REGULAR) \
+ )
+
+#define IS_LL_ADC_INJ_SEQ_SCAN_LENGTH(__INJ_SEQ_SCAN_LENGTH__) \
+ ( ((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_DISABLE) \
+ || ((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_ENABLE_2RANKS) \
+ || ((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_ENABLE_3RANKS) \
+ || ((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_ENABLE_4RANKS) \
+ )
+
+#define IS_LL_ADC_INJ_SEQ_SCAN_DISCONT_MODE(__INJ_SEQ_DISCONT_MODE__) \
+ ( ((__INJ_SEQ_DISCONT_MODE__) == LL_ADC_INJ_SEQ_DISCONT_DISABLE) \
+ || ((__INJ_SEQ_DISCONT_MODE__) == LL_ADC_INJ_SEQ_DISCONT_1RANK) \
+ )
+
+#if defined(ADC_MULTIMODE_SUPPORT)
+/* Check of parameters for configuration of ADC hierarchical scope: */
+/* multimode. */
+#define IS_LL_ADC_MULTI_MODE(__MULTI_MODE__) \
+ ( ((__MULTI_MODE__) == LL_ADC_MULTI_INDEPENDENT) \
+ || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_SIMULT) \
+ || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_INTERL_FAST) \
+ || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_INTERL_SLOW) \
+ || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_INJ_SIMULT) \
+ || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_INJ_ALTERN) \
+ || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_SIM_INJ_SIM) \
+ || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_SIM_INJ_ALT) \
+ || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_INTFAST_INJ_SIM) \
+ || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_INTSLOW_INJ_SIM) \
+ )
+
+#define IS_LL_ADC_MULTI_MASTER_SLAVE(__MULTI_MASTER_SLAVE__) \
+ ( ((__MULTI_MASTER_SLAVE__) == LL_ADC_MULTI_MASTER) \
+ || ((__MULTI_MASTER_SLAVE__) == LL_ADC_MULTI_SLAVE) \
+ || ((__MULTI_MASTER_SLAVE__) == LL_ADC_MULTI_MASTER_SLAVE) \
+ )
+
+#endif /* ADC_MULTIMODE_SUPPORT */
+/**
+ * @}
+ */
+
+
+/* Private function prototypes -----------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup ADC_LL_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup ADC_LL_EF_Init
+ * @{
+ */
+
+/**
+ * @brief De-initialize registers of all ADC instances belonging to
+ * the same ADC common instance to their default reset values.
+ * @param ADCxy_COMMON ADC common instance
+ * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() )
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: ADC common registers are de-initialized
+ * - ERROR: not applicable
+ */
+ErrorStatus LL_ADC_CommonDeInit(ADC_Common_TypeDef *ADCxy_COMMON)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_COMMON_INSTANCE(ADCxy_COMMON));
+
+ /* Force reset of ADC clock (core clock) */
+ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_ADC1);
+
+ /* Release reset of ADC clock (core clock) */
+ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_ADC1);
+
+ return SUCCESS;
+}
+
+/**
+ * @brief Initialize some features of ADC common parameters
+ * (all ADC instances belonging to the same ADC common instance)
+ * and multimode (for devices with several ADC instances available).
+ * @note The setting of ADC common parameters is conditioned to
+ * ADC instances state:
+ * All ADC instances belonging to the same ADC common instance
+ * must be disabled.
+ * @param ADCxy_COMMON ADC common instance
+ * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() )
+ * @param ADC_CommonInitStruct Pointer to a @ref LL_ADC_CommonInitTypeDef structure
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: ADC common registers are initialized
+ * - ERROR: ADC common registers are not initialized
+ */
+ErrorStatus LL_ADC_CommonInit(ADC_Common_TypeDef *ADCxy_COMMON, LL_ADC_CommonInitTypeDef *ADC_CommonInitStruct)
+{
+ ErrorStatus status = SUCCESS;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_COMMON_INSTANCE(ADCxy_COMMON));
+#if defined(ADC_MULTIMODE_SUPPORT)
+ assert_param(IS_LL_ADC_MULTI_MODE(ADC_CommonInitStruct->Multimode));
+#endif /* ADC_MULTIMODE_SUPPORT */
+
+ /* Note: Hardware constraint (refer to description of functions */
+ /* "LL_ADC_SetCommonXXX()" and "LL_ADC_SetMultiXXX()"): */
+ /* On this STM32 serie, setting of these features is conditioned to */
+ /* ADC state: */
+ /* All ADC instances of the ADC common group must be disabled. */
+ if(__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(ADCxy_COMMON) == 0U)
+ {
+ /* Configuration of ADC hierarchical scope: */
+ /* - common to several ADC */
+ /* (all ADC instances belonging to the same ADC common instance) */
+ /* - multimode (if several ADC instances available on the */
+ /* selected device) */
+ /* - Set ADC multimode configuration */
+ /* - Set ADC multimode DMA transfer */
+ /* - Set ADC multimode: delay between 2 sampling phases */
+#if defined(ADC_MULTIMODE_SUPPORT)
+ if(ADC_CommonInitStruct->Multimode != LL_ADC_MULTI_INDEPENDENT)
+ {
+ MODIFY_REG(ADCxy_COMMON->CR1,
+ ADC_CR1_DUALMOD,
+ ADC_CommonInitStruct->Multimode
+ );
+ }
+ else
+ {
+ MODIFY_REG(ADCxy_COMMON->CR1,
+ ADC_CR1_DUALMOD,
+ LL_ADC_MULTI_INDEPENDENT
+ );
+ }
+#endif
+ }
+ else
+ {
+ /* Initialization error: One or several ADC instances belonging to */
+ /* the same ADC common instance are not disabled. */
+ status = ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Set each @ref LL_ADC_CommonInitTypeDef field to default value.
+ * @param ADC_CommonInitStruct Pointer to a @ref LL_ADC_CommonInitTypeDef structure
+ * whose fields will be set to default values.
+ * @retval None
+ */
+void LL_ADC_CommonStructInit(LL_ADC_CommonInitTypeDef *ADC_CommonInitStruct)
+{
+ /* Set ADC_CommonInitStruct fields to default values */
+ /* Set fields of ADC common */
+ /* (all ADC instances belonging to the same ADC common instance) */
+
+#if defined(ADC_MULTIMODE_SUPPORT)
+ /* Set fields of ADC multimode */
+ ADC_CommonInitStruct->Multimode = LL_ADC_MULTI_INDEPENDENT;
+#endif /* ADC_MULTIMODE_SUPPORT */
+}
+
+/**
+ * @brief De-initialize registers of the selected ADC instance
+ * to their default reset values.
+ * @note To reset all ADC instances quickly (perform a hard reset),
+ * use function @ref LL_ADC_CommonDeInit().
+ * @param ADCx ADC instance
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: ADC registers are de-initialized
+ * - ERROR: ADC registers are not de-initialized
+ */
+ErrorStatus LL_ADC_DeInit(ADC_TypeDef *ADCx)
+{
+ ErrorStatus status = SUCCESS;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(ADCx));
+
+ /* Disable ADC instance if not already disabled. */
+ if(LL_ADC_IsEnabled(ADCx) == 1U)
+ {
+ /* Set ADC group regular trigger source to SW start to ensure to not */
+ /* have an external trigger event occurring during the conversion stop */
+ /* ADC disable process. */
+ LL_ADC_REG_SetTriggerSource(ADCx, LL_ADC_REG_TRIG_SOFTWARE);
+
+ /* Set ADC group injected trigger source to SW start to ensure to not */
+ /* have an external trigger event occurring during the conversion stop */
+ /* ADC disable process. */
+ LL_ADC_INJ_SetTriggerSource(ADCx, LL_ADC_INJ_TRIG_SOFTWARE);
+
+ /* Disable the ADC instance */
+ LL_ADC_Disable(ADCx);
+ }
+
+ /* Check whether ADC state is compliant with expected state */
+ /* (hardware requirements of bits state to reset registers below) */
+ if(READ_BIT(ADCx->CR2, ADC_CR2_ADON) == 0U)
+ {
+ /* ========== Reset ADC registers ========== */
+ /* Reset register SR */
+ CLEAR_BIT(ADCx->SR,
+ ( LL_ADC_FLAG_STRT
+ | LL_ADC_FLAG_JSTRT
+ | LL_ADC_FLAG_EOS
+ | LL_ADC_FLAG_JEOS
+ | LL_ADC_FLAG_AWD1 )
+ );
+
+ /* Reset register CR1 */
+ #if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG)
+
+ CLEAR_BIT(ADCx->CR1,
+ ( ADC_CR1_AWDEN | ADC_CR1_JAWDEN | ADC_CR1_DUALMOD
+ | ADC_CR1_DISCNUM | ADC_CR1_JDISCEN | ADC_CR1_DISCEN
+ | ADC_CR1_JAUTO | ADC_CR1_AWDSGL | ADC_CR1_SCAN
+ | ADC_CR1_JEOCIE | ADC_CR1_AWDIE | ADC_CR1_EOCIE
+ | ADC_CR1_AWDCH )
+ );
+ #else
+
+ CLEAR_BIT(ADCx->CR1,
+ ( ADC_CR1_AWDEN | ADC_CR1_JAWDEN | ADC_CR1_DISCNUM
+ | ADC_CR1_JDISCEN | ADC_CR1_DISCEN | ADC_CR1_JAUTO
+ | ADC_CR1_AWDSGL | ADC_CR1_SCAN | ADC_CR1_JEOCIE
+ | ADC_CR1_AWDIE | ADC_CR1_EOCIE | ADC_CR1_AWDCH )
+ );
+ #endif
+
+ /* Reset register CR2 */
+ CLEAR_BIT(ADCx->CR2,
+ ( ADC_CR2_TSVREFE
+ | ADC_CR2_SWSTART | ADC_CR2_EXTTRIG | ADC_CR2_EXTSEL
+ | ADC_CR2_JSWSTART | ADC_CR2_JEXTTRIG | ADC_CR2_JEXTSEL
+ | ADC_CR2_ALIGN | ADC_CR2_DMA
+ | ADC_CR2_RSTCAL | ADC_CR2_CAL
+ | ADC_CR2_CONT | ADC_CR2_ADON )
+ );
+
+ /* Reset register SMPR1 */
+ CLEAR_BIT(ADCx->SMPR1,
+ ( ADC_SMPR1_SMP17 | ADC_SMPR1_SMP16
+ | ADC_SMPR1_SMP15 | ADC_SMPR1_SMP14 | ADC_SMPR1_SMP13
+ | ADC_SMPR1_SMP12 | ADC_SMPR1_SMP11 | ADC_SMPR1_SMP10)
+ );
+
+ /* Reset register SMPR2 */
+ CLEAR_BIT(ADCx->SMPR2,
+ ( ADC_SMPR2_SMP9
+ | ADC_SMPR2_SMP8 | ADC_SMPR2_SMP7 | ADC_SMPR2_SMP6
+ | ADC_SMPR2_SMP5 | ADC_SMPR2_SMP4 | ADC_SMPR2_SMP3
+ | ADC_SMPR2_SMP2 | ADC_SMPR2_SMP1 | ADC_SMPR2_SMP0)
+ );
+
+ /* Reset register JOFR1 */
+ CLEAR_BIT(ADCx->JOFR1, ADC_JOFR1_JOFFSET1);
+ /* Reset register JOFR2 */
+ CLEAR_BIT(ADCx->JOFR2, ADC_JOFR2_JOFFSET2);
+ /* Reset register JOFR3 */
+ CLEAR_BIT(ADCx->JOFR3, ADC_JOFR3_JOFFSET3);
+ /* Reset register JOFR4 */
+ CLEAR_BIT(ADCx->JOFR4, ADC_JOFR4_JOFFSET4);
+
+ /* Reset register HTR */
+ SET_BIT(ADCx->HTR, ADC_HTR_HT);
+ /* Reset register LTR */
+ CLEAR_BIT(ADCx->LTR, ADC_LTR_LT);
+
+ /* Reset register SQR1 */
+ CLEAR_BIT(ADCx->SQR1,
+ ( ADC_SQR1_L
+ | ADC_SQR1_SQ16
+ | ADC_SQR1_SQ15 | ADC_SQR1_SQ14 | ADC_SQR1_SQ13)
+ );
+
+ /* Reset register SQR2 */
+ CLEAR_BIT(ADCx->SQR2,
+ ( ADC_SQR2_SQ12 | ADC_SQR2_SQ11 | ADC_SQR2_SQ10
+ | ADC_SQR2_SQ9 | ADC_SQR2_SQ8 | ADC_SQR2_SQ7)
+ );
+
+
+ /* Reset register JSQR */
+ CLEAR_BIT(ADCx->JSQR,
+ ( ADC_JSQR_JL
+ | ADC_JSQR_JSQ4 | ADC_JSQR_JSQ3
+ | ADC_JSQR_JSQ2 | ADC_JSQR_JSQ1 )
+ );
+
+ /* Reset register DR */
+ /* bits in access mode read only, no direct reset applicable */
+
+ /* Reset registers JDR1, JDR2, JDR3, JDR4 */
+ /* bits in access mode read only, no direct reset applicable */
+
+ }
+
+ return status;
+}
+
+/**
+ * @brief Initialize some features of ADC instance.
+ * @note These parameters have an impact on ADC scope: ADC instance.
+ * Affects both group regular and group injected (availability
+ * of ADC group injected depends on STM32 families).
+ * Refer to corresponding unitary functions into
+ * @ref ADC_LL_EF_Configuration_ADC_Instance .
+ * @note The setting of these parameters by function @ref LL_ADC_Init()
+ * is conditioned to ADC state:
+ * ADC instance must be disabled.
+ * This condition is applied to all ADC features, for efficiency
+ * and compatibility over all STM32 families. However, the different
+ * features can be set under different ADC state conditions
+ * (setting possible with ADC enabled without conversion on going,
+ * ADC enabled with conversion on going, ...)
+ * Each feature can be updated afterwards with a unitary function
+ * and potentially with ADC in a different state than disabled,
+ * refer to description of each function for setting
+ * conditioned to ADC state.
+ * @note After using this function, some other features must be configured
+ * using LL unitary functions.
+ * The minimum configuration remaining to be done is:
+ * - Set ADC group regular or group injected sequencer:
+ * map channel on the selected sequencer rank.
+ * Refer to function @ref LL_ADC_REG_SetSequencerRanks().
+ * - Set ADC channel sampling time
+ * Refer to function LL_ADC_SetChannelSamplingTime();
+ * @param ADCx ADC instance
+ * @param ADC_InitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: ADC registers are initialized
+ * - ERROR: ADC registers are not initialized
+ */
+ErrorStatus LL_ADC_Init(ADC_TypeDef *ADCx, LL_ADC_InitTypeDef *ADC_InitStruct)
+{
+ ErrorStatus status = SUCCESS;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(ADCx));
+
+ assert_param(IS_LL_ADC_DATA_ALIGN(ADC_InitStruct->DataAlignment));
+ assert_param(IS_LL_ADC_SCAN_SELECTION(ADC_InitStruct->SequencersScanMode));
+
+ /* Note: Hardware constraint (refer to description of this function): */
+ /* ADC instance must be disabled. */
+ if(LL_ADC_IsEnabled(ADCx) == 0U)
+ {
+ /* Configuration of ADC hierarchical scope: */
+ /* - ADC instance */
+ /* - Set ADC conversion data alignment */
+ MODIFY_REG(ADCx->CR1,
+ ADC_CR1_SCAN
+ ,
+ ADC_InitStruct->SequencersScanMode
+ );
+
+ MODIFY_REG(ADCx->CR2,
+ ADC_CR2_ALIGN
+ ,
+ ADC_InitStruct->DataAlignment
+ );
+
+ }
+ else
+ {
+ /* Initialization error: ADC instance is not disabled. */
+ status = ERROR;
+ }
+ return status;
+}
+
+/**
+ * @brief Set each @ref LL_ADC_InitTypeDef field to default value.
+ * @param ADC_InitStruct Pointer to a @ref LL_ADC_InitTypeDef structure
+ * whose fields will be set to default values.
+ * @retval None
+ */
+void LL_ADC_StructInit(LL_ADC_InitTypeDef *ADC_InitStruct)
+{
+ /* Set ADC_InitStruct fields to default values */
+ /* Set fields of ADC instance */
+ ADC_InitStruct->DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;
+
+ /* Enable scan mode to have a generic behavior with ADC of other */
+ /* STM32 families, without this setting available: */
+ /* ADC group regular sequencer and ADC group injected sequencer depend */
+ /* only of their own configuration. */
+ ADC_InitStruct->SequencersScanMode = LL_ADC_SEQ_SCAN_ENABLE;
+
+}
+
+/**
+ * @brief Initialize some features of ADC group regular.
+ * @note These parameters have an impact on ADC scope: ADC group regular.
+ * Refer to corresponding unitary functions into
+ * @ref ADC_LL_EF_Configuration_ADC_Group_Regular
+ * (functions with prefix "REG").
+ * @note The setting of these parameters by function @ref LL_ADC_Init()
+ * is conditioned to ADC state:
+ * ADC instance must be disabled.
+ * This condition is applied to all ADC features, for efficiency
+ * and compatibility over all STM32 families. However, the different
+ * features can be set under different ADC state conditions
+ * (setting possible with ADC enabled without conversion on going,
+ * ADC enabled with conversion on going, ...)
+ * Each feature can be updated afterwards with a unitary function
+ * and potentially with ADC in a different state than disabled,
+ * refer to description of each function for setting
+ * conditioned to ADC state.
+ * @note After using this function, other features must be configured
+ * using LL unitary functions.
+ * The minimum configuration remaining to be done is:
+ * - Set ADC group regular or group injected sequencer:
+ * map channel on the selected sequencer rank.
+ * Refer to function @ref LL_ADC_REG_SetSequencerRanks().
+ * - Set ADC channel sampling time
+ * Refer to function LL_ADC_SetChannelSamplingTime();
+ * @param ADCx ADC instance
+ * @param ADC_REG_InitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: ADC registers are initialized
+ * - ERROR: ADC registers are not initialized
+ */
+ErrorStatus LL_ADC_REG_Init(ADC_TypeDef *ADCx, LL_ADC_REG_InitTypeDef *ADC_REG_InitStruct)
+{
+ ErrorStatus status = SUCCESS;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(ADCx));
+#if defined(ADC3)
+ assert_param(IS_LL_ADC_REG_TRIG_SOURCE(ADCx, ADC_REG_InitStruct->TriggerSource));
+#else
+ assert_param(IS_LL_ADC_REG_TRIG_SOURCE(ADC_REG_InitStruct->TriggerSource));
+#endif
+ assert_param(IS_LL_ADC_REG_SEQ_SCAN_LENGTH(ADC_REG_InitStruct->SequencerLength));
+ if(ADC_REG_InitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE)
+ {
+ assert_param(IS_LL_ADC_REG_SEQ_SCAN_DISCONT_MODE(ADC_REG_InitStruct->SequencerDiscont));
+ }
+ assert_param(IS_LL_ADC_REG_CONTINUOUS_MODE(ADC_REG_InitStruct->ContinuousMode));
+ assert_param(IS_LL_ADC_REG_DMA_TRANSFER(ADC_REG_InitStruct->DMATransfer));
+
+ /* Note: Hardware constraint (refer to description of this function): */
+ /* ADC instance must be disabled. */
+ if(LL_ADC_IsEnabled(ADCx) == 0U)
+ {
+ /* Configuration of ADC hierarchical scope: */
+ /* - ADC group regular */
+ /* - Set ADC group regular trigger source */
+ /* - Set ADC group regular sequencer length */
+ /* - Set ADC group regular sequencer discontinuous mode */
+ /* - Set ADC group regular continuous mode */
+ /* - Set ADC group regular conversion data transfer: no transfer or */
+ /* transfer by DMA, and DMA requests mode */
+ /* Note: On this STM32 serie, ADC trigger edge is set when starting */
+ /* ADC conversion. */
+ /* Refer to function @ref LL_ADC_REG_StartConversionExtTrig(). */
+ if(ADC_REG_InitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE)
+ {
+ MODIFY_REG(ADCx->CR1,
+ ADC_CR1_DISCEN
+ | ADC_CR1_DISCNUM
+ ,
+ ADC_REG_InitStruct->SequencerLength
+ | ADC_REG_InitStruct->SequencerDiscont
+ );
+ }
+ else
+ {
+ MODIFY_REG(ADCx->CR1,
+ ADC_CR1_DISCEN
+ | ADC_CR1_DISCNUM
+ ,
+ ADC_REG_InitStruct->SequencerLength
+ | LL_ADC_REG_SEQ_DISCONT_DISABLE
+ );
+ }
+
+ MODIFY_REG(ADCx->CR2,
+ ADC_CR2_EXTSEL
+ | ADC_CR2_CONT
+ | ADC_CR2_DMA
+ ,
+ ADC_REG_InitStruct->TriggerSource
+ | ADC_REG_InitStruct->ContinuousMode
+ | ADC_REG_InitStruct->DMATransfer
+ );
+
+ /* Set ADC group regular sequencer length and scan direction */
+ /* Note: Hardware constraint (refer to description of this function): */
+ /* Note: If ADC instance feature scan mode is disabled */
+ /* (refer to ADC instance initialization structure */
+ /* parameter @ref SequencersScanMode */
+ /* or function @ref LL_ADC_SetSequencersScanMode() ), */
+ /* this parameter is discarded. */
+ LL_ADC_REG_SetSequencerLength(ADCx, ADC_REG_InitStruct->SequencerLength);
+ }
+ else
+ {
+ /* Initialization error: ADC instance is not disabled. */
+ status = ERROR;
+ }
+ return status;
+}
+
+/**
+ * @brief Set each @ref LL_ADC_REG_InitTypeDef field to default value.
+ * @param ADC_REG_InitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure
+ * whose fields will be set to default values.
+ * @retval None
+ */
+void LL_ADC_REG_StructInit(LL_ADC_REG_InitTypeDef *ADC_REG_InitStruct)
+{
+ /* Set ADC_REG_InitStruct fields to default values */
+ /* Set fields of ADC group regular */
+ /* Note: On this STM32 serie, ADC trigger edge is set when starting */
+ /* ADC conversion. */
+ /* Refer to function @ref LL_ADC_REG_StartConversionExtTrig(). */
+ ADC_REG_InitStruct->TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;
+ ADC_REG_InitStruct->SequencerLength = LL_ADC_REG_SEQ_SCAN_DISABLE;
+ ADC_REG_InitStruct->SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
+ ADC_REG_InitStruct->ContinuousMode = LL_ADC_REG_CONV_SINGLE;
+ ADC_REG_InitStruct->DMATransfer = LL_ADC_REG_DMA_TRANSFER_NONE;
+}
+
+/**
+ * @brief Initialize some features of ADC group injected.
+ * @note These parameters have an impact on ADC scope: ADC group injected.
+ * Refer to corresponding unitary functions into
+ * @ref ADC_LL_EF_Configuration_ADC_Group_Regular
+ * (functions with prefix "INJ").
+ * @note The setting of these parameters by function @ref LL_ADC_Init()
+ * is conditioned to ADC state:
+ * ADC instance must be disabled.
+ * This condition is applied to all ADC features, for efficiency
+ * and compatibility over all STM32 families. However, the different
+ * features can be set under different ADC state conditions
+ * (setting possible with ADC enabled without conversion on going,
+ * ADC enabled with conversion on going, ...)
+ * Each feature can be updated afterwards with a unitary function
+ * and potentially with ADC in a different state than disabled,
+ * refer to description of each function for setting
+ * conditioned to ADC state.
+ * @note After using this function, other features must be configured
+ * using LL unitary functions.
+ * The minimum configuration remaining to be done is:
+ * - Set ADC group injected sequencer:
+ * map channel on the selected sequencer rank.
+ * Refer to function @ref LL_ADC_INJ_SetSequencerRanks().
+ * - Set ADC channel sampling time
+ * Refer to function LL_ADC_SetChannelSamplingTime();
+ * @param ADCx ADC instance
+ * @param ADC_INJ_InitStruct Pointer to a @ref LL_ADC_INJ_InitTypeDef structure
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: ADC registers are initialized
+ * - ERROR: ADC registers are not initialized
+ */
+ErrorStatus LL_ADC_INJ_Init(ADC_TypeDef *ADCx, LL_ADC_INJ_InitTypeDef *ADC_INJ_InitStruct)
+{
+ ErrorStatus status = SUCCESS;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(ADCx));
+#if defined(ADC3)
+ assert_param(IS_LL_ADC_INJ_TRIG_SOURCE(ADCx, ADC_INJ_InitStruct->TriggerSource));
+#else
+ assert_param(IS_LL_ADC_INJ_TRIG_SOURCE(ADC_INJ_InitStruct->TriggerSource));
+#endif
+ assert_param(IS_LL_ADC_INJ_SEQ_SCAN_LENGTH(ADC_INJ_InitStruct->SequencerLength));
+ if(ADC_INJ_InitStruct->SequencerLength != LL_ADC_INJ_SEQ_SCAN_DISABLE)
+ {
+ assert_param(IS_LL_ADC_INJ_SEQ_SCAN_DISCONT_MODE(ADC_INJ_InitStruct->SequencerDiscont));
+ }
+ assert_param(IS_LL_ADC_INJ_TRIG_AUTO(ADC_INJ_InitStruct->TrigAuto));
+
+ /* Note: Hardware constraint (refer to description of this function): */
+ /* ADC instance must be disabled. */
+ if(LL_ADC_IsEnabled(ADCx) == 0U)
+ {
+ /* Configuration of ADC hierarchical scope: */
+ /* - ADC group injected */
+ /* - Set ADC group injected trigger source */
+ /* - Set ADC group injected sequencer length */
+ /* - Set ADC group injected sequencer discontinuous mode */
+ /* - Set ADC group injected conversion trigger: independent or */
+ /* from ADC group regular */
+ /* Note: On this STM32 serie, ADC trigger edge is set when starting */
+ /* ADC conversion. */
+ /* Refer to function @ref LL_ADC_INJ_StartConversionExtTrig(). */
+ if(ADC_INJ_InitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE)
+ {
+ MODIFY_REG(ADCx->CR1,
+ ADC_CR1_JDISCEN
+ | ADC_CR1_JAUTO
+ ,
+ ADC_INJ_InitStruct->SequencerDiscont
+ | ADC_INJ_InitStruct->TrigAuto
+ );
+ }
+ else
+ {
+ MODIFY_REG(ADCx->CR1,
+ ADC_CR1_JDISCEN
+ | ADC_CR1_JAUTO
+ ,
+ LL_ADC_REG_SEQ_DISCONT_DISABLE
+ | ADC_INJ_InitStruct->TrigAuto
+ );
+ }
+
+ MODIFY_REG(ADCx->CR2,
+ ADC_CR2_JEXTSEL
+ ,
+ ADC_INJ_InitStruct->TriggerSource
+ );
+
+ /* Note: Hardware constraint (refer to description of this function): */
+ /* Note: If ADC instance feature scan mode is disabled */
+ /* (refer to ADC instance initialization structure */
+ /* parameter @ref SequencersScanMode */
+ /* or function @ref LL_ADC_SetSequencersScanMode() ), */
+ /* this parameter is discarded. */
+ LL_ADC_INJ_SetSequencerLength(ADCx, ADC_INJ_InitStruct->SequencerLength);
+ }
+ else
+ {
+ /* Initialization error: ADC instance is not disabled. */
+ status = ERROR;
+ }
+ return status;
+}
+
+/**
+ * @brief Set each @ref LL_ADC_INJ_InitTypeDef field to default value.
+ * @param ADC_INJ_InitStruct Pointer to a @ref LL_ADC_INJ_InitTypeDef structure
+ * whose fields will be set to default values.
+ * @retval None
+ */
+void LL_ADC_INJ_StructInit(LL_ADC_INJ_InitTypeDef *ADC_INJ_InitStruct)
+{
+ /* Set ADC_INJ_InitStruct fields to default values */
+ /* Set fields of ADC group injected */
+ ADC_INJ_InitStruct->TriggerSource = LL_ADC_INJ_TRIG_SOFTWARE;
+ ADC_INJ_InitStruct->SequencerLength = LL_ADC_INJ_SEQ_SCAN_DISABLE;
+ ADC_INJ_InitStruct->SequencerDiscont = LL_ADC_INJ_SEQ_DISCONT_DISABLE;
+ ADC_INJ_InitStruct->TrigAuto = LL_ADC_INJ_TRIG_INDEPENDENT;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* ADC1 || ADC2 || ADC3 */
+
+/**
+ * @}
+ */
+
+#endif /* USE_FULL_LL_DRIVER */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_crc.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_crc.c
new file mode 100644
index 0000000..11eb7d9
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_crc.c
@@ -0,0 +1,124 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_crc.c
+ * @author MCD Application Team
+ * @brief CRC LL module driver.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+#if defined(USE_FULL_LL_DRIVER)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_crc.h"
+#include "stm32f1xx_ll_bus.h"
+
+#ifdef USE_FULL_ASSERT
+#include "stm32_assert.h"
+#else
+#define assert_param(expr) ((void)0U)
+#endif
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (CRC)
+
+/** @addtogroup CRC_LL
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup CRC_LL_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup CRC_LL_EF_Init
+ * @{
+ */
+
+/**
+ * @brief De-initialize CRC registers (Registers restored to their default values).
+ * @param CRCx CRC Instance
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: CRC registers are de-initialized
+ * - ERROR: CRC registers are not de-initialized
+ */
+ErrorStatus LL_CRC_DeInit(CRC_TypeDef *CRCx)
+{
+ ErrorStatus status = SUCCESS;
+
+ /* Check the parameters */
+ assert_param(IS_CRC_ALL_INSTANCE(CRCx));
+
+ if (CRCx == CRC)
+ {
+
+ /* Reset the CRC calculation unit */
+ LL_CRC_ResetCRCCalculationUnit(CRCx);
+
+ /* Reset IDR register */
+ LL_CRC_Write_IDR(CRCx, 0x00U);
+ }
+ else
+ {
+ status = ERROR;
+ }
+
+ return (status);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* defined (CRC) */
+
+/**
+ * @}
+ */
+
+#endif /* USE_FULL_LL_DRIVER */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_dac.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_dac.c
new file mode 100644
index 0000000..5aa0d05
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_dac.c
@@ -0,0 +1,272 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_dac.c
+ * @author MCD Application Team
+ * @brief DAC LL module driver
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+#if defined(USE_FULL_LL_DRIVER)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_dac.h"
+#include "stm32f1xx_ll_bus.h"
+
+#ifdef USE_FULL_ASSERT
+ #include "stm32_assert.h"
+#else
+ #define assert_param(expr) ((void)0U)
+#endif
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (DAC)
+
+/** @addtogroup DAC_LL DAC
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+
+/** @addtogroup DAC_LL_Private_Macros
+ * @{
+ */
+
+#define IS_LL_DAC_CHANNEL(__DACX__, __DAC_CHANNEL__) \
+ ( \
+ ((__DAC_CHANNEL__) == LL_DAC_CHANNEL_1) \
+ || ((__DAC_CHANNEL__) == LL_DAC_CHANNEL_2) \
+ )
+
+#define IS_LL_DAC_TRIGGER_SOURCE(__TRIGGER_SOURCE__) \
+ ( ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_SOFTWARE) \
+ || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM3_TRGO) \
+ || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM15_TRGO) \
+ || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM2_TRGO) \
+ || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM4_TRGO) \
+ || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM5_TRGO) \
+ || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM6_TRGO) \
+ || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM7_TRGO) \
+ || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM8_TRGO) \
+ || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_EXTI_LINE9) \
+ )
+#define IS_LL_DAC_WAVE_AUTO_GENER_MODE(__WAVE_AUTO_GENERATION_MODE__) \
+ ( ((__WAVE_AUTO_GENERATION_MODE__) == LL_DAC_WAVE_AUTO_GENERATION_NONE) \
+ || ((__WAVE_AUTO_GENERATION_MODE__) == LL_DAC_WAVE_AUTO_GENERATION_NOISE) \
+ || ((__WAVE_AUTO_GENERATION_MODE__) == LL_DAC_WAVE_AUTO_GENERATION_TRIANGLE) \
+ )
+
+#define IS_LL_DAC_WAVE_AUTO_GENER_CONFIG(__WAVE_AUTO_GENERATION_CONFIG__) \
+ ( ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BIT0) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS1_0) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS2_0) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS3_0) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS4_0) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS5_0) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS6_0) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS7_0) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS8_0) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS9_0) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS10_0) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS11_0) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_1) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_3) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_7) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_15) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_31) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_63) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_127) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_255) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_511) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_1023) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_2047) \
+ || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_4095) \
+ )
+
+#define IS_LL_DAC_OUTPUT_BUFFER(__OUTPUT_BUFFER__) \
+ ( ((__OUTPUT_BUFFER__) == LL_DAC_OUTPUT_BUFFER_ENABLE) \
+ || ((__OUTPUT_BUFFER__) == LL_DAC_OUTPUT_BUFFER_DISABLE) \
+ )
+
+/**
+ * @}
+ */
+
+
+/* Private function prototypes -----------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup DAC_LL_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup DAC_LL_EF_Init
+ * @{
+ */
+
+/**
+ * @brief De-initialize registers of the selected DAC instance
+ * to their default reset values.
+ * @param DACx DAC instance
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: DAC registers are de-initialized
+ * - ERROR: not applicable
+ */
+ErrorStatus LL_DAC_DeInit(DAC_TypeDef *DACx)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_ALL_INSTANCE(DACx));
+
+ /* Force reset of DAC1 clock */
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_DAC1);
+
+ /* Release reset of DAC1 clock */
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_DAC1);
+ return SUCCESS;
+}
+
+/**
+ * @brief Initialize some features of DAC instance.
+ * @note The setting of these parameters by function @ref LL_DAC_Init()
+ * is conditioned to DAC state:
+ * DAC instance must be disabled.
+ * @param DACx DAC instance
+ * @param DAC_Channel This parameter can be one of the following values:
+ * @arg @ref LL_DAC_CHANNEL_1
+ * @arg @ref LL_DAC_CHANNEL_2
+ * @param DAC_InitStruct Pointer to a @ref LL_DAC_InitTypeDef structure
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: DAC registers are initialized
+ * - ERROR: DAC registers are not initialized
+ */
+ErrorStatus LL_DAC_Init(DAC_TypeDef *DACx, uint32_t DAC_Channel, LL_DAC_InitTypeDef *DAC_InitStruct)
+{
+ ErrorStatus status = SUCCESS;
+
+ /* Check the parameters */
+ assert_param(IS_DAC_ALL_INSTANCE(DACx));
+ assert_param(IS_LL_DAC_CHANNEL(DACx, DAC_Channel));
+ assert_param(IS_LL_DAC_TRIGGER_SOURCE(DAC_InitStruct->TriggerSource));
+ assert_param(IS_LL_DAC_OUTPUT_BUFFER(DAC_InitStruct->OutputBuffer));
+ assert_param(IS_LL_DAC_WAVE_AUTO_GENER_MODE(DAC_InitStruct->WaveAutoGeneration));
+ if (DAC_InitStruct->WaveAutoGeneration != LL_DAC_WAVE_AUTO_GENERATION_NONE)
+ {
+ assert_param(IS_LL_DAC_WAVE_AUTO_GENER_CONFIG(DAC_InitStruct->WaveAutoGenerationConfig));
+ }
+
+ /* Note: Hardware constraint (refer to description of this function) */
+ /* DAC instance must be disabled. */
+ if(LL_DAC_IsEnabled(DACx, DAC_Channel) == 0U)
+ {
+ /* Configuration of DAC channel: */
+ /* - TriggerSource */
+ /* - WaveAutoGeneration */
+ /* - OutputBuffer */
+ if (DAC_InitStruct->WaveAutoGeneration != LL_DAC_WAVE_AUTO_GENERATION_NONE)
+ {
+ MODIFY_REG(DACx->CR,
+ ( DAC_CR_TSEL1
+ | DAC_CR_WAVE1
+ | DAC_CR_MAMP1
+ | DAC_CR_BOFF1
+ ) << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)
+ ,
+ ( DAC_InitStruct->TriggerSource
+ | DAC_InitStruct->WaveAutoGeneration
+ | DAC_InitStruct->WaveAutoGenerationConfig
+ | DAC_InitStruct->OutputBuffer
+ ) << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)
+ );
+ }
+ else
+ {
+ MODIFY_REG(DACx->CR,
+ ( DAC_CR_TSEL1
+ | DAC_CR_WAVE1
+ | DAC_CR_BOFF1
+ ) << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)
+ ,
+ ( DAC_InitStruct->TriggerSource
+ | LL_DAC_WAVE_AUTO_GENERATION_NONE
+ | DAC_InitStruct->OutputBuffer
+ ) << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)
+ );
+ }
+ }
+ else
+ {
+ /* Initialization error: DAC instance is not disabled. */
+ status = ERROR;
+ }
+ return status;
+}
+
+/**
+ * @brief Set each @ref LL_DAC_InitTypeDef field to default value.
+ * @param DAC_InitStruct pointer to a @ref LL_DAC_InitTypeDef structure
+ * whose fields will be set to default values.
+ * @retval None
+ */
+void LL_DAC_StructInit(LL_DAC_InitTypeDef *DAC_InitStruct)
+{
+ /* Set DAC_InitStruct fields to default values */
+ DAC_InitStruct->TriggerSource = LL_DAC_TRIG_SOFTWARE;
+ DAC_InitStruct->WaveAutoGeneration = LL_DAC_WAVE_AUTO_GENERATION_NONE;
+ /* Note: Parameter discarded if wave auto generation is disabled, */
+ /* set anyway to its default value. */
+ DAC_InitStruct->WaveAutoGenerationConfig = LL_DAC_NOISE_LFSR_UNMASK_BIT0;
+ DAC_InitStruct->OutputBuffer = LL_DAC_OUTPUT_BUFFER_ENABLE;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* DAC */
+
+/**
+ * @}
+ */
+
+#endif /* USE_FULL_LL_DRIVER */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_dma.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_dma.c
new file mode 100644
index 0000000..f07c23c
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_dma.c
@@ -0,0 +1,329 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_dma.c
+ * @author MCD Application Team
+ * @brief DMA LL module driver.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+#if defined(USE_FULL_LL_DRIVER)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_dma.h"
+#include "stm32f1xx_ll_bus.h"
+#ifdef USE_FULL_ASSERT
+#include "stm32_assert.h"
+#else
+#define assert_param(expr) ((void)0U)
+#endif
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (DMA1) || defined (DMA2)
+
+/** @defgroup DMA_LL DMA
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/** @addtogroup DMA_LL_Private_Macros
+ * @{
+ */
+#define IS_LL_DMA_DIRECTION(__VALUE__) (((__VALUE__) == LL_DMA_DIRECTION_PERIPH_TO_MEMORY) || \
+ ((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_PERIPH) || \
+ ((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_MEMORY))
+
+#define IS_LL_DMA_MODE(__VALUE__) (((__VALUE__) == LL_DMA_MODE_NORMAL) || \
+ ((__VALUE__) == LL_DMA_MODE_CIRCULAR))
+
+#define IS_LL_DMA_PERIPHINCMODE(__VALUE__) (((__VALUE__) == LL_DMA_PERIPH_INCREMENT) || \
+ ((__VALUE__) == LL_DMA_PERIPH_NOINCREMENT))
+
+#define IS_LL_DMA_MEMORYINCMODE(__VALUE__) (((__VALUE__) == LL_DMA_MEMORY_INCREMENT) || \
+ ((__VALUE__) == LL_DMA_MEMORY_NOINCREMENT))
+
+#define IS_LL_DMA_PERIPHDATASIZE(__VALUE__) (((__VALUE__) == LL_DMA_PDATAALIGN_BYTE) || \
+ ((__VALUE__) == LL_DMA_PDATAALIGN_HALFWORD) || \
+ ((__VALUE__) == LL_DMA_PDATAALIGN_WORD))
+
+#define IS_LL_DMA_MEMORYDATASIZE(__VALUE__) (((__VALUE__) == LL_DMA_MDATAALIGN_BYTE) || \
+ ((__VALUE__) == LL_DMA_MDATAALIGN_HALFWORD) || \
+ ((__VALUE__) == LL_DMA_MDATAALIGN_WORD))
+
+#define IS_LL_DMA_NBDATA(__VALUE__) ((__VALUE__) <= 0x0000FFFFU)
+
+#define IS_LL_DMA_PRIORITY(__VALUE__) (((__VALUE__) == LL_DMA_PRIORITY_LOW) || \
+ ((__VALUE__) == LL_DMA_PRIORITY_MEDIUM) || \
+ ((__VALUE__) == LL_DMA_PRIORITY_HIGH) || \
+ ((__VALUE__) == LL_DMA_PRIORITY_VERYHIGH))
+
+#if defined (DMA2)
+#define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL) ((((INSTANCE) == DMA1) && \
+ (((CHANNEL) == LL_DMA_CHANNEL_1) || \
+ ((CHANNEL) == LL_DMA_CHANNEL_2) || \
+ ((CHANNEL) == LL_DMA_CHANNEL_3) || \
+ ((CHANNEL) == LL_DMA_CHANNEL_4) || \
+ ((CHANNEL) == LL_DMA_CHANNEL_5) || \
+ ((CHANNEL) == LL_DMA_CHANNEL_6) || \
+ ((CHANNEL) == LL_DMA_CHANNEL_7))) || \
+ (((INSTANCE) == DMA2) && \
+ (((CHANNEL) == LL_DMA_CHANNEL_1) || \
+ ((CHANNEL) == LL_DMA_CHANNEL_2) || \
+ ((CHANNEL) == LL_DMA_CHANNEL_3) || \
+ ((CHANNEL) == LL_DMA_CHANNEL_4) || \
+ ((CHANNEL) == LL_DMA_CHANNEL_5))))
+#else
+#define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL) ((((INSTANCE) == DMA1) && \
+ (((CHANNEL) == LL_DMA_CHANNEL_1) || \
+ ((CHANNEL) == LL_DMA_CHANNEL_2) || \
+ ((CHANNEL) == LL_DMA_CHANNEL_3) || \
+ ((CHANNEL) == LL_DMA_CHANNEL_4) || \
+ ((CHANNEL) == LL_DMA_CHANNEL_5) || \
+ ((CHANNEL) == LL_DMA_CHANNEL_6) || \
+ ((CHANNEL) == LL_DMA_CHANNEL_7))))
+#endif
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup DMA_LL_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup DMA_LL_EF_Init
+ * @{
+ */
+
+/**
+ * @brief De-initialize the DMA registers to their default reset values.
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: DMA registers are de-initialized
+ * - ERROR: DMA registers are not de-initialized
+ */
+uint32_t LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Channel)
+{
+ DMA_Channel_TypeDef *tmp = (DMA_Channel_TypeDef *)DMA1_Channel1;
+ ErrorStatus status = SUCCESS;
+
+ /* Check the DMA Instance DMAx and Channel parameters*/
+ assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel));
+
+ tmp = (DMA_Channel_TypeDef *)(__LL_DMA_GET_CHANNEL_INSTANCE(DMAx, Channel));
+
+ /* Disable the selected DMAx_Channely */
+ CLEAR_BIT(tmp->CCR, DMA_CCR_EN);
+
+ /* Reset DMAx_Channely control register */
+ LL_DMA_WriteReg(tmp, CCR, 0U);
+
+ /* Reset DMAx_Channely remaining bytes register */
+ LL_DMA_WriteReg(tmp, CNDTR, 0U);
+
+ /* Reset DMAx_Channely peripheral address register */
+ LL_DMA_WriteReg(tmp, CPAR, 0U);
+
+ /* Reset DMAx_Channely memory address register */
+ LL_DMA_WriteReg(tmp, CMAR, 0U);
+
+ if (Channel == LL_DMA_CHANNEL_1)
+ {
+ /* Reset interrupt pending bits for DMAx Channel1 */
+ LL_DMA_ClearFlag_GI1(DMAx);
+ }
+ else if (Channel == LL_DMA_CHANNEL_2)
+ {
+ /* Reset interrupt pending bits for DMAx Channel2 */
+ LL_DMA_ClearFlag_GI2(DMAx);
+ }
+ else if (Channel == LL_DMA_CHANNEL_3)
+ {
+ /* Reset interrupt pending bits for DMAx Channel3 */
+ LL_DMA_ClearFlag_GI3(DMAx);
+ }
+ else if (Channel == LL_DMA_CHANNEL_4)
+ {
+ /* Reset interrupt pending bits for DMAx Channel4 */
+ LL_DMA_ClearFlag_GI4(DMAx);
+ }
+ else if (Channel == LL_DMA_CHANNEL_5)
+ {
+ /* Reset interrupt pending bits for DMAx Channel5 */
+ LL_DMA_ClearFlag_GI5(DMAx);
+ }
+
+ else if (Channel == LL_DMA_CHANNEL_6)
+ {
+ /* Reset interrupt pending bits for DMAx Channel6 */
+ LL_DMA_ClearFlag_GI6(DMAx);
+ }
+ else if (Channel == LL_DMA_CHANNEL_7)
+ {
+ /* Reset interrupt pending bits for DMAx Channel7 */
+ LL_DMA_ClearFlag_GI7(DMAx);
+ }
+ else
+ {
+ status = ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Initialize the DMA registers according to the specified parameters in DMA_InitStruct.
+ * @note To convert DMAx_Channely Instance to DMAx Instance and Channely, use helper macros :
+ * @arg @ref __LL_DMA_GET_INSTANCE
+ * @arg @ref __LL_DMA_GET_CHANNEL
+ * @param DMAx DMAx Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_DMA_CHANNEL_1
+ * @arg @ref LL_DMA_CHANNEL_2
+ * @arg @ref LL_DMA_CHANNEL_3
+ * @arg @ref LL_DMA_CHANNEL_4
+ * @arg @ref LL_DMA_CHANNEL_5
+ * @arg @ref LL_DMA_CHANNEL_6
+ * @arg @ref LL_DMA_CHANNEL_7
+ * @param DMA_InitStruct pointer to a @ref LL_DMA_InitTypeDef structure.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: DMA registers are initialized
+ * - ERROR: Not applicable
+ */
+uint32_t LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Channel, LL_DMA_InitTypeDef *DMA_InitStruct)
+{
+ /* Check the DMA Instance DMAx and Channel parameters*/
+ assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel));
+
+ /* Check the DMA parameters from DMA_InitStruct */
+ assert_param(IS_LL_DMA_DIRECTION(DMA_InitStruct->Direction));
+ assert_param(IS_LL_DMA_MODE(DMA_InitStruct->Mode));
+ assert_param(IS_LL_DMA_PERIPHINCMODE(DMA_InitStruct->PeriphOrM2MSrcIncMode));
+ assert_param(IS_LL_DMA_MEMORYINCMODE(DMA_InitStruct->MemoryOrM2MDstIncMode));
+ assert_param(IS_LL_DMA_PERIPHDATASIZE(DMA_InitStruct->PeriphOrM2MSrcDataSize));
+ assert_param(IS_LL_DMA_MEMORYDATASIZE(DMA_InitStruct->MemoryOrM2MDstDataSize));
+ assert_param(IS_LL_DMA_NBDATA(DMA_InitStruct->NbData));
+ assert_param(IS_LL_DMA_PRIORITY(DMA_InitStruct->Priority));
+
+ /*---------------------------- DMAx CCR Configuration ------------------------
+ * Configure DMAx_Channely: data transfer direction, data transfer mode,
+ * peripheral and memory increment mode,
+ * data size alignment and priority level with parameters :
+ * - Direction: DMA_CCR_DIR and DMA_CCR_MEM2MEM bits
+ * - Mode: DMA_CCR_CIRC bit
+ * - PeriphOrM2MSrcIncMode: DMA_CCR_PINC bit
+ * - MemoryOrM2MDstIncMode: DMA_CCR_MINC bit
+ * - PeriphOrM2MSrcDataSize: DMA_CCR_PSIZE[1:0] bits
+ * - MemoryOrM2MDstDataSize: DMA_CCR_MSIZE[1:0] bits
+ * - Priority: DMA_CCR_PL[1:0] bits
+ */
+ LL_DMA_ConfigTransfer(DMAx, Channel, DMA_InitStruct->Direction | \
+ DMA_InitStruct->Mode | \
+ DMA_InitStruct->PeriphOrM2MSrcIncMode | \
+ DMA_InitStruct->MemoryOrM2MDstIncMode | \
+ DMA_InitStruct->PeriphOrM2MSrcDataSize | \
+ DMA_InitStruct->MemoryOrM2MDstDataSize | \
+ DMA_InitStruct->Priority);
+
+ /*-------------------------- DMAx CMAR Configuration -------------------------
+ * Configure the memory or destination base address with parameter :
+ * - MemoryOrM2MDstAddress: DMA_CMAR_MA[31:0] bits
+ */
+ LL_DMA_SetMemoryAddress(DMAx, Channel, DMA_InitStruct->MemoryOrM2MDstAddress);
+
+ /*-------------------------- DMAx CPAR Configuration -------------------------
+ * Configure the peripheral or source base address with parameter :
+ * - PeriphOrM2MSrcAddress: DMA_CPAR_PA[31:0] bits
+ */
+ LL_DMA_SetPeriphAddress(DMAx, Channel, DMA_InitStruct->PeriphOrM2MSrcAddress);
+
+ /*--------------------------- DMAx CNDTR Configuration -----------------------
+ * Configure the peripheral base address with parameter :
+ * - NbData: DMA_CNDTR_NDT[15:0] bits
+ */
+ LL_DMA_SetDataLength(DMAx, Channel, DMA_InitStruct->NbData);
+
+ return SUCCESS;
+}
+
+/**
+ * @brief Set each @ref LL_DMA_InitTypeDef field to default value.
+ * @param DMA_InitStruct Pointer to a @ref LL_DMA_InitTypeDef structure.
+ * @retval None
+ */
+void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct)
+{
+ /* Set DMA_InitStruct fields to default values */
+ DMA_InitStruct->PeriphOrM2MSrcAddress = 0x00000000U;
+ DMA_InitStruct->MemoryOrM2MDstAddress = 0x00000000U;
+ DMA_InitStruct->Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
+ DMA_InitStruct->Mode = LL_DMA_MODE_NORMAL;
+ DMA_InitStruct->PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
+ DMA_InitStruct->MemoryOrM2MDstIncMode = LL_DMA_MEMORY_NOINCREMENT;
+ DMA_InitStruct->PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
+ DMA_InitStruct->MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
+ DMA_InitStruct->NbData = 0x00000000U;
+ DMA_InitStruct->Priority = LL_DMA_PRIORITY_LOW;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* DMA1 || DMA2 */
+
+/**
+ * @}
+ */
+
+#endif /* USE_FULL_LL_DRIVER */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_exti.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_exti.c
new file mode 100644
index 0000000..dacbc3f
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_exti.c
@@ -0,0 +1,230 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_exti.c
+ * @author MCD Application Team
+ * @brief EXTI LL module driver.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+#if defined(USE_FULL_LL_DRIVER)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_exti.h"
+#ifdef USE_FULL_ASSERT
+#include "stm32_assert.h"
+#else
+#define assert_param(expr) ((void)0U)
+#endif
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (EXTI)
+
+/** @defgroup EXTI_LL EXTI
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/** @addtogroup EXTI_LL_Private_Macros
+ * @{
+ */
+
+#define IS_LL_EXTI_LINE_0_31(__VALUE__) (((__VALUE__) & ~LL_EXTI_LINE_ALL_0_31) == 0x00000000U)
+
+#define IS_LL_EXTI_MODE(__VALUE__) (((__VALUE__) == LL_EXTI_MODE_IT) \
+ || ((__VALUE__) == LL_EXTI_MODE_EVENT) \
+ || ((__VALUE__) == LL_EXTI_MODE_IT_EVENT))
+
+
+#define IS_LL_EXTI_TRIGGER(__VALUE__) (((__VALUE__) == LL_EXTI_TRIGGER_NONE) \
+ || ((__VALUE__) == LL_EXTI_TRIGGER_RISING) \
+ || ((__VALUE__) == LL_EXTI_TRIGGER_FALLING) \
+ || ((__VALUE__) == LL_EXTI_TRIGGER_RISING_FALLING))
+
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup EXTI_LL_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup EXTI_LL_EF_Init
+ * @{
+ */
+
+/**
+ * @brief De-initialize the EXTI registers to their default reset values.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: EXTI registers are de-initialized
+ * - ERROR: not applicable
+ */
+uint32_t LL_EXTI_DeInit(void)
+{
+ /* Interrupt mask register set to default reset values */
+ LL_EXTI_WriteReg(IMR, 0x00000000U);
+ /* Event mask register set to default reset values */
+ LL_EXTI_WriteReg(EMR, 0x00000000U);
+ /* Rising Trigger selection register set to default reset values */
+ LL_EXTI_WriteReg(RTSR, 0x00000000U);
+ /* Falling Trigger selection register set to default reset values */
+ LL_EXTI_WriteReg(FTSR, 0x00000000U);
+ /* Software interrupt event register set to default reset values */
+ LL_EXTI_WriteReg(SWIER, 0x00000000U);
+ /* Pending register clear */
+ LL_EXTI_WriteReg(PR, 0x000FFFFFU);
+
+ return SUCCESS;
+}
+
+/**
+ * @brief Initialize the EXTI registers according to the specified parameters in EXTI_InitStruct.
+ * @param EXTI_InitStruct pointer to a @ref LL_EXTI_InitTypeDef structure.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: EXTI registers are initialized
+ * - ERROR: not applicable
+ */
+uint32_t LL_EXTI_Init(LL_EXTI_InitTypeDef *EXTI_InitStruct)
+{
+ ErrorStatus status = SUCCESS;
+ /* Check the parameters */
+ assert_param(IS_LL_EXTI_LINE_0_31(EXTI_InitStruct->Line_0_31));
+ assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->LineCommand));
+ assert_param(IS_LL_EXTI_MODE(EXTI_InitStruct->Mode));
+
+ /* ENABLE LineCommand */
+ if (EXTI_InitStruct->LineCommand != DISABLE)
+ {
+ assert_param(IS_LL_EXTI_TRIGGER(EXTI_InitStruct->Trigger));
+
+ /* Configure EXTI Lines in range from 0 to 31 */
+ if (EXTI_InitStruct->Line_0_31 != LL_EXTI_LINE_NONE)
+ {
+ switch (EXTI_InitStruct->Mode)
+ {
+ case LL_EXTI_MODE_IT:
+ /* First Disable Event on provided Lines */
+ LL_EXTI_DisableEvent_0_31(EXTI_InitStruct->Line_0_31);
+ /* Then Enable IT on provided Lines */
+ LL_EXTI_EnableIT_0_31(EXTI_InitStruct->Line_0_31);
+ break;
+ case LL_EXTI_MODE_EVENT:
+ /* First Disable IT on provided Lines */
+ LL_EXTI_DisableIT_0_31(EXTI_InitStruct->Line_0_31);
+ /* Then Enable Event on provided Lines */
+ LL_EXTI_EnableEvent_0_31(EXTI_InitStruct->Line_0_31);
+ break;
+ case LL_EXTI_MODE_IT_EVENT:
+ /* Directly Enable IT & Event on provided Lines */
+ LL_EXTI_EnableIT_0_31(EXTI_InitStruct->Line_0_31);
+ LL_EXTI_EnableEvent_0_31(EXTI_InitStruct->Line_0_31);
+ break;
+ default:
+ status = ERROR;
+ break;
+ }
+ if (EXTI_InitStruct->Trigger != LL_EXTI_TRIGGER_NONE)
+ {
+ switch (EXTI_InitStruct->Trigger)
+ {
+ case LL_EXTI_TRIGGER_RISING:
+ /* First Disable Falling Trigger on provided Lines */
+ LL_EXTI_DisableFallingTrig_0_31(EXTI_InitStruct->Line_0_31);
+ /* Then Enable Rising Trigger on provided Lines */
+ LL_EXTI_EnableRisingTrig_0_31(EXTI_InitStruct->Line_0_31);
+ break;
+ case LL_EXTI_TRIGGER_FALLING:
+ /* First Disable Rising Trigger on provided Lines */
+ LL_EXTI_DisableRisingTrig_0_31(EXTI_InitStruct->Line_0_31);
+ /* Then Enable Falling Trigger on provided Lines */
+ LL_EXTI_EnableFallingTrig_0_31(EXTI_InitStruct->Line_0_31);
+ break;
+ case LL_EXTI_TRIGGER_RISING_FALLING:
+ LL_EXTI_EnableRisingTrig_0_31(EXTI_InitStruct->Line_0_31);
+ LL_EXTI_EnableFallingTrig_0_31(EXTI_InitStruct->Line_0_31);
+ break;
+ default:
+ status = ERROR;
+ break;
+ }
+ }
+ }
+ }
+ /* DISABLE LineCommand */
+ else
+ {
+ /* De-configure EXTI Lines in range from 0 to 31 */
+ LL_EXTI_DisableIT_0_31(EXTI_InitStruct->Line_0_31);
+ LL_EXTI_DisableEvent_0_31(EXTI_InitStruct->Line_0_31);
+ }
+ return status;
+}
+
+/**
+ * @brief Set each @ref LL_EXTI_InitTypeDef field to default value.
+ * @param EXTI_InitStruct Pointer to a @ref LL_EXTI_InitTypeDef structure.
+ * @retval None
+ */
+void LL_EXTI_StructInit(LL_EXTI_InitTypeDef *EXTI_InitStruct)
+{
+ EXTI_InitStruct->Line_0_31 = LL_EXTI_LINE_NONE;
+ EXTI_InitStruct->LineCommand = DISABLE;
+ EXTI_InitStruct->Mode = LL_EXTI_MODE_IT;
+ EXTI_InitStruct->Trigger = LL_EXTI_TRIGGER_FALLING;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* defined (EXTI) */
+
+/**
+ * @}
+ */
+
+#endif /* USE_FULL_LL_DRIVER */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_fsmc.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_fsmc.c
new file mode 100644
index 0000000..3edbdf3
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_fsmc.c
@@ -0,0 +1,929 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_fsmc.c
+ * @author MCD Application Team
+ * @brief FSMC Low Layer HAL module driver.
+ *
+ * This file provides firmware functions to manage the following
+ * functionalities of the Flexible Static Memory Controller (FSMC) peripheral memories:
+ * + Initialization/de-initialization functions
+ * + Peripheral Control functions
+ * + Peripheral State functions
+ *
+ @verbatim
+ =============================================================================
+ ##### FSMC peripheral features #####
+ =============================================================================
+ [..] The Flexible static memory controller (FSMC) includes following memory controllers:
+ (+) The NOR/PSRAM memory controller
+ (+) The PC Card memory controller
+ (+) The NAND memory controller
+ (PC Card and NAND controllers available only on STM32F101xE, STM32F103xE, STM32F101xG and STM32F103xG)
+
+ [..] The FSMC functional block makes the interface with synchronous and asynchronous static
+ memories and 16-bit PC memory cards. Its main purposes are:
+ (+) to translate AHB transactions into the appropriate external device protocol.
+ (+) to meet the access time requirements of the external memory devices.
+
+ [..] All external memories share the addresses, data and control signals with the controller.
+ Each external device is accessed by means of a unique Chip Select. The FSMC performs
+ only one access at a time to an external device.
+ The main features of the FSMC controller are the following:
+ (+) Interface with static-memory mapped devices including:
+ (++) Static random access memory (SRAM).
+ (++) NOR Flash memory.
+ (++) PSRAM (4 memory banks).
+ (++) 16-bit PC Card compatible devices.
+ (++) Two banks of NAND Flash memory with ECC hardware to check up to 8 Kbytes of
+ data.
+ (+) Independent Chip Select control for each memory bank.
+ (+) Independent configuration for each memory bank.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#if defined(FSMC_BANK1)
+
+#if defined(HAL_SRAM_MODULE_ENABLED) || defined(HAL_NOR_MODULE_ENABLED) || defined(HAL_PCCARD_MODULE_ENABLED) || defined(HAL_NAND_MODULE_ENABLED)
+
+/** @defgroup FSMC_LL FSMC Low Layer
+ * @brief FSMC driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup FSMC_LL_Exported_Functions FSMC Low Layer Exported Functions
+ * @{
+ */
+
+/** @defgroup FSMC_NORSRAM FSMC NORSRAM Controller functions
+ * @brief NORSRAM Controller functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use NORSRAM device driver #####
+ ==============================================================================
+
+ [..]
+ This driver contains a set of APIs to interface with the FSMC NORSRAM banks in order
+ to run the NORSRAM external devices.
+
+ (+) FSMC NORSRAM bank reset using the function FSMC_NORSRAM_DeInit()
+ (+) FSMC NORSRAM bank control configuration using the function FSMC_NORSRAM_Init()
+ (+) FSMC NORSRAM bank timing configuration using the function FSMC_NORSRAM_Timing_Init()
+ (+) FSMC NORSRAM bank extended timing configuration using the function
+ FSMC_NORSRAM_Extended_Timing_Init()
+ (+) FSMC NORSRAM bank enable/disable write operation using the functions
+ FSMC_NORSRAM_WriteOperation_Enable()/FSMC_NORSRAM_WriteOperation_Disable()
+
+@endverbatim
+ * @{
+ */
+
+/** @addtogroup FSMC_LL_NORSRAM_Private_Functions_Group1
+ * @brief Initialization and Configuration functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### Initialization and de_initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the FSMC NORSRAM interface
+ (+) De-initialize the FSMC NORSRAM interface
+ (+) Configure the FSMC clock and associated GPIOs
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initialize the FSMC_NORSRAM device according to the specified
+ * control parameters in the FSMC_NORSRAM_InitTypeDef
+ * @param Device: Pointer to NORSRAM device instance
+ * @param Init: Pointer to NORSRAM Initialization structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_Init(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_InitTypeDef *Init)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FSMC_NORSRAM_BANK(Init->NSBank));
+ assert_param(IS_FSMC_MUX(Init->DataAddressMux));
+ assert_param(IS_FSMC_MEMORY(Init->MemoryType));
+ assert_param(IS_FSMC_NORSRAM_MEMORY_WIDTH(Init->MemoryDataWidth));
+ assert_param(IS_FSMC_BURSTMODE(Init->BurstAccessMode));
+ assert_param(IS_FSMC_WAIT_POLARITY(Init->WaitSignalPolarity));
+ assert_param(IS_FSMC_WRAP_MODE(Init->WrapMode));
+ assert_param(IS_FSMC_WAIT_SIGNAL_ACTIVE(Init->WaitSignalActive));
+ assert_param(IS_FSMC_WRITE_OPERATION(Init->WriteOperation));
+ assert_param(IS_FSMC_WAITE_SIGNAL(Init->WaitSignal));
+ assert_param(IS_FSMC_EXTENDED_MODE(Init->ExtendedMode));
+ assert_param(IS_FSMC_ASYNWAIT(Init->AsynchronousWait));
+ assert_param(IS_FSMC_WRITE_BURST(Init->WriteBurst));
+
+ /* Disable NORSRAM Device */
+ __FSMC_NORSRAM_DISABLE(Device, Init->NSBank);
+
+ /* Set NORSRAM device control parameters */
+ if (Init->MemoryType == FSMC_MEMORY_TYPE_NOR)
+ {
+ MODIFY_REG(Device->BTCR[Init->NSBank], BCR_CLEAR_MASK, (uint32_t)(FSMC_NORSRAM_FLASH_ACCESS_ENABLE
+ | Init->DataAddressMux
+ | Init->MemoryType
+ | Init->MemoryDataWidth
+ | Init->BurstAccessMode
+ | Init->WaitSignalPolarity
+ | Init->WrapMode
+ | Init->WaitSignalActive
+ | Init->WriteOperation
+ | Init->WaitSignal
+ | Init->ExtendedMode
+ | Init->AsynchronousWait
+ | Init->WriteBurst
+ )
+ );
+ }
+ else
+ {
+ MODIFY_REG(Device->BTCR[Init->NSBank], BCR_CLEAR_MASK, (uint32_t)(FSMC_NORSRAM_FLASH_ACCESS_DISABLE
+ | Init->DataAddressMux
+ | Init->MemoryType
+ | Init->MemoryDataWidth
+ | Init->BurstAccessMode
+ | Init->WaitSignalPolarity
+ | Init->WrapMode
+ | Init->WaitSignalActive
+ | Init->WriteOperation
+ | Init->WaitSignal
+ | Init->ExtendedMode
+ | Init->AsynchronousWait
+ | Init->WriteBurst
+ )
+ );
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitialize the FSMC_NORSRAM peripheral
+ * @param Device: Pointer to NORSRAM device instance
+ * @param ExDevice: Pointer to NORSRAM extended mode device instance
+ * @param Bank: NORSRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_DeInit(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FSMC_NORSRAM_EXTENDED_DEVICE(ExDevice));
+ assert_param(IS_FSMC_NORSRAM_BANK(Bank));
+
+ /* Disable the FSMC_NORSRAM device */
+ __FSMC_NORSRAM_DISABLE(Device, Bank);
+
+ /* De-initialize the FSMC_NORSRAM device */
+ /* FSMC_NORSRAM_BANK1 */
+ if(Bank == FSMC_NORSRAM_BANK1)
+ {
+ Device->BTCR[Bank] = 0x000030DBU;
+ }
+ /* FSMC_NORSRAM_BANK2, FSMC_NORSRAM_BANK3 or FSMC_NORSRAM_BANK4 */
+ else
+ {
+ Device->BTCR[Bank] = 0x000030D2U;
+ }
+
+ Device->BTCR[Bank + 1U] = 0x0FFFFFFFU;
+ ExDevice->BWTR[Bank] = 0x0FFFFFFFU;
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Initialize the FSMC_NORSRAM Timing according to the specified
+ * parameters in the FSMC_NORSRAM_TimingTypeDef
+ * @param Device: Pointer to NORSRAM device instance
+ * @param Timing: Pointer to NORSRAM Timing structure
+ * @param Bank: NORSRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_Timing_Init(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FSMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
+ assert_param(IS_FSMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
+ assert_param(IS_FSMC_DATASETUP_TIME(Timing->DataSetupTime));
+ assert_param(IS_FSMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
+ assert_param(IS_FSMC_CLK_DIV(Timing->CLKDivision));
+ assert_param(IS_FSMC_DATA_LATENCY(Timing->DataLatency));
+ assert_param(IS_FSMC_ACCESS_MODE(Timing->AccessMode));
+ assert_param(IS_FSMC_NORSRAM_BANK(Bank));
+
+ /* Set FSMC_NORSRAM device timing parameters */
+ MODIFY_REG(Device->BTCR[Bank + 1U], \
+ BTR_CLEAR_MASK, \
+ (uint32_t)(Timing->AddressSetupTime | \
+ ((Timing->AddressHoldTime) << FSMC_BTRx_ADDHLD_Pos) | \
+ ((Timing->DataSetupTime) << FSMC_BTRx_DATAST_Pos) | \
+ ((Timing->BusTurnAroundDuration) << FSMC_BTRx_BUSTURN_Pos) | \
+ (((Timing->CLKDivision) - 1U) << FSMC_BTRx_CLKDIV_Pos) | \
+ (((Timing->DataLatency) - 2U) << FSMC_BTRx_DATLAT_Pos) | \
+ (Timing->AccessMode)));
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initialize the FSMC_NORSRAM Extended mode Timing according to the specified
+ * parameters in the FSMC_NORSRAM_TimingTypeDef
+ * @param Device: Pointer to NORSRAM device instance
+ * @param Timing: Pointer to NORSRAM Timing structure
+ * @param Bank: NORSRAM bank number
+ * @param ExtendedMode FSMC Extended Mode
+ * This parameter can be one of the following values:
+ * @arg FSMC_EXTENDED_MODE_DISABLE
+ * @arg FSMC_EXTENDED_MODE_ENABLE
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_Extended_Timing_Init(FSMC_NORSRAM_EXTENDED_TypeDef *Device, FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, uint32_t ExtendedMode)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_EXTENDED_MODE(ExtendedMode));
+
+ /* Set NORSRAM device timing register for write configuration, if extended mode is used */
+ if(ExtendedMode == FSMC_EXTENDED_MODE_ENABLE)
+ {
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_EXTENDED_DEVICE(Device));
+ assert_param(IS_FSMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
+ assert_param(IS_FSMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
+ assert_param(IS_FSMC_DATASETUP_TIME(Timing->DataSetupTime));
+#if defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG)
+ assert_param(IS_FSMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
+#else
+ assert_param(IS_FSMC_CLK_DIV(Timing->CLKDivision));
+ assert_param(IS_FSMC_DATA_LATENCY(Timing->DataLatency));
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+ assert_param(IS_FSMC_ACCESS_MODE(Timing->AccessMode));
+ assert_param(IS_FSMC_NORSRAM_BANK(Bank));
+
+ /* Set NORSRAM device timing register for write configuration, if extended mode is used */
+#if defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG)
+ MODIFY_REG(Device->BWTR[Bank], \
+ BWTR_CLEAR_MASK, \
+ (uint32_t)(Timing->AddressSetupTime | \
+ ((Timing->AddressHoldTime) << FSMC_BWTRx_ADDHLD_Pos) | \
+ ((Timing->DataSetupTime) << FSMC_BWTRx_DATAST_Pos) | \
+ Timing->AccessMode | \
+ ((Timing->BusTurnAroundDuration) << FSMC_BWTRx_BUSTURN_Pos)));
+#else
+ MODIFY_REG(Device->BWTR[Bank], \
+ BWTR_CLEAR_MASK, \
+ (uint32_t)(Timing->AddressSetupTime | \
+ ((Timing->AddressHoldTime) << FSMC_BWTRx_ADDHLD_Pos) | \
+ ((Timing->DataSetupTime) << FSMC_BWTRx_DATAST_Pos) | \
+ Timing->AccessMode | \
+ (((Timing->CLKDivision) - 1U) << FSMC_BTRx_CLKDIV_Pos) | \
+ (((Timing->DataLatency) - 2U) << FSMC_BWTRx_DATLAT_Pos)));
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+ }
+ else
+ {
+ Device->BWTR[Bank] = 0x0FFFFFFFU;
+ }
+
+ return HAL_OK;
+}
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NORSRAM_Group2 Control functions
+ * @brief management functions
+ *
+@verbatim
+ ==============================================================================
+ ##### FSMC_NORSRAM Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control dynamically
+ the FSMC NORSRAM interface.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables dynamically FSMC_NORSRAM write operation.
+ * @param Device: Pointer to NORSRAM device instance
+ * @param Bank: NORSRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Enable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FSMC_NORSRAM_BANK(Bank));
+
+ /* Enable write operation */
+ SET_BIT(Device->BTCR[Bank], FSMC_WRITE_OPERATION_ENABLE);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically FSMC_NORSRAM write operation.
+ * @param Device: Pointer to NORSRAM device instance
+ * @param Bank: NORSRAM bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Disable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_DEVICE(Device));
+ assert_param(IS_FSMC_NORSRAM_BANK(Bank));
+
+ /* Disable write operation */
+ CLEAR_BIT(Device->BTCR[Bank], FSMC_WRITE_OPERATION_ENABLE);
+
+ return HAL_OK;
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#if (defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG))
+/** @defgroup FSMC_NAND FSMC NAND Controller functions
+ * @brief NAND Controller functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use NAND device driver #####
+ ==============================================================================
+ [..]
+ This driver contains a set of APIs to interface with the FSMC NAND banks in order
+ to run the NAND external devices.
+
+ (+) FSMC NAND bank reset using the function FSMC_NAND_DeInit()
+ (+) FSMC NAND bank control configuration using the function FSMC_NAND_Init()
+ (+) FSMC NAND bank common space timing configuration using the function
+ FSMC_NAND_CommonSpace_Timing_Init()
+ (+) FSMC NAND bank attribute space timing configuration using the function
+ FSMC_NAND_AttributeSpace_Timing_Init()
+ (+) FSMC NAND bank enable/disable ECC correction feature using the functions
+ FSMC_NAND_ECC_Enable()/FSMC_NAND_ECC_Disable()
+ (+) FSMC NAND bank get ECC correction code using the function FSMC_NAND_GetECC()
+
+@endverbatim
+ * @{
+ */
+
+/** @defgroup FSMC_NAND_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de_initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the FSMC NAND interface
+ (+) De-initialize the FSMC NAND interface
+ (+) Configure the FSMC clock and associated GPIOs
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the FSMC_NAND device according to the specified
+ * control parameters in the FSMC_NAND_HandleTypeDef
+ * @param Device: Pointer to NAND device instance
+ * @param Init: Pointer to NAND Initialization structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_InitTypeDef *Init)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_NAND_BANK(Init->NandBank));
+ assert_param(IS_FSMC_WAIT_FEATURE(Init->Waitfeature));
+ assert_param(IS_FSMC_NAND_MEMORY_WIDTH(Init->MemoryDataWidth));
+ assert_param(IS_FSMC_ECC_STATE(Init->EccComputation));
+ assert_param(IS_FSMC_ECCPAGE_SIZE(Init->ECCPageSize));
+ assert_param(IS_FSMC_TCLR_TIME(Init->TCLRSetupTime));
+ assert_param(IS_FSMC_TAR_TIME(Init->TARSetupTime));
+
+ /* Set NAND device control parameters */
+ if (Init->NandBank == FSMC_NAND_BANK2)
+ {
+ /* NAND bank 2 registers configuration */
+ MODIFY_REG(Device->PCR2, PCR_CLEAR_MASK, (Init->Waitfeature |
+ FSMC_PCR_MEMORY_TYPE_NAND |
+ Init->MemoryDataWidth |
+ Init->EccComputation |
+ Init->ECCPageSize |
+ ((Init->TCLRSetupTime) << FSMC_PCRx_TCLR_Pos) |
+ ((Init->TARSetupTime) << FSMC_PCRx_TAR_Pos)));
+ }
+ else
+ {
+ /* NAND bank 3 registers configuration */
+ MODIFY_REG(Device->PCR3, PCR_CLEAR_MASK, (Init->Waitfeature |
+ FSMC_PCR_MEMORY_TYPE_NAND |
+ Init->MemoryDataWidth |
+ Init->EccComputation |
+ Init->ECCPageSize |
+ ((Init->TCLRSetupTime) << FSMC_PCRx_TCLR_Pos) |
+ ((Init->TARSetupTime) << FSMC_PCRx_TAR_Pos)));
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FSMC_NAND Common space Timing according to the specified
+ * parameters in the FSMC_NAND_PCC_TimingTypeDef
+ * @param Device: Pointer to NAND device instance
+ * @param Timing: Pointer to NAND timing structure
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_CommonSpace_Timing_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
+ assert_param(IS_FSMC_NAND_BANK(Bank));
+
+ /* Set FMC_NAND device timing parameters */
+ if(Bank == FSMC_NAND_BANK2)
+ {
+ /* NAND bank 2 registers configuration */
+ MODIFY_REG(Device->PMEM2, PMEM_CLEAR_MASK, (Timing->SetupTime | \
+ ((Timing->WaitSetupTime) << FSMC_PMEMx_MEMWAITx_Pos) | \
+ ((Timing->HoldSetupTime) << FSMC_PMEMx_MEMHOLDx_Pos) | \
+ ((Timing->HiZSetupTime) << FSMC_PMEMx_MEMHIZx_Pos)));
+ }
+ else
+ {
+ /* NAND bank 3 registers configuration */
+ MODIFY_REG(Device->PMEM3, PMEM_CLEAR_MASK, (Timing->SetupTime | \
+ ((Timing->WaitSetupTime) << FSMC_PMEMx_MEMWAITx_Pos) | \
+ ((Timing->HoldSetupTime) << FSMC_PMEMx_MEMHOLDx_Pos) | \
+ ((Timing->HiZSetupTime) << FSMC_PMEMx_MEMHIZx_Pos)));
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FSMC_NAND Attribute space Timing according to the specified
+ * parameters in the FSMC_NAND_PCC_TimingTypeDef
+ * @param Device: Pointer to NAND device instance
+ * @param Timing: Pointer to NAND timing structure
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_AttributeSpace_Timing_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
+ assert_param(IS_FSMC_NAND_BANK(Bank));
+
+ /* Set FMC_NAND device timing parameters */
+ if(Bank == FSMC_NAND_BANK2)
+ {
+ /* NAND bank 2 registers configuration */
+ MODIFY_REG(Device->PATT2, PATT_CLEAR_MASK, (Timing->SetupTime | \
+ ((Timing->WaitSetupTime) << FSMC_PATTx_ATTWAITx_Pos) | \
+ ((Timing->HoldSetupTime) << FSMC_PATTx_ATTHOLDx_Pos) | \
+ ((Timing->HiZSetupTime) << FSMC_PATTx_ATTHIZx_Pos)));
+ }
+ else
+ {
+ /* NAND bank 3 registers configuration */
+ MODIFY_REG(Device->PATT3, PATT_CLEAR_MASK, (Timing->SetupTime | \
+ ((Timing->WaitSetupTime) << FSMC_PATTx_ATTWAITx_Pos) | \
+ ((Timing->HoldSetupTime) << FSMC_PATTx_ATTHOLDx_Pos) | \
+ ((Timing->HiZSetupTime) << FSMC_PATTx_ATTHIZx_Pos)));
+ }
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief DeInitializes the FSMC_NAND device
+ * @param Device: Pointer to NAND device instance
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_DeInit(FSMC_NAND_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_NAND_BANK(Bank));
+
+ /* Disable the NAND Bank */
+ __FSMC_NAND_DISABLE(Device, Bank);
+
+ /* De-initialize the NAND Bank */
+ if(Bank == FSMC_NAND_BANK2)
+ {
+ /* Set the FSMC_NAND_BANK2 registers to their reset values */
+ WRITE_REG(Device->PCR2, 0x00000018U);
+ WRITE_REG(Device->SR2, 0x00000040U);
+ WRITE_REG(Device->PMEM2, 0xFCFCFCFCU);
+ WRITE_REG(Device->PATT2, 0xFCFCFCFCU);
+ }
+ /* FSMC_Bank3_NAND */
+ else
+ {
+ /* Set the FSMC_NAND_BANK3 registers to their reset values */
+ WRITE_REG(Device->PCR3, 0x00000018U);
+ WRITE_REG(Device->SR3, 0x00000040U);
+ WRITE_REG(Device->PMEM3, 0xFCFCFCFCU);
+ WRITE_REG(Device->PATT3, 0xFCFCFCFCU);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup FSMC_NAND_Exported_Functions_Group2 Peripheral Control functions
+ * @brief management functions
+ *
+@verbatim
+ ==============================================================================
+ ##### FSMC_NAND Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control dynamically
+ the FSMC NAND interface.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables dynamically FSMC_NAND ECC feature.
+ * @param Device: Pointer to NAND device instance
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_ECC_Enable(FSMC_NAND_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_NAND_BANK(Bank));
+
+ /* Enable ECC feature */
+ if(Bank == FSMC_NAND_BANK2)
+ {
+ SET_BIT(Device->PCR2, FSMC_PCRx_ECCEN);
+ }
+ else
+ {
+ SET_BIT(Device->PCR3, FSMC_PCRx_ECCEN);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically FSMC_NAND ECC feature.
+ * @param Device: Pointer to NAND device instance
+ * @param Bank: NAND bank number
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_ECC_Disable(FSMC_NAND_TypeDef *Device, uint32_t Bank)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_NAND_BANK(Bank));
+
+ /* Disable ECC feature */
+ if(Bank == FSMC_NAND_BANK2)
+ {
+ CLEAR_BIT(Device->PCR2, FSMC_PCRx_ECCEN);
+ }
+ else
+ {
+ CLEAR_BIT(Device->PCR3, FSMC_PCRx_ECCEN);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disables dynamically FSMC_NAND ECC feature.
+ * @param Device: Pointer to NAND device instance
+ * @param ECCval: Pointer to ECC value
+ * @param Bank: NAND bank number
+ * @param Timeout: Timeout wait value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_NAND_GetECC(FSMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank, uint32_t Timeout)
+{
+ uint32_t tickstart = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_FSMC_NAND_DEVICE(Device));
+ assert_param(IS_FSMC_NAND_BANK(Bank));
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait until FIFO is empty */
+ while(__FSMC_NAND_GET_FLAG(Device, Bank, FSMC_FLAG_FEMPT) == RESET)
+ {
+ /* Check for the Timeout */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ if(Bank == FSMC_NAND_BANK2)
+ {
+ /* Get the ECCR2 register value */
+ *ECCval = (uint32_t)Device->ECCR2;
+ }
+ else
+ {
+ /* Get the ECCR3 register value */
+ *ECCval = (uint32_t)Device->ECCR3;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_PCCARD FSMC PCCARD Controller functions
+ * @brief PCCARD Controller functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use PCCARD device driver #####
+ ==============================================================================
+ [..]
+ This driver contains a set of APIs to interface with the FSMC PCCARD bank in order
+ to run the PCCARD/compact flash external devices.
+
+ (+) FSMC PCCARD bank reset using the function FSMC_PCCARD_DeInit()
+ (+) FSMC PCCARD bank control configuration using the function FSMC_PCCARD_Init()
+ (+) FSMC PCCARD bank common space timing configuration using the function
+ FSMC_PCCARD_CommonSpace_Timing_Init()
+ (+) FSMC PCCARD bank attribute space timing configuration using the function
+ FSMC_PCCARD_AttributeSpace_Timing_Init()
+ (+) FSMC PCCARD bank IO space timing configuration using the function
+ FSMC_PCCARD_IOSpace_Timing_Init()
+
+@endverbatim
+ * @{
+ */
+
+/** @defgroup FSMC_PCCARD_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de_initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the FSMC PCCARD interface
+ (+) De-initialize the FSMC PCCARD interface
+ (+) Configure the FSMC clock and associated GPIOs
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the FSMC_PCCARD device according to the specified
+ * control parameters in the FSMC_PCCARD_HandleTypeDef
+ * @param Device: Pointer to PCCARD device instance
+ * @param Init: Pointer to PCCARD Initialization structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_PCCARD_Init(FSMC_PCCARD_TypeDef *Device, FSMC_PCCARD_InitTypeDef *Init)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_PCCARD_DEVICE(Device));
+ assert_param(IS_FSMC_WAIT_FEATURE(Init->Waitfeature));
+ assert_param(IS_FSMC_TCLR_TIME(Init->TCLRSetupTime));
+ assert_param(IS_FSMC_TAR_TIME(Init->TARSetupTime));
+
+ /* Set FSMC_PCCARD device control parameters */
+ MODIFY_REG(Device->PCR4,
+ (FSMC_PCRx_PTYP | FSMC_PCRx_PWAITEN | FSMC_PCRx_PWID |
+ FSMC_PCRx_TCLR | FSMC_PCRx_TAR),
+ (FSMC_PCR_MEMORY_TYPE_PCCARD |
+ Init->Waitfeature |
+ FSMC_NAND_PCC_MEM_BUS_WIDTH_16 |
+ (Init->TCLRSetupTime << FSMC_PCRx_TCLR_Pos) |
+ (Init->TARSetupTime << FSMC_PCRx_TAR_Pos)));
+
+ return HAL_OK;
+
+}
+
+/**
+ * @brief Initializes the FSMC_PCCARD Common space Timing according to the specified
+ * parameters in the FSMC_NAND_PCC_TimingTypeDef
+ * @param Device: Pointer to PCCARD device instance
+ * @param Timing: Pointer to PCCARD timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_PCCARD_CommonSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_PCCARD_DEVICE(Device));
+ assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
+
+ /* Set PCCARD timing parameters */
+ MODIFY_REG(Device->PMEM4, PMEM_CLEAR_MASK,
+ (Timing->SetupTime |
+ ((Timing->WaitSetupTime) << FSMC_PMEMx_MEMWAITx_Pos) |
+ ((Timing->HoldSetupTime) << FSMC_PMEMx_MEMHOLDx_Pos) |
+ ((Timing->HiZSetupTime) << FSMC_PMEMx_MEMHIZx_Pos)));
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FSMC_PCCARD Attribute space Timing according to the specified
+ * parameters in the FSMC_NAND_PCC_TimingTypeDef
+ * @param Device: Pointer to PCCARD device instance
+ * @param Timing: Pointer to PCCARD timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_PCCARD_AttributeSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_PCCARD_DEVICE(Device));
+ assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
+
+ /* Set PCCARD timing parameters */
+ MODIFY_REG(Device->PATT4, PATT_CLEAR_MASK, \
+ (Timing->SetupTime | \
+ ((Timing->WaitSetupTime) << FSMC_PATTx_ATTWAITx_Pos) | \
+ ((Timing->HoldSetupTime) << FSMC_PATTx_ATTHOLDx_Pos) | \
+ ((Timing->HiZSetupTime) << FSMC_PATTx_ATTHIZx_Pos)));
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the FSMC_PCCARD IO space Timing according to the specified
+ * parameters in the FSMC_NAND_PCC_TimingTypeDef
+ * @param Device: Pointer to PCCARD device instance
+ * @param Timing: Pointer to PCCARD timing structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_PCCARD_IOSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_PCCARD_DEVICE(Device));
+ assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime));
+
+ /* Set FSMC_PCCARD device timing parameters */
+ MODIFY_REG(Device->PIO4, PIO4_CLEAR_MASK, \
+ (Timing->SetupTime | \
+ (Timing->WaitSetupTime << FSMC_PIO4_IOWAIT4_Pos) | \
+ (Timing->HoldSetupTime << FSMC_PIO4_IOHOLD4_Pos) | \
+ (Timing->HiZSetupTime << FSMC_PIO4_IOHIZ4_Pos)));
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the FSMC_PCCARD device
+ * @param Device: Pointer to PCCARD device instance
+ * @retval HAL status
+ */
+HAL_StatusTypeDef FSMC_PCCARD_DeInit(FSMC_PCCARD_TypeDef *Device)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_PCCARD_DEVICE(Device));
+
+ /* Disable the FSMC_PCCARD device */
+ __FSMC_PCCARD_DISABLE(Device);
+
+ /* De-initialize the FSMC_PCCARD device */
+ WRITE_REG(Device->PCR4, 0x00000018U);
+ WRITE_REG(Device->SR4, 0x00000040U);
+ WRITE_REG(Device->PMEM4, 0xFCFCFCFCU);
+ WRITE_REG(Device->PATT4, 0xFCFCFCFCU);
+ WRITE_REG(Device->PIO4, 0xFCFCFCFCU);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_SRAM_MODULE_ENABLED || HAL_NOR_MODULE_ENABLED || HAL_NAND_MODULE_ENABLED || HAL_PCCARD_MODULE_ENABLED */
+
+#endif /* FSMC_BANK1 */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_gpio.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_gpio.c
new file mode 100644
index 0000000..c182e59
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_gpio.c
@@ -0,0 +1,268 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_gpio.c
+ * @author MCD Application Team
+ * @brief GPIO LL module driver.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+#if defined(USE_FULL_LL_DRIVER)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_gpio.h"
+#include "stm32f1xx_ll_bus.h"
+#ifdef USE_FULL_ASSERT
+#include "stm32_assert.h"
+#else
+#define assert_param(expr) ((void)0U)
+#endif
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (GPIOA) || defined (GPIOB) || defined (GPIOC) || defined (GPIOD) || defined (GPIOE) || defined (GPIOF) || defined (GPIOG)
+
+/** @addtogroup GPIO_LL
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/** @addtogroup GPIO_LL_Private_Macros
+ * @{
+ */
+
+#define IS_LL_GPIO_PIN(__VALUE__) ((((__VALUE__) & LL_GPIO_PIN_ALL)!= 0U) &&\
+ (((__VALUE__) & (~LL_GPIO_PIN_ALL))== 0U))
+
+#define IS_LL_GPIO_MODE(__VALUE__) (((__VALUE__) == LL_GPIO_MODE_ANALOG) ||\
+ ((__VALUE__) == LL_GPIO_MODE_FLOATING) ||\
+ ((__VALUE__) == LL_GPIO_MODE_INPUT) ||\
+ ((__VALUE__) == LL_GPIO_MODE_OUTPUT) ||\
+ ((__VALUE__) == LL_GPIO_MODE_ALTERNATE))
+
+#define IS_LL_GPIO_SPEED(__VALUE__) (((__VALUE__) == LL_GPIO_SPEED_FREQ_LOW) ||\
+ ((__VALUE__) == LL_GPIO_SPEED_FREQ_MEDIUM) ||\
+ ((__VALUE__) == LL_GPIO_SPEED_FREQ_HIGH))
+
+#define IS_LL_GPIO_OUTPUT_TYPE(__VALUE__) (((__VALUE__) == LL_GPIO_OUTPUT_PUSHPULL) ||\
+ ((__VALUE__) == LL_GPIO_OUTPUT_OPENDRAIN))
+
+#define IS_LL_GPIO_PULL(__VALUE__) (((__VALUE__) == LL_GPIO_PULL_DOWN) ||\
+ ((__VALUE__) == LL_GPIO_PULL_UP))
+
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup GPIO_LL_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup GPIO_LL_EF_Init
+ * @{
+ */
+
+/**
+ * @brief De-initialize GPIO registers (Registers restored to their default values).
+ * @param GPIOx GPIO Port
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: GPIO registers are de-initialized
+ * - ERROR: Wrong GPIO Port
+ */
+ErrorStatus LL_GPIO_DeInit(GPIO_TypeDef *GPIOx)
+{
+ ErrorStatus status = SUCCESS;
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
+
+ /* Force and Release reset on clock of GPIOx Port */
+ if (GPIOx == GPIOA)
+ {
+ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOA);
+ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOA);
+ }
+ else if (GPIOx == GPIOB)
+ {
+ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOB);
+ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOB);
+ }
+ else if (GPIOx == GPIOC)
+ {
+ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOC);
+ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOC);
+ }
+ else if (GPIOx == GPIOD)
+ {
+ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOD);
+ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOD);
+ }
+#if defined(GPIOE)
+ else if (GPIOx == GPIOE)
+ {
+ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOE);
+ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOE);
+ }
+#endif
+#if defined(GPIOF)
+ else if (GPIOx == GPIOF)
+ {
+ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOF);
+ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOF);
+ }
+#endif
+#if defined(GPIOG)
+ else if (GPIOx == GPIOG)
+ {
+ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOG);
+ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOG);
+ }
+#endif
+ else
+ {
+ status = ERROR;
+ }
+
+ return (status);
+}
+
+/**
+ * @brief Initialize GPIO registers according to the specified parameters in GPIO_InitStruct.
+ * @param GPIOx GPIO Port
+ * @param GPIO_InitStruct: pointer to a @ref LL_GPIO_InitTypeDef structure
+ * that contains the configuration information for the specified GPIO peripheral.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: GPIO registers are initialized according to GPIO_InitStruct content
+ * - ERROR: Not applicable
+ */
+ErrorStatus LL_GPIO_Init(GPIO_TypeDef *GPIOx, LL_GPIO_InitTypeDef *GPIO_InitStruct)
+{
+ uint32_t pinmask;
+ uint32_t pinpos;
+ uint32_t currentpin;
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
+ assert_param(IS_LL_GPIO_PIN(GPIO_InitStruct->Pin));
+
+ /* ------------------------- Configure the port pins ---------------- */
+ /* Initialize pinpos on first pin set */
+
+ pinmask = ((GPIO_InitStruct->Pin) << GPIO_PIN_MASK_POS) >> GPIO_PIN_NB;
+ pinpos = POSITION_VAL(pinmask);
+
+ /* Configure the port pins */
+ while ((pinmask >> pinpos) != 0U)
+ {
+ /* skip if bit is not set */
+ if ((pinmask & (1U << pinpos)) != 0U)
+ {
+ /* Get current io position */
+ if (pinpos < GPIO_PIN_MASK_POS)
+ {
+ currentpin = (0x00000101U << pinpos);
+ }
+ else
+ {
+ currentpin = ((0x00010001U << (pinpos - GPIO_PIN_MASK_POS)) | 0x04000000U);
+ }
+
+ /* Check Pin Mode and Pin Pull parameters */
+ assert_param(IS_LL_GPIO_MODE(GPIO_InitStruct->Mode));
+ assert_param(IS_LL_GPIO_PULL(GPIO_InitStruct->Pull));
+
+ /* Pin Mode configuration */
+ LL_GPIO_SetPinMode(GPIOx, currentpin, GPIO_InitStruct->Mode);
+
+ /* Pull-up Pull-down resistor configuration*/
+ LL_GPIO_SetPinPull(GPIOx, currentpin, GPIO_InitStruct->Pull);
+
+ if ((GPIO_InitStruct->Mode == LL_GPIO_MODE_OUTPUT) || (GPIO_InitStruct->Mode == LL_GPIO_MODE_ALTERNATE))
+ {
+ /* Check speed and Output mode parameters */
+ assert_param(IS_LL_GPIO_SPEED(GPIO_InitStruct->Speed));
+ assert_param(IS_LL_GPIO_OUTPUT_TYPE(GPIO_InitStruct->OutputType));
+
+ /* Speed mode configuration */
+ LL_GPIO_SetPinSpeed(GPIOx, currentpin, GPIO_InitStruct->Speed);
+
+ /* Output mode configuration*/
+ LL_GPIO_SetPinOutputType(GPIOx, currentpin, GPIO_InitStruct->OutputType);
+ }
+ }
+ pinpos++;
+ }
+ return (SUCCESS);
+}
+
+/**
+ * @brief Set each @ref LL_GPIO_InitTypeDef field to default value.
+ * @param GPIO_InitStruct: pointer to a @ref LL_GPIO_InitTypeDef structure
+ * whose fields will be set to default values.
+ * @retval None
+ */
+
+void LL_GPIO_StructInit(LL_GPIO_InitTypeDef *GPIO_InitStruct)
+{
+ /* Reset GPIO init structure parameters values */
+ GPIO_InitStruct->Pin = LL_GPIO_PIN_ALL;
+ GPIO_InitStruct->Mode = LL_GPIO_MODE_FLOATING;
+ GPIO_InitStruct->Speed = LL_GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct->OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
+ GPIO_InitStruct->Pull = LL_GPIO_PULL_DOWN;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* defined (GPIOA) || defined (GPIOB) || defined (GPIOC) || defined (GPIOD) || defined (GPIOE) || defined (GPIOF) || defined (GPIOG) */
+
+/**
+ * @}
+ */
+
+#endif /* USE_FULL_LL_DRIVER */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_i2c.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_i2c.c
new file mode 100644
index 0000000..ef7fedb
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_i2c.c
@@ -0,0 +1,237 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_i2c.c
+ * @author MCD Application Team
+ * @brief I2C LL module driver.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+#if defined(USE_FULL_LL_DRIVER)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_i2c.h"
+#include "stm32f1xx_ll_bus.h"
+#include "stm32f1xx_ll_rcc.h"
+#ifdef USE_FULL_ASSERT
+#include "stm32_assert.h"
+#else
+#define assert_param(expr) ((void)0U)
+#endif
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (I2C1) || defined (I2C2)
+
+/** @defgroup I2C_LL I2C
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/** @addtogroup I2C_LL_Private_Macros
+ * @{
+ */
+
+#define IS_LL_I2C_PERIPHERAL_MODE(__VALUE__) (((__VALUE__) == LL_I2C_MODE_I2C) || \
+ ((__VALUE__) == LL_I2C_MODE_SMBUS_HOST) || \
+ ((__VALUE__) == LL_I2C_MODE_SMBUS_DEVICE) || \
+ ((__VALUE__) == LL_I2C_MODE_SMBUS_DEVICE_ARP))
+
+#define IS_LL_I2C_CLOCK_SPEED(__VALUE__) (((__VALUE__) > 0U) && ((__VALUE__) <= LL_I2C_MAX_SPEED_FAST))
+
+#define IS_LL_I2C_DUTY_CYCLE(__VALUE__) (((__VALUE__) == LL_I2C_DUTYCYCLE_2) || \
+ ((__VALUE__) == LL_I2C_DUTYCYCLE_16_9))
+
+#define IS_LL_I2C_OWN_ADDRESS1(__VALUE__) ((__VALUE__) <= 0x000003FFU)
+
+#define IS_LL_I2C_TYPE_ACKNOWLEDGE(__VALUE__) (((__VALUE__) == LL_I2C_ACK) || \
+ ((__VALUE__) == LL_I2C_NACK))
+
+#define IS_LL_I2C_OWN_ADDRSIZE(__VALUE__) (((__VALUE__) == LL_I2C_OWNADDRESS1_7BIT) || \
+ ((__VALUE__) == LL_I2C_OWNADDRESS1_10BIT))
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup I2C_LL_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup I2C_LL_EF_Init
+ * @{
+ */
+
+/**
+ * @brief De-initialize the I2C registers to their default reset values.
+ * @param I2Cx I2C Instance.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS I2C registers are de-initialized
+ * - ERROR I2C registers are not de-initialized
+ */
+uint32_t LL_I2C_DeInit(I2C_TypeDef *I2Cx)
+{
+ ErrorStatus status = SUCCESS;
+
+ /* Check the I2C Instance I2Cx */
+ assert_param(IS_I2C_ALL_INSTANCE(I2Cx));
+
+ if (I2Cx == I2C1)
+ {
+ /* Force reset of I2C clock */
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1);
+
+ /* Release reset of I2C clock */
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1);
+ }
+#if defined(I2C2)
+ else if (I2Cx == I2C2)
+ {
+ /* Force reset of I2C clock */
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C2);
+
+ /* Release reset of I2C clock */
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C2);
+
+ }
+#endif /* I2C2 */
+ else
+ {
+ status = ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Initialize the I2C registers according to the specified parameters in I2C_InitStruct.
+ * @param I2Cx I2C Instance.
+ * @param I2C_InitStruct pointer to a @ref LL_I2C_InitTypeDef structure.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS I2C registers are initialized
+ * - ERROR Not applicable
+ */
+uint32_t LL_I2C_Init(I2C_TypeDef *I2Cx, LL_I2C_InitTypeDef *I2C_InitStruct)
+{
+ LL_RCC_ClocksTypeDef rcc_clocks;
+
+ /* Check the I2C Instance I2Cx */
+ assert_param(IS_I2C_ALL_INSTANCE(I2Cx));
+
+ /* Check the I2C parameters from I2C_InitStruct */
+ assert_param(IS_LL_I2C_PERIPHERAL_MODE(I2C_InitStruct->PeripheralMode));
+ assert_param(IS_LL_I2C_CLOCK_SPEED(I2C_InitStruct->ClockSpeed));
+ assert_param(IS_LL_I2C_DUTY_CYCLE(I2C_InitStruct->DutyCycle));
+ assert_param(IS_LL_I2C_OWN_ADDRESS1(I2C_InitStruct->OwnAddress1));
+ assert_param(IS_LL_I2C_TYPE_ACKNOWLEDGE(I2C_InitStruct->TypeAcknowledge));
+ assert_param(IS_LL_I2C_OWN_ADDRSIZE(I2C_InitStruct->OwnAddrSize));
+
+ /* Disable the selected I2Cx Peripheral */
+ LL_I2C_Disable(I2Cx);
+
+ /* Retrieve Clock frequencies */
+ LL_RCC_GetSystemClocksFreq(&rcc_clocks);
+
+ /*---------------------------- I2Cx SCL Clock Speed Configuration ------------
+ * Configure the SCL speed :
+ * - ClockSpeed: I2C_CR2_FREQ[5:0], I2C_TRISE_TRISE[5:0], I2C_CCR_FS,
+ * and I2C_CCR_CCR[11:0] bits
+ * - DutyCycle: I2C_CCR_DUTY[7:0] bits
+ */
+ LL_I2C_ConfigSpeed(I2Cx, rcc_clocks.PCLK1_Frequency, I2C_InitStruct->ClockSpeed, I2C_InitStruct->DutyCycle);
+
+ /*---------------------------- I2Cx OAR1 Configuration -----------------------
+ * Disable, Configure and Enable I2Cx device own address 1 with parameters :
+ * - OwnAddress1: I2C_OAR1_ADD[9:8], I2C_OAR1_ADD[7:1] and I2C_OAR1_ADD0 bits
+ * - OwnAddrSize: I2C_OAR1_ADDMODE bit
+ */
+ LL_I2C_SetOwnAddress1(I2Cx, I2C_InitStruct->OwnAddress1, I2C_InitStruct->OwnAddrSize);
+
+ /*---------------------------- I2Cx MODE Configuration -----------------------
+ * Configure I2Cx peripheral mode with parameter :
+ * - PeripheralMode: I2C_CR1_SMBUS, I2C_CR1_SMBTYPE and I2C_CR1_ENARP bits
+ */
+ LL_I2C_SetMode(I2Cx, I2C_InitStruct->PeripheralMode);
+
+ /* Enable the selected I2Cx Peripheral */
+ LL_I2C_Enable(I2Cx);
+
+ /*---------------------------- I2Cx CR2 Configuration ------------------------
+ * Configure the ACKnowledge or Non ACKnowledge condition
+ * after the address receive match code or next received byte with parameter :
+ * - TypeAcknowledge: I2C_CR2_NACK bit
+ */
+ LL_I2C_AcknowledgeNextData(I2Cx, I2C_InitStruct->TypeAcknowledge);
+
+ return SUCCESS;
+}
+
+/**
+ * @brief Set each @ref LL_I2C_InitTypeDef field to default value.
+ * @param I2C_InitStruct Pointer to a @ref LL_I2C_InitTypeDef structure.
+ * @retval None
+ */
+void LL_I2C_StructInit(LL_I2C_InitTypeDef *I2C_InitStruct)
+{
+ /* Set I2C_InitStruct fields to default values */
+ I2C_InitStruct->PeripheralMode = LL_I2C_MODE_I2C;
+ I2C_InitStruct->ClockSpeed = 5000U;
+ I2C_InitStruct->DutyCycle = LL_I2C_DUTYCYCLE_2;
+ I2C_InitStruct->OwnAddress1 = 0U;
+ I2C_InitStruct->TypeAcknowledge = LL_I2C_NACK;
+ I2C_InitStruct->OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* I2C1 || I2C2 */
+
+/**
+ * @}
+ */
+
+#endif /* USE_FULL_LL_DRIVER */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_pwr.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_pwr.c
new file mode 100644
index 0000000..c60e7a3
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_pwr.c
@@ -0,0 +1,101 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_pwr.c
+ * @author MCD Application Team
+ * @brief PWR LL module driver.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+#if defined(USE_FULL_LL_DRIVER)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_pwr.h"
+#include "stm32f1xx_ll_bus.h"
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined(PWR)
+
+/** @defgroup PWR_LL PWR
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup PWR_LL_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup PWR_LL_EF_Init
+ * @{
+ */
+
+/**
+ * @brief De-initialize the PWR registers to their default reset values.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: PWR registers are de-initialized
+ * - ERROR: not applicable
+ */
+ErrorStatus LL_PWR_DeInit(void)
+{
+ /* Force reset of PWR clock */
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_PWR);
+
+ /* Release reset of PWR clock */
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_PWR);
+
+ return SUCCESS;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* defined(PWR) */
+/**
+ * @}
+ */
+
+#endif /* USE_FULL_LL_DRIVER */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rcc.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rcc.c
new file mode 100644
index 0000000..fcc0ccb
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rcc.c
@@ -0,0 +1,489 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_rcc.c
+ * @author MCD Application Team
+ * @brief RCC LL module driver.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+#if defined(USE_FULL_LL_DRIVER)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_rcc.h"
+#ifdef USE_FULL_ASSERT
+ #include "stm32_assert.h"
+#else
+ #define assert_param(expr) ((void)0U)
+#endif /* USE_FULL_ASSERT */
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined(RCC)
+
+/** @defgroup RCC_LL RCC
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/** @addtogroup RCC_LL_Private_Macros
+ * @{
+ */
+#if defined(RCC_PLLI2S_SUPPORT)
+#define IS_LL_RCC_I2S_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_I2S2_CLKSOURCE) \
+ || ((__VALUE__) == LL_RCC_I2S3_CLKSOURCE))
+#endif /* RCC_PLLI2S_SUPPORT */
+
+#if defined(USB) || defined(USB_OTG_FS)
+#define IS_LL_RCC_USB_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_USB_CLKSOURCE))
+#endif /* USB */
+
+#define IS_LL_RCC_ADC_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_ADC_CLKSOURCE))
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup RCC_LL_Private_Functions RCC Private functions
+ * @{
+ */
+uint32_t RCC_GetSystemClockFreq(void);
+uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency);
+uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency);
+uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency);
+uint32_t RCC_PLL_GetFreqDomain_SYS(void);
+#if defined(RCC_PLLI2S_SUPPORT)
+uint32_t RCC_PLLI2S_GetFreqDomain_I2S(void);
+#endif /* RCC_PLLI2S_SUPPORT */
+#if defined(RCC_PLL2_SUPPORT)
+uint32_t RCC_PLL2_GetFreqClockFreq(void);
+#endif /* RCC_PLL2_SUPPORT */
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup RCC_LL_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup RCC_LL_EF_Init
+ * @{
+ */
+
+/**
+ * @brief Reset the RCC clock configuration to the default reset state.
+ * @note The default reset state of the clock configuration is given below:
+ * - HSI ON and used as system clock source
+ * - HSE PLL, PLL2 & PLL3 are OFF
+ * - AHB, APB1 and APB2 prescaler set to 1.
+ * - CSS, MCO OFF
+ * - All interrupts disabled
+ * @note This function doesn't modify the configuration of the
+ * - Peripheral clocks
+ * - LSI, LSE and RTC clocks
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RCC registers are de-initialized
+ * - ERROR: not applicable
+ */
+ErrorStatus LL_RCC_DeInit(void)
+{
+ /* Set HSION bit */
+ LL_RCC_HSI_Enable();
+
+ /* Wait for HSI READY bit */
+ while(LL_RCC_HSI_IsReady() != 1U)
+ {}
+
+ /* Configure HSI as system clock source */
+ LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
+
+ /* Wait till clock switch is ready */
+ while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI)
+ {}
+
+ /* Reset PLLON bit */
+ CLEAR_BIT(RCC->CR, RCC_CR_PLLON);
+
+ /* Wait for PLL READY bit to be reset */
+ while(LL_RCC_PLL_IsReady() != 0U)
+ {}
+
+ /* Reset CFGR register */
+ LL_RCC_WriteReg(CFGR, 0x00000000U);
+
+ /* Reset HSEON, HSEBYP & CSSON bits */
+ CLEAR_BIT(RCC->CR, (RCC_CR_CSSON | RCC_CR_HSEON | RCC_CR_HSEBYP));
+
+#if defined(RCC_CR_PLL2ON)
+ /* Reset PLL2ON bit */
+ CLEAR_BIT(RCC->CR, RCC_CR_PLL2ON);
+#endif /* RCC_CR_PLL2ON */
+
+#if defined(RCC_CR_PLL3ON)
+ /* Reset PLL3ON bit */
+ CLEAR_BIT(RCC->CR, RCC_CR_PLL3ON);
+#endif /* RCC_CR_PLL3ON */
+
+ /* Set HSITRIM bits to the reset value */
+ LL_RCC_HSI_SetCalibTrimming(0x10U);
+
+#if defined(RCC_CFGR2_PREDIV1)
+ /* Reset CFGR2 register */
+ LL_RCC_WriteReg(CFGR2, 0x00000000U);
+#endif /* RCC_CFGR2_PREDIV1 */
+
+ /* Disable all interrupts */
+ LL_RCC_WriteReg(CIR, 0x00000000U);
+
+ /* Clear reset flags */
+ LL_RCC_ClearResetFlags();
+
+ return SUCCESS;
+}
+
+/**
+ * @}
+ */
+
+/** @addtogroup RCC_LL_EF_Get_Freq
+ * @brief Return the frequencies of different on chip clocks; System, AHB, APB1 and APB2 buses clocks
+ * and different peripheral clocks available on the device.
+ * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(**)
+ * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(***)
+ * @note If SYSCLK source is PLL, function returns values based on
+ * HSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors.
+ * @note (**) HSI_VALUE is a defined constant but the real value may vary
+ * depending on the variations in voltage and temperature.
+ * @note (***) HSE_VALUE is a defined constant, user has to ensure that
+ * HSE_VALUE is same as the real frequency of the crystal used.
+ * Otherwise, this function may have wrong result.
+ * @note The result of this function could be incorrect when using fractional
+ * value for HSE crystal.
+ * @note This function can be used by the user application to compute the
+ * baud-rate for the communication peripherals or configure other parameters.
+ * @{
+ */
+
+/**
+ * @brief Return the frequencies of different on chip clocks; System, AHB, APB1 and APB2 buses clocks
+ * @note Each time SYSCLK, HCLK, PCLK1 and/or PCLK2 clock changes, this function
+ * must be called to update structure fields. Otherwise, any
+ * configuration based on this function will be incorrect.
+ * @param RCC_Clocks pointer to a @ref LL_RCC_ClocksTypeDef structure which will hold the clocks frequencies
+ * @retval None
+ */
+void LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef *RCC_Clocks)
+{
+ /* Get SYSCLK frequency */
+ RCC_Clocks->SYSCLK_Frequency = RCC_GetSystemClockFreq();
+
+ /* HCLK clock frequency */
+ RCC_Clocks->HCLK_Frequency = RCC_GetHCLKClockFreq(RCC_Clocks->SYSCLK_Frequency);
+
+ /* PCLK1 clock frequency */
+ RCC_Clocks->PCLK1_Frequency = RCC_GetPCLK1ClockFreq(RCC_Clocks->HCLK_Frequency);
+
+ /* PCLK2 clock frequency */
+ RCC_Clocks->PCLK2_Frequency = RCC_GetPCLK2ClockFreq(RCC_Clocks->HCLK_Frequency);
+}
+
+#if defined(RCC_CFGR2_I2S2SRC)
+/**
+ * @brief Return I2Sx clock frequency
+ * @param I2SxSource This parameter can be one of the following values:
+ * @arg @ref LL_RCC_I2S2_CLKSOURCE
+ * @arg @ref LL_RCC_I2S3_CLKSOURCE
+ * @retval I2S clock frequency (in Hz)
+ */
+uint32_t LL_RCC_GetI2SClockFreq(uint32_t I2SxSource)
+{
+ uint32_t i2s_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
+
+ /* Check parameter */
+ assert_param(IS_LL_RCC_I2S_CLKSOURCE(I2SxSource));
+
+ /* I2S1CLK clock frequency */
+ switch (LL_RCC_GetI2SClockSource(I2SxSource))
+ {
+ case LL_RCC_I2S2_CLKSOURCE_SYSCLK: /*!< System clock selected as I2S clock source */
+ case LL_RCC_I2S3_CLKSOURCE_SYSCLK:
+ i2s_frequency = RCC_GetSystemClockFreq();
+ break;
+
+ case LL_RCC_I2S2_CLKSOURCE_PLLI2S_VCO: /*!< PLLI2S oscillator clock selected as I2S clock source */
+ case LL_RCC_I2S3_CLKSOURCE_PLLI2S_VCO:
+ default:
+ i2s_frequency = RCC_PLLI2S_GetFreqDomain_I2S() * 2U;
+ break;
+ }
+
+ return i2s_frequency;
+}
+#endif /* RCC_CFGR2_I2S2SRC */
+
+#if defined(USB) || defined(USB_OTG_FS)
+/**
+ * @brief Return USBx clock frequency
+ * @param USBxSource This parameter can be one of the following values:
+ * @arg @ref LL_RCC_USB_CLKSOURCE
+ * @retval USB clock frequency (in Hz)
+ * @arg @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI), HSE or PLL is not ready
+ */
+uint32_t LL_RCC_GetUSBClockFreq(uint32_t USBxSource)
+{
+ uint32_t usb_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
+
+ /* Check parameter */
+ assert_param(IS_LL_RCC_USB_CLKSOURCE(USBxSource));
+
+ /* USBCLK clock frequency */
+ switch (LL_RCC_GetUSBClockSource(USBxSource))
+ {
+#if defined(RCC_CFGR_USBPRE)
+ case LL_RCC_USB_CLKSOURCE_PLL: /* PLL clock used as USB clock source */
+ if (LL_RCC_PLL_IsReady())
+ {
+ usb_frequency = RCC_PLL_GetFreqDomain_SYS();
+ }
+ break;
+
+ case LL_RCC_USB_CLKSOURCE_PLL_DIV_1_5: /* PLL clock divided by 1.5 used as USB clock source */
+ default:
+ if (LL_RCC_PLL_IsReady())
+ {
+ usb_frequency = (RCC_PLL_GetFreqDomain_SYS() * 3U) / 2U;
+ }
+ break;
+#endif /* RCC_CFGR_USBPRE */
+#if defined(RCC_CFGR_OTGFSPRE)
+ /* USBCLK = PLLVCO/2
+ = (2 x PLLCLK) / 2
+ = PLLCLK */
+ case LL_RCC_USB_CLKSOURCE_PLL_DIV_2: /* PLL clock used as USB clock source */
+ if (LL_RCC_PLL_IsReady())
+ {
+ usb_frequency = RCC_PLL_GetFreqDomain_SYS();
+ }
+ break;
+
+ /* USBCLK = PLLVCO/3
+ = (2 x PLLCLK) / 3 */
+ case LL_RCC_USB_CLKSOURCE_PLL_DIV_3: /* PLL clock divided by 3 used as USB clock source */
+ default:
+ if (LL_RCC_PLL_IsReady())
+ {
+ usb_frequency = (RCC_PLL_GetFreqDomain_SYS() * 2U) / 3U;
+ }
+ break;
+#endif /* RCC_CFGR_OTGFSPRE */
+ }
+
+ return usb_frequency;
+}
+#endif /* USB */
+
+/**
+ * @brief Return ADCx clock frequency
+ * @param ADCxSource This parameter can be one of the following values:
+ * @arg @ref LL_RCC_ADC_CLKSOURCE
+ * @retval ADC clock frequency (in Hz)
+ */
+uint32_t LL_RCC_GetADCClockFreq(uint32_t ADCxSource)
+{
+ uint32_t adc_prescaler = 0U;
+ uint32_t adc_frequency = 0U;
+
+ /* Check parameter */
+ assert_param(IS_LL_RCC_ADC_CLKSOURCE(ADCxSource));
+
+ /* Get ADC prescaler */
+ adc_prescaler = LL_RCC_GetADCClockSource(ADCxSource);
+
+ /* ADC frequency = PCLK2 frequency / ADC prescaler (2, 4, 6 or 8) */
+ adc_frequency = RCC_GetPCLK2ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()))
+ / (((adc_prescaler >> POSITION_VAL(ADCxSource)) + 1U) * 2U);
+
+ return adc_frequency;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup RCC_LL_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Return SYSTEM clock frequency
+ * @retval SYSTEM clock frequency (in Hz)
+ */
+uint32_t RCC_GetSystemClockFreq(void)
+{
+ uint32_t frequency = 0U;
+
+ /* Get SYSCLK source -------------------------------------------------------*/
+ switch (LL_RCC_GetSysClkSource())
+ {
+ case LL_RCC_SYS_CLKSOURCE_STATUS_HSI: /* HSI used as system clock source */
+ frequency = HSI_VALUE;
+ break;
+
+ case LL_RCC_SYS_CLKSOURCE_STATUS_HSE: /* HSE used as system clock source */
+ frequency = HSE_VALUE;
+ break;
+
+ case LL_RCC_SYS_CLKSOURCE_STATUS_PLL: /* PLL used as system clock source */
+ frequency = RCC_PLL_GetFreqDomain_SYS();
+ break;
+
+ default:
+ frequency = HSI_VALUE;
+ break;
+ }
+
+ return frequency;
+}
+
+/**
+ * @brief Return HCLK clock frequency
+ * @param SYSCLK_Frequency SYSCLK clock frequency
+ * @retval HCLK clock frequency (in Hz)
+ */
+uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency)
+{
+ /* HCLK clock frequency */
+ return __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, LL_RCC_GetAHBPrescaler());
+}
+
+/**
+ * @brief Return PCLK1 clock frequency
+ * @param HCLK_Frequency HCLK clock frequency
+ * @retval PCLK1 clock frequency (in Hz)
+ */
+uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency)
+{
+ /* PCLK1 clock frequency */
+ return __LL_RCC_CALC_PCLK1_FREQ(HCLK_Frequency, LL_RCC_GetAPB1Prescaler());
+}
+
+/**
+ * @brief Return PCLK2 clock frequency
+ * @param HCLK_Frequency HCLK clock frequency
+ * @retval PCLK2 clock frequency (in Hz)
+ */
+uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency)
+{
+ /* PCLK2 clock frequency */
+ return __LL_RCC_CALC_PCLK2_FREQ(HCLK_Frequency, LL_RCC_GetAPB2Prescaler());
+}
+
+/**
+ * @brief Return PLL clock frequency used for system domain
+ * @retval PLL clock frequency (in Hz)
+ */
+uint32_t RCC_PLL_GetFreqDomain_SYS(void)
+{
+ uint32_t pllinputfreq = 0U, pllsource = 0U;
+
+ /* PLL_VCO = (HSE_VALUE, HSI_VALUE or PLL2 / PLL Predivider) * PLL Multiplicator */
+
+ /* Get PLL source */
+ pllsource = LL_RCC_PLL_GetMainSource();
+
+ switch (pllsource)
+ {
+ case LL_RCC_PLLSOURCE_HSI_DIV_2: /* HSI used as PLL clock source */
+ pllinputfreq = HSI_VALUE / 2U;
+ break;
+
+ case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
+ pllinputfreq = HSE_VALUE / (LL_RCC_PLL_GetPrediv() + 1U);
+ break;
+
+#if defined(RCC_PLL2_SUPPORT)
+ case LL_RCC_PLLSOURCE_PLL2: /* PLL2 used as PLL clock source */
+ pllinputfreq = RCC_PLL2_GetFreqClockFreq() / (LL_RCC_PLL_GetPrediv() + 1U);
+ break;
+#endif /* RCC_PLL2_SUPPORT */
+
+ default:
+ pllinputfreq = HSI_VALUE / 2U;
+ break;
+ }
+ return __LL_RCC_CALC_PLLCLK_FREQ(pllinputfreq, LL_RCC_PLL_GetMultiplicator());
+}
+
+#if defined(RCC_PLL2_SUPPORT)
+/**
+ * @brief Return PLL clock frequency used for system domain
+ * @retval PLL clock frequency (in Hz)
+ */
+uint32_t RCC_PLL2_GetFreqClockFreq(void)
+{
+ return __LL_RCC_CALC_PLL2CLK_FREQ(HSE_VALUE, LL_RCC_PLL2_GetMultiplicator(), LL_RCC_HSE_GetPrediv2());
+}
+#endif /* RCC_PLL2_SUPPORT */
+
+#if defined(RCC_PLLI2S_SUPPORT)
+/**
+ * @brief Return PLL clock frequency used for system domain
+ * @retval PLL clock frequency (in Hz)
+ */
+uint32_t RCC_PLLI2S_GetFreqDomain_I2S(void)
+{
+ return __LL_RCC_CALC_PLLI2SCLK_FREQ(HSE_VALUE, LL_RCC_PLLI2S_GetMultiplicator(), LL_RCC_HSE_GetPrediv2());
+}
+#endif /* RCC_PLLI2S_SUPPORT */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* defined(RCC) */
+
+/**
+ * @}
+ */
+
+#endif /* USE_FULL_LL_DRIVER */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rtc.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rtc.c
new file mode 100644
index 0000000..8fad26a
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rtc.c
@@ -0,0 +1,556 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_rtc.c
+ * @author MCD Application Team
+ * @brief RTC LL module driver.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+#if defined(USE_FULL_LL_DRIVER)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_rtc.h"
+#include "stm32f1xx_ll_cortex.h"
+#ifdef USE_FULL_ASSERT
+#include "stm32_assert.h"
+#else
+#define assert_param(expr) ((void)0U)
+#endif
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined(RTC)
+
+/** @addtogroup RTC_LL
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @addtogroup RTC_LL_Private_Constants
+ * @{
+ */
+/* Default values used for prescaler */
+#define RTC_ASYNCH_PRESC_DEFAULT 0x00007FFFU
+
+/* Values used for timeout */
+#define RTC_INITMODE_TIMEOUT 1000U /* 1s when tick set to 1ms */
+#define RTC_SYNCHRO_TIMEOUT 1000U /* 1s when tick set to 1ms */
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @addtogroup RTC_LL_Private_Macros
+ * @{
+ */
+
+#define IS_LL_RTC_ASYNCH_PREDIV(__VALUE__) ((__VALUE__) <= 0xFFFFFU)
+
+#define IS_LL_RTC_FORMAT(__VALUE__) (((__VALUE__) == LL_RTC_FORMAT_BIN) \
+ || ((__VALUE__) == LL_RTC_FORMAT_BCD))
+
+#define IS_LL_RTC_HOUR24(__HOUR__) ((__HOUR__) <= 23U)
+#define IS_LL_RTC_MINUTES(__MINUTES__) ((__MINUTES__) <= 59U)
+#define IS_LL_RTC_SECONDS(__SECONDS__) ((__SECONDS__) <= 59U)
+#define IS_LL_RTC_CALIB_OUTPUT(__OUTPUT__) (((__OUTPUT__) == LL_RTC_CALIB_OUTPUT_NONE) || \
+ ((__OUTPUT__) == LL_RTC_CALIB_OUTPUT_RTCCLOCK) || \
+ ((__OUTPUT__) == LL_RTC_CALIB_OUTPUT_ALARM) || \
+ ((__OUTPUT__) == LL_RTC_CALIB_OUTPUT_SECOND))
+/**
+ * @}
+ */
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup RTC_LL_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup RTC_LL_EF_Init
+ * @{
+ */
+
+/**
+ * @brief De-Initializes the RTC registers to their default reset values.
+ * @note This function doesn't reset the RTC Clock source and RTC Backup Data
+ * registers.
+ * @param RTCx RTC Instance
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC registers are de-initialized
+ * - ERROR: RTC registers are not de-initialized
+ */
+ErrorStatus LL_RTC_DeInit(RTC_TypeDef *RTCx)
+{
+ ErrorStatus status = ERROR;
+
+ /* Check the parameter */
+ assert_param(IS_RTC_ALL_INSTANCE(RTCx));
+
+ /* Disable the write protection for RTC registers */
+ LL_RTC_DisableWriteProtection(RTCx);
+
+ /* Set Initialization mode */
+ if (LL_RTC_EnterInitMode(RTCx) != ERROR)
+ {
+ LL_RTC_WriteReg(RTCx,CNTL, 0x0000);
+ LL_RTC_WriteReg(RTCx,CNTH, 0x0000);
+ LL_RTC_WriteReg(RTCx,PRLH, 0x0000);
+ LL_RTC_WriteReg(RTCx,PRLL, 0x8000);
+ LL_RTC_WriteReg(RTCx,CRH, 0x0000);
+ LL_RTC_WriteReg(RTCx,CRL, 0x0020);
+
+ /* Reset Tamper and alternate functions configuration register */
+ LL_RTC_WriteReg(BKP,RTCCR, 0x00000000U);
+ LL_RTC_WriteReg(BKP,CR, 0x00000000U);
+ LL_RTC_WriteReg(BKP,CSR, 0x00000000U);
+
+ /* Exit Initialization Mode */
+ if(LL_RTC_ExitInitMode(RTCx) == ERROR)
+ {
+ return ERROR;
+ }
+
+ /* Wait till the RTC RSF flag is set */
+ status = LL_RTC_WaitForSynchro(RTCx);
+
+ /* Clear RSF Flag */
+ LL_RTC_ClearFlag_RS(RTCx);
+ }
+
+ /* Enable the write protection for RTC registers */
+ LL_RTC_EnableWriteProtection(RTCx);
+
+ return status;
+}
+
+/**
+ * @brief Initializes the RTC registers according to the specified parameters
+ * in RTC_InitStruct.
+ * @param RTCx RTC Instance
+ * @param RTC_InitStruct pointer to a @ref LL_RTC_InitTypeDef structure that contains
+ * the configuration information for the RTC peripheral.
+ * @note The RTC Prescaler register is write protected and can be written in
+ * initialization mode only.
+ * @note the user should call LL_RTC_StructInit() or the structure of Prescaler
+ * need to be initialized before RTC init()
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC registers are initialized
+ * - ERROR: RTC registers are not initialized
+ */
+ErrorStatus LL_RTC_Init(RTC_TypeDef *RTCx, LL_RTC_InitTypeDef *RTC_InitStruct)
+{
+ ErrorStatus status = ERROR;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_ALL_INSTANCE(RTCx));
+ assert_param(IS_LL_RTC_ASYNCH_PREDIV(RTC_InitStruct->AsynchPrescaler));
+ assert_param(IS_LL_RTC_CALIB_OUTPUT(RTC_InitStruct->OutPutSource));
+ /* Waiting for synchro */
+ if(LL_RTC_WaitForSynchro(RTCx) != ERROR)
+ {
+ /* Set Initialization mode */
+ if (LL_RTC_EnterInitMode(RTCx) != ERROR)
+ {
+ /* Clear Flag Bits */
+ LL_RTC_ClearFlag_ALR(RTCx);
+ LL_RTC_ClearFlag_OW(RTCx);
+ LL_RTC_ClearFlag_SEC(RTCx);
+
+ if(RTC_InitStruct->OutPutSource != LL_RTC_CALIB_OUTPUT_NONE)
+ {
+ /* Disable the selected Tamper Pin */
+ LL_RTC_TAMPER_Disable(BKP);
+ }
+ /* Set the signal which will be routed to RTC Tamper Pin */
+ LL_RTC_SetOutputSource(BKP, RTC_InitStruct->OutPutSource);
+
+ /* Configure Synchronous and Asynchronous prescaler factor */
+ LL_RTC_SetAsynchPrescaler(RTCx, RTC_InitStruct->AsynchPrescaler);
+
+ /* Exit Initialization Mode */
+ LL_RTC_ExitInitMode(RTCx);
+
+ status = SUCCESS;
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief Set each @ref LL_RTC_InitTypeDef field to default value.
+ * @param RTC_InitStruct pointer to a @ref LL_RTC_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void LL_RTC_StructInit(LL_RTC_InitTypeDef *RTC_InitStruct)
+{
+ /* Set RTC_InitStruct fields to default values */
+ RTC_InitStruct->AsynchPrescaler = RTC_ASYNCH_PRESC_DEFAULT;
+ RTC_InitStruct->OutPutSource = LL_RTC_CALIB_OUTPUT_NONE;
+}
+
+/**
+ * @brief Set the RTC current time.
+ * @param RTCx RTC Instance
+ * @param RTC_Format This parameter can be one of the following values:
+ * @arg @ref LL_RTC_FORMAT_BIN
+ * @arg @ref LL_RTC_FORMAT_BCD
+ * @param RTC_TimeStruct pointer to a RTC_TimeTypeDef structure that contains
+ * the time configuration information for the RTC.
+ * @note The user should call LL_RTC_TIME_StructInit() or the structure
+ * of time need to be initialized before time init()
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC Time register is configured
+ * - ERROR: RTC Time register is not configured
+ */
+ErrorStatus LL_RTC_TIME_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_TimeTypeDef *RTC_TimeStruct)
+{
+ ErrorStatus status = ERROR;
+ uint32_t counter_time = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_ALL_INSTANCE(RTCx));
+ assert_param(IS_LL_RTC_FORMAT(RTC_Format));
+
+ if (RTC_Format == LL_RTC_FORMAT_BIN)
+ {
+ assert_param(IS_LL_RTC_HOUR24(RTC_TimeStruct->Hours));
+ assert_param(IS_LL_RTC_MINUTES(RTC_TimeStruct->Minutes));
+ assert_param(IS_LL_RTC_SECONDS(RTC_TimeStruct->Seconds));
+ }
+ else
+ {
+ assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Hours)));
+ assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Minutes)));
+ assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Seconds)));
+ }
+
+ /* Enter Initialization mode */
+ if (LL_RTC_EnterInitMode(RTCx) != ERROR)
+ {
+ /* Check the input parameters format */
+ if (RTC_Format != LL_RTC_FORMAT_BIN)
+ {
+ counter_time = (uint32_t)(((uint32_t)RTC_TimeStruct->Hours * 3600U) + \
+ ((uint32_t)RTC_TimeStruct->Minutes * 60U) + \
+ ((uint32_t)RTC_TimeStruct->Seconds));
+ LL_RTC_TIME_Set(RTCx, counter_time);
+ }
+ else
+ {
+ counter_time = (((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Hours)) * 3600U) + \
+ ((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Minutes)) * 60U) + \
+ ((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Seconds))));
+ LL_RTC_TIME_Set(RTCx, counter_time);
+ }
+ status = SUCCESS;
+ }
+ /* Exit Initialization mode */
+ LL_RTC_ExitInitMode(RTCx);
+
+ return status;
+}
+
+/**
+ * @brief Set each @ref LL_RTC_TimeTypeDef field to default value (Time = 00h:00min:00sec).
+ * @param RTC_TimeStruct pointer to a @ref LL_RTC_TimeTypeDef structure which will be initialized.
+ * @retval None
+ */
+void LL_RTC_TIME_StructInit(LL_RTC_TimeTypeDef *RTC_TimeStruct)
+{
+ /* Time = 00h:00min:00sec */
+ RTC_TimeStruct->Hours = 0U;
+ RTC_TimeStruct->Minutes = 0U;
+ RTC_TimeStruct->Seconds = 0U;
+}
+
+/**
+ * @brief Set the RTC Alarm.
+ * @param RTCx RTC Instance
+ * @param RTC_Format This parameter can be one of the following values:
+ * @arg @ref LL_RTC_FORMAT_BIN
+ * @arg @ref LL_RTC_FORMAT_BCD
+ * @param RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure that
+ * contains the alarm configuration parameters.
+ * @note the user should call LL_RTC_ALARM_StructInit() or the structure
+ * of Alarm need to be initialized before Alarm init()
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: ALARM registers are configured
+ * - ERROR: ALARM registers are not configured
+ */
+ErrorStatus LL_RTC_ALARM_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_AlarmTypeDef *RTC_AlarmStruct)
+{
+ ErrorStatus status = ERROR;
+ uint32_t counter_alarm = 0U;
+ /* Check the parameters */
+ assert_param(IS_RTC_ALL_INSTANCE(RTCx));
+ assert_param(IS_LL_RTC_FORMAT(RTC_Format));
+
+ if (RTC_Format == LL_RTC_FORMAT_BIN)
+ {
+ assert_param(IS_LL_RTC_HOUR24(RTC_AlarmStruct->AlarmTime.Hours));
+ assert_param(IS_LL_RTC_MINUTES(RTC_AlarmStruct->AlarmTime.Minutes));
+ assert_param(IS_LL_RTC_SECONDS(RTC_AlarmStruct->AlarmTime.Seconds));
+ }
+ else
+ {
+ assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours)));
+ assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Minutes)));
+ assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Seconds)));
+ }
+
+ /* Enter Initialization mode */
+ if (LL_RTC_EnterInitMode(RTCx) != ERROR)
+ {
+ /* Check the input parameters format */
+ if (RTC_Format != LL_RTC_FORMAT_BIN)
+ {
+ counter_alarm = (uint32_t)(((uint32_t)RTC_AlarmStruct->AlarmTime.Hours * 3600U) + \
+ ((uint32_t)RTC_AlarmStruct->AlarmTime.Minutes * 60U) + \
+ ((uint32_t)RTC_AlarmStruct->AlarmTime.Seconds));
+ LL_RTC_ALARM_Set(RTCx, counter_alarm);
+ }
+ else
+ {
+ counter_alarm = (((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours)) * 3600U) + \
+ ((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Minutes)) * 60U) + \
+ ((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Seconds))));
+ LL_RTC_ALARM_Set(RTCx, counter_alarm);
+ }
+ status = SUCCESS;
+ }
+ /* Exit Initialization mode */
+ LL_RTC_ExitInitMode(RTCx);
+
+ return status;
+}
+
+/**
+ * @brief Set each @ref LL_RTC_AlarmTypeDef of ALARM field to default value (Time = 00h:00mn:00sec /
+ * Day = 1st day of the month/Mask = all fields are masked).
+ * @param RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure which will be initialized.
+ * @retval None
+ */
+void LL_RTC_ALARM_StructInit(LL_RTC_AlarmTypeDef *RTC_AlarmStruct)
+{
+ /* Alarm Time Settings : Time = 00h:00mn:00sec */
+ RTC_AlarmStruct->AlarmTime.Hours = 0U;
+ RTC_AlarmStruct->AlarmTime.Minutes = 0U;
+ RTC_AlarmStruct->AlarmTime.Seconds = 0U;
+}
+
+/**
+ * @brief Enters the RTC Initialization mode.
+ * @param RTCx RTC Instance
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC is in Init mode
+ * - ERROR: RTC is not in Init mode
+ */
+ErrorStatus LL_RTC_EnterInitMode(RTC_TypeDef *RTCx)
+{
+ __IO uint32_t timeout = RTC_INITMODE_TIMEOUT;
+ ErrorStatus status = SUCCESS;
+ uint32_t tmp = 0U;
+
+ /* Check the parameter */
+ assert_param(IS_RTC_ALL_INSTANCE(RTCx));
+
+ /* Wait till RTC is in INIT state and if Time out is reached exit */
+ tmp = LL_RTC_IsActiveFlag_RTOF(RTCx);
+ while ((timeout != 0U) && (tmp != 1U))
+ {
+ if (LL_SYSTICK_IsActiveCounterFlag() == 1U)
+ {
+ timeout --;
+ }
+ tmp = LL_RTC_IsActiveFlag_RTOF(RTCx);
+ if (timeout == 0U)
+ {
+ status = ERROR;
+ }
+ }
+
+ /* Disable the write protection for RTC registers */
+ LL_RTC_DisableWriteProtection(RTCx);
+
+ return status;
+}
+
+/**
+ * @brief Exit the RTC Initialization mode.
+ * @note When the initialization sequence is complete, the calendar restarts
+ * counting after 4 RTCCLK cycles.
+ * @param RTCx RTC Instance
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC exited from in Init mode
+ * - ERROR: Not applicable
+ */
+ErrorStatus LL_RTC_ExitInitMode(RTC_TypeDef *RTCx)
+{
+ __IO uint32_t timeout = RTC_INITMODE_TIMEOUT;
+ ErrorStatus status = SUCCESS;
+ uint32_t tmp = 0U;
+
+ /* Check the parameter */
+ assert_param(IS_RTC_ALL_INSTANCE(RTCx));
+
+ /* Disable initialization mode */
+ LL_RTC_EnableWriteProtection(RTCx);
+
+ /* Wait till RTC is in INIT state and if Time out is reached exit */
+ tmp = LL_RTC_IsActiveFlag_RTOF(RTCx);
+ while ((timeout != 0U) && (tmp != 1U))
+ {
+ if (LL_SYSTICK_IsActiveCounterFlag() == 1U)
+ {
+ timeout --;
+ }
+ tmp = LL_RTC_IsActiveFlag_RTOF(RTCx);
+ if (timeout == 0U)
+ {
+ status = ERROR;
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief Set the Time Counter
+ * @param RTCx RTC Instance
+ * @param TimeCounter this value can be from 0 to 0xFFFFFFFF
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC Counter register configured
+ * - ERROR: Not applicable
+ */
+ErrorStatus LL_RTC_TIME_SetCounter(RTC_TypeDef *RTCx, uint32_t TimeCounter)
+{
+ ErrorStatus status = ERROR;
+ /* Check the parameter */
+ assert_param(IS_RTC_ALL_INSTANCE(RTCx));
+
+ /* Enter Initialization mode */
+ if (LL_RTC_EnterInitMode(RTCx) != ERROR)
+ {
+ LL_RTC_TIME_Set(RTCx, TimeCounter);
+ status = SUCCESS;
+ }
+ /* Exit Initialization mode */
+ LL_RTC_ExitInitMode(RTCx);
+
+ return status;
+}
+
+/**
+ * @brief Set Alarm Counter.
+ * @param RTCx RTC Instance
+ * @param AlarmCounter this value can be from 0 to 0xFFFFFFFF
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC exited from in Init mode
+ * - ERROR: Not applicable
+ */
+ErrorStatus LL_RTC_ALARM_SetCounter(RTC_TypeDef *RTCx, uint32_t AlarmCounter)
+{
+ ErrorStatus status = ERROR;
+ /* Check the parameter */
+ assert_param(IS_RTC_ALL_INSTANCE(RTCx));
+
+ /* Enter Initialization mode */
+ if (LL_RTC_EnterInitMode(RTCx) != ERROR)
+ {
+ LL_RTC_ALARM_Set(RTCx, AlarmCounter);
+ status = SUCCESS;
+ }
+ /* Exit Initialization mode */
+ LL_RTC_ExitInitMode(RTCx);
+
+ return status;
+}
+
+/**
+ * @brief Waits until the RTC registers are synchronized with RTC APB clock.
+ * @note The RTC Resynchronization mode is write protected, use the
+ * @ref LL_RTC_DisableWriteProtection before calling this function.
+ * @param RTCx RTC Instance
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC registers are synchronised
+ * - ERROR: RTC registers are not synchronised
+ */
+ErrorStatus LL_RTC_WaitForSynchro(RTC_TypeDef *RTCx)
+{
+ __IO uint32_t timeout = RTC_SYNCHRO_TIMEOUT;
+ ErrorStatus status = SUCCESS;
+ uint32_t tmp = 0U;
+
+ /* Check the parameter */
+ assert_param(IS_RTC_ALL_INSTANCE(RTCx));
+
+ /* Clear RSF flag */
+ LL_RTC_ClearFlag_RS(RTCx);
+
+ /* Wait the registers to be synchronised */
+ tmp = LL_RTC_IsActiveFlag_RS(RTCx);
+ while ((timeout != 0U) && (tmp != 0U))
+ {
+ if (LL_SYSTICK_IsActiveCounterFlag() == 1U)
+ {
+ timeout--;
+ }
+ tmp = LL_RTC_IsActiveFlag_RS(RTCx);
+ if (timeout == 0U)
+ {
+ status = ERROR;
+ }
+ }
+
+ return (status);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* defined(RTC) */
+
+/**
+ * @}
+ */
+
+#endif /* USE_FULL_LL_DRIVER */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_sdmmc.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_sdmmc.c
new file mode 100644
index 0000000..567bf2d
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_sdmmc.c
@@ -0,0 +1,1500 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_sdmmc.c
+ * @author MCD Application Team
+ * @brief SDIO Low Layer HAL module driver.
+ *
+ * This file provides firmware functions to manage the following
+ * functionalities of the SDIO peripheral:
+ * + Initialization/de-initialization functions
+ * + I/O operation functions
+ * + Peripheral Control functions
+ * + Peripheral State functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### SDMMC peripheral features #####
+ ==============================================================================
+ [..] The SD/SDMMC MMC card host interface (SDMMC) provides an interface between the APB2
+ peripheral bus and MultiMedia cards (MMCs), SD memory cards, SDMMC cards and CE-ATA
+ devices.
+
+ [..] The SDMMC features include the following:
+ (+) Full compliance with MultiMedia Card System Specification Version 4.2. Card support
+ for three different databus modes: 1-bit (default), 4-bit and 8-bit
+ (+) Full compatibility with previous versions of MultiMedia Cards (forward compatibility)
+ (+) Full compliance with SD Memory Card Specifications Version 2.0
+ (+) Full compliance with SD I/O Card Specification Version 2.0: card support for two
+ different data bus modes: 1-bit (default) and 4-bit
+ (+) Full support of the CE-ATA features (full compliance with CE-ATA digital protocol
+ Rev1.1)
+ (+) Data transfer up to 48 MHz for the 8 bit mode
+ (+) Data and command output enable signals to control external bidirectional drivers.
+
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ This driver is a considered as a driver of service for external devices drivers
+ that interfaces with the SDMMC peripheral.
+ According to the device used (SD card/ MMC card / SDMMC card ...), a set of APIs
+ is used in the device's driver to perform SDMMC operations and functionalities.
+
+ This driver is almost transparent for the final user, it is only used to implement other
+ functionalities of the external device.
+
+ [..]
+ (+) The SDIO peripheral uses two clock signals:
+ (++) SDIO adapter clock (SDIOCLK = HCLK)
+ (++) AHB bus clock (HCLK/2)
+
+ -@@- PCLK2 and SDMMC_CK clock frequencies must respect the following condition:
+ Frequency(PCLK2) >= (3 / 8 x Frequency(SDMMC_CK))
+
+ (+) Enable/Disable peripheral clock using RCC peripheral macros related to SDMMC
+ peripheral.
+
+ (+) Enable the Power ON State using the SDIO_PowerState_ON(SDIOx)
+ function and disable it using the function SDIO_PowerState_OFF(SDIOx).
+
+ (+) Enable/Disable the clock using the __SDIO_ENABLE()/__SDIO_DISABLE() macros.
+
+ (+) Enable/Disable the peripheral interrupts using the macros __SDIO_ENABLE_IT(hsdio, IT)
+ and __SDIO_DISABLE_IT(hsdio, IT) if you need to use interrupt mode.
+
+ (+) When using the DMA mode
+ (++) Configure the DMA in the MSP layer of the external device
+ (++) Active the needed channel Request
+ (++) Enable the DMA using __SDIO_DMA_ENABLE() macro or Disable it using the macro
+ __SDIO_DMA_DISABLE().
+
+ (+) To control the CPSM (Command Path State Machine) and send
+ commands to the card use the SDIO_SendCommand(),
+ SDIO_GetCommandResponse() and SDIO_GetResponse() functions. First, user has
+ to fill the command structure (pointer to SDIO_CmdInitTypeDef) according
+ to the selected command to be sent.
+ The parameters that should be filled are:
+ (++) Command Argument
+ (++) Command Index
+ (++) Command Response type
+ (++) Command Wait
+ (++) CPSM Status (Enable or Disable).
+
+ -@@- To check if the command is well received, read the SDIO_CMDRESP
+ register using the SDIO_GetCommandResponse().
+ The SDMMC responses registers (SDIO_RESP1 to SDIO_RESP2), use the
+ SDIO_GetResponse() function.
+
+ (+) To control the DPSM (Data Path State Machine) and send/receive
+ data to/from the card use the SDIO_ConfigData(), SDIO_GetDataCounter(),
+ SDIO_ReadFIFO(), SDIO_WriteFIFO() and SDIO_GetFIFOCount() functions.
+
+ *** Read Operations ***
+ =======================
+ [..]
+ (#) First, user has to fill the data structure (pointer to
+ SDIO_DataInitTypeDef) according to the selected data type to be received.
+ The parameters that should be filled are:
+ (++) Data TimeOut
+ (++) Data Length
+ (++) Data Block size
+ (++) Data Transfer direction: should be from card (To SDMMC)
+ (++) Data Transfer mode
+ (++) DPSM Status (Enable or Disable)
+
+ (#) Configure the SDMMC resources to receive the data from the card
+ according to selected transfer mode (Refer to Step 8, 9 and 10).
+
+ (#) Send the selected Read command (refer to step 11).
+
+ (#) Use the SDIO flags/interrupts to check the transfer status.
+
+ *** Write Operations ***
+ ========================
+ [..]
+ (#) First, user has to fill the data structure (pointer to
+ SDIO_DataInitTypeDef) according to the selected data type to be received.
+ The parameters that should be filled are:
+ (++) Data TimeOut
+ (++) Data Length
+ (++) Data Block size
+ (++) Data Transfer direction: should be to card (To CARD)
+ (++) Data Transfer mode
+ (++) DPSM Status (Enable or Disable)
+
+ (#) Configure the SDMMC resources to send the data to the card according to
+ selected transfer mode.
+
+ (#) Send the selected Write command.
+
+ (#) Use the SDIO flags/interrupts to check the transfer status.
+
+ *** Command management operations ***
+ =====================================
+ [..]
+ (#) The commands used for Read/Write//Erase operations are managed in
+ separate functions.
+ Each function allows to send the needed command with the related argument,
+ then check the response.
+ By the same approach, you could implement a command and check the response.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+
+#if defined(STM32F103xE) || defined(STM32F103xG)
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup SDMMC_LL SDMMC Low Layer
+ * @brief Low layer module for SD
+ * @{
+ */
+#if defined (HAL_SD_MODULE_ENABLED) || defined(HAL_MMC_MODULE_ENABLED)
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+static uint32_t SDMMC_GetCmdError(SDIO_TypeDef *SDIOx);
+static uint32_t SDMMC_GetCmdResp1(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint32_t Timeout);
+static uint32_t SDMMC_GetCmdResp2(SDIO_TypeDef *SDIOx);
+static uint32_t SDMMC_GetCmdResp3(SDIO_TypeDef *SDIOx);
+static uint32_t SDMMC_GetCmdResp7(SDIO_TypeDef *SDIOx);
+static uint32_t SDMMC_GetCmdResp6(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint16_t *pRCA);
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup SDMMC_LL_Exported_Functions SDMMC Low Layer Exported Functions
+ * @{
+ */
+
+/** @defgroup HAL_SDMMC_LL_Group1 Initialization de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization/de-initialization functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the SDMMC according to the specified
+ * parameters in the SDMMC_InitTypeDef and create the associated handle.
+ * @param SDIOx: Pointer to SDMMC register base
+ * @param Init: SDMMC initialization structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef SDIO_Init(SDIO_TypeDef *SDIOx, SDIO_InitTypeDef Init)
+{
+ uint32_t tmpreg = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_SDIO_ALL_INSTANCE(SDIOx));
+ assert_param(IS_SDIO_CLOCK_EDGE(Init.ClockEdge));
+ assert_param(IS_SDIO_CLOCK_BYPASS(Init.ClockBypass));
+ assert_param(IS_SDIO_CLOCK_POWER_SAVE(Init.ClockPowerSave));
+ assert_param(IS_SDIO_BUS_WIDE(Init.BusWide));
+ assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(Init.HardwareFlowControl));
+ assert_param(IS_SDIO_CLKDIV(Init.ClockDiv));
+
+ /* Set SDMMC configuration parameters */
+ tmpreg |= (Init.ClockEdge |\
+ Init.ClockBypass |\
+ Init.ClockPowerSave |\
+ Init.BusWide |\
+ Init.HardwareFlowControl |\
+ Init.ClockDiv
+ );
+
+ /* Write to SDMMC CLKCR */
+ MODIFY_REG(SDIOx->CLKCR, CLKCR_CLEAR_MASK, tmpreg);
+
+ return HAL_OK;
+}
+
+
+/**
+ * @}
+ */
+
+/** @defgroup HAL_SDMMC_LL_Group2 IO operation functions
+ * @brief Data transfers functions
+ *
+@verbatim
+ ===============================================================================
+ ##### I/O operation functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the SDMMC data
+ transfers.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Read data (word) from Rx FIFO in blocking mode (polling)
+ * @param SDIOx: Pointer to SDMMC register base
+ * @retval HAL status
+ */
+uint32_t SDIO_ReadFIFO(SDIO_TypeDef *SDIOx)
+{
+ /* Read data from Rx FIFO */
+ return (SDIOx->FIFO);
+}
+
+/**
+ * @brief Write data (word) to Tx FIFO in blocking mode (polling)
+ * @param SDIOx: Pointer to SDMMC register base
+ * @param pWriteData: pointer to data to write
+ * @retval HAL status
+ */
+HAL_StatusTypeDef SDIO_WriteFIFO(SDIO_TypeDef *SDIOx, uint32_t *pWriteData)
+{
+ /* Write data to FIFO */
+ SDIOx->FIFO = *pWriteData;
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup HAL_SDMMC_LL_Group3 Peripheral Control functions
+ * @brief management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the SDMMC data
+ transfers.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Set SDMMC Power state to ON.
+ * @param SDIOx: Pointer to SDMMC register base
+ * @retval HAL status
+ */
+HAL_StatusTypeDef SDIO_PowerState_ON(SDIO_TypeDef *SDIOx)
+{
+ /* Set power state to ON */
+ SDIOx->POWER = SDIO_POWER_PWRCTRL;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Set SDMMC Power state to OFF.
+ * @param SDIOx: Pointer to SDMMC register base
+ * @retval HAL status
+ */
+HAL_StatusTypeDef SDIO_PowerState_OFF(SDIO_TypeDef *SDIOx)
+{
+ /* Set power state to OFF */
+ SDIOx->POWER = 0x00000000U;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Get SDMMC Power state.
+ * @param SDIOx: Pointer to SDMMC register base
+ * @retval Power status of the controller. The returned value can be one of the
+ * following values:
+ * - 0x00: Power OFF
+ * - 0x02: Power UP
+ * - 0x03: Power ON
+ */
+uint32_t SDIO_GetPowerState(SDIO_TypeDef *SDIOx)
+{
+ return (SDIOx->POWER & SDIO_POWER_PWRCTRL);
+}
+
+/**
+ * @brief Configure the SDMMC command path according to the specified parameters in
+ * SDIO_CmdInitTypeDef structure and send the command
+ * @param SDIOx: Pointer to SDMMC register base
+ * @param Command: pointer to a SDIO_CmdInitTypeDef structure that contains
+ * the configuration information for the SDMMC command
+ * @retval HAL status
+ */
+HAL_StatusTypeDef SDIO_SendCommand(SDIO_TypeDef *SDIOx, SDIO_CmdInitTypeDef *Command)
+{
+ uint32_t tmpreg = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_SDIO_CMD_INDEX(Command->CmdIndex));
+ assert_param(IS_SDIO_RESPONSE(Command->Response));
+ assert_param(IS_SDIO_WAIT(Command->WaitForInterrupt));
+ assert_param(IS_SDIO_CPSM(Command->CPSM));
+
+ /* Set the SDMMC Argument value */
+ SDIOx->ARG = Command->Argument;
+
+ /* Set SDMMC command parameters */
+ tmpreg |= (uint32_t)(Command->CmdIndex |\
+ Command->Response |\
+ Command->WaitForInterrupt |\
+ Command->CPSM);
+
+ /* Write to SDMMC CMD register */
+ MODIFY_REG(SDIOx->CMD, CMD_CLEAR_MASK, tmpreg);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Return the command index of last command for which response received
+ * @param SDIOx: Pointer to SDMMC register base
+ * @retval Command index of the last command response received
+ */
+uint8_t SDIO_GetCommandResponse(SDIO_TypeDef *SDIOx)
+{
+ return (uint8_t)(SDIOx->RESPCMD);
+}
+
+
+/**
+ * @brief Return the response received from the card for the last command
+ * @param SDIOx: Pointer to SDMMC register base
+ * @param Response: Specifies the SDMMC response register.
+ * This parameter can be one of the following values:
+ * @arg SDIO_RESP1: Response Register 1
+ * @arg SDIO_RESP2: Response Register 2
+ * @arg SDIO_RESP3: Response Register 3
+ * @arg SDIO_RESP4: Response Register 4
+ * @retval The Corresponding response register value
+ */
+uint32_t SDIO_GetResponse(SDIO_TypeDef *SDIOx, uint32_t Response)
+{
+ __IO uint32_t tmp = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_SDIO_RESP(Response));
+
+ /* Get the response */
+ tmp = (uint32_t)&(SDIOx->RESP1) + Response;
+
+ return (*(__IO uint32_t *) tmp);
+}
+
+/**
+ * @brief Configure the SDMMC data path according to the specified
+ * parameters in the SDIO_DataInitTypeDef.
+ * @param SDIOx: Pointer to SDMMC register base
+ * @param Data : pointer to a SDIO_DataInitTypeDef structure
+ * that contains the configuration information for the SDMMC data.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef SDIO_ConfigData(SDIO_TypeDef *SDIOx, SDIO_DataInitTypeDef* Data)
+{
+ uint32_t tmpreg = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_SDIO_DATA_LENGTH(Data->DataLength));
+ assert_param(IS_SDIO_BLOCK_SIZE(Data->DataBlockSize));
+ assert_param(IS_SDIO_TRANSFER_DIR(Data->TransferDir));
+ assert_param(IS_SDIO_TRANSFER_MODE(Data->TransferMode));
+ assert_param(IS_SDIO_DPSM(Data->DPSM));
+
+ /* Set the SDMMC Data TimeOut value */
+ SDIOx->DTIMER = Data->DataTimeOut;
+
+ /* Set the SDMMC DataLength value */
+ SDIOx->DLEN = Data->DataLength;
+
+ /* Set the SDMMC data configuration parameters */
+ tmpreg |= (uint32_t)(Data->DataBlockSize |\
+ Data->TransferDir |\
+ Data->TransferMode |\
+ Data->DPSM);
+
+ /* Write to SDMMC DCTRL */
+ MODIFY_REG(SDIOx->DCTRL, DCTRL_CLEAR_MASK, tmpreg);
+
+ return HAL_OK;
+
+}
+
+/**
+ * @brief Returns number of remaining data bytes to be transferred.
+ * @param SDIOx: Pointer to SDMMC register base
+ * @retval Number of remaining data bytes to be transferred
+ */
+uint32_t SDIO_GetDataCounter(SDIO_TypeDef *SDIOx)
+{
+ return (SDIOx->DCOUNT);
+}
+
+/**
+ * @brief Get the FIFO data
+ * @param SDIOx: Pointer to SDMMC register base
+ * @retval Data received
+ */
+uint32_t SDIO_GetFIFOCount(SDIO_TypeDef *SDIOx)
+{
+ return (SDIOx->FIFO);
+}
+
+/**
+ * @brief Sets one of the two options of inserting read wait interval.
+ * @param SDIOx: Pointer to SDMMC register base
+ * @param SDIO_ReadWaitMode: SDMMC Read Wait operation mode.
+ * This parameter can be:
+ * @arg SDIO_READ_WAIT_MODE_CLK: Read Wait control by stopping SDMMCCLK
+ * @arg SDIO_READ_WAIT_MODE_DATA2: Read Wait control using SDMMC_DATA2
+ * @retval None
+ */
+HAL_StatusTypeDef SDIO_SetSDMMCReadWaitMode(SDIO_TypeDef *SDIOx, uint32_t SDIO_ReadWaitMode)
+{
+ /* Check the parameters */
+ assert_param(IS_SDIO_READWAIT_MODE(SDIO_ReadWaitMode));
+
+ /* Set SDMMC read wait mode */
+ MODIFY_REG(SDIOx->DCTRL, SDIO_DCTRL_RWMOD, SDIO_ReadWaitMode);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup HAL_SDMMC_LL_Group4 Command management functions
+ * @brief Data transfers functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Commands management functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the needed commands.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Send the Data Block Lenght command and check the response
+ * @param SDIOx: Pointer to SDMMC register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdBlockLength(SDIO_TypeDef *SDIOx, uint32_t BlockSize)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ /* Set Block Size for Card */
+ sdmmc_cmdinit.Argument = (uint32_t)BlockSize;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_BLOCKLEN;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SET_BLOCKLEN, SDIO_CMDTIMEOUT);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Read Single Block command and check the response
+ * @param SDIOx: Pointer to SDMMC register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdReadSingleBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ /* Set Block Size for Card */
+ sdmmc_cmdinit.Argument = (uint32_t)ReadAdd;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_READ_SINGLE_BLOCK;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_READ_SINGLE_BLOCK, SDIO_CMDTIMEOUT);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Read Multi Block command and check the response
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdReadMultiBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ /* Set Block Size for Card */
+ sdmmc_cmdinit.Argument = (uint32_t)ReadAdd;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_READ_MULT_BLOCK;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_READ_MULT_BLOCK, SDIO_CMDTIMEOUT);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Write Single Block command and check the response
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdWriteSingleBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ /* Set Block Size for Card */
+ sdmmc_cmdinit.Argument = (uint32_t)WriteAdd;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_WRITE_SINGLE_BLOCK;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_WRITE_SINGLE_BLOCK, SDIO_CMDTIMEOUT);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Write Multi Block command and check the response
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdWriteMultiBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ /* Set Block Size for Card */
+ sdmmc_cmdinit.Argument = (uint32_t)WriteAdd;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_WRITE_MULT_BLOCK;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_WRITE_MULT_BLOCK, SDIO_CMDTIMEOUT);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Start Address Erase command for SD and check the response
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdSDEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ /* Set Block Size for Card */
+ sdmmc_cmdinit.Argument = (uint32_t)StartAdd;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_ERASE_GRP_START;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_ERASE_GRP_START, SDIO_CMDTIMEOUT);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the End Address Erase command for SD and check the response
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdSDEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ /* Set Block Size for Card */
+ sdmmc_cmdinit.Argument = (uint32_t)EndAdd;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_ERASE_GRP_END;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_ERASE_GRP_END, SDIO_CMDTIMEOUT);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Start Address Erase command and check the response
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ /* Set Block Size for Card */
+ sdmmc_cmdinit.Argument = (uint32_t)StartAdd;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE_GRP_START;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_ERASE_GRP_START, SDIO_CMDTIMEOUT);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the End Address Erase command and check the response
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ /* Set Block Size for Card */
+ sdmmc_cmdinit.Argument = (uint32_t)EndAdd;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE_GRP_END;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_ERASE_GRP_END, SDIO_CMDTIMEOUT);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Erase command and check the response
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdErase(SDIO_TypeDef *SDIOx)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ /* Set Block Size for Card */
+ sdmmc_cmdinit.Argument = 0U;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_ERASE, SDIO_MAXERASETIMEOUT);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Stop Transfer command and check the response.
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdStopTransfer(SDIO_TypeDef *SDIOx)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ /* Send CMD12 STOP_TRANSMISSION */
+ sdmmc_cmdinit.Argument = 0U;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_STOP_TRANSMISSION;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_STOP_TRANSMISSION, 100000000U);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Select Deselect command and check the response.
+ * @param SDIOx: Pointer to SDIO register base
+ * @param addr: Address of the card to be selected
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdSelDesel(SDIO_TypeDef *SDIOx, uint64_t Addr)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ /* Send CMD7 SDMMC_SEL_DESEL_CARD */
+ sdmmc_cmdinit.Argument = (uint32_t)Addr;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEL_DESEL_CARD;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SEL_DESEL_CARD, SDIO_CMDTIMEOUT);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Go Idle State command and check the response.
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdGoIdleState(SDIO_TypeDef *SDIOx)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ sdmmc_cmdinit.Argument = 0U;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_GO_IDLE_STATE;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_NO;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdError(SDIOx);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Operating Condition command and check the response.
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdOperCond(SDIO_TypeDef *SDIOx)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ /* Send CMD8 to verify SD card interface operating condition */
+ /* Argument: - [31:12]: Reserved (shall be set to '0')
+ - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
+ - [7:0]: Check Pattern (recommended 0xAA) */
+ /* CMD Response: R7 */
+ sdmmc_cmdinit.Argument = SDMMC_CHECK_PATTERN;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SEND_EXT_CSD;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp7(SDIOx);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Application command to verify that that the next command
+ * is an application specific com-mand rather than a standard command
+ * and check the response.
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdAppCommand(SDIO_TypeDef *SDIOx, uint32_t Argument)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ sdmmc_cmdinit.Argument = (uint32_t)Argument;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_APP_CMD;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ /* If there is a HAL_ERROR, it is a MMC card, else
+ it is a SD card: SD card 2.0 (voltage range mismatch)
+ or SD card 1.x */
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_APP_CMD, SDIO_CMDTIMEOUT);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the command asking the accessed card to send its operating
+ * condition register (OCR)
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdAppOperCommand(SDIO_TypeDef *SDIOx, uint32_t SdType)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ sdmmc_cmdinit.Argument = SDMMC_VOLTAGE_WINDOW_SD | SdType;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_OP_COND;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp3(SDIOx);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Bus Width command and check the response.
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdBusWidth(SDIO_TypeDef *SDIOx, uint32_t BusWidth)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ sdmmc_cmdinit.Argument = (uint32_t)BusWidth;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_APP_SD_SET_BUSWIDTH;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_APP_SD_SET_BUSWIDTH, SDIO_CMDTIMEOUT);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Send SCR command and check the response.
+ * @param SDIOx: Pointer to SDMMC register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdSendSCR(SDIO_TypeDef *SDIOx)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ /* Send CMD51 SD_APP_SEND_SCR */
+ sdmmc_cmdinit.Argument = 0U;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_SEND_SCR;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_APP_SEND_SCR, SDIO_CMDTIMEOUT);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Send CID command and check the response.
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdSendCID(SDIO_TypeDef *SDIOx)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ /* Send CMD2 ALL_SEND_CID */
+ sdmmc_cmdinit.Argument = 0U;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ALL_SEND_CID;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_LONG;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp2(SDIOx);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Send CSD command and check the response.
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdSendCSD(SDIO_TypeDef *SDIOx, uint32_t Argument)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ /* Send CMD9 SEND_CSD */
+ sdmmc_cmdinit.Argument = (uint32_t)Argument;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_CSD;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_LONG;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp2(SDIOx);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Send CSD command and check the response.
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdSetRelAdd(SDIO_TypeDef *SDIOx, uint16_t *pRCA)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ /* Send CMD3 SD_CMD_SET_REL_ADDR */
+ sdmmc_cmdinit.Argument = 0U;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_REL_ADDR;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp6(SDIOx, SDMMC_CMD_SET_REL_ADDR, pRCA);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Status command and check the response.
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdSendStatus(SDIO_TypeDef *SDIOx, uint32_t Argument)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ sdmmc_cmdinit.Argument = (uint32_t)Argument;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_STATUS;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SEND_STATUS, SDIO_CMDTIMEOUT);
+
+ return errorstate;
+}
+
+/**
+ * @brief Send the Status register command and check the response.
+ * @param SDIOx: Pointer to SDIO register base
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdStatusRegister(SDIO_TypeDef *SDIOx)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ sdmmc_cmdinit.Argument = 0U;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_STATUS;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_APP_STATUS, SDIO_CMDTIMEOUT);
+
+ return errorstate;
+}
+
+/**
+ * @brief Sends host capacity support information and activates the card's
+ * initialization process. Send SDMMC_CMD_SEND_OP_COND command
+ * @param SDIOx: Pointer to SDIO register base
+ * @parame Argument: Argument used for the command
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdOpCondition(SDIO_TypeDef *SDIOx, uint32_t Argument)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ sdmmc_cmdinit.Argument = Argument;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_OP_COND;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp3(SDIOx);
+
+ return errorstate;
+}
+
+/**
+ * @brief Checks switchable function and switch card function. SDMMC_CMD_HS_SWITCH comand
+ * @param SDIOx: Pointer to SDIO register base
+ * @parame Argument: Argument used for the command
+ * @retval HAL status
+ */
+uint32_t SDMMC_CmdSwitch(SDIO_TypeDef *SDIOx, uint32_t Argument)
+{
+ SDIO_CmdInitTypeDef sdmmc_cmdinit;
+ uint32_t errorstate = SDMMC_ERROR_NONE;
+
+ sdmmc_cmdinit.Argument = Argument;
+ sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SWITCH;
+ sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
+ sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
+ sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
+ SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
+
+ /* Check for error conditions */
+ errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_HS_SWITCH, SDIO_CMDTIMEOUT);
+
+ return errorstate;
+}
+
+/**
+ * @}
+ */
+
+/* Private function ----------------------------------------------------------*/
+/** @addtogroup SD_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Checks for error conditions for CMD0.
+ * @param hsd: SD handle
+ * @retval SD Card error state
+ */
+static uint32_t SDMMC_GetCmdError(SDIO_TypeDef *SDIOx)
+{
+ /* 8 is the number of required instructions cycles for the below loop statement.
+ The SDMMC_CMDTIMEOUT is expressed in ms */
+ register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
+
+ do
+ {
+ if (count-- == 0U)
+ {
+ return SDMMC_ERROR_TIMEOUT;
+ }
+
+ }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CMDSENT));
+
+ /* Clear all the static flags */
+ __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
+
+ return SDMMC_ERROR_NONE;
+}
+
+/**
+ * @brief Checks for error conditions for R1 response.
+ * @param hsd: SD handle
+ * @param SD_CMD: The sent command index
+ * @retval SD Card error state
+ */
+static uint32_t SDMMC_GetCmdResp1(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint32_t Timeout)
+{
+ uint32_t response_r1;
+
+ /* 8 is the number of required instructions cycles for the below loop statement.
+ The Timeout is expressed in ms */
+ register uint32_t count = Timeout * (SystemCoreClock / 8U /1000U);
+
+ do
+ {
+ if (count-- == 0U)
+ {
+ return SDMMC_ERROR_TIMEOUT;
+ }
+
+ }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
+
+ if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
+ {
+ __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
+
+ return SDMMC_ERROR_CMD_RSP_TIMEOUT;
+ }
+ else if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
+ {
+ __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
+
+ return SDMMC_ERROR_CMD_CRC_FAIL;
+ }
+
+ /* Check response received is of desired command */
+ if(SDIO_GetCommandResponse(SDIOx) != SD_CMD)
+ {
+ return SDMMC_ERROR_CMD_CRC_FAIL;
+ }
+
+ /* Clear all the static flags */
+ __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
+
+ /* We have received response, retrieve it for analysis */
+ response_r1 = SDIO_GetResponse(SDIOx, SDIO_RESP1);
+
+ if((response_r1 & SDMMC_OCR_ERRORBITS) == SDMMC_ALLZERO)
+ {
+ return SDMMC_ERROR_NONE;
+ }
+ else if((response_r1 & SDMMC_OCR_ADDR_OUT_OF_RANGE) == SDMMC_OCR_ADDR_OUT_OF_RANGE)
+ {
+ return SDMMC_ERROR_ADDR_OUT_OF_RANGE;
+ }
+ else if((response_r1 & SDMMC_OCR_ADDR_MISALIGNED) == SDMMC_OCR_ADDR_MISALIGNED)
+ {
+ return SDMMC_ERROR_ADDR_MISALIGNED;
+ }
+ else if((response_r1 & SDMMC_OCR_BLOCK_LEN_ERR) == SDMMC_OCR_BLOCK_LEN_ERR)
+ {
+ return SDMMC_ERROR_BLOCK_LEN_ERR;
+ }
+ else if((response_r1 & SDMMC_OCR_ERASE_SEQ_ERR) == SDMMC_OCR_ERASE_SEQ_ERR)
+ {
+ return SDMMC_ERROR_ERASE_SEQ_ERR;
+ }
+ else if((response_r1 & SDMMC_OCR_BAD_ERASE_PARAM) == SDMMC_OCR_BAD_ERASE_PARAM)
+ {
+ return SDMMC_ERROR_BAD_ERASE_PARAM;
+ }
+ else if((response_r1 & SDMMC_OCR_WRITE_PROT_VIOLATION) == SDMMC_OCR_WRITE_PROT_VIOLATION)
+ {
+ return SDMMC_ERROR_WRITE_PROT_VIOLATION;
+ }
+ else if((response_r1 & SDMMC_OCR_LOCK_UNLOCK_FAILED) == SDMMC_OCR_LOCK_UNLOCK_FAILED)
+ {
+ return SDMMC_ERROR_LOCK_UNLOCK_FAILED;
+ }
+ else if((response_r1 & SDMMC_OCR_COM_CRC_FAILED) == SDMMC_OCR_COM_CRC_FAILED)
+ {
+ return SDMMC_ERROR_COM_CRC_FAILED;
+ }
+ else if((response_r1 & SDMMC_OCR_ILLEGAL_CMD) == SDMMC_OCR_ILLEGAL_CMD)
+ {
+ return SDMMC_ERROR_ILLEGAL_CMD;
+ }
+ else if((response_r1 & SDMMC_OCR_CARD_ECC_FAILED) == SDMMC_OCR_CARD_ECC_FAILED)
+ {
+ return SDMMC_ERROR_CARD_ECC_FAILED;
+ }
+ else if((response_r1 & SDMMC_OCR_CC_ERROR) == SDMMC_OCR_CC_ERROR)
+ {
+ return SDMMC_ERROR_CC_ERR;
+ }
+ else if((response_r1 & SDMMC_OCR_STREAM_READ_UNDERRUN) == SDMMC_OCR_STREAM_READ_UNDERRUN)
+ {
+ return SDMMC_ERROR_STREAM_READ_UNDERRUN;
+ }
+ else if((response_r1 & SDMMC_OCR_STREAM_WRITE_OVERRUN) == SDMMC_OCR_STREAM_WRITE_OVERRUN)
+ {
+ return SDMMC_ERROR_STREAM_WRITE_OVERRUN;
+ }
+ else if((response_r1 & SDMMC_OCR_CID_CSD_OVERWRITE) == SDMMC_OCR_CID_CSD_OVERWRITE)
+ {
+ return SDMMC_ERROR_CID_CSD_OVERWRITE;
+ }
+ else if((response_r1 & SDMMC_OCR_WP_ERASE_SKIP) == SDMMC_OCR_WP_ERASE_SKIP)
+ {
+ return SDMMC_ERROR_WP_ERASE_SKIP;
+ }
+ else if((response_r1 & SDMMC_OCR_CARD_ECC_DISABLED) == SDMMC_OCR_CARD_ECC_DISABLED)
+ {
+ return SDMMC_ERROR_CARD_ECC_DISABLED;
+ }
+ else if((response_r1 & SDMMC_OCR_ERASE_RESET) == SDMMC_OCR_ERASE_RESET)
+ {
+ return SDMMC_ERROR_ERASE_RESET;
+ }
+ else if((response_r1 & SDMMC_OCR_AKE_SEQ_ERROR) == SDMMC_OCR_AKE_SEQ_ERROR)
+ {
+ return SDMMC_ERROR_AKE_SEQ_ERR;
+ }
+ else
+ {
+ return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
+ }
+}
+
+/**
+ * @brief Checks for error conditions for R2 (CID or CSD) response.
+ * @param hsd: SD handle
+ * @retval SD Card error state
+ */
+static uint32_t SDMMC_GetCmdResp2(SDIO_TypeDef *SDIOx)
+{
+ /* 8 is the number of required instructions cycles for the below loop statement.
+ The SDMMC_CMDTIMEOUT is expressed in ms */
+ register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
+
+ do
+ {
+ if (count-- == 0U)
+ {
+ return SDMMC_ERROR_TIMEOUT;
+ }
+
+ }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
+
+ if (__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
+ {
+ __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
+
+ return SDMMC_ERROR_CMD_RSP_TIMEOUT;
+ }
+ else if (__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
+ {
+ __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
+
+ return SDMMC_ERROR_CMD_CRC_FAIL;
+ }
+ else
+ {
+ /* No error flag set */
+ /* Clear all the static flags */
+ __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
+ }
+
+ return SDMMC_ERROR_NONE;
+}
+
+/**
+ * @brief Checks for error conditions for R3 (OCR) response.
+ * @param hsd: SD handle
+ * @retval SD Card error state
+ */
+static uint32_t SDMMC_GetCmdResp3(SDIO_TypeDef *SDIOx)
+{
+ /* 8 is the number of required instructions cycles for the below loop statement.
+ The SDMMC_CMDTIMEOUT is expressed in ms */
+ register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
+
+ do
+ {
+ if (count-- == 0U)
+ {
+ return SDMMC_ERROR_TIMEOUT;
+ }
+
+ }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
+
+ if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
+ {
+ __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
+
+ return SDMMC_ERROR_CMD_RSP_TIMEOUT;
+ }
+ else
+
+ {
+ /* Clear all the static flags */
+ __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
+ }
+
+ return SDMMC_ERROR_NONE;
+}
+
+/**
+ * @brief Checks for error conditions for R6 (RCA) response.
+ * @param hsd: SD handle
+ * @param SD_CMD: The sent command index
+ * @param pRCA: Pointer to the variable that will contain the SD card relative
+ * address RCA
+ * @retval SD Card error state
+ */
+static uint32_t SDMMC_GetCmdResp6(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint16_t *pRCA)
+{
+ uint32_t response_r1;
+
+ /* 8 is the number of required instructions cycles for the below loop statement.
+ The SDMMC_CMDTIMEOUT is expressed in ms */
+ register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
+
+ do
+ {
+ if (count-- == 0U)
+ {
+ return SDMMC_ERROR_TIMEOUT;
+ }
+
+ }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
+
+ if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
+ {
+ __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
+
+ return SDMMC_ERROR_CMD_RSP_TIMEOUT;
+ }
+ else if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
+ {
+ __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
+
+ return SDMMC_ERROR_CMD_CRC_FAIL;
+ }
+
+ /* Check response received is of desired command */
+ if(SDIO_GetCommandResponse(SDIOx) != SD_CMD)
+ {
+ return SDMMC_ERROR_CMD_CRC_FAIL;
+ }
+
+ /* Clear all the static flags */
+ __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
+
+ /* We have received response, retrieve it. */
+ response_r1 = SDIO_GetResponse(SDIOx, SDIO_RESP1);
+
+ if((response_r1 & (SDMMC_R6_GENERAL_UNKNOWN_ERROR | SDMMC_R6_ILLEGAL_CMD | SDMMC_R6_COM_CRC_FAILED)) == SDMMC_ALLZERO)
+ {
+ *pRCA = (uint16_t) (response_r1 >> 16);
+
+ return SDMMC_ERROR_NONE;
+ }
+ else if((response_r1 & SDMMC_R6_ILLEGAL_CMD) == SDMMC_R6_ILLEGAL_CMD)
+ {
+ return SDMMC_ERROR_ILLEGAL_CMD;
+ }
+ else if((response_r1 & SDMMC_R6_COM_CRC_FAILED) == SDMMC_R6_COM_CRC_FAILED)
+ {
+ return SDMMC_ERROR_COM_CRC_FAILED;
+ }
+ else
+ {
+ return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
+ }
+}
+
+/**
+ * @brief Checks for error conditions for R7 response.
+ * @param hsd: SD handle
+ * @retval SD Card error state
+ */
+static uint32_t SDMMC_GetCmdResp7(SDIO_TypeDef *SDIOx)
+{
+ /* 8 is the number of required instructions cycles for the below loop statement.
+ The SDIO_CMDTIMEOUT is expressed in ms */
+ register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
+
+ do
+ {
+ if (count-- == 0U)
+ {
+ return SDMMC_ERROR_TIMEOUT;
+ }
+
+ }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
+
+ if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
+ {
+ /* Card is SD V2.0 compliant */
+ __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CMDREND);
+
+ return SDMMC_ERROR_CMD_RSP_TIMEOUT;
+ }
+
+ if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CMDREND))
+ {
+ /* Card is SD V2.0 compliant */
+ __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CMDREND);
+ }
+
+ return SDMMC_ERROR_NONE;
+
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F103xE || STM32F103xG */
+
+#endif /* (HAL_SD_MODULE_ENABLED) || (HAL_MMC_MODULE_ENABLED) */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_spi.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_spi.c
new file mode 100644
index 0000000..9e11b67
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_spi.c
@@ -0,0 +1,560 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_spi.c
+ * @author MCD Application Team
+ * @brief SPI LL module driver.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+#if defined(USE_FULL_LL_DRIVER)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_spi.h"
+#include "stm32f1xx_ll_bus.h"
+#include "stm32f1xx_ll_rcc.h"
+
+#ifdef USE_FULL_ASSERT
+#include "stm32_assert.h"
+#else
+#define assert_param(expr) ((void)0U)
+#endif
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (SPI1) || defined (SPI2) || defined (SPI3)
+
+/** @addtogroup SPI_LL
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup SPI_LL_Private_Constants SPI Private Constants
+ * @{
+ */
+/* SPI registers Masks */
+#define SPI_CR1_CLEAR_MASK (SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_MSTR | \
+ SPI_CR1_BR | SPI_CR1_LSBFIRST | SPI_CR1_SSI | \
+ SPI_CR1_SSM | SPI_CR1_RXONLY | SPI_CR1_DFF | \
+ SPI_CR1_CRCNEXT | SPI_CR1_CRCEN | SPI_CR1_BIDIOE | \
+ SPI_CR1_BIDIMODE)
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup SPI_LL_Private_Macros SPI Private Macros
+ * @{
+ */
+#define IS_LL_SPI_TRANSFER_DIRECTION(__VALUE__) (((__VALUE__) == LL_SPI_FULL_DUPLEX) \
+ || ((__VALUE__) == LL_SPI_SIMPLEX_RX) \
+ || ((__VALUE__) == LL_SPI_HALF_DUPLEX_RX) \
+ || ((__VALUE__) == LL_SPI_HALF_DUPLEX_TX))
+
+#define IS_LL_SPI_MODE(__VALUE__) (((__VALUE__) == LL_SPI_MODE_MASTER) \
+ || ((__VALUE__) == LL_SPI_MODE_SLAVE))
+
+#define IS_LL_SPI_DATAWIDTH(__VALUE__) (((__VALUE__) == LL_SPI_DATAWIDTH_8BIT) \
+ || ((__VALUE__) == LL_SPI_DATAWIDTH_16BIT))
+
+#define IS_LL_SPI_POLARITY(__VALUE__) (((__VALUE__) == LL_SPI_POLARITY_LOW) \
+ || ((__VALUE__) == LL_SPI_POLARITY_HIGH))
+
+#define IS_LL_SPI_PHASE(__VALUE__) (((__VALUE__) == LL_SPI_PHASE_1EDGE) \
+ || ((__VALUE__) == LL_SPI_PHASE_2EDGE))
+
+#define IS_LL_SPI_NSS(__VALUE__) (((__VALUE__) == LL_SPI_NSS_SOFT) \
+ || ((__VALUE__) == LL_SPI_NSS_HARD_INPUT) \
+ || ((__VALUE__) == LL_SPI_NSS_HARD_OUTPUT))
+
+#define IS_LL_SPI_BAUDRATE(__VALUE__) (((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV2) \
+ || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV4) \
+ || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV8) \
+ || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV16) \
+ || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV32) \
+ || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV64) \
+ || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV128) \
+ || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV256))
+
+#define IS_LL_SPI_BITORDER(__VALUE__) (((__VALUE__) == LL_SPI_LSB_FIRST) \
+ || ((__VALUE__) == LL_SPI_MSB_FIRST))
+
+#define IS_LL_SPI_CRCCALCULATION(__VALUE__) (((__VALUE__) == LL_SPI_CRCCALCULATION_ENABLE) \
+ || ((__VALUE__) == LL_SPI_CRCCALCULATION_DISABLE))
+
+#define IS_LL_SPI_CRC_POLYNOMIAL(__VALUE__) ((__VALUE__) >= 0x1U)
+
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup SPI_LL_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup SPI_LL_EF_Init
+ * @{
+ */
+
+/**
+ * @brief De-initialize the SPI registers to their default reset values.
+ * @param SPIx SPI Instance
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: SPI registers are de-initialized
+ * - ERROR: SPI registers are not de-initialized
+ */
+ErrorStatus LL_SPI_DeInit(SPI_TypeDef *SPIx)
+{
+ ErrorStatus status = ERROR;
+
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_INSTANCE(SPIx));
+
+#if defined(SPI1)
+ if (SPIx == SPI1)
+ {
+ /* Force reset of SPI clock */
+ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
+
+ /* Release reset of SPI clock */
+ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1);
+
+ status = SUCCESS;
+ }
+#endif /* SPI1 */
+#if defined(SPI2)
+ if (SPIx == SPI2)
+ {
+ /* Force reset of SPI clock */
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
+
+ /* Release reset of SPI clock */
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2);
+
+ status = SUCCESS;
+ }
+#endif /* SPI2 */
+#if defined(SPI3)
+ if (SPIx == SPI3)
+ {
+ /* Force reset of SPI clock */
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI3);
+
+ /* Release reset of SPI clock */
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI3);
+
+ status = SUCCESS;
+ }
+#endif /* SPI3 */
+
+ return status;
+}
+
+/**
+ * @brief Initialize the SPI registers according to the specified parameters in SPI_InitStruct.
+ * @note As some bits in SPI configuration registers can only be written when the SPI is disabled (SPI_CR1_SPE bit =0),
+ * SPI IP should be in disabled state prior calling this function. Otherwise, ERROR result will be returned.
+ * @param SPIx SPI Instance
+ * @param SPI_InitStruct pointer to a @ref LL_SPI_InitTypeDef structure
+ * @retval An ErrorStatus enumeration value. (Return always SUCCESS)
+ */
+ErrorStatus LL_SPI_Init(SPI_TypeDef *SPIx, LL_SPI_InitTypeDef *SPI_InitStruct)
+{
+ ErrorStatus status = ERROR;
+
+ /* Check the SPI Instance SPIx*/
+ assert_param(IS_SPI_ALL_INSTANCE(SPIx));
+
+ /* Check the SPI parameters from SPI_InitStruct*/
+ assert_param(IS_LL_SPI_TRANSFER_DIRECTION(SPI_InitStruct->TransferDirection));
+ assert_param(IS_LL_SPI_MODE(SPI_InitStruct->Mode));
+ assert_param(IS_LL_SPI_DATAWIDTH(SPI_InitStruct->DataWidth));
+ assert_param(IS_LL_SPI_POLARITY(SPI_InitStruct->ClockPolarity));
+ assert_param(IS_LL_SPI_PHASE(SPI_InitStruct->ClockPhase));
+ assert_param(IS_LL_SPI_NSS(SPI_InitStruct->NSS));
+ assert_param(IS_LL_SPI_BAUDRATE(SPI_InitStruct->BaudRate));
+ assert_param(IS_LL_SPI_BITORDER(SPI_InitStruct->BitOrder));
+ assert_param(IS_LL_SPI_CRCCALCULATION(SPI_InitStruct->CRCCalculation));
+
+ if (LL_SPI_IsEnabled(SPIx) == 0x00000000U)
+ {
+ /*---------------------------- SPIx CR1 Configuration ------------------------
+ * Configure SPIx CR1 with parameters:
+ * - TransferDirection: SPI_CR1_BIDIMODE, SPI_CR1_BIDIOE and SPI_CR1_RXONLY bits
+ * - Master/Slave Mode: SPI_CR1_MSTR bit
+ * - DataWidth: SPI_CR1_DFF bit
+ * - ClockPolarity: SPI_CR1_CPOL bit
+ * - ClockPhase: SPI_CR1_CPHA bit
+ * - NSS management: SPI_CR1_SSM bit
+ * - BaudRate prescaler: SPI_CR1_BR[2:0] bits
+ * - BitOrder: SPI_CR1_LSBFIRST bit
+ * - CRCCalculation: SPI_CR1_CRCEN bit
+ */
+ MODIFY_REG(SPIx->CR1,
+ SPI_CR1_CLEAR_MASK,
+ SPI_InitStruct->TransferDirection | SPI_InitStruct->Mode | SPI_InitStruct->DataWidth |
+ SPI_InitStruct->ClockPolarity | SPI_InitStruct->ClockPhase |
+ SPI_InitStruct->NSS | SPI_InitStruct->BaudRate |
+ SPI_InitStruct->BitOrder | SPI_InitStruct->CRCCalculation);
+
+ /*---------------------------- SPIx CR2 Configuration ------------------------
+ * Configure SPIx CR2 with parameters:
+ * - NSS management: SSOE bit
+ */
+ MODIFY_REG(SPIx->CR2, SPI_CR2_SSOE, (SPI_InitStruct->NSS >> 16U));
+
+ /*---------------------------- SPIx CRCPR Configuration ----------------------
+ * Configure SPIx CRCPR with parameters:
+ * - CRCPoly: CRCPOLY[15:0] bits
+ */
+ if (SPI_InitStruct->CRCCalculation == LL_SPI_CRCCALCULATION_ENABLE)
+ {
+ assert_param(IS_LL_SPI_CRC_POLYNOMIAL(SPI_InitStruct->CRCPoly));
+ LL_SPI_SetCRCPolynomial(SPIx, SPI_InitStruct->CRCPoly);
+ }
+ status = SUCCESS;
+ }
+
+#if defined (SPI_I2S_SUPPORT)
+ /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */
+ CLEAR_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SMOD);
+#endif /* SPI_I2S_SUPPORT */
+ return status;
+}
+
+/**
+ * @brief Set each @ref LL_SPI_InitTypeDef field to default value.
+ * @param SPI_InitStruct pointer to a @ref LL_SPI_InitTypeDef structure
+ * whose fields will be set to default values.
+ * @retval None
+ */
+void LL_SPI_StructInit(LL_SPI_InitTypeDef *SPI_InitStruct)
+{
+ /* Set SPI_InitStruct fields to default values */
+ SPI_InitStruct->TransferDirection = LL_SPI_FULL_DUPLEX;
+ SPI_InitStruct->Mode = LL_SPI_MODE_SLAVE;
+ SPI_InitStruct->DataWidth = LL_SPI_DATAWIDTH_8BIT;
+ SPI_InitStruct->ClockPolarity = LL_SPI_POLARITY_LOW;
+ SPI_InitStruct->ClockPhase = LL_SPI_PHASE_1EDGE;
+ SPI_InitStruct->NSS = LL_SPI_NSS_HARD_INPUT;
+ SPI_InitStruct->BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2;
+ SPI_InitStruct->BitOrder = LL_SPI_MSB_FIRST;
+ SPI_InitStruct->CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
+ SPI_InitStruct->CRCPoly = 7U;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#if defined(SPI_I2S_SUPPORT)
+/** @addtogroup I2S_LL
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup I2S_LL_Private_Constants I2S Private Constants
+ * @{
+ */
+/* I2S registers Masks */
+#define I2S_I2SCFGR_CLEAR_MASK (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | \
+ SPI_I2SCFGR_CKPOL | SPI_I2SCFGR_I2SSTD | \
+ SPI_I2SCFGR_I2SCFG | SPI_I2SCFGR_I2SMOD )
+
+#define I2S_I2SPR_CLEAR_MASK 0x0002U
+/**
+ * @}
+ */
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup I2S_LL_Private_Macros I2S Private Macros
+ * @{
+ */
+
+#define IS_LL_I2S_DATAFORMAT(__VALUE__) (((__VALUE__) == LL_I2S_DATAFORMAT_16B) \
+ || ((__VALUE__) == LL_I2S_DATAFORMAT_16B_EXTENDED) \
+ || ((__VALUE__) == LL_I2S_DATAFORMAT_24B) \
+ || ((__VALUE__) == LL_I2S_DATAFORMAT_32B))
+
+#define IS_LL_I2S_CPOL(__VALUE__) (((__VALUE__) == LL_I2S_POLARITY_LOW) \
+ || ((__VALUE__) == LL_I2S_POLARITY_HIGH))
+
+#define IS_LL_I2S_STANDARD(__VALUE__) (((__VALUE__) == LL_I2S_STANDARD_PHILIPS) \
+ || ((__VALUE__) == LL_I2S_STANDARD_MSB) \
+ || ((__VALUE__) == LL_I2S_STANDARD_LSB) \
+ || ((__VALUE__) == LL_I2S_STANDARD_PCM_SHORT) \
+ || ((__VALUE__) == LL_I2S_STANDARD_PCM_LONG))
+
+#define IS_LL_I2S_MODE(__VALUE__) (((__VALUE__) == LL_I2S_MODE_SLAVE_TX) \
+ || ((__VALUE__) == LL_I2S_MODE_SLAVE_RX) \
+ || ((__VALUE__) == LL_I2S_MODE_MASTER_TX) \
+ || ((__VALUE__) == LL_I2S_MODE_MASTER_RX))
+
+#define IS_LL_I2S_MCLK_OUTPUT(__VALUE__) (((__VALUE__) == LL_I2S_MCLK_OUTPUT_ENABLE) \
+ || ((__VALUE__) == LL_I2S_MCLK_OUTPUT_DISABLE))
+
+#define IS_LL_I2S_AUDIO_FREQ(__VALUE__) ((((__VALUE__) >= LL_I2S_AUDIOFREQ_8K) \
+ && ((__VALUE__) <= LL_I2S_AUDIOFREQ_192K)) \
+ || ((__VALUE__) == LL_I2S_AUDIOFREQ_DEFAULT))
+
+#define IS_LL_I2S_PRESCALER_LINEAR(__VALUE__) ((__VALUE__) >= 0x2U)
+
+#define IS_LL_I2S_PRESCALER_PARITY(__VALUE__) (((__VALUE__) == LL_I2S_PRESCALER_PARITY_EVEN) \
+ || ((__VALUE__) == LL_I2S_PRESCALER_PARITY_ODD))
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup I2S_LL_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup I2S_LL_EF_Init
+ * @{
+ */
+
+/**
+ * @brief De-initialize the SPI/I2S registers to their default reset values.
+ * @param SPIx SPI Instance
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: SPI registers are de-initialized
+ * - ERROR: SPI registers are not de-initialized
+ */
+ErrorStatus LL_I2S_DeInit(SPI_TypeDef *SPIx)
+{
+ return LL_SPI_DeInit(SPIx);
+}
+
+/**
+ * @brief Initializes the SPI/I2S registers according to the specified parameters in I2S_InitStruct.
+ * @note As some bits in SPI configuration registers can only be written when the SPI is disabled (SPI_CR1_SPE bit =0),
+ * SPI IP should be in disabled state prior calling this function. Otherwise, ERROR result will be returned.
+ * @param SPIx SPI Instance
+ * @param I2S_InitStruct pointer to a @ref LL_I2S_InitTypeDef structure
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: SPI registers are Initialized
+ * - ERROR: SPI registers are not Initialized
+ */
+ErrorStatus LL_I2S_Init(SPI_TypeDef *SPIx, LL_I2S_InitTypeDef *I2S_InitStruct)
+{
+ uint16_t i2sdiv = 2U, i2sodd = 0U, packetlength = 1U;
+ uint32_t tmp = 0U;
+ uint32_t sourceclock = 0U;
+#if defined(I2S2_I2S3_CLOCK_FEATURE)
+#else
+ LL_RCC_ClocksTypeDef rcc_clocks;
+#endif /* I2S2_I2S3_CLOCK_FEATURE */
+ ErrorStatus status = ERROR;
+
+ /* Check the I2S parameters */
+ assert_param(IS_I2S_ALL_INSTANCE(SPIx));
+ assert_param(IS_LL_I2S_MODE(I2S_InitStruct->Mode));
+ assert_param(IS_LL_I2S_STANDARD(I2S_InitStruct->Standard));
+ assert_param(IS_LL_I2S_DATAFORMAT(I2S_InitStruct->DataFormat));
+ assert_param(IS_LL_I2S_MCLK_OUTPUT(I2S_InitStruct->MCLKOutput));
+ assert_param(IS_LL_I2S_AUDIO_FREQ(I2S_InitStruct->AudioFreq));
+ assert_param(IS_LL_I2S_CPOL(I2S_InitStruct->ClockPolarity));
+
+ if (LL_I2S_IsEnabled(SPIx) == 0x00000000U)
+ {
+ /*---------------------------- SPIx I2SCFGR Configuration --------------------
+ * Configure SPIx I2SCFGR with parameters:
+ * - Mode: SPI_I2SCFGR_I2SCFG[1:0] bit
+ * - Standard: SPI_I2SCFGR_I2SSTD[1:0] and SPI_I2SCFGR_PCMSYNC bits
+ * - DataFormat: SPI_I2SCFGR_CHLEN and SPI_I2SCFGR_DATLEN bits
+ * - ClockPolarity: SPI_I2SCFGR_CKPOL bit
+ */
+
+ /* Write to SPIx I2SCFGR */
+ MODIFY_REG(SPIx->I2SCFGR,
+ I2S_I2SCFGR_CLEAR_MASK,
+ I2S_InitStruct->Mode | I2S_InitStruct->Standard |
+ I2S_InitStruct->DataFormat | I2S_InitStruct->ClockPolarity |
+ SPI_I2SCFGR_I2SMOD);
+
+ /*---------------------------- SPIx I2SPR Configuration ----------------------
+ * Configure SPIx I2SPR with parameters:
+ * - MCLKOutput: SPI_I2SPR_MCKOE bit
+ * - AudioFreq: SPI_I2SPR_I2SDIV[7:0] and SPI_I2SPR_ODD bits
+ */
+
+ /* If the requested audio frequency is not the default, compute the prescaler (i2sodd, i2sdiv)
+ * else, default values are used: i2sodd = 0U, i2sdiv = 2U.
+ */
+ if (I2S_InitStruct->AudioFreq != LL_I2S_AUDIOFREQ_DEFAULT)
+ {
+ /* Check the frame length (For the Prescaler computing)
+ * Default value: LL_I2S_DATAFORMAT_16B (packetlength = 1U).
+ */
+ if (I2S_InitStruct->DataFormat != LL_I2S_DATAFORMAT_16B)
+ {
+ /* Packet length is 32 bits */
+ packetlength = 2U;
+ }
+#if defined(I2S2_I2S3_CLOCK_FEATURE)
+ /* If an external I2S clock has to be used, the specific define should be set
+ in the project configuration or in the stm32f1xx_ll_rcc.h file */
+ if(SPIx == SPI2)
+ {
+ /* Get the I2S source clock value */
+ sourceclock = LL_RCC_GetI2SClockFreq(LL_RCC_I2S2_CLKSOURCE);
+ }
+ else /* SPI3 */
+ {
+ /* Get the I2S source clock value */
+ sourceclock = LL_RCC_GetI2SClockFreq(LL_RCC_I2S3_CLKSOURCE);
+ }
+#else
+ /* I2S Clock source is System clock: Get System Clock frequency */
+ LL_RCC_GetSystemClocksFreq(&rcc_clocks);
+
+ /* Get the source clock value: based on System Clock value */
+ sourceclock = rcc_clocks.SYSCLK_Frequency;
+#endif /* I2S2_I2S3_CLOCK_FEATURE */
+ /* Compute the Real divider depending on the MCLK output state with a floating point */
+ if (I2S_InitStruct->MCLKOutput == LL_I2S_MCLK_OUTPUT_ENABLE)
+ {
+ /* MCLK output is enabled */
+ tmp = (uint16_t)(((((sourceclock / 256U) * 10U) / I2S_InitStruct->AudioFreq)) + 5U);
+ }
+ else
+ {
+ /* MCLK output is disabled */
+ tmp = (uint16_t)(((((sourceclock / (32U * packetlength)) * 10U) / I2S_InitStruct->AudioFreq)) + 5U);
+ }
+
+ /* Remove the floating point */
+ tmp = tmp / 10U;
+
+ /* Check the parity of the divider */
+ i2sodd = (uint16_t)(tmp & (uint16_t)0x0001U);
+
+ /* Compute the i2sdiv prescaler */
+ i2sdiv = (uint16_t)((tmp - i2sodd) / 2U);
+
+ /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
+ i2sodd = (uint16_t)(i2sodd << 8U);
+ }
+
+ /* Test if the divider is 1 or 0 or greater than 0xFF */
+ if ((i2sdiv < 2U) || (i2sdiv > 0xFFU))
+ {
+ /* Set the default values */
+ i2sdiv = 2U;
+ i2sodd = 0U;
+ }
+
+ /* Write to SPIx I2SPR register the computed value */
+ WRITE_REG(SPIx->I2SPR, i2sdiv | i2sodd | I2S_InitStruct->MCLKOutput);
+
+ status = SUCCESS;
+ }
+ return status;
+}
+
+/**
+ * @brief Set each @ref LL_I2S_InitTypeDef field to default value.
+ * @param I2S_InitStruct pointer to a @ref LL_I2S_InitTypeDef structure
+ * whose fields will be set to default values.
+ * @retval None
+ */
+void LL_I2S_StructInit(LL_I2S_InitTypeDef *I2S_InitStruct)
+{
+ /*--------------- Reset I2S init structure parameters values -----------------*/
+ I2S_InitStruct->Mode = LL_I2S_MODE_SLAVE_TX;
+ I2S_InitStruct->Standard = LL_I2S_STANDARD_PHILIPS;
+ I2S_InitStruct->DataFormat = LL_I2S_DATAFORMAT_16B;
+ I2S_InitStruct->MCLKOutput = LL_I2S_MCLK_OUTPUT_DISABLE;
+ I2S_InitStruct->AudioFreq = LL_I2S_AUDIOFREQ_DEFAULT;
+ I2S_InitStruct->ClockPolarity = LL_I2S_POLARITY_LOW;
+}
+
+/**
+ * @brief Set linear and parity prescaler.
+ * @note To calculate value of PrescalerLinear(I2SDIV[7:0] bits) and PrescalerParity(ODD bit)\n
+ * Check Audio frequency table and formulas inside Reference Manual (SPI/I2S).
+ * @param SPIx SPI Instance
+ * @param PrescalerLinear value: Min_Data=0x02 and Max_Data=0xFF.
+ * @param PrescalerParity This parameter can be one of the following values:
+ * @arg @ref LL_I2S_PRESCALER_PARITY_EVEN
+ * @arg @ref LL_I2S_PRESCALER_PARITY_ODD
+ * @retval None
+ */
+void LL_I2S_ConfigPrescaler(SPI_TypeDef *SPIx, uint32_t PrescalerLinear, uint32_t PrescalerParity)
+{
+ /* Check the I2S parameters */
+ assert_param(IS_I2S_ALL_INSTANCE(SPIx));
+ assert_param(IS_LL_I2S_PRESCALER_LINEAR(PrescalerLinear));
+ assert_param(IS_LL_I2S_PRESCALER_PARITY(PrescalerParity));
+
+ /* Write to SPIx I2SPR */
+ MODIFY_REG(SPIx->I2SPR, SPI_I2SPR_I2SDIV | SPI_I2SPR_ODD, PrescalerLinear | (PrescalerParity << 8U));
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* SPI_I2S_SUPPORT */
+
+#endif /* defined (SPI1) || defined (SPI2) || defined (SPI3) */
+
+/**
+ * @}
+ */
+
+#endif /* USE_FULL_LL_DRIVER */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_tim.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_tim.c
new file mode 100644
index 0000000..63ee597
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_tim.c
@@ -0,0 +1,1214 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_tim.c
+ * @author MCD Application Team
+ * @brief TIM LL module driver.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+#if defined(USE_FULL_LL_DRIVER)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_tim.h"
+#include "stm32f1xx_ll_bus.h"
+
+#ifdef USE_FULL_ASSERT
+#include "stm32_assert.h"
+#else
+#define assert_param(expr) ((void)0U)
+#endif
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (TIM1) || defined (TIM2) || defined (TIM3) || defined (TIM4) || defined (TIM5) || defined (TIM6) || defined (TIM7) || defined (TIM8) || defined (TIM9) || defined (TIM10) || defined (TIM11) || defined (TIM12) || defined (TIM13) || defined (TIM14) || defined (TIM15) || defined (TIM16) || defined (TIM17)
+
+/** @addtogroup TIM_LL
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/** @addtogroup TIM_LL_Private_Macros
+ * @{
+ */
+#define IS_LL_TIM_COUNTERMODE(__VALUE__) (((__VALUE__) == LL_TIM_COUNTERMODE_UP) \
+ || ((__VALUE__) == LL_TIM_COUNTERMODE_DOWN) \
+ || ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_UP) \
+ || ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_DOWN) \
+ || ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_UP_DOWN))
+
+#define IS_LL_TIM_CLOCKDIVISION(__VALUE__) (((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV1) \
+ || ((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV2) \
+ || ((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV4))
+
+#define IS_LL_TIM_OCMODE(__VALUE__) (((__VALUE__) == LL_TIM_OCMODE_FROZEN) \
+ || ((__VALUE__) == LL_TIM_OCMODE_ACTIVE) \
+ || ((__VALUE__) == LL_TIM_OCMODE_INACTIVE) \
+ || ((__VALUE__) == LL_TIM_OCMODE_TOGGLE) \
+ || ((__VALUE__) == LL_TIM_OCMODE_FORCED_INACTIVE) \
+ || ((__VALUE__) == LL_TIM_OCMODE_FORCED_ACTIVE) \
+ || ((__VALUE__) == LL_TIM_OCMODE_PWM1) \
+ || ((__VALUE__) == LL_TIM_OCMODE_PWM2))
+
+#define IS_LL_TIM_OCSTATE(__VALUE__) (((__VALUE__) == LL_TIM_OCSTATE_DISABLE) \
+ || ((__VALUE__) == LL_TIM_OCSTATE_ENABLE))
+
+#define IS_LL_TIM_OCPOLARITY(__VALUE__) (((__VALUE__) == LL_TIM_OCPOLARITY_HIGH) \
+ || ((__VALUE__) == LL_TIM_OCPOLARITY_LOW))
+
+#define IS_LL_TIM_OCIDLESTATE(__VALUE__) (((__VALUE__) == LL_TIM_OCIDLESTATE_LOW) \
+ || ((__VALUE__) == LL_TIM_OCIDLESTATE_HIGH))
+
+#define IS_LL_TIM_ACTIVEINPUT(__VALUE__) (((__VALUE__) == LL_TIM_ACTIVEINPUT_DIRECTTI) \
+ || ((__VALUE__) == LL_TIM_ACTIVEINPUT_INDIRECTTI) \
+ || ((__VALUE__) == LL_TIM_ACTIVEINPUT_TRC))
+
+#define IS_LL_TIM_ICPSC(__VALUE__) (((__VALUE__) == LL_TIM_ICPSC_DIV1) \
+ || ((__VALUE__) == LL_TIM_ICPSC_DIV2) \
+ || ((__VALUE__) == LL_TIM_ICPSC_DIV4) \
+ || ((__VALUE__) == LL_TIM_ICPSC_DIV8))
+
+#define IS_LL_TIM_IC_FILTER(__VALUE__) (((__VALUE__) == LL_TIM_IC_FILTER_FDIV1) \
+ || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N2) \
+ || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N4) \
+ || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N8) \
+ || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV2_N6) \
+ || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV2_N8) \
+ || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV4_N6) \
+ || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV4_N8) \
+ || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV8_N6) \
+ || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV8_N8) \
+ || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N5) \
+ || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N6) \
+ || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N8) \
+ || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N5) \
+ || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N6) \
+ || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N8))
+
+#define IS_LL_TIM_IC_POLARITY(__VALUE__) (((__VALUE__) == LL_TIM_IC_POLARITY_RISING) \
+ || ((__VALUE__) == LL_TIM_IC_POLARITY_FALLING))
+
+#define IS_LL_TIM_ENCODERMODE(__VALUE__) (((__VALUE__) == LL_TIM_ENCODERMODE_X2_TI1) \
+ || ((__VALUE__) == LL_TIM_ENCODERMODE_X2_TI2) \
+ || ((__VALUE__) == LL_TIM_ENCODERMODE_X4_TI12))
+
+#define IS_LL_TIM_IC_POLARITY_ENCODER(__VALUE__) (((__VALUE__) == LL_TIM_IC_POLARITY_RISING) \
+ || ((__VALUE__) == LL_TIM_IC_POLARITY_FALLING))
+
+#define IS_LL_TIM_OSSR_STATE(__VALUE__) (((__VALUE__) == LL_TIM_OSSR_DISABLE) \
+ || ((__VALUE__) == LL_TIM_OSSR_ENABLE))
+
+#define IS_LL_TIM_OSSI_STATE(__VALUE__) (((__VALUE__) == LL_TIM_OSSI_DISABLE) \
+ || ((__VALUE__) == LL_TIM_OSSI_ENABLE))
+
+#define IS_LL_TIM_LOCK_LEVEL(__VALUE__) (((__VALUE__) == LL_TIM_LOCKLEVEL_OFF) \
+ || ((__VALUE__) == LL_TIM_LOCKLEVEL_1) \
+ || ((__VALUE__) == LL_TIM_LOCKLEVEL_2) \
+ || ((__VALUE__) == LL_TIM_LOCKLEVEL_3))
+
+#define IS_LL_TIM_BREAK_STATE(__VALUE__) (((__VALUE__) == LL_TIM_BREAK_DISABLE) \
+ || ((__VALUE__) == LL_TIM_BREAK_ENABLE))
+
+#define IS_LL_TIM_BREAK_POLARITY(__VALUE__) (((__VALUE__) == LL_TIM_BREAK_POLARITY_LOW) \
+ || ((__VALUE__) == LL_TIM_BREAK_POLARITY_HIGH))
+
+#define IS_LL_TIM_AUTOMATIC_OUTPUT_STATE(__VALUE__) (((__VALUE__) == LL_TIM_AUTOMATICOUTPUT_DISABLE) \
+ || ((__VALUE__) == LL_TIM_AUTOMATICOUTPUT_ENABLE))
+/**
+ * @}
+ */
+
+
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup TIM_LL_Private_Functions TIM Private Functions
+ * @{
+ */
+static ErrorStatus OC1Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct);
+static ErrorStatus OC2Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct);
+static ErrorStatus OC3Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct);
+static ErrorStatus OC4Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct);
+static ErrorStatus IC1Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct);
+static ErrorStatus IC2Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct);
+static ErrorStatus IC3Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct);
+static ErrorStatus IC4Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct);
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup TIM_LL_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup TIM_LL_EF_Init
+ * @{
+ */
+
+/**
+ * @brief Set TIMx registers to their reset values.
+ * @param TIMx Timer instance
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: TIMx registers are de-initialized
+ * - ERROR: invalid TIMx instance
+ */
+ErrorStatus LL_TIM_DeInit(TIM_TypeDef *TIMx)
+{
+ ErrorStatus result = SUCCESS;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(TIMx));
+
+ if (TIMx == TIM2)
+ {
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM2);
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM2);
+ }
+#if defined(TIM1)
+ else if (TIMx == TIM1)
+ {
+ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM1);
+ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM1);
+ }
+#endif
+#if defined(TIM3)
+ else if (TIMx == TIM3)
+ {
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM3);
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM3);
+ }
+#endif
+#if defined(TIM4)
+ else if (TIMx == TIM4)
+ {
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM4);
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM4);
+ }
+#endif
+#if defined(TIM5)
+ else if (TIMx == TIM5)
+ {
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM5);
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM5);
+ }
+#endif
+#if defined(TIM6)
+ else if (TIMx == TIM6)
+ {
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM6);
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM6);
+ }
+#endif
+#if defined (TIM7)
+ else if (TIMx == TIM7)
+ {
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM7);
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM7);
+ }
+#endif
+#if defined(TIM8)
+ else if (TIMx == TIM8)
+ {
+ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM8);
+ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM8);
+ }
+#endif
+#if defined(TIM9)
+ else if (TIMx == TIM9)
+ {
+ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM9);
+ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM9);
+ }
+#endif
+#if defined(TIM10)
+ else if (TIMx == TIM10)
+ {
+ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM10);
+ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM10);
+ }
+#endif
+#if defined(TIM11)
+ else if (TIMx == TIM11)
+ {
+ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM11);
+ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM11);
+ }
+#endif
+#if defined(TIM12)
+ else if (TIMx == TIM12)
+ {
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM12);
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM12);
+ }
+#endif
+#if defined(TIM13)
+ else if (TIMx == TIM13)
+ {
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM13);
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM13);
+ }
+#endif
+#if defined(TIM14)
+ else if (TIMx == TIM14)
+ {
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM14);
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM14);
+ }
+#endif
+#if defined(TIM15)
+ else if (TIMx == TIM15)
+ {
+ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM15);
+ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM15);
+ }
+#endif
+#if defined(TIM16)
+ else if (TIMx == TIM16)
+ {
+ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM16);
+ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM16);
+ }
+#endif
+#if defined(TIM17)
+ else if (TIMx == TIM17)
+ {
+ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM17);
+ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM17);
+ }
+#endif
+ else
+ {
+ result = ERROR;
+ }
+
+ return result;
+}
+
+/**
+ * @brief Set the fields of the time base unit configuration data structure
+ * to their default values.
+ * @param TIM_InitStruct pointer to a @ref LL_TIM_InitTypeDef structure (time base unit configuration data structure)
+ * @retval None
+ */
+void LL_TIM_StructInit(LL_TIM_InitTypeDef *TIM_InitStruct)
+{
+ /* Set the default configuration */
+ TIM_InitStruct->Prescaler = (uint16_t)0x0000;
+ TIM_InitStruct->CounterMode = LL_TIM_COUNTERMODE_UP;
+ TIM_InitStruct->Autoreload = 0xFFFFFFFFU;
+ TIM_InitStruct->ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
+ TIM_InitStruct->RepetitionCounter = (uint8_t)0x00;
+}
+
+/**
+ * @brief Configure the TIMx time base unit.
+ * @param TIMx Timer Instance
+ * @param TIM_InitStruct pointer to a @ref LL_TIM_InitTypeDef structure (TIMx time base unit configuration data structure)
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: TIMx registers are de-initialized
+ * - ERROR: not applicable
+ */
+ErrorStatus LL_TIM_Init(TIM_TypeDef *TIMx, LL_TIM_InitTypeDef *TIM_InitStruct)
+{
+ uint32_t tmpcr1 = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(TIMx));
+ assert_param(IS_LL_TIM_COUNTERMODE(TIM_InitStruct->CounterMode));
+ assert_param(IS_LL_TIM_CLOCKDIVISION(TIM_InitStruct->ClockDivision));
+
+ tmpcr1 = LL_TIM_ReadReg(TIMx, CR1);
+
+ if (IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx))
+ {
+ /* Select the Counter Mode */
+ MODIFY_REG(tmpcr1, (TIM_CR1_DIR | TIM_CR1_CMS), TIM_InitStruct->CounterMode);
+ }
+
+ if (IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx))
+ {
+ /* Set the clock division */
+ MODIFY_REG(tmpcr1, TIM_CR1_CKD, TIM_InitStruct->ClockDivision);
+ }
+
+ /* Write to TIMx CR1 */
+ LL_TIM_WriteReg(TIMx, CR1, tmpcr1);
+
+ /* Set the Autoreload value */
+ LL_TIM_SetAutoReload(TIMx, TIM_InitStruct->Autoreload);
+
+ /* Set the Prescaler value */
+ LL_TIM_SetPrescaler(TIMx, TIM_InitStruct->Prescaler);
+
+ if (IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx))
+ {
+ /* Set the Repetition Counter value */
+ LL_TIM_SetRepetitionCounter(TIMx, TIM_InitStruct->RepetitionCounter);
+ }
+
+ /* Generate an update event to reload the Prescaler
+ and the repetition counter value (if applicable) immediately */
+ LL_TIM_GenerateEvent_UPDATE(TIMx);
+
+ return SUCCESS;
+}
+
+/**
+ * @brief Set the fields of the TIMx output channel configuration data
+ * structure to their default values.
+ * @param TIM_OC_InitStruct pointer to a @ref LL_TIM_OC_InitTypeDef structure (the output channel configuration data structure)
+ * @retval None
+ */
+void LL_TIM_OC_StructInit(LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct)
+{
+ /* Set the default configuration */
+ TIM_OC_InitStruct->OCMode = LL_TIM_OCMODE_FROZEN;
+ TIM_OC_InitStruct->OCState = LL_TIM_OCSTATE_DISABLE;
+ TIM_OC_InitStruct->OCNState = LL_TIM_OCSTATE_DISABLE;
+ TIM_OC_InitStruct->CompareValue = 0x00000000U;
+ TIM_OC_InitStruct->OCPolarity = LL_TIM_OCPOLARITY_HIGH;
+ TIM_OC_InitStruct->OCNPolarity = LL_TIM_OCPOLARITY_HIGH;
+ TIM_OC_InitStruct->OCIdleState = LL_TIM_OCIDLESTATE_LOW;
+ TIM_OC_InitStruct->OCNIdleState = LL_TIM_OCIDLESTATE_LOW;
+}
+
+/**
+ * @brief Configure the TIMx output channel.
+ * @param TIMx Timer Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_TIM_CHANNEL_CH1
+ * @arg @ref LL_TIM_CHANNEL_CH2
+ * @arg @ref LL_TIM_CHANNEL_CH3
+ * @arg @ref LL_TIM_CHANNEL_CH4
+ * @param TIM_OC_InitStruct pointer to a @ref LL_TIM_OC_InitTypeDef structure (TIMx output channel configuration data structure)
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: TIMx output channel is initialized
+ * - ERROR: TIMx output channel is not initialized
+ */
+ErrorStatus LL_TIM_OC_Init(TIM_TypeDef *TIMx, uint32_t Channel, LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct)
+{
+ ErrorStatus result = ERROR;
+
+ switch (Channel)
+ {
+ case LL_TIM_CHANNEL_CH1:
+ result = OC1Config(TIMx, TIM_OC_InitStruct);
+ break;
+ case LL_TIM_CHANNEL_CH2:
+ result = OC2Config(TIMx, TIM_OC_InitStruct);
+ break;
+ case LL_TIM_CHANNEL_CH3:
+ result = OC3Config(TIMx, TIM_OC_InitStruct);
+ break;
+ case LL_TIM_CHANNEL_CH4:
+ result = OC4Config(TIMx, TIM_OC_InitStruct);
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+/**
+ * @brief Set the fields of the TIMx input channel configuration data
+ * structure to their default values.
+ * @param TIM_ICInitStruct pointer to a @ref LL_TIM_IC_InitTypeDef structure (the input channel configuration data structure)
+ * @retval None
+ */
+void LL_TIM_IC_StructInit(LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
+{
+ /* Set the default configuration */
+ TIM_ICInitStruct->ICPolarity = LL_TIM_IC_POLARITY_RISING;
+ TIM_ICInitStruct->ICActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI;
+ TIM_ICInitStruct->ICPrescaler = LL_TIM_ICPSC_DIV1;
+ TIM_ICInitStruct->ICFilter = LL_TIM_IC_FILTER_FDIV1;
+}
+
+/**
+ * @brief Configure the TIMx input channel.
+ * @param TIMx Timer Instance
+ * @param Channel This parameter can be one of the following values:
+ * @arg @ref LL_TIM_CHANNEL_CH1
+ * @arg @ref LL_TIM_CHANNEL_CH2
+ * @arg @ref LL_TIM_CHANNEL_CH3
+ * @arg @ref LL_TIM_CHANNEL_CH4
+ * @param TIM_IC_InitStruct pointer to a @ref LL_TIM_IC_InitTypeDef structure (TIMx input channel configuration data structure)
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: TIMx output channel is initialized
+ * - ERROR: TIMx output channel is not initialized
+ */
+ErrorStatus LL_TIM_IC_Init(TIM_TypeDef *TIMx, uint32_t Channel, LL_TIM_IC_InitTypeDef *TIM_IC_InitStruct)
+{
+ ErrorStatus result = ERROR;
+
+ switch (Channel)
+ {
+ case LL_TIM_CHANNEL_CH1:
+ result = IC1Config(TIMx, TIM_IC_InitStruct);
+ break;
+ case LL_TIM_CHANNEL_CH2:
+ result = IC2Config(TIMx, TIM_IC_InitStruct);
+ break;
+ case LL_TIM_CHANNEL_CH3:
+ result = IC3Config(TIMx, TIM_IC_InitStruct);
+ break;
+ case LL_TIM_CHANNEL_CH4:
+ result = IC4Config(TIMx, TIM_IC_InitStruct);
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+/**
+ * @brief Fills each TIM_EncoderInitStruct field with its default value
+ * @param TIM_EncoderInitStruct pointer to a @ref LL_TIM_ENCODER_InitTypeDef structure (encoder interface configuration data structure)
+ * @retval None
+ */
+void LL_TIM_ENCODER_StructInit(LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct)
+{
+ /* Set the default configuration */
+ TIM_EncoderInitStruct->EncoderMode = LL_TIM_ENCODERMODE_X2_TI1;
+ TIM_EncoderInitStruct->IC1Polarity = LL_TIM_IC_POLARITY_RISING;
+ TIM_EncoderInitStruct->IC1ActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI;
+ TIM_EncoderInitStruct->IC1Prescaler = LL_TIM_ICPSC_DIV1;
+ TIM_EncoderInitStruct->IC1Filter = LL_TIM_IC_FILTER_FDIV1;
+ TIM_EncoderInitStruct->IC2Polarity = LL_TIM_IC_POLARITY_RISING;
+ TIM_EncoderInitStruct->IC2ActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI;
+ TIM_EncoderInitStruct->IC2Prescaler = LL_TIM_ICPSC_DIV1;
+ TIM_EncoderInitStruct->IC2Filter = LL_TIM_IC_FILTER_FDIV1;
+}
+
+/**
+ * @brief Configure the encoder interface of the timer instance.
+ * @param TIMx Timer Instance
+ * @param TIM_EncoderInitStruct pointer to a @ref LL_TIM_ENCODER_InitTypeDef structure (TIMx encoder interface configuration data structure)
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: TIMx registers are de-initialized
+ * - ERROR: not applicable
+ */
+ErrorStatus LL_TIM_ENCODER_Init(TIM_TypeDef *TIMx, LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct)
+{
+ uint32_t tmpccmr1 = 0U;
+ uint32_t tmpccer = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(TIMx));
+ assert_param(IS_LL_TIM_ENCODERMODE(TIM_EncoderInitStruct->EncoderMode));
+ assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_EncoderInitStruct->IC1Polarity));
+ assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_EncoderInitStruct->IC1ActiveInput));
+ assert_param(IS_LL_TIM_ICPSC(TIM_EncoderInitStruct->IC1Prescaler));
+ assert_param(IS_LL_TIM_IC_FILTER(TIM_EncoderInitStruct->IC1Filter));
+ assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_EncoderInitStruct->IC2Polarity));
+ assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_EncoderInitStruct->IC2ActiveInput));
+ assert_param(IS_LL_TIM_ICPSC(TIM_EncoderInitStruct->IC2Prescaler));
+ assert_param(IS_LL_TIM_IC_FILTER(TIM_EncoderInitStruct->IC2Filter));
+
+ /* Disable the CC1 and CC2: Reset the CC1E and CC2E Bits */
+ TIMx->CCER &= (uint32_t)~(TIM_CCER_CC1E | TIM_CCER_CC2E);
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1);
+
+ /* Get the TIMx CCER register value */
+ tmpccer = LL_TIM_ReadReg(TIMx, CCER);
+
+ /* Configure TI1 */
+ tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC);
+ tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1ActiveInput >> 16U);
+ tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1Filter >> 16U);
+ tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1Prescaler >> 16U);
+
+ /* Configure TI2 */
+ tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC2S | TIM_CCMR1_IC2F | TIM_CCMR1_IC2PSC);
+ tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2ActiveInput >> 8U);
+ tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2Filter >> 8U);
+ tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2Prescaler >> 8U);
+
+ /* Set TI1 and TI2 polarity and enable TI1 and TI2 */
+ tmpccer &= (uint32_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP | TIM_CCER_CC2P | TIM_CCER_CC2NP);
+ tmpccer |= (uint32_t)(TIM_EncoderInitStruct->IC1Polarity);
+ tmpccer |= (uint32_t)(TIM_EncoderInitStruct->IC2Polarity << 4U);
+ tmpccer |= (uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E);
+
+ /* Set encoder mode */
+ LL_TIM_SetEncoderMode(TIMx, TIM_EncoderInitStruct->EncoderMode);
+
+ /* Write to TIMx CCMR1 */
+ LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1);
+
+ /* Write to TIMx CCER */
+ LL_TIM_WriteReg(TIMx, CCER, tmpccer);
+
+ return SUCCESS;
+}
+
+/**
+ * @brief Set the fields of the TIMx Hall sensor interface configuration data
+ * structure to their default values.
+ * @param TIM_HallSensorInitStruct pointer to a @ref LL_TIM_HALLSENSOR_InitTypeDef structure (HALL sensor interface configuration data structure)
+ * @retval None
+ */
+void LL_TIM_HALLSENSOR_StructInit(LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct)
+{
+ /* Set the default configuration */
+ TIM_HallSensorInitStruct->IC1Polarity = LL_TIM_IC_POLARITY_RISING;
+ TIM_HallSensorInitStruct->IC1Prescaler = LL_TIM_ICPSC_DIV1;
+ TIM_HallSensorInitStruct->IC1Filter = LL_TIM_IC_FILTER_FDIV1;
+ TIM_HallSensorInitStruct->CommutationDelay = 0U;
+}
+
+/**
+ * @brief Configure the Hall sensor interface of the timer instance.
+ * @note TIMx CH1, CH2 and CH3 inputs connected through a XOR
+ * to the TI1 input channel
+ * @note TIMx slave mode controller is configured in reset mode.
+ Selected internal trigger is TI1F_ED.
+ * @note Channel 1 is configured as input, IC1 is mapped on TRC.
+ * @note Captured value stored in TIMx_CCR1 correspond to the time elapsed
+ * between 2 changes on the inputs. It gives information about motor speed.
+ * @note Channel 2 is configured in output PWM 2 mode.
+ * @note Compare value stored in TIMx_CCR2 corresponds to the commutation delay.
+ * @note OC2REF is selected as trigger output on TRGO.
+ * @param TIMx Timer Instance
+ * @param TIM_HallSensorInitStruct pointer to a @ref LL_TIM_HALLSENSOR_InitTypeDef structure (TIMx HALL sensor interface configuration data structure)
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: TIMx registers are de-initialized
+ * - ERROR: not applicable
+ */
+ErrorStatus LL_TIM_HALLSENSOR_Init(TIM_TypeDef *TIMx, LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct)
+{
+ uint32_t tmpcr2 = 0U;
+ uint32_t tmpccmr1 = 0U;
+ uint32_t tmpccer = 0U;
+ uint32_t tmpsmcr = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(TIMx));
+ assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_HallSensorInitStruct->IC1Polarity));
+ assert_param(IS_LL_TIM_ICPSC(TIM_HallSensorInitStruct->IC1Prescaler));
+ assert_param(IS_LL_TIM_IC_FILTER(TIM_HallSensorInitStruct->IC1Filter));
+
+ /* Disable the CC1 and CC2: Reset the CC1E and CC2E Bits */
+ TIMx->CCER &= (uint32_t)~(TIM_CCER_CC1E | TIM_CCER_CC2E);
+
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1);
+
+ /* Get the TIMx CCER register value */
+ tmpccer = LL_TIM_ReadReg(TIMx, CCER);
+
+ /* Get the TIMx SMCR register value */
+ tmpsmcr = LL_TIM_ReadReg(TIMx, SMCR);
+
+ /* Connect TIMx_CH1, CH2 and CH3 pins to the TI1 input */
+ tmpcr2 |= TIM_CR2_TI1S;
+
+ /* OC2REF signal is used as trigger output (TRGO) */
+ tmpcr2 |= LL_TIM_TRGO_OC2REF;
+
+ /* Configure the slave mode controller */
+ tmpsmcr &= (uint32_t)~(TIM_SMCR_TS | TIM_SMCR_SMS);
+ tmpsmcr |= LL_TIM_TS_TI1F_ED;
+ tmpsmcr |= LL_TIM_SLAVEMODE_RESET;
+
+ /* Configure input channel 1 */
+ tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC);
+ tmpccmr1 |= (uint32_t)(LL_TIM_ACTIVEINPUT_TRC >> 16U);
+ tmpccmr1 |= (uint32_t)(TIM_HallSensorInitStruct->IC1Filter >> 16U);
+ tmpccmr1 |= (uint32_t)(TIM_HallSensorInitStruct->IC1Prescaler >> 16U);
+
+ /* Configure input channel 2 */
+ tmpccmr1 &= (uint32_t)~(TIM_CCMR1_OC2M | TIM_CCMR1_OC2FE | TIM_CCMR1_OC2PE | TIM_CCMR1_OC2CE);
+ tmpccmr1 |= (uint32_t)(LL_TIM_OCMODE_PWM2 << 8U);
+
+ /* Set Channel 1 polarity and enable Channel 1 and Channel2 */
+ tmpccer &= (uint32_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP | TIM_CCER_CC2P | TIM_CCER_CC2NP);
+ tmpccer |= (uint32_t)(TIM_HallSensorInitStruct->IC1Polarity);
+ tmpccer |= (uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E);
+
+ /* Write to TIMx CR2 */
+ LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
+
+ /* Write to TIMx SMCR */
+ LL_TIM_WriteReg(TIMx, SMCR, tmpsmcr);
+
+ /* Write to TIMx CCMR1 */
+ LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1);
+
+ /* Write to TIMx CCER */
+ LL_TIM_WriteReg(TIMx, CCER, tmpccer);
+
+ /* Write to TIMx CCR2 */
+ LL_TIM_OC_SetCompareCH2(TIMx, TIM_HallSensorInitStruct->CommutationDelay);
+
+ return SUCCESS;
+}
+
+/**
+ * @brief Set the fields of the Break and Dead Time configuration data structure
+ * to their default values.
+ * @param TIM_BDTRInitStruct pointer to a @ref LL_TIM_BDTR_InitTypeDef structure (Break and Dead Time configuration data structure)
+ * @retval None
+ */
+void LL_TIM_BDTR_StructInit(LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct)
+{
+ /* Set the default configuration */
+ TIM_BDTRInitStruct->OSSRState = LL_TIM_OSSR_DISABLE;
+ TIM_BDTRInitStruct->OSSIState = LL_TIM_OSSI_DISABLE;
+ TIM_BDTRInitStruct->LockLevel = LL_TIM_LOCKLEVEL_OFF;
+ TIM_BDTRInitStruct->DeadTime = (uint8_t)0x00;
+ TIM_BDTRInitStruct->BreakState = LL_TIM_BREAK_DISABLE;
+ TIM_BDTRInitStruct->BreakPolarity = LL_TIM_BREAK_POLARITY_LOW;
+ TIM_BDTRInitStruct->AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE;
+}
+
+/**
+ * @brief Configure the Break and Dead Time feature of the timer instance.
+ * @note As the bits AOE, BKP, BKE, OSSR, OSSI and DTG[7:0] can be write-locked
+ * depending on the LOCK configuration, it can be necessary to configure all of
+ * them during the first write access to the TIMx_BDTR register.
+ * @note Macro @ref IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not
+ * a timer instance provides a break input.
+ * @param TIMx Timer Instance
+ * @param TIM_BDTRInitStruct pointer to a @ref LL_TIM_BDTR_InitTypeDef structure(Break and Dead Time configuration data structure)
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: Break and Dead Time is initialized
+ * - ERROR: not applicable
+ */
+ErrorStatus LL_TIM_BDTR_Init(TIM_TypeDef *TIMx, LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct)
+{
+ uint32_t tmpbdtr = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_BREAK_INSTANCE(TIMx));
+ assert_param(IS_LL_TIM_OSSR_STATE(TIM_BDTRInitStruct->OSSRState));
+ assert_param(IS_LL_TIM_OSSI_STATE(TIM_BDTRInitStruct->OSSIState));
+ assert_param(IS_LL_TIM_LOCK_LEVEL(TIM_BDTRInitStruct->LockLevel));
+ assert_param(IS_LL_TIM_BREAK_STATE(TIM_BDTRInitStruct->BreakState));
+ assert_param(IS_LL_TIM_BREAK_POLARITY(TIM_BDTRInitStruct->BreakPolarity));
+ assert_param(IS_LL_TIM_AUTOMATIC_OUTPUT_STATE(TIM_BDTRInitStruct->AutomaticOutput));
+
+ /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State,
+ the OSSI State, the dead time value and the Automatic Output Enable Bit */
+
+ /* Set the BDTR bits */
+ MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, TIM_BDTRInitStruct->DeadTime);
+ MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, TIM_BDTRInitStruct->LockLevel);
+ MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, TIM_BDTRInitStruct->OSSIState);
+ MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, TIM_BDTRInitStruct->OSSRState);
+ MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, TIM_BDTRInitStruct->BreakState);
+ MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, TIM_BDTRInitStruct->BreakPolarity);
+ MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, TIM_BDTRInitStruct->AutomaticOutput);
+ MODIFY_REG(tmpbdtr, TIM_BDTR_MOE, TIM_BDTRInitStruct->AutomaticOutput);
+
+ /* Set TIMx_BDTR */
+ LL_TIM_WriteReg(TIMx, BDTR, tmpbdtr);
+
+ return SUCCESS;
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup TIM_LL_Private_Functions TIM Private Functions
+ * @brief Private functions
+ * @{
+ */
+/**
+ * @brief Configure the TIMx output channel 1.
+ * @param TIMx Timer Instance
+ * @param TIM_OCInitStruct pointer to the the TIMx output channel 1 configuration data structure
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: TIMx registers are de-initialized
+ * - ERROR: not applicable
+ */
+static ErrorStatus OC1Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct)
+{
+ uint32_t tmpccmr1 = 0U;
+ uint32_t tmpccer = 0U;
+ uint32_t tmpcr2 = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_CC1_INSTANCE(TIMx));
+ assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode));
+ assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState));
+ assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity));
+ assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState));
+ assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity));
+
+ /* Disable the Channel 1: Reset the CC1E Bit */
+ CLEAR_BIT(TIMx->CCER, TIM_CCER_CC1E);
+
+ /* Get the TIMx CCER register value */
+ tmpccer = LL_TIM_ReadReg(TIMx, CCER);
+
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1);
+
+ /* Reset Capture/Compare selection Bits */
+ CLEAR_BIT(tmpccmr1, TIM_CCMR1_CC1S);
+
+ /* Set the Output Compare Mode */
+ MODIFY_REG(tmpccmr1, TIM_CCMR1_OC1M, TIM_OCInitStruct->OCMode);
+
+ /* Set the Output Compare Polarity */
+ MODIFY_REG(tmpccer, TIM_CCER_CC1P, TIM_OCInitStruct->OCPolarity);
+
+ /* Set the Output State */
+ MODIFY_REG(tmpccer, TIM_CCER_CC1E, TIM_OCInitStruct->OCState);
+
+ if (IS_TIM_BREAK_INSTANCE(TIMx))
+ {
+ assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState));
+ assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState));
+
+ /* Set the complementary output Polarity */
+ MODIFY_REG(tmpccer, TIM_CCER_CC1NP, TIM_OCInitStruct->OCNPolarity << 2U);
+
+ /* Set the complementary output State */
+ MODIFY_REG(tmpccer, TIM_CCER_CC1NE, TIM_OCInitStruct->OCNState << 2U);
+
+ /* Set the Output Idle state */
+ MODIFY_REG(tmpcr2, TIM_CR2_OIS1, TIM_OCInitStruct->OCIdleState);
+
+ /* Set the complementary output Idle state */
+ MODIFY_REG(tmpcr2, TIM_CR2_OIS1N, TIM_OCInitStruct->OCNIdleState << 1U);
+ }
+
+ /* Write to TIMx CR2 */
+ LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
+
+ /* Write to TIMx CCMR1 */
+ LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1);
+
+ /* Set the Capture Compare Register value */
+ LL_TIM_OC_SetCompareCH1(TIMx, TIM_OCInitStruct->CompareValue);
+
+ /* Write to TIMx CCER */
+ LL_TIM_WriteReg(TIMx, CCER, tmpccer);
+
+ return SUCCESS;
+}
+
+/**
+ * @brief Configure the TIMx output channel 2.
+ * @param TIMx Timer Instance
+ * @param TIM_OCInitStruct pointer to the the TIMx output channel 2 configuration data structure
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: TIMx registers are de-initialized
+ * - ERROR: not applicable
+ */
+static ErrorStatus OC2Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct)
+{
+ uint32_t tmpccmr1 = 0U;
+ uint32_t tmpccer = 0U;
+ uint32_t tmpcr2 = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_CC2_INSTANCE(TIMx));
+ assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode));
+ assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState));
+ assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity));
+ assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState));
+ assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity));
+
+ /* Disable the Channel 2: Reset the CC2E Bit */
+ CLEAR_BIT(TIMx->CCER, TIM_CCER_CC2E);
+
+ /* Get the TIMx CCER register value */
+ tmpccer = LL_TIM_ReadReg(TIMx, CCER);
+
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1);
+
+ /* Reset Capture/Compare selection Bits */
+ CLEAR_BIT(tmpccmr1, TIM_CCMR1_CC2S);
+
+ /* Select the Output Compare Mode */
+ MODIFY_REG(tmpccmr1, TIM_CCMR1_OC2M, TIM_OCInitStruct->OCMode << 8U);
+
+ /* Set the Output Compare Polarity */
+ MODIFY_REG(tmpccer, TIM_CCER_CC2P, TIM_OCInitStruct->OCPolarity << 4U);
+
+ /* Set the Output State */
+ MODIFY_REG(tmpccer, TIM_CCER_CC2E, TIM_OCInitStruct->OCState << 4U);
+
+ if (IS_TIM_BREAK_INSTANCE(TIMx))
+ {
+ assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState));
+ assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState));
+
+ /* Set the complementary output Polarity */
+ MODIFY_REG(tmpccer, TIM_CCER_CC2NP, TIM_OCInitStruct->OCNPolarity << 6U);
+
+ /* Set the complementary output State */
+ MODIFY_REG(tmpccer, TIM_CCER_CC2NE, TIM_OCInitStruct->OCNState << 6U);
+
+ /* Set the Output Idle state */
+ MODIFY_REG(tmpcr2, TIM_CR2_OIS2, TIM_OCInitStruct->OCIdleState << 2U);
+
+ /* Set the complementary output Idle state */
+ MODIFY_REG(tmpcr2, TIM_CR2_OIS2N, TIM_OCInitStruct->OCNIdleState << 3U);
+ }
+
+ /* Write to TIMx CR2 */
+ LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
+
+ /* Write to TIMx CCMR1 */
+ LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1);
+
+ /* Set the Capture Compare Register value */
+ LL_TIM_OC_SetCompareCH2(TIMx, TIM_OCInitStruct->CompareValue);
+
+ /* Write to TIMx CCER */
+ LL_TIM_WriteReg(TIMx, CCER, tmpccer);
+
+ return SUCCESS;
+}
+
+/**
+ * @brief Configure the TIMx output channel 3.
+ * @param TIMx Timer Instance
+ * @param TIM_OCInitStruct pointer to the the TIMx output channel 3 configuration data structure
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: TIMx registers are de-initialized
+ * - ERROR: not applicable
+ */
+static ErrorStatus OC3Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct)
+{
+ uint32_t tmpccmr2 = 0U;
+ uint32_t tmpccer = 0U;
+ uint32_t tmpcr2 = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_CC3_INSTANCE(TIMx));
+ assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode));
+ assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState));
+ assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity));
+ assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState));
+ assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity));
+
+ /* Disable the Channel 3: Reset the CC3E Bit */
+ CLEAR_BIT(TIMx->CCER, TIM_CCER_CC3E);
+
+ /* Get the TIMx CCER register value */
+ tmpccer = LL_TIM_ReadReg(TIMx, CCER);
+
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
+
+ /* Get the TIMx CCMR2 register value */
+ tmpccmr2 = LL_TIM_ReadReg(TIMx, CCMR2);
+
+ /* Reset Capture/Compare selection Bits */
+ CLEAR_BIT(tmpccmr2, TIM_CCMR2_CC3S);
+
+ /* Select the Output Compare Mode */
+ MODIFY_REG(tmpccmr2, TIM_CCMR2_OC3M, TIM_OCInitStruct->OCMode);
+
+ /* Set the Output Compare Polarity */
+ MODIFY_REG(tmpccer, TIM_CCER_CC3P, TIM_OCInitStruct->OCPolarity << 8U);
+
+ /* Set the Output State */
+ MODIFY_REG(tmpccer, TIM_CCER_CC3E, TIM_OCInitStruct->OCState << 8U);
+
+ if (IS_TIM_BREAK_INSTANCE(TIMx))
+ {
+ assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState));
+ assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState));
+
+ /* Set the complementary output Polarity */
+ MODIFY_REG(tmpccer, TIM_CCER_CC3NP, TIM_OCInitStruct->OCNPolarity << 10U);
+
+ /* Set the complementary output State */
+ MODIFY_REG(tmpccer, TIM_CCER_CC3NE, TIM_OCInitStruct->OCNState << 10U);
+
+ /* Set the Output Idle state */
+ MODIFY_REG(tmpcr2, TIM_CR2_OIS3, TIM_OCInitStruct->OCIdleState << 4U);
+
+ /* Set the complementary output Idle state */
+ MODIFY_REG(tmpcr2, TIM_CR2_OIS3N, TIM_OCInitStruct->OCNIdleState << 5U);
+ }
+
+ /* Write to TIMx CR2 */
+ LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
+
+ /* Write to TIMx CCMR2 */
+ LL_TIM_WriteReg(TIMx, CCMR2, tmpccmr2);
+
+ /* Set the Capture Compare Register value */
+ LL_TIM_OC_SetCompareCH3(TIMx, TIM_OCInitStruct->CompareValue);
+
+ /* Write to TIMx CCER */
+ LL_TIM_WriteReg(TIMx, CCER, tmpccer);
+
+ return SUCCESS;
+}
+
+/**
+ * @brief Configure the TIMx output channel 4.
+ * @param TIMx Timer Instance
+ * @param TIM_OCInitStruct pointer to the the TIMx output channel 4 configuration data structure
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: TIMx registers are de-initialized
+ * - ERROR: not applicable
+ */
+static ErrorStatus OC4Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct)
+{
+ uint32_t tmpccmr2 = 0U;
+ uint32_t tmpccer = 0U;
+ uint32_t tmpcr2 = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_CC4_INSTANCE(TIMx));
+ assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode));
+ assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState));
+ assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity));
+ assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity));
+ assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState));
+
+ /* Disable the Channel 4: Reset the CC4E Bit */
+ CLEAR_BIT(TIMx->CCER, TIM_CCER_CC4E);
+
+ /* Get the TIMx CCER register value */
+ tmpccer = LL_TIM_ReadReg(TIMx, CCER);
+
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
+
+ /* Get the TIMx CCMR2 register value */
+ tmpccmr2 = LL_TIM_ReadReg(TIMx, CCMR2);
+
+ /* Reset Capture/Compare selection Bits */
+ CLEAR_BIT(tmpccmr2, TIM_CCMR2_CC4S);
+
+ /* Select the Output Compare Mode */
+ MODIFY_REG(tmpccmr2, TIM_CCMR2_OC4M, TIM_OCInitStruct->OCMode << 8U);
+
+ /* Set the Output Compare Polarity */
+ MODIFY_REG(tmpccer, TIM_CCER_CC4P, TIM_OCInitStruct->OCPolarity << 12U);
+
+ /* Set the Output State */
+ MODIFY_REG(tmpccer, TIM_CCER_CC4E, TIM_OCInitStruct->OCState << 12U);
+
+ if (IS_TIM_BREAK_INSTANCE(TIMx))
+ {
+ assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState));
+ assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState));
+
+ /* Set the Output Idle state */
+ MODIFY_REG(tmpcr2, TIM_CR2_OIS4, TIM_OCInitStruct->OCIdleState << 6U);
+ }
+
+ /* Write to TIMx CR2 */
+ LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
+
+ /* Write to TIMx CCMR2 */
+ LL_TIM_WriteReg(TIMx, CCMR2, tmpccmr2);
+
+ /* Set the Capture Compare Register value */
+ LL_TIM_OC_SetCompareCH4(TIMx, TIM_OCInitStruct->CompareValue);
+
+ /* Write to TIMx CCER */
+ LL_TIM_WriteReg(TIMx, CCER, tmpccer);
+
+ return SUCCESS;
+}
+
+
+/**
+ * @brief Configure the TIMx input channel 1.
+ * @param TIMx Timer Instance
+ * @param TIM_ICInitStruct pointer to the the TIMx input channel 1 configuration data structure
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: TIMx registers are de-initialized
+ * - ERROR: not applicable
+ */
+static ErrorStatus IC1Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CC1_INSTANCE(TIMx));
+ assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity));
+ assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput));
+ assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler));
+ assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter));
+
+ /* Disable the Channel 1: Reset the CC1E Bit */
+ TIMx->CCER &= (uint32_t)~TIM_CCER_CC1E;
+
+ /* Select the Input and set the filter and the prescaler value */
+ MODIFY_REG(TIMx->CCMR1,
+ (TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC),
+ (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 16U);
+
+ /* Select the Polarity and set the CC1E Bit */
+ MODIFY_REG(TIMx->CCER,
+ (TIM_CCER_CC1P | TIM_CCER_CC1NP),
+ (TIM_ICInitStruct->ICPolarity | TIM_CCER_CC1E));
+
+ return SUCCESS;
+}
+
+/**
+ * @brief Configure the TIMx input channel 2.
+ * @param TIMx Timer Instance
+ * @param TIM_ICInitStruct pointer to the the TIMx input channel 2 configuration data structure
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: TIMx registers are de-initialized
+ * - ERROR: not applicable
+ */
+static ErrorStatus IC2Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CC2_INSTANCE(TIMx));
+ assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity));
+ assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput));
+ assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler));
+ assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter));
+
+ /* Disable the Channel 2: Reset the CC2E Bit */
+ TIMx->CCER &= (uint32_t)~TIM_CCER_CC2E;
+
+ /* Select the Input and set the filter and the prescaler value */
+ MODIFY_REG(TIMx->CCMR1,
+ (TIM_CCMR1_CC2S | TIM_CCMR1_IC2F | TIM_CCMR1_IC2PSC),
+ (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 8U);
+
+ /* Select the Polarity and set the CC2E Bit */
+ MODIFY_REG(TIMx->CCER,
+ (TIM_CCER_CC2P | TIM_CCER_CC2NP),
+ ((TIM_ICInitStruct->ICPolarity << 4U) | TIM_CCER_CC2E));
+
+ return SUCCESS;
+}
+
+/**
+ * @brief Configure the TIMx input channel 3.
+ * @param TIMx Timer Instance
+ * @param TIM_ICInitStruct pointer to the the TIMx input channel 3 configuration data structure
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: TIMx registers are de-initialized
+ * - ERROR: not applicable
+ */
+static ErrorStatus IC3Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CC3_INSTANCE(TIMx));
+ assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity));
+ assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput));
+ assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler));
+ assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter));
+
+ /* Disable the Channel 3: Reset the CC3E Bit */
+ TIMx->CCER &= (uint32_t)~TIM_CCER_CC3E;
+
+ /* Select the Input and set the filter and the prescaler value */
+ MODIFY_REG(TIMx->CCMR2,
+ (TIM_CCMR2_CC3S | TIM_CCMR2_IC3F | TIM_CCMR2_IC3PSC),
+ (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 16U);
+
+ /* Select the Polarity and set the CC3E Bit */
+ MODIFY_REG(TIMx->CCER,
+ (TIM_CCER_CC3P | TIM_CCER_CC3NP),
+ ((TIM_ICInitStruct->ICPolarity << 8U) | TIM_CCER_CC3E));
+
+ return SUCCESS;
+}
+
+/**
+ * @brief Configure the TIMx input channel 4.
+ * @param TIMx Timer Instance
+ * @param TIM_ICInitStruct pointer to the the TIMx input channel 4 configuration data structure
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: TIMx registers are de-initialized
+ * - ERROR: not applicable
+ */
+static ErrorStatus IC4Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CC4_INSTANCE(TIMx));
+ assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity));
+ assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput));
+ assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler));
+ assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter));
+
+ /* Disable the Channel 4: Reset the CC4E Bit */
+ TIMx->CCER &= (uint32_t)~TIM_CCER_CC4E;
+
+ /* Select the Input and set the filter and the prescaler value */
+ MODIFY_REG(TIMx->CCMR2,
+ (TIM_CCMR2_CC4S | TIM_CCMR2_IC4F | TIM_CCMR2_IC4PSC),
+ (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 8U);
+
+ /* Select the Polarity and set the CC4E Bit */
+ MODIFY_REG(TIMx->CCER,
+ TIM_CCER_CC4P,
+ ((TIM_ICInitStruct->ICPolarity << 12U) | TIM_CCER_CC4E));
+
+ return SUCCESS;
+}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* TIM1 || TIM2 || TIM3 || TIM4 || TIM5 || TIM6 || TIM7 || TIM8 || TIM9 || TIM10 || TIM11 || TIM12 || TIM13 || TIM14 || TIM15 || TIM16 || TIM17 */
+
+/**
+ * @}
+ */
+
+#endif /* USE_FULL_LL_DRIVER */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usart.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usart.c
new file mode 100644
index 0000000..1fdded6
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usart.c
@@ -0,0 +1,449 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_usart.c
+ * @author MCD Application Team
+ * @brief USART LL module driver.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+#if defined(USE_FULL_LL_DRIVER)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_usart.h"
+#include "stm32f1xx_ll_rcc.h"
+#include "stm32f1xx_ll_bus.h"
+#ifdef USE_FULL_ASSERT
+#include "stm32_assert.h"
+#else
+#define assert_param(expr) ((void)0U)
+#endif
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (USART1) || defined (USART2) || defined (USART3) || defined (UART4) || defined (UART5)
+
+/** @addtogroup USART_LL
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @addtogroup USART_LL_Private_Constants
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/* Private macros ------------------------------------------------------------*/
+/** @addtogroup USART_LL_Private_Macros
+ * @{
+ */
+
+/* __BAUDRATE__ The maximum Baud Rate is derived from the maximum clock available
+ * divided by the smallest oversampling used on the USART (i.e. 8) */
+#define IS_LL_USART_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) <= 10000000U)
+
+#define IS_LL_USART_DIRECTION(__VALUE__) (((__VALUE__) == LL_USART_DIRECTION_NONE) \
+ || ((__VALUE__) == LL_USART_DIRECTION_RX) \
+ || ((__VALUE__) == LL_USART_DIRECTION_TX) \
+ || ((__VALUE__) == LL_USART_DIRECTION_TX_RX))
+
+#define IS_LL_USART_PARITY(__VALUE__) (((__VALUE__) == LL_USART_PARITY_NONE) \
+ || ((__VALUE__) == LL_USART_PARITY_EVEN) \
+ || ((__VALUE__) == LL_USART_PARITY_ODD))
+
+#define IS_LL_USART_DATAWIDTH(__VALUE__) (((__VALUE__) == LL_USART_DATAWIDTH_8B) \
+ || ((__VALUE__) == LL_USART_DATAWIDTH_9B))
+
+#define IS_LL_USART_OVERSAMPLING(__VALUE__) (((__VALUE__) == LL_USART_OVERSAMPLING_16) \
+ || ((__VALUE__) == LL_USART_OVERSAMPLING_8))
+
+#define IS_LL_USART_LASTBITCLKOUTPUT(__VALUE__) (((__VALUE__) == LL_USART_LASTCLKPULSE_NO_OUTPUT) \
+ || ((__VALUE__) == LL_USART_LASTCLKPULSE_OUTPUT))
+
+#define IS_LL_USART_CLOCKPHASE(__VALUE__) (((__VALUE__) == LL_USART_PHASE_1EDGE) \
+ || ((__VALUE__) == LL_USART_PHASE_2EDGE))
+
+#define IS_LL_USART_CLOCKPOLARITY(__VALUE__) (((__VALUE__) == LL_USART_POLARITY_LOW) \
+ || ((__VALUE__) == LL_USART_POLARITY_HIGH))
+
+#define IS_LL_USART_CLOCKOUTPUT(__VALUE__) (((__VALUE__) == LL_USART_CLOCK_DISABLE) \
+ || ((__VALUE__) == LL_USART_CLOCK_ENABLE))
+
+#define IS_LL_USART_STOPBITS(__VALUE__) (((__VALUE__) == LL_USART_STOPBITS_0_5) \
+ || ((__VALUE__) == LL_USART_STOPBITS_1) \
+ || ((__VALUE__) == LL_USART_STOPBITS_1_5) \
+ || ((__VALUE__) == LL_USART_STOPBITS_2))
+
+#define IS_LL_USART_HWCONTROL(__VALUE__) (((__VALUE__) == LL_USART_HWCONTROL_NONE) \
+ || ((__VALUE__) == LL_USART_HWCONTROL_RTS) \
+ || ((__VALUE__) == LL_USART_HWCONTROL_CTS) \
+ || ((__VALUE__) == LL_USART_HWCONTROL_RTS_CTS))
+
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup USART_LL_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup USART_LL_EF_Init
+ * @{
+ */
+
+/**
+ * @brief De-initialize USART registers (Registers restored to their default values).
+ * @param USARTx USART Instance
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: USART registers are de-initialized
+ * - ERROR: USART registers are not de-initialized
+ */
+ErrorStatus LL_USART_DeInit(USART_TypeDef *USARTx)
+{
+ ErrorStatus status = SUCCESS;
+
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(USARTx));
+
+ if (USARTx == USART1)
+ {
+ /* Force reset of USART clock */
+ LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_USART1);
+
+ /* Release reset of USART clock */
+ LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_USART1);
+ }
+ else if (USARTx == USART2)
+ {
+ /* Force reset of USART clock */
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_USART2);
+
+ /* Release reset of USART clock */
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_USART2);
+ }
+#if defined(USART3)
+ else if (USARTx == USART3)
+ {
+ /* Force reset of USART clock */
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_USART3);
+
+ /* Release reset of USART clock */
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_USART3);
+ }
+#endif /* USART3 */
+#if defined(UART4)
+ else if (USARTx == UART4)
+ {
+ /* Force reset of UART clock */
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_UART4);
+
+ /* Release reset of UART clock */
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_UART4);
+ }
+#endif /* UART4 */
+#if defined(UART5)
+ else if (USARTx == UART5)
+ {
+ /* Force reset of UART clock */
+ LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_UART5);
+
+ /* Release reset of UART clock */
+ LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_UART5);
+ }
+#endif /* UART5 */
+ else
+ {
+ status = ERROR;
+ }
+
+ return (status);
+}
+
+/**
+ * @brief Initialize USART registers according to the specified
+ * parameters in USART_InitStruct.
+ * @note As some bits in USART configuration registers can only be written when the USART is disabled (USART_CR1_UE bit =0),
+ * USART IP should be in disabled state prior calling this function. Otherwise, ERROR result will be returned.
+ * @note Baud rate value stored in USART_InitStruct BaudRate field, should be valid (different from 0).
+ * @param USARTx USART Instance
+ * @param USART_InitStruct: pointer to a LL_USART_InitTypeDef structure
+ * that contains the configuration information for the specified USART peripheral.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: USART registers are initialized according to USART_InitStruct content
+ * - ERROR: Problem occurred during USART Registers initialization
+ */
+ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, LL_USART_InitTypeDef *USART_InitStruct)
+{
+ ErrorStatus status = ERROR;
+ uint32_t periphclk = LL_RCC_PERIPH_FREQUENCY_NO;
+ LL_RCC_ClocksTypeDef rcc_clocks;
+
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(USARTx));
+ assert_param(IS_LL_USART_BAUDRATE(USART_InitStruct->BaudRate));
+ assert_param(IS_LL_USART_DATAWIDTH(USART_InitStruct->DataWidth));
+ assert_param(IS_LL_USART_STOPBITS(USART_InitStruct->StopBits));
+ assert_param(IS_LL_USART_PARITY(USART_InitStruct->Parity));
+ assert_param(IS_LL_USART_DIRECTION(USART_InitStruct->TransferDirection));
+ assert_param(IS_LL_USART_HWCONTROL(USART_InitStruct->HardwareFlowControl));
+#if defined(USART_CR1_OVER8)
+ assert_param(IS_LL_USART_OVERSAMPLING(USART_InitStruct->OverSampling));
+#endif /* USART_OverSampling_Feature */
+
+ /* USART needs to be in disabled state, in order to be able to configure some bits in
+ CRx registers */
+ if (LL_USART_IsEnabled(USARTx) == 0U)
+ {
+ /*---------------------------- USART CR1 Configuration -----------------------
+ * Configure USARTx CR1 (USART Word Length, Parity, Mode and Oversampling bits) with parameters:
+ * - DataWidth: USART_CR1_M bits according to USART_InitStruct->DataWidth value
+ * - Parity: USART_CR1_PCE, USART_CR1_PS bits according to USART_InitStruct->Parity value
+ * - TransferDirection: USART_CR1_TE, USART_CR1_RE bits according to USART_InitStruct->TransferDirection value
+ * - Oversampling: USART_CR1_OVER8 bit according to USART_InitStruct->OverSampling value.
+ */
+#if defined(USART_CR1_OVER8)
+ MODIFY_REG(USARTx->CR1,
+ (USART_CR1_M | USART_CR1_PCE | USART_CR1_PS |
+ USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8),
+ (USART_InitStruct->DataWidth | USART_InitStruct->Parity |
+ USART_InitStruct->TransferDirection | USART_InitStruct->OverSampling));
+#else
+ MODIFY_REG(USARTx->CR1,
+ (USART_CR1_M | USART_CR1_PCE | USART_CR1_PS |
+ USART_CR1_TE | USART_CR1_RE),
+ (USART_InitStruct->DataWidth | USART_InitStruct->Parity |
+ USART_InitStruct->TransferDirection));
+#endif /* USART_OverSampling_Feature */
+
+ /*---------------------------- USART CR2 Configuration -----------------------
+ * Configure USARTx CR2 (Stop bits) with parameters:
+ * - Stop Bits: USART_CR2_STOP bits according to USART_InitStruct->StopBits value.
+ * - CLKEN, CPOL, CPHA and LBCL bits are to be configured using LL_USART_ClockInit().
+ */
+ LL_USART_SetStopBitsLength(USARTx, USART_InitStruct->StopBits);
+
+ /*---------------------------- USART CR3 Configuration -----------------------
+ * Configure USARTx CR3 (Hardware Flow Control) with parameters:
+ * - HardwareFlowControl: USART_CR3_RTSE, USART_CR3_CTSE bits according to USART_InitStruct->HardwareFlowControl value.
+ */
+ LL_USART_SetHWFlowCtrl(USARTx, USART_InitStruct->HardwareFlowControl);
+
+ /*---------------------------- USART BRR Configuration -----------------------
+ * Retrieve Clock frequency used for USART Peripheral
+ */
+ LL_RCC_GetSystemClocksFreq(&rcc_clocks);
+ if (USARTx == USART1)
+ {
+ periphclk = rcc_clocks.PCLK2_Frequency;
+ }
+ else if (USARTx == USART2)
+ {
+ periphclk = rcc_clocks.PCLK1_Frequency;
+ }
+#if defined(USART3)
+ else if (USARTx == USART3)
+ {
+ periphclk = rcc_clocks.PCLK1_Frequency;
+ }
+#endif /* USART3 */
+#if defined(UART4)
+ else if (USARTx == UART4)
+ {
+ periphclk = rcc_clocks.PCLK1_Frequency;
+ }
+#endif /* UART4 */
+#if defined(UART5)
+ else if (USARTx == UART5)
+ {
+ periphclk = rcc_clocks.PCLK1_Frequency;
+ }
+#endif /* UART5 */
+ else
+ {
+ /* Nothing to do, as error code is already assigned to ERROR value */
+ }
+
+ /* Configure the USART Baud Rate :
+ - valid baud rate value (different from 0) is required
+ - Peripheral clock as returned by RCC service, should be valid (different from 0).
+ */
+ if ((periphclk != LL_RCC_PERIPH_FREQUENCY_NO)
+ && (USART_InitStruct->BaudRate != 0U))
+ {
+ status = SUCCESS;
+#if defined(USART_CR1_OVER8)
+ LL_USART_SetBaudRate(USARTx,
+ periphclk,
+ USART_InitStruct->OverSampling,
+ USART_InitStruct->BaudRate);
+#else
+ LL_USART_SetBaudRate(USARTx,
+ periphclk,
+ USART_InitStruct->BaudRate);
+#endif /* USART_OverSampling_Feature */
+ }
+ }
+ /* Endif (=> USART not in Disabled state => return ERROR) */
+
+ return (status);
+}
+
+/**
+ * @brief Set each @ref LL_USART_InitTypeDef field to default value.
+ * @param USART_InitStruct: pointer to a @ref LL_USART_InitTypeDef structure
+ * whose fields will be set to default values.
+ * @retval None
+ */
+
+void LL_USART_StructInit(LL_USART_InitTypeDef *USART_InitStruct)
+{
+ /* Set USART_InitStruct fields to default values */
+ USART_InitStruct->BaudRate = 9600U;
+ USART_InitStruct->DataWidth = LL_USART_DATAWIDTH_8B;
+ USART_InitStruct->StopBits = LL_USART_STOPBITS_1;
+ USART_InitStruct->Parity = LL_USART_PARITY_NONE ;
+ USART_InitStruct->TransferDirection = LL_USART_DIRECTION_TX_RX;
+ USART_InitStruct->HardwareFlowControl = LL_USART_HWCONTROL_NONE;
+#if defined(USART_CR1_OVER8)
+ USART_InitStruct->OverSampling = LL_USART_OVERSAMPLING_16;
+#endif /* USART_OverSampling_Feature */
+}
+
+/**
+ * @brief Initialize USART Clock related settings according to the
+ * specified parameters in the USART_ClockInitStruct.
+ * @note As some bits in USART configuration registers can only be written when the USART is disabled (USART_CR1_UE bit =0),
+ * USART IP should be in disabled state prior calling this function. Otherwise, ERROR result will be returned.
+ * @param USARTx USART Instance
+ * @param USART_ClockInitStruct: pointer to a @ref LL_USART_ClockInitTypeDef structure
+ * that contains the Clock configuration information for the specified USART peripheral.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: USART registers related to Clock settings are initialized according to USART_ClockInitStruct content
+ * - ERROR: Problem occurred during USART Registers initialization
+ */
+ErrorStatus LL_USART_ClockInit(USART_TypeDef *USARTx, LL_USART_ClockInitTypeDef *USART_ClockInitStruct)
+{
+ ErrorStatus status = SUCCESS;
+
+ /* Check USART Instance and Clock signal output parameters */
+ assert_param(IS_UART_INSTANCE(USARTx));
+ assert_param(IS_LL_USART_CLOCKOUTPUT(USART_ClockInitStruct->ClockOutput));
+
+ /* USART needs to be in disabled state, in order to be able to configure some bits in
+ CRx registers */
+ if (LL_USART_IsEnabled(USARTx) == 0U)
+ {
+ /*---------------------------- USART CR2 Configuration -----------------------*/
+ /* If Clock signal has to be output */
+ if (USART_ClockInitStruct->ClockOutput == LL_USART_CLOCK_DISABLE)
+ {
+ /* Deactivate Clock signal delivery :
+ * - Disable Clock Output: USART_CR2_CLKEN cleared
+ */
+ LL_USART_DisableSCLKOutput(USARTx);
+ }
+ else
+ {
+ /* Ensure USART instance is USART capable */
+ assert_param(IS_USART_INSTANCE(USARTx));
+
+ /* Check clock related parameters */
+ assert_param(IS_LL_USART_CLOCKPOLARITY(USART_ClockInitStruct->ClockPolarity));
+ assert_param(IS_LL_USART_CLOCKPHASE(USART_ClockInitStruct->ClockPhase));
+ assert_param(IS_LL_USART_LASTBITCLKOUTPUT(USART_ClockInitStruct->LastBitClockPulse));
+
+ /*---------------------------- USART CR2 Configuration -----------------------
+ * Configure USARTx CR2 (Clock signal related bits) with parameters:
+ * - Enable Clock Output: USART_CR2_CLKEN set
+ * - Clock Polarity: USART_CR2_CPOL bit according to USART_ClockInitStruct->ClockPolarity value
+ * - Clock Phase: USART_CR2_CPHA bit according to USART_ClockInitStruct->ClockPhase value
+ * - Last Bit Clock Pulse Output: USART_CR2_LBCL bit according to USART_ClockInitStruct->LastBitClockPulse value.
+ */
+ MODIFY_REG(USARTx->CR2,
+ USART_CR2_CLKEN | USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_LBCL,
+ USART_CR2_CLKEN | USART_ClockInitStruct->ClockPolarity |
+ USART_ClockInitStruct->ClockPhase | USART_ClockInitStruct->LastBitClockPulse);
+ }
+ }
+ /* Else (USART not in Disabled state => return ERROR */
+ else
+ {
+ status = ERROR;
+ }
+
+ return (status);
+}
+
+/**
+ * @brief Set each field of a @ref LL_USART_ClockInitTypeDef type structure to default value.
+ * @param USART_ClockInitStruct: pointer to a @ref LL_USART_ClockInitTypeDef structure
+ * whose fields will be set to default values.
+ * @retval None
+ */
+void LL_USART_ClockStructInit(LL_USART_ClockInitTypeDef *USART_ClockInitStruct)
+{
+ /* Set LL_USART_ClockInitStruct fields with default values */
+ USART_ClockInitStruct->ClockOutput = LL_USART_CLOCK_DISABLE;
+ USART_ClockInitStruct->ClockPolarity = LL_USART_POLARITY_LOW; /* Not relevant when ClockOutput = LL_USART_CLOCK_DISABLE */
+ USART_ClockInitStruct->ClockPhase = LL_USART_PHASE_1EDGE; /* Not relevant when ClockOutput = LL_USART_CLOCK_DISABLE */
+ USART_ClockInitStruct->LastBitClockPulse = LL_USART_LASTCLKPULSE_NO_OUTPUT; /* Not relevant when ClockOutput = LL_USART_CLOCK_DISABLE */
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* USART1 || USART2 || USART3 || UART4 || UART5 */
+
+/**
+ * @}
+ */
+
+#endif /* USE_FULL_LL_DRIVER */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usb.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usb.c
new file mode 100644
index 0000000..1ee33c1
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usb.c
@@ -0,0 +1,2336 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_usb.c
+ * @author MCD Application Team
+ * @brief USB Low Layer HAL module driver.
+ *
+ * This file provides firmware functions to manage the following
+ * functionalities of the USB Peripheral Controller:
+ * + Initialization/de-initialization functions
+ * + I/O operation functions
+ * + Peripheral Control functions
+ * + Peripheral State functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure.
+
+ (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
+
+ (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup USB_LL USB Low Layer
+ * @brief Low layer module for USB_FS and USB_OTG_FS drivers
+ * @{
+ */
+
+#if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
+
+#if defined(STM32F102x6) || defined(STM32F102xB) || \
+ defined(STM32F103x6) || defined(STM32F103xB) || \
+ defined(STM32F103xE) || defined(STM32F103xG) || \
+ defined(STM32F105xC) || defined(STM32F107xC)
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+#if defined (USB_OTG_FS)
+/** @defgroup USB_LL_Private_Functions USB Low Layer Private Functions
+ * @{
+ */
+static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
+/**
+ * @}
+ */
+#endif /* USB_OTG_FS */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup USB_LL_Exported_Functions USB Low Layer Exported Functions
+ * @{
+ */
+
+/** @defgroup USB_LL_Exported_Functions_Group1 Peripheral Control functions
+ * @brief management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the PCD data
+ transfers.
+
+@endverbatim
+ * @{
+ */
+
+/*==============================================================================
+ USB OTG FS peripheral available on STM32F105xx and STM32F107xx devices
+==============================================================================*/
+#if defined (USB_OTG_FS)
+
+/**
+ * @brief Initializes the USB Core
+ * @param USBx: USB Instance
+ * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
+ * the configuration information for the specified USBx peripheral.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(cfg);
+
+ /* Select FS Embedded PHY */
+ USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
+
+ /* Reset after a PHY select and set Host mode */
+ USB_CoreReset(USBx);
+
+ /* Deactivate the power down*/
+ USBx->GCCFG = USB_OTG_GCCFG_PWRDWN;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_EnableGlobalInt
+ * Enables the controller's Global Int in the AHB Config reg
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
+{
+ USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DisableGlobalInt
+ * Disable the controller's Global Int in the AHB Config reg
+ * @param USBx : Selected device
+ * @retval HAL status
+*/
+HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
+{
+ USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_SetCurrentMode : Set functional mode
+ * @param USBx : Selected device
+ * @param mode : current core mode
+ * This parameter can be one of the these values:
+ * @arg USB_DEVICE_MODE: Peripheral mode mode
+ * @arg USB_HOST_MODE: Host mode
+ * @arg USB_DRD_MODE: Dual Role Device mode
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx , USB_ModeTypeDef mode)
+{
+ USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
+
+ if ( mode == USB_HOST_MODE)
+ {
+ USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
+ }
+ else if (mode == USB_DEVICE_MODE)
+ {
+ USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
+ }
+ HAL_Delay(50);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DevInit : Initializes the USB_OTG controller registers
+ * for device mode
+ * @param USBx : Selected device
+ * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
+ * the configuration information for the specified USBx peripheral.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DevInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
+{
+ uint32_t index = 0;
+
+ for (index = 0; index < 15 ; index++)
+ {
+ USBx->DIEPTXF[index] = 0;
+ }
+
+ /*Activate VBUS Sensing B */
+ USBx->GCCFG |= USB_OTG_GCCFG_VBUSBSEN;
+
+ /* Restart the Phy Clock */
+ USBx_PCGCCTL = 0;
+
+ /* Device mode configuration */
+ USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80;
+
+ /* Set Full speed phy */
+ USB_SetDevSpeed (USBx , USB_OTG_SPEED_FULL);
+
+ /* Flush the FIFOs */
+ USB_FlushTxFifo(USBx , 0x10); /* all Tx FIFOs */
+ USB_FlushRxFifo(USBx);
+
+ /* Clear all pending Device Interrupts */
+ USBx_DEVICE->DIEPMSK = 0;
+ USBx_DEVICE->DOEPMSK = 0;
+ USBx_DEVICE->DAINT = 0xFFFFFFFF;
+ USBx_DEVICE->DAINTMSK = 0;
+
+ for (index = 0; index < cfg.dev_endpoints; index++)
+ {
+ if ((USBx_INEP(index)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
+ {
+ USBx_INEP(index)->DIEPCTL = (USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK);
+ }
+ else
+ {
+ USBx_INEP(index)->DIEPCTL = 0;
+ }
+
+ USBx_INEP(index)->DIEPTSIZ = 0;
+ USBx_INEP(index)->DIEPINT = 0xFF;
+ }
+
+ for (index = 0; index < cfg.dev_endpoints; index++)
+ {
+ if ((USBx_OUTEP(index)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
+ {
+ USBx_OUTEP(index)->DOEPCTL = (USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK);
+ }
+ else
+ {
+ USBx_OUTEP(index)->DOEPCTL = 0;
+ }
+
+ USBx_OUTEP(index)->DOEPTSIZ = 0;
+ USBx_OUTEP(index)->DOEPINT = 0xFF;
+ }
+
+ USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
+
+ /* Disable all interrupts. */
+ USBx->GINTMSK = 0;
+
+ /* Clear any pending interrupts */
+ USBx->GINTSTS = 0xBFFFFFFF;
+
+ /* Enable the common interrupts */
+ USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
+
+ /* Enable interrupts matching to the Device mode ONLY */
+ USBx->GINTMSK |= (USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |\
+ USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |\
+ USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM|\
+ USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
+
+ if(cfg.Sof_enable)
+ {
+ USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
+ }
+
+ if (cfg.vbus_sensing_enable == ENABLE)
+ {
+ USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO
+ * @param USBx : Selected device
+ * @param num : FIFO number
+ * This parameter can be a value from 1 to 15
+ 15 means Flush all Tx FIFOs
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_FlushTxFifo (USB_OTG_GlobalTypeDef *USBx, uint32_t num )
+{
+ uint32_t count = 0;
+
+ USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH |(uint32_t)(num << 6));
+
+ do
+ {
+ if (++count > 200000)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_FlushRxFifo : Flush Rx FIFO
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
+{
+ uint32_t count = 0;
+
+ USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
+
+ do
+ {
+ if (++count > 200000)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_SetDevSpeed :Initializes the DevSpd field of DCFG register
+ * depending the PHY type and the enumeration speed of the device.
+ * @param USBx : Selected device
+ * @param speed : device speed
+ * This parameter can be one of the these values:
+ * @arg USB_OTG_SPEED_FULL: Full speed mode
+ * @arg USB_OTG_SPEED_LOW: Low speed mode
+ * @retval Hal status
+ */
+HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx , uint8_t speed)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ USBx_DEVICE->DCFG |= speed;
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_GetDevSpeed :Return the Dev Speed
+ * @param USBx : Selected device
+ * @retval speed : device speed
+ * This parameter can be one of the these values:
+ * @arg USB_OTG_SPEED_FULL: Full speed mode
+ * @arg USB_OTG_SPEED_LOW: Low speed mode
+ */
+uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx)
+{
+ uint8_t speed = 0;
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ if (((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ)||
+ ((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_48MHZ))
+ {
+ speed = USB_OTG_SPEED_FULL;
+ }
+ else if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ)
+ {
+ speed = USB_OTG_SPEED_LOW;
+ }
+
+ return speed;
+}
+
+/**
+ * @brief Activate and configure an endpoint
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ if (ep->is_in)
+ {
+ /* Assign a Tx FIFO */
+ ep->tx_fifo_num = ep->num;
+ }
+ /* Set initial data PID. */
+ if (ep->type == EP_TYPE_BULK )
+ {
+ ep->data_pid_start = 0;
+ }
+
+ if (ep->is_in == 1)
+ {
+ USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)));
+
+ if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0)
+ {
+ USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\
+ ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP));
+ }
+ }
+ else
+ {
+ USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16);
+
+ if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0)
+ {
+ USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\
+ (USB_OTG_DIEPCTL_SD0PID_SEVNFRM)| (USB_OTG_DOEPCTL_USBAEP));
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief De-activate and de-initialize an endpoint
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ /* Read DEPCTLn register */
+ if (ep->is_in == 1)
+ {
+ USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))));
+ USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))));
+ USBx_INEP(ep->num)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
+ }
+ else
+ {
+ USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));
+ USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));
+ USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_EPStartXfer : setup and starts a transfer over an EP
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep)
+{
+ uint16_t pktcnt = 0;
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ /* IN endpoint */
+ if (ep->is_in == 1)
+ {
+ /* Zero Length Packet? */
+ if (ep->xfer_len == 0)
+ {
+ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
+ USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ;
+ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
+ }
+ else
+ {
+ /* Program the transfer size and packet count
+ * as follows: xfersize = N * maxpacket +
+ * short_packet pktcnt = N + (short_packet
+ * exist ? 1 : 0)
+ */
+ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
+ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
+ USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (((ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket) << 19)) ;
+ USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
+
+ if (ep->type == EP_TYPE_ISOC)
+ {
+ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
+ USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1 << 29));
+ }
+ }
+
+ if (ep->type != EP_TYPE_ISOC)
+ {
+ /* Enable the Tx FIFO Empty Interrupt for this EP */
+ if (ep->xfer_len > 0)
+ {
+ USBx_DEVICE->DIEPEMPMSK |= 1 << ep->num;
+ }
+ }
+
+ if (ep->type == EP_TYPE_ISOC)
+ {
+ if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0)
+ {
+ USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
+ }
+ else
+ {
+ USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
+ }
+ }
+
+ /* EP enable, IN data in FIFO */
+ USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
+
+ if (ep->type == EP_TYPE_ISOC)
+ {
+ USB_WritePacket(USBx, ep->xfer_buff, ep->num, ep->xfer_len);
+ }
+ }
+ else /* OUT endpoint */
+ {
+ /* Program the transfer size and packet count as follows:
+ * pktcnt = N
+ * xfersize = N * maxpacket
+ */
+ USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
+ USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
+
+ if (ep->xfer_len == 0)
+ {
+ USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
+ USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19));
+ }
+ else
+ {
+ pktcnt = (ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket;
+ USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (pktcnt << 19));
+ USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt));
+ }
+
+ if (ep->type == EP_TYPE_ISOC)
+ {
+ if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0)
+ {
+ USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
+ }
+ else
+ {
+ USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
+ }
+ }
+ /* EP enable */
+ USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_EP0StartXfer : setup and starts a transfer over the EP 0
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ /* IN endpoint */
+ if (ep->is_in == 1)
+ {
+ /* Zero Length Packet? */
+ if (ep->xfer_len == 0)
+ {
+ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
+ USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19));
+ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
+ }
+ else
+ {
+ /* Program the transfer size and packet count
+ * as follows: xfersize = N * maxpacket +
+ * short_packet pktcnt = N + (short_packet
+ * exist ? 1 : 0)
+ */
+ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
+ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
+
+ if(ep->xfer_len > ep->maxpacket)
+ {
+ ep->xfer_len = ep->maxpacket;
+ }
+ USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19));
+ USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
+ }
+
+ /* Enable the Tx FIFO Empty Interrupt for this EP */
+ if (ep->xfer_len > 0)
+ {
+ USBx_DEVICE->DIEPEMPMSK |= 1 << (ep->num);
+ }
+
+ /* EP enable, IN data in FIFO */
+ USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
+ }
+ else /* OUT endpoint */
+ {
+ /* Program the transfer size and packet count as follows:
+ * pktcnt = N
+ * xfersize = N * maxpacket
+ */
+ USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
+ USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
+
+ if (ep->xfer_len > 0)
+ {
+ ep->xfer_len = ep->maxpacket;
+ }
+
+ USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19));
+ USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket));
+
+ /* EP enable */
+ USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
+ * with the EP/channel
+ * @param USBx : Selected device
+ * @param src : pointer to source buffer
+ * @param ch_ep_num : endpoint or host channel number
+ * @param len : Number of bytes to write
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len)
+{
+ uint32_t count32b = 0 , index = 0;
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ count32b = (len + 3) / 4;
+ for (index = 0; index < count32b; index++, src += 4)
+ {
+ USBx_DFIFO(ch_ep_num) = *((__packed uint32_t *)src);
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_ReadPacket : read a packet from the Tx FIFO associated
+ * with the EP/channel
+ * @param USBx : Selected device
+ * @param dest : destination pointer
+ * @param len : Number of bytes to read
+ * @retval pointer to destination buffer
+ */
+void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
+{
+ uint32_t index = 0;
+ uint32_t count32b = (len + 3) / 4;
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ for ( index = 0; index < count32b; index++, dest += 4 )
+ {
+ *(__packed uint32_t *)dest = USBx_DFIFO(0);
+
+ }
+ return ((void *)dest);
+}
+
+/**
+ * @brief USB_EPSetStall : set a stall condition over an EP
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ if (ep->is_in == 1)
+ {
+ if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == 0)
+ {
+ USBx_INEP(ep->num)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
+ }
+ USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
+ }
+ else
+ {
+ if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == 0)
+ {
+ USBx_OUTEP(ep->num)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
+ }
+ USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_EPClearStall : Clear a stall condition over an EP
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ if (ep->is_in == 1)
+ {
+ USBx_INEP(ep->num)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
+ if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
+ {
+ USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
+ }
+ }
+ else
+ {
+ USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
+ if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
+ {
+ USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_StopDevice : Stop the usb device mode
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
+{
+ uint32_t index = 0;
+
+ /* Clear Pending interrupt */
+ for (index = 0; index < 15 ; index++)
+ {
+ USBx_INEP(index)->DIEPINT = 0xFF;
+ USBx_OUTEP(index)->DOEPINT = 0xFF;
+ }
+ USBx_DEVICE->DAINT = 0xFFFFFFFF;
+
+ /* Clear interrupt masks */
+ USBx_DEVICE->DIEPMSK = 0;
+ USBx_DEVICE->DOEPMSK = 0;
+ USBx_DEVICE->DAINTMSK = 0;
+
+ /* Flush the FIFO */
+ USB_FlushRxFifo(USBx);
+ USB_FlushTxFifo(USBx , 0x10 );
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_SetDevAddress : Stop the usb device mode
+ * @param USBx : Selected device
+ * @param address : new device address to be assigned
+ * This parameter can be a value from 0 to 255
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_SetDevAddress (USB_OTG_GlobalTypeDef *USBx, uint8_t address)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ UNUSED(address);
+ USBx_DEVICE->DCFG &= ~ (USB_OTG_DCFG_DAD);
+ USBx_DEVICE->DCFG |= (address << 4) & USB_OTG_DCFG_DAD;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DevConnect (USB_OTG_GlobalTypeDef *USBx)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS ;
+ HAL_Delay(3);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DevDisconnect (USB_OTG_GlobalTypeDef *USBx)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
+ HAL_Delay(3);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_ReadInterrupts: return the global USB interrupt status
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+uint32_t USB_ReadInterrupts (USB_OTG_GlobalTypeDef *USBx)
+{
+ uint32_t tmpreg = 0;
+
+ tmpreg = USBx->GINTSTS;
+ tmpreg &= USBx->GINTMSK;
+ return tmpreg;
+}
+
+/**
+ * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+uint32_t USB_ReadDevAllOutEpInterrupt (USB_OTG_GlobalTypeDef *USBx)
+{
+ uint32_t tmpreg = 0;
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ tmpreg = USBx_DEVICE->DAINT;
+ tmpreg &= USBx_DEVICE->DAINTMSK;
+ return ((tmpreg & 0xffff0000) >> 16);
+}
+
+/**
+ * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+uint32_t USB_ReadDevAllInEpInterrupt (USB_OTG_GlobalTypeDef *USBx)
+{
+ uint32_t tmpreg = 0;
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ tmpreg = USBx_DEVICE->DAINT;
+ tmpreg &= USBx_DEVICE->DAINTMSK;
+ return ((tmpreg & 0xFFFF));
+}
+
+/**
+ * @brief Returns Device OUT EP Interrupt register
+ * @param USBx : Selected device
+ * @param epnum : endpoint number
+ * This parameter can be a value from 0 to 15
+ * @retval Device OUT EP Interrupt register
+ */
+uint32_t USB_ReadDevOutEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ uint32_t tmpreg = 0;
+ tmpreg = USBx_OUTEP(epnum)->DOEPINT;
+ tmpreg &= USBx_DEVICE->DOEPMSK;
+ return tmpreg;
+}
+
+/**
+ * @brief Returns Device IN EP Interrupt register
+ * @param USBx : Selected device
+ * @param epnum : endpoint number
+ * This parameter can be a value from 0 to 15
+ * @retval Device IN EP Interrupt register
+ */
+uint32_t USB_ReadDevInEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum)
+{
+ uint32_t tmpreg = 0, msk = 0, emp = 0;
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ msk = USBx_DEVICE->DIEPMSK;
+ emp = USBx_DEVICE->DIEPEMPMSK;
+ msk |= ((emp >> epnum) & 0x1) << 7;
+ tmpreg = USBx_INEP(epnum)->DIEPINT & msk;
+ return tmpreg;
+}
+
+/**
+ * @brief USB_ClearInterrupts: clear a USB interrupt
+ * @param USBx : Selected device
+ * @param interrupt : interrupt flag
+ * @retval None
+ */
+void USB_ClearInterrupts (USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
+{
+ USBx->GINTSTS |= interrupt;
+}
+
+/**
+ * @brief Returns USB core mode
+ * @param USBx : Selected device
+ * @retval return core mode : Host or Device
+ * This parameter can be one of the these values:
+ * 0 : Host
+ * 1 : Device
+ */
+uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ return ((USBx->GINTSTS ) & 0x1);
+}
+
+/**
+ * @brief Activate EP0 for Setup transactions
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_ActivateSetup (USB_OTG_GlobalTypeDef *USBx)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ /* Set the MPS of the IN EP based on the enumeration speed */
+ USBx_INEP(0)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
+
+ if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ)
+ {
+ USBx_INEP(0)->DIEPCTL |= 3;
+ }
+ USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Prepare the EP0 to start the first control setup
+ * @param USBx : Selected device
+ * @param psetup : pointer to setup packet
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t *psetup)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ UNUSED(psetup);
+ USBx_OUTEP(0)->DOEPTSIZ = 0;
+ USBx_OUTEP(0)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19));
+ USBx_OUTEP(0)->DOEPTSIZ |= (3 * 8);
+ USBx_OUTEP(0)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_HostInit : Initializes the USB OTG controller registers
+ * for Host mode
+ * @param USBx : Selected device
+ * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
+ * the configuration information for the specified USBx peripheral.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_HostInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
+{
+ uint32_t index = 0;
+
+ /* Restart the Phy Clock */
+ USBx_PCGCCTL = 0;
+
+ /* no VBUS sensing*/
+ USBx->GCCFG &=~ (USB_OTG_GCCFG_VBUSASEN);
+ USBx->GCCFG &=~ (USB_OTG_GCCFG_VBUSBSEN);
+
+ /* Disable the FS/LS support mode only */
+ if((cfg.speed == USB_OTG_SPEED_FULL)&&
+ (USBx != USB_OTG_FS))
+ {
+ USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS;
+ }
+ else
+ {
+ USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
+ }
+
+ /* Make sure the FIFOs are flushed. */
+ USB_FlushTxFifo(USBx, 0x10 ); /* all Tx FIFOs */
+ USB_FlushRxFifo(USBx);
+
+ /* Clear all pending HC Interrupts */
+ for (index = 0; index < cfg.Host_channels; index++)
+ {
+ USBx_HC(index)->HCINT = 0xFFFFFFFF;
+ USBx_HC(index)->HCINTMSK = 0;
+ }
+
+ /* Enable VBUS driving */
+ USB_DriveVbus(USBx, 1);
+
+ HAL_Delay(200);
+
+ /* Disable all interrupts. */
+ USBx->GINTMSK = 0;
+
+ /* Clear any pending interrupts */
+ USBx->GINTSTS = 0xFFFFFFFF;
+
+ if(USBx == USB_OTG_FS)
+ {
+ /* set Rx FIFO size */
+ USBx->GRXFSIZ = (uint32_t )0x80;
+ USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x60 << 16)& USB_OTG_NPTXFD) | 0x80);
+ USBx->HPTXFSIZ = (uint32_t )(((0x40 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0);
+ }
+
+ /* Enable the common interrupts */
+ USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
+
+ /* Enable interrupts matching to the Host mode ONLY */
+ USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM |\
+ USB_OTG_GINTMSK_SOFM |USB_OTG_GINTSTS_DISCINT|\
+ USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
+ * HCFG register on the PHY type and set the right frame interval
+ * @param USBx : Selected device
+ * @param freq : clock frequency
+ * This parameter can be one of the these values:
+ * HCFG_48_MHZ : Full Speed 48 MHz Clock
+ * HCFG_6_MHZ : Low Speed 6 MHz Clock
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx , uint8_t freq)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
+ USBx_HOST->HCFG |= (freq & USB_OTG_HCFG_FSLSPCS);
+
+ if (freq == HCFG_48_MHZ)
+ {
+ USBx_HOST->HFIR = (uint32_t)48000;
+ }
+ else if (freq == HCFG_6_MHZ)
+ {
+ USBx_HOST->HFIR = (uint32_t)6000;
+ }
+ return HAL_OK;
+}
+
+/**
+* @brief USB_OTG_ResetPort : Reset Host Port
+ * @param USBx : Selected device
+ * @retval HAL status
+ * @note : (1)The application must wait at least 10 ms
+ * before clearing the reset bit.
+ */
+HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx)
+{
+ __IO uint32_t hprt0 = 0;
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ hprt0 = USBx_HPRT0;
+
+ hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
+ USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
+
+ USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
+ HAL_Delay (10); /* See Note #1 */
+ USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DriveVbus : activate or de-activate vbus
+ * @param state : VBUS state
+ * This parameter can be one of the these values:
+ * 0 : VBUS Active
+ * 1 : VBUS Inactive
+ * @retval HAL status
+*/
+HAL_StatusTypeDef USB_DriveVbus (USB_OTG_GlobalTypeDef *USBx, uint8_t state)
+{
+ __IO uint32_t hprt0 = 0;
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ hprt0 = USBx_HPRT0;
+ hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
+ USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
+
+ if (((hprt0 & USB_OTG_HPRT_PPWR) == 0 ) && (state == 1 ))
+ {
+ USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
+ }
+ if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0 ))
+ {
+ USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief Return Host Core speed
+ * @param USBx : Selected device
+ * @retval speed : Host speed
+ * This parameter can be one of the these values:
+ * @arg USB_OTG_SPEED_FULL: Full speed mode
+ * @arg USB_OTG_SPEED_LOW: Low speed mode
+ */
+uint32_t USB_GetHostSpeed (USB_OTG_GlobalTypeDef *USBx)
+{
+ __IO uint32_t hprt0 = 0;
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ hprt0 = USBx_HPRT0;
+ return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
+}
+
+/**
+ * @brief Return Host Current Frame number
+ * @param USBx : Selected device
+ * @retval current frame number
+*/
+uint32_t USB_GetCurrentFrame (USB_OTG_GlobalTypeDef *USBx)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
+}
+
+/**
+ * @brief Initialize a host channel
+ * @param USBx : Selected device
+ * @param ch_num : Channel number
+ * This parameter can be a value from 1 to 15
+ * @param epnum : Endpoint number
+ * This parameter can be a value from 1 to 15
+ * @param dev_address : Current device address
+ * This parameter can be a value from 0 to 255
+ * @param speed : Current device speed
+ * This parameter can be one of the these values:
+ * @arg USB_OTG_SPEED_FULL: Full speed mode
+ * @arg USB_OTG_SPEED_LOW: Low speed mode
+ * @param ep_type : Endpoint Type
+ * This parameter can be one of the these values:
+ * @arg EP_TYPE_CTRL: Control type
+ * @arg EP_TYPE_ISOC: Isochronous type
+ * @arg EP_TYPE_BULK: Bulk type
+ * @arg EP_TYPE_INTR: Interrupt type
+ * @param mps : Max Packet Size
+ * This parameter can be a value from 0 to32K
+ * @retval HAL state
+ */
+HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx,
+ uint8_t ch_num,
+ uint8_t epnum,
+ uint8_t dev_address,
+ uint8_t speed,
+ uint8_t ep_type,
+ uint16_t mps)
+{
+ /* Clear old interrupt conditions for this host channel. */
+ USBx_HC(ch_num)->HCINT = 0xFFFFFFFF;
+
+ /* Enable channel interrupts required for this transfer. */
+ switch (ep_type)
+ {
+ case EP_TYPE_CTRL:
+ case EP_TYPE_BULK:
+ USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
+ USB_OTG_HCINTMSK_STALLM |\
+ USB_OTG_HCINTMSK_TXERRM |\
+ USB_OTG_HCINTMSK_DTERRM |\
+ USB_OTG_HCINTMSK_AHBERR |\
+ USB_OTG_HCINTMSK_NAKM ;
+
+ if (epnum & 0x80)
+ {
+ USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
+ }
+ break;
+
+ case EP_TYPE_INTR:
+ USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
+ USB_OTG_HCINTMSK_STALLM |\
+ USB_OTG_HCINTMSK_TXERRM |\
+ USB_OTG_HCINTMSK_DTERRM |\
+ USB_OTG_HCINTMSK_NAKM |\
+ USB_OTG_HCINTMSK_AHBERR |\
+ USB_OTG_HCINTMSK_FRMORM ;
+
+ if (epnum & 0x80)
+ {
+ USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
+ }
+
+ break;
+
+ case EP_TYPE_ISOC:
+ USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
+ USB_OTG_HCINTMSK_ACKM |\
+ USB_OTG_HCINTMSK_AHBERR |\
+ USB_OTG_HCINTMSK_FRMORM ;
+
+ if (epnum & 0x80)
+ {
+ USBx_HC(ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
+ }
+ break;
+ }
+
+ /* Enable the top level host channel interrupt. */
+ USBx_HOST->HAINTMSK |= (1 << ch_num);
+
+ /* Make sure host channel interrupts are enabled. */
+ USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
+
+ /* Program the HCCHAR register */
+ USBx_HC(ch_num)->HCCHAR = (((dev_address << 22) & USB_OTG_HCCHAR_DAD) |\
+ (((epnum & 0x7F)<< 11) & USB_OTG_HCCHAR_EPNUM)|\
+ ((((epnum & 0x80) == 0x80)<< 15) & USB_OTG_HCCHAR_EPDIR)|\
+ (((speed == HPRT0_PRTSPD_LOW_SPEED)<< 17) & USB_OTG_HCCHAR_LSDEV)|\
+ ((ep_type << 18) & USB_OTG_HCCHAR_EPTYP)|\
+ (mps & USB_OTG_HCCHAR_MPSIZ));
+
+ if (ep_type == EP_TYPE_INTR)
+ {
+ USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM ;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Start a transfer over a host channel
+ * @param USBx : Selected device
+ * @param hc : pointer to host channel structure
+ * @retval HAL state
+ */
+#if defined (__CC_ARM) /*!< ARM Compiler */
+#pragma O0
+#elif defined (__GNUC__) /*!< GNU Compiler */
+#pragma GCC optimize ("O0")
+#endif /* __CC_ARM */
+HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc)
+{
+ uint8_t is_oddframe = 0;
+ uint16_t len_words = 0;
+ uint16_t num_packets = 0;
+ uint16_t max_hc_pkt_count = 256;
+ uint32_t tmpreg = 0;
+
+ /* Compute the expected number of packets associated to the transfer */
+ if (hc->xfer_len > 0)
+ {
+ num_packets = (hc->xfer_len + hc->max_packet - 1) / hc->max_packet;
+
+ if (num_packets > max_hc_pkt_count)
+ {
+ num_packets = max_hc_pkt_count;
+ hc->xfer_len = num_packets * hc->max_packet;
+ }
+ }
+ else
+ {
+ num_packets = 1;
+ }
+ if (hc->ep_is_in)
+ {
+ hc->xfer_len = num_packets * hc->max_packet;
+ }
+
+ /* Initialize the HCTSIZn register */
+ USBx_HC(hc->ch_num)->HCTSIZ = (((hc->xfer_len) & USB_OTG_HCTSIZ_XFRSIZ)) |\
+ ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |\
+ (((hc->data_pid) << 29) & USB_OTG_HCTSIZ_DPID);
+
+ is_oddframe = (USBx_HOST->HFNUM & 0x01) ? 0 : 1;
+ USBx_HC(hc->ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
+ USBx_HC(hc->ch_num)->HCCHAR |= (is_oddframe << 29);
+
+ /* Set host channel enable */
+ tmpreg = USBx_HC(hc->ch_num)->HCCHAR;
+ tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
+ tmpreg |= USB_OTG_HCCHAR_CHENA;
+ USBx_HC(hc->ch_num)->HCCHAR = tmpreg;
+
+ if((hc->ep_is_in == 0) && (hc->xfer_len > 0))
+ {
+ switch(hc->ep_type)
+ {
+ /* Non periodic transfer */
+ case EP_TYPE_CTRL:
+ case EP_TYPE_BULK:
+ len_words = (hc->xfer_len + 3) / 4;
+
+ /* check if there is enough space in FIFO space */
+ if(len_words > (USBx->HNPTXSTS & 0xFFFF))
+ {
+ /* need to process data in nptxfempty interrupt */
+ USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
+ }
+ break;
+
+ /* Periodic transfer */
+ case EP_TYPE_INTR:
+ case EP_TYPE_ISOC:
+ len_words = (hc->xfer_len + 3) / 4;
+ /* check if there is enough space in FIFO space */
+ if(len_words > (USBx_HOST->HPTXSTS & 0xFFFF)) /* split the transfer */
+ {
+ /* need to process data in ptxfempty interrupt */
+ USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Write packet into the Tx FIFO. */
+ USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, hc->xfer_len);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Read all host channel interrupts status
+ * @param USBx : Selected device
+ * @retval HAL state
+ */
+uint32_t USB_HC_ReadInterrupt (USB_OTG_GlobalTypeDef *USBx)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ return ((USBx_HOST->HAINT) & 0xFFFF);
+}
+
+/**
+ * @brief Halt a host channel
+ * @param USBx : Selected device
+ * @param hc_num : Host Channel number
+ * This parameter can be a value from 1 to 15
+ * @retval HAL state
+ */
+HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx , uint8_t hc_num)
+{
+ uint32_t count = 0;
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ /* Check for space in the request queue to issue the halt. */
+ if (((((USBx_HC(hc_num)->HCCHAR) & USB_OTG_HCCHAR_EPTYP) >> 18) == HCCHAR_CTRL) ||
+ (((((USBx_HC(hc_num)->HCCHAR) & USB_OTG_HCCHAR_EPTYP) >> 18) == HCCHAR_BULK)))
+ {
+ USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
+
+ if ((USBx->HNPTXSTS & 0xFFFF) == 0)
+ {
+ USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
+ USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
+ USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
+ do
+ {
+ if (++count > 1000)
+ {
+ break;
+ }
+ }
+ while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
+ }
+ else
+ {
+ USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
+ }
+ }
+ else
+ {
+ USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
+
+ if ((USBx_HOST->HPTXSTS & 0xFFFF) == 0)
+ {
+ USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
+ USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
+ USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
+ do
+ {
+ if (++count > 1000)
+ {
+ break;
+ }
+ }
+ while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
+ }
+ else
+ {
+ USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initiate Do Ping protocol
+ * @param USBx : Selected device
+ * @param hc_num : Host Channel number
+ * This parameter can be a value from 1 to 15
+ * @retval HAL state
+ */
+HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx , uint8_t ch_num)
+{
+ uint8_t num_packets = 1;
+ uint32_t tmpreg = 0;
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+
+ USBx_HC(ch_num)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |\
+ USB_OTG_HCTSIZ_DOPING;
+
+ /* Set host channel enable */
+ tmpreg = USBx_HC(ch_num)->HCCHAR;
+ tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
+ tmpreg |= USB_OTG_HCCHAR_CHENA;
+ USBx_HC(ch_num)->HCCHAR = tmpreg;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Stop Host Core
+ * @param USBx : Selected device
+ * @retval HAL state
+ */
+HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
+{
+ uint8_t index;
+ uint32_t count = 0;
+ uint32_t value = 0;
+
+ USB_DisableGlobalInt(USBx);
+
+ /* Flush FIFO */
+ USB_FlushTxFifo(USBx, 0x10);
+ USB_FlushRxFifo(USBx);
+
+ /* Flush out any leftover queued requests. */
+ for (index = 0; index <= 15; index++)
+ {
+ value = USBx_HC(index)->HCCHAR;
+ value |= USB_OTG_HCCHAR_CHDIS;
+ value &= ~USB_OTG_HCCHAR_CHENA;
+ value &= ~USB_OTG_HCCHAR_EPDIR;
+ USBx_HC(index)->HCCHAR = value;
+ }
+
+ /* Halt all channels to put them into a known state. */
+ for (index = 0; index <= 15; index++)
+ {
+ value = USBx_HC(index)->HCCHAR ;
+ value |= USB_OTG_HCCHAR_CHDIS;
+ value |= USB_OTG_HCCHAR_CHENA;
+ value &= ~USB_OTG_HCCHAR_EPDIR;
+ USBx_HC(index)->HCCHAR = value;
+
+ do
+ {
+ if (++count > 1000)
+ {
+ break;
+ }
+ }
+ while ((USBx_HC(index)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
+ }
+
+ /* Clear any pending Host interrupts */
+ USBx_HOST->HAINT = 0xFFFFFFFF;
+ USBx->GINTSTS = 0xFFFFFFFF;
+ USB_EnableGlobalInt(USBx);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_ActivateRemoteWakeup : active remote wakeup signalling
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
+ {
+ /* active Remote wakeup signalling */
+ USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DeActivateRemoteWakeup : de-active remote wakeup signalling
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ /* active Remote wakeup signalling */
+ USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
+ return HAL_OK;
+}
+
+#endif /* USB_OTG_FS */
+
+/*==============================================================================
+ USB Device FS peripheral available on STM32F102xx and STM32F103xx devices
+==============================================================================*/
+#if defined (USB)
+/**
+ * @brief Initializes the USB Core
+ * @param USBx: USB Instance
+ * @param cfg : pointer to a USB_CfgTypeDef structure that contains
+ * the configuration information for the specified USBx peripheral.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ UNUSED(cfg);
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_EnableGlobalInt
+ * Enables the controller's Global Int in the AHB Config reg
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx)
+{
+ uint32_t winterruptmask = 0;
+
+ /* Set winterruptmask variable */
+ winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \
+ | USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_RESETM;
+
+ /* Set interrupt mask */
+ USBx->CNTR |= winterruptmask;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DisableGlobalInt
+ * Disable the controller's Global Int in the AHB Config reg
+ * @param USBx : Selected device
+ * @retval HAL status
+*/
+HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx)
+{
+ uint32_t winterruptmask = 0;
+
+ /* Set winterruptmask variable */
+ winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \
+ | USB_CNTR_ESOFM | USB_CNTR_RESETM;
+
+ /* Clear interrupt mask */
+ USBx->CNTR &= ~winterruptmask;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_SetCurrentMode : Set functional mode
+ * @param USBx : Selected device
+ * @param mode : current core mode
+ * This parameter can be one of the these values:
+ * @arg USB_DEVICE_MODE: Peripheral mode mode
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx , USB_ModeTypeDef mode)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ UNUSED(mode);
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DevInit : Initializes the USB controller registers
+ * for device mode
+ * @param USBx : Selected device
+ * @param cfg : pointer to a USB_CfgTypeDef structure that contains
+ * the configuration information for the specified USBx peripheral.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DevInit (USB_TypeDef *USBx, USB_CfgTypeDef cfg)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(cfg);
+
+ /* Init Device */
+ /*CNTR_FRES = 1*/
+ USBx->CNTR = USB_CNTR_FRES;
+
+ /*CNTR_FRES = 0*/
+ USBx->CNTR = 0;
+
+ /*Clear pending interrupts*/
+ USBx->ISTR = 0;
+
+ /*Set Btable Address*/
+ USBx->BTABLE = BTABLE_ADDRESS;
+
+ /* Enable USB Device Interrupt mask */
+ USB_EnableGlobalInt(USBx);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_FlushTxFifo : Flush a Tx FIFO
+ * @param USBx : Selected device
+ * @param num : FIFO number
+ * This parameter can be a value from 1 to 15
+ 15 means Flush all Tx FIFOs
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_FlushTxFifo (USB_TypeDef *USBx, uint32_t num)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ UNUSED(num);
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_FlushRxFifo : Flush Rx FIFO
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_FlushRxFifo(USB_TypeDef *USBx)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return HAL_OK;
+}
+
+/**
+ * @brief Activate and configure an endpoint
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
+{
+ /* initialize Endpoint */
+ switch (ep->type)
+ {
+ case EP_TYPE_CTRL:
+ PCD_SET_EPTYPE(USBx, ep->num, USB_EP_CONTROL);
+ break;
+ case EP_TYPE_BULK:
+ PCD_SET_EPTYPE(USBx, ep->num, USB_EP_BULK);
+ break;
+ case EP_TYPE_INTR:
+ PCD_SET_EPTYPE(USBx, ep->num, USB_EP_INTERRUPT);
+ break;
+ case EP_TYPE_ISOC:
+ PCD_SET_EPTYPE(USBx, ep->num, USB_EP_ISOCHRONOUS);
+ break;
+ default:
+ break;
+ }
+
+ PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num);
+
+ if (ep->doublebuffer == 0)
+ {
+ if (ep->is_in)
+ {
+ /*Set the endpoint Transmit buffer address */
+ PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress);
+ PCD_CLEAR_TX_DTOG(USBx, ep->num);
+ /* Configure NAK status for the Endpoint*/
+ PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
+ }
+ else
+ {
+ /*Set the endpoint Receive buffer address */
+ PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress);
+ /*Set the endpoint Receive buffer counter*/
+ PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket);
+ PCD_CLEAR_RX_DTOG(USBx, ep->num);
+ /* Configure VALID status for the Endpoint*/
+ PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
+ }
+ }
+ /*Double Buffer*/
+ else
+ {
+ /*Set the endpoint as double buffered*/
+ PCD_SET_EP_DBUF(USBx, ep->num);
+ /*Set buffer address for double buffered mode*/
+ PCD_SET_EP_DBUF_ADDR(USBx, ep->num,ep->pmaaddr0, ep->pmaaddr1);
+
+ if (ep->is_in==0)
+ {
+ /* Clear the data toggle bits for the endpoint IN/OUT*/
+ PCD_CLEAR_RX_DTOG(USBx, ep->num);
+ PCD_CLEAR_TX_DTOG(USBx, ep->num);
+
+ /* Reset value of the data toggle bits for the endpoint out*/
+ PCD_TX_DTOG(USBx, ep->num);
+
+ PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
+ PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
+ }
+ else
+ {
+ /* Clear the data toggle bits for the endpoint IN/OUT*/
+ PCD_CLEAR_RX_DTOG(USBx, ep->num);
+ PCD_CLEAR_TX_DTOG(USBx, ep->num);
+ PCD_RX_DTOG(USBx, ep->num);
+ /* Configure DISABLE status for the Endpoint*/
+ PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
+ PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief De-activate and de-initialize an endpoint
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
+{
+ if (ep->doublebuffer == 0)
+ {
+ if (ep->is_in)
+ {
+ PCD_CLEAR_TX_DTOG(USBx, ep->num);
+ /* Configure DISABLE status for the Endpoint*/
+ PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
+ }
+ else
+ {
+ PCD_CLEAR_RX_DTOG(USBx, ep->num);
+ /* Configure DISABLE status for the Endpoint*/
+ PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
+ }
+ }
+ /*Double Buffer*/
+ else
+ {
+ if (ep->is_in==0)
+ {
+ /* Clear the data toggle bits for the endpoint IN/OUT*/
+ PCD_CLEAR_RX_DTOG(USBx, ep->num);
+ PCD_CLEAR_TX_DTOG(USBx, ep->num);
+
+ /* Reset value of the data toggle bits for the endpoint out*/
+ PCD_TX_DTOG(USBx, ep->num);
+
+ PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
+ PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
+ }
+ else
+ {
+ /* Clear the data toggle bits for the endpoint IN/OUT*/
+ PCD_CLEAR_RX_DTOG(USBx, ep->num);
+ PCD_CLEAR_TX_DTOG(USBx, ep->num);
+ PCD_RX_DTOG(USBx, ep->num);
+ /* Configure DISABLE status for the Endpoint*/
+ PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
+ PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_EPStartXfer : setup and starts a transfer over an EP
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx , USB_EPTypeDef *ep)
+{
+ uint16_t pmabuffer = 0;
+ uint32_t len = ep->xfer_len;
+
+ /* IN endpoint */
+ if (ep->is_in == 1)
+ {
+ /*Multi packet transfer*/
+ if (ep->xfer_len > ep->maxpacket)
+ {
+ len=ep->maxpacket;
+ ep->xfer_len-=len;
+ }
+ else
+ {
+ len=ep->xfer_len;
+ ep->xfer_len =0;
+ }
+
+ /* configure and validate Tx endpoint */
+ if (ep->doublebuffer == 0)
+ {
+ USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, len);
+ PCD_SET_EP_TX_CNT(USBx, ep->num, len);
+ }
+ else
+ {
+ /* Write the data to the USB endpoint */
+ if (PCD_GET_ENDPOINT(USBx, ep->num)& USB_EP_DTOG_TX)
+ {
+ /* Set the Double buffer counter for pmabuffer1 */
+ PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
+ pmabuffer = ep->pmaaddr1;
+ }
+ else
+ {
+ /* Set the Double buffer counter for pmabuffer0 */
+ PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
+ pmabuffer = ep->pmaaddr0;
+ }
+ USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, len);
+ PCD_FreeUserBuffer(USBx, ep->num, ep->is_in);
+ }
+
+ PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
+ }
+ else /* OUT endpoint */
+ {
+ /* Multi packet transfer*/
+ if (ep->xfer_len > ep->maxpacket)
+ {
+ len=ep->maxpacket;
+ ep->xfer_len-=len;
+ }
+ else
+ {
+ len=ep->xfer_len;
+ ep->xfer_len =0;
+ }
+
+ /* configure and validate Rx endpoint */
+ if (ep->doublebuffer == 0)
+ {
+ /*Set RX buffer count*/
+ PCD_SET_EP_RX_CNT(USBx, ep->num, len);
+ }
+ else
+ {
+ /*Set the Double buffer counter*/
+ PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len);
+ }
+
+ PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
+ * with the EP/channel
+ * @param USBx : Selected device
+ * @param src : pointer to source buffer
+ * @param ch_ep_num : endpoint or host channel number
+ * @param len : Number of bytes to write
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_WritePacket(USB_TypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ UNUSED(src);
+ UNUSED(ch_ep_num);
+ UNUSED(len);
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_ReadPacket : read a packet from the Tx FIFO associated
+ * with the EP/channel
+ * @param USBx : Selected device
+ * @param dest : destination pointer
+ * @param len : Number of bytes to read
+ * @retval pointer to destination buffer
+ */
+void *USB_ReadPacket(USB_TypeDef *USBx, uint8_t *dest, uint16_t len)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ UNUSED(dest);
+ UNUSED(len);
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return ((void *)NULL);
+}
+
+/**
+ * @brief USB_EPSetStall : set a stall condition over an EP
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx , USB_EPTypeDef *ep)
+{
+ if (ep->num == 0)
+ {
+ /* This macro sets STALL status for RX & TX*/
+ PCD_SET_EP_TXRX_STATUS(USBx, ep->num, USB_EP_RX_STALL, USB_EP_TX_STALL);
+ }
+ else
+ {
+ if (ep->is_in)
+ {
+ PCD_SET_EP_TX_STATUS(USBx, ep->num , USB_EP_TX_STALL);
+ }
+ else
+ {
+ PCD_SET_EP_RX_STATUS(USBx, ep->num , USB_EP_RX_STALL);
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_EPClearStall : Clear a stall condition over an EP
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
+{
+ if (ep->is_in)
+ {
+ PCD_CLEAR_TX_DTOG(USBx, ep->num);
+ PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
+ }
+ else
+ {
+ PCD_CLEAR_RX_DTOG(USBx, ep->num);
+ PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_StopDevice : Stop the usb device mode
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
+{
+ /* disable all interrupts and force USB reset */
+ USBx->CNTR = USB_CNTR_FRES;
+
+ /* clear interrupt status register */
+ USBx->ISTR = 0;
+
+ /* switch-off device */
+ USBx->CNTR = (USB_CNTR_FRES | USB_CNTR_PDWN);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_SetDevAddress : Stop the usb device mode
+ * @param USBx : Selected device
+ * @param address : new device address to be assigned
+ * This parameter can be a value from 0 to 255
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_SetDevAddress (USB_TypeDef *USBx, uint8_t address)
+{
+ if(address == 0)
+ {
+ /* set device address and enable function */
+ USBx->DADDR = USB_DADDR_EF;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DevConnect (USB_TypeDef *USBx)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DevDisconnect (USB_TypeDef *USBx)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_ReadInterrupts: return the global USB interrupt status
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+uint32_t USB_ReadInterrupts (USB_TypeDef *USBx)
+{
+ uint32_t tmpreg = 0;
+
+ tmpreg = USBx->ISTR;
+ return tmpreg;
+}
+
+/**
+ * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+uint32_t USB_ReadDevAllOutEpInterrupt (USB_TypeDef *USBx)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return (0);
+}
+
+/**
+ * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+uint32_t USB_ReadDevAllInEpInterrupt (USB_TypeDef *USBx)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return (0);
+}
+
+/**
+ * @brief Returns Device OUT EP Interrupt register
+ * @param USBx : Selected device
+ * @param epnum : endpoint number
+ * This parameter can be a value from 0 to 15
+ * @retval Device OUT EP Interrupt register
+ */
+uint32_t USB_ReadDevOutEPInterrupt (USB_TypeDef *USBx , uint8_t epnum)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ UNUSED(epnum);
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return (0);
+}
+
+/**
+ * @brief Returns Device IN EP Interrupt register
+ * @param USBx : Selected device
+ * @param epnum : endpoint number
+ * This parameter can be a value from 0 to 15
+ * @retval Device IN EP Interrupt register
+ */
+uint32_t USB_ReadDevInEPInterrupt (USB_TypeDef *USBx , uint8_t epnum)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ UNUSED(epnum);
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return (0);
+}
+
+/**
+ * @brief USB_ClearInterrupts: clear a USB interrupt
+ * @param USBx : Selected device
+ * @param interrupt : interrupt flag
+ * @retval None
+ */
+void USB_ClearInterrupts (USB_TypeDef *USBx, uint32_t interrupt)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ UNUSED(interrupt);
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+}
+
+/**
+ * @brief Prepare the EP0 to start the first control setup
+ * @param USBx : Selected device
+ * @param psetup : pointer to setup packet
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EP0_OutStart(USB_TypeDef *USBx, uint8_t *psetup)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(USBx);
+ UNUSED(psetup);
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_ActivateRemoteWakeup : active remote wakeup signalling
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
+{
+ USBx->CNTR |= USB_CNTR_RESUME;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DeActivateRemoteWakeup : de-active remote wakeup signalling
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
+{
+ USBx->CNTR &= ~(USB_CNTR_RESUME);
+ return HAL_OK;
+}
+
+/**
+ * @brief Copy a buffer from user memory area to packet memory area (PMA)
+ * @param USBx : pointer to USB register.
+ * @param pbUsrBuf : pointer to user memory area.
+ * @param wPMABufAddr : address into PMA.
+ * @param wNBytes : number of bytes to be copied.
+ * @retval None
+ */
+void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
+{
+ uint32_t nbytes = (wNBytes + 1) >> 1; /* nbytes = (wNBytes + 1) / 2 */
+ uint32_t index = 0, temp1 = 0, temp2 = 0;
+ uint16_t *pdwVal = NULL;
+
+ pdwVal = (uint16_t *)(wPMABufAddr * 2 + (uint32_t)USBx + 0x400);
+ for (index = nbytes; index != 0; index--)
+ {
+ temp1 = (uint16_t) * pbUsrBuf;
+ pbUsrBuf++;
+ temp2 = temp1 | (uint16_t) * pbUsrBuf << 8;
+ *pdwVal++ = temp2;
+ pdwVal++;
+ pbUsrBuf++;
+ }
+}
+
+/**
+ * @brief Copy a buffer from user memory area to packet memory area (PMA)
+ * @param USBx : pointer to USB register.
+* @param pbUsrBuf : pointer to user memory area.
+ * @param wPMABufAddr : address into PMA.
+ * @param wNBytes : number of bytes to be copied.
+ * @retval None
+ */
+void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
+{
+ uint32_t nbytes = (wNBytes + 1) >> 1;/* /2*/
+ uint32_t index = 0;
+ uint32_t *pdwVal = NULL;
+
+ pdwVal = (uint32_t *)(wPMABufAddr * 2 + (uint32_t)USBx + 0x400);
+ for (index = nbytes; index != 0; index--)
+ {
+ *(uint16_t*)pbUsrBuf++ = *pdwVal++;
+ pbUsrBuf++;
+ }
+}
+
+#endif /* USB */
+
+/**
+ * @}
+ */
+/**
+ * @}
+ */
+
+#if defined (USB_OTG_FS)
+/** @addtogroup USB_LL_Private_Functions
+ * @{
+ */
+/**
+ * @brief Reset the USB Core (needed after USB clock settings change)
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
+{
+ uint32_t count = 0;
+
+ /* Wait for AHB master IDLE state. */
+ do
+ {
+ if (++count > 200000)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0);
+
+ /* Core Soft Reset */
+ count = 0;
+ USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
+
+ do
+ {
+ if (++count > 200000)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
+
+ return HAL_OK;
+}
+/**
+ * @}
+ */
+#endif /* USB_OTG_FS */
+
+#endif /* STM32F102x6 || STM32F102xB || */
+ /* STM32F103x6 || STM32F103xB || */
+ /* STM32F103xE || STM32F103xG || */
+ /* STM32F105xC || STM32F107xC */
+
+#endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_utils.c b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_utils.c
new file mode 100644
index 0000000..e5de6cf
--- /dev/null
+++ b/templates/blackpill/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_utils.c
@@ -0,0 +1,621 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_utils.c
+ * @author MCD Application Team
+ * @brief UTILS LL module driver.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2016 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_rcc.h"
+#include "stm32f1xx_ll_utils.h"
+#include "stm32f1xx_ll_system.h"
+#ifdef USE_FULL_ASSERT
+#include "stm32_assert.h"
+#else
+#define assert_param(expr) ((void)0U)
+#endif
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+/** @addtogroup UTILS_LL
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @addtogroup UTILS_LL_Private_Constants
+ * @{
+ */
+
+/* Defines used for PLL range */
+#define UTILS_PLL_OUTPUT_MAX RCC_MAX_FREQUENCY /*!< Frequency max for PLL output, in Hz */
+
+/* Defines used for HSE range */
+#define UTILS_HSE_FREQUENCY_MIN RCC_HSE_MIN /*!< Frequency min for HSE frequency, in Hz */
+#define UTILS_HSE_FREQUENCY_MAX RCC_HSE_MAX /*!< Frequency max for HSE frequency, in Hz */
+
+/* Defines used for FLASH latency according to HCLK Frequency */
+#if defined(FLASH_ACR_LATENCY)
+#define UTILS_LATENCY1_FREQ 24000000U /*!< SYSCLK frequency to set FLASH latency 1 */
+#define UTILS_LATENCY2_FREQ 48000000U /*!< SYSCLK frequency to set FLASH latency 2 */
+#else
+ /*!< No Latency Configuration in this device */
+#endif
+/**
+ * @}
+ */
+/* Private macros ------------------------------------------------------------*/
+/** @addtogroup UTILS_LL_Private_Macros
+ * @{
+ */
+#define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1) \
+ || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2) \
+ || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4) \
+ || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8) \
+ || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16) \
+ || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64) \
+ || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
+ || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
+ || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
+
+#define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
+ || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
+ || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
+ || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
+ || ((__VALUE__) == LL_RCC_APB1_DIV_16))
+
+#define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
+ || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
+ || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
+ || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
+ || ((__VALUE__) == LL_RCC_APB2_DIV_16))
+
+#if defined(RCC_CFGR_PLLMULL6_5)
+#define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_4) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_5) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_6) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_7) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_8) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_9) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_6_5))
+#else
+#define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_2) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_3) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_4) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_5) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_6) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_7) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_8) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_9) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_10) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_11) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_12) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_13) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_14) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_15) \
+ || ((__VALUE__) == LL_RCC_PLL_MUL_16))
+#endif /* RCC_CFGR_PLLMULL6_5 */
+
+#if defined(RCC_CFGR2_PREDIV1)
+#define IS_LL_UTILS_PREDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PREDIV_DIV_1) || ((__VALUE__) == LL_RCC_PREDIV_DIV_2) || \
+ ((__VALUE__) == LL_RCC_PREDIV_DIV_3) || ((__VALUE__) == LL_RCC_PREDIV_DIV_4) || \
+ ((__VALUE__) == LL_RCC_PREDIV_DIV_5) || ((__VALUE__) == LL_RCC_PREDIV_DIV_6) || \
+ ((__VALUE__) == LL_RCC_PREDIV_DIV_7) || ((__VALUE__) == LL_RCC_PREDIV_DIV_8) || \
+ ((__VALUE__) == LL_RCC_PREDIV_DIV_9) || ((__VALUE__) == LL_RCC_PREDIV_DIV_10) || \
+ ((__VALUE__) == LL_RCC_PREDIV_DIV_11) || ((__VALUE__) == LL_RCC_PREDIV_DIV_12) || \
+ ((__VALUE__) == LL_RCC_PREDIV_DIV_13) || ((__VALUE__) == LL_RCC_PREDIV_DIV_14) || \
+ ((__VALUE__) == LL_RCC_PREDIV_DIV_15) || ((__VALUE__) == LL_RCC_PREDIV_DIV_16))
+#else
+#define IS_LL_UTILS_PREDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PREDIV_DIV_1) || ((__VALUE__) == LL_RCC_PREDIV_DIV_2))
+#endif /*RCC_PREDIV1_DIV_2_16_SUPPORT*/
+
+#define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((__VALUE__) <= UTILS_PLL_OUTPUT_MAX)
+
+
+#define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
+ || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
+
+#define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
+/**
+ * @}
+ */
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup UTILS_LL_Private_Functions UTILS Private functions
+ * @{
+ */
+static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
+ LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
+#if defined(FLASH_ACR_LATENCY)
+static ErrorStatus UTILS_SetFlashLatency(uint32_t Frequency);
+#endif /* FLASH_ACR_LATENCY */
+static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
+static ErrorStatus UTILS_PLL_IsBusy(void);
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup UTILS_LL_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup UTILS_LL_EF_DELAY
+ * @{
+ */
+
+/**
+ * @brief This function configures the Cortex-M SysTick source to have 1ms time base.
+ * @note When a RTOS is used, it is recommended to avoid changing the Systick
+ * configuration by calling this function, for a delay use rather osDelay RTOS service.
+ * @param HCLKFrequency HCLK frequency in Hz
+ * @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
+ * @retval None
+ */
+void LL_Init1msTick(uint32_t HCLKFrequency)
+{
+ /* Use frequency provided in argument */
+ LL_InitTick(HCLKFrequency, 1000U);
+}
+
+/**
+ * @brief This function provides accurate delay (in milliseconds) based
+ * on SysTick counter flag
+ * @note When a RTOS is used, it is recommended to avoid using blocking delay
+ * and use rather osDelay service.
+ * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
+ * will configure Systick to 1ms
+ * @param Delay specifies the delay time length, in milliseconds.
+ * @retval None
+ */
+void LL_mDelay(uint32_t Delay)
+{
+ __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
+ /* Add this code to indicate that local variable is not used */
+ ((void)tmp);
+
+ /* Add a period to guaranty minimum wait */
+ if (Delay < LL_MAX_DELAY)
+ {
+ Delay++;
+ }
+
+ while (Delay)
+ {
+ if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
+ {
+ Delay--;
+ }
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @addtogroup UTILS_EF_SYSTEM
+ * @brief System Configuration functions
+ *
+ @verbatim
+ ===============================================================================
+ ##### System Configuration functions #####
+ ===============================================================================
+ [..]
+ System, AHB and APB buses clocks configuration
+
+ (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is RCC_MAX_FREQUENCY Hz.
+ @endverbatim
+ @internal
+ Depending on the SYSCLK frequency, the flash latency should be adapted accordingly:
+ (++) +-----------------------------------------------+
+ (++) | Latency | SYSCLK clock frequency (MHz) |
+ (++) |---------------|-------------------------------|
+ (++) |0WS(1CPU cycle)| 0 < SYSCLK <= 24 |
+ (++) |---------------|-------------------------------|
+ (++) |1WS(2CPU cycle)| 24 < SYSCLK <= 48 |
+ (++) |---------------|-------------------------------|
+ (++) |2WS(3CPU cycle)| 48 < SYSCLK <= 72 |
+ (++) +-----------------------------------------------+
+ @endinternal
+ * @{
+ */
+
+/**
+ * @brief This function sets directly SystemCoreClock CMSIS variable.
+ * @note Variable can be calculated also through SystemCoreClockUpdate function.
+ * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
+ * @retval None
+ */
+void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
+{
+ /* HCLK clock frequency */
+ SystemCoreClock = HCLKFrequency;
+}
+
+/**
+ * @brief This function configures system clock with HSI as clock source of the PLL
+ * @note The application need to ensure that PLL is disabled.
+ * @note Function is based on the following formula:
+ * - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
+ * - PREDIV: Set to 2 for few devices
+ * - PLLMUL: The application software must set correctly the PLL multiplication factor to
+ * not exceed 72MHz
+ * @note FLASH latency can be modified through this function.
+ * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
+ * the configuration information for the PLL.
+ * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
+ * the configuration information for the BUS prescalers.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: Max frequency configuration done
+ * - ERROR: Max frequency configuration not done
+ */
+ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
+ LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
+{
+ ErrorStatus status = SUCCESS;
+ uint32_t pllfreq = 0U;
+
+ /* Check if one of the PLL is enabled */
+ if (UTILS_PLL_IsBusy() == SUCCESS)
+ {
+#if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
+ /* Check PREDIV value */
+ assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
+#else
+ /* Force PREDIV value to 2 */
+ UTILS_PLLInitStruct->Prediv = LL_RCC_PREDIV_DIV_2;
+#endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
+ /* Calculate the new PLL output frequency */
+ pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
+
+ /* Enable HSI if not enabled */
+ if (LL_RCC_HSI_IsReady() != 1U)
+ {
+ LL_RCC_HSI_Enable();
+ while (LL_RCC_HSI_IsReady() != 1U)
+ {
+ /* Wait for HSI ready */
+ }
+ }
+
+ /* Configure PLL */
+ LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, UTILS_PLLInitStruct->PLLMul);
+
+ /* Enable PLL and switch system clock to PLL */
+ status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
+ }
+ else
+ {
+ /* Current PLL configuration cannot be modified */
+ status = ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief This function configures system clock with HSE as clock source of the PLL
+ * @note The application need to ensure that PLL is disabled.
+ * @note Function is based on the following formula:
+ * - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
+ * - PREDIV: Set to 2 for few devices
+ * - PLLMUL: The application software must set correctly the PLL multiplication factor to
+ * not exceed @ref UTILS_PLL_OUTPUT_MAX
+ * @note FLASH latency can be modified through this function.
+ * @param HSEFrequency Value between Min_Data = RCC_HSE_MIN and Max_Data = RCC_HSE_MAX
+ * @param HSEBypass This parameter can be one of the following values:
+ * @arg @ref LL_UTILS_HSEBYPASS_ON
+ * @arg @ref LL_UTILS_HSEBYPASS_OFF
+ * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
+ * the configuration information for the PLL.
+ * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
+ * the configuration information for the BUS prescalers.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: Max frequency configuration done
+ * - ERROR: Max frequency configuration not done
+ */
+ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
+ LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
+{
+ ErrorStatus status = SUCCESS;
+ uint32_t pllfreq = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
+ assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
+
+ /* Check if one of the PLL is enabled */
+ if (UTILS_PLL_IsBusy() == SUCCESS)
+ {
+ assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->Prediv));
+
+ /* Calculate the new PLL output frequency */
+ pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
+
+ /* Enable HSE if not enabled */
+ if (LL_RCC_HSE_IsReady() != 1U)
+ {
+ /* Check if need to enable HSE bypass feature or not */
+ if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
+ {
+ LL_RCC_HSE_EnableBypass();
+ }
+ else
+ {
+ LL_RCC_HSE_DisableBypass();
+ }
+
+ /* Enable HSE */
+ LL_RCC_HSE_Enable();
+ while (LL_RCC_HSE_IsReady() != 1U)
+ {
+ /* Wait for HSE ready */
+ }
+ }
+
+ /* Configure PLL */
+ LL_RCC_PLL_ConfigDomain_SYS((RCC_CFGR_PLLSRC | UTILS_PLLInitStruct->Prediv), UTILS_PLLInitStruct->PLLMul);
+
+ /* Enable PLL and switch system clock to PLL */
+ status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
+ }
+ else
+ {
+ /* Current PLL configuration cannot be modified */
+ status = ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup UTILS_LL_Private_Functions
+ * @{
+ */
+/**
+ * @brief Update number of Flash wait states in line with new frequency and current
+ voltage range.
+ * @param Frequency SYSCLK frequency
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: Latency has been modified
+ * - ERROR: Latency cannot be modified
+ */
+#if defined(FLASH_ACR_LATENCY)
+static ErrorStatus UTILS_SetFlashLatency(uint32_t Frequency)
+{
+ ErrorStatus status = SUCCESS;
+
+ uint32_t latency = LL_FLASH_LATENCY_0; /* default value 0WS */
+
+ /* Frequency cannot be equal to 0 */
+ if (Frequency == 0U)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ if (Frequency > UTILS_LATENCY2_FREQ)
+ {
+ /* 48 < SYSCLK <= 72 => 2WS (3 CPU cycles) */
+ latency = LL_FLASH_LATENCY_2;
+ }
+ else
+ {
+ if (Frequency > UTILS_LATENCY1_FREQ)
+ {
+ /* 24 < SYSCLK <= 48 => 1WS (2 CPU cycles) */
+ latency = LL_FLASH_LATENCY_1;
+ }
+ /* else SYSCLK < 24MHz default LL_FLASH_LATENCY_0 0WS */
+ }
+
+ LL_FLASH_SetLatency(latency);
+
+ /* Check that the new number of wait states is taken into account to access the Flash
+ memory by reading the FLASH_ACR register */
+ if (LL_FLASH_GetLatency() != latency)
+ {
+ status = ERROR;
+ }
+ }
+ return status;
+}
+#endif /* FLASH_ACR_LATENCY */
+
+/**
+ * @brief Function to check that PLL can be modified
+ * @param PLL_InputFrequency PLL input frequency (in Hz)
+ * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
+ * the configuration information for the PLL.
+ * @retval PLL output frequency (in Hz)
+ */
+static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
+{
+ uint32_t pllfreq = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_LL_UTILS_PLLMUL_VALUE(UTILS_PLLInitStruct->PLLMul));
+
+ /* Check different PLL parameters according to RM */
+#if defined (RCC_CFGR2_PREDIV1)
+ pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / (UTILS_PLLInitStruct->Prediv + 1U), UTILS_PLLInitStruct->PLLMul);
+#elif defined(RCC_CFGR2_PREDIV1SRC)
+ pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
+#else
+ pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / ((UTILS_PLLInitStruct->Prediv >> RCC_CFGR_PLLXTPRE_Pos) + 1U), UTILS_PLLInitStruct->PLLMul);
+#endif /*RCC_CFGR2_PREDIV1SRC*/
+ assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
+
+ return pllfreq;
+}
+
+/**
+ * @brief Function to check that PLL can be modified
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: PLL modification can be done
+ * - ERROR: PLL is busy
+ */
+static ErrorStatus UTILS_PLL_IsBusy(void)
+{
+ ErrorStatus status = SUCCESS;
+
+ /* Check if PLL is busy*/
+ if (LL_RCC_PLL_IsReady() != 0U)
+ {
+ /* PLL configuration cannot be modified */
+ status = ERROR;
+ }
+#if defined(RCC_PLL2_SUPPORT)
+ /* Check if PLL2 is busy*/
+ if (LL_RCC_PLL2_IsReady() != 0U)
+ {
+ /* PLL2 configuration cannot be modified */
+ status = ERROR;
+ }
+#endif /* RCC_PLL2_SUPPORT */
+
+#if defined(RCC_PLLI2S_SUPPORT)
+ /* Check if PLLI2S is busy*/
+ if (LL_RCC_PLLI2S_IsReady() != 0U)
+ {
+ /* PLLI2S configuration cannot be modified */
+ status = ERROR;
+ }
+#endif /* RCC_PLLI2S_SUPPORT */
+
+ return status;
+}
+
+/**
+ * @brief Function to enable PLL and switch system clock to PLL
+ * @param SYSCLK_Frequency SYSCLK frequency
+ * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
+ * the configuration information for the BUS prescalers.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: No problem to switch system to PLL
+ * - ERROR: Problem to switch system to PLL
+ */
+static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
+{
+ ErrorStatus status = SUCCESS;
+#if defined(FLASH_ACR_LATENCY)
+ uint32_t sysclk_frequency_current = 0U;
+#endif /* FLASH_ACR_LATENCY */
+
+ assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
+ assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
+ assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
+
+#if defined(FLASH_ACR_LATENCY)
+ /* Calculate current SYSCLK frequency */
+ sysclk_frequency_current = (SystemCoreClock << AHBPrescTable[LL_RCC_GetAHBPrescaler() >> RCC_CFGR_HPRE_Pos]);
+#endif /* FLASH_ACR_LATENCY */
+
+ /* Increasing the number of wait states because of higher CPU frequency */
+#if defined (FLASH_ACR_LATENCY)
+ if (sysclk_frequency_current < SYSCLK_Frequency)
+ {
+ /* Set FLASH latency to highest latency */
+ status = UTILS_SetFlashLatency(SYSCLK_Frequency);
+ }
+#endif /* FLASH_ACR_LATENCY */
+
+ /* Update system clock configuration */
+ if (status == SUCCESS)
+ {
+#if defined(RCC_PLL2_SUPPORT)
+ /* Enable PLL2 */
+ LL_RCC_PLL2_Enable();
+ while (LL_RCC_PLL2_IsReady() != 1U)
+ {
+ /* Wait for PLL2 ready */
+ }
+
+#endif /* RCC_PLL2_SUPPORT */
+ /* Enable PLL */
+ LL_RCC_PLL_Enable();
+ while (LL_RCC_PLL_IsReady() != 1U)
+ {
+ /* Wait for PLL ready */
+ }
+
+ /* Sysclk activation on the main PLL */
+ LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
+ LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
+ while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
+ {
+ /* Wait for system clock switch to PLL */
+ }
+
+ /* Set APB1 & APB2 prescaler*/
+ LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
+ LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
+ }
+
+ /* Decreasing the number of wait states because of lower CPU frequency */
+#if defined (FLASH_ACR_LATENCY)
+ if (sysclk_frequency_current > SYSCLK_Frequency)
+ {
+ /* Set FLASH latency to lowest latency */
+ status = UTILS_SetFlashLatency(SYSCLK_Frequency);
+ }
+#endif /* FLASH_ACR_LATENCY */
+
+ /* Update SystemCoreClock variable */
+ if (status == SUCCESS)
+ {
+ LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider));
+ }
+
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Inc/main.h b/templates/blackpill/Inc/main.h
new file mode 100644
index 0000000..1ce83b2
--- /dev/null
+++ b/templates/blackpill/Inc/main.h
@@ -0,0 +1,117 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file : main.h
+ * @brief : Header for main.c file.
+ * This file contains the common defines of the application.
+ ******************************************************************************
+ ** This notice applies to any and all portions of this file
+ * that are not between comment pairs USER CODE BEGIN and
+ * USER CODE END. Other portions of this file, whether
+ * inserted by the user or by software development tools
+ * are owned by their respective copyright owners.
+ *
+ * COPYRIGHT(c) 2019 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __MAIN_H
+#define __MAIN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_ll_rcc.h"
+#include "stm32f1xx_ll_bus.h"
+#include "stm32f1xx_ll_system.h"
+#include "stm32f1xx_ll_exti.h"
+#include "stm32f1xx_ll_cortex.h"
+#include "stm32f1xx_ll_utils.h"
+#include "stm32f1xx_ll_pwr.h"
+#include "stm32f1xx_ll_dma.h"
+#include "stm32f1xx_ll_usart.h"
+#include "stm32f1xx.h"
+#include "stm32f1xx_ll_gpio.h"
+
+#if defined(USE_FULL_ASSERT)
+#include "stm32_assert.h"
+#endif /* USE_FULL_ASSERT */
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Exported types ------------------------------------------------------------*/
+/* USER CODE BEGIN ET */
+
+/* USER CODE END ET */
+
+/* Exported constants --------------------------------------------------------*/
+/* USER CODE BEGIN EC */
+
+/* USER CODE END EC */
+
+/* Exported macro ------------------------------------------------------------*/
+/* USER CODE BEGIN EM */
+
+/* USER CODE END EM */
+
+/* Exported functions prototypes ---------------------------------------------*/
+void Error_Handler(void);
+
+/* USER CODE BEGIN EFP */
+
+/* USER CODE END EFP */
+
+/* Private defines -----------------------------------------------------------*/
+#ifndef NVIC_PRIORITYGROUP_0
+#define NVIC_PRIORITYGROUP_0 ((uint32_t)0x00000007) /*!< 0 bit for pre-emption priority,
+ 4 bits for subpriority */
+#define NVIC_PRIORITYGROUP_1 ((uint32_t)0x00000006) /*!< 1 bit for pre-emption priority,
+ 3 bits for subpriority */
+#define NVIC_PRIORITYGROUP_2 ((uint32_t)0x00000005) /*!< 2 bits for pre-emption priority,
+ 2 bits for subpriority */
+#define NVIC_PRIORITYGROUP_3 ((uint32_t)0x00000004) /*!< 3 bits for pre-emption priority,
+ 1 bit for subpriority */
+#define NVIC_PRIORITYGROUP_4 ((uint32_t)0x00000003) /*!< 4 bits for pre-emption priority,
+ 0 bit for subpriority */
+#endif
+/* USER CODE BEGIN Private defines */
+
+/* USER CODE END Private defines */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MAIN_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Inc/stm32_assert.h b/templates/blackpill/Inc/stm32_assert.h
new file mode 100644
index 0000000..3cbee3c
--- /dev/null
+++ b/templates/blackpill/Inc/stm32_assert.h
@@ -0,0 +1,73 @@
+/**
+ ******************************************************************************
+ * @file stm32_assert.h
+ * @brief STM32 assert file.
+ ******************************************************************************
+ ** This notice applies to any and all portions of this file
+ * that are not between comment pairs USER CODE BEGIN and
+ * USER CODE END. Other portions of this file, whether
+ * inserted by the user or by software development tools
+ * are owned by their respective copyright owners.
+ *
+ * COPYRIGHT(c) 2019 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32_ASSERT_H
+#define __STM32_ASSERT_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Includes ------------------------------------------------------------------*/
+/* 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)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+ void assert_failed(uint8_t* file, uint32_t line);
+#else
+ #define assert_param(expr) ((void)0U)
+#endif /* USE_FULL_ASSERT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32_ASSERT_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Inc/stm32f1xx_it.h b/templates/blackpill/Inc/stm32f1xx_it.h
new file mode 100644
index 0000000..d773f36
--- /dev/null
+++ b/templates/blackpill/Inc/stm32f1xx_it.h
@@ -0,0 +1,88 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file stm32f1xx_it.h
+ * @brief This file contains the headers of the interrupt handlers.
+ ******************************************************************************
+ *
+ * COPYRIGHT(c) 2019 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_IT_H
+#define __STM32F1xx_IT_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+#include "stm32f1xx.h"
+#include "stm32f1xx_ll_system.h"
+#include "stm32f1xx_ll_gpio.h"
+#include "stm32f1xx_ll_exti.h"
+/* Exported types ------------------------------------------------------------*/
+/* USER CODE BEGIN ET */
+
+/* USER CODE END ET */
+
+/* Exported constants --------------------------------------------------------*/
+/* USER CODE BEGIN EC */
+
+/* USER CODE END EC */
+
+/* Exported macro ------------------------------------------------------------*/
+/* USER CODE BEGIN EM */
+
+/* USER CODE END EM */
+
+/* Exported functions prototypes ---------------------------------------------*/
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void MemManage_Handler(void);
+void BusFault_Handler(void);
+void UsageFault_Handler(void);
+void SVC_Handler(void);
+void DebugMon_Handler(void);
+void PendSV_Handler(void);
+void SysTick_Handler(void);
+/* USER CODE BEGIN EFP */
+
+/* USER CODE END EFP */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_IT_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Makefile b/templates/blackpill/Makefile
new file mode 100644
index 0000000..70e4e0b
--- /dev/null
+++ b/templates/blackpill/Makefile
@@ -0,0 +1,189 @@
+##########################################################################################################################
+# File automatically-generated by tool: [projectgenerator] version: [3.0.0] date: [Wed Jul 03 10:04:07 CEST 2019]
+##########################################################################################################################
+
+# ------------------------------------------------
+# Generic Makefile (based on gcc)
+#
+# ChangeLog :
+# 2017-02-10 - Several enhancements + project update mode
+# 2015-07-22 - first version
+# ------------------------------------------------
+
+######################################
+# target
+######################################
+TARGET = blackpill
+
+
+######################################
+# building variables
+######################################
+# debug build?
+DEBUG = 1
+# optimization
+OPT = -Og
+
+
+#######################################
+# paths
+#######################################
+# Build path
+BUILD_DIR = build
+
+######################################
+# source
+######################################
+# C sources
+C_SOURCES = \
+Src/main.c \
+Src/stm32f1xx_it.c \
+Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rcc.c \
+Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_utils.c \
+Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_exti.c \
+Src/system_stm32f1xx.c \
+Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_gpio.c \
+Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_pwr.c \
+Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usart.c \
+Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_dma.c \
+$(SRC_FILES)
+
+# ASM sources
+ASM_SOURCES = \
+startup_stm32f103xb.s
+
+
+#######################################
+# binaries
+#######################################
+PREFIX = arm-none-eabi-
+# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx)
+# either it can be added to the PATH environment variable.
+ifdef GCC_PATH
+CC = $(GCC_PATH)/$(PREFIX)gcc
+AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp
+CP = $(GCC_PATH)/$(PREFIX)objcopy
+SZ = $(GCC_PATH)/$(PREFIX)size
+else
+CC = $(PREFIX)gcc
+AS = $(PREFIX)gcc -x assembler-with-cpp
+CP = $(PREFIX)objcopy
+SZ = $(PREFIX)size
+endif
+HEX = $(CP) -O ihex
+BIN = $(CP) -O binary -S
+
+#######################################
+# CFLAGS
+#######################################
+# cpu
+CPU = -mcpu=cortex-m3
+
+# fpu
+# NONE for Cortex-M0/M0+/M3
+
+# float-abi
+
+
+# mcu
+MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)
+
+# macros for gcc
+# AS defines
+AS_DEFS =
+
+# C defines
+C_DEFS = \
+-DUSE_FULL_LL_DRIVER \
+-DSTM32F103xB \
+-DHSE_VALUE=8000000 \
+-DHSE_STARTUP_TIMEOUT=100 \
+-DLSE_STARTUP_TIMEOUT=5000 \
+-DLSE_VALUE=32768 \
+-DHSI_VALUE=8000000 \
+-DLSI_VALUE=40000 \
+-DVDD_VALUE=3300 \
+-DPREFETCH_ENABLE=1
+
+
+# AS includes
+AS_INCLUDES =
+
+# C includes
+C_INCLUDES = \
+-IInc \
+-IDrivers/STM32F1xx_HAL_Driver/Inc \
+-IDrivers/CMSIS/Device/ST/STM32F1xx/Include \
+-IDrivers/CMSIS/Include
+
+
+# compile gcc flags
+ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
+
+CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
+
+ifeq ($(DEBUG), 1)
+CFLAGS += -g -gdwarf-2
+endif
+
+
+# Generate dependency information
+CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
+
+
+#######################################
+# LDFLAGS
+#######################################
+# link script
+LDSCRIPT = STM32F103C8Tx_FLASH.ld
+
+# libraries
+LIBS = -lc -lm -lnosys
+LIBDIR =
+LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections
+
+# default action: build all
+all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin
+
+
+#######################################
+# build the application
+#######################################
+# list of objects
+OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
+vpath %.c $(sort $(dir $(C_SOURCES)))
+# list of ASM program objects
+OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
+vpath %.s $(sort $(dir $(ASM_SOURCES)))
+
+$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
+ $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
+
+$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
+ $(AS) -c $(CFLAGS) $< -o $@
+
+$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
+ $(CC) $(OBJECTS) $(LDFLAGS) -o $@
+ $(SZ) $@
+
+$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
+ $(HEX) $< $@
+
+$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
+ $(BIN) $< $@
+
+$(BUILD_DIR):
+ mkdir $@
+
+#######################################
+# clean up
+#######################################
+clean:
+ -rm -fR $(BUILD_DIR)
+
+#######################################
+# dependencies
+#######################################
+-include $(wildcard $(BUILD_DIR)/*.d)
+
+# *** EOF ***
diff --git a/templates/blackpill/STM32F103C8Tx_FLASH.ld b/templates/blackpill/STM32F103C8Tx_FLASH.ld
new file mode 100644
index 0000000..38d06c5
--- /dev/null
+++ b/templates/blackpill/STM32F103C8Tx_FLASH.ld
@@ -0,0 +1,169 @@
+/*
+*****************************************************************************
+**
+
+** File : LinkerScript.ld
+**
+** Abstract : Linker script for STM32F103C8Tx Device with
+** 64KByte FLASH, 20KByte RAM
+**
+** Set heap size, stack size and stack location according
+** to application requirements.
+**
+** Set memory bank area and size if external memory is used.
+**
+** Target : STMicroelectronics STM32
+**
+**
+** Distribution: The file is distributed as is, without any warranty
+** of any kind.
+**
+** (c)Copyright Ac6.
+** You may use this file as-is or modify it according to the needs of your
+** project. Distribution of this file (unmodified or modified) is not
+** permitted. Ac6 permit registered System Workbench for MCU users the
+** rights to distribute the assembled, compiled & linked contents of this
+** file as part of an application binary file, provided that it is built
+** using the System Workbench for MCU toolchain.
+**
+*****************************************************************************
+*/
+
+/* Entry Point */
+ENTRY(Reset_Handler)
+
+/* Highest address of the user mode stack */
+_estack = 0x20005000; /* end of RAM */
+/* Generate a link error if heap and stack don't fit into RAM */
+_Min_Heap_Size = 0x200; /* required amount of heap */
+_Min_Stack_Size = 0x400; /* required amount of stack */
+
+/* Specify the memory areas */
+MEMORY
+{
+RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
+FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K
+}
+
+/* Define output sections */
+SECTIONS
+{
+ /* The startup code goes first into FLASH */
+ .isr_vector :
+ {
+ . = ALIGN(4);
+ KEEP(*(.isr_vector)) /* Startup code */
+ . = ALIGN(4);
+ } >FLASH
+
+ /* The program code and other data goes into FLASH */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text) /* .text sections (code) */
+ *(.text*) /* .text* sections (code) */
+ *(.glue_7) /* glue arm to thumb code */
+ *(.glue_7t) /* glue thumb to arm code */
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ . = ALIGN(4);
+ _etext = .; /* define a global symbols at end of code */
+ } >FLASH
+
+ /* Constant data goes into FLASH */
+ .rodata :
+ {
+ . = ALIGN(4);
+ *(.rodata) /* .rodata sections (constants, strings, etc.) */
+ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
+ . = ALIGN(4);
+ } >FLASH
+
+ .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
+ .ARM : {
+ __exidx_start = .;
+ *(.ARM.exidx*)
+ __exidx_end = .;
+ } >FLASH
+
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array*))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >FLASH
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array*))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ } >FLASH
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array*))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } >FLASH
+
+ /* used by the startup to initialize data */
+ _sidata = LOADADDR(.data);
+
+ /* Initialized data sections goes into RAM, load LMA copy after code */
+ .data :
+ {
+ . = ALIGN(4);
+ _sdata = .; /* create a global symbol at data start */
+ *(.data) /* .data sections */
+ *(.data*) /* .data* sections */
+
+ . = ALIGN(4);
+ _edata = .; /* define a global symbol at data end */
+ } >RAM AT> FLASH
+
+
+ /* Uninitialized data section */
+ . = ALIGN(4);
+ .bss :
+ {
+ /* This is used by the startup in order to initialize the .bss secion */
+ _sbss = .; /* define a global symbol at bss start */
+ __bss_start__ = _sbss;
+ *(.bss)
+ *(.bss*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = .; /* define a global symbol at bss end */
+ __bss_end__ = _ebss;
+ } >RAM
+
+ /* User_heap_stack section, used to check that there is enough RAM left */
+ ._user_heap_stack :
+ {
+ . = ALIGN(8);
+ PROVIDE ( end = . );
+ PROVIDE ( _end = . );
+ . = . + _Min_Heap_Size;
+ . = . + _Min_Stack_Size;
+ . = ALIGN(8);
+ } >RAM
+
+
+
+ /* Remove information from the standard libraries */
+ /DISCARD/ :
+ {
+ libc.a ( * )
+ libm.a ( * )
+ libgcc.a ( * )
+ }
+
+ .ARM.attributes 0 : { *(.ARM.attributes) }
+}
+
+
diff --git a/assets/templates/blackpill/Src/Makefile b/templates/blackpill/Src/Makefile
similarity index 100%
rename from assets/templates/blackpill/Src/Makefile
rename to templates/blackpill/Src/Makefile
diff --git a/templates/blackpill/Src/aes.c b/templates/blackpill/Src/aes.c
new file mode 100644
index 0000000..560624c
--- /dev/null
+++ b/templates/blackpill/Src/aes.c
@@ -0,0 +1,2209 @@
+/*
+ * FIPS-197 compliant AES implementation
+ *
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
+ *
+ * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
+ * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_AES_C)
+
+#include
+
+#include "aes.h"
+#include "platform.h"
+#include "platform_util.h"
+#if defined(MBEDTLS_PADLOCK_C)
+#include "mbedtls/padlock.h"
+#endif
+#if defined(MBEDTLS_AESNI_C)
+#include "mbedtls/aesni.h"
+#endif
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "platform.h"
+#else
+#include
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if !defined(MBEDTLS_AES_ALT)
+
+/* Parameter validation macros based on platform_util.h */
+#define AES_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA )
+#define AES_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
+/*
+ * 32-bit integer manipulation macros (little endian)
+ */
+#ifndef GET_UINT32_LE
+#define GET_UINT32_LE(n,b,i) \
+{ \
+ (n) = ( (uint32_t) (b)[(i) ] ) \
+ | ( (uint32_t) (b)[(i) + 1] << 8 ) \
+ | ( (uint32_t) (b)[(i) + 2] << 16 ) \
+ | ( (uint32_t) (b)[(i) + 3] << 24 ); \
+}
+#endif
+
+#ifndef PUT_UINT32_LE
+#define PUT_UINT32_LE(n,b,i) \
+{ \
+ (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
+ (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
+ (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
+ (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
+}
+#endif
+
+#if defined(MBEDTLS_PADLOCK_C) && \
+ ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) )
+static int aes_padlock_ace = -1;
+#endif
+
+#if defined(MBEDTLS_AES_ROM_TABLES)
+/*
+ * Forward S-box
+ */
+static const unsigned char FSb[256] =
+{
+ 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
+ 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
+ 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
+ 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
+ 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
+ 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
+ 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
+ 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
+ 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
+ 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
+ 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
+ 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
+ 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
+ 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
+ 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
+ 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
+ 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
+ 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
+ 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
+ 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
+ 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
+ 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
+ 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
+ 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
+ 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
+ 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
+ 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
+ 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
+ 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
+ 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
+ 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
+ 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
+};
+
+/*
+ * Forward tables
+ */
+#define FT \
+\
+ V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \
+ V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \
+ V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \
+ V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \
+ V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \
+ V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \
+ V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \
+ V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \
+ V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \
+ V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \
+ V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \
+ V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \
+ V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \
+ V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \
+ V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \
+ V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \
+ V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \
+ V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \
+ V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \
+ V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \
+ V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \
+ V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \
+ V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \
+ V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \
+ V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \
+ V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \
+ V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \
+ V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \
+ V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \
+ V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \
+ V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \
+ V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \
+ V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \
+ V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \
+ V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \
+ V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \
+ V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \
+ V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \
+ V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \
+ V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \
+ V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \
+ V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \
+ V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \
+ V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \
+ V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \
+ V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \
+ V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \
+ V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \
+ V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \
+ V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \
+ V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \
+ V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \
+ V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \
+ V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \
+ V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \
+ V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \
+ V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \
+ V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \
+ V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \
+ V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \
+ V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \
+ V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \
+ V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \
+ V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
+
+#define V(a,b,c,d) 0x##a##b##c##d
+static const uint32_t FT0[256] = { FT };
+#undef V
+
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+
+#define V(a,b,c,d) 0x##b##c##d##a
+static const uint32_t FT1[256] = { FT };
+#undef V
+
+#define V(a,b,c,d) 0x##c##d##a##b
+static const uint32_t FT2[256] = { FT };
+#undef V
+
+#define V(a,b,c,d) 0x##d##a##b##c
+static const uint32_t FT3[256] = { FT };
+#undef V
+
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+#undef FT
+
+/*
+ * Reverse S-box
+ */
+static const unsigned char RSb[256] =
+{
+ 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
+ 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
+ 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
+ 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
+ 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
+ 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
+ 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
+ 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
+ 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
+ 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
+ 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
+ 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
+ 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
+ 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
+ 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
+ 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
+ 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
+ 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
+ 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
+ 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
+ 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
+ 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
+ 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
+ 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
+ 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
+ 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
+ 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
+ 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
+ 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
+ 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
+ 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
+ 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
+};
+
+/*
+ * Reverse tables
+ */
+#define RT \
+\
+ V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \
+ V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \
+ V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \
+ V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \
+ V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \
+ V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \
+ V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \
+ V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \
+ V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \
+ V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \
+ V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \
+ V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \
+ V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \
+ V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \
+ V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \
+ V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \
+ V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \
+ V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \
+ V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \
+ V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \
+ V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \
+ V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \
+ V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \
+ V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \
+ V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \
+ V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \
+ V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \
+ V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \
+ V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \
+ V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \
+ V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \
+ V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \
+ V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \
+ V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \
+ V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \
+ V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \
+ V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \
+ V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \
+ V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \
+ V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \
+ V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \
+ V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \
+ V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \
+ V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \
+ V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \
+ V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \
+ V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \
+ V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \
+ V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \
+ V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \
+ V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \
+ V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \
+ V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \
+ V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \
+ V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \
+ V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \
+ V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \
+ V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \
+ V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \
+ V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \
+ V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \
+ V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \
+ V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \
+ V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0)
+
+#define V(a,b,c,d) 0x##a##b##c##d
+static const uint32_t RT0[256] = { RT };
+#undef V
+
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+
+#define V(a,b,c,d) 0x##b##c##d##a
+static const uint32_t RT1[256] = { RT };
+#undef V
+
+#define V(a,b,c,d) 0x##c##d##a##b
+static const uint32_t RT2[256] = { RT };
+#undef V
+
+#define V(a,b,c,d) 0x##d##a##b##c
+static const uint32_t RT3[256] = { RT };
+#undef V
+
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+#undef RT
+
+/*
+ * Round constants
+ */
+static const uint32_t RCON[10] =
+{
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008,
+ 0x00000010, 0x00000020, 0x00000040, 0x00000080,
+ 0x0000001B, 0x00000036
+};
+
+#else /* MBEDTLS_AES_ROM_TABLES */
+
+/*
+ * Forward S-box & tables
+ */
+static unsigned char FSb[256];
+static uint32_t FT0[256];
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+static uint32_t FT1[256];
+static uint32_t FT2[256];
+static uint32_t FT3[256];
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+/*
+ * Reverse S-box & tables
+ */
+static unsigned char RSb[256];
+static uint32_t RT0[256];
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+static uint32_t RT1[256];
+static uint32_t RT2[256];
+static uint32_t RT3[256];
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+/*
+ * Round constants
+ */
+static uint32_t RCON[10];
+
+/*
+ * Tables generation code
+ */
+#define ROTL8(x) ( ( (x) << 8 ) & 0xFFFFFFFF ) | ( (x) >> 24 )
+#define XTIME(x) ( ( (x) << 1 ) ^ ( ( (x) & 0x80 ) ? 0x1B : 0x00 ) )
+#define MUL(x,y) ( ( (x) && (y) ) ? pow[(log[(x)]+log[(y)]) % 255] : 0 )
+
+static int aes_init_done = 0;
+
+static void aes_gen_tables( void )
+{
+ int i, x, y, z;
+ int pow[256];
+ int log[256];
+
+ /*
+ * compute pow and log tables over GF(2^8)
+ */
+ for( i = 0, x = 1; i < 256; i++ )
+ {
+ pow[i] = x;
+ log[x] = i;
+ x = ( x ^ XTIME( x ) ) & 0xFF;
+ }
+
+ /*
+ * calculate the round constants
+ */
+ for( i = 0, x = 1; i < 10; i++ )
+ {
+ RCON[i] = (uint32_t) x;
+ x = XTIME( x ) & 0xFF;
+ }
+
+ /*
+ * generate the forward and reverse S-boxes
+ */
+ FSb[0x00] = 0x63;
+ RSb[0x63] = 0x00;
+
+ for( i = 1; i < 256; i++ )
+ {
+ x = pow[255 - log[i]];
+
+ y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+ x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+ x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+ x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+ x ^= y ^ 0x63;
+
+ FSb[i] = (unsigned char) x;
+ RSb[x] = (unsigned char) i;
+ }
+
+ /*
+ * generate the forward and reverse tables
+ */
+ for( i = 0; i < 256; i++ )
+ {
+ x = FSb[i];
+ y = XTIME( x ) & 0xFF;
+ z = ( y ^ x ) & 0xFF;
+
+ FT0[i] = ( (uint32_t) y ) ^
+ ( (uint32_t) x << 8 ) ^
+ ( (uint32_t) x << 16 ) ^
+ ( (uint32_t) z << 24 );
+
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+ FT1[i] = ROTL8( FT0[i] );
+ FT2[i] = ROTL8( FT1[i] );
+ FT3[i] = ROTL8( FT2[i] );
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+ x = RSb[i];
+
+ RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^
+ ( (uint32_t) MUL( 0x09, x ) << 8 ) ^
+ ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
+ ( (uint32_t) MUL( 0x0B, x ) << 24 );
+
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+ RT1[i] = ROTL8( RT0[i] );
+ RT2[i] = ROTL8( RT1[i] );
+ RT3[i] = ROTL8( RT2[i] );
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+ }
+}
+
+#undef ROTL8
+
+#endif /* MBEDTLS_AES_ROM_TABLES */
+
+#if defined(MBEDTLS_AES_FEWER_TABLES)
+
+#define ROTL8(x) ( (uint32_t)( ( x ) << 8 ) + (uint32_t)( ( x ) >> 24 ) )
+#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) )
+#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >> 8 ) )
+
+#define AES_RT0(idx) RT0[idx]
+#define AES_RT1(idx) ROTL8( RT0[idx] )
+#define AES_RT2(idx) ROTL16( RT0[idx] )
+#define AES_RT3(idx) ROTL24( RT0[idx] )
+
+#define AES_FT0(idx) FT0[idx]
+#define AES_FT1(idx) ROTL8( FT0[idx] )
+#define AES_FT2(idx) ROTL16( FT0[idx] )
+#define AES_FT3(idx) ROTL24( FT0[idx] )
+
+#else /* MBEDTLS_AES_FEWER_TABLES */
+
+#define AES_RT0(idx) RT0[idx]
+#define AES_RT1(idx) RT1[idx]
+#define AES_RT2(idx) RT2[idx]
+#define AES_RT3(idx) RT3[idx]
+
+#define AES_FT0(idx) FT0[idx]
+#define AES_FT1(idx) FT1[idx]
+#define AES_FT2(idx) FT2[idx]
+#define AES_FT3(idx) FT3[idx]
+
+#endif /* MBEDTLS_AES_FEWER_TABLES */
+
+void mbedtls_aes_init( mbedtls_aes_context *ctx )
+{
+ AES_VALIDATE( ctx != NULL );
+
+ memset( ctx, 0, sizeof( mbedtls_aes_context ) );
+}
+
+void mbedtls_aes_free( mbedtls_aes_context *ctx )
+{
+ if( ctx == NULL )
+ return;
+
+ mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
+{
+ AES_VALIDATE( ctx != NULL );
+
+ mbedtls_aes_init( &ctx->crypt );
+ mbedtls_aes_init( &ctx->tweak );
+}
+
+void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
+{
+ if( ctx == NULL )
+ return;
+
+ mbedtls_aes_free( &ctx->crypt );
+ mbedtls_aes_free( &ctx->tweak );
+}
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+/*
+ * AES key schedule (encryption)
+ */
+#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
+int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
+ unsigned int keybits )
+{
+ unsigned int i;
+ uint32_t *RK;
+
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( key != NULL );
+
+ switch( keybits )
+ {
+ case 128: ctx->nr = 10; break;
+ case 192: ctx->nr = 12; break;
+ case 256: ctx->nr = 14; break;
+ default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
+ }
+
+#if !defined(MBEDTLS_AES_ROM_TABLES)
+ if( aes_init_done == 0 )
+ {
+ aes_gen_tables();
+ aes_init_done = 1;
+ }
+#endif
+
+#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
+ if( aes_padlock_ace == -1 )
+ aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
+
+ if( aes_padlock_ace )
+ ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
+ else
+#endif
+ ctx->rk = RK = ctx->buf;
+
+#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
+ if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
+ return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) );
+#endif
+
+ for( i = 0; i < ( keybits >> 5 ); i++ )
+ {
+ GET_UINT32_LE( RK[i], key, i << 2 );
+ }
+
+ switch( ctx->nr )
+ {
+ case 10:
+
+ for( i = 0; i < 10; i++, RK += 4 )
+ {
+ RK[4] = RK[0] ^ RCON[i] ^
+ ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^
+ ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 );
+
+ RK[5] = RK[1] ^ RK[4];
+ RK[6] = RK[2] ^ RK[5];
+ RK[7] = RK[3] ^ RK[6];
+ }
+ break;
+
+ case 12:
+
+ for( i = 0; i < 8; i++, RK += 6 )
+ {
+ RK[6] = RK[0] ^ RCON[i] ^
+ ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^
+ ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 );
+
+ RK[7] = RK[1] ^ RK[6];
+ RK[8] = RK[2] ^ RK[7];
+ RK[9] = RK[3] ^ RK[8];
+ RK[10] = RK[4] ^ RK[9];
+ RK[11] = RK[5] ^ RK[10];
+ }
+ break;
+
+ case 14:
+
+ for( i = 0; i < 7; i++, RK += 8 )
+ {
+ RK[8] = RK[0] ^ RCON[i] ^
+ ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^
+ ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 );
+
+ RK[9] = RK[1] ^ RK[8];
+ RK[10] = RK[2] ^ RK[9];
+ RK[11] = RK[3] ^ RK[10];
+
+ RK[12] = RK[4] ^
+ ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^
+ ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
+
+ RK[13] = RK[5] ^ RK[12];
+ RK[14] = RK[6] ^ RK[13];
+ RK[15] = RK[7] ^ RK[14];
+ }
+ break;
+ }
+
+ return( 0 );
+}
+#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
+
+/*
+ * AES key schedule (decryption)
+ */
+#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
+int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
+ unsigned int keybits )
+{
+ int i, j, ret;
+ mbedtls_aes_context cty;
+ uint32_t *RK;
+ uint32_t *SK;
+
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( key != NULL );
+
+ mbedtls_aes_init( &cty );
+
+#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
+ if( aes_padlock_ace == -1 )
+ aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
+
+ if( aes_padlock_ace )
+ ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
+ else
+#endif
+ ctx->rk = RK = ctx->buf;
+
+ /* Also checks keybits */
+ if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 )
+ goto exit;
+
+ ctx->nr = cty.nr;
+
+#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
+ if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
+ {
+ mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk,
+ (const unsigned char *) cty.rk, ctx->nr );
+ goto exit;
+ }
+#endif
+
+ SK = cty.rk + cty.nr * 4;
+
+ *RK++ = *SK++;
+ *RK++ = *SK++;
+ *RK++ = *SK++;
+ *RK++ = *SK++;
+
+ for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
+ {
+ for( j = 0; j < 4; j++, SK++ )
+ {
+ *RK++ = AES_RT0( FSb[ ( *SK ) & 0xFF ] ) ^
+ AES_RT1( FSb[ ( *SK >> 8 ) & 0xFF ] ) ^
+ AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^
+ AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] );
+ }
+ }
+
+ *RK++ = *SK++;
+ *RK++ = *SK++;
+ *RK++ = *SK++;
+ *RK++ = *SK++;
+
+exit:
+ mbedtls_aes_free( &cty );
+
+ return( ret );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
+ unsigned int keybits,
+ const unsigned char **key1,
+ unsigned int *key1bits,
+ const unsigned char **key2,
+ unsigned int *key2bits )
+{
+ const unsigned int half_keybits = keybits / 2;
+ const unsigned int half_keybytes = half_keybits / 8;
+
+ switch( keybits )
+ {
+ case 256: break;
+ case 512: break;
+ default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
+ }
+
+ *key1bits = half_keybits;
+ *key2bits = half_keybits;
+ *key1 = &key[0];
+ *key2 = &key[half_keybytes];
+
+ return 0;
+}
+
+int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
+ const unsigned char *key,
+ unsigned int keybits)
+{
+ int ret;
+ const unsigned char *key1, *key2;
+ unsigned int key1bits, key2bits;
+
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( key != NULL );
+
+ ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
+ &key2, &key2bits );
+ if( ret != 0 )
+ return( ret );
+
+ /* Set the tweak key. Always set tweak key for the encryption mode. */
+ ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
+ if( ret != 0 )
+ return( ret );
+
+ /* Set crypt key for encryption. */
+ return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits );
+}
+
+int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
+ const unsigned char *key,
+ unsigned int keybits)
+{
+ int ret;
+ const unsigned char *key1, *key2;
+ unsigned int key1bits, key2bits;
+
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( key != NULL );
+
+ ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
+ &key2, &key2bits );
+ if( ret != 0 )
+ return( ret );
+
+ /* Set the tweak key. Always set tweak key for encryption. */
+ ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
+ if( ret != 0 )
+ return( ret );
+
+ /* Set crypt key for decryption. */
+ return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits );
+}
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
+
+#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
+ do \
+ { \
+ (X0) = *RK++ ^ AES_FT0( ( (Y0) ) & 0xFF ) ^ \
+ AES_FT1( ( (Y1) >> 8 ) & 0xFF ) ^ \
+ AES_FT2( ( (Y2) >> 16 ) & 0xFF ) ^ \
+ AES_FT3( ( (Y3) >> 24 ) & 0xFF ); \
+ \
+ (X1) = *RK++ ^ AES_FT0( ( (Y1) ) & 0xFF ) ^ \
+ AES_FT1( ( (Y2) >> 8 ) & 0xFF ) ^ \
+ AES_FT2( ( (Y3) >> 16 ) & 0xFF ) ^ \
+ AES_FT3( ( (Y0) >> 24 ) & 0xFF ); \
+ \
+ (X2) = *RK++ ^ AES_FT0( ( (Y2) ) & 0xFF ) ^ \
+ AES_FT1( ( (Y3) >> 8 ) & 0xFF ) ^ \
+ AES_FT2( ( (Y0) >> 16 ) & 0xFF ) ^ \
+ AES_FT3( ( (Y1) >> 24 ) & 0xFF ); \
+ \
+ (X3) = *RK++ ^ AES_FT0( ( (Y3) ) & 0xFF ) ^ \
+ AES_FT1( ( (Y0) >> 8 ) & 0xFF ) ^ \
+ AES_FT2( ( (Y1) >> 16 ) & 0xFF ) ^ \
+ AES_FT3( ( (Y2) >> 24 ) & 0xFF ); \
+ } while( 0 )
+
+#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
+ do \
+ { \
+ (X0) = *RK++ ^ AES_RT0( ( (Y0) ) & 0xFF ) ^ \
+ AES_RT1( ( (Y3) >> 8 ) & 0xFF ) ^ \
+ AES_RT2( ( (Y2) >> 16 ) & 0xFF ) ^ \
+ AES_RT3( ( (Y1) >> 24 ) & 0xFF ); \
+ \
+ (X1) = *RK++ ^ AES_RT0( ( (Y1) ) & 0xFF ) ^ \
+ AES_RT1( ( (Y0) >> 8 ) & 0xFF ) ^ \
+ AES_RT2( ( (Y3) >> 16 ) & 0xFF ) ^ \
+ AES_RT3( ( (Y2) >> 24 ) & 0xFF ); \
+ \
+ (X2) = *RK++ ^ AES_RT0( ( (Y2) ) & 0xFF ) ^ \
+ AES_RT1( ( (Y1) >> 8 ) & 0xFF ) ^ \
+ AES_RT2( ( (Y0) >> 16 ) & 0xFF ) ^ \
+ AES_RT3( ( (Y3) >> 24 ) & 0xFF ); \
+ \
+ (X3) = *RK++ ^ AES_RT0( ( (Y3) ) & 0xFF ) ^ \
+ AES_RT1( ( (Y2) >> 8 ) & 0xFF ) ^ \
+ AES_RT2( ( (Y1) >> 16 ) & 0xFF ) ^ \
+ AES_RT3( ( (Y0) >> 24 ) & 0xFF ); \
+ } while( 0 )
+
+/*
+ * AES-ECB block encryption
+ */
+#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
+int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
+ const unsigned char input[16],
+ unsigned char output[16] )
+{
+ int i;
+ uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+
+ RK = ctx->rk;
+
+ GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++;
+ GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++;
+ GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++;
+ GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
+
+ for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
+ {
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
+ }
+
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+
+ X0 = *RK++ ^ \
+ ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^
+ ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
+
+ X1 = *RK++ ^ \
+ ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^
+ ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
+
+ X2 = *RK++ ^ \
+ ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^
+ ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
+
+ X3 = *RK++ ^ \
+ ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^
+ ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
+
+ PUT_UINT32_LE( X0, output, 0 );
+ PUT_UINT32_LE( X1, output, 4 );
+ PUT_UINT32_LE( X2, output, 8 );
+ PUT_UINT32_LE( X3, output, 12 );
+
+ return( 0 );
+}
+#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
+ const unsigned char input[16],
+ unsigned char output[16] )
+{
+ mbedtls_internal_aes_encrypt( ctx, input, output );
+}
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/*
+ * AES-ECB block decryption
+ */
+#if !defined(MBEDTLS_AES_DECRYPT_ALT)
+int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
+ const unsigned char input[16],
+ unsigned char output[16] )
+{
+ int i;
+ uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+
+ RK = ctx->rk;
+
+ GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++;
+ GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++;
+ GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++;
+ GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
+
+ for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
+ {
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
+ }
+
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+
+ X0 = *RK++ ^ \
+ ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^
+ ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
+
+ X1 = *RK++ ^ \
+ ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^
+ ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
+
+ X2 = *RK++ ^ \
+ ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^
+ ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
+
+ X3 = *RK++ ^ \
+ ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^
+ ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
+
+ PUT_UINT32_LE( X0, output, 0 );
+ PUT_UINT32_LE( X1, output, 4 );
+ PUT_UINT32_LE( X2, output, 8 );
+ PUT_UINT32_LE( X3, output, 12 );
+
+ return( 0 );
+}
+#endif /* !MBEDTLS_AES_DECRYPT_ALT */
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
+ const unsigned char input[16],
+ unsigned char output[16] )
+{
+ mbedtls_internal_aes_decrypt( ctx, input, output );
+}
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/*
+ * AES-ECB block encryption/decryption
+ */
+int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
+ int mode,
+ const unsigned char input[16],
+ unsigned char output[16] )
+{
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( input != NULL );
+ AES_VALIDATE_RET( output != NULL );
+ AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+ mode == MBEDTLS_AES_DECRYPT );
+
+#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
+ if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
+ return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) );
+#endif
+
+#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
+ if( aes_padlock_ace )
+ {
+ if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 )
+ return( 0 );
+
+ // If padlock data misaligned, we just fall back to
+ // unaccelerated mode
+ //
+ }
+#endif
+
+ if( mode == MBEDTLS_AES_ENCRYPT )
+ return( mbedtls_internal_aes_encrypt( ctx, input, output ) );
+ else
+ return( mbedtls_internal_aes_decrypt( ctx, input, output ) );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/*
+ * AES-CBC buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
+ int mode,
+ size_t length,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output )
+{
+ int i;
+ unsigned char temp[16];
+
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+ mode == MBEDTLS_AES_DECRYPT );
+ AES_VALIDATE_RET( iv != NULL );
+ AES_VALIDATE_RET( input != NULL );
+ AES_VALIDATE_RET( output != NULL );
+
+ if( length % 16 )
+ return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
+
+#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
+ if( aes_padlock_ace )
+ {
+ if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
+ return( 0 );
+
+ // If padlock data misaligned, we just fall back to
+ // unaccelerated mode
+ //
+ }
+#endif
+
+ if( mode == MBEDTLS_AES_DECRYPT )
+ {
+ while( length > 0 )
+ {
+ memcpy( temp, input, 16 );
+ mbedtls_aes_crypt_ecb( ctx, mode, input, output );
+
+ for( i = 0; i < 16; i++ )
+ output[i] = (unsigned char)( output[i] ^ iv[i] );
+
+ memcpy( iv, temp, 16 );
+
+ input += 16;
+ output += 16;
+ length -= 16;
+ }
+ }
+ else
+ {
+ while( length > 0 )
+ {
+ for( i = 0; i < 16; i++ )
+ output[i] = (unsigned char)( input[i] ^ iv[i] );
+
+ mbedtls_aes_crypt_ecb( ctx, mode, output, output );
+ memcpy( iv, output, 16 );
+
+ input += 16;
+ output += 16;
+ length -= 16;
+ }
+ }
+
+ return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+
+/* Endianess with 64 bits values */
+#ifndef GET_UINT64_LE
+#define GET_UINT64_LE(n,b,i) \
+{ \
+ (n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \
+ | ( (uint64_t) (b)[(i) + 6] << 48 ) \
+ | ( (uint64_t) (b)[(i) + 5] << 40 ) \
+ | ( (uint64_t) (b)[(i) + 4] << 32 ) \
+ | ( (uint64_t) (b)[(i) + 3] << 24 ) \
+ | ( (uint64_t) (b)[(i) + 2] << 16 ) \
+ | ( (uint64_t) (b)[(i) + 1] << 8 ) \
+ | ( (uint64_t) (b)[(i) ] ); \
+}
+#endif
+
+#ifndef PUT_UINT64_LE
+#define PUT_UINT64_LE(n,b,i) \
+{ \
+ (b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \
+ (b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \
+ (b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \
+ (b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \
+ (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
+ (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
+ (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
+ (b)[(i) ] = (unsigned char) ( (n) ); \
+}
+#endif
+
+typedef unsigned char mbedtls_be128[16];
+
+/*
+ * GF(2^128) multiplication function
+ *
+ * This function multiplies a field element by x in the polynomial field
+ * representation. It uses 64-bit word operations to gain speed but compensates
+ * for machine endianess and hence works correctly on both big and little
+ * endian machines.
+ */
+static void mbedtls_gf128mul_x_ble( unsigned char r[16],
+ const unsigned char x[16] )
+{
+ uint64_t a, b, ra, rb;
+
+ GET_UINT64_LE( a, x, 0 );
+ GET_UINT64_LE( b, x, 8 );
+
+ ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
+ rb = ( a >> 63 ) | ( b << 1 );
+
+ PUT_UINT64_LE( ra, r, 0 );
+ PUT_UINT64_LE( rb, r, 8 );
+}
+
+/*
+ * AES-XTS buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
+ int mode,
+ size_t length,
+ const unsigned char data_unit[16],
+ const unsigned char *input,
+ unsigned char *output )
+{
+ int ret;
+ size_t blocks = length / 16;
+ size_t leftover = length % 16;
+ unsigned char tweak[16];
+ unsigned char prev_tweak[16];
+ unsigned char tmp[16];
+
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+ mode == MBEDTLS_AES_DECRYPT );
+ AES_VALIDATE_RET( data_unit != NULL );
+ AES_VALIDATE_RET( input != NULL );
+ AES_VALIDATE_RET( output != NULL );
+
+ /* Data units must be at least 16 bytes long. */
+ if( length < 16 )
+ return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+
+ /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
+ if( length > ( 1 << 20 ) * 16 )
+ return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+
+ /* Compute the tweak. */
+ ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
+ data_unit, tweak );
+ if( ret != 0 )
+ return( ret );
+
+ while( blocks-- )
+ {
+ size_t i;
+
+ if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
+ {
+ /* We are on the last block in a decrypt operation that has
+ * leftover bytes, so we need to use the next tweak for this block,
+ * and this tweak for the lefover bytes. Save the current tweak for
+ * the leftovers and then update the current tweak for use on this,
+ * the last full block. */
+ memcpy( prev_tweak, tweak, sizeof( tweak ) );
+ mbedtls_gf128mul_x_ble( tweak, tweak );
+ }
+
+ for( i = 0; i < 16; i++ )
+ tmp[i] = input[i] ^ tweak[i];
+
+ ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
+ if( ret != 0 )
+ return( ret );
+
+ for( i = 0; i < 16; i++ )
+ output[i] = tmp[i] ^ tweak[i];
+
+ /* Update the tweak for the next block. */
+ mbedtls_gf128mul_x_ble( tweak, tweak );
+
+ output += 16;
+ input += 16;
+ }
+
+ if( leftover )
+ {
+ /* If we are on the leftover bytes in a decrypt operation, we need to
+ * use the previous tweak for these bytes (as saved in prev_tweak). */
+ unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
+
+ /* We are now on the final part of the data unit, which doesn't divide
+ * evenly by 16. It's time for ciphertext stealing. */
+ size_t i;
+ unsigned char *prev_output = output - 16;
+
+ /* Copy ciphertext bytes from the previous block to our output for each
+ * byte of cyphertext we won't steal. At the same time, copy the
+ * remainder of the input for this final round (since the loop bounds
+ * are the same). */
+ for( i = 0; i < leftover; i++ )
+ {
+ output[i] = prev_output[i];
+ tmp[i] = input[i] ^ t[i];
+ }
+
+ /* Copy ciphertext bytes from the previous block for input in this
+ * round. */
+ for( ; i < 16; i++ )
+ tmp[i] = prev_output[i] ^ t[i];
+
+ ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
+ if( ret != 0 )
+ return ret;
+
+ /* Write the result back to the previous block, overriding the previous
+ * output we copied. */
+ for( i = 0; i < 16; i++ )
+ prev_output[i] = tmp[i] ^ t[i];
+ }
+
+ return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+/*
+ * AES-CFB128 buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
+ int mode,
+ size_t length,
+ size_t *iv_off,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output )
+{
+ int c;
+ size_t n;
+
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+ mode == MBEDTLS_AES_DECRYPT );
+ AES_VALIDATE_RET( iv_off != NULL );
+ AES_VALIDATE_RET( iv != NULL );
+ AES_VALIDATE_RET( input != NULL );
+ AES_VALIDATE_RET( output != NULL );
+
+ n = *iv_off;
+
+ if( n > 15 )
+ return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
+
+ if( mode == MBEDTLS_AES_DECRYPT )
+ {
+ while( length-- )
+ {
+ if( n == 0 )
+ mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+
+ c = *input++;
+ *output++ = (unsigned char)( c ^ iv[n] );
+ iv[n] = (unsigned char) c;
+
+ n = ( n + 1 ) & 0x0F;
+ }
+ }
+ else
+ {
+ while( length-- )
+ {
+ if( n == 0 )
+ mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+
+ iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
+
+ n = ( n + 1 ) & 0x0F;
+ }
+ }
+
+ *iv_off = n;
+
+ return( 0 );
+}
+
+/*
+ * AES-CFB8 buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
+ int mode,
+ size_t length,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output )
+{
+ unsigned char c;
+ unsigned char ov[17];
+
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+ mode == MBEDTLS_AES_DECRYPT );
+ AES_VALIDATE_RET( iv != NULL );
+ AES_VALIDATE_RET( input != NULL );
+ AES_VALIDATE_RET( output != NULL );
+ while( length-- )
+ {
+ memcpy( ov, iv, 16 );
+ mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+
+ if( mode == MBEDTLS_AES_DECRYPT )
+ ov[16] = *input;
+
+ c = *output++ = (unsigned char)( iv[0] ^ *input++ );
+
+ if( mode == MBEDTLS_AES_ENCRYPT )
+ ov[16] = c;
+
+ memcpy( iv, ov + 1, 16 );
+ }
+
+ return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+/*
+ * AES-OFB (Output Feedback Mode) buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
+ size_t length,
+ size_t *iv_off,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output )
+{
+ int ret = 0;
+ size_t n;
+
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( iv_off != NULL );
+ AES_VALIDATE_RET( iv != NULL );
+ AES_VALIDATE_RET( input != NULL );
+ AES_VALIDATE_RET( output != NULL );
+
+ n = *iv_off;
+
+ if( n > 15 )
+ return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
+
+ while( length-- )
+ {
+ if( n == 0 )
+ {
+ ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+ if( ret != 0 )
+ goto exit;
+ }
+ *output++ = *input++ ^ iv[n];
+
+ n = ( n + 1 ) & 0x0F;
+ }
+
+ *iv_off = n;
+
+exit:
+ return( ret );
+}
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/*
+ * AES-CTR buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
+ size_t length,
+ size_t *nc_off,
+ unsigned char nonce_counter[16],
+ unsigned char stream_block[16],
+ const unsigned char *input,
+ unsigned char *output )
+{
+ int c, i;
+ size_t n;
+
+ AES_VALIDATE_RET( ctx != NULL );
+ AES_VALIDATE_RET( nc_off != NULL );
+ AES_VALIDATE_RET( nonce_counter != NULL );
+ AES_VALIDATE_RET( stream_block != NULL );
+ AES_VALIDATE_RET( input != NULL );
+ AES_VALIDATE_RET( output != NULL );
+
+ n = *nc_off;
+
+ if ( n > 0x0F )
+ return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
+
+ while( length-- )
+ {
+ if( n == 0 ) {
+ mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
+
+ for( i = 16; i > 0; i-- )
+ if( ++nonce_counter[i - 1] != 0 )
+ break;
+ }
+ c = *input++;
+ *output++ = (unsigned char)( c ^ stream_block[n] );
+
+ n = ( n + 1 ) & 0x0F;
+ }
+
+ *nc_off = n;
+
+ return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#endif /* !MBEDTLS_AES_ALT */
+
+#if defined(MBEDTLS_SELF_TEST)
+/*
+ * AES test vectors from:
+ *
+ * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
+ */
+static const unsigned char aes_test_ecb_dec[3][16] =
+{
+ { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
+ 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
+ { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
+ 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
+ { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
+ 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
+};
+
+static const unsigned char aes_test_ecb_enc[3][16] =
+{
+ { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
+ 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
+ { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
+ 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
+ { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
+ 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
+};
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const unsigned char aes_test_cbc_dec[3][16] =
+{
+ { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
+ 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
+ { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
+ 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
+ { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
+ 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
+};
+
+static const unsigned char aes_test_cbc_enc[3][16] =
+{
+ { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
+ 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
+ { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
+ 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
+ { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
+ 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+/*
+ * AES-CFB128 test vectors from:
+ *
+ * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+ */
+static const unsigned char aes_test_cfb128_key[3][32] =
+{
+ { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
+ 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
+ { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
+ 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
+ 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
+ { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
+ 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
+ 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
+ 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
+};
+
+static const unsigned char aes_test_cfb128_iv[16] =
+{
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+};
+
+static const unsigned char aes_test_cfb128_pt[64] =
+{
+ 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
+ 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
+ 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
+ 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
+ 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
+ 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
+ 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
+ 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
+};
+
+static const unsigned char aes_test_cfb128_ct[3][64] =
+{
+ { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
+ 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
+ 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
+ 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
+ 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
+ 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
+ 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
+ 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
+ { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
+ 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
+ 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
+ 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
+ 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
+ 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
+ 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
+ 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
+ { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
+ 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
+ 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
+ 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
+ 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
+ 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
+ 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
+ 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
+};
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+/*
+ * AES-OFB test vectors from:
+ *
+ * https://csrc.nist.gov/publications/detail/sp/800-38a/final
+ */
+static const unsigned char aes_test_ofb_key[3][32] =
+{
+ { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
+ 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
+ { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
+ 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
+ 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
+ { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
+ 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
+ 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
+ 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
+};
+
+static const unsigned char aes_test_ofb_iv[16] =
+{
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+};
+
+static const unsigned char aes_test_ofb_pt[64] =
+{
+ 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
+ 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
+ 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
+ 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
+ 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
+ 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
+ 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
+ 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
+};
+
+static const unsigned char aes_test_ofb_ct[3][64] =
+{
+ { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
+ 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
+ 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
+ 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
+ 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
+ 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
+ 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
+ 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
+ { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
+ 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
+ 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
+ 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
+ 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
+ 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
+ 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
+ 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
+ { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
+ 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
+ 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
+ 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
+ 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
+ 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
+ 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
+ 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
+};
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/*
+ * AES-CTR test vectors from:
+ *
+ * http://www.faqs.org/rfcs/rfc3686.html
+ */
+
+static const unsigned char aes_test_ctr_key[3][16] =
+{
+ { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
+ 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
+ { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
+ 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
+ { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
+ 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
+};
+
+static const unsigned char aes_test_ctr_nonce_counter[3][16] =
+{
+ { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
+ { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
+ 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
+ { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
+ 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
+};
+
+static const unsigned char aes_test_ctr_pt[3][48] =
+{
+ { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
+ 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
+
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
+
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x20, 0x21, 0x22, 0x23 }
+};
+
+static const unsigned char aes_test_ctr_ct[3][48] =
+{
+ { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
+ 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
+ { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
+ 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
+ 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
+ 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
+ { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
+ 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
+ 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
+ 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
+ 0x25, 0xB2, 0x07, 0x2F }
+};
+
+static const int aes_test_ctr_len[3] =
+ { 16, 32, 36 };
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+/*
+ * AES-XTS test vectors from:
+ *
+ * IEEE P1619/D16 Annex B
+ * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
+ * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
+ */
+static const unsigned char aes_test_xts_key[][32] =
+{
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
+ { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
+ 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
+};
+
+static const unsigned char aes_test_xts_pt32[][32] =
+{
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
+ { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
+};
+
+static const unsigned char aes_test_xts_ct32[][32] =
+{
+ { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
+ 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
+ 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
+ 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
+ { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
+ 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
+ 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
+ 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
+ { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
+ 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
+ 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
+ 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
+};
+
+static const unsigned char aes_test_xts_data_unit[][16] =
+{
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+};
+
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+/*
+ * Checkup routine
+ */
+int mbedtls_aes_self_test( int verbose )
+{
+ int ret = 0, i, j, u, mode;
+ unsigned int keybits;
+ unsigned char key[32];
+ unsigned char buf[64];
+ const unsigned char *aes_tests;
+#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
+ unsigned char iv[16];
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ unsigned char prv[16];
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
+ defined(MBEDTLS_CIPHER_MODE_OFB)
+ size_t offset;
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
+ int len;
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ unsigned char nonce_counter[16];
+ unsigned char stream_block[16];
+#endif
+ mbedtls_aes_context ctx;
+
+ memset( key, 0, 32 );
+ mbedtls_aes_init( &ctx );
+
+ /*
+ * ECB mode
+ */
+ for( i = 0; i < 6; i++ )
+ {
+ u = i >> 1;
+ keybits = 128 + u * 64;
+ mode = i & 1;
+
+ if( verbose != 0 )
+ mbedtls_printf( " AES-ECB-%3d (%s): ", keybits,
+ ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
+
+ memset( buf, 0, 16 );
+
+ if( mode == MBEDTLS_AES_DECRYPT )
+ {
+ ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
+ aes_tests = aes_test_ecb_dec[u];
+ }
+ else
+ {
+ ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
+ aes_tests = aes_test_ecb_enc[u];
+ }
+
+ /*
+ * AES-192 is an optional feature that may be unavailable when
+ * there is an alternative underlying implementation i.e. when
+ * MBEDTLS_AES_ALT is defined.
+ */
+ if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
+ {
+ mbedtls_printf( "skipped\n" );
+ continue;
+ }
+ else if( ret != 0 )
+ {
+ goto exit;
+ }
+
+ for( j = 0; j < 10000; j++ )
+ {
+ ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf );
+ if( ret != 0 )
+ goto exit;
+ }
+
+ if( memcmp( buf, aes_tests, 16 ) != 0 )
+ {
+ ret = 1;
+ goto exit;
+ }
+
+ if( verbose != 0 )
+ mbedtls_printf( "passed\n" );
+ }
+
+ if( verbose != 0 )
+ mbedtls_printf( "\n" );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ /*
+ * CBC mode
+ */
+ for( i = 0; i < 6; i++ )
+ {
+ u = i >> 1;
+ keybits = 128 + u * 64;
+ mode = i & 1;
+
+ if( verbose != 0 )
+ mbedtls_printf( " AES-CBC-%3d (%s): ", keybits,
+ ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
+
+ memset( iv , 0, 16 );
+ memset( prv, 0, 16 );
+ memset( buf, 0, 16 );
+
+ if( mode == MBEDTLS_AES_DECRYPT )
+ {
+ ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
+ aes_tests = aes_test_cbc_dec[u];
+ }
+ else
+ {
+ ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
+ aes_tests = aes_test_cbc_enc[u];
+ }
+
+ /*
+ * AES-192 is an optional feature that may be unavailable when
+ * there is an alternative underlying implementation i.e. when
+ * MBEDTLS_AES_ALT is defined.
+ */
+ if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
+ {
+ mbedtls_printf( "skipped\n" );
+ continue;
+ }
+ else if( ret != 0 )
+ {
+ goto exit;
+ }
+
+ for( j = 0; j < 10000; j++ )
+ {
+ if( mode == MBEDTLS_AES_ENCRYPT )
+ {
+ unsigned char tmp[16];
+
+ memcpy( tmp, prv, 16 );
+ memcpy( prv, buf, 16 );
+ memcpy( buf, tmp, 16 );
+ }
+
+ ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf );
+ if( ret != 0 )
+ goto exit;
+
+ }
+
+ if( memcmp( buf, aes_tests, 16 ) != 0 )
+ {
+ ret = 1;
+ goto exit;
+ }
+
+ if( verbose != 0 )
+ mbedtls_printf( "passed\n" );
+ }
+
+ if( verbose != 0 )
+ mbedtls_printf( "\n" );
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ /*
+ * CFB128 mode
+ */
+ for( i = 0; i < 6; i++ )
+ {
+ u = i >> 1;
+ keybits = 128 + u * 64;
+ mode = i & 1;
+
+ if( verbose != 0 )
+ mbedtls_printf( " AES-CFB128-%3d (%s): ", keybits,
+ ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
+
+ memcpy( iv, aes_test_cfb128_iv, 16 );
+ memcpy( key, aes_test_cfb128_key[u], keybits / 8 );
+
+ offset = 0;
+ ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
+ /*
+ * AES-192 is an optional feature that may be unavailable when
+ * there is an alternative underlying implementation i.e. when
+ * MBEDTLS_AES_ALT is defined.
+ */
+ if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
+ {
+ mbedtls_printf( "skipped\n" );
+ continue;
+ }
+ else if( ret != 0 )
+ {
+ goto exit;
+ }
+
+ if( mode == MBEDTLS_AES_DECRYPT )
+ {
+ memcpy( buf, aes_test_cfb128_ct[u], 64 );
+ aes_tests = aes_test_cfb128_pt;
+ }
+ else
+ {
+ memcpy( buf, aes_test_cfb128_pt, 64 );
+ aes_tests = aes_test_cfb128_ct[u];
+ }
+
+ ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf );
+ if( ret != 0 )
+ goto exit;
+
+ if( memcmp( buf, aes_tests, 64 ) != 0 )
+ {
+ ret = 1;
+ goto exit;
+ }
+
+ if( verbose != 0 )
+ mbedtls_printf( "passed\n" );
+ }
+
+ if( verbose != 0 )
+ mbedtls_printf( "\n" );
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ /*
+ * OFB mode
+ */
+ for( i = 0; i < 6; i++ )
+ {
+ u = i >> 1;
+ keybits = 128 + u * 64;
+ mode = i & 1;
+
+ if( verbose != 0 )
+ mbedtls_printf( " AES-OFB-%3d (%s): ", keybits,
+ ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
+
+ memcpy( iv, aes_test_ofb_iv, 16 );
+ memcpy( key, aes_test_ofb_key[u], keybits / 8 );
+
+ offset = 0;
+ ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
+ /*
+ * AES-192 is an optional feature that may be unavailable when
+ * there is an alternative underlying implementation i.e. when
+ * MBEDTLS_AES_ALT is defined.
+ */
+ if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
+ {
+ mbedtls_printf( "skipped\n" );
+ continue;
+ }
+ else if( ret != 0 )
+ {
+ goto exit;
+ }
+
+ if( mode == MBEDTLS_AES_DECRYPT )
+ {
+ memcpy( buf, aes_test_ofb_ct[u], 64 );
+ aes_tests = aes_test_ofb_pt;
+ }
+ else
+ {
+ memcpy( buf, aes_test_ofb_pt, 64 );
+ aes_tests = aes_test_ofb_ct[u];
+ }
+
+ ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf );
+ if( ret != 0 )
+ goto exit;
+
+ if( memcmp( buf, aes_tests, 64 ) != 0 )
+ {
+ ret = 1;
+ goto exit;
+ }
+
+ if( verbose != 0 )
+ mbedtls_printf( "passed\n" );
+ }
+
+ if( verbose != 0 )
+ mbedtls_printf( "\n" );
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ /*
+ * CTR mode
+ */
+ for( i = 0; i < 6; i++ )
+ {
+ u = i >> 1;
+ mode = i & 1;
+
+ if( verbose != 0 )
+ mbedtls_printf( " AES-CTR-128 (%s): ",
+ ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
+
+ memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 );
+ memcpy( key, aes_test_ctr_key[u], 16 );
+
+ offset = 0;
+ if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 )
+ goto exit;
+
+ len = aes_test_ctr_len[u];
+
+ if( mode == MBEDTLS_AES_DECRYPT )
+ {
+ memcpy( buf, aes_test_ctr_ct[u], len );
+ aes_tests = aes_test_ctr_pt[u];
+ }
+ else
+ {
+ memcpy( buf, aes_test_ctr_pt[u], len );
+ aes_tests = aes_test_ctr_ct[u];
+ }
+
+ ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter,
+ stream_block, buf, buf );
+ if( ret != 0 )
+ goto exit;
+
+ if( memcmp( buf, aes_tests, len ) != 0 )
+ {
+ ret = 1;
+ goto exit;
+ }
+
+ if( verbose != 0 )
+ mbedtls_printf( "passed\n" );
+ }
+
+ if( verbose != 0 )
+ mbedtls_printf( "\n" );
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ {
+ static const int num_tests =
+ sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
+ mbedtls_aes_xts_context ctx_xts;
+
+ /*
+ * XTS mode
+ */
+ mbedtls_aes_xts_init( &ctx_xts );
+
+ for( i = 0; i < num_tests << 1; i++ )
+ {
+ const unsigned char *data_unit;
+ u = i >> 1;
+ mode = i & 1;
+
+ if( verbose != 0 )
+ mbedtls_printf( " AES-XTS-128 (%s): ",
+ ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
+
+ memset( key, 0, sizeof( key ) );
+ memcpy( key, aes_test_xts_key[u], 32 );
+ data_unit = aes_test_xts_data_unit[u];
+
+ len = sizeof( *aes_test_xts_ct32 );
+
+ if( mode == MBEDTLS_AES_DECRYPT )
+ {
+ ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 );
+ if( ret != 0)
+ goto exit;
+ memcpy( buf, aes_test_xts_ct32[u], len );
+ aes_tests = aes_test_xts_pt32[u];
+ }
+ else
+ {
+ ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 );
+ if( ret != 0)
+ goto exit;
+ memcpy( buf, aes_test_xts_pt32[u], len );
+ aes_tests = aes_test_xts_ct32[u];
+ }
+
+
+ ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit,
+ buf, buf );
+ if( ret != 0 )
+ goto exit;
+
+ if( memcmp( buf, aes_tests, len ) != 0 )
+ {
+ ret = 1;
+ goto exit;
+ }
+
+ if( verbose != 0 )
+ mbedtls_printf( "passed\n" );
+ }
+
+ if( verbose != 0 )
+ mbedtls_printf( "\n" );
+
+ mbedtls_aes_xts_free( &ctx_xts );
+ }
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+ ret = 0;
+
+exit:
+ if( ret != 0 && verbose != 0 )
+ mbedtls_printf( "failed\n" );
+
+ mbedtls_aes_free( &ctx );
+
+ return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_AES_C */
diff --git a/templates/blackpill/Src/aes.h b/templates/blackpill/Src/aes.h
new file mode 100644
index 0000000..94e7282
--- /dev/null
+++ b/templates/blackpill/Src/aes.h
@@ -0,0 +1,674 @@
+/**
+ * \file aes.h
+ *
+ * \brief This file contains AES definitions and functions.
+ *
+ * The Advanced Encryption Standard (AES) specifies a FIPS-approved
+ * cryptographic algorithm that can be used to protect electronic
+ * data.
+ *
+ * The AES algorithm is a symmetric block cipher that can
+ * encrypt and decrypt information. For more information, see
+ * FIPS Publication 197: Advanced Encryption Standard and
+ * ISO/IEC 18033-2:2006: Information technology -- Security
+ * techniques -- Encryption algorithms -- Part 2: Asymmetric
+ * ciphers.
+ *
+ * The AES-XTS block mode is standardized by NIST SP 800-38E
+ *
+ * and described in detail by IEEE P1619
+ * .
+ */
+
+/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ * This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_AES_H
+#define MBEDTLS_AES_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include
+#include
+
+/* padlock.c and aesni.c rely on these values! */
+#define MBEDTLS_AES_ENCRYPT 1 /**< AES encryption. */
+#define MBEDTLS_AES_DECRYPT 0 /**< AES decryption. */
+
+/* Error codes in range 0x0020-0x0022 */
+#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
+#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
+
+/* Error codes in range 0x0021-0x0025 */
+#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021 /**< Invalid input data. */
+
+/* MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE is deprecated and should not be used. */
+#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE -0x0023 /**< Feature not available. For example, an unsupported AES key size. */
+
+/* MBEDTLS_ERR_AES_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_AES_HW_ACCEL_FAILED -0x0025 /**< AES hardware accelerator failed. */
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+ !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_AES_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief The AES context-type definition.
+ */
+typedef struct mbedtls_aes_context
+{
+ int nr; /*!< The number of rounds. */
+ uint32_t *rk; /*!< AES round keys. */
+ uint32_t buf[68]; /*!< Unaligned data buffer. This buffer can
+ hold 32 extra Bytes, which can be used for
+ one of the following purposes:
+ - Alignment if VIA padlock is
+ used.
+ - Simplifying key expansion in the 256-bit
+ case by generating an extra round key.
+
*/
+}
+mbedtls_aes_context;
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+/**
+ * \brief The AES XTS context-type definition.
+ */
+typedef struct mbedtls_aes_xts_context
+{
+ mbedtls_aes_context crypt; /*!< The AES context to use for AES block
+ encryption or decryption. */
+ mbedtls_aes_context tweak; /*!< The AES context used for tweak
+ computation. */
+} mbedtls_aes_xts_context;
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#else /* MBEDTLS_AES_ALT */
+#include "aes_alt.h"
+#endif /* MBEDTLS_AES_ALT */
+
+/**
+ * \brief This function initializes the specified AES context.
+ *
+ * It must be the first API called before using
+ * the context.
+ *
+ * \param ctx The AES context to initialize. This must not be \c NULL.
+ */
+void mbedtls_aes_init( mbedtls_aes_context *ctx );
+
+/**
+ * \brief This function releases and clears the specified AES context.
+ *
+ * \param ctx The AES context to clear.
+ * If this is \c NULL, this function does nothing.
+ * Otherwise, the context must have been at least initialized.
+ */
+void mbedtls_aes_free( mbedtls_aes_context *ctx );
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+/**
+ * \brief This function initializes the specified AES XTS context.
+ *
+ * It must be the first API called before using
+ * the context.
+ *
+ * \param ctx The AES XTS context to initialize. This must not be \c NULL.
+ */
+void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx );
+
+/**
+ * \brief This function releases and clears the specified AES XTS context.
+ *
+ * \param ctx The AES XTS context to clear.
+ * If this is \c NULL, this function does nothing.
+ * Otherwise, the context must have been at least initialized.
+ */
+void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx );
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+/**
+ * \brief This function sets the encryption key.
+ *
+ * \param ctx The AES context to which the key should be bound.
+ * It must be initialized.
+ * \param key The encryption key.
+ * This must be a readable buffer of size \p keybits bits.
+ * \param keybits The size of data passed in bits. Valid options are:
+ * - 128 bits
+ * - 192 bits
+ * - 256 bits
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
+ */
+int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
+ unsigned int keybits );
+
+/**
+ * \brief This function sets the decryption key.
+ *
+ * \param ctx The AES context to which the key should be bound.
+ * It must be initialized.
+ * \param key The decryption key.
+ * This must be a readable buffer of size \p keybits bits.
+ * \param keybits The size of data passed. Valid options are:
+ * - 128 bits
+ * - 192 bits
+ * - 256 bits
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
+ */
+int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
+ unsigned int keybits );
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+/**
+ * \brief This function prepares an XTS context for encryption and
+ * sets the encryption key.
+ *
+ * \param ctx The AES XTS context to which the key should be bound.
+ * It must be initialized.
+ * \param key The encryption key. This is comprised of the XTS key1
+ * concatenated with the XTS key2.
+ * This must be a readable buffer of size \p keybits bits.
+ * \param keybits The size of \p key passed in bits. Valid options are:
+ * - 256 bits (each of key1 and key2 is a 128-bit key)
+ * - 512 bits (each of key1 and key2 is a 256-bit key)
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
+ */
+int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
+ const unsigned char *key,
+ unsigned int keybits );
+
+/**
+ * \brief This function prepares an XTS context for decryption and
+ * sets the decryption key.
+ *
+ * \param ctx The AES XTS context to which the key should be bound.
+ * It must be initialized.
+ * \param key The decryption key. This is comprised of the XTS key1
+ * concatenated with the XTS key2.
+ * This must be a readable buffer of size \p keybits bits.
+ * \param keybits The size of \p key passed in bits. Valid options are:
+ * - 256 bits (each of key1 and key2 is a 128-bit key)
+ * - 512 bits (each of key1 and key2 is a 256-bit key)
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
+ */
+int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
+ const unsigned char *key,
+ unsigned int keybits );
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+/**
+ * \brief This function performs an AES single-block encryption or
+ * decryption operation.
+ *
+ * It performs the operation defined in the \p mode parameter
+ * (encrypt or decrypt), on the input data buffer defined in
+ * the \p input parameter.
+ *
+ * mbedtls_aes_init(), and either mbedtls_aes_setkey_enc() or
+ * mbedtls_aes_setkey_dec() must be called before the first
+ * call to this API with the same context.
+ *
+ * \param ctx The AES context to use for encryption or decryption.
+ * It must be initialized and bound to a key.
+ * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
+ * #MBEDTLS_AES_DECRYPT.
+ * \param input The buffer holding the input data.
+ * It must be readable and at least \c 16 Bytes long.
+ * \param output The buffer where the output data will be written.
+ * It must be writeable and at least \c 16 Bytes long.
+
+ * \return \c 0 on success.
+ */
+int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
+ int mode,
+ const unsigned char input[16],
+ unsigned char output[16] );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/**
+ * \brief This function performs an AES-CBC encryption or decryption operation
+ * on full blocks.
+ *
+ * It performs the operation defined in the \p mode
+ * parameter (encrypt/decrypt), on the input data buffer defined in
+ * the \p input parameter.
+ *
+ * It can be called as many times as needed, until all the input
+ * data is processed. mbedtls_aes_init(), and either
+ * mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called
+ * before the first call to this API with the same context.
+ *
+ * \note This function operates on full blocks, that is, the input size
+ * must be a multiple of the AES block size of \c 16 Bytes.
+ *
+ * \note Upon exit, the content of the IV is updated so that you can
+ * call the same function again on the next
+ * block(s) of data and get the same result as if it was
+ * encrypted in one call. This allows a "streaming" usage.
+ * If you need to retain the contents of the IV, you should
+ * either save it manually or use the cipher module instead.
+ *
+ *
+ * \param ctx The AES context to use for encryption or decryption.
+ * It must be initialized and bound to a key.
+ * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
+ * #MBEDTLS_AES_DECRYPT.
+ * \param length The length of the input data in Bytes. This must be a
+ * multiple of the block size (\c 16 Bytes).
+ * \param iv Initialization vector (updated after use).
+ * It must be a readable and writeable buffer of \c 16 Bytes.
+ * \param input The buffer holding the input data.
+ * It must be readable and of size \p length Bytes.
+ * \param output The buffer holding the output data.
+ * It must be writeable and of size \p length Bytes.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
+ * on failure.
+ */
+int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
+ int mode,
+ size_t length,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+/**
+ * \brief This function performs an AES-XTS encryption or decryption
+ * operation for an entire XTS data unit.
+ *
+ * AES-XTS encrypts or decrypts blocks based on their location as
+ * defined by a data unit number. The data unit number must be
+ * provided by \p data_unit.
+ *
+ * NIST SP 800-38E limits the maximum size of a data unit to 2^20
+ * AES blocks. If the data unit is larger than this, this function
+ * returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH.
+ *
+ * \param ctx The AES XTS context to use for AES XTS operations.
+ * It must be initialized and bound to a key.
+ * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
+ * #MBEDTLS_AES_DECRYPT.
+ * \param length The length of a data unit in Bytes. This can be any
+ * length between 16 bytes and 2^24 bytes inclusive
+ * (between 1 and 2^20 block cipher blocks).
+ * \param data_unit The address of the data unit encoded as an array of 16
+ * bytes in little-endian format. For disk encryption, this
+ * is typically the index of the block device sector that
+ * contains the data.
+ * \param input The buffer holding the input data (which is an entire
+ * data unit). This function reads \p length Bytes from \p
+ * input.
+ * \param output The buffer holding the output data (which is an entire
+ * data unit). This function writes \p length Bytes to \p
+ * output.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is
+ * smaller than an AES block in size (16 Bytes) or if \p
+ * length is larger than 2^20 blocks (16 MiB).
+ */
+int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
+ int mode,
+ size_t length,
+ const unsigned char data_unit[16],
+ const unsigned char *input,
+ unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+/**
+ * \brief This function performs an AES-CFB128 encryption or decryption
+ * operation.
+ *
+ * It performs the operation defined in the \p mode
+ * parameter (encrypt or decrypt), on the input data buffer
+ * defined in the \p input parameter.
+ *
+ * For CFB, you must set up the context with mbedtls_aes_setkey_enc(),
+ * regardless of whether you are performing an encryption or decryption
+ * operation, that is, regardless of the \p mode parameter. This is
+ * because CFB mode uses the same key schedule for encryption and
+ * decryption.
+ *
+ * \note Upon exit, the content of the IV is updated so that you can
+ * call the same function again on the next
+ * block(s) of data and get the same result as if it was
+ * encrypted in one call. This allows a "streaming" usage.
+ * If you need to retain the contents of the
+ * IV, you must either save it manually or use the cipher
+ * module instead.
+ *
+ *
+ * \param ctx The AES context to use for encryption or decryption.
+ * It must be initialized and bound to a key.
+ * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
+ * #MBEDTLS_AES_DECRYPT.
+ * \param length The length of the input data in Bytes.
+ * \param iv_off The offset in IV (updated after use).
+ * It must point to a valid \c size_t.
+ * \param iv The initialization vector (updated after use).
+ * It must be a readable and writeable buffer of \c 16 Bytes.
+ * \param input The buffer holding the input data.
+ * It must be readable and of size \p length Bytes.
+ * \param output The buffer holding the output data.
+ * It must be writeable and of size \p length Bytes.
+ *
+ * \return \c 0 on success.
+ */
+int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
+ int mode,
+ size_t length,
+ size_t *iv_off,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief This function performs an AES-CFB8 encryption or decryption
+ * operation.
+ *
+ * It performs the operation defined in the \p mode
+ * parameter (encrypt/decrypt), on the input data buffer defined
+ * in the \p input parameter.
+ *
+ * Due to the nature of CFB, you must use the same key schedule for
+ * both encryption and decryption operations. Therefore, you must
+ * use the context initialized with mbedtls_aes_setkey_enc() for
+ * both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT.
+ *
+ * \note Upon exit, the content of the IV is updated so that you can
+ * call the same function again on the next
+ * block(s) of data and get the same result as if it was
+ * encrypted in one call. This allows a "streaming" usage.
+ * If you need to retain the contents of the
+ * IV, you should either save it manually or use the cipher
+ * module instead.
+ *
+ *
+ * \param ctx The AES context to use for encryption or decryption.
+ * It must be initialized and bound to a key.
+ * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
+ * #MBEDTLS_AES_DECRYPT
+ * \param length The length of the input data.
+ * \param iv The initialization vector (updated after use).
+ * It must be a readable and writeable buffer of \c 16 Bytes.
+ * \param input The buffer holding the input data.
+ * It must be readable and of size \p length Bytes.
+ * \param output The buffer holding the output data.
+ * It must be writeable and of size \p length Bytes.
+ *
+ * \return \c 0 on success.
+ */
+int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
+ int mode,
+ size_t length,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output );
+#endif /*MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+/**
+ * \brief This function performs an AES-OFB (Output Feedback Mode)
+ * encryption or decryption operation.
+ *
+ * For OFB, you must set up the context with
+ * mbedtls_aes_setkey_enc(), regardless of whether you are
+ * performing an encryption or decryption operation. This is
+ * because OFB mode uses the same key schedule for encryption and
+ * decryption.
+ *
+ * The OFB operation is identical for encryption or decryption,
+ * therefore no operation mode needs to be specified.
+ *
+ * \note Upon exit, the content of iv, the Initialisation Vector, is
+ * updated so that you can call the same function again on the next
+ * block(s) of data and get the same result as if it was encrypted
+ * in one call. This allows a "streaming" usage, by initialising
+ * iv_off to 0 before the first call, and preserving its value
+ * between calls.
+ *
+ * For non-streaming use, the iv should be initialised on each call
+ * to a unique value, and iv_off set to 0 on each call.
+ *
+ * If you need to retain the contents of the initialisation vector,
+ * you must either save it manually or use the cipher module
+ * instead.
+ *
+ * \warning For the OFB mode, the initialisation vector must be unique
+ * every encryption operation. Reuse of an initialisation vector
+ * will compromise security.
+ *
+ * \param ctx The AES context to use for encryption or decryption.
+ * It must be initialized and bound to a key.
+ * \param length The length of the input data.
+ * \param iv_off The offset in IV (updated after use).
+ * It must point to a valid \c size_t.
+ * \param iv The initialization vector (updated after use).
+ * It must be a readable and writeable buffer of \c 16 Bytes.
+ * \param input The buffer holding the input data.
+ * It must be readable and of size \p length Bytes.
+ * \param output The buffer holding the output data.
+ * It must be writeable and of size \p length Bytes.
+ *
+ * \return \c 0 on success.
+ */
+int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
+ size_t length,
+ size_t *iv_off,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output );
+
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/**
+ * \brief This function performs an AES-CTR encryption or decryption
+ * operation.
+ *
+ * This function performs the operation defined in the \p mode
+ * parameter (encrypt/decrypt), on the input data buffer
+ * defined in the \p input parameter.
+ *
+ * Due to the nature of CTR, you must use the same key schedule
+ * for both encryption and decryption operations. Therefore, you
+ * must use the context initialized with mbedtls_aes_setkey_enc()
+ * for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT.
+ *
+ * \warning You must never reuse a nonce value with the same key. Doing so
+ * would void the encryption for the two messages encrypted with
+ * the same nonce and key.
+ *
+ * There are two common strategies for managing nonces with CTR:
+ *
+ * 1. You can handle everything as a single message processed over
+ * successive calls to this function. In that case, you want to
+ * set \p nonce_counter and \p nc_off to 0 for the first call, and
+ * then preserve the values of \p nonce_counter, \p nc_off and \p
+ * stream_block across calls to this function as they will be
+ * updated by this function.
+ *
+ * With this strategy, you must not encrypt more than 2**128
+ * blocks of data with the same key.
+ *
+ * 2. You can encrypt separate messages by dividing the \p
+ * nonce_counter buffer in two areas: the first one used for a
+ * per-message nonce, handled by yourself, and the second one
+ * updated by this function internally.
+ *
+ * For example, you might reserve the first 12 bytes for the
+ * per-message nonce, and the last 4 bytes for internal use. In that
+ * case, before calling this function on a new message you need to
+ * set the first 12 bytes of \p nonce_counter to your chosen nonce
+ * value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
+ * stream_block to be ignored). That way, you can encrypt at most
+ * 2**96 messages of up to 2**32 blocks each with the same key.
+ *
+ * The per-message nonce (or information sufficient to reconstruct
+ * it) needs to be communicated with the ciphertext and must be unique.
+ * The recommended way to ensure uniqueness is to use a message
+ * counter. An alternative is to generate random nonces, but this
+ * limits the number of messages that can be securely encrypted:
+ * for example, with 96-bit random nonces, you should not encrypt
+ * more than 2**32 messages with the same key.
+ *
+ * Note that for both stategies, sizes are measured in blocks and
+ * that an AES block is 16 bytes.
+ *
+ * \warning Upon return, \p stream_block contains sensitive data. Its
+ * content must not be written to insecure storage and should be
+ * securely discarded as soon as it's no longer needed.
+ *
+ * \param ctx The AES context to use for encryption or decryption.
+ * It must be initialized and bound to a key.
+ * \param length The length of the input data.
+ * \param nc_off The offset in the current \p stream_block, for
+ * resuming within the current cipher stream. The
+ * offset pointer should be 0 at the start of a stream.
+ * It must point to a valid \c size_t.
+ * \param nonce_counter The 128-bit nonce and counter.
+ * It must be a readable-writeable buffer of \c 16 Bytes.
+ * \param stream_block The saved stream block for resuming. This is
+ * overwritten by the function.
+ * It must be a readable-writeable buffer of \c 16 Bytes.
+ * \param input The buffer holding the input data.
+ * It must be readable and of size \p length Bytes.
+ * \param output The buffer holding the output data.
+ * It must be writeable and of size \p length Bytes.
+ *
+ * \return \c 0 on success.
+ */
+int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
+ size_t length,
+ size_t *nc_off,
+ unsigned char nonce_counter[16],
+ unsigned char stream_block[16],
+ const unsigned char *input,
+ unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+/**
+ * \brief Internal AES block encryption function. This is only
+ * exposed to allow overriding it using
+ * \c MBEDTLS_AES_ENCRYPT_ALT.
+ *
+ * \param ctx The AES context to use for encryption.
+ * \param input The plaintext block.
+ * \param output The output (ciphertext) block.
+ *
+ * \return \c 0 on success.
+ */
+int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
+ const unsigned char input[16],
+ unsigned char output[16] );
+
+/**
+ * \brief Internal AES block decryption function. This is only
+ * exposed to allow overriding it using see
+ * \c MBEDTLS_AES_DECRYPT_ALT.
+ *
+ * \param ctx The AES context to use for decryption.
+ * \param input The ciphertext block.
+ * \param output The output (plaintext) block.
+ *
+ * \return \c 0 on success.
+ */
+int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
+ const unsigned char input[16],
+ unsigned char output[16] );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief Deprecated internal AES block encryption function
+ * without return value.
+ *
+ * \deprecated Superseded by mbedtls_internal_aes_encrypt()
+ *
+ * \param ctx The AES context to use for encryption.
+ * \param input Plaintext block.
+ * \param output Output (ciphertext) block.
+ */
+MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
+ const unsigned char input[16],
+ unsigned char output[16] );
+
+/**
+ * \brief Deprecated internal AES block decryption function
+ * without return value.
+ *
+ * \deprecated Superseded by mbedtls_internal_aes_decrypt()
+ *
+ * \param ctx The AES context to use for decryption.
+ * \param input Ciphertext block.
+ * \param output Output (plaintext) block.
+ */
+MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
+ const unsigned char input[16],
+ unsigned char output[16] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+
+#if defined(MBEDTLS_SELF_TEST)
+/**
+ * \brief Checkup routine.
+ *
+ * \return \c 0 on success.
+ * \return \c 1 on failure.
+ */
+int mbedtls_aes_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* aes.h */
diff --git a/templates/blackpill/Src/cipher.c b/templates/blackpill/Src/cipher.c
new file mode 100644
index 0000000..0a46dae
--- /dev/null
+++ b/templates/blackpill/Src/cipher.c
@@ -0,0 +1,1540 @@
+/**
+ * \file cipher.c
+ *
+ * \brief Generic cipher wrapper for mbed TLS
+ *
+ * \author Adriaan de Jong
+ *
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_CIPHER_C)
+
+#include "cipher.h"
+#include "cipher_internal.h"
+#include "platform_util.h"
+
+#include
+#include
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+#include "mbedtls/chachapoly.h"
+#endif
+
+#if defined(MBEDTLS_GCM_C)
+#include "gcm.h"
+#endif
+
+#if defined(MBEDTLS_CCM_C)
+#include "mbedtls/ccm.h"
+#endif
+
+#if defined(MBEDTLS_CHACHA20_C)
+#include "mbedtls/chacha20.h"
+#endif
+
+#if defined(MBEDTLS_CMAC_C)
+#include "mbedtls/cmac.h"
+#endif
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#include "mbedtls/psa_util.h"
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#if defined(MBEDTLS_NIST_KW_C)
+#include "mbedtls/nist_kw.h"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#define mbedtls_calloc calloc
+#define mbedtls_free free
+#endif
+
+#define CIPHER_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA )
+#define CIPHER_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
+/* Compare the contents of two buffers in constant time.
+ * Returns 0 if the contents are bitwise identical, otherwise returns
+ * a non-zero value.
+ * This is currently only used by GCM and ChaCha20+Poly1305.
+ */
+static int mbedtls_constant_time_memcmp( const void *v1, const void *v2,
+ size_t len )
+{
+ const unsigned char *p1 = (const unsigned char*) v1;
+ const unsigned char *p2 = (const unsigned char*) v2;
+ size_t i;
+ unsigned char diff;
+
+ for( diff = 0, i = 0; i < len; i++ )
+ diff |= p1[i] ^ p2[i];
+
+ return( (int)diff );
+}
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
+
+static int supported_init = 0;
+
+const int *mbedtls_cipher_list( void )
+{
+ const mbedtls_cipher_definition_t *def;
+ int *type;
+
+ if( ! supported_init )
+ {
+ def = mbedtls_cipher_definitions;
+ type = mbedtls_cipher_supported;
+
+ while( def->type != 0 )
+ *type++ = (*def++).type;
+
+ *type = 0;
+
+ supported_init = 1;
+ }
+
+ return( mbedtls_cipher_supported );
+}
+
+const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type(
+ const mbedtls_cipher_type_t cipher_type )
+{
+ const mbedtls_cipher_definition_t *def;
+
+ for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
+ if( def->type == cipher_type )
+ return( def->info );
+
+ return( NULL );
+}
+
+const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string(
+ const char *cipher_name )
+{
+ const mbedtls_cipher_definition_t *def;
+
+ if( NULL == cipher_name )
+ return( NULL );
+
+ for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
+ if( ! strcmp( def->info->name, cipher_name ) )
+ return( def->info );
+
+ return( NULL );
+}
+
+const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values(
+ const mbedtls_cipher_id_t cipher_id,
+ int key_bitlen,
+ const mbedtls_cipher_mode_t mode )
+{
+ const mbedtls_cipher_definition_t *def;
+
+ for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
+ if( def->info->base->cipher == cipher_id &&
+ def->info->key_bitlen == (unsigned) key_bitlen &&
+ def->info->mode == mode )
+ return( def->info );
+
+ return( NULL );
+}
+
+void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx )
+{
+ CIPHER_VALIDATE( ctx != NULL );
+ memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
+}
+
+void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
+{
+ if( ctx == NULL )
+ return;
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ if( ctx->cipher_ctx != NULL )
+ {
+ mbedtls_cipher_context_psa * const cipher_psa =
+ (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
+
+ if( cipher_psa->slot_state == MBEDTLS_CIPHER_PSA_KEY_OWNED )
+ {
+ /* xxx_free() doesn't allow to return failures. */
+ (void) psa_destroy_key( cipher_psa->slot );
+ }
+
+ mbedtls_platform_zeroize( cipher_psa, sizeof( *cipher_psa ) );
+ mbedtls_free( cipher_psa );
+ }
+
+ mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
+ return;
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#if defined(MBEDTLS_CMAC_C)
+ if( ctx->cmac_ctx )
+ {
+ mbedtls_platform_zeroize( ctx->cmac_ctx,
+ sizeof( mbedtls_cmac_context_t ) );
+ mbedtls_free( ctx->cmac_ctx );
+ }
+#endif
+
+ if( ctx->cipher_ctx )
+ ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx );
+
+ mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
+}
+
+int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
+ const mbedtls_cipher_info_t *cipher_info )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ if( cipher_info == NULL )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
+
+ if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) )
+ return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
+
+ ctx->cipher_info = cipher_info;
+
+#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
+ /*
+ * Ignore possible errors caused by a cipher mode that doesn't use padding
+ */
+#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
+ (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 );
+#else
+ (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE );
+#endif
+#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
+
+ return( 0 );
+}
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx,
+ const mbedtls_cipher_info_t *cipher_info,
+ size_t taglen )
+{
+ psa_algorithm_t alg;
+ mbedtls_cipher_context_psa *cipher_psa;
+
+ if( NULL == cipher_info || NULL == ctx )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ /* Check that the underlying cipher mode and cipher type are
+ * supported by the underlying PSA Crypto implementation. */
+ alg = mbedtls_psa_translate_cipher_mode( cipher_info->mode, taglen );
+ if( alg == 0 )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ if( mbedtls_psa_translate_cipher_type( cipher_info->type ) == 0 )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+
+ memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
+
+ cipher_psa = mbedtls_calloc( 1, sizeof(mbedtls_cipher_context_psa ) );
+ if( cipher_psa == NULL )
+ return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
+ cipher_psa->alg = alg;
+ ctx->cipher_ctx = cipher_psa;
+ ctx->cipher_info = cipher_info;
+ ctx->psa_enabled = 1;
+ return( 0 );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
+ const unsigned char *key,
+ int key_bitlen,
+ const mbedtls_operation_t operation )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( key != NULL );
+ CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT ||
+ operation == MBEDTLS_DECRYPT );
+ if( ctx->cipher_info == NULL )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ mbedtls_cipher_context_psa * const cipher_psa =
+ (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
+
+ size_t const key_bytelen = ( (size_t) key_bitlen + 7 ) / 8;
+
+ psa_status_t status;
+ psa_key_type_t key_type;
+ psa_key_usage_t key_usage;
+ psa_key_policy_t key_policy;
+
+ /* PSA Crypto API only accepts byte-aligned keys. */
+ if( key_bitlen % 8 != 0 )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ /* Don't allow keys to be set multiple times. */
+ if( cipher_psa->slot_state != MBEDTLS_CIPHER_PSA_KEY_UNSET )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ key_type = mbedtls_psa_translate_cipher_type(
+ ctx->cipher_info->type );
+ if( key_type == 0 )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+
+ /* Allocate a key slot to use. */
+ status = psa_allocate_key( &cipher_psa->slot );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ /* Indicate that we own the key slot and need to
+ * destroy it in mbedtls_cipher_free(). */
+ cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED;
+
+ /* From that point on, the responsibility for destroying the
+ * key slot is on mbedtls_cipher_free(). This includes the case
+ * where the policy setup or key import below fail, as
+ * mbedtls_cipher_free() needs to be called in any case. */
+
+ /* Setup policy for the new key slot. */
+ key_policy = psa_key_policy_init();
+
+ /* Mbed TLS' cipher layer doesn't enforce the mode of operation
+ * (encrypt vs. decrypt): it is possible to setup a key for encryption
+ * and use it for AEAD decryption. Until tests relying on this
+ * are changed, allow any usage in PSA. */
+ /* key_usage = mbedtls_psa_translate_cipher_operation( operation ); */
+ key_usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
+ psa_key_policy_set_usage( &key_policy, key_usage, cipher_psa->alg );
+ status = psa_set_key_policy( cipher_psa->slot, &key_policy );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ /* Populate new key slot. */
+ status = psa_import_key( cipher_psa->slot,
+ key_type, key, key_bytelen );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ ctx->key_bitlen = key_bitlen;
+ ctx->operation = operation;
+ return( 0 );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 &&
+ (int) ctx->cipher_info->key_bitlen != key_bitlen )
+ {
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+ }
+
+ ctx->key_bitlen = key_bitlen;
+ ctx->operation = operation;
+
+ /*
+ * For OFB, CFB and CTR mode always use the encryption key schedule
+ */
+ if( MBEDTLS_ENCRYPT == operation ||
+ MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
+ MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
+ MBEDTLS_MODE_CTR == ctx->cipher_info->mode )
+ {
+ return( ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
+ ctx->key_bitlen ) );
+ }
+
+ if( MBEDTLS_DECRYPT == operation )
+ return( ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
+ ctx->key_bitlen ) );
+
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+}
+
+int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv,
+ size_t iv_len )
+{
+ size_t actual_iv_size;
+
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+ if( ctx->cipher_info == NULL )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto has an API for multipart
+ * operations, we currently don't make it
+ * accessible through the cipher layer. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ /* avoid buffer overflow in ctx->iv */
+ if( iv_len > MBEDTLS_MAX_IV_LENGTH )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+
+ if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 )
+ actual_iv_size = iv_len;
+ else
+ {
+ actual_iv_size = ctx->cipher_info->iv_size;
+
+ /* avoid reading past the end of input buffer */
+ if( actual_iv_size > iv_len )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+ }
+
+#if defined(MBEDTLS_CHACHA20_C)
+ if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
+ {
+ if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx,
+ iv,
+ 0U ) ) /* Initial counter value */
+ {
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+ }
+ }
+#endif
+
+ if ( actual_iv_size != 0 )
+ {
+ memcpy( ctx->iv, iv, actual_iv_size );
+ ctx->iv_size = actual_iv_size;
+ }
+
+ return( 0 );
+}
+
+int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ if( ctx->cipher_info == NULL )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* We don't support resetting PSA-based
+ * cipher contexts, yet. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ ctx->unprocessed_len = 0;
+
+ return( 0 );
+}
+
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
+int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
+ const unsigned char *ad, size_t ad_len )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+ if( ctx->cipher_info == NULL )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto has an API for multipart
+ * operations, we currently don't make it
+ * accessible through the cipher layer. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#if defined(MBEDTLS_GCM_C)
+ if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
+ {
+ return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
+ ctx->iv, ctx->iv_size, ad, ad_len ) );
+ }
+#endif
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+ if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
+ {
+ int result;
+ mbedtls_chachapoly_mode_t mode;
+
+ mode = ( ctx->operation == MBEDTLS_ENCRYPT )
+ ? MBEDTLS_CHACHAPOLY_ENCRYPT
+ : MBEDTLS_CHACHAPOLY_DECRYPT;
+
+ result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
+ ctx->iv,
+ mode );
+ if ( result != 0 )
+ return( result );
+
+ return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
+ ad, ad_len ) );
+ }
+#endif
+
+ return( 0 );
+}
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
+
+int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
+ size_t ilen, unsigned char *output, size_t *olen )
+{
+ int ret;
+ size_t block_size;
+
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+ if( ctx->cipher_info == NULL )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto has an API for multipart
+ * operations, we currently don't make it
+ * accessible through the cipher layer. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ *olen = 0;
+ block_size = mbedtls_cipher_get_block_size( ctx );
+
+ if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB )
+ {
+ if( ilen != block_size )
+ return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
+
+ *olen = ilen;
+
+ if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx,
+ ctx->operation, input, output ) ) )
+ {
+ return( ret );
+ }
+
+ return( 0 );
+ }
+
+#if defined(MBEDTLS_GCM_C)
+ if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM )
+ {
+ *olen = ilen;
+ return( mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
+ output ) );
+ }
+#endif
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+ if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 )
+ {
+ *olen = ilen;
+ return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
+ ilen, input, output ) );
+ }
+#endif
+
+ if ( 0 == block_size )
+ {
+ return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
+ }
+
+ if( input == output &&
+ ( ctx->unprocessed_len != 0 || ilen % block_size ) )
+ {
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+ }
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC )
+ {
+ size_t copy_len = 0;
+
+ /*
+ * If there is not enough data for a full block, cache it.
+ */
+ if( ( ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding &&
+ ilen <= block_size - ctx->unprocessed_len ) ||
+ ( ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding &&
+ ilen < block_size - ctx->unprocessed_len ) ||
+ ( ctx->operation == MBEDTLS_ENCRYPT &&
+ ilen < block_size - ctx->unprocessed_len ) )
+ {
+ memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
+ ilen );
+
+ ctx->unprocessed_len += ilen;
+ return( 0 );
+ }
+
+ /*
+ * Process cached data first
+ */
+ if( 0 != ctx->unprocessed_len )
+ {
+ copy_len = block_size - ctx->unprocessed_len;
+
+ memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
+ copy_len );
+
+ if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
+ ctx->operation, block_size, ctx->iv,
+ ctx->unprocessed_data, output ) ) )
+ {
+ return( ret );
+ }
+
+ *olen += block_size;
+ output += block_size;
+ ctx->unprocessed_len = 0;
+
+ input += copy_len;
+ ilen -= copy_len;
+ }
+
+ /*
+ * Cache final, incomplete block
+ */
+ if( 0 != ilen )
+ {
+ if( 0 == block_size )
+ {
+ return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
+ }
+
+ /* Encryption: only cache partial blocks
+ * Decryption w/ padding: always keep at least one whole block
+ * Decryption w/o padding: only cache partial blocks
+ */
+ copy_len = ilen % block_size;
+ if( copy_len == 0 &&
+ ctx->operation == MBEDTLS_DECRYPT &&
+ NULL != ctx->add_padding)
+ {
+ copy_len = block_size;
+ }
+
+ memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
+ copy_len );
+
+ ctx->unprocessed_len += copy_len;
+ ilen -= copy_len;
+ }
+
+ /*
+ * Process remaining full blocks
+ */
+ if( ilen )
+ {
+ if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
+ ctx->operation, ilen, ctx->iv, input, output ) ) )
+ {
+ return( ret );
+ }
+
+ *olen += ilen;
+ }
+
+ return( 0 );
+ }
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB )
+ {
+ if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx,
+ ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv,
+ input, output ) ) )
+ {
+ return( ret );
+ }
+
+ *olen = ilen;
+
+ return( 0 );
+ }
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB )
+ {
+ if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx,
+ ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) )
+ {
+ return( ret );
+ }
+
+ *olen = ilen;
+
+ return( 0 );
+ }
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR )
+ {
+ if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx,
+ ilen, &ctx->unprocessed_len, ctx->iv,
+ ctx->unprocessed_data, input, output ) ) )
+ {
+ return( ret );
+ }
+
+ *olen = ilen;
+
+ return( 0 );
+ }
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS )
+ {
+ if( ctx->unprocessed_len > 0 ) {
+ /* We can only process an entire data unit at a time. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+
+ ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx,
+ ctx->operation, ilen, ctx->iv, input, output );
+ if( ret != 0 )
+ {
+ return( ret );
+ }
+
+ *olen = ilen;
+
+ return( 0 );
+ }
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM )
+ {
+ if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx,
+ ilen, input, output ) ) )
+ {
+ return( ret );
+ }
+
+ *olen = ilen;
+
+ return( 0 );
+ }
+#endif /* MBEDTLS_CIPHER_MODE_STREAM */
+
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
+#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
+/*
+ * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len
+ */
+static void add_pkcs_padding( unsigned char *output, size_t output_len,
+ size_t data_len )
+{
+ size_t padding_len = output_len - data_len;
+ unsigned char i;
+
+ for( i = 0; i < padding_len; i++ )
+ output[data_len + i] = (unsigned char) padding_len;
+}
+
+static int get_pkcs_padding( unsigned char *input, size_t input_len,
+ size_t *data_len )
+{
+ size_t i, pad_idx;
+ unsigned char padding_len, bad = 0;
+
+ if( NULL == input || NULL == data_len )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ padding_len = input[input_len - 1];
+ *data_len = input_len - padding_len;
+
+ /* Avoid logical || since it results in a branch */
+ bad |= padding_len > input_len;
+ bad |= padding_len == 0;
+
+ /* The number of bytes checked must be independent of padding_len,
+ * so pick input_len, which is usually 8 or 16 (one block) */
+ pad_idx = input_len - padding_len;
+ for( i = 0; i < input_len; i++ )
+ bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx );
+
+ return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
+}
+#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
+
+#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
+/*
+ * One and zeros padding: fill with 80 00 ... 00
+ */
+static void add_one_and_zeros_padding( unsigned char *output,
+ size_t output_len, size_t data_len )
+{
+ size_t padding_len = output_len - data_len;
+ unsigned char i = 0;
+
+ output[data_len] = 0x80;
+ for( i = 1; i < padding_len; i++ )
+ output[data_len + i] = 0x00;
+}
+
+static int get_one_and_zeros_padding( unsigned char *input, size_t input_len,
+ size_t *data_len )
+{
+ size_t i;
+ unsigned char done = 0, prev_done, bad;
+
+ if( NULL == input || NULL == data_len )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ bad = 0x80;
+ *data_len = 0;
+ for( i = input_len; i > 0; i-- )
+ {
+ prev_done = done;
+ done |= ( input[i - 1] != 0 );
+ *data_len |= ( i - 1 ) * ( done != prev_done );
+ bad ^= input[i - 1] * ( done != prev_done );
+ }
+
+ return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
+
+}
+#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
+
+#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
+/*
+ * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length
+ */
+static void add_zeros_and_len_padding( unsigned char *output,
+ size_t output_len, size_t data_len )
+{
+ size_t padding_len = output_len - data_len;
+ unsigned char i = 0;
+
+ for( i = 1; i < padding_len; i++ )
+ output[data_len + i - 1] = 0x00;
+ output[output_len - 1] = (unsigned char) padding_len;
+}
+
+static int get_zeros_and_len_padding( unsigned char *input, size_t input_len,
+ size_t *data_len )
+{
+ size_t i, pad_idx;
+ unsigned char padding_len, bad = 0;
+
+ if( NULL == input || NULL == data_len )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ padding_len = input[input_len - 1];
+ *data_len = input_len - padding_len;
+
+ /* Avoid logical || since it results in a branch */
+ bad |= padding_len > input_len;
+ bad |= padding_len == 0;
+
+ /* The number of bytes checked must be independent of padding_len */
+ pad_idx = input_len - padding_len;
+ for( i = 0; i < input_len - 1; i++ )
+ bad |= input[i] * ( i >= pad_idx );
+
+ return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
+}
+#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
+
+#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
+/*
+ * Zero padding: fill with 00 ... 00
+ */
+static void add_zeros_padding( unsigned char *output,
+ size_t output_len, size_t data_len )
+{
+ size_t i;
+
+ for( i = data_len; i < output_len; i++ )
+ output[i] = 0x00;
+}
+
+static int get_zeros_padding( unsigned char *input, size_t input_len,
+ size_t *data_len )
+{
+ size_t i;
+ unsigned char done = 0, prev_done;
+
+ if( NULL == input || NULL == data_len )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ *data_len = 0;
+ for( i = input_len; i > 0; i-- )
+ {
+ prev_done = done;
+ done |= ( input[i-1] != 0 );
+ *data_len |= i * ( done != prev_done );
+ }
+
+ return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
+
+/*
+ * No padding: don't pad :)
+ *
+ * There is no add_padding function (check for NULL in mbedtls_cipher_finish)
+ * but a trivial get_padding function
+ */
+static int get_no_padding( unsigned char *input, size_t input_len,
+ size_t *data_len )
+{
+ if( NULL == input || NULL == data_len )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ *data_len = input_len;
+
+ return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
+
+int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
+ unsigned char *output, size_t *olen )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+ if( ctx->cipher_info == NULL )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto has an API for multipart
+ * operations, we currently don't make it
+ * accessible through the cipher layer. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ *olen = 0;
+
+ if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
+ MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
+ MBEDTLS_MODE_CTR == ctx->cipher_info->mode ||
+ MBEDTLS_MODE_GCM == ctx->cipher_info->mode ||
+ MBEDTLS_MODE_XTS == ctx->cipher_info->mode ||
+ MBEDTLS_MODE_STREAM == ctx->cipher_info->mode )
+ {
+ return( 0 );
+ }
+
+ if ( ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) ||
+ ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) )
+ {
+ return( 0 );
+ }
+
+ if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode )
+ {
+ if( ctx->unprocessed_len != 0 )
+ return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
+
+ return( 0 );
+ }
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode )
+ {
+ int ret = 0;
+
+ if( MBEDTLS_ENCRYPT == ctx->operation )
+ {
+ /* check for 'no padding' mode */
+ if( NULL == ctx->add_padding )
+ {
+ if( 0 != ctx->unprocessed_len )
+ return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
+
+ return( 0 );
+ }
+
+ ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ),
+ ctx->unprocessed_len );
+ }
+ else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len )
+ {
+ /*
+ * For decrypt operations, expect a full block,
+ * or an empty block if no padding
+ */
+ if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len )
+ return( 0 );
+
+ return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
+ }
+
+ /* cipher block */
+ if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
+ ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv,
+ ctx->unprocessed_data, output ) ) )
+ {
+ return( ret );
+ }
+
+ /* Set output size for decryption */
+ if( MBEDTLS_DECRYPT == ctx->operation )
+ return( ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
+ olen ) );
+
+ /* Set output size for encryption */
+ *olen = mbedtls_cipher_get_block_size( ctx );
+ return( 0 );
+ }
+#else
+ ((void) output);
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
+int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
+ mbedtls_cipher_padding_t mode )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+
+ if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
+ {
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+ }
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto knows about CBC padding
+ * schemes, we currently don't make them
+ * accessible through the cipher layer. */
+ if( mode != MBEDTLS_PADDING_NONE )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+
+ return( 0 );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ switch( mode )
+ {
+#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
+ case MBEDTLS_PADDING_PKCS7:
+ ctx->add_padding = add_pkcs_padding;
+ ctx->get_padding = get_pkcs_padding;
+ break;
+#endif
+#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
+ case MBEDTLS_PADDING_ONE_AND_ZEROS:
+ ctx->add_padding = add_one_and_zeros_padding;
+ ctx->get_padding = get_one_and_zeros_padding;
+ break;
+#endif
+#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
+ case MBEDTLS_PADDING_ZEROS_AND_LEN:
+ ctx->add_padding = add_zeros_and_len_padding;
+ ctx->get_padding = get_zeros_and_len_padding;
+ break;
+#endif
+#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
+ case MBEDTLS_PADDING_ZEROS:
+ ctx->add_padding = add_zeros_padding;
+ ctx->get_padding = get_zeros_padding;
+ break;
+#endif
+ case MBEDTLS_PADDING_NONE:
+ ctx->add_padding = NULL;
+ ctx->get_padding = get_no_padding;
+ break;
+
+ default:
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+
+ return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
+
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
+int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
+ unsigned char *tag, size_t tag_len )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+ if( ctx->cipher_info == NULL )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ if( MBEDTLS_ENCRYPT != ctx->operation )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto has an API for multipart
+ * operations, we currently don't make it
+ * accessible through the cipher layer. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+
+ return( 0 );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#if defined(MBEDTLS_GCM_C)
+ if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
+ return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
+ tag, tag_len ) );
+#endif
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+ if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
+ {
+ /* Don't allow truncated MAC for Poly1305 */
+ if ( tag_len != 16U )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ return( mbedtls_chachapoly_finish(
+ (mbedtls_chachapoly_context*) ctx->cipher_ctx, tag ) );
+ }
+#endif
+
+ return( 0 );
+}
+
+int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
+ const unsigned char *tag, size_t tag_len )
+{
+ unsigned char check_tag[16];
+ int ret;
+
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+ if( ctx->cipher_info == NULL )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ if( MBEDTLS_DECRYPT != ctx->operation )
+ {
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+ }
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto has an API for multipart
+ * operations, we currently don't make it
+ * accessible through the cipher layer. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#if defined(MBEDTLS_GCM_C)
+ if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
+ {
+ if( tag_len > sizeof( check_tag ) )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ if( 0 != ( ret = mbedtls_gcm_finish(
+ (mbedtls_gcm_context *) ctx->cipher_ctx,
+ check_tag, tag_len ) ) )
+ {
+ return( ret );
+ }
+
+ /* Check the tag in "constant-time" */
+ if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
+ return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
+
+ return( 0 );
+ }
+#endif /* MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+ if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
+ {
+ /* Don't allow truncated MAC for Poly1305 */
+ if ( tag_len != sizeof( check_tag ) )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ ret = mbedtls_chachapoly_finish(
+ (mbedtls_chachapoly_context*) ctx->cipher_ctx, check_tag );
+ if ( ret != 0 )
+ {
+ return( ret );
+ }
+
+ /* Check the tag in "constant-time" */
+ if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
+ return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
+
+ return( 0 );
+ }
+#endif /* MBEDTLS_CHACHAPOLY_C */
+
+ return( 0 );
+}
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
+
+/*
+ * Packet-oriented wrapper for non-AEAD modes
+ */
+int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen )
+{
+ int ret;
+ size_t finish_olen;
+
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* As in the non-PSA case, we don't check that
+ * a key has been set. If not, the key slot will
+ * still be in its default state of 0, which is
+ * guaranteed to be invalid, hence the PSA-call
+ * below will gracefully fail. */
+ mbedtls_cipher_context_psa * const cipher_psa =
+ (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
+
+ psa_status_t status;
+ psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT;
+ size_t part_len;
+
+ if( ctx->operation == MBEDTLS_DECRYPT )
+ {
+ status = psa_cipher_decrypt_setup( &cipher_op,
+ cipher_psa->slot,
+ cipher_psa->alg );
+ }
+ else if( ctx->operation == MBEDTLS_ENCRYPT )
+ {
+ status = psa_cipher_encrypt_setup( &cipher_op,
+ cipher_psa->slot,
+ cipher_psa->alg );
+ }
+ else
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ /* In the following, we can immediately return on an error,
+ * because the PSA Crypto API guarantees that cipher operations
+ * are terminated by unsuccessful calls to psa_cipher_update(),
+ * and by any call to psa_cipher_finish(). */
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ status = psa_cipher_set_iv( &cipher_op, iv, iv_len );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ status = psa_cipher_update( &cipher_op,
+ input, ilen,
+ output, ilen, olen );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ status = psa_cipher_finish( &cipher_op,
+ output + *olen, ilen - *olen,
+ &part_len );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ *olen += part_len;
+ return( 0 );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
+ return( ret );
+
+ if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 )
+ return( ret );
+
+ if( ( ret = mbedtls_cipher_update( ctx, input, ilen,
+ output, olen ) ) != 0 )
+ return( ret );
+
+ if( ( ret = mbedtls_cipher_finish( ctx, output + *olen,
+ &finish_olen ) ) != 0 )
+ return( ret );
+
+ *olen += finish_olen;
+
+ return( 0 );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_AEAD)
+/*
+ * Packet-oriented encryption for AEAD modes
+ */
+int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen,
+ unsigned char *tag, size_t tag_len )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv != NULL );
+ CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+ CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* As in the non-PSA case, we don't check that
+ * a key has been set. If not, the key slot will
+ * still be in its default state of 0, which is
+ * guaranteed to be invalid, hence the PSA-call
+ * below will gracefully fail. */
+ mbedtls_cipher_context_psa * const cipher_psa =
+ (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
+
+ psa_status_t status;
+
+ /* PSA Crypto API always writes the authentication tag
+ * at the end of the encrypted message. */
+ if( tag != output + ilen )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+
+ status = psa_aead_encrypt( cipher_psa->slot,
+ cipher_psa->alg,
+ iv, iv_len,
+ ad, ad_len,
+ input, ilen,
+ output, ilen + tag_len, olen );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ *olen -= tag_len;
+ return( 0 );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#if defined(MBEDTLS_GCM_C)
+ if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
+ {
+ *olen = ilen;
+ return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT,
+ ilen, iv, iv_len, ad, ad_len,
+ input, output, tag_len, tag ) );
+ }
+#endif /* MBEDTLS_GCM_C */
+#if defined(MBEDTLS_CCM_C)
+ if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
+ {
+ *olen = ilen;
+ return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen,
+ iv, iv_len, ad, ad_len, input, output,
+ tag, tag_len ) );
+ }
+#endif /* MBEDTLS_CCM_C */
+#if defined(MBEDTLS_CHACHAPOLY_C)
+ if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
+ {
+ /* ChachaPoly has fixed length nonce and MAC (tag) */
+ if ( ( iv_len != ctx->cipher_info->iv_size ) ||
+ ( tag_len != 16U ) )
+ {
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+ }
+
+ *olen = ilen;
+ return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx,
+ ilen, iv, ad, ad_len, input, output, tag ) );
+ }
+#endif /* MBEDTLS_CHACHAPOLY_C */
+#if defined(MBEDTLS_NIST_KW_C)
+ if( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
+ MBEDTLS_MODE_KWP == ctx->cipher_info->mode )
+ {
+ mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
+ MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
+
+ /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */
+ if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
+ {
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+ }
+
+ return( mbedtls_nist_kw_wrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) );
+ }
+#endif /* MBEDTLS_NIST_KW_C */
+
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+}
+
+/*
+ * Packet-oriented decryption for AEAD modes
+ */
+int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen,
+ const unsigned char *tag, size_t tag_len )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv != NULL );
+ CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+ CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* As in the non-PSA case, we don't check that
+ * a key has been set. If not, the key slot will
+ * still be in its default state of 0, which is
+ * guaranteed to be invalid, hence the PSA-call
+ * below will gracefully fail. */
+ mbedtls_cipher_context_psa * const cipher_psa =
+ (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
+
+ psa_status_t status;
+
+ /* PSA Crypto API always writes the authentication tag
+ * at the end of the encrypted message. */
+ if( tag != input + ilen )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+
+ status = psa_aead_decrypt( cipher_psa->slot,
+ cipher_psa->alg,
+ iv, iv_len,
+ ad, ad_len,
+ input, ilen + tag_len,
+ output, ilen, olen );
+ if( status == PSA_ERROR_INVALID_SIGNATURE )
+ return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
+ else if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ return( 0 );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#if defined(MBEDTLS_GCM_C)
+ if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
+ {
+ int ret;
+
+ *olen = ilen;
+ ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen,
+ iv, iv_len, ad, ad_len,
+ tag, tag_len, input, output );
+
+ if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED )
+ ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
+
+ return( ret );
+ }
+#endif /* MBEDTLS_GCM_C */
+#if defined(MBEDTLS_CCM_C)
+ if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
+ {
+ int ret;
+
+ *olen = ilen;
+ ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen,
+ iv, iv_len, ad, ad_len,
+ input, output, tag, tag_len );
+
+ if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED )
+ ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
+
+ return( ret );
+ }
+#endif /* MBEDTLS_CCM_C */
+#if defined(MBEDTLS_CHACHAPOLY_C)
+ if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
+ {
+ int ret;
+
+ /* ChachaPoly has fixed length nonce and MAC (tag) */
+ if ( ( iv_len != ctx->cipher_info->iv_size ) ||
+ ( tag_len != 16U ) )
+ {
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+ }
+
+ *olen = ilen;
+ ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen,
+ iv, ad, ad_len, tag, input, output );
+
+ if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED )
+ ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
+
+ return( ret );
+ }
+#endif /* MBEDTLS_CHACHAPOLY_C */
+#if defined(MBEDTLS_NIST_KW_C)
+ if( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
+ MBEDTLS_MODE_KWP == ctx->cipher_info->mode )
+ {
+ mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
+ MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
+
+ /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */
+ if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
+ {
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+ }
+
+ return( mbedtls_nist_kw_unwrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) );
+ }
+#endif /* MBEDTLS_NIST_KW_C */
+
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+}
+#endif /* MBEDTLS_CIPHER_MODE_AEAD */
+
+#endif /* MBEDTLS_CIPHER_C */
diff --git a/templates/blackpill/Src/cipher.h b/templates/blackpill/Src/cipher.h
new file mode 100644
index 0000000..ea00703
--- /dev/null
+++ b/templates/blackpill/Src/cipher.h
@@ -0,0 +1,926 @@
+/**
+ * \file cipher.h
+ *
+ * \brief This file contains an abstraction interface for use with the cipher
+ * primitives provided by the library. It provides a common interface to all of
+ * the available cipher operations.
+ *
+ * \author Adriaan de Jong
+ */
+/*
+ * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ * This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_CIPHER_H
+#define MBEDTLS_CIPHER_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include
+#include "platform_util.h"
+
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
+#define MBEDTLS_CIPHER_MODE_AEAD
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#define MBEDTLS_CIPHER_MODE_WITH_PADDING
+#endif
+
+#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \
+ defined(MBEDTLS_CHACHA20_C)
+#define MBEDTLS_CIPHER_MODE_STREAM
+#endif
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+ !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */
+#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters. */
+#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */
+#define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */
+#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */
+#define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */
+#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 /**< The context is invalid. For example, because it was freed. */
+
+/* MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED -0x6400 /**< Cipher hardware accelerator failed. */
+
+#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length. */
+#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Supported cipher types.
+ *
+ * \warning RC4 and DES are considered weak ciphers and their use
+ * constitutes a security risk. Arm recommends considering stronger
+ * ciphers instead.
+ */
+typedef enum {
+ MBEDTLS_CIPHER_ID_NONE = 0, /**< Placeholder to mark the end of cipher ID lists. */
+ MBEDTLS_CIPHER_ID_NULL, /**< The identity cipher, treated as a stream cipher. */
+ MBEDTLS_CIPHER_ID_AES, /**< The AES cipher. */
+ MBEDTLS_CIPHER_ID_DES, /**< The DES cipher. */
+ MBEDTLS_CIPHER_ID_3DES, /**< The Triple DES cipher. */
+ MBEDTLS_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */
+ MBEDTLS_CIPHER_ID_BLOWFISH, /**< The Blowfish cipher. */
+ MBEDTLS_CIPHER_ID_ARC4, /**< The RC4 cipher. */
+ MBEDTLS_CIPHER_ID_ARIA, /**< The Aria cipher. */
+ MBEDTLS_CIPHER_ID_CHACHA20, /**< The ChaCha20 cipher. */
+} mbedtls_cipher_id_t;
+
+/**
+ * \brief Supported {cipher type, cipher mode} pairs.
+ *
+ * \warning RC4 and DES are considered weak ciphers and their use
+ * constitutes a security risk. Arm recommends considering stronger
+ * ciphers instead.
+ */
+typedef enum {
+ MBEDTLS_CIPHER_NONE = 0, /**< Placeholder to mark the end of cipher-pair lists. */
+ MBEDTLS_CIPHER_NULL, /**< The identity stream cipher. */
+ MBEDTLS_CIPHER_AES_128_ECB, /**< AES cipher with 128-bit ECB mode. */
+ MBEDTLS_CIPHER_AES_192_ECB, /**< AES cipher with 192-bit ECB mode. */
+ MBEDTLS_CIPHER_AES_256_ECB, /**< AES cipher with 256-bit ECB mode. */
+ MBEDTLS_CIPHER_AES_128_CBC, /**< AES cipher with 128-bit CBC mode. */
+ MBEDTLS_CIPHER_AES_192_CBC, /**< AES cipher with 192-bit CBC mode. */
+ MBEDTLS_CIPHER_AES_256_CBC, /**< AES cipher with 256-bit CBC mode. */
+ MBEDTLS_CIPHER_AES_128_CFB128, /**< AES cipher with 128-bit CFB128 mode. */
+ MBEDTLS_CIPHER_AES_192_CFB128, /**< AES cipher with 192-bit CFB128 mode. */
+ MBEDTLS_CIPHER_AES_256_CFB128, /**< AES cipher with 256-bit CFB128 mode. */
+ MBEDTLS_CIPHER_AES_128_CTR, /**< AES cipher with 128-bit CTR mode. */
+ MBEDTLS_CIPHER_AES_192_CTR, /**< AES cipher with 192-bit CTR mode. */
+ MBEDTLS_CIPHER_AES_256_CTR, /**< AES cipher with 256-bit CTR mode. */
+ MBEDTLS_CIPHER_AES_128_GCM, /**< AES cipher with 128-bit GCM mode. */
+ MBEDTLS_CIPHER_AES_192_GCM, /**< AES cipher with 192-bit GCM mode. */
+ MBEDTLS_CIPHER_AES_256_GCM, /**< AES cipher with 256-bit GCM mode. */
+ MBEDTLS_CIPHER_CAMELLIA_128_ECB, /**< Camellia cipher with 128-bit ECB mode. */
+ MBEDTLS_CIPHER_CAMELLIA_192_ECB, /**< Camellia cipher with 192-bit ECB mode. */
+ MBEDTLS_CIPHER_CAMELLIA_256_ECB, /**< Camellia cipher with 256-bit ECB mode. */
+ MBEDTLS_CIPHER_CAMELLIA_128_CBC, /**< Camellia cipher with 128-bit CBC mode. */
+ MBEDTLS_CIPHER_CAMELLIA_192_CBC, /**< Camellia cipher with 192-bit CBC mode. */
+ MBEDTLS_CIPHER_CAMELLIA_256_CBC, /**< Camellia cipher with 256-bit CBC mode. */
+ MBEDTLS_CIPHER_CAMELLIA_128_CFB128, /**< Camellia cipher with 128-bit CFB128 mode. */
+ MBEDTLS_CIPHER_CAMELLIA_192_CFB128, /**< Camellia cipher with 192-bit CFB128 mode. */
+ MBEDTLS_CIPHER_CAMELLIA_256_CFB128, /**< Camellia cipher with 256-bit CFB128 mode. */
+ MBEDTLS_CIPHER_CAMELLIA_128_CTR, /**< Camellia cipher with 128-bit CTR mode. */
+ MBEDTLS_CIPHER_CAMELLIA_192_CTR, /**< Camellia cipher with 192-bit CTR mode. */
+ MBEDTLS_CIPHER_CAMELLIA_256_CTR, /**< Camellia cipher with 256-bit CTR mode. */
+ MBEDTLS_CIPHER_CAMELLIA_128_GCM, /**< Camellia cipher with 128-bit GCM mode. */
+ MBEDTLS_CIPHER_CAMELLIA_192_GCM, /**< Camellia cipher with 192-bit GCM mode. */
+ MBEDTLS_CIPHER_CAMELLIA_256_GCM, /**< Camellia cipher with 256-bit GCM mode. */
+ MBEDTLS_CIPHER_DES_ECB, /**< DES cipher with ECB mode. */
+ MBEDTLS_CIPHER_DES_CBC, /**< DES cipher with CBC mode. */
+ MBEDTLS_CIPHER_DES_EDE_ECB, /**< DES cipher with EDE ECB mode. */
+ MBEDTLS_CIPHER_DES_EDE_CBC, /**< DES cipher with EDE CBC mode. */
+ MBEDTLS_CIPHER_DES_EDE3_ECB, /**< DES cipher with EDE3 ECB mode. */
+ MBEDTLS_CIPHER_DES_EDE3_CBC, /**< DES cipher with EDE3 CBC mode. */
+ MBEDTLS_CIPHER_BLOWFISH_ECB, /**< Blowfish cipher with ECB mode. */
+ MBEDTLS_CIPHER_BLOWFISH_CBC, /**< Blowfish cipher with CBC mode. */
+ MBEDTLS_CIPHER_BLOWFISH_CFB64, /**< Blowfish cipher with CFB64 mode. */
+ MBEDTLS_CIPHER_BLOWFISH_CTR, /**< Blowfish cipher with CTR mode. */
+ MBEDTLS_CIPHER_ARC4_128, /**< RC4 cipher with 128-bit mode. */
+ MBEDTLS_CIPHER_AES_128_CCM, /**< AES cipher with 128-bit CCM mode. */
+ MBEDTLS_CIPHER_AES_192_CCM, /**< AES cipher with 192-bit CCM mode. */
+ MBEDTLS_CIPHER_AES_256_CCM, /**< AES cipher with 256-bit CCM mode. */
+ MBEDTLS_CIPHER_CAMELLIA_128_CCM, /**< Camellia cipher with 128-bit CCM mode. */
+ MBEDTLS_CIPHER_CAMELLIA_192_CCM, /**< Camellia cipher with 192-bit CCM mode. */
+ MBEDTLS_CIPHER_CAMELLIA_256_CCM, /**< Camellia cipher with 256-bit CCM mode. */
+ MBEDTLS_CIPHER_ARIA_128_ECB, /**< Aria cipher with 128-bit key and ECB mode. */
+ MBEDTLS_CIPHER_ARIA_192_ECB, /**< Aria cipher with 192-bit key and ECB mode. */
+ MBEDTLS_CIPHER_ARIA_256_ECB, /**< Aria cipher with 256-bit key and ECB mode. */
+ MBEDTLS_CIPHER_ARIA_128_CBC, /**< Aria cipher with 128-bit key and CBC mode. */
+ MBEDTLS_CIPHER_ARIA_192_CBC, /**< Aria cipher with 192-bit key and CBC mode. */
+ MBEDTLS_CIPHER_ARIA_256_CBC, /**< Aria cipher with 256-bit key and CBC mode. */
+ MBEDTLS_CIPHER_ARIA_128_CFB128, /**< Aria cipher with 128-bit key and CFB-128 mode. */
+ MBEDTLS_CIPHER_ARIA_192_CFB128, /**< Aria cipher with 192-bit key and CFB-128 mode. */
+ MBEDTLS_CIPHER_ARIA_256_CFB128, /**< Aria cipher with 256-bit key and CFB-128 mode. */
+ MBEDTLS_CIPHER_ARIA_128_CTR, /**< Aria cipher with 128-bit key and CTR mode. */
+ MBEDTLS_CIPHER_ARIA_192_CTR, /**< Aria cipher with 192-bit key and CTR mode. */
+ MBEDTLS_CIPHER_ARIA_256_CTR, /**< Aria cipher with 256-bit key and CTR mode. */
+ MBEDTLS_CIPHER_ARIA_128_GCM, /**< Aria cipher with 128-bit key and GCM mode. */
+ MBEDTLS_CIPHER_ARIA_192_GCM, /**< Aria cipher with 192-bit key and GCM mode. */
+ MBEDTLS_CIPHER_ARIA_256_GCM, /**< Aria cipher with 256-bit key and GCM mode. */
+ MBEDTLS_CIPHER_ARIA_128_CCM, /**< Aria cipher with 128-bit key and CCM mode. */
+ MBEDTLS_CIPHER_ARIA_192_CCM, /**< Aria cipher with 192-bit key and CCM mode. */
+ MBEDTLS_CIPHER_ARIA_256_CCM, /**< Aria cipher with 256-bit key and CCM mode. */
+ MBEDTLS_CIPHER_AES_128_OFB, /**< AES 128-bit cipher in OFB mode. */
+ MBEDTLS_CIPHER_AES_192_OFB, /**< AES 192-bit cipher in OFB mode. */
+ MBEDTLS_CIPHER_AES_256_OFB, /**< AES 256-bit cipher in OFB mode. */
+ MBEDTLS_CIPHER_AES_128_XTS, /**< AES 128-bit cipher in XTS block mode. */
+ MBEDTLS_CIPHER_AES_256_XTS, /**< AES 256-bit cipher in XTS block mode. */
+ MBEDTLS_CIPHER_CHACHA20, /**< ChaCha20 stream cipher. */
+ MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< ChaCha20-Poly1305 AEAD cipher. */
+ MBEDTLS_CIPHER_AES_128_KW, /**< AES cipher with 128-bit NIST KW mode. */
+ MBEDTLS_CIPHER_AES_192_KW, /**< AES cipher with 192-bit NIST KW mode. */
+ MBEDTLS_CIPHER_AES_256_KW, /**< AES cipher with 256-bit NIST KW mode. */
+ MBEDTLS_CIPHER_AES_128_KWP, /**< AES cipher with 128-bit NIST KWP mode. */
+ MBEDTLS_CIPHER_AES_192_KWP, /**< AES cipher with 192-bit NIST KWP mode. */
+ MBEDTLS_CIPHER_AES_256_KWP, /**< AES cipher with 256-bit NIST KWP mode. */
+} mbedtls_cipher_type_t;
+
+/** Supported cipher modes. */
+typedef enum {
+ MBEDTLS_MODE_NONE = 0, /**< None. */
+ MBEDTLS_MODE_ECB, /**< The ECB cipher mode. */
+ MBEDTLS_MODE_CBC, /**< The CBC cipher mode. */
+ MBEDTLS_MODE_CFB, /**< The CFB cipher mode. */
+ MBEDTLS_MODE_OFB, /**< The OFB cipher mode. */
+ MBEDTLS_MODE_CTR, /**< The CTR cipher mode. */
+ MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */
+ MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */
+ MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */
+ MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */
+ MBEDTLS_MODE_CHACHAPOLY, /**< The ChaCha-Poly cipher mode. */
+ MBEDTLS_MODE_KW, /**< The SP800-38F KW mode */
+ MBEDTLS_MODE_KWP, /**< The SP800-38F KWP mode */
+} mbedtls_cipher_mode_t;
+
+/** Supported cipher padding types. */
+typedef enum {
+ MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default). */
+ MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding. */
+ MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding. */
+ MBEDTLS_PADDING_ZEROS, /**< Zero padding (not reversible). */
+ MBEDTLS_PADDING_NONE, /**< Never pad (full blocks only). */
+} mbedtls_cipher_padding_t;
+
+/** Type of operation. */
+typedef enum {
+ MBEDTLS_OPERATION_NONE = -1,
+ MBEDTLS_DECRYPT = 0,
+ MBEDTLS_ENCRYPT,
+} mbedtls_operation_t;
+
+enum {
+ /** Undefined key length. */
+ MBEDTLS_KEY_LENGTH_NONE = 0,
+ /** Key length, in bits (including parity), for DES keys. */
+ MBEDTLS_KEY_LENGTH_DES = 64,
+ /** Key length in bits, including parity, for DES in two-key EDE. */
+ MBEDTLS_KEY_LENGTH_DES_EDE = 128,
+ /** Key length in bits, including parity, for DES in three-key EDE. */
+ MBEDTLS_KEY_LENGTH_DES_EDE3 = 192,
+};
+
+/** Maximum length of any IV, in Bytes. */
+#define MBEDTLS_MAX_IV_LENGTH 16
+/** Maximum block size of any cipher, in Bytes. */
+#define MBEDTLS_MAX_BLOCK_LENGTH 16
+
+/**
+ * Base cipher information (opaque struct).
+ */
+typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t;
+
+/**
+ * CMAC context (opaque struct).
+ */
+typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t;
+
+/**
+ * Cipher information. Allows calling cipher functions
+ * in a generic way.
+ */
+typedef struct mbedtls_cipher_info_t
+{
+ /** Full cipher identifier. For example,
+ * MBEDTLS_CIPHER_AES_256_CBC.
+ */
+ mbedtls_cipher_type_t type;
+
+ /** The cipher mode. For example, MBEDTLS_MODE_CBC. */
+ mbedtls_cipher_mode_t mode;
+
+ /** The cipher key length, in bits. This is the
+ * default length for variable sized ciphers.
+ * Includes parity bits for ciphers like DES.
+ */
+ unsigned int key_bitlen;
+
+ /** Name of the cipher. */
+ const char * name;
+
+ /** IV or nonce size, in Bytes.
+ * For ciphers that accept variable IV sizes,
+ * this is the recommended size.
+ */
+ unsigned int iv_size;
+
+ /** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and
+ * MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the
+ * cipher supports variable IV or variable key sizes, respectively.
+ */
+ int flags;
+
+ /** The block size, in Bytes. */
+ unsigned int block_size;
+
+ /** Struct for base cipher information and functions. */
+ const mbedtls_cipher_base_t *base;
+
+} mbedtls_cipher_info_t;
+
+/**
+ * Generic cipher context.
+ */
+typedef struct mbedtls_cipher_context_t
+{
+ /** Information about the associated cipher. */
+ const mbedtls_cipher_info_t *cipher_info;
+
+ /** Key length to use. */
+ int key_bitlen;
+
+ /** Operation that the key of the context has been
+ * initialized for.
+ */
+ mbedtls_operation_t operation;
+
+#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
+ /** Padding functions to use, if relevant for
+ * the specific cipher mode.
+ */
+ void (*add_padding)( unsigned char *output, size_t olen, size_t data_len );
+ int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len );
+#endif
+
+ /** Buffer for input that has not been processed yet. */
+ unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH];
+
+ /** Number of Bytes that have not been processed yet. */
+ size_t unprocessed_len;
+
+ /** Current IV or NONCE_COUNTER for CTR-mode, data unit (or sector) number
+ * for XTS-mode. */
+ unsigned char iv[MBEDTLS_MAX_IV_LENGTH];
+
+ /** IV size in Bytes, for ciphers with variable-length IVs. */
+ size_t iv_size;
+
+ /** The cipher-specific context. */
+ void *cipher_ctx;
+
+#if defined(MBEDTLS_CMAC_C)
+ /** CMAC-specific context. */
+ mbedtls_cmac_context_t *cmac_ctx;
+#endif
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ /** Indicates whether the cipher operations should be performed
+ * by Mbed TLS' own crypto library or an external implementation
+ * of the PSA Crypto API.
+ * This is unset if the cipher context was established through
+ * mbedtls_cipher_setup(), and set if it was established through
+ * mbedtls_cipher_setup_psa().
+ */
+ unsigned char psa_enabled;
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+} mbedtls_cipher_context_t;
+
+/**
+ * \brief This function retrieves the list of ciphers supported
+ * by the generic cipher module.
+ *
+ * For any cipher identifier in the returned list, you can
+ * obtain the corresponding generic cipher information structure
+ * via mbedtls_cipher_info_from_type(), which can then be used
+ * to prepare a cipher context via mbedtls_cipher_setup().
+ *
+ *
+ * \return A statically-allocated array of cipher identifiers
+ * of type cipher_type_t. The last entry is zero.
+ */
+const int *mbedtls_cipher_list( void );
+
+/**
+ * \brief This function retrieves the cipher-information
+ * structure associated with the given cipher name.
+ *
+ * \param cipher_name Name of the cipher to search for. This must not be
+ * \c NULL.
+ *
+ * \return The cipher information structure associated with the
+ * given \p cipher_name.
+ * \return \c NULL if the associated cipher information is not found.
+ */
+const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name );
+
+/**
+ * \brief This function retrieves the cipher-information
+ * structure associated with the given cipher type.
+ *
+ * \param cipher_type Type of the cipher to search for.
+ *
+ * \return The cipher information structure associated with the
+ * given \p cipher_type.
+ * \return \c NULL if the associated cipher information is not found.
+ */
+const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type );
+
+/**
+ * \brief This function retrieves the cipher-information
+ * structure associated with the given cipher ID,
+ * key size and mode.
+ *
+ * \param cipher_id The ID of the cipher to search for. For example,
+ * #MBEDTLS_CIPHER_ID_AES.
+ * \param key_bitlen The length of the key in bits.
+ * \param mode The cipher mode. For example, #MBEDTLS_MODE_CBC.
+ *
+ * \return The cipher information structure associated with the
+ * given \p cipher_id.
+ * \return \c NULL if the associated cipher information is not found.
+ */
+const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
+ int key_bitlen,
+ const mbedtls_cipher_mode_t mode );
+
+/**
+ * \brief This function initializes a \p cipher_context as NONE.
+ *
+ * \param ctx The context to be initialized. This must not be \c NULL.
+ */
+void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
+
+/**
+ * \brief This function frees and clears the cipher-specific
+ * context of \p ctx. Freeing \p ctx itself remains the
+ * responsibility of the caller.
+ *
+ * \param ctx The context to be freed. If this is \c NULL, the
+ * function has no effect, otherwise this must point to an
+ * initialized context.
+ */
+void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx );
+
+
+/**
+ * \brief This function initializes a cipher context for
+ * use with the given cipher primitive.
+ *
+ * \param ctx The context to initialize. This must be initialized.
+ * \param cipher_info The cipher to use.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
+ * cipher-specific context fails.
+ *
+ * \internal Currently, the function also clears the structure.
+ * In future versions, the caller will be required to call
+ * mbedtls_cipher_init() on the structure first.
+ */
+int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
+ const mbedtls_cipher_info_t *cipher_info );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/**
+ * \brief This function initializes a cipher context for
+ * PSA-based use with the given cipher primitive.
+ *
+ * \note See #MBEDTLS_USE_PSA_CRYPTO for information on PSA.
+ *
+ * \param ctx The context to initialize. May not be \c NULL.
+ * \param cipher_info The cipher to use.
+ * \param taglen For AEAD ciphers, the length in bytes of the
+ * authentication tag to use. Subsequent uses of
+ * mbedtls_cipher_auth_encrypt() or
+ * mbedtls_cipher_auth_decrypt() must provide
+ * the same tag length.
+ * For non-AEAD ciphers, the value must be \c 0.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
+ * cipher-specific context fails.
+ */
+int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx,
+ const mbedtls_cipher_info_t *cipher_info,
+ size_t taglen );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+/**
+ * \brief This function returns the block size of the given cipher.
+ *
+ * \param ctx The context of the cipher. This must be initialized.
+ *
+ * \return The block size of the underlying cipher.
+ * \return \c 0 if \p ctx has not been initialized.
+ */
+static inline unsigned int mbedtls_cipher_get_block_size(
+ const mbedtls_cipher_context_t *ctx )
+{
+ MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
+ if( ctx->cipher_info == NULL )
+ return 0;
+
+ return ctx->cipher_info->block_size;
+}
+
+/**
+ * \brief This function returns the mode of operation for
+ * the cipher. For example, MBEDTLS_MODE_CBC.
+ *
+ * \param ctx The context of the cipher. This must be initialized.
+ *
+ * \return The mode of operation.
+ * \return #MBEDTLS_MODE_NONE if \p ctx has not been initialized.
+ */
+static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode(
+ const mbedtls_cipher_context_t *ctx )
+{
+ MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, MBEDTLS_MODE_NONE );
+ if( ctx->cipher_info == NULL )
+ return MBEDTLS_MODE_NONE;
+
+ return ctx->cipher_info->mode;
+}
+
+/**
+ * \brief This function returns the size of the IV or nonce
+ * of the cipher, in Bytes.
+ *
+ * \param ctx The context of the cipher. This must be initialized.
+ *
+ * \return The recommended IV size if no IV has been set.
+ * \return \c 0 for ciphers not using an IV or a nonce.
+ * \return The actual size if an IV has been set.
+ */
+static inline int mbedtls_cipher_get_iv_size(
+ const mbedtls_cipher_context_t *ctx )
+{
+ MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
+ if( ctx->cipher_info == NULL )
+ return 0;
+
+ if( ctx->iv_size != 0 )
+ return (int) ctx->iv_size;
+
+ return (int) ctx->cipher_info->iv_size;
+}
+
+/**
+ * \brief This function returns the type of the given cipher.
+ *
+ * \param ctx The context of the cipher. This must be initialized.
+ *
+ * \return The type of the cipher.
+ * \return #MBEDTLS_CIPHER_NONE if \p ctx has not been initialized.
+ */
+static inline mbedtls_cipher_type_t mbedtls_cipher_get_type(
+ const mbedtls_cipher_context_t *ctx )
+{
+ MBEDTLS_INTERNAL_VALIDATE_RET(
+ ctx != NULL, MBEDTLS_CIPHER_NONE );
+ if( ctx->cipher_info == NULL )
+ return MBEDTLS_CIPHER_NONE;
+
+ return ctx->cipher_info->type;
+}
+
+/**
+ * \brief This function returns the name of the given cipher
+ * as a string.
+ *
+ * \param ctx The context of the cipher. This must be initialized.
+ *
+ * \return The name of the cipher.
+ * \return NULL if \p ctx has not been not initialized.
+ */
+static inline const char *mbedtls_cipher_get_name(
+ const mbedtls_cipher_context_t *ctx )
+{
+ MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
+ if( ctx->cipher_info == NULL )
+ return 0;
+
+ return ctx->cipher_info->name;
+}
+
+/**
+ * \brief This function returns the key length of the cipher.
+ *
+ * \param ctx The context of the cipher. This must be initialized.
+ *
+ * \return The key length of the cipher in bits.
+ * \return #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been
+ * initialized.
+ */
+static inline int mbedtls_cipher_get_key_bitlen(
+ const mbedtls_cipher_context_t *ctx )
+{
+ MBEDTLS_INTERNAL_VALIDATE_RET(
+ ctx != NULL, MBEDTLS_KEY_LENGTH_NONE );
+ if( ctx->cipher_info == NULL )
+ return MBEDTLS_KEY_LENGTH_NONE;
+
+ return (int) ctx->cipher_info->key_bitlen;
+}
+
+/**
+ * \brief This function returns the operation of the given cipher.
+ *
+ * \param ctx The context of the cipher. This must be initialized.
+ *
+ * \return The type of operation: #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
+ * \return #MBEDTLS_OPERATION_NONE if \p ctx has not been initialized.
+ */
+static inline mbedtls_operation_t mbedtls_cipher_get_operation(
+ const mbedtls_cipher_context_t *ctx )
+{
+ MBEDTLS_INTERNAL_VALIDATE_RET(
+ ctx != NULL, MBEDTLS_OPERATION_NONE );
+ if( ctx->cipher_info == NULL )
+ return MBEDTLS_OPERATION_NONE;
+
+ return ctx->operation;
+}
+
+/**
+ * \brief This function sets the key to use with the given context.
+ *
+ * \param ctx The generic cipher context. This must be initialized and
+ * bound to a cipher information structure.
+ * \param key The key to use. This must be a readable buffer of at
+ * least \p key_bitlen Bits.
+ * \param key_bitlen The key length to use, in Bits.
+ * \param operation The operation that the key will be used for:
+ * #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
+ const unsigned char *key,
+ int key_bitlen,
+ const mbedtls_operation_t operation );
+
+#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
+/**
+ * \brief This function sets the padding mode, for cipher modes
+ * that use padding.
+ *
+ * The default passing mode is PKCS7 padding.
+ *
+ * \param ctx The generic cipher context. This must be initialized and
+ * bound to a cipher information structure.
+ * \param mode The padding mode.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
+ * if the selected padding mode is not supported.
+ * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode
+ * does not support padding.
+ */
+int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
+ mbedtls_cipher_padding_t mode );
+#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
+
+/**
+ * \brief This function sets the initialization vector (IV)
+ * or nonce.
+ *
+ * \note Some ciphers do not use IVs nor nonce. For these
+ * ciphers, this function has no effect.
+ *
+ * \param ctx The generic cipher context. This must be initialized and
+ * bound to a cipher information structure.
+ * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. This
+ * must be a readable buffer of at least \p iv_len Bytes.
+ * \param iv_len The IV length for ciphers with variable-size IV.
+ * This parameter is discarded by ciphers with fixed-size IV.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ */
+int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv,
+ size_t iv_len );
+
+/**
+ * \brief This function resets the cipher state.
+ *
+ * \param ctx The generic cipher context. This must be initialized.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ */
+int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx );
+
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
+/**
+ * \brief This function adds additional data for AEAD ciphers.
+ * Currently supported with GCM and ChaCha20+Poly1305.
+ * This must be called exactly once, after
+ * mbedtls_cipher_reset().
+ *
+ * \param ctx The generic cipher context. This must be initialized.
+ * \param ad The additional data to use. This must be a readable
+ * buffer of at least \p ad_len Bytes.
+ * \param ad_len The length of \p ad in Bytes.
+ *
+ * \return \c 0 on success.
+ * \return A specific error code on failure.
+ */
+int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
+ const unsigned char *ad, size_t ad_len );
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
+
+/**
+ * \brief The generic cipher update function. It encrypts or
+ * decrypts using the given cipher context. Writes as
+ * many block-sized blocks of data as possible to output.
+ * Any data that cannot be written immediately is either
+ * added to the next block, or flushed when
+ * mbedtls_cipher_finish() is called.
+ * Exception: For MBEDTLS_MODE_ECB, expects a single block
+ * in size. For example, 16 Bytes for AES.
+ *
+ * \note If the underlying cipher is used in GCM mode, all calls
+ * to this function, except for the last one before
+ * mbedtls_cipher_finish(), must have \p ilen as a
+ * multiple of the block size of the cipher.
+ *
+ * \param ctx The generic cipher context. This must be initialized and
+ * bound to a key.
+ * \param input The buffer holding the input data. This must be a
+ * readable buffer of at least \p ilen Bytes.
+ * \param ilen The length of the input data.
+ * \param output The buffer for the output data. This must be able to
+ * hold at least `ilen + block_size`. This must not be the
+ * same buffer as \p input.
+ * \param olen The length of the output data, to be updated with the
+ * actual number of Bytes written. This must not be
+ * \c NULL.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an
+ * unsupported mode for a cipher.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx,
+ const unsigned char *input,
+ size_t ilen, unsigned char *output,
+ size_t *olen );
+
+/**
+ * \brief The generic cipher finalization function. If data still
+ * needs to be flushed from an incomplete block, the data
+ * contained in it is padded to the size of
+ * the last block, and written to the \p output buffer.
+ *
+ * \param ctx The generic cipher context. This must be initialized and
+ * bound to a key.
+ * \param output The buffer to write data to. This needs to be a writable
+ * buffer of at least \p block_size Bytes.
+ * \param olen The length of the data written to the \p output buffer.
+ * This may not be \c NULL.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
+ * expecting a full block but not receiving one.
+ * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
+ * while decrypting.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
+ unsigned char *output, size_t *olen );
+
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
+/**
+ * \brief This function writes a tag for AEAD ciphers.
+ * Currently supported with GCM and ChaCha20+Poly1305.
+ * This must be called after mbedtls_cipher_finish().
+ *
+ * \param ctx The generic cipher context. This must be initialized,
+ * bound to a key, and have just completed a cipher
+ * operation through mbedtls_cipher_finish() the tag for
+ * which should be written.
+ * \param tag The buffer to write the tag to. This must be a writable
+ * buffer of at least \p tag_len Bytes.
+ * \param tag_len The length of the tag to write.
+ *
+ * \return \c 0 on success.
+ * \return A specific error code on failure.
+ */
+int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
+ unsigned char *tag, size_t tag_len );
+
+/**
+ * \brief This function checks the tag for AEAD ciphers.
+ * Currently supported with GCM and ChaCha20+Poly1305.
+ * This must be called after mbedtls_cipher_finish().
+ *
+ * \param ctx The generic cipher context. This must be initialized.
+ * \param tag The buffer holding the tag. This must be a readable
+ * buffer of at least \p tag_len Bytes.
+ * \param tag_len The length of the tag to check.
+ *
+ * \return \c 0 on success.
+ * \return A specific error code on failure.
+ */
+int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
+ const unsigned char *tag, size_t tag_len );
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
+
+/**
+ * \brief The generic all-in-one encryption/decryption function,
+ * for all ciphers except AEAD constructs.
+ *
+ * \param ctx The generic cipher context. This must be initialized.
+ * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ * This must be a readable buffer of at least \p iv_len
+ * Bytes.
+ * \param iv_len The IV length for ciphers with variable-size IV.
+ * This parameter is discarded by ciphers with fixed-size
+ * IV.
+ * \param input The buffer holding the input data. This must be a
+ * readable buffer of at least \p ilen Bytes.
+ * \param ilen The length of the input data in Bytes.
+ * \param output The buffer for the output data. This must be able to
+ * hold at least `ilen + block_size`. This must not be the
+ * same buffer as \p input.
+ * \param olen The length of the output data, to be updated with the
+ * actual number of Bytes written. This must not be
+ * \c NULL.
+ *
+ * \note Some ciphers do not use IVs nor nonce. For these
+ * ciphers, use \p iv = NULL and \p iv_len = 0.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
+ * expecting a full block but not receiving one.
+ * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
+ * while decrypting.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen );
+
+#if defined(MBEDTLS_CIPHER_MODE_AEAD)
+/**
+ * \brief The generic autenticated encryption (AEAD) function.
+ *
+ * \param ctx The generic cipher context. This must be initialized and
+ * bound to a key.
+ * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ * This must be a readable buffer of at least \p iv_len
+ * Bytes.
+ * \param iv_len The IV length for ciphers with variable-size IV.
+ * This parameter is discarded by ciphers with fixed-size IV.
+ * \param ad The additional data to authenticate. This must be a
+ * readable buffer of at least \p ad_len Bytes.
+ * \param ad_len The length of \p ad.
+ * \param input The buffer holding the input data. This must be a
+ * readable buffer of at least \p ilen Bytes.
+ * \param ilen The length of the input data.
+ * \param output The buffer for the output data. This must be able to
+ * hold at least \p ilen Bytes.
+ * \param olen The length of the output data, to be updated with the
+ * actual number of Bytes written. This must not be
+ * \c NULL.
+ * \param tag The buffer for the authentication tag. This must be a
+ * writable buffer of at least \p tag_len Bytes.
+ * \param tag_len The desired length of the authentication tag.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen,
+ unsigned char *tag, size_t tag_len );
+
+/**
+ * \brief The generic autenticated decryption (AEAD) function.
+ *
+ * \note If the data is not authentic, then the output buffer
+ * is zeroed out to prevent the unauthentic plaintext being
+ * used, making this interface safer.
+ *
+ * \param ctx The generic cipher context. This must be initialized and
+ * and bound to a key.
+ * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ * This must be a readable buffer of at least \p iv_len
+ * Bytes.
+ * \param iv_len The IV length for ciphers with variable-size IV.
+ * This parameter is discarded by ciphers with fixed-size IV.
+ * \param ad The additional data to be authenticated. This must be a
+ * readable buffer of at least \p ad_len Bytes.
+ * \param ad_len The length of \p ad.
+ * \param input The buffer holding the input data. This must be a
+ * readable buffer of at least \p ilen Bytes.
+ * \param ilen The length of the input data.
+ * \param output The buffer for the output data.
+ * This must be able to hold at least \p ilen Bytes.
+ * \param olen The length of the output data, to be updated with the
+ * actual number of Bytes written. This must not be
+ * \c NULL.
+ * \param tag The buffer holding the authentication tag. This must be
+ * a readable buffer of at least \p tag_len Bytes.
+ * \param tag_len The length of the authentication tag.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen,
+ const unsigned char *tag, size_t tag_len );
+#endif /* MBEDTLS_CIPHER_MODE_AEAD */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_CIPHER_H */
diff --git a/templates/blackpill/Src/cipher_internal.h b/templates/blackpill/Src/cipher_internal.h
new file mode 100644
index 0000000..d711339
--- /dev/null
+++ b/templates/blackpill/Src/cipher_internal.h
@@ -0,0 +1,153 @@
+/**
+ * \file cipher_internal.h
+ *
+ * \brief Cipher wrappers.
+ *
+ * \author Adriaan de Jong
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_CIPHER_WRAP_H
+#define MBEDTLS_CIPHER_WRAP_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "cipher.h"
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Base cipher information. The non-mode specific functions and values.
+ */
+struct mbedtls_cipher_base_t
+{
+ /** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */
+ mbedtls_cipher_id_t cipher;
+
+ /** Encrypt using ECB */
+ int (*ecb_func)( void *ctx, mbedtls_operation_t mode,
+ const unsigned char *input, unsigned char *output );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ /** Encrypt using CBC */
+ int (*cbc_func)( void *ctx, mbedtls_operation_t mode, size_t length,
+ unsigned char *iv, const unsigned char *input,
+ unsigned char *output );
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ /** Encrypt using CFB (Full length) */
+ int (*cfb_func)( void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off,
+ unsigned char *iv, const unsigned char *input,
+ unsigned char *output );
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ /** Encrypt using OFB (Full length) */
+ int (*ofb_func)( void *ctx, size_t length, size_t *iv_off,
+ unsigned char *iv,
+ const unsigned char *input,
+ unsigned char *output );
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ /** Encrypt using CTR */
+ int (*ctr_func)( void *ctx, size_t length, size_t *nc_off,
+ unsigned char *nonce_counter, unsigned char *stream_block,
+ const unsigned char *input, unsigned char *output );
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ /** Encrypt or decrypt using XTS. */
+ int (*xts_func)( void *ctx, mbedtls_operation_t mode, size_t length,
+ const unsigned char data_unit[16],
+ const unsigned char *input, unsigned char *output );
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ /** Encrypt using STREAM */
+ int (*stream_func)( void *ctx, size_t length,
+ const unsigned char *input, unsigned char *output );
+#endif
+
+ /** Set key for encryption purposes */
+ int (*setkey_enc_func)( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen );
+
+ /** Set key for decryption purposes */
+ int (*setkey_dec_func)( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen);
+
+ /** Allocate a new context */
+ void * (*ctx_alloc_func)( void );
+
+ /** Free the given context */
+ void (*ctx_free_func)( void *ctx );
+
+};
+
+typedef struct
+{
+ mbedtls_cipher_type_t type;
+ const mbedtls_cipher_info_t *info;
+} mbedtls_cipher_definition_t;
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+typedef enum
+{
+ MBEDTLS_CIPHER_PSA_KEY_UNSET = 0,
+ MBEDTLS_CIPHER_PSA_KEY_OWNED, /* Used for PSA-based cipher contexts which */
+ /* use raw key material internally imported */
+ /* into a allocated key slot, and which */
+ /* hence need to destroy that key slot */
+ /* when they are no longer needed. */
+ MBEDTLS_CIPHER_PSA_KEY_NOT_OWNED, /* Used for PSA-based cipher contexts */
+ /* which use a key from a key slot */
+ /* provided by the user, and which */
+ /* hence should not be destroyed when */
+ /* the context is no longer needed. */
+} mbedtls_cipher_psa_key_ownership;
+
+typedef struct
+{
+ psa_algorithm_t alg;
+ psa_key_handle_t slot;
+ mbedtls_cipher_psa_key_ownership slot_state;
+} mbedtls_cipher_context_psa;
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[];
+
+extern int mbedtls_cipher_supported[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_CIPHER_WRAP_H */
diff --git a/templates/blackpill/Src/cipher_wrap.c b/templates/blackpill/Src/cipher_wrap.c
new file mode 100644
index 0000000..fcbc92d
--- /dev/null
+++ b/templates/blackpill/Src/cipher_wrap.c
@@ -0,0 +1,2411 @@
+/**
+ * \file cipher_wrap.c
+ *
+ * \brief Generic cipher wrapper for mbed TLS
+ *
+ * \author Adriaan de Jong
+ *
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_CIPHER_C)
+
+#include "cipher_internal.h"
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+#include "mbedtls/chachapoly.h"
+#endif
+
+#if defined(MBEDTLS_AES_C)
+#include "aes.h"
+#endif
+
+#if defined(MBEDTLS_ARC4_C)
+#include "mbedtls/arc4.h"
+#endif
+
+#if defined(MBEDTLS_CAMELLIA_C)
+#include "mbedtls/camellia.h"
+#endif
+
+#if defined(MBEDTLS_ARIA_C)
+#include "mbedtls/aria.h"
+#endif
+
+#if defined(MBEDTLS_DES_C)
+#include "mbedtls/des.h"
+#endif
+
+#if defined(MBEDTLS_BLOWFISH_C)
+#include "mbedtls/blowfish.h"
+#endif
+
+#if defined(MBEDTLS_CHACHA20_C)
+#include "mbedtls/chacha20.h"
+#endif
+
+#if defined(MBEDTLS_GCM_C)
+#include "gcm.h"
+#endif
+
+#if defined(MBEDTLS_CCM_C)
+#include "mbedtls/ccm.h"
+#endif
+
+#if defined(MBEDTLS_NIST_KW_C)
+#include "mbedtls/nist_kw.h"
+#endif
+
+#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
+#include
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include
+#define mbedtls_calloc calloc
+#define mbedtls_free free
+#endif
+
+#if defined(MBEDTLS_GCM_C)
+/* shared by all GCM ciphers */
+static void *gcm_ctx_alloc( void )
+{
+ void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_gcm_context ) );
+
+ if( ctx != NULL )
+ mbedtls_gcm_init( (mbedtls_gcm_context *) ctx );
+
+ return( ctx );
+}
+
+static void gcm_ctx_free( void *ctx )
+{
+ mbedtls_gcm_free( ctx );
+ mbedtls_free( ctx );
+}
+#endif /* MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_CCM_C)
+/* shared by all CCM ciphers */
+static void *ccm_ctx_alloc( void )
+{
+ void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ccm_context ) );
+
+ if( ctx != NULL )
+ mbedtls_ccm_init( (mbedtls_ccm_context *) ctx );
+
+ return( ctx );
+}
+
+static void ccm_ctx_free( void *ctx )
+{
+ mbedtls_ccm_free( ctx );
+ mbedtls_free( ctx );
+}
+#endif /* MBEDTLS_CCM_C */
+
+#if defined(MBEDTLS_AES_C)
+
+static int aes_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
+ const unsigned char *input, unsigned char *output )
+{
+ return mbedtls_aes_crypt_ecb( (mbedtls_aes_context *) ctx, operation, input, output );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static int aes_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length,
+ unsigned char *iv, const unsigned char *input, unsigned char *output )
+{
+ return mbedtls_aes_crypt_cbc( (mbedtls_aes_context *) ctx, operation, length, iv, input,
+ output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static int aes_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation,
+ size_t length, size_t *iv_off, unsigned char *iv,
+ const unsigned char *input, unsigned char *output )
+{
+ return mbedtls_aes_crypt_cfb128( (mbedtls_aes_context *) ctx, operation, length, iv_off, iv,
+ input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+static int aes_crypt_ofb_wrap( void *ctx, size_t length, size_t *iv_off,
+ unsigned char *iv, const unsigned char *input, unsigned char *output )
+{
+ return mbedtls_aes_crypt_ofb( (mbedtls_aes_context *) ctx, length, iv_off,
+ iv, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
+ unsigned char *nonce_counter, unsigned char *stream_block,
+ const unsigned char *input, unsigned char *output )
+{
+ return mbedtls_aes_crypt_ctr( (mbedtls_aes_context *) ctx, length, nc_off, nonce_counter,
+ stream_block, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+static int aes_crypt_xts_wrap( void *ctx, mbedtls_operation_t operation,
+ size_t length,
+ const unsigned char data_unit[16],
+ const unsigned char *input,
+ unsigned char *output )
+{
+ mbedtls_aes_xts_context *xts_ctx = ctx;
+ int mode;
+
+ switch( operation )
+ {
+ case MBEDTLS_ENCRYPT:
+ mode = MBEDTLS_AES_ENCRYPT;
+ break;
+ case MBEDTLS_DECRYPT:
+ mode = MBEDTLS_AES_DECRYPT;
+ break;
+ default:
+ return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+ }
+
+ return mbedtls_aes_crypt_xts( xts_ctx, mode, length,
+ data_unit, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_aes_setkey_dec( (mbedtls_aes_context *) ctx, key, key_bitlen );
+}
+
+static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_aes_setkey_enc( (mbedtls_aes_context *) ctx, key, key_bitlen );
+}
+
+static void * aes_ctx_alloc( void )
+{
+ mbedtls_aes_context *aes = mbedtls_calloc( 1, sizeof( mbedtls_aes_context ) );
+
+ if( aes == NULL )
+ return( NULL );
+
+ mbedtls_aes_init( aes );
+
+ return( aes );
+}
+
+static void aes_ctx_free( void *ctx )
+{
+ mbedtls_aes_free( (mbedtls_aes_context *) ctx );
+ mbedtls_free( ctx );
+}
+
+static const mbedtls_cipher_base_t aes_info = {
+ MBEDTLS_CIPHER_ID_AES,
+ aes_crypt_ecb_wrap,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ aes_crypt_cbc_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ aes_crypt_cfb128_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ aes_crypt_ofb_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ aes_crypt_ctr_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ NULL,
+#endif
+ aes_setkey_enc_wrap,
+ aes_setkey_dec_wrap,
+ aes_ctx_alloc,
+ aes_ctx_free
+};
+
+static const mbedtls_cipher_info_t aes_128_ecb_info = {
+ MBEDTLS_CIPHER_AES_128_ECB,
+ MBEDTLS_MODE_ECB,
+ 128,
+ "AES-128-ECB",
+ 0,
+ 0,
+ 16,
+ &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_ecb_info = {
+ MBEDTLS_CIPHER_AES_192_ECB,
+ MBEDTLS_MODE_ECB,
+ 192,
+ "AES-192-ECB",
+ 0,
+ 0,
+ 16,
+ &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_ecb_info = {
+ MBEDTLS_CIPHER_AES_256_ECB,
+ MBEDTLS_MODE_ECB,
+ 256,
+ "AES-256-ECB",
+ 0,
+ 0,
+ 16,
+ &aes_info
+};
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const mbedtls_cipher_info_t aes_128_cbc_info = {
+ MBEDTLS_CIPHER_AES_128_CBC,
+ MBEDTLS_MODE_CBC,
+ 128,
+ "AES-128-CBC",
+ 16,
+ 0,
+ 16,
+ &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_cbc_info = {
+ MBEDTLS_CIPHER_AES_192_CBC,
+ MBEDTLS_MODE_CBC,
+ 192,
+ "AES-192-CBC",
+ 16,
+ 0,
+ 16,
+ &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_cbc_info = {
+ MBEDTLS_CIPHER_AES_256_CBC,
+ MBEDTLS_MODE_CBC,
+ 256,
+ "AES-256-CBC",
+ 16,
+ 0,
+ 16,
+ &aes_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static const mbedtls_cipher_info_t aes_128_cfb128_info = {
+ MBEDTLS_CIPHER_AES_128_CFB128,
+ MBEDTLS_MODE_CFB,
+ 128,
+ "AES-128-CFB128",
+ 16,
+ 0,
+ 16,
+ &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_cfb128_info = {
+ MBEDTLS_CIPHER_AES_192_CFB128,
+ MBEDTLS_MODE_CFB,
+ 192,
+ "AES-192-CFB128",
+ 16,
+ 0,
+ 16,
+ &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_cfb128_info = {
+ MBEDTLS_CIPHER_AES_256_CFB128,
+ MBEDTLS_MODE_CFB,
+ 256,
+ "AES-256-CFB128",
+ 16,
+ 0,
+ 16,
+ &aes_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+static const mbedtls_cipher_info_t aes_128_ofb_info = {
+ MBEDTLS_CIPHER_AES_128_OFB,
+ MBEDTLS_MODE_OFB,
+ 128,
+ "AES-128-OFB",
+ 16,
+ 0,
+ 16,
+ &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_ofb_info = {
+ MBEDTLS_CIPHER_AES_192_OFB,
+ MBEDTLS_MODE_OFB,
+ 192,
+ "AES-192-OFB",
+ 16,
+ 0,
+ 16,
+ &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_ofb_info = {
+ MBEDTLS_CIPHER_AES_256_OFB,
+ MBEDTLS_MODE_OFB,
+ 256,
+ "AES-256-OFB",
+ 16,
+ 0,
+ 16,
+ &aes_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static const mbedtls_cipher_info_t aes_128_ctr_info = {
+ MBEDTLS_CIPHER_AES_128_CTR,
+ MBEDTLS_MODE_CTR,
+ 128,
+ "AES-128-CTR",
+ 16,
+ 0,
+ 16,
+ &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_ctr_info = {
+ MBEDTLS_CIPHER_AES_192_CTR,
+ MBEDTLS_MODE_CTR,
+ 192,
+ "AES-192-CTR",
+ 16,
+ 0,
+ 16,
+ &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_ctr_info = {
+ MBEDTLS_CIPHER_AES_256_CTR,
+ MBEDTLS_MODE_CTR,
+ 256,
+ "AES-256-CTR",
+ 16,
+ 0,
+ 16,
+ &aes_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+static int xts_aes_setkey_enc_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ mbedtls_aes_xts_context *xts_ctx = ctx;
+ return( mbedtls_aes_xts_setkey_enc( xts_ctx, key, key_bitlen ) );
+}
+
+static int xts_aes_setkey_dec_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ mbedtls_aes_xts_context *xts_ctx = ctx;
+ return( mbedtls_aes_xts_setkey_dec( xts_ctx, key, key_bitlen ) );
+}
+
+static void *xts_aes_ctx_alloc( void )
+{
+ mbedtls_aes_xts_context *xts_ctx = mbedtls_calloc( 1, sizeof( *xts_ctx ) );
+
+ if( xts_ctx != NULL )
+ mbedtls_aes_xts_init( xts_ctx );
+
+ return( xts_ctx );
+}
+
+static void xts_aes_ctx_free( void *ctx )
+{
+ mbedtls_aes_xts_context *xts_ctx = ctx;
+
+ if( xts_ctx == NULL )
+ return;
+
+ mbedtls_aes_xts_free( xts_ctx );
+ mbedtls_free( xts_ctx );
+}
+
+static const mbedtls_cipher_base_t xts_aes_info = {
+ MBEDTLS_CIPHER_ID_AES,
+ NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ aes_crypt_xts_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ NULL,
+#endif
+ xts_aes_setkey_enc_wrap,
+ xts_aes_setkey_dec_wrap,
+ xts_aes_ctx_alloc,
+ xts_aes_ctx_free
+};
+
+static const mbedtls_cipher_info_t aes_128_xts_info = {
+ MBEDTLS_CIPHER_AES_128_XTS,
+ MBEDTLS_MODE_XTS,
+ 256,
+ "AES-128-XTS",
+ 16,
+ 0,
+ 16,
+ &xts_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_xts_info = {
+ MBEDTLS_CIPHER_AES_256_XTS,
+ MBEDTLS_MODE_XTS,
+ 512,
+ "AES-256-XTS",
+ 16,
+ 0,
+ 16,
+ &xts_aes_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#if defined(MBEDTLS_GCM_C)
+static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_AES,
+ key, key_bitlen );
+}
+
+static const mbedtls_cipher_base_t gcm_aes_info = {
+ MBEDTLS_CIPHER_ID_AES,
+ NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ NULL,
+#endif
+ gcm_aes_setkey_wrap,
+ gcm_aes_setkey_wrap,
+ gcm_ctx_alloc,
+ gcm_ctx_free,
+};
+
+static const mbedtls_cipher_info_t aes_128_gcm_info = {
+ MBEDTLS_CIPHER_AES_128_GCM,
+ MBEDTLS_MODE_GCM,
+ 128,
+ "AES-128-GCM",
+ 12,
+ MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+ 16,
+ &gcm_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_gcm_info = {
+ MBEDTLS_CIPHER_AES_192_GCM,
+ MBEDTLS_MODE_GCM,
+ 192,
+ "AES-192-GCM",
+ 12,
+ MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+ 16,
+ &gcm_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_gcm_info = {
+ MBEDTLS_CIPHER_AES_256_GCM,
+ MBEDTLS_MODE_GCM,
+ 256,
+ "AES-256-GCM",
+ 12,
+ MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+ 16,
+ &gcm_aes_info
+};
+#endif /* MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_CCM_C)
+static int ccm_aes_setkey_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_AES,
+ key, key_bitlen );
+}
+
+static const mbedtls_cipher_base_t ccm_aes_info = {
+ MBEDTLS_CIPHER_ID_AES,
+ NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ NULL,
+#endif
+ ccm_aes_setkey_wrap,
+ ccm_aes_setkey_wrap,
+ ccm_ctx_alloc,
+ ccm_ctx_free,
+};
+
+static const mbedtls_cipher_info_t aes_128_ccm_info = {
+ MBEDTLS_CIPHER_AES_128_CCM,
+ MBEDTLS_MODE_CCM,
+ 128,
+ "AES-128-CCM",
+ 12,
+ MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+ 16,
+ &ccm_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_ccm_info = {
+ MBEDTLS_CIPHER_AES_192_CCM,
+ MBEDTLS_MODE_CCM,
+ 192,
+ "AES-192-CCM",
+ 12,
+ MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+ 16,
+ &ccm_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_ccm_info = {
+ MBEDTLS_CIPHER_AES_256_CCM,
+ MBEDTLS_MODE_CCM,
+ 256,
+ "AES-256-CCM",
+ 12,
+ MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+ 16,
+ &ccm_aes_info
+};
+#endif /* MBEDTLS_CCM_C */
+
+#endif /* MBEDTLS_AES_C */
+
+#if defined(MBEDTLS_CAMELLIA_C)
+
+static int camellia_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
+ const unsigned char *input, unsigned char *output )
+{
+ return mbedtls_camellia_crypt_ecb( (mbedtls_camellia_context *) ctx, operation, input,
+ output );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static int camellia_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation,
+ size_t length, unsigned char *iv,
+ const unsigned char *input, unsigned char *output )
+{
+ return mbedtls_camellia_crypt_cbc( (mbedtls_camellia_context *) ctx, operation, length, iv,
+ input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static int camellia_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation,
+ size_t length, size_t *iv_off, unsigned char *iv,
+ const unsigned char *input, unsigned char *output )
+{
+ return mbedtls_camellia_crypt_cfb128( (mbedtls_camellia_context *) ctx, operation, length,
+ iv_off, iv, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static int camellia_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
+ unsigned char *nonce_counter, unsigned char *stream_block,
+ const unsigned char *input, unsigned char *output )
+{
+ return mbedtls_camellia_crypt_ctr( (mbedtls_camellia_context *) ctx, length, nc_off,
+ nonce_counter, stream_block, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_camellia_setkey_dec( (mbedtls_camellia_context *) ctx, key, key_bitlen );
+}
+
+static int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_camellia_setkey_enc( (mbedtls_camellia_context *) ctx, key, key_bitlen );
+}
+
+static void * camellia_ctx_alloc( void )
+{
+ mbedtls_camellia_context *ctx;
+ ctx = mbedtls_calloc( 1, sizeof( mbedtls_camellia_context ) );
+
+ if( ctx == NULL )
+ return( NULL );
+
+ mbedtls_camellia_init( ctx );
+
+ return( ctx );
+}
+
+static void camellia_ctx_free( void *ctx )
+{
+ mbedtls_camellia_free( (mbedtls_camellia_context *) ctx );
+ mbedtls_free( ctx );
+}
+
+static const mbedtls_cipher_base_t camellia_info = {
+ MBEDTLS_CIPHER_ID_CAMELLIA,
+ camellia_crypt_ecb_wrap,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ camellia_crypt_cbc_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ camellia_crypt_cfb128_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ camellia_crypt_ctr_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ NULL,
+#endif
+ camellia_setkey_enc_wrap,
+ camellia_setkey_dec_wrap,
+ camellia_ctx_alloc,
+ camellia_ctx_free
+};
+
+static const mbedtls_cipher_info_t camellia_128_ecb_info = {
+ MBEDTLS_CIPHER_CAMELLIA_128_ECB,
+ MBEDTLS_MODE_ECB,
+ 128,
+ "CAMELLIA-128-ECB",
+ 16,
+ 0,
+ 16,
+ &camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_192_ecb_info = {
+ MBEDTLS_CIPHER_CAMELLIA_192_ECB,
+ MBEDTLS_MODE_ECB,
+ 192,
+ "CAMELLIA-192-ECB",
+ 16,
+ 0,
+ 16,
+ &camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_256_ecb_info = {
+ MBEDTLS_CIPHER_CAMELLIA_256_ECB,
+ MBEDTLS_MODE_ECB,
+ 256,
+ "CAMELLIA-256-ECB",
+ 16,
+ 0,
+ 16,
+ &camellia_info
+};
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const mbedtls_cipher_info_t camellia_128_cbc_info = {
+ MBEDTLS_CIPHER_CAMELLIA_128_CBC,
+ MBEDTLS_MODE_CBC,
+ 128,
+ "CAMELLIA-128-CBC",
+ 16,
+ 0,
+ 16,
+ &camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_192_cbc_info = {
+ MBEDTLS_CIPHER_CAMELLIA_192_CBC,
+ MBEDTLS_MODE_CBC,
+ 192,
+ "CAMELLIA-192-CBC",
+ 16,
+ 0,
+ 16,
+ &camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_256_cbc_info = {
+ MBEDTLS_CIPHER_CAMELLIA_256_CBC,
+ MBEDTLS_MODE_CBC,
+ 256,
+ "CAMELLIA-256-CBC",
+ 16,
+ 0,
+ 16,
+ &camellia_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static const mbedtls_cipher_info_t camellia_128_cfb128_info = {
+ MBEDTLS_CIPHER_CAMELLIA_128_CFB128,
+ MBEDTLS_MODE_CFB,
+ 128,
+ "CAMELLIA-128-CFB128",
+ 16,
+ 0,
+ 16,
+ &camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_192_cfb128_info = {
+ MBEDTLS_CIPHER_CAMELLIA_192_CFB128,
+ MBEDTLS_MODE_CFB,
+ 192,
+ "CAMELLIA-192-CFB128",
+ 16,
+ 0,
+ 16,
+ &camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_256_cfb128_info = {
+ MBEDTLS_CIPHER_CAMELLIA_256_CFB128,
+ MBEDTLS_MODE_CFB,
+ 256,
+ "CAMELLIA-256-CFB128",
+ 16,
+ 0,
+ 16,
+ &camellia_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static const mbedtls_cipher_info_t camellia_128_ctr_info = {
+ MBEDTLS_CIPHER_CAMELLIA_128_CTR,
+ MBEDTLS_MODE_CTR,
+ 128,
+ "CAMELLIA-128-CTR",
+ 16,
+ 0,
+ 16,
+ &camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_192_ctr_info = {
+ MBEDTLS_CIPHER_CAMELLIA_192_CTR,
+ MBEDTLS_MODE_CTR,
+ 192,
+ "CAMELLIA-192-CTR",
+ 16,
+ 0,
+ 16,
+ &camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_256_ctr_info = {
+ MBEDTLS_CIPHER_CAMELLIA_256_CTR,
+ MBEDTLS_MODE_CTR,
+ 256,
+ "CAMELLIA-256-CTR",
+ 16,
+ 0,
+ 16,
+ &camellia_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_GCM_C)
+static int gcm_camellia_setkey_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA,
+ key, key_bitlen );
+}
+
+static const mbedtls_cipher_base_t gcm_camellia_info = {
+ MBEDTLS_CIPHER_ID_CAMELLIA,
+ NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ NULL,
+#endif
+ gcm_camellia_setkey_wrap,
+ gcm_camellia_setkey_wrap,
+ gcm_ctx_alloc,
+ gcm_ctx_free,
+};
+
+static const mbedtls_cipher_info_t camellia_128_gcm_info = {
+ MBEDTLS_CIPHER_CAMELLIA_128_GCM,
+ MBEDTLS_MODE_GCM,
+ 128,
+ "CAMELLIA-128-GCM",
+ 12,
+ MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+ 16,
+ &gcm_camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_192_gcm_info = {
+ MBEDTLS_CIPHER_CAMELLIA_192_GCM,
+ MBEDTLS_MODE_GCM,
+ 192,
+ "CAMELLIA-192-GCM",
+ 12,
+ MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+ 16,
+ &gcm_camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_256_gcm_info = {
+ MBEDTLS_CIPHER_CAMELLIA_256_GCM,
+ MBEDTLS_MODE_GCM,
+ 256,
+ "CAMELLIA-256-GCM",
+ 12,
+ MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+ 16,
+ &gcm_camellia_info
+};
+#endif /* MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_CCM_C)
+static int ccm_camellia_setkey_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA,
+ key, key_bitlen );
+}
+
+static const mbedtls_cipher_base_t ccm_camellia_info = {
+ MBEDTLS_CIPHER_ID_CAMELLIA,
+ NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ NULL,
+#endif
+ ccm_camellia_setkey_wrap,
+ ccm_camellia_setkey_wrap,
+ ccm_ctx_alloc,
+ ccm_ctx_free,
+};
+
+static const mbedtls_cipher_info_t camellia_128_ccm_info = {
+ MBEDTLS_CIPHER_CAMELLIA_128_CCM,
+ MBEDTLS_MODE_CCM,
+ 128,
+ "CAMELLIA-128-CCM",
+ 12,
+ MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+ 16,
+ &ccm_camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_192_ccm_info = {
+ MBEDTLS_CIPHER_CAMELLIA_192_CCM,
+ MBEDTLS_MODE_CCM,
+ 192,
+ "CAMELLIA-192-CCM",
+ 12,
+ MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+ 16,
+ &ccm_camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_256_ccm_info = {
+ MBEDTLS_CIPHER_CAMELLIA_256_CCM,
+ MBEDTLS_MODE_CCM,
+ 256,
+ "CAMELLIA-256-CCM",
+ 12,
+ MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+ 16,
+ &ccm_camellia_info
+};
+#endif /* MBEDTLS_CCM_C */
+
+#endif /* MBEDTLS_CAMELLIA_C */
+
+#if defined(MBEDTLS_ARIA_C)
+
+static int aria_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
+ const unsigned char *input, unsigned char *output )
+{
+ (void) operation;
+ return mbedtls_aria_crypt_ecb( (mbedtls_aria_context *) ctx, input,
+ output );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static int aria_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation,
+ size_t length, unsigned char *iv,
+ const unsigned char *input, unsigned char *output )
+{
+ return mbedtls_aria_crypt_cbc( (mbedtls_aria_context *) ctx, operation, length, iv,
+ input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static int aria_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation,
+ size_t length, size_t *iv_off, unsigned char *iv,
+ const unsigned char *input, unsigned char *output )
+{
+ return mbedtls_aria_crypt_cfb128( (mbedtls_aria_context *) ctx, operation, length,
+ iv_off, iv, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static int aria_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
+ unsigned char *nonce_counter, unsigned char *stream_block,
+ const unsigned char *input, unsigned char *output )
+{
+ return mbedtls_aria_crypt_ctr( (mbedtls_aria_context *) ctx, length, nc_off,
+ nonce_counter, stream_block, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+static int aria_setkey_dec_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_aria_setkey_dec( (mbedtls_aria_context *) ctx, key, key_bitlen );
+}
+
+static int aria_setkey_enc_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_aria_setkey_enc( (mbedtls_aria_context *) ctx, key, key_bitlen );
+}
+
+static void * aria_ctx_alloc( void )
+{
+ mbedtls_aria_context *ctx;
+ ctx = mbedtls_calloc( 1, sizeof( mbedtls_aria_context ) );
+
+ if( ctx == NULL )
+ return( NULL );
+
+ mbedtls_aria_init( ctx );
+
+ return( ctx );
+}
+
+static void aria_ctx_free( void *ctx )
+{
+ mbedtls_aria_free( (mbedtls_aria_context *) ctx );
+ mbedtls_free( ctx );
+}
+
+static const mbedtls_cipher_base_t aria_info = {
+ MBEDTLS_CIPHER_ID_ARIA,
+ aria_crypt_ecb_wrap,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ aria_crypt_cbc_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ aria_crypt_cfb128_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ aria_crypt_ctr_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ NULL,
+#endif
+ aria_setkey_enc_wrap,
+ aria_setkey_dec_wrap,
+ aria_ctx_alloc,
+ aria_ctx_free
+};
+
+static const mbedtls_cipher_info_t aria_128_ecb_info = {
+ MBEDTLS_CIPHER_ARIA_128_ECB,
+ MBEDTLS_MODE_ECB,
+ 128,
+ "ARIA-128-ECB",
+ 16,
+ 0,
+ 16,
+ &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_ecb_info = {
+ MBEDTLS_CIPHER_ARIA_192_ECB,
+ MBEDTLS_MODE_ECB,
+ 192,
+ "ARIA-192-ECB",
+ 16,
+ 0,
+ 16,
+ &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_ecb_info = {
+ MBEDTLS_CIPHER_ARIA_256_ECB,
+ MBEDTLS_MODE_ECB,
+ 256,
+ "ARIA-256-ECB",
+ 16,
+ 0,
+ 16,
+ &aria_info
+};
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const mbedtls_cipher_info_t aria_128_cbc_info = {
+ MBEDTLS_CIPHER_ARIA_128_CBC,
+ MBEDTLS_MODE_CBC,
+ 128,
+ "ARIA-128-CBC",
+ 16,
+ 0,
+ 16,
+ &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_cbc_info = {
+ MBEDTLS_CIPHER_ARIA_192_CBC,
+ MBEDTLS_MODE_CBC,
+ 192,
+ "ARIA-192-CBC",
+ 16,
+ 0,
+ 16,
+ &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_cbc_info = {
+ MBEDTLS_CIPHER_ARIA_256_CBC,
+ MBEDTLS_MODE_CBC,
+ 256,
+ "ARIA-256-CBC",
+ 16,
+ 0,
+ 16,
+ &aria_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static const mbedtls_cipher_info_t aria_128_cfb128_info = {
+ MBEDTLS_CIPHER_ARIA_128_CFB128,
+ MBEDTLS_MODE_CFB,
+ 128,
+ "ARIA-128-CFB128",
+ 16,
+ 0,
+ 16,
+ &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_cfb128_info = {
+ MBEDTLS_CIPHER_ARIA_192_CFB128,
+ MBEDTLS_MODE_CFB,
+ 192,
+ "ARIA-192-CFB128",
+ 16,
+ 0,
+ 16,
+ &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_cfb128_info = {
+ MBEDTLS_CIPHER_ARIA_256_CFB128,
+ MBEDTLS_MODE_CFB,
+ 256,
+ "ARIA-256-CFB128",
+ 16,
+ 0,
+ 16,
+ &aria_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static const mbedtls_cipher_info_t aria_128_ctr_info = {
+ MBEDTLS_CIPHER_ARIA_128_CTR,
+ MBEDTLS_MODE_CTR,
+ 128,
+ "ARIA-128-CTR",
+ 16,
+ 0,
+ 16,
+ &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_ctr_info = {
+ MBEDTLS_CIPHER_ARIA_192_CTR,
+ MBEDTLS_MODE_CTR,
+ 192,
+ "ARIA-192-CTR",
+ 16,
+ 0,
+ 16,
+ &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_ctr_info = {
+ MBEDTLS_CIPHER_ARIA_256_CTR,
+ MBEDTLS_MODE_CTR,
+ 256,
+ "ARIA-256-CTR",
+ 16,
+ 0,
+ 16,
+ &aria_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_GCM_C)
+static int gcm_aria_setkey_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA,
+ key, key_bitlen );
+}
+
+static const mbedtls_cipher_base_t gcm_aria_info = {
+ MBEDTLS_CIPHER_ID_ARIA,
+ NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ NULL,
+#endif
+ gcm_aria_setkey_wrap,
+ gcm_aria_setkey_wrap,
+ gcm_ctx_alloc,
+ gcm_ctx_free,
+};
+
+static const mbedtls_cipher_info_t aria_128_gcm_info = {
+ MBEDTLS_CIPHER_ARIA_128_GCM,
+ MBEDTLS_MODE_GCM,
+ 128,
+ "ARIA-128-GCM",
+ 12,
+ MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+ 16,
+ &gcm_aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_gcm_info = {
+ MBEDTLS_CIPHER_ARIA_192_GCM,
+ MBEDTLS_MODE_GCM,
+ 192,
+ "ARIA-192-GCM",
+ 12,
+ MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+ 16,
+ &gcm_aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_gcm_info = {
+ MBEDTLS_CIPHER_ARIA_256_GCM,
+ MBEDTLS_MODE_GCM,
+ 256,
+ "ARIA-256-GCM",
+ 12,
+ MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+ 16,
+ &gcm_aria_info
+};
+#endif /* MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_CCM_C)
+static int ccm_aria_setkey_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA,
+ key, key_bitlen );
+}
+
+static const mbedtls_cipher_base_t ccm_aria_info = {
+ MBEDTLS_CIPHER_ID_ARIA,
+ NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ NULL,
+#endif
+ ccm_aria_setkey_wrap,
+ ccm_aria_setkey_wrap,
+ ccm_ctx_alloc,
+ ccm_ctx_free,
+};
+
+static const mbedtls_cipher_info_t aria_128_ccm_info = {
+ MBEDTLS_CIPHER_ARIA_128_CCM,
+ MBEDTLS_MODE_CCM,
+ 128,
+ "ARIA-128-CCM",
+ 12,
+ MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+ 16,
+ &ccm_aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_ccm_info = {
+ MBEDTLS_CIPHER_ARIA_192_CCM,
+ MBEDTLS_MODE_CCM,
+ 192,
+ "ARIA-192-CCM",
+ 12,
+ MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+ 16,
+ &ccm_aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_ccm_info = {
+ MBEDTLS_CIPHER_ARIA_256_CCM,
+ MBEDTLS_MODE_CCM,
+ 256,
+ "ARIA-256-CCM",
+ 12,
+ MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+ 16,
+ &ccm_aria_info
+};
+#endif /* MBEDTLS_CCM_C */
+
+#endif /* MBEDTLS_ARIA_C */
+
+#if defined(MBEDTLS_DES_C)
+
+static int des_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
+ const unsigned char *input, unsigned char *output )
+{
+ ((void) operation);
+ return mbedtls_des_crypt_ecb( (mbedtls_des_context *) ctx, input, output );
+}
+
+static int des3_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
+ const unsigned char *input, unsigned char *output )
+{
+ ((void) operation);
+ return mbedtls_des3_crypt_ecb( (mbedtls_des3_context *) ctx, input, output );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static int des_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length,
+ unsigned char *iv, const unsigned char *input, unsigned char *output )
+{
+ return mbedtls_des_crypt_cbc( (mbedtls_des_context *) ctx, operation, length, iv, input,
+ output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static int des3_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length,
+ unsigned char *iv, const unsigned char *input, unsigned char *output )
+{
+ return mbedtls_des3_crypt_cbc( (mbedtls_des3_context *) ctx, operation, length, iv, input,
+ output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+static int des_setkey_dec_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ ((void) key_bitlen);
+
+ return mbedtls_des_setkey_dec( (mbedtls_des_context *) ctx, key );
+}
+
+static int des_setkey_enc_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ ((void) key_bitlen);
+
+ return mbedtls_des_setkey_enc( (mbedtls_des_context *) ctx, key );
+}
+
+static int des3_set2key_dec_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ ((void) key_bitlen);
+
+ return mbedtls_des3_set2key_dec( (mbedtls_des3_context *) ctx, key );
+}
+
+static int des3_set2key_enc_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ ((void) key_bitlen);
+
+ return mbedtls_des3_set2key_enc( (mbedtls_des3_context *) ctx, key );
+}
+
+static int des3_set3key_dec_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ ((void) key_bitlen);
+
+ return mbedtls_des3_set3key_dec( (mbedtls_des3_context *) ctx, key );
+}
+
+static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ ((void) key_bitlen);
+
+ return mbedtls_des3_set3key_enc( (mbedtls_des3_context *) ctx, key );
+}
+
+static void * des_ctx_alloc( void )
+{
+ mbedtls_des_context *des = mbedtls_calloc( 1, sizeof( mbedtls_des_context ) );
+
+ if( des == NULL )
+ return( NULL );
+
+ mbedtls_des_init( des );
+
+ return( des );
+}
+
+static void des_ctx_free( void *ctx )
+{
+ mbedtls_des_free( (mbedtls_des_context *) ctx );
+ mbedtls_free( ctx );
+}
+
+static void * des3_ctx_alloc( void )
+{
+ mbedtls_des3_context *des3;
+ des3 = mbedtls_calloc( 1, sizeof( mbedtls_des3_context ) );
+
+ if( des3 == NULL )
+ return( NULL );
+
+ mbedtls_des3_init( des3 );
+
+ return( des3 );
+}
+
+static void des3_ctx_free( void *ctx )
+{
+ mbedtls_des3_free( (mbedtls_des3_context *) ctx );
+ mbedtls_free( ctx );
+}
+
+static const mbedtls_cipher_base_t des_info = {
+ MBEDTLS_CIPHER_ID_DES,
+ des_crypt_ecb_wrap,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ des_crypt_cbc_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ NULL,
+#endif
+ des_setkey_enc_wrap,
+ des_setkey_dec_wrap,
+ des_ctx_alloc,
+ des_ctx_free
+};
+
+static const mbedtls_cipher_info_t des_ecb_info = {
+ MBEDTLS_CIPHER_DES_ECB,
+ MBEDTLS_MODE_ECB,
+ MBEDTLS_KEY_LENGTH_DES,
+ "DES-ECB",
+ 8,
+ 0,
+ 8,
+ &des_info
+};
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const mbedtls_cipher_info_t des_cbc_info = {
+ MBEDTLS_CIPHER_DES_CBC,
+ MBEDTLS_MODE_CBC,
+ MBEDTLS_KEY_LENGTH_DES,
+ "DES-CBC",
+ 8,
+ 0,
+ 8,
+ &des_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+static const mbedtls_cipher_base_t des_ede_info = {
+ MBEDTLS_CIPHER_ID_DES,
+ des3_crypt_ecb_wrap,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ des3_crypt_cbc_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ NULL,
+#endif
+ des3_set2key_enc_wrap,
+ des3_set2key_dec_wrap,
+ des3_ctx_alloc,
+ des3_ctx_free
+};
+
+static const mbedtls_cipher_info_t des_ede_ecb_info = {
+ MBEDTLS_CIPHER_DES_EDE_ECB,
+ MBEDTLS_MODE_ECB,
+ MBEDTLS_KEY_LENGTH_DES_EDE,
+ "DES-EDE-ECB",
+ 8,
+ 0,
+ 8,
+ &des_ede_info
+};
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const mbedtls_cipher_info_t des_ede_cbc_info = {
+ MBEDTLS_CIPHER_DES_EDE_CBC,
+ MBEDTLS_MODE_CBC,
+ MBEDTLS_KEY_LENGTH_DES_EDE,
+ "DES-EDE-CBC",
+ 8,
+ 0,
+ 8,
+ &des_ede_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+static const mbedtls_cipher_base_t des_ede3_info = {
+ MBEDTLS_CIPHER_ID_3DES,
+ des3_crypt_ecb_wrap,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ des3_crypt_cbc_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ NULL,
+#endif
+ des3_set3key_enc_wrap,
+ des3_set3key_dec_wrap,
+ des3_ctx_alloc,
+ des3_ctx_free
+};
+
+static const mbedtls_cipher_info_t des_ede3_ecb_info = {
+ MBEDTLS_CIPHER_DES_EDE3_ECB,
+ MBEDTLS_MODE_ECB,
+ MBEDTLS_KEY_LENGTH_DES_EDE3,
+ "DES-EDE3-ECB",
+ 8,
+ 0,
+ 8,
+ &des_ede3_info
+};
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const mbedtls_cipher_info_t des_ede3_cbc_info = {
+ MBEDTLS_CIPHER_DES_EDE3_CBC,
+ MBEDTLS_MODE_CBC,
+ MBEDTLS_KEY_LENGTH_DES_EDE3,
+ "DES-EDE3-CBC",
+ 8,
+ 0,
+ 8,
+ &des_ede3_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_BLOWFISH_C)
+
+static int blowfish_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
+ const unsigned char *input, unsigned char *output )
+{
+ return mbedtls_blowfish_crypt_ecb( (mbedtls_blowfish_context *) ctx, operation, input,
+ output );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static int blowfish_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation,
+ size_t length, unsigned char *iv, const unsigned char *input,
+ unsigned char *output )
+{
+ return mbedtls_blowfish_crypt_cbc( (mbedtls_blowfish_context *) ctx, operation, length, iv,
+ input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static int blowfish_crypt_cfb64_wrap( void *ctx, mbedtls_operation_t operation,
+ size_t length, size_t *iv_off, unsigned char *iv,
+ const unsigned char *input, unsigned char *output )
+{
+ return mbedtls_blowfish_crypt_cfb64( (mbedtls_blowfish_context *) ctx, operation, length,
+ iv_off, iv, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
+ unsigned char *nonce_counter, unsigned char *stream_block,
+ const unsigned char *input, unsigned char *output )
+{
+ return mbedtls_blowfish_crypt_ctr( (mbedtls_blowfish_context *) ctx, length, nc_off,
+ nonce_counter, stream_block, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+static int blowfish_setkey_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_blowfish_setkey( (mbedtls_blowfish_context *) ctx, key, key_bitlen );
+}
+
+static void * blowfish_ctx_alloc( void )
+{
+ mbedtls_blowfish_context *ctx;
+ ctx = mbedtls_calloc( 1, sizeof( mbedtls_blowfish_context ) );
+
+ if( ctx == NULL )
+ return( NULL );
+
+ mbedtls_blowfish_init( ctx );
+
+ return( ctx );
+}
+
+static void blowfish_ctx_free( void *ctx )
+{
+ mbedtls_blowfish_free( (mbedtls_blowfish_context *) ctx );
+ mbedtls_free( ctx );
+}
+
+static const mbedtls_cipher_base_t blowfish_info = {
+ MBEDTLS_CIPHER_ID_BLOWFISH,
+ blowfish_crypt_ecb_wrap,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ blowfish_crypt_cbc_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ blowfish_crypt_cfb64_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ blowfish_crypt_ctr_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ NULL,
+#endif
+ blowfish_setkey_wrap,
+ blowfish_setkey_wrap,
+ blowfish_ctx_alloc,
+ blowfish_ctx_free
+};
+
+static const mbedtls_cipher_info_t blowfish_ecb_info = {
+ MBEDTLS_CIPHER_BLOWFISH_ECB,
+ MBEDTLS_MODE_ECB,
+ 128,
+ "BLOWFISH-ECB",
+ 8,
+ MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
+ 8,
+ &blowfish_info
+};
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const mbedtls_cipher_info_t blowfish_cbc_info = {
+ MBEDTLS_CIPHER_BLOWFISH_CBC,
+ MBEDTLS_MODE_CBC,
+ 128,
+ "BLOWFISH-CBC",
+ 8,
+ MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
+ 8,
+ &blowfish_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static const mbedtls_cipher_info_t blowfish_cfb64_info = {
+ MBEDTLS_CIPHER_BLOWFISH_CFB64,
+ MBEDTLS_MODE_CFB,
+ 128,
+ "BLOWFISH-CFB64",
+ 8,
+ MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
+ 8,
+ &blowfish_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static const mbedtls_cipher_info_t blowfish_ctr_info = {
+ MBEDTLS_CIPHER_BLOWFISH_CTR,
+ MBEDTLS_MODE_CTR,
+ 128,
+ "BLOWFISH-CTR",
+ 8,
+ MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
+ 8,
+ &blowfish_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+#endif /* MBEDTLS_BLOWFISH_C */
+
+#if defined(MBEDTLS_ARC4_C)
+static int arc4_crypt_stream_wrap( void *ctx, size_t length,
+ const unsigned char *input,
+ unsigned char *output )
+{
+ return( mbedtls_arc4_crypt( (mbedtls_arc4_context *) ctx, length, input, output ) );
+}
+
+static int arc4_setkey_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ /* we get key_bitlen in bits, arc4 expects it in bytes */
+ if( key_bitlen % 8 != 0 )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ mbedtls_arc4_setup( (mbedtls_arc4_context *) ctx, key, key_bitlen / 8 );
+ return( 0 );
+}
+
+static void * arc4_ctx_alloc( void )
+{
+ mbedtls_arc4_context *ctx;
+ ctx = mbedtls_calloc( 1, sizeof( mbedtls_arc4_context ) );
+
+ if( ctx == NULL )
+ return( NULL );
+
+ mbedtls_arc4_init( ctx );
+
+ return( ctx );
+}
+
+static void arc4_ctx_free( void *ctx )
+{
+ mbedtls_arc4_free( (mbedtls_arc4_context *) ctx );
+ mbedtls_free( ctx );
+}
+
+static const mbedtls_cipher_base_t arc4_base_info = {
+ MBEDTLS_CIPHER_ID_ARC4,
+ NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ arc4_crypt_stream_wrap,
+#endif
+ arc4_setkey_wrap,
+ arc4_setkey_wrap,
+ arc4_ctx_alloc,
+ arc4_ctx_free
+};
+
+static const mbedtls_cipher_info_t arc4_128_info = {
+ MBEDTLS_CIPHER_ARC4_128,
+ MBEDTLS_MODE_STREAM,
+ 128,
+ "ARC4-128",
+ 0,
+ 0,
+ 1,
+ &arc4_base_info
+};
+#endif /* MBEDTLS_ARC4_C */
+
+#if defined(MBEDTLS_CHACHA20_C)
+
+static int chacha20_setkey_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ if( key_bitlen != 256U )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ if ( 0 != mbedtls_chacha20_setkey( (mbedtls_chacha20_context*)ctx, key ) )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ return( 0 );
+}
+
+static int chacha20_stream_wrap( void *ctx, size_t length,
+ const unsigned char *input,
+ unsigned char *output )
+{
+ int ret;
+
+ ret = mbedtls_chacha20_update( ctx, length, input, output );
+ if( ret == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ return( ret );
+}
+
+static void * chacha20_ctx_alloc( void )
+{
+ mbedtls_chacha20_context *ctx;
+ ctx = mbedtls_calloc( 1, sizeof( mbedtls_chacha20_context ) );
+
+ if( ctx == NULL )
+ return( NULL );
+
+ mbedtls_chacha20_init( ctx );
+
+ return( ctx );
+}
+
+static void chacha20_ctx_free( void *ctx )
+{
+ mbedtls_chacha20_free( (mbedtls_chacha20_context *) ctx );
+ mbedtls_free( ctx );
+}
+
+static const mbedtls_cipher_base_t chacha20_base_info = {
+ MBEDTLS_CIPHER_ID_CHACHA20,
+ NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ chacha20_stream_wrap,
+#endif
+ chacha20_setkey_wrap,
+ chacha20_setkey_wrap,
+ chacha20_ctx_alloc,
+ chacha20_ctx_free
+};
+static const mbedtls_cipher_info_t chacha20_info = {
+ MBEDTLS_CIPHER_CHACHA20,
+ MBEDTLS_MODE_STREAM,
+ 256,
+ "CHACHA20",
+ 12,
+ 0,
+ 1,
+ &chacha20_base_info
+};
+#endif /* MBEDTLS_CHACHA20_C */
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+
+static int chachapoly_setkey_wrap( void *ctx,
+ const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ if( key_bitlen != 256U )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ if ( 0 != mbedtls_chachapoly_setkey( (mbedtls_chachapoly_context*)ctx, key ) )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ return( 0 );
+}
+
+static void * chachapoly_ctx_alloc( void )
+{
+ mbedtls_chachapoly_context *ctx;
+ ctx = mbedtls_calloc( 1, sizeof( mbedtls_chachapoly_context ) );
+
+ if( ctx == NULL )
+ return( NULL );
+
+ mbedtls_chachapoly_init( ctx );
+
+ return( ctx );
+}
+
+static void chachapoly_ctx_free( void *ctx )
+{
+ mbedtls_chachapoly_free( (mbedtls_chachapoly_context *) ctx );
+ mbedtls_free( ctx );
+}
+
+static const mbedtls_cipher_base_t chachapoly_base_info = {
+ MBEDTLS_CIPHER_ID_CHACHA20,
+ NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ NULL,
+#endif
+ chachapoly_setkey_wrap,
+ chachapoly_setkey_wrap,
+ chachapoly_ctx_alloc,
+ chachapoly_ctx_free
+};
+static const mbedtls_cipher_info_t chachapoly_info = {
+ MBEDTLS_CIPHER_CHACHA20_POLY1305,
+ MBEDTLS_MODE_CHACHAPOLY,
+ 256,
+ "CHACHA20-POLY1305",
+ 12,
+ 0,
+ 1,
+ &chachapoly_base_info
+};
+#endif /* MBEDTLS_CHACHAPOLY_C */
+
+#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
+static int null_crypt_stream( void *ctx, size_t length,
+ const unsigned char *input,
+ unsigned char *output )
+{
+ ((void) ctx);
+ memmove( output, input, length );
+ return( 0 );
+}
+
+static int null_setkey( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ ((void) ctx);
+ ((void) key);
+ ((void) key_bitlen);
+
+ return( 0 );
+}
+
+static void * null_ctx_alloc( void )
+{
+ return( (void *) 1 );
+}
+
+static void null_ctx_free( void *ctx )
+{
+ ((void) ctx);
+}
+
+static const mbedtls_cipher_base_t null_base_info = {
+ MBEDTLS_CIPHER_ID_NULL,
+ NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ null_crypt_stream,
+#endif
+ null_setkey,
+ null_setkey,
+ null_ctx_alloc,
+ null_ctx_free
+};
+
+static const mbedtls_cipher_info_t null_cipher_info = {
+ MBEDTLS_CIPHER_NULL,
+ MBEDTLS_MODE_STREAM,
+ 0,
+ "NULL",
+ 0,
+ 0,
+ 1,
+ &null_base_info
+};
+#endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */
+
+#if defined(MBEDTLS_NIST_KW_C)
+static void *kw_ctx_alloc( void )
+{
+ void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_nist_kw_context ) );
+
+ if( ctx != NULL )
+ mbedtls_nist_kw_init( (mbedtls_nist_kw_context *) ctx );
+
+ return( ctx );
+}
+
+static void kw_ctx_free( void *ctx )
+{
+ mbedtls_nist_kw_free( ctx );
+ mbedtls_free( ctx );
+}
+
+static int kw_aes_setkey_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_nist_kw_setkey( (mbedtls_nist_kw_context *) ctx,
+ MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 1 );
+}
+
+static int kw_aes_setkey_unwrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_nist_kw_setkey( (mbedtls_nist_kw_context *) ctx,
+ MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 0 );
+}
+
+static const mbedtls_cipher_base_t kw_aes_info = {
+ MBEDTLS_CIPHER_ID_AES,
+ NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ NULL,
+#endif
+ kw_aes_setkey_wrap,
+ kw_aes_setkey_unwrap,
+ kw_ctx_alloc,
+ kw_ctx_free,
+};
+
+static const mbedtls_cipher_info_t aes_128_nist_kw_info = {
+ MBEDTLS_CIPHER_AES_128_KW,
+ MBEDTLS_MODE_KW,
+ 128,
+ "AES-128-KW",
+ 0,
+ 0,
+ 16,
+ &kw_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_nist_kw_info = {
+ MBEDTLS_CIPHER_AES_192_KW,
+ MBEDTLS_MODE_KW,
+ 192,
+ "AES-192-KW",
+ 0,
+ 0,
+ 16,
+ &kw_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_nist_kw_info = {
+ MBEDTLS_CIPHER_AES_256_KW,
+ MBEDTLS_MODE_KW,
+ 256,
+ "AES-256-KW",
+ 0,
+ 0,
+ 16,
+ &kw_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_128_nist_kwp_info = {
+ MBEDTLS_CIPHER_AES_128_KWP,
+ MBEDTLS_MODE_KWP,
+ 128,
+ "AES-128-KWP",
+ 0,
+ 0,
+ 16,
+ &kw_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_nist_kwp_info = {
+ MBEDTLS_CIPHER_AES_192_KWP,
+ MBEDTLS_MODE_KWP,
+ 192,
+ "AES-192-KWP",
+ 0,
+ 0,
+ 16,
+ &kw_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_nist_kwp_info = {
+ MBEDTLS_CIPHER_AES_256_KWP,
+ MBEDTLS_MODE_KWP,
+ 256,
+ "AES-256-KWP",
+ 0,
+ 0,
+ 16,
+ &kw_aes_info
+};
+#endif /* MBEDTLS_NIST_KW_C */
+
+const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] =
+{
+#if defined(MBEDTLS_AES_C)
+ { MBEDTLS_CIPHER_AES_128_ECB, &aes_128_ecb_info },
+ { MBEDTLS_CIPHER_AES_192_ECB, &aes_192_ecb_info },
+ { MBEDTLS_CIPHER_AES_256_ECB, &aes_256_ecb_info },
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ { MBEDTLS_CIPHER_AES_128_CBC, &aes_128_cbc_info },
+ { MBEDTLS_CIPHER_AES_192_CBC, &aes_192_cbc_info },
+ { MBEDTLS_CIPHER_AES_256_CBC, &aes_256_cbc_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ { MBEDTLS_CIPHER_AES_128_CFB128, &aes_128_cfb128_info },
+ { MBEDTLS_CIPHER_AES_192_CFB128, &aes_192_cfb128_info },
+ { MBEDTLS_CIPHER_AES_256_CFB128, &aes_256_cfb128_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ { MBEDTLS_CIPHER_AES_128_OFB, &aes_128_ofb_info },
+ { MBEDTLS_CIPHER_AES_192_OFB, &aes_192_ofb_info },
+ { MBEDTLS_CIPHER_AES_256_OFB, &aes_256_ofb_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ { MBEDTLS_CIPHER_AES_128_CTR, &aes_128_ctr_info },
+ { MBEDTLS_CIPHER_AES_192_CTR, &aes_192_ctr_info },
+ { MBEDTLS_CIPHER_AES_256_CTR, &aes_256_ctr_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ { MBEDTLS_CIPHER_AES_128_XTS, &aes_128_xts_info },
+ { MBEDTLS_CIPHER_AES_256_XTS, &aes_256_xts_info },
+#endif
+#if defined(MBEDTLS_GCM_C)
+ { MBEDTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info },
+ { MBEDTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info },
+ { MBEDTLS_CIPHER_AES_256_GCM, &aes_256_gcm_info },
+#endif
+#if defined(MBEDTLS_CCM_C)
+ { MBEDTLS_CIPHER_AES_128_CCM, &aes_128_ccm_info },
+ { MBEDTLS_CIPHER_AES_192_CCM, &aes_192_ccm_info },
+ { MBEDTLS_CIPHER_AES_256_CCM, &aes_256_ccm_info },
+#endif
+#endif /* MBEDTLS_AES_C */
+
+#if defined(MBEDTLS_ARC4_C)
+ { MBEDTLS_CIPHER_ARC4_128, &arc4_128_info },
+#endif
+
+#if defined(MBEDTLS_BLOWFISH_C)
+ { MBEDTLS_CIPHER_BLOWFISH_ECB, &blowfish_ecb_info },
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ { MBEDTLS_CIPHER_BLOWFISH_CBC, &blowfish_cbc_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ { MBEDTLS_CIPHER_BLOWFISH_CFB64, &blowfish_cfb64_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ { MBEDTLS_CIPHER_BLOWFISH_CTR, &blowfish_ctr_info },
+#endif
+#endif /* MBEDTLS_BLOWFISH_C */
+
+#if defined(MBEDTLS_CAMELLIA_C)
+ { MBEDTLS_CIPHER_CAMELLIA_128_ECB, &camellia_128_ecb_info },
+ { MBEDTLS_CIPHER_CAMELLIA_192_ECB, &camellia_192_ecb_info },
+ { MBEDTLS_CIPHER_CAMELLIA_256_ECB, &camellia_256_ecb_info },
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ { MBEDTLS_CIPHER_CAMELLIA_128_CBC, &camellia_128_cbc_info },
+ { MBEDTLS_CIPHER_CAMELLIA_192_CBC, &camellia_192_cbc_info },
+ { MBEDTLS_CIPHER_CAMELLIA_256_CBC, &camellia_256_cbc_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ { MBEDTLS_CIPHER_CAMELLIA_128_CFB128, &camellia_128_cfb128_info },
+ { MBEDTLS_CIPHER_CAMELLIA_192_CFB128, &camellia_192_cfb128_info },
+ { MBEDTLS_CIPHER_CAMELLIA_256_CFB128, &camellia_256_cfb128_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ { MBEDTLS_CIPHER_CAMELLIA_128_CTR, &camellia_128_ctr_info },
+ { MBEDTLS_CIPHER_CAMELLIA_192_CTR, &camellia_192_ctr_info },
+ { MBEDTLS_CIPHER_CAMELLIA_256_CTR, &camellia_256_ctr_info },
+#endif
+#if defined(MBEDTLS_GCM_C)
+ { MBEDTLS_CIPHER_CAMELLIA_128_GCM, &camellia_128_gcm_info },
+ { MBEDTLS_CIPHER_CAMELLIA_192_GCM, &camellia_192_gcm_info },
+ { MBEDTLS_CIPHER_CAMELLIA_256_GCM, &camellia_256_gcm_info },
+#endif
+#if defined(MBEDTLS_CCM_C)
+ { MBEDTLS_CIPHER_CAMELLIA_128_CCM, &camellia_128_ccm_info },
+ { MBEDTLS_CIPHER_CAMELLIA_192_CCM, &camellia_192_ccm_info },
+ { MBEDTLS_CIPHER_CAMELLIA_256_CCM, &camellia_256_ccm_info },
+#endif
+#endif /* MBEDTLS_CAMELLIA_C */
+
+#if defined(MBEDTLS_ARIA_C)
+ { MBEDTLS_CIPHER_ARIA_128_ECB, &aria_128_ecb_info },
+ { MBEDTLS_CIPHER_ARIA_192_ECB, &aria_192_ecb_info },
+ { MBEDTLS_CIPHER_ARIA_256_ECB, &aria_256_ecb_info },
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ { MBEDTLS_CIPHER_ARIA_128_CBC, &aria_128_cbc_info },
+ { MBEDTLS_CIPHER_ARIA_192_CBC, &aria_192_cbc_info },
+ { MBEDTLS_CIPHER_ARIA_256_CBC, &aria_256_cbc_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ { MBEDTLS_CIPHER_ARIA_128_CFB128, &aria_128_cfb128_info },
+ { MBEDTLS_CIPHER_ARIA_192_CFB128, &aria_192_cfb128_info },
+ { MBEDTLS_CIPHER_ARIA_256_CFB128, &aria_256_cfb128_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ { MBEDTLS_CIPHER_ARIA_128_CTR, &aria_128_ctr_info },
+ { MBEDTLS_CIPHER_ARIA_192_CTR, &aria_192_ctr_info },
+ { MBEDTLS_CIPHER_ARIA_256_CTR, &aria_256_ctr_info },
+#endif
+#if defined(MBEDTLS_GCM_C)
+ { MBEDTLS_CIPHER_ARIA_128_GCM, &aria_128_gcm_info },
+ { MBEDTLS_CIPHER_ARIA_192_GCM, &aria_192_gcm_info },
+ { MBEDTLS_CIPHER_ARIA_256_GCM, &aria_256_gcm_info },
+#endif
+#if defined(MBEDTLS_CCM_C)
+ { MBEDTLS_CIPHER_ARIA_128_CCM, &aria_128_ccm_info },
+ { MBEDTLS_CIPHER_ARIA_192_CCM, &aria_192_ccm_info },
+ { MBEDTLS_CIPHER_ARIA_256_CCM, &aria_256_ccm_info },
+#endif
+#endif /* MBEDTLS_ARIA_C */
+
+#if defined(MBEDTLS_DES_C)
+ { MBEDTLS_CIPHER_DES_ECB, &des_ecb_info },
+ { MBEDTLS_CIPHER_DES_EDE_ECB, &des_ede_ecb_info },
+ { MBEDTLS_CIPHER_DES_EDE3_ECB, &des_ede3_ecb_info },
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ { MBEDTLS_CIPHER_DES_CBC, &des_cbc_info },
+ { MBEDTLS_CIPHER_DES_EDE_CBC, &des_ede_cbc_info },
+ { MBEDTLS_CIPHER_DES_EDE3_CBC, &des_ede3_cbc_info },
+#endif
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_CHACHA20_C)
+ { MBEDTLS_CIPHER_CHACHA20, &chacha20_info },
+#endif
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+ { MBEDTLS_CIPHER_CHACHA20_POLY1305, &chachapoly_info },
+#endif
+
+#if defined(MBEDTLS_NIST_KW_C)
+ { MBEDTLS_CIPHER_AES_128_KW, &aes_128_nist_kw_info },
+ { MBEDTLS_CIPHER_AES_192_KW, &aes_192_nist_kw_info },
+ { MBEDTLS_CIPHER_AES_256_KW, &aes_256_nist_kw_info },
+ { MBEDTLS_CIPHER_AES_128_KWP, &aes_128_nist_kwp_info },
+ { MBEDTLS_CIPHER_AES_192_KWP, &aes_192_nist_kwp_info },
+ { MBEDTLS_CIPHER_AES_256_KWP, &aes_256_nist_kwp_info },
+#endif
+
+#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
+ { MBEDTLS_CIPHER_NULL, &null_cipher_info },
+#endif /* MBEDTLS_CIPHER_NULL_CIPHER */
+
+ { MBEDTLS_CIPHER_NONE, NULL }
+};
+
+#define NUM_CIPHERS ( sizeof(mbedtls_cipher_definitions) / \
+ sizeof(mbedtls_cipher_definitions[0]) )
+int mbedtls_cipher_supported[NUM_CIPHERS];
+
+#endif /* MBEDTLS_CIPHER_C */
diff --git a/templates/blackpill/Src/config.h b/templates/blackpill/Src/config.h
new file mode 100644
index 0000000..953afea
--- /dev/null
+++ b/templates/blackpill/Src/config.h
@@ -0,0 +1,5 @@
+#pragma once
+#define MBEDTLS_GCM_C
+#define MBEDTLS_CIPHER_C
+#define MBEDTLS_AES_C
+#define MBEDTLS_SELF_TEST
diff --git a/templates/blackpill/Src/gcm.c b/templates/blackpill/Src/gcm.c
new file mode 100644
index 0000000..d3af74c
--- /dev/null
+++ b/templates/blackpill/Src/gcm.c
@@ -0,0 +1,1020 @@
+/*
+ * NIST SP800-38D compliant GCM implementation
+ *
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
+ *
+ * See also:
+ * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
+ *
+ * We use the algorithm described as Shoup's method with 4-bit tables in
+ * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_GCM_C)
+
+#include "gcm.h"
+#include "platform_util.h"
+
+#include
+
+#if defined(MBEDTLS_AESNI_C)
+#include "mbedtls/aesni.h"
+#endif
+
+#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
+#include "aes.h"
+#include "platform.h"
+#if !defined(MBEDTLS_PLATFORM_C)
+#include
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
+
+#if !defined(MBEDTLS_GCM_ALT)
+
+/* Parameter validation macros */
+#define GCM_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
+#define GCM_VALIDATE( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE( cond )
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i) \
+{ \
+ (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
+ | ( (uint32_t) (b)[(i) + 1] << 16 ) \
+ | ( (uint32_t) (b)[(i) + 2] << 8 ) \
+ | ( (uint32_t) (b)[(i) + 3] ); \
+}
+#endif
+
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_BE(n,b,i) \
+{ \
+ (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
+ (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
+ (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
+ (b)[(i) + 3] = (unsigned char) ( (n) ); \
+}
+#endif
+
+/*
+ * Initialize a context
+ */
+void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
+{
+ GCM_VALIDATE( ctx != NULL );
+ memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
+}
+
+/*
+ * Precompute small multiples of H, that is set
+ * HH[i] || HL[i] = H times i,
+ * where i is seen as a field element as in [MGV], ie high-order bits
+ * correspond to low powers of P. The result is stored in the same way, that
+ * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
+ * corresponds to P^127.
+ */
+static int gcm_gen_table( mbedtls_gcm_context *ctx )
+{
+ int ret, i, j;
+ uint64_t hi, lo;
+ uint64_t vl, vh;
+ unsigned char h[16];
+ size_t olen = 0;
+
+ memset( h, 0, 16 );
+ if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
+ return( ret );
+
+ /* pack h as two 64-bits ints, big-endian */
+ GET_UINT32_BE( hi, h, 0 );
+ GET_UINT32_BE( lo, h, 4 );
+ vh = (uint64_t) hi << 32 | lo;
+
+ GET_UINT32_BE( hi, h, 8 );
+ GET_UINT32_BE( lo, h, 12 );
+ vl = (uint64_t) hi << 32 | lo;
+
+ /* 8 = 1000 corresponds to 1 in GF(2^128) */
+ ctx->HL[8] = vl;
+ ctx->HH[8] = vh;
+
+#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
+ /* With CLMUL support, we need only h, not the rest of the table */
+ if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
+ return( 0 );
+#endif
+
+ /* 0 corresponds to 0 in GF(2^128) */
+ ctx->HH[0] = 0;
+ ctx->HL[0] = 0;
+
+ for( i = 4; i > 0; i >>= 1 )
+ {
+ uint32_t T = ( vl & 1 ) * 0xe1000000U;
+ vl = ( vh << 63 ) | ( vl >> 1 );
+ vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
+
+ ctx->HL[i] = vl;
+ ctx->HH[i] = vh;
+ }
+
+ for( i = 2; i <= 8; i *= 2 )
+ {
+ uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
+ vh = *HiH;
+ vl = *HiL;
+ for( j = 1; j < i; j++ )
+ {
+ HiH[j] = vh ^ ctx->HH[j];
+ HiL[j] = vl ^ ctx->HL[j];
+ }
+ }
+
+ return( 0 );
+}
+
+int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
+ mbedtls_cipher_id_t cipher,
+ const unsigned char *key,
+ unsigned int keybits )
+{
+ int ret;
+ const mbedtls_cipher_info_t *cipher_info;
+
+ GCM_VALIDATE_RET( ctx != NULL );
+ GCM_VALIDATE_RET( key != NULL );
+ GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
+
+ cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
+ MBEDTLS_MODE_ECB );
+ if( cipher_info == NULL )
+ return( MBEDTLS_ERR_GCM_BAD_INPUT );
+
+ if( cipher_info->block_size != 16 )
+ return( MBEDTLS_ERR_GCM_BAD_INPUT );
+
+ mbedtls_cipher_free( &ctx->cipher_ctx );
+
+ if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
+ return( ret );
+
+ if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
+ MBEDTLS_ENCRYPT ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ if( ( ret = gcm_gen_table( ctx ) ) != 0 )
+ return( ret );
+
+ return( 0 );
+}
+
+/*
+ * Shoup's method for multiplication use this table with
+ * last4[x] = x times P^128
+ * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
+ */
+static const uint64_t last4[16] =
+{
+ 0x0000, 0x1c20, 0x3840, 0x2460,
+ 0x7080, 0x6ca0, 0x48c0, 0x54e0,
+ 0xe100, 0xfd20, 0xd940, 0xc560,
+ 0x9180, 0x8da0, 0xa9c0, 0xb5e0
+};
+
+/*
+ * Sets output to x times H using the precomputed tables.
+ * x and output are seen as elements of GF(2^128) as in [MGV].
+ */
+static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
+ unsigned char output[16] )
+{
+ int i = 0;
+ unsigned char lo, hi, rem;
+ uint64_t zh, zl;
+
+#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
+ if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
+ unsigned char h[16];
+
+ PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
+ PUT_UINT32_BE( ctx->HH[8], h, 4 );
+ PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
+ PUT_UINT32_BE( ctx->HL[8], h, 12 );
+
+ mbedtls_aesni_gcm_mult( output, x, h );
+ return;
+ }
+#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
+
+ lo = x[15] & 0xf;
+
+ zh = ctx->HH[lo];
+ zl = ctx->HL[lo];
+
+ for( i = 15; i >= 0; i-- )
+ {
+ lo = x[i] & 0xf;
+ hi = x[i] >> 4;
+
+ if( i != 15 )
+ {
+ rem = (unsigned char) zl & 0xf;
+ zl = ( zh << 60 ) | ( zl >> 4 );
+ zh = ( zh >> 4 );
+ zh ^= (uint64_t) last4[rem] << 48;
+ zh ^= ctx->HH[lo];
+ zl ^= ctx->HL[lo];
+
+ }
+
+ rem = (unsigned char) zl & 0xf;
+ zl = ( zh << 60 ) | ( zl >> 4 );
+ zh = ( zh >> 4 );
+ zh ^= (uint64_t) last4[rem] << 48;
+ zh ^= ctx->HH[hi];
+ zl ^= ctx->HL[hi];
+ }
+
+ PUT_UINT32_BE( zh >> 32, output, 0 );
+ PUT_UINT32_BE( zh, output, 4 );
+ PUT_UINT32_BE( zl >> 32, output, 8 );
+ PUT_UINT32_BE( zl, output, 12 );
+}
+
+int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
+ int mode,
+ const unsigned char *iv,
+ size_t iv_len,
+ const unsigned char *add,
+ size_t add_len )
+{
+ int ret;
+ unsigned char work_buf[16];
+ size_t i;
+ const unsigned char *p;
+ size_t use_len, olen = 0;
+
+ GCM_VALIDATE_RET( ctx != NULL );
+ GCM_VALIDATE_RET( iv != NULL );
+ GCM_VALIDATE_RET( add_len == 0 || add != NULL );
+
+ /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
+ /* IV is not allowed to be zero length */
+ if( iv_len == 0 ||
+ ( (uint64_t) iv_len ) >> 61 != 0 ||
+ ( (uint64_t) add_len ) >> 61 != 0 )
+ {
+ return( MBEDTLS_ERR_GCM_BAD_INPUT );
+ }
+
+ memset( ctx->y, 0x00, sizeof(ctx->y) );
+ memset( ctx->buf, 0x00, sizeof(ctx->buf) );
+
+ ctx->mode = mode;
+ ctx->len = 0;
+ ctx->add_len = 0;
+
+ if( iv_len == 12 )
+ {
+ memcpy( ctx->y, iv, iv_len );
+ ctx->y[15] = 1;
+ }
+ else
+ {
+ memset( work_buf, 0x00, 16 );
+ PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
+
+ p = iv;
+ while( iv_len > 0 )
+ {
+ use_len = ( iv_len < 16 ) ? iv_len : 16;
+
+ for( i = 0; i < use_len; i++ )
+ ctx->y[i] ^= p[i];
+
+ gcm_mult( ctx, ctx->y, ctx->y );
+
+ iv_len -= use_len;
+ p += use_len;
+ }
+
+ for( i = 0; i < 16; i++ )
+ ctx->y[i] ^= work_buf[i];
+
+ gcm_mult( ctx, ctx->y, ctx->y );
+ }
+
+ if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
+ ctx->base_ectr, &olen ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ ctx->add_len = add_len;
+ p = add;
+ while( add_len > 0 )
+ {
+ use_len = ( add_len < 16 ) ? add_len : 16;
+
+ for( i = 0; i < use_len; i++ )
+ ctx->buf[i] ^= p[i];
+
+ gcm_mult( ctx, ctx->buf, ctx->buf );
+
+ add_len -= use_len;
+ p += use_len;
+ }
+
+ return( 0 );
+}
+
+int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
+ size_t length,
+ const unsigned char *input,
+ unsigned char *output )
+{
+ int ret;
+ unsigned char ectr[16];
+ size_t i;
+ const unsigned char *p;
+ unsigned char *out_p = output;
+ size_t use_len, olen = 0;
+
+ GCM_VALIDATE_RET( ctx != NULL );
+ GCM_VALIDATE_RET( length == 0 || input != NULL );
+ GCM_VALIDATE_RET( length == 0 || output != NULL );
+
+ if( output > input && (size_t) ( output - input ) < length )
+ return( MBEDTLS_ERR_GCM_BAD_INPUT );
+
+ /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
+ * Also check for possible overflow */
+ if( ctx->len + length < ctx->len ||
+ (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
+ {
+ return( MBEDTLS_ERR_GCM_BAD_INPUT );
+ }
+
+ ctx->len += length;
+
+ p = input;
+ while( length > 0 )
+ {
+ use_len = ( length < 16 ) ? length : 16;
+
+ for( i = 16; i > 12; i-- )
+ if( ++ctx->y[i - 1] != 0 )
+ break;
+
+ if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
+ &olen ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ for( i = 0; i < use_len; i++ )
+ {
+ if( ctx->mode == MBEDTLS_GCM_DECRYPT )
+ ctx->buf[i] ^= p[i];
+ out_p[i] = ectr[i] ^ p[i];
+ if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
+ ctx->buf[i] ^= out_p[i];
+ }
+
+ gcm_mult( ctx, ctx->buf, ctx->buf );
+
+ length -= use_len;
+ p += use_len;
+ out_p += use_len;
+ }
+
+ return( 0 );
+}
+
+int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
+ unsigned char *tag,
+ size_t tag_len )
+{
+ unsigned char work_buf[16];
+ size_t i;
+ uint64_t orig_len;
+ uint64_t orig_add_len;
+
+ GCM_VALIDATE_RET( ctx != NULL );
+ GCM_VALIDATE_RET( tag != NULL );
+
+ orig_len = ctx->len * 8;
+ orig_add_len = ctx->add_len * 8;
+
+ if( tag_len > 16 || tag_len < 4 )
+ return( MBEDTLS_ERR_GCM_BAD_INPUT );
+
+ memcpy( tag, ctx->base_ectr, tag_len );
+
+ if( orig_len || orig_add_len )
+ {
+ memset( work_buf, 0x00, 16 );
+
+ PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
+ PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
+ PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
+ PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
+
+ for( i = 0; i < 16; i++ )
+ ctx->buf[i] ^= work_buf[i];
+
+ gcm_mult( ctx, ctx->buf, ctx->buf );
+
+ for( i = 0; i < tag_len; i++ )
+ tag[i] ^= ctx->buf[i];
+ }
+
+ return( 0 );
+}
+
+int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
+ int mode,
+ size_t length,
+ const unsigned char *iv,
+ size_t iv_len,
+ const unsigned char *add,
+ size_t add_len,
+ const unsigned char *input,
+ unsigned char *output,
+ size_t tag_len,
+ unsigned char *tag )
+{
+ int ret;
+
+ GCM_VALIDATE_RET( ctx != NULL );
+ GCM_VALIDATE_RET( iv != NULL );
+ GCM_VALIDATE_RET( add_len == 0 || add != NULL );
+ GCM_VALIDATE_RET( length == 0 || input != NULL );
+ GCM_VALIDATE_RET( length == 0 || output != NULL );
+ GCM_VALIDATE_RET( tag != NULL );
+
+ if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
+ return( ret );
+
+ if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
+ return( ret );
+
+ if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
+ return( ret );
+
+ return( 0 );
+}
+
+int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
+ size_t length,
+ const unsigned char *iv,
+ size_t iv_len,
+ const unsigned char *add,
+ size_t add_len,
+ const unsigned char *tag,
+ size_t tag_len,
+ const unsigned char *input,
+ unsigned char *output )
+{
+ int ret;
+ unsigned char check_tag[16];
+ size_t i;
+ int diff;
+
+ GCM_VALIDATE_RET( ctx != NULL );
+ GCM_VALIDATE_RET( iv != NULL );
+ GCM_VALIDATE_RET( add_len == 0 || add != NULL );
+ GCM_VALIDATE_RET( tag != NULL );
+ GCM_VALIDATE_RET( length == 0 || input != NULL );
+ GCM_VALIDATE_RET( length == 0 || output != NULL );
+
+ if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
+ iv, iv_len, add, add_len,
+ input, output, tag_len, check_tag ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ /* Check tag in "constant-time" */
+ for( diff = 0, i = 0; i < tag_len; i++ )
+ diff |= tag[i] ^ check_tag[i];
+
+ if( diff != 0 )
+ {
+ mbedtls_platform_zeroize( output, length );
+ return( MBEDTLS_ERR_GCM_AUTH_FAILED );
+ }
+
+ return( 0 );
+}
+
+void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
+{
+ if( ctx == NULL )
+ return;
+ mbedtls_cipher_free( &ctx->cipher_ctx );
+ mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
+}
+
+#endif /* !MBEDTLS_GCM_ALT */
+
+#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
+/*
+ * AES-GCM test vectors from:
+ *
+ * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
+ */
+#define MAX_TESTS 6
+
+static const int key_index_test_data[MAX_TESTS] =
+ { 0, 0, 1, 1, 1, 1 };
+
+static const unsigned char key_test_data[MAX_TESTS][32] =
+{
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
+};
+
+static const size_t iv_len_test_data[MAX_TESTS] =
+ { 12, 12, 12, 12, 8, 60 };
+
+static const int iv_index_test_data[MAX_TESTS] =
+ { 0, 0, 1, 1, 1, 2 };
+
+static const unsigned char iv_test_data[MAX_TESTS][64] =
+{
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00 },
+ { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 },
+ { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
+ 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
+ 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
+ 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
+ 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
+ 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
+ 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
+ 0xa6, 0x37, 0xb3, 0x9b },
+};
+
+static const size_t add_len_test_data[MAX_TESTS] =
+ { 0, 0, 0, 20, 20, 20 };
+
+static const int add_index_test_data[MAX_TESTS] =
+ { 0, 0, 0, 1, 1, 1 };
+
+static const unsigned char additional_test_data[MAX_TESTS][64] =
+{
+ { 0x00 },
+ { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xab, 0xad, 0xda, 0xd2 },
+};
+
+static const size_t pt_len_test_data[MAX_TESTS] =
+ { 0, 16, 64, 60, 60, 60 };
+
+static const int pt_index_test_data[MAX_TESTS] =
+ { 0, 0, 1, 1, 1, 1 };
+
+static const unsigned char pt_test_data[MAX_TESTS][64] =
+{
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
+};
+
+static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
+{
+ { 0x00 },
+ { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
+ 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
+ { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+ 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+ 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+ 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+ 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+ 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+ 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+ 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
+ { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+ 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+ 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+ 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+ 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+ 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+ 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+ 0x3d, 0x58, 0xe0, 0x91 },
+ { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
+ 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
+ 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
+ 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
+ 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
+ 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
+ 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
+ 0xc2, 0x3f, 0x45, 0x98 },
+ { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
+ 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
+ 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
+ 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
+ 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
+ 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
+ 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
+ 0x4c, 0x34, 0xae, 0xe5 },
+ { 0x00 },
+ { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
+ 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
+ { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
+ 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
+ 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
+ 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
+ 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
+ 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
+ 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
+ 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
+ { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
+ 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
+ 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
+ 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
+ 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
+ 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
+ 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
+ 0xcc, 0xda, 0x27, 0x10 },
+ { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
+ 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
+ 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
+ 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
+ 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
+ 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
+ 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
+ 0xa0, 0xf0, 0x62, 0xf7 },
+ { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
+ 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
+ 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
+ 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
+ 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
+ 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
+ 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
+ 0xe9, 0xb7, 0x37, 0x3b },
+ { 0x00 },
+ { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
+ 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
+ { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
+ 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
+ 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
+ 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
+ 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
+ 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
+ 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
+ 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
+ { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
+ 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
+ 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
+ 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
+ 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
+ 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
+ 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
+ 0xbc, 0xc9, 0xf6, 0x62 },
+ { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
+ 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
+ 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
+ 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
+ 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
+ 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
+ 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
+ 0xf4, 0x7c, 0x9b, 0x1f },
+ { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
+ 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
+ 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
+ 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
+ 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
+ 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
+ 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
+ 0x44, 0xae, 0x7e, 0x3f },
+};
+
+static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
+{
+ { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
+ 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
+ { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
+ 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
+ { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
+ 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
+ { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
+ 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
+ { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
+ 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
+ { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
+ 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
+ { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
+ 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
+ { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
+ 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
+ { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
+ 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
+ { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
+ 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
+ { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
+ 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
+ { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
+ 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
+ { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
+ 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
+ { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
+ 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
+ { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
+ 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
+ { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
+ 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
+ { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
+ 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
+ { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
+ 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
+};
+
+int mbedtls_gcm_self_test( int verbose )
+{
+ mbedtls_gcm_context ctx;
+ unsigned char buf[64];
+ unsigned char tag_buf[16];
+ int i, j, ret;
+ mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
+
+ for( j = 0; j < 3; j++ )
+ {
+ int key_len = 128 + 64 * j;
+
+ for( i = 0; i < MAX_TESTS; i++ )
+ {
+ mbedtls_gcm_init( &ctx );
+
+ if( verbose != 0 )
+ mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
+ key_len, i, "enc" );
+
+ ret = mbedtls_gcm_setkey( &ctx, cipher,
+ key_test_data[key_index_test_data[i]],
+ key_len );
+ /*
+ * AES-192 is an optional feature that may be unavailable when
+ * there is an alternative underlying implementation i.e. when
+ * MBEDTLS_AES_ALT is defined.
+ */
+ if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
+ {
+ mbedtls_printf( "skipped\n" );
+ break;
+ }
+ else if( ret != 0 )
+ {
+ goto exit;
+ }
+
+ ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
+ pt_len_test_data[i],
+ iv_test_data[iv_index_test_data[i]],
+ iv_len_test_data[i],
+ additional_test_data[add_index_test_data[i]],
+ add_len_test_data[i],
+ pt_test_data[pt_index_test_data[i]],
+ buf, 16, tag_buf );
+ if( ret != 0 )
+ goto exit;
+
+ if ( memcmp( buf, ct_test_data[j * 6 + i],
+ pt_len_test_data[i] ) != 0 ||
+ memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
+ {
+ ret = 1;
+ goto exit;
+ }
+
+ mbedtls_gcm_free( &ctx );
+
+ if( verbose != 0 )
+ mbedtls_printf( "passed\n" );
+
+ mbedtls_gcm_init( &ctx );
+
+ if( verbose != 0 )
+ mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
+ key_len, i, "dec" );
+
+ ret = mbedtls_gcm_setkey( &ctx, cipher,
+ key_test_data[key_index_test_data[i]],
+ key_len );
+ if( ret != 0 )
+ goto exit;
+
+ ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
+ pt_len_test_data[i],
+ iv_test_data[iv_index_test_data[i]],
+ iv_len_test_data[i],
+ additional_test_data[add_index_test_data[i]],
+ add_len_test_data[i],
+ ct_test_data[j * 6 + i], buf, 16, tag_buf );
+
+ if( ret != 0 )
+ goto exit;
+
+ if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
+ pt_len_test_data[i] ) != 0 ||
+ memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
+ {
+ ret = 1;
+ goto exit;
+ }
+
+ mbedtls_gcm_free( &ctx );
+
+ if( verbose != 0 )
+ mbedtls_printf( "passed\n" );
+
+ mbedtls_gcm_init( &ctx );
+
+ if( verbose != 0 )
+ mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
+ key_len, i, "enc" );
+
+ ret = mbedtls_gcm_setkey( &ctx, cipher,
+ key_test_data[key_index_test_data[i]],
+ key_len );
+ if( ret != 0 )
+ goto exit;
+
+ ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
+ iv_test_data[iv_index_test_data[i]],
+ iv_len_test_data[i],
+ additional_test_data[add_index_test_data[i]],
+ add_len_test_data[i] );
+ if( ret != 0 )
+ goto exit;
+
+ if( pt_len_test_data[i] > 32 )
+ {
+ size_t rest_len = pt_len_test_data[i] - 32;
+ ret = mbedtls_gcm_update( &ctx, 32,
+ pt_test_data[pt_index_test_data[i]],
+ buf );
+ if( ret != 0 )
+ goto exit;
+
+ ret = mbedtls_gcm_update( &ctx, rest_len,
+ pt_test_data[pt_index_test_data[i]] + 32,
+ buf + 32 );
+ if( ret != 0 )
+ goto exit;
+ }
+ else
+ {
+ ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
+ pt_test_data[pt_index_test_data[i]],
+ buf );
+ if( ret != 0 )
+ goto exit;
+ }
+
+ ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
+ if( ret != 0 )
+ goto exit;
+
+ if( memcmp( buf, ct_test_data[j * 6 + i],
+ pt_len_test_data[i] ) != 0 ||
+ memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
+ {
+ ret = 1;
+ goto exit;
+ }
+
+ mbedtls_gcm_free( &ctx );
+
+ if( verbose != 0 )
+ mbedtls_printf( "passed\n" );
+
+ mbedtls_gcm_init( &ctx );
+
+ if( verbose != 0 )
+ mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
+ key_len, i, "dec" );
+
+ ret = mbedtls_gcm_setkey( &ctx, cipher,
+ key_test_data[key_index_test_data[i]],
+ key_len );
+ if( ret != 0 )
+ goto exit;
+
+ ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
+ iv_test_data[iv_index_test_data[i]],
+ iv_len_test_data[i],
+ additional_test_data[add_index_test_data[i]],
+ add_len_test_data[i] );
+ if( ret != 0 )
+ goto exit;
+
+ if( pt_len_test_data[i] > 32 )
+ {
+ size_t rest_len = pt_len_test_data[i] - 32;
+ ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i],
+ buf );
+ if( ret != 0 )
+ goto exit;
+
+ ret = mbedtls_gcm_update( &ctx, rest_len,
+ ct_test_data[j * 6 + i] + 32,
+ buf + 32 );
+ if( ret != 0 )
+ goto exit;
+ }
+ else
+ {
+ ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
+ ct_test_data[j * 6 + i],
+ buf );
+ if( ret != 0 )
+ goto exit;
+ }
+
+ ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
+ if( ret != 0 )
+ goto exit;
+
+ if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
+ pt_len_test_data[i] ) != 0 ||
+ memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
+ {
+ ret = 1;
+ goto exit;
+ }
+
+ mbedtls_gcm_free( &ctx );
+
+ if( verbose != 0 )
+ mbedtls_printf( "passed\n" );
+ }
+ }
+
+ if( verbose != 0 )
+ mbedtls_printf( "\n" );
+
+ ret = 0;
+
+exit:
+ if( ret != 0 )
+ {
+ if( verbose != 0 )
+ mbedtls_printf( "failed\n" );
+ mbedtls_gcm_free( &ctx );
+ }
+
+ return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
+
+#endif /* MBEDTLS_GCM_C */
diff --git a/templates/blackpill/Src/gcm.h b/templates/blackpill/Src/gcm.h
new file mode 100644
index 0000000..fd130ab
--- /dev/null
+++ b/templates/blackpill/Src/gcm.h
@@ -0,0 +1,326 @@
+/**
+ * \file gcm.h
+ *
+ * \brief This file contains GCM definitions and functions.
+ *
+ * The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined
+ * in D. McGrew, J. Viega, The Galois/Counter Mode of Operation
+ * (GCM), Natl. Inst. Stand. Technol.
+ *
+ * For more information on GCM, see NIST SP 800-38D: Recommendation for
+ * Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC.
+ *
+ */
+/*
+ * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ * This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_GCM_H
+#define MBEDTLS_GCM_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "cipher.h"
+
+#include
+
+#define MBEDTLS_GCM_ENCRYPT 1
+#define MBEDTLS_GCM_DECRYPT 0
+
+#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */
+
+/* MBEDTLS_ERR_GCM_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_GCM_HW_ACCEL_FAILED -0x0013 /**< GCM hardware accelerator failed. */
+
+#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_GCM_ALT)
+
+/**
+ * \brief The GCM context structure.
+ */
+typedef struct mbedtls_gcm_context
+{
+ mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */
+ uint64_t HL[16]; /*!< Precalculated HTable low. */
+ uint64_t HH[16]; /*!< Precalculated HTable high. */
+ uint64_t len; /*!< The total length of the encrypted data. */
+ uint64_t add_len; /*!< The total length of the additional data. */
+ unsigned char base_ectr[16]; /*!< The first ECTR for tag. */
+ unsigned char y[16]; /*!< The Y working value. */
+ unsigned char buf[16]; /*!< The buf working value. */
+ int mode; /*!< The operation to perform:
+ #MBEDTLS_GCM_ENCRYPT or
+ #MBEDTLS_GCM_DECRYPT. */
+}
+mbedtls_gcm_context;
+
+#else /* !MBEDTLS_GCM_ALT */
+#include "gcm_alt.h"
+#endif /* !MBEDTLS_GCM_ALT */
+
+/**
+ * \brief This function initializes the specified GCM context,
+ * to make references valid, and prepares the context
+ * for mbedtls_gcm_setkey() or mbedtls_gcm_free().
+ *
+ * The function does not bind the GCM context to a particular
+ * cipher, nor set the key. For this purpose, use
+ * mbedtls_gcm_setkey().
+ *
+ * \param ctx The GCM context to initialize. This must not be \c NULL.
+ */
+void mbedtls_gcm_init( mbedtls_gcm_context *ctx );
+
+/**
+ * \brief This function associates a GCM context with a
+ * cipher algorithm and a key.
+ *
+ * \param ctx The GCM context. This must be initialized.
+ * \param cipher The 128-bit block cipher to use.
+ * \param key The encryption key. This must be a readable buffer of at
+ * least \p keybits bits.
+ * \param keybits The key size in bits. Valid options are:
+ * - 128 bits
+ * - 192 bits
+ * - 256 bits
+ *
+ * \return \c 0 on success.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
+ mbedtls_cipher_id_t cipher,
+ const unsigned char *key,
+ unsigned int keybits );
+
+/**
+ * \brief This function performs GCM encryption or decryption of a buffer.
+ *
+ * \note For encryption, the output buffer can be the same as the
+ * input buffer. For decryption, the output buffer cannot be
+ * the same as input buffer. If the buffers overlap, the output
+ * buffer must trail at least 8 Bytes behind the input buffer.
+ *
+ * \warning When this function performs a decryption, it outputs the
+ * authentication tag and does not verify that the data is
+ * authentic. You should use this function to perform encryption
+ * only. For decryption, use mbedtls_gcm_auth_decrypt() instead.
+ *
+ * \param ctx The GCM context to use for encryption or decryption. This
+ * must be initialized.
+ * \param mode The operation to perform:
+ * - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption.
+ * The ciphertext is written to \p output and the
+ * authentication tag is written to \p tag.
+ * - #MBEDTLS_GCM_DECRYPT to perform decryption.
+ * The plaintext is written to \p output and the
+ * authentication tag is written to \p tag.
+ * Note that this mode is not recommended, because it does
+ * not verify the authenticity of the data. For this reason,
+ * you should use mbedtls_gcm_auth_decrypt() instead of
+ * calling this function in decryption mode.
+ * \param length The length of the input data, which is equal to the length
+ * of the output data.
+ * \param iv The initialization vector. This must be a readable buffer of
+ * at least \p iv_len Bytes.
+ * \param iv_len The length of the IV.
+ * \param add The buffer holding the additional data. This must be of at
+ * least that size in Bytes.
+ * \param add_len The length of the additional data.
+ * \param input The buffer holding the input data. If \p length is greater
+ * than zero, this must be a readable buffer of at least that
+ * size in Bytes.
+ * \param output The buffer for holding the output data. If \p length is greater
+ * than zero, this must be a writable buffer of at least that
+ * size in Bytes.
+ * \param tag_len The length of the tag to generate.
+ * \param tag The buffer for holding the tag. This must be a readable
+ * buffer of at least \p tag_len Bytes.
+ *
+ * \return \c 0 if the encryption or decryption was performed
+ * successfully. Note that in #MBEDTLS_GCM_DECRYPT mode,
+ * this does not indicate that the data is authentic.
+ * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are
+ * not valid or a cipher-specific error code if the encryption
+ * or decryption failed.
+ */
+int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
+ int mode,
+ size_t length,
+ const unsigned char *iv,
+ size_t iv_len,
+ const unsigned char *add,
+ size_t add_len,
+ const unsigned char *input,
+ unsigned char *output,
+ size_t tag_len,
+ unsigned char *tag );
+
+/**
+ * \brief This function performs a GCM authenticated decryption of a
+ * buffer.
+ *
+ * \note For decryption, the output buffer cannot be the same as
+ * input buffer. If the buffers overlap, the output buffer
+ * must trail at least 8 Bytes behind the input buffer.
+ *
+ * \param ctx The GCM context. This must be initialized.
+ * \param length The length of the ciphertext to decrypt, which is also
+ * the length of the decrypted plaintext.
+ * \param iv The initialization vector. This must be a readable buffer
+ * of at least \p iv_len Bytes.
+ * \param iv_len The length of the IV.
+ * \param add The buffer holding the additional data. This must be of at
+ * least that size in Bytes.
+ * \param add_len The length of the additional data.
+ * \param tag The buffer holding the tag to verify. This must be a
+ * readable buffer of at least \p tag_len Bytes.
+ * \param tag_len The length of the tag to verify.
+ * \param input The buffer holding the ciphertext. If \p length is greater
+ * than zero, this must be a readable buffer of at least that
+ * size.
+ * \param output The buffer for holding the decrypted plaintext. If \p length
+ * is greater than zero, this must be a writable buffer of at
+ * least that size.
+ *
+ * \return \c 0 if successful and authenticated.
+ * \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match.
+ * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are
+ * not valid or a cipher-specific error code if the decryption
+ * failed.
+ */
+int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
+ size_t length,
+ const unsigned char *iv,
+ size_t iv_len,
+ const unsigned char *add,
+ size_t add_len,
+ const unsigned char *tag,
+ size_t tag_len,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief This function starts a GCM encryption or decryption
+ * operation.
+ *
+ * \param ctx The GCM context. This must be initialized.
+ * \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or
+ * #MBEDTLS_GCM_DECRYPT.
+ * \param iv The initialization vector. This must be a readable buffer of
+ * at least \p iv_len Bytes.
+ * \param iv_len The length of the IV.
+ * \param add The buffer holding the additional data, or \c NULL
+ * if \p add_len is \c 0.
+ * \param add_len The length of the additional data. If \c 0,
+ * \p add may be \c NULL.
+ *
+ * \return \c 0 on success.
+ */
+int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
+ int mode,
+ const unsigned char *iv,
+ size_t iv_len,
+ const unsigned char *add,
+ size_t add_len );
+
+/**
+ * \brief This function feeds an input buffer into an ongoing GCM
+ * encryption or decryption operation.
+ *
+ * ` The function expects input to be a multiple of 16
+ * Bytes. Only the last call before calling
+ * mbedtls_gcm_finish() can be less than 16 Bytes.
+ *
+ * \note For decryption, the output buffer cannot be the same as
+ * input buffer. If the buffers overlap, the output buffer
+ * must trail at least 8 Bytes behind the input buffer.
+ *
+ * \param ctx The GCM context. This must be initialized.
+ * \param length The length of the input data. This must be a multiple of
+ * 16 except in the last call before mbedtls_gcm_finish().
+ * \param input The buffer holding the input data. If \p length is greater
+ * than zero, this must be a readable buffer of at least that
+ * size in Bytes.
+ * \param output The buffer for holding the output data. If \p length is
+ * greater than zero, this must be a writable buffer of at
+ * least that size in Bytes.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
+ */
+int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
+ size_t length,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief This function finishes the GCM operation and generates
+ * the authentication tag.
+ *
+ * It wraps up the GCM stream, and generates the
+ * tag. The tag can have a maximum length of 16 Bytes.
+ *
+ * \param ctx The GCM context. This must be initialized.
+ * \param tag The buffer for holding the tag. This must be a readable
+ * buffer of at least \p tag_len Bytes.
+ * \param tag_len The length of the tag to generate. This must be at least
+ * four.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
+ */
+int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
+ unsigned char *tag,
+ size_t tag_len );
+
+/**
+ * \brief This function clears a GCM context and the underlying
+ * cipher sub-context.
+ *
+ * \param ctx The GCM context to clear. If this is \c NULL, the call has
+ * no effect. Otherwise, this must be initialized.
+ */
+void mbedtls_gcm_free( mbedtls_gcm_context *ctx );
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief The GCM checkup routine.
+ *
+ * \return \c 0 on success.
+ * \return \c 1 on failure.
+ */
+int mbedtls_gcm_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* gcm.h */
diff --git a/templates/blackpill/Src/main.c b/templates/blackpill/Src/main.c
new file mode 100644
index 0000000..47b5494
--- /dev/null
+++ b/templates/blackpill/Src/main.c
@@ -0,0 +1,331 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file : main.c
+ * @brief : Main program body
+ ******************************************************************************
+ ** This notice applies to any and all portions of this file
+ * that are not between comment pairs USER CODE BEGIN and
+ * USER CODE END. Other portions of this file, whether
+ * inserted by the user or by software development tools
+ * are owned by their respective copyright owners.
+ *
+ * COPYRIGHT(c) 2019 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN PTD */
+
+/* USER CODE END PTD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN PD */
+
+/* USER CODE END PD */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN PM */
+
+/* USER CODE END PM */
+
+/* Private variables ---------------------------------------------------------*/
+
+/* USER CODE BEGIN PV */
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+void SystemClock_Config(void);
+static void MX_GPIO_Init(void);
+static void MX_USART1_UART_Init(void);
+/* USER CODE BEGIN PFP */
+
+/* USER CODE END PFP */
+
+/* Private user code ---------------------------------------------------------*/
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/**
+ * @brief The application entry point.
+ * @retval int
+ */
+int main(void)
+{
+ /* USER CODE BEGIN 1 */
+
+ /* USER CODE END 1 */
+
+ /* MCU Configuration--------------------------------------------------------*/
+
+ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
+
+
+ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_AFIO);
+ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
+
+ NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
+
+ /* System interrupt init*/
+
+ /**NOJTAG: JTAG-DP Disabled and SW-DP Enabled
+ */
+ LL_GPIO_AF_Remap_SWJ_NOJTAG();
+
+ /* USER CODE BEGIN Init */
+
+ /* USER CODE END Init */
+
+ /* Configure the system clock */
+ SystemClock_Config();
+
+ /* USER CODE BEGIN SysInit */
+
+ /* USER CODE END SysInit */
+
+ /* Initialize all configured peripherals */
+ MX_GPIO_Init();
+ MX_USART1_UART_Init();
+ /* USER CODE BEGIN 2 */
+
+ /* USER CODE END 2 */
+
+ /* Infinite loop */
+ /* USER CODE BEGIN WHILE */
+ uint8_t trm = 0xFF;
+ uint8_t rcv;
+
+ while (1)
+ {
+ /* USER CODE END WHILE */
+ while (!LL_USART_IsActiveFlag_TXE(USART1));
+ LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_12);
+ LL_USART_TransmitData8(USART1, trm);
+ LL_mDelay(100);
+ while (LL_USART_IsActiveFlag_RXNE(USART1));
+ LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_12);
+ rcv = LL_USART_ReceiveData8(USART1);
+ LL_mDelay(100);
+ /* USER CODE BEGIN 3 */
+ }
+ /* USER CODE END 3 */
+}
+
+/**
+ * @brief System Clock Configuration
+ * @retval None
+ */
+void SystemClock_Config(void)
+{
+ LL_FLASH_SetLatency(LL_FLASH_LATENCY_1);
+
+ if(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_1)
+ {
+ Error_Handler();
+ }
+ LL_RCC_HSI_SetCalibTrimming(16);
+ LL_RCC_HSI_Enable();
+
+ /* Wait till HSI is ready */
+ while(LL_RCC_HSI_IsReady() != 1)
+ {
+
+ }
+ LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, LL_RCC_PLL_MUL_12);
+ LL_RCC_PLL_Enable();
+
+ /* Wait till PLL is ready */
+ while(LL_RCC_PLL_IsReady() != 1)
+ {
+
+ }
+ LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
+ LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
+ LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
+ LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
+
+ /* Wait till System clock is ready */
+ while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
+ {
+
+ }
+ LL_Init1msTick(48000000);
+ LL_SYSTICK_SetClkSource(LL_SYSTICK_CLKSOURCE_HCLK);
+ LL_SetSystemCoreClock(48000000);
+}
+
+/**
+ * @brief USART1 Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_USART1_UART_Init(void)
+{
+
+ /* USER CODE BEGIN USART1_Init 0 */
+
+ /* USER CODE END USART1_Init 0 */
+
+ LL_USART_InitTypeDef USART_InitStruct = {0};
+
+ LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+ /* Peripheral clock enable */
+ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);
+
+ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA);
+ /**USART1 GPIO Configuration
+ PA9 ------> USART1_TX
+ PA10 ------> USART1_RX
+ */
+ GPIO_InitStruct.Pin = LL_GPIO_PIN_9;
+ GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
+ GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
+ GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
+ LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
+ GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;
+ LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /* USER CODE BEGIN USART1_Init 1 */
+
+ /* USER CODE END USART1_Init 1 */
+ USART_InitStruct.BaudRate = 115200;
+ USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
+ USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
+ USART_InitStruct.Parity = LL_USART_PARITY_NONE;
+ USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
+ USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
+ LL_USART_Init(USART1, &USART_InitStruct);
+ LL_USART_ConfigAsyncMode(USART1);
+ LL_USART_Enable(USART1);
+ /* USER CODE BEGIN USART1_Init 2 */
+
+ /* USER CODE END USART1_Init 2 */
+
+}
+
+/**
+ * @brief GPIO Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_GPIO_Init(void)
+{
+ LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+ /* GPIO Ports Clock Enable */
+ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOC);
+ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOD);
+ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA);
+ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB);
+
+ /**/
+ LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_12);
+
+ /**/
+ GPIO_InitStruct.Pin = LL_GPIO_PIN_13|LL_GPIO_PIN_14|LL_GPIO_PIN_15;
+ GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
+ LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+ /**/
+ GPIO_InitStruct.Pin = LL_GPIO_PIN_0|LL_GPIO_PIN_1;
+ GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
+ LL_GPIO_Init(GPIOD, &GPIO_InitStruct);
+
+ /**/
+ GPIO_InitStruct.Pin = LL_GPIO_PIN_0|LL_GPIO_PIN_1|LL_GPIO_PIN_2|LL_GPIO_PIN_3
+ |LL_GPIO_PIN_4|LL_GPIO_PIN_5|LL_GPIO_PIN_6|LL_GPIO_PIN_7
+ |LL_GPIO_PIN_8|LL_GPIO_PIN_11|LL_GPIO_PIN_12|LL_GPIO_PIN_15;
+ GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
+ LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /**/
+ GPIO_InitStruct.Pin = LL_GPIO_PIN_0|LL_GPIO_PIN_1|LL_GPIO_PIN_2|LL_GPIO_PIN_10
+ |LL_GPIO_PIN_11|LL_GPIO_PIN_13|LL_GPIO_PIN_14|LL_GPIO_PIN_15
+ |LL_GPIO_PIN_3|LL_GPIO_PIN_4|LL_GPIO_PIN_5|LL_GPIO_PIN_6
+ |LL_GPIO_PIN_7|LL_GPIO_PIN_8|LL_GPIO_PIN_9;
+ GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
+ LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ /**/
+ GPIO_InitStruct.Pin = LL_GPIO_PIN_12;
+ GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
+ GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
+ LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ /**/
+ LL_GPIO_AF_EnableRemap_PD01();
+
+}
+
+/* USER CODE BEGIN 4 */
+
+/* USER CODE END 4 */
+
+/**
+ * @brief This function is executed in case of error occurrence.
+ * @retval None
+ */
+void Error_Handler(void)
+{
+ /* USER CODE BEGIN Error_Handler_Debug */
+ /* User can add his own implementation to report the HAL error return state */
+
+ /* USER CODE END Error_Handler_Debug */
+}
+
+#ifdef USE_FULL_ASSERT
+/**
+ * @brief Reports the name of the source file and the source line number
+ * where the assert_param error has occurred.
+ * @param file: pointer to the source file name
+ * @param line: assert_param error line source number
+ * @retval None
+ */
+void assert_failed(uint8_t *file, uint32_t line)
+{
+ /* USER CODE BEGIN 6 */
+ /* User can add his own implementation to report the file name and line number,
+ tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+ /* USER CODE END 6 */
+}
+#endif /* USE_FULL_ASSERT */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Src/mygcmmain.c b/templates/blackpill/Src/mygcmmain.c
new file mode 100644
index 0000000..b292efc
--- /dev/null
+++ b/templates/blackpill/Src/mygcmmain.c
@@ -0,0 +1,54 @@
+#include "gcm.h"
+#include "platform_util.h"
+#include
+
+static void single_encryption(void) {
+ mbedtls_gcm_context ctx;
+ unsigned char buf[64];
+ unsigned char tag_buf[16];
+ int ret;
+ mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
+ // 32 bytes.. that's 256 bits
+ const unsigned char key[32] = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 };
+ unsigned char plaintext[64] = { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 };
+ unsigned char expected_ciphertext[64] = { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+ 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+ 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+ 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+ 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+ 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+ 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+ 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85};
+ const unsigned char initial_value[12] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88 };
+ const unsigned char additional[] = {};
+
+ mbedtls_gcm_init( &ctx );
+ // 128 bits, not bytes!
+ ret = mbedtls_gcm_setkey( &ctx, cipher, key, 128 );
+
+ ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, 64, initial_value, 12, additional, 0, plaintext, buf, 16, tag_buf);
+ mbedtls_gcm_free( &ctx );
+ if (memcmp(buf, expected_ciphertext, 64) == 0) {
+ printf("Local test workerino!\n");
+ } else {
+ printf("Local test failed -.-\n");
+ }
+
+}
+
+int main(void) {
+ mbedtls_gcm_self_test(1);
+ single_encryption();
+ return 0;
+}
diff --git a/templates/blackpill/Src/platform.c b/templates/blackpill/Src/platform.c
new file mode 100644
index 0000000..8792873
--- /dev/null
+++ b/templates/blackpill/Src/platform.c
@@ -0,0 +1,391 @@
+/*
+ * Platform abstraction layer
+ *
+ * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+
+#include "platform.h"
+#include "platform_util.h"
+
+/* The compile time configuration of memory allocation via the macros
+ * MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO takes precedence over the runtime
+ * configuration via mbedtls_platform_set_calloc_free(). So, omit everything
+ * related to the latter if MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO are defined. */
+#if defined(MBEDTLS_PLATFORM_MEMORY) && \
+ !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && \
+ defined(MBEDTLS_PLATFORM_FREE_MACRO) )
+
+#if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
+static void *platform_calloc_uninit( size_t n, size_t size )
+{
+ ((void) n);
+ ((void) size);
+ return( NULL );
+}
+
+#define MBEDTLS_PLATFORM_STD_CALLOC platform_calloc_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_CALLOC */
+
+#if !defined(MBEDTLS_PLATFORM_STD_FREE)
+static void platform_free_uninit( void *ptr )
+{
+ ((void) ptr);
+}
+
+#define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_FREE */
+
+static void * (*mbedtls_calloc_func)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC;
+static void (*mbedtls_free_func)( void * ) = MBEDTLS_PLATFORM_STD_FREE;
+
+void * mbedtls_calloc( size_t nmemb, size_t size )
+{
+ return (*mbedtls_calloc_func)( nmemb, size );
+}
+
+void mbedtls_free( void * ptr )
+{
+ (*mbedtls_free_func)( ptr );
+}
+
+int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
+ void (*free_func)( void * ) )
+{
+ mbedtls_calloc_func = calloc_func;
+ mbedtls_free_func = free_func;
+ return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_MEMORY &&
+ !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&
+ defined(MBEDTLS_PLATFORM_FREE_MACRO) ) */
+
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
+#include
+int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... )
+{
+ int ret;
+ va_list argp;
+
+ va_start( argp, fmt );
+ ret = mbedtls_vsnprintf( s, n, fmt, argp );
+ va_end( argp );
+
+ return( ret );
+}
+#endif
+
+#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static int platform_snprintf_uninit( char * s, size_t n,
+ const char * format, ... )
+{
+ ((void) s);
+ ((void) n);
+ ((void) format);
+ return( 0 );
+}
+
+#define MBEDTLS_PLATFORM_STD_SNPRINTF platform_snprintf_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_SNPRINTF */
+
+int (*mbedtls_snprintf)( char * s, size_t n,
+ const char * format,
+ ... ) = MBEDTLS_PLATFORM_STD_SNPRINTF;
+
+int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
+ const char * format,
+ ... ) )
+{
+ mbedtls_snprintf = snprintf_func;
+ return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
+
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
+#include
+int mbedtls_platform_win32_vsnprintf( char *s, size_t n, const char *fmt, va_list arg )
+{
+ int ret;
+
+ /* Avoid calling the invalid parameter handler by checking ourselves */
+ if( s == NULL || n == 0 || fmt == NULL )
+ return( -1 );
+
+#if defined(_TRUNCATE)
+ ret = vsnprintf_s( s, n, _TRUNCATE, fmt, arg );
+#else
+ ret = vsnprintf( s, n, fmt, arg );
+ if( ret < 0 || (size_t) ret == n )
+ {
+ s[n-1] = '\0';
+ ret = -1;
+ }
+#endif
+
+ return( ret );
+}
+#endif
+
+#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static int platform_vsnprintf_uninit( char * s, size_t n,
+ const char * format, va_list arg )
+{
+ ((void) s);
+ ((void) n);
+ ((void) format);
+ ((void) arg);
+ return( -1 );
+}
+
+#define MBEDTLS_PLATFORM_STD_VSNPRINTF platform_vsnprintf_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_VSNPRINTF */
+
+int (*mbedtls_vsnprintf)( char * s, size_t n,
+ const char * format,
+ va_list arg ) = MBEDTLS_PLATFORM_STD_VSNPRINTF;
+
+int mbedtls_platform_set_vsnprintf( int (*vsnprintf_func)( char * s, size_t n,
+ const char * format,
+ va_list arg ) )
+{
+ mbedtls_vsnprintf = vsnprintf_func;
+ return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
+
+#if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static int platform_printf_uninit( const char *format, ... )
+{
+ ((void) format);
+ return( 0 );
+}
+
+#define MBEDTLS_PLATFORM_STD_PRINTF platform_printf_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_PRINTF */
+
+int (*mbedtls_printf)( const char *, ... ) = MBEDTLS_PLATFORM_STD_PRINTF;
+
+int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) )
+{
+ mbedtls_printf = printf_func;
+ return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */
+
+#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static int platform_fprintf_uninit( FILE *stream, const char *format, ... )
+{
+ ((void) stream);
+ ((void) format);
+ return( 0 );
+}
+
+#define MBEDTLS_PLATFORM_STD_FPRINTF platform_fprintf_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_FPRINTF */
+
+int (*mbedtls_fprintf)( FILE *, const char *, ... ) =
+ MBEDTLS_PLATFORM_STD_FPRINTF;
+
+int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *, const char *, ... ) )
+{
+ mbedtls_fprintf = fprintf_func;
+ return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */
+
+#if defined(MBEDTLS_PLATFORM_EXIT_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_EXIT)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static void platform_exit_uninit( int status )
+{
+ ((void) status);
+}
+
+#define MBEDTLS_PLATFORM_STD_EXIT platform_exit_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_EXIT */
+
+void (*mbedtls_exit)( int status ) = MBEDTLS_PLATFORM_STD_EXIT;
+
+int mbedtls_platform_set_exit( void (*exit_func)( int status ) )
+{
+ mbedtls_exit = exit_func;
+ return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_EXIT_ALT */
+
+#if defined(MBEDTLS_HAVE_TIME)
+
+#if defined(MBEDTLS_PLATFORM_TIME_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_TIME)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static mbedtls_time_t platform_time_uninit( mbedtls_time_t* timer )
+{
+ ((void) timer);
+ return( 0 );
+}
+
+#define MBEDTLS_PLATFORM_STD_TIME platform_time_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_TIME */
+
+mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* timer ) = MBEDTLS_PLATFORM_STD_TIME;
+
+int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* timer ) )
+{
+ mbedtls_time = time_func;
+ return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_TIME_ALT */
+
+#endif /* MBEDTLS_HAVE_TIME */
+
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
+/* Default implementations for the platform independent seed functions use
+ * standard libc file functions to read from and write to a pre-defined filename
+ */
+int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len )
+{
+ FILE *file;
+ size_t n;
+
+ if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL )
+ return( -1 );
+
+ if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len )
+ {
+ fclose( file );
+ mbedtls_platform_zeroize( buf, buf_len );
+ return( -1 );
+ }
+
+ fclose( file );
+ return( (int)n );
+}
+
+int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len )
+{
+ FILE *file;
+ size_t n;
+
+ if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL )
+ return -1;
+
+ if( ( n = fwrite( buf, 1, buf_len, file ) ) != buf_len )
+ {
+ fclose( file );
+ return -1;
+ }
+
+ fclose( file );
+ return( (int)n );
+}
+#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
+
+#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static int platform_nv_seed_read_uninit( unsigned char *buf, size_t buf_len )
+{
+ ((void) buf);
+ ((void) buf_len);
+ return( -1 );
+}
+
+#define MBEDTLS_PLATFORM_STD_NV_SEED_READ platform_nv_seed_read_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_READ */
+
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static int platform_nv_seed_write_uninit( unsigned char *buf, size_t buf_len )
+{
+ ((void) buf);
+ ((void) buf_len);
+ return( -1 );
+}
+
+#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE platform_nv_seed_write_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_WRITE */
+
+int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) =
+ MBEDTLS_PLATFORM_STD_NV_SEED_READ;
+int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) =
+ MBEDTLS_PLATFORM_STD_NV_SEED_WRITE;
+
+int mbedtls_platform_set_nv_seed(
+ int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ),
+ int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) )
+{
+ mbedtls_nv_seed_read = nv_seed_read_func;
+ mbedtls_nv_seed_write = nv_seed_write_func;
+ return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+
+#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT)
+/*
+ * Placeholder platform setup that does nothing by default
+ */
+int mbedtls_platform_setup( mbedtls_platform_context *ctx )
+{
+ (void)ctx;
+
+ return( 0 );
+}
+
+/*
+ * Placeholder platform teardown that does nothing by default
+ */
+void mbedtls_platform_teardown( mbedtls_platform_context *ctx )
+{
+ (void)ctx;
+}
+#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
+
+#endif /* MBEDTLS_PLATFORM_C */
diff --git a/templates/blackpill/Src/platform.h b/templates/blackpill/Src/platform.h
new file mode 100644
index 0000000..363d6b3
--- /dev/null
+++ b/templates/blackpill/Src/platform.h
@@ -0,0 +1,419 @@
+/**
+ * \file platform.h
+ *
+ * \brief This file contains the definitions and functions of the
+ * Mbed TLS platform abstraction layer.
+ *
+ * The platform abstraction layer removes the need for the library
+ * to directly link to standard C library functions or operating
+ * system services, making the library easier to port and embed.
+ * Application developers and users of the library can provide their own
+ * implementations of these functions, or implementations specific to
+ * their platform, which can be statically linked to the library or
+ * dynamically configured at runtime.
+ */
+/*
+ * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ * This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_PLATFORM_H
+#define MBEDTLS_PLATFORM_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_HAVE_TIME)
+#include "platform_time.h"
+#endif
+
+#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED -0x0070 /**< Hardware accelerator failed */
+#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED -0x0072 /**< The requested feature is not supported by the platform */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h or define them on the compiler command line.
+ * \{
+ */
+
+/* The older Microsoft Windows common runtime provides non-conforming
+ * implementations of some standard library functions, including snprintf
+ * and vsnprintf. This affects MSVC and MinGW builds.
+ */
+#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900)
+#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF
+#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF
+#endif
+
+#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
+#include
+#include
+#include
+#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
+#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use. */
+#else
+#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< The default \c snprintf function to use. */
+#endif
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF)
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
+#define MBEDTLS_PLATFORM_STD_VSNPRINTF mbedtls_platform_win32_vsnprintf /**< The default \c vsnprintf function to use. */
+#else
+#define MBEDTLS_PLATFORM_STD_VSNPRINTF vsnprintf /**< The default \c vsnprintf function to use. */
+#endif
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
+#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< The default \c printf function to use. */
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF)
+#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< The default \c fprintf function to use. */
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
+#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< The default \c calloc function to use. */
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_FREE)
+#define MBEDTLS_PLATFORM_STD_FREE free /**< The default \c free function to use. */
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_EXIT)
+#define MBEDTLS_PLATFORM_STD_EXIT exit /**< The default \c exit function to use. */
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_TIME)
+#define MBEDTLS_PLATFORM_STD_TIME time /**< The default \c time function to use. */
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS)
+#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS /**< The default exit value to use. */
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE)
+#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE /**< The default exit value to use. */
+#endif
+#if defined(MBEDTLS_FS_IO)
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ)
+#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE)
+#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE)
+#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile"
+#endif
+#endif /* MBEDTLS_FS_IO */
+#else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
+#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR)
+#include MBEDTLS_PLATFORM_STD_MEM_HDR
+#endif
+#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
+
+
+/* \} name SECTION: Module settings */
+
+/*
+ * The function pointers for calloc and free.
+ */
+#if defined(MBEDTLS_PLATFORM_MEMORY)
+#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \
+ defined(MBEDTLS_PLATFORM_CALLOC_MACRO)
+#define mbedtls_free MBEDTLS_PLATFORM_FREE_MACRO
+#define mbedtls_calloc MBEDTLS_PLATFORM_CALLOC_MACRO
+#else
+/* For size_t */
+#include
+extern void *mbedtls_calloc( size_t n, size_t size );
+extern void mbedtls_free( void *ptr );
+
+/**
+ * \brief This function dynamically sets the memory-management
+ * functions used by the library, during runtime.
+ *
+ * \param calloc_func The \c calloc function implementation.
+ * \param free_func The \c free function implementation.
+ *
+ * \return \c 0.
+ */
+int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
+ void (*free_func)( void * ) );
+#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */
+#else /* !MBEDTLS_PLATFORM_MEMORY */
+#define mbedtls_free free
+#define mbedtls_calloc calloc
+#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */
+
+/*
+ * The function pointers for fprintf
+ */
+#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
+/* We need FILE * */
+#include
+extern int (*mbedtls_fprintf)( FILE *stream, const char *format, ... );
+
+/**
+ * \brief This function dynamically configures the fprintf
+ * function that is called when the
+ * mbedtls_fprintf() function is invoked by the library.
+ *
+ * \param fprintf_func The \c fprintf function implementation.
+ *
+ * \return \c 0.
+ */
+int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *,
+ ... ) );
+#else
+#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO)
+#define mbedtls_fprintf MBEDTLS_PLATFORM_FPRINTF_MACRO
+#else
+#define mbedtls_fprintf fprintf
+#endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */
+#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */
+
+/*
+ * The function pointers for printf
+ */
+#if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
+extern int (*mbedtls_printf)( const char *format, ... );
+
+/**
+ * \brief This function dynamically configures the snprintf
+ * function that is called when the mbedtls_snprintf()
+ * function is invoked by the library.
+ *
+ * \param printf_func The \c printf function implementation.
+ *
+ * \return \c 0 on success.
+ */
+int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) );
+#else /* !MBEDTLS_PLATFORM_PRINTF_ALT */
+#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO)
+#define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO
+#else
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */
+#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */
+
+/*
+ * The function pointers for snprintf
+ *
+ * The snprintf implementation should conform to C99:
+ * - it *must* always correctly zero-terminate the buffer
+ * (except when n == 0, then it must leave the buffer untouched)
+ * - however it is acceptable to return -1 instead of the required length when
+ * the destination buffer is too short.
+ */
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
+/* For Windows (inc. MSYS2), we provide our own fixed implementation */
+int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... );
+#endif
+
+#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
+extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... );
+
+/**
+ * \brief This function allows configuring a custom
+ * \c snprintf function pointer.
+ *
+ * \param snprintf_func The \c snprintf function implementation.
+ *
+ * \return \c 0 on success.
+ */
+int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
+ const char * format, ... ) );
+#else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
+#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
+#define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO
+#else
+#define mbedtls_snprintf MBEDTLS_PLATFORM_STD_SNPRINTF
+#endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */
+#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
+
+/*
+ * The function pointers for vsnprintf
+ *
+ * The vsnprintf implementation should conform to C99:
+ * - it *must* always correctly zero-terminate the buffer
+ * (except when n == 0, then it must leave the buffer untouched)
+ * - however it is acceptable to return -1 instead of the required length when
+ * the destination buffer is too short.
+ */
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
+#include
+/* For Older Windows (inc. MSYS2), we provide our own fixed implementation */
+int mbedtls_platform_win32_vsnprintf( char *s, size_t n, const char *fmt, va_list arg );
+#endif
+
+#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT)
+#include
+extern int (*mbedtls_vsnprintf)( char * s, size_t n, const char * format, va_list arg );
+
+/**
+ * \brief Set your own snprintf function pointer
+ *
+ * \param vsnprintf_func The \c vsnprintf function implementation
+ *
+ * \return \c 0
+ */
+int mbedtls_platform_set_vsnprintf( int (*vsnprintf_func)( char * s, size_t n,
+ const char * format, va_list arg ) );
+#else /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
+#if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
+#define mbedtls_vsnprintf MBEDTLS_PLATFORM_VSNPRINTF_MACRO
+#else
+#define mbedtls_vsnprintf vsnprintf
+#endif /* MBEDTLS_PLATFORM_VSNPRINTF_MACRO */
+#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
+
+/*
+ * The function pointers for exit
+ */
+#if defined(MBEDTLS_PLATFORM_EXIT_ALT)
+extern void (*mbedtls_exit)( int status );
+
+/**
+ * \brief This function dynamically configures the exit
+ * function that is called when the mbedtls_exit()
+ * function is invoked by the library.
+ *
+ * \param exit_func The \c exit function implementation.
+ *
+ * \return \c 0 on success.
+ */
+int mbedtls_platform_set_exit( void (*exit_func)( int status ) );
+#else
+#if defined(MBEDTLS_PLATFORM_EXIT_MACRO)
+#define mbedtls_exit MBEDTLS_PLATFORM_EXIT_MACRO
+#else
+#define mbedtls_exit exit
+#endif /* MBEDTLS_PLATFORM_EXIT_MACRO */
+#endif /* MBEDTLS_PLATFORM_EXIT_ALT */
+
+/*
+ * The default exit values
+ */
+#if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS)
+#define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS
+#else
+#define MBEDTLS_EXIT_SUCCESS 0
+#endif
+#if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE)
+#define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE
+#else
+#define MBEDTLS_EXIT_FAILURE 1
+#endif
+
+/*
+ * The function pointers for reading from and writing a seed file to
+ * Non-Volatile storage (NV) in a platform-independent way
+ *
+ * Only enabled when the NV seed entropy source is enabled
+ */
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
+/* Internal standard platform definitions */
+int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len );
+int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len );
+#endif
+
+#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
+extern int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len );
+extern int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len );
+
+/**
+ * \brief This function allows configuring custom seed file writing and
+ * reading functions.
+ *
+ * \param nv_seed_read_func The seed reading function implementation.
+ * \param nv_seed_write_func The seed writing function implementation.
+ *
+ * \return \c 0 on success.
+ */
+int mbedtls_platform_set_nv_seed(
+ int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ),
+ int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len )
+ );
+#else
+#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \
+ defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO)
+#define mbedtls_nv_seed_read MBEDTLS_PLATFORM_NV_SEED_READ_MACRO
+#define mbedtls_nv_seed_write MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO
+#else
+#define mbedtls_nv_seed_read mbedtls_platform_std_nv_seed_read
+#define mbedtls_nv_seed_write mbedtls_platform_std_nv_seed_write
+#endif
+#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+
+#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT)
+
+/**
+ * \brief The platform context structure.
+ *
+ * \note This structure may be used to assist platform-specific
+ * setup or teardown operations.
+ */
+typedef struct mbedtls_platform_context
+{
+ char dummy; /**< A placeholder member, as empty structs are not portable. */
+}
+mbedtls_platform_context;
+
+#else
+#include "platform_alt.h"
+#endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
+
+/**
+ * \brief This function performs any platform-specific initialization
+ * operations.
+ *
+ * \note This function should be called before any other library functions.
+ *
+ * Its implementation is platform-specific, and unless
+ * platform-specific code is provided, it does nothing.
+ *
+ * \note The usage and necessity of this function is dependent on the platform.
+ *
+ * \param ctx The platform context.
+ *
+ * \return \c 0 on success.
+ */
+int mbedtls_platform_setup( mbedtls_platform_context *ctx );
+/**
+ * \brief This function performs any platform teardown operations.
+ *
+ * \note This function should be called after every other Mbed TLS module
+ * has been correctly freed using the appropriate free function.
+ *
+ * Its implementation is platform-specific, and unless
+ * platform-specific code is provided, it does nothing.
+ *
+ * \note The usage and necessity of this function is dependent on the platform.
+ *
+ * \param ctx The platform context.
+ *
+ */
+void mbedtls_platform_teardown( mbedtls_platform_context *ctx );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* platform.h */
diff --git a/templates/blackpill/Src/platform_time.h b/templates/blackpill/Src/platform_time.h
new file mode 100644
index 0000000..2ed36f5
--- /dev/null
+++ b/templates/blackpill/Src/platform_time.h
@@ -0,0 +1,82 @@
+/**
+ * \file platform_time.h
+ *
+ * \brief mbed TLS Platform time abstraction
+ */
+/*
+ * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_PLATFORM_TIME_H
+#define MBEDTLS_PLATFORM_TIME_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h or define them on the compiler command line.
+ * \{
+ */
+
+/*
+ * The time_t datatype
+ */
+#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO)
+typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t;
+#else
+/* For time_t */
+#include
+typedef time_t mbedtls_time_t;
+#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */
+
+/*
+ * The function pointers for time
+ */
+#if defined(MBEDTLS_PLATFORM_TIME_ALT)
+extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time );
+
+/**
+ * \brief Set your own time function pointer
+ *
+ * \param time_func the time function implementation
+ *
+ * \return 0
+ */
+int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) );
+#else
+#if defined(MBEDTLS_PLATFORM_TIME_MACRO)
+#define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO
+#else
+#define mbedtls_time time
+#endif /* MBEDTLS_PLATFORM_TIME_MACRO */
+#endif /* MBEDTLS_PLATFORM_TIME_ALT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* platform_time.h */
diff --git a/templates/blackpill/Src/platform_util.c b/templates/blackpill/Src/platform_util.c
new file mode 100644
index 0000000..04a64b3
--- /dev/null
+++ b/templates/blackpill/Src/platform_util.c
@@ -0,0 +1,136 @@
+/*
+ * Common and shared functions used by multiple modules in the Mbed TLS
+ * library.
+ *
+ * Copyright (C) 2018, Arm Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ * This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ * Ensure gmtime_r is available even with -std=c99; must be defined before
+ * config.h, which pulls in glibc's features.h. Harmless on other platforms.
+ */
+#if !defined(_POSIX_C_SOURCE)
+#define _POSIX_C_SOURCE 200112L
+#endif
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "platform_util.h"
+#include "platform.h"
+#include "threading.h"
+
+#include
+#include
+
+#if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT)
+/*
+ * This implementation should never be optimized out by the compiler
+ *
+ * This implementation for mbedtls_platform_zeroize() was inspired from Colin
+ * Percival's blog article at:
+ *
+ * http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html
+ *
+ * It uses a volatile function pointer to the standard memset(). Because the
+ * pointer is volatile the compiler expects it to change at
+ * any time and will not optimize out the call that could potentially perform
+ * other operations on the input buffer instead of just setting it to 0.
+ * Nevertheless, as pointed out by davidtgoldblatt on Hacker News
+ * (refer to http://www.daemonology.net/blog/2014-09-05-erratum.html for
+ * details), optimizations of the following form are still possible:
+ *
+ * if( memset_func != memset )
+ * memset_func( buf, 0, len );
+ *
+ * Note that it is extremely difficult to guarantee that
+ * mbedtls_platform_zeroize() will not be optimized out by aggressive compilers
+ * in a portable way. For this reason, Mbed TLS also provides the configuration
+ * option MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure
+ * mbedtls_platform_zeroize() to use a suitable implementation for their
+ * platform and needs.
+ */
+static void * (* const volatile memset_func)( void *, int, size_t ) = memset;
+
+void mbedtls_platform_zeroize( void *buf, size_t len )
+{
+ memset_func( buf, 0, len );
+}
+#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */
+
+#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
+#include
+#if !defined(_WIN32) && (defined(unix) || \
+ defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \
+ defined(__MACH__)))
+#include
+#endif /* !_WIN32 && (unix || __unix || __unix__ ||
+ * (__APPLE__ && __MACH__)) */
+
+#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
+ ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
+ _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) )
+/*
+ * This is a convenience shorthand macro to avoid checking the long
+ * preprocessor conditions above. Ideally, we could expose this macro in
+ * platform_util.h and simply use it in platform_util.c, threading.c and
+ * threading.h. However, this macro is not part of the Mbed TLS public API, so
+ * we keep it private by only defining it in this file
+ */
+#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) )
+#define PLATFORM_UTIL_USE_GMTIME
+#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */
+
+#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
+ ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
+ _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */
+
+struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
+ struct tm *tm_buf )
+{
+#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
+ return( ( gmtime_s( tm_buf, tt ) == 0 ) ? tm_buf : NULL );
+#elif !defined(PLATFORM_UTIL_USE_GMTIME)
+ return( gmtime_r( tt, tm_buf ) );
+#else
+ struct tm *lt;
+
+#if defined(MBEDTLS_THREADING_C)
+ if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 )
+ return( NULL );
+#endif /* MBEDTLS_THREADING_C */
+
+ lt = gmtime( tt );
+
+ if( lt != NULL )
+ {
+ memcpy( tm_buf, lt, sizeof( struct tm ) );
+ }
+
+#if defined(MBEDTLS_THREADING_C)
+ if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 )
+ return( NULL );
+#endif /* MBEDTLS_THREADING_C */
+
+ return( ( lt == NULL ) ? NULL : tm_buf );
+#endif /* _WIN32 && !EFIX64 && !EFI32 */
+}
+#endif /* MBEDTLS_HAVE_TIME_DATE && MBEDTLS_PLATFORM_GMTIME_R_ALT */
diff --git a/templates/blackpill/Src/platform_util.h b/templates/blackpill/Src/platform_util.h
new file mode 100644
index 0000000..09d0965
--- /dev/null
+++ b/templates/blackpill/Src/platform_util.h
@@ -0,0 +1,196 @@
+/**
+ * \file platform_util.h
+ *
+ * \brief Common and shared functions used by multiple modules in the Mbed TLS
+ * library.
+ */
+/*
+ * Copyright (C) 2018, Arm Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ * This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_PLATFORM_UTIL_H
+#define MBEDTLS_PLATFORM_UTIL_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include
+#if defined(MBEDTLS_HAVE_TIME_DATE)
+#include "platform_time.h"
+#include
+#endif /* MBEDTLS_HAVE_TIME_DATE */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_CHECK_PARAMS)
+
+#if defined(MBEDTLS_CHECK_PARAMS_ASSERT)
+/* Allow the user to define MBEDTLS_PARAM_FAILED to something like assert
+ * (which is what our config.h suggests). */
+#include
+#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */
+
+#if defined(MBEDTLS_PARAM_FAILED)
+/** An alternative definition of MBEDTLS_PARAM_FAILED has been set in config.h.
+ *
+ * This flag can be used to check whether it is safe to assume that
+ * MBEDTLS_PARAM_FAILED() will expand to a call to mbedtls_param_failed().
+ */
+#define MBEDTLS_PARAM_FAILED_ALT
+
+#elif defined(MBEDTLS_CHECK_PARAMS_ASSERT)
+#define MBEDTLS_PARAM_FAILED( cond ) assert( cond )
+#define MBEDTLS_PARAM_FAILED_ALT
+
+#else /* MBEDTLS_PARAM_FAILED */
+#define MBEDTLS_PARAM_FAILED( cond ) \
+ mbedtls_param_failed( #cond, __FILE__, __LINE__ )
+
+/**
+ * \brief User supplied callback function for parameter validation failure.
+ * See #MBEDTLS_CHECK_PARAMS for context.
+ *
+ * This function will be called unless an alternative treatement
+ * is defined through the #MBEDTLS_PARAM_FAILED macro.
+ *
+ * This function can return, and the operation will be aborted, or
+ * alternatively, through use of setjmp()/longjmp() can resume
+ * execution in the application code.
+ *
+ * \param failure_condition The assertion that didn't hold.
+ * \param file The file where the assertion failed.
+ * \param line The line in the file where the assertion failed.
+ */
+void mbedtls_param_failed( const char *failure_condition,
+ const char *file,
+ int line );
+#endif /* MBEDTLS_PARAM_FAILED */
+
+/* Internal macro meant to be called only from within the library. */
+#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) \
+ do { \
+ if( !(cond) ) \
+ { \
+ MBEDTLS_PARAM_FAILED( cond ); \
+ return( ret ); \
+ } \
+ } while( 0 )
+
+/* Internal macro meant to be called only from within the library. */
+#define MBEDTLS_INTERNAL_VALIDATE( cond ) \
+ do { \
+ if( !(cond) ) \
+ { \
+ MBEDTLS_PARAM_FAILED( cond ); \
+ return; \
+ } \
+ } while( 0 )
+
+#else /* MBEDTLS_CHECK_PARAMS */
+
+/* Internal macros meant to be called only from within the library. */
+#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) do { } while( 0 )
+#define MBEDTLS_INTERNAL_VALIDATE( cond ) do { } while( 0 )
+
+#endif /* MBEDTLS_CHECK_PARAMS */
+
+/* Internal helper macros for deprecating API constants. */
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+/* Deliberately don't (yet) export MBEDTLS_DEPRECATED here
+ * to avoid conflict with other headers which define and use
+ * it, too. We might want to move all these definitions here at
+ * some point for uniformity. */
+#define MBEDTLS_DEPRECATED __attribute__((deprecated))
+MBEDTLS_DEPRECATED typedef char const * mbedtls_deprecated_string_constant_t;
+#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) \
+ ( (mbedtls_deprecated_string_constant_t) ( VAL ) )
+MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t;
+#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) \
+ ( (mbedtls_deprecated_numeric_constant_t) ( VAL ) )
+#undef MBEDTLS_DEPRECATED
+#else /* MBEDTLS_DEPRECATED_WARNING */
+#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) VAL
+#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) VAL
+#endif /* MBEDTLS_DEPRECATED_WARNING */
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief Securely zeroize a buffer
+ *
+ * The function is meant to wipe the data contained in a buffer so
+ * that it can no longer be recovered even if the program memory
+ * is later compromised. Call this function on sensitive data
+ * stored on the stack before returning from a function, and on
+ * sensitive data stored on the heap before freeing the heap
+ * object.
+ *
+ * It is extremely difficult to guarantee that calls to
+ * mbedtls_platform_zeroize() are not removed by aggressive
+ * compiler optimizations in a portable way. For this reason, Mbed
+ * TLS provides the configuration option
+ * MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure
+ * mbedtls_platform_zeroize() to use a suitable implementation for
+ * their platform and needs
+ *
+ * \param buf Buffer to be zeroized
+ * \param len Length of the buffer in bytes
+ *
+ */
+void mbedtls_platform_zeroize( void *buf, size_t len );
+
+#if defined(MBEDTLS_HAVE_TIME_DATE)
+/**
+ * \brief Platform-specific implementation of gmtime_r()
+ *
+ * The function is a thread-safe abstraction that behaves
+ * similarly to the gmtime_r() function from Unix/POSIX.
+ *
+ * Mbed TLS will try to identify the underlying platform and
+ * make use of an appropriate underlying implementation (e.g.
+ * gmtime_r() for POSIX and gmtime_s() for Windows). If this is
+ * not possible, then gmtime() will be used. In this case, calls
+ * from the library to gmtime() will be guarded by the mutex
+ * mbedtls_threading_gmtime_mutex if MBEDTLS_THREADING_C is
+ * enabled. It is recommended that calls from outside the library
+ * are also guarded by this mutex.
+ *
+ * If MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, then Mbed TLS will
+ * unconditionally use the alternative implementation for
+ * mbedtls_platform_gmtime_r() supplied by the user at compile time.
+ *
+ * \param tt Pointer to an object containing time (in seconds) since the
+ * epoch to be converted
+ * \param tm_buf Pointer to an object where the results will be stored
+ *
+ * \return Pointer to an object of type struct tm on success, otherwise
+ * NULL
+ */
+struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
+ struct tm *tm_buf );
+#endif /* MBEDTLS_HAVE_TIME_DATE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_PLATFORM_UTIL_H */
diff --git a/templates/blackpill/Src/stm32f1xx_it.c b/templates/blackpill/Src/stm32f1xx_it.c
new file mode 100644
index 0000000..5d3e7fa
--- /dev/null
+++ b/templates/blackpill/Src/stm32f1xx_it.c
@@ -0,0 +1,217 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file stm32f1xx_it.c
+ * @brief Interrupt Service Routines.
+ ******************************************************************************
+ *
+ * COPYRIGHT(c) 2019 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+#include "stm32f1xx_it.h"
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN TD */
+
+/* USER CODE END TD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN PD */
+
+/* USER CODE END PD */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN PM */
+
+/* USER CODE END PM */
+
+/* Private variables ---------------------------------------------------------*/
+/* USER CODE BEGIN PV */
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+/* USER CODE BEGIN PFP */
+
+/* USER CODE END PFP */
+
+/* Private user code ---------------------------------------------------------*/
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/* External variables --------------------------------------------------------*/
+/* USER CODE BEGIN EV */
+
+/* USER CODE END EV */
+
+/******************************************************************************/
+/* Cortex-M3 Processor Interruption and Exception Handlers */
+/******************************************************************************/
+/**
+ * @brief This function handles Non maskable interrupt.
+ */
+void NMI_Handler(void)
+{
+ /* USER CODE BEGIN NonMaskableInt_IRQn 0 */
+
+ /* USER CODE END NonMaskableInt_IRQn 0 */
+ /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
+
+ /* USER CODE END NonMaskableInt_IRQn 1 */
+}
+
+/**
+ * @brief This function handles Hard fault interrupt.
+ */
+void HardFault_Handler(void)
+{
+ /* USER CODE BEGIN HardFault_IRQn 0 */
+
+ /* USER CODE END HardFault_IRQn 0 */
+ while (1)
+ {
+ /* USER CODE BEGIN W1_HardFault_IRQn 0 */
+ /* USER CODE END W1_HardFault_IRQn 0 */
+ }
+}
+
+/**
+ * @brief This function handles Memory management fault.
+ */
+void MemManage_Handler(void)
+{
+ /* USER CODE BEGIN MemoryManagement_IRQn 0 */
+
+ /* USER CODE END MemoryManagement_IRQn 0 */
+ while (1)
+ {
+ /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
+ /* USER CODE END W1_MemoryManagement_IRQn 0 */
+ }
+}
+
+/**
+ * @brief This function handles Prefetch fault, memory access fault.
+ */
+void BusFault_Handler(void)
+{
+ /* USER CODE BEGIN BusFault_IRQn 0 */
+
+ /* USER CODE END BusFault_IRQn 0 */
+ while (1)
+ {
+ /* USER CODE BEGIN W1_BusFault_IRQn 0 */
+ /* USER CODE END W1_BusFault_IRQn 0 */
+ }
+}
+
+/**
+ * @brief This function handles Undefined instruction or illegal state.
+ */
+void UsageFault_Handler(void)
+{
+ /* USER CODE BEGIN UsageFault_IRQn 0 */
+
+ /* USER CODE END UsageFault_IRQn 0 */
+ while (1)
+ {
+ /* USER CODE BEGIN W1_UsageFault_IRQn 0 */
+ /* USER CODE END W1_UsageFault_IRQn 0 */
+ }
+}
+
+/**
+ * @brief This function handles System service call via SWI instruction.
+ */
+void SVC_Handler(void)
+{
+ /* USER CODE BEGIN SVCall_IRQn 0 */
+
+ /* USER CODE END SVCall_IRQn 0 */
+ /* USER CODE BEGIN SVCall_IRQn 1 */
+
+ /* USER CODE END SVCall_IRQn 1 */
+}
+
+/**
+ * @brief This function handles Debug monitor.
+ */
+void DebugMon_Handler(void)
+{
+ /* USER CODE BEGIN DebugMonitor_IRQn 0 */
+
+ /* USER CODE END DebugMonitor_IRQn 0 */
+ /* USER CODE BEGIN DebugMonitor_IRQn 1 */
+
+ /* USER CODE END DebugMonitor_IRQn 1 */
+}
+
+/**
+ * @brief This function handles Pendable request for system service.
+ */
+void PendSV_Handler(void)
+{
+ /* USER CODE BEGIN PendSV_IRQn 0 */
+
+ /* USER CODE END PendSV_IRQn 0 */
+ /* USER CODE BEGIN PendSV_IRQn 1 */
+
+ /* USER CODE END PendSV_IRQn 1 */
+}
+
+/**
+ * @brief This function handles System tick timer.
+ */
+void SysTick_Handler(void)
+{
+ /* USER CODE BEGIN SysTick_IRQn 0 */
+
+ /* USER CODE END SysTick_IRQn 0 */
+
+ /* USER CODE BEGIN SysTick_IRQn 1 */
+
+ /* USER CODE END SysTick_IRQn 1 */
+}
+
+/******************************************************************************/
+/* STM32F1xx Peripheral Interrupt Handlers */
+/* Add here the Interrupt Handlers for the used peripherals. */
+/* For the available peripheral interrupt handler names, */
+/* please refer to the startup file (startup_stm32f1xx.s). */
+/******************************************************************************/
+
+/* USER CODE BEGIN 1 */
+
+/* USER CODE END 1 */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Src/system_stm32f1xx.c b/templates/blackpill/Src/system_stm32f1xx.c
new file mode 100644
index 0000000..789b551
--- /dev/null
+++ b/templates/blackpill/Src/system_stm32f1xx.c
@@ -0,0 +1,448 @@
+/**
+ ******************************************************************************
+ * @file system_stm32f1xx.c
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @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_stm32f1xx_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_stm32f1xx_xx.s" file, to
+ * configure the system clock before to branch to main program.
+ *
+ * 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depending on
+ * the product used), refer to "HSE_VALUE".
+ * 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
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup stm32f1xx_system
+ * @{
+ */
+
+/** @addtogroup STM32F1xx_System_Private_Includes
+ * @{
+ */
+
+#include "stm32f1xx.h"
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F1xx_System_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F1xx_System_Private_Defines
+ * @{
+ */
+
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE 8000000U /*!< Default value of the External oscillator in Hz.
+ This value can be provided and adapted by the user application. */
+#endif /* HSE_VALUE */
+
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE 8000000U /*!< Default value of the Internal oscillator in Hz.
+ This value can be provided and adapted by the user application. */
+#endif /* HSI_VALUE */
+
+/*!< Uncomment the following line if you need to use external SRAM */
+#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
+/* #define DATA_IN_ExtSRAM */
+#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
+
+/*!< Uncomment the following line if you need to relocate your vector Table in
+ Internal SRAM. */
+/* #define VECT_TAB_SRAM */
+#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
+ This value must be a multiple of 0x200. */
+
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F1xx_System_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F1xx_System_Private_Variables
+ * @{
+ */
+
+/*******************************************************************************
+* Clock Definitions
+*******************************************************************************/
+#if defined(STM32F100xB) ||defined(STM32F100xE)
+ uint32_t SystemCoreClock = 24000000U; /*!< System Clock Frequency (Core Clock) */
+#else /*!< HSI Selected as System Clock source */
+ uint32_t SystemCoreClock = 72000000U; /*!< System Clock Frequency (Core Clock) */
+#endif
+
+const uint8_t AHBPrescTable[16U] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+const uint8_t APBPrescTable[8U] = {0, 0, 0, 0, 1, 2, 3, 4};
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F1xx_System_Private_FunctionPrototypes
+ * @{
+ */
+
+#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
+#ifdef DATA_IN_ExtSRAM
+ static void SystemInit_ExtMemCtl(void);
+#endif /* DATA_IN_ExtSRAM */
+#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F1xx_System_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Setup the microcontroller system
+ * Initialize the Embedded Flash Interface, the PLL and update the
+ * SystemCoreClock variable.
+ * @note This function should be used only after reset.
+ * @param None
+ * @retval None
+ */
+void SystemInit (void)
+{
+ /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
+ /* Set HSION bit */
+ RCC->CR |= 0x00000001U;
+
+ /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
+#if !defined(STM32F105xC) && !defined(STM32F107xC)
+ RCC->CFGR &= 0xF8FF0000U;
+#else
+ RCC->CFGR &= 0xF0FF0000U;
+#endif /* STM32F105xC */
+
+ /* Reset HSEON, CSSON and PLLON bits */
+ RCC->CR &= 0xFEF6FFFFU;
+
+ /* Reset HSEBYP bit */
+ RCC->CR &= 0xFFFBFFFFU;
+
+ /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
+ RCC->CFGR &= 0xFF80FFFFU;
+
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ /* Reset PLL2ON and PLL3ON bits */
+ RCC->CR &= 0xEBFFFFFFU;
+
+ /* Disable all interrupts and clear pending bits */
+ RCC->CIR = 0x00FF0000U;
+
+ /* Reset CFGR2 register */
+ RCC->CFGR2 = 0x00000000U;
+#elif defined(STM32F100xB) || defined(STM32F100xE)
+ /* Disable all interrupts and clear pending bits */
+ RCC->CIR = 0x009F0000U;
+
+ /* Reset CFGR2 register */
+ RCC->CFGR2 = 0x00000000U;
+#else
+ /* Disable all interrupts and clear pending bits */
+ RCC->CIR = 0x009F0000U;
+#endif /* STM32F105xC */
+
+#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
+ #ifdef DATA_IN_ExtSRAM
+ SystemInit_ExtMemCtl();
+ #endif /* DATA_IN_ExtSRAM */
+#endif
+
+#ifdef VECT_TAB_SRAM
+ SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
+#else
+ SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
+#endif
+}
+
+/**
+ * @brief Update SystemCoreClock variable according to Clock Register Values.
+ * The SystemCoreClock variable contains the core clock (HCLK), it can
+ * be used by the user application to setup the SysTick timer or configure
+ * other parameters.
+ *
+ * @note Each time the core clock (HCLK) changes, this function must be called
+ * to update SystemCoreClock variable value. Otherwise, any configuration
+ * based on this variable will be incorrect.
+ *
+ * @note - The system frequency computed by this function is not the real
+ * frequency in the chip. It is calculated based on the predefined
+ * constant and the selected clock source:
+ *
+ * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
+ *
+ * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
+ *
+ * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
+ * or HSI_VALUE(*) multiplied by the PLL factors.
+ *
+ * (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
+ * 8 MHz) but the real value may vary depending on the variations
+ * in voltage and temperature.
+ *
+ * (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
+ * 8 MHz or 25 MHz, depending on the product used), user has to ensure
+ * that HSE_VALUE is same as the real frequency of the crystal used.
+ * Otherwise, this function may have wrong result.
+ *
+ * - The result of this function could be not correct when using fractional
+ * value for HSE crystal.
+ * @param None
+ * @retval None
+ */
+void SystemCoreClockUpdate (void)
+{
+ uint32_t tmp = 0U, pllmull = 0U, pllsource = 0U;
+
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ uint32_t prediv1source = 0U, prediv1factor = 0U, prediv2factor = 0U, pll2mull = 0U;
+#endif /* STM32F105xC */
+
+#if defined(STM32F100xB) || defined(STM32F100xE)
+ uint32_t prediv1factor = 0U;
+#endif /* STM32F100xB or STM32F100xE */
+
+ /* Get SYSCLK source -------------------------------------------------------*/
+ tmp = RCC->CFGR & RCC_CFGR_SWS;
+
+ switch (tmp)
+ {
+ case 0x00U: /* HSI used as system clock */
+ SystemCoreClock = HSI_VALUE;
+ break;
+ case 0x04U: /* HSE used as system clock */
+ SystemCoreClock = HSE_VALUE;
+ break;
+ case 0x08U: /* PLL used as system clock */
+
+ /* Get PLL clock source and multiplication factor ----------------------*/
+ pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
+ pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
+
+#if !defined(STM32F105xC) && !defined(STM32F107xC)
+ pllmull = ( pllmull >> 18U) + 2U;
+
+ if (pllsource == 0x00U)
+ {
+ /* HSI oscillator clock divided by 2 selected as PLL clock entry */
+ SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
+ }
+ else
+ {
+ #if defined(STM32F100xB) || defined(STM32F100xE)
+ prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
+ /* HSE oscillator clock selected as PREDIV1 clock entry */
+ SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
+ #else
+ /* HSE selected as PLL clock entry */
+ if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
+ {/* HSE oscillator clock divided by 2 */
+ SystemCoreClock = (HSE_VALUE >> 1U) * pllmull;
+ }
+ else
+ {
+ SystemCoreClock = HSE_VALUE * pllmull;
+ }
+ #endif
+ }
+#else
+ pllmull = pllmull >> 18U;
+
+ if (pllmull != 0x0DU)
+ {
+ pllmull += 2U;
+ }
+ else
+ { /* PLL multiplication factor = PLL input clock * 6.5 */
+ pllmull = 13U / 2U;
+ }
+
+ if (pllsource == 0x00U)
+ {
+ /* HSI oscillator clock divided by 2 selected as PLL clock entry */
+ SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
+ }
+ else
+ {/* PREDIV1 selected as PLL clock entry */
+
+ /* Get PREDIV1 clock source and division factor */
+ prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
+ prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
+
+ if (prediv1source == 0U)
+ {
+ /* HSE oscillator clock selected as PREDIV1 clock entry */
+ SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
+ }
+ else
+ {/* PLL2 clock selected as PREDIV1 clock entry */
+
+ /* Get PREDIV2 division factor and PLL2 multiplication factor */
+ prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4U) + 1U;
+ pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8U) + 2U;
+ SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
+ }
+ }
+#endif /* STM32F105xC */
+ break;
+
+ default:
+ SystemCoreClock = HSI_VALUE;
+ break;
+ }
+
+ /* Compute HCLK clock frequency ----------------*/
+ /* Get HCLK prescaler */
+ tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
+ /* HCLK clock frequency */
+ SystemCoreClock >>= tmp;
+}
+
+#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
+/**
+ * @brief Setup the external memory controller. Called in startup_stm32f1xx.s
+ * before jump to __main
+ * @param None
+ * @retval None
+ */
+#ifdef DATA_IN_ExtSRAM
+/**
+ * @brief Setup the external memory controller.
+ * Called in startup_stm32f1xx_xx.s/.c before jump to main.
+ * This function configures the external SRAM mounted on STM3210E-EVAL
+ * board (STM32 High density devices). This SRAM will be used as program
+ * data memory (including heap and stack).
+ * @param None
+ * @retval None
+ */
+void SystemInit_ExtMemCtl(void)
+{
+ __IO uint32_t tmpreg;
+ /*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
+ required, then adjust the Register Addresses */
+
+ /* Enable FSMC clock */
+ RCC->AHBENR = 0x00000114U;
+
+ /* Delay after an RCC peripheral clock enabling */
+ tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN);
+
+ /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
+ RCC->APB2ENR = 0x000001E0U;
+
+ /* Delay after an RCC peripheral clock enabling */
+ tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);
+
+ (void)(tmpreg);
+
+/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/
+/*---------------- SRAM Address lines configuration -------------------------*/
+/*---------------- NOE and NWE configuration --------------------------------*/
+/*---------------- NE3 configuration ----------------------------------------*/
+/*---------------- NBL0, NBL1 configuration ---------------------------------*/
+
+ GPIOD->CRL = 0x44BB44BBU;
+ GPIOD->CRH = 0xBBBBBBBBU;
+
+ GPIOE->CRL = 0xB44444BBU;
+ GPIOE->CRH = 0xBBBBBBBBU;
+
+ GPIOF->CRL = 0x44BBBBBBU;
+ GPIOF->CRH = 0xBBBB4444U;
+
+ GPIOG->CRL = 0x44BBBBBBU;
+ GPIOG->CRH = 0x444B4B44U;
+
+/*---------------- FSMC Configuration ---------------------------------------*/
+/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/
+
+ FSMC_Bank1->BTCR[4U] = 0x00001091U;
+ FSMC_Bank1->BTCR[5U] = 0x00110212U;
+}
+#endif /* DATA_IN_ExtSRAM */
+#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/templates/blackpill/Src/threading.c b/templates/blackpill/Src/threading.c
new file mode 100644
index 0000000..7c90c7c
--- /dev/null
+++ b/templates/blackpill/Src/threading.c
@@ -0,0 +1,187 @@
+/*
+ * Threading abstraction layer
+ *
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ * Ensure gmtime_r is available even with -std=c99; must be defined before
+ * config.h, which pulls in glibc's features.h. Harmless on other platforms.
+ */
+#if !defined(_POSIX_C_SOURCE)
+#define _POSIX_C_SOURCE 200112L
+#endif
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_THREADING_C)
+
+#include "mbedtls/threading.h"
+
+#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
+
+#if !defined(_WIN32) && (defined(unix) || \
+ defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \
+ defined(__MACH__)))
+#include
+#endif /* !_WIN32 && (unix || __unix || __unix__ ||
+ * (__APPLE__ && __MACH__)) */
+
+#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
+ ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
+ _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) )
+/*
+ * This is a convenience shorthand macro to avoid checking the long
+ * preprocessor conditions above. Ideally, we could expose this macro in
+ * platform_util.h and simply use it in platform_util.c, threading.c and
+ * threading.h. However, this macro is not part of the Mbed TLS public API, so
+ * we keep it private by only defining it in this file
+ */
+
+#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) )
+#define THREADING_USE_GMTIME
+#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */
+
+#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
+ ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
+ _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */
+
+#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */
+
+#if defined(MBEDTLS_THREADING_PTHREAD)
+static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex )
+{
+ if( mutex == NULL )
+ return;
+
+ mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0;
+}
+
+static void threading_mutex_free_pthread( mbedtls_threading_mutex_t *mutex )
+{
+ if( mutex == NULL || !mutex->is_valid )
+ return;
+
+ (void) pthread_mutex_destroy( &mutex->mutex );
+ mutex->is_valid = 0;
+}
+
+static int threading_mutex_lock_pthread( mbedtls_threading_mutex_t *mutex )
+{
+ if( mutex == NULL || ! mutex->is_valid )
+ return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA );
+
+ if( pthread_mutex_lock( &mutex->mutex ) != 0 )
+ return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+
+ return( 0 );
+}
+
+static int threading_mutex_unlock_pthread( mbedtls_threading_mutex_t *mutex )
+{
+ if( mutex == NULL || ! mutex->is_valid )
+ return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA );
+
+ if( pthread_mutex_unlock( &mutex->mutex ) != 0 )
+ return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+
+ return( 0 );
+}
+
+void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_init_pthread;
+void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_free_pthread;
+int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_lock_pthread;
+int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_unlock_pthread;
+
+/*
+ * With phtreads we can statically initialize mutexes
+ */
+#define MUTEX_INIT = { PTHREAD_MUTEX_INITIALIZER, 1 }
+
+#endif /* MBEDTLS_THREADING_PTHREAD */
+
+#if defined(MBEDTLS_THREADING_ALT)
+static int threading_mutex_fail( mbedtls_threading_mutex_t *mutex )
+{
+ ((void) mutex );
+ return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA );
+}
+static void threading_mutex_dummy( mbedtls_threading_mutex_t *mutex )
+{
+ ((void) mutex );
+ return;
+}
+
+void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy;
+void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy;
+int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail;
+int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail;
+
+/*
+ * Set functions pointers and initialize global mutexes
+ */
+void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ),
+ void (*mutex_free)( mbedtls_threading_mutex_t * ),
+ int (*mutex_lock)( mbedtls_threading_mutex_t * ),
+ int (*mutex_unlock)( mbedtls_threading_mutex_t * ) )
+{
+ mbedtls_mutex_init = mutex_init;
+ mbedtls_mutex_free = mutex_free;
+ mbedtls_mutex_lock = mutex_lock;
+ mbedtls_mutex_unlock = mutex_unlock;
+
+#if defined(MBEDTLS_FS_IO)
+ mbedtls_mutex_init( &mbedtls_threading_readdir_mutex );
+#endif
+#if defined(THREADING_USE_GMTIME)
+ mbedtls_mutex_init( &mbedtls_threading_gmtime_mutex );
+#endif
+}
+
+/*
+ * Free global mutexes
+ */
+void mbedtls_threading_free_alt( void )
+{
+#if defined(MBEDTLS_FS_IO)
+ mbedtls_mutex_free( &mbedtls_threading_readdir_mutex );
+#endif
+#if defined(THREADING_USE_GMTIME)
+ mbedtls_mutex_free( &mbedtls_threading_gmtime_mutex );
+#endif
+}
+#endif /* MBEDTLS_THREADING_ALT */
+
+/*
+ * Define global mutexes
+ */
+#ifndef MUTEX_INIT
+#define MUTEX_INIT
+#endif
+#if defined(MBEDTLS_FS_IO)
+mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex MUTEX_INIT;
+#endif
+#if defined(THREADING_USE_GMTIME)
+mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT;
+#endif
+
+#endif /* MBEDTLS_THREADING_C */
diff --git a/templates/blackpill/Src/threading.h b/templates/blackpill/Src/threading.h
new file mode 100644
index 0000000..92e6e6b
--- /dev/null
+++ b/templates/blackpill/Src/threading.h
@@ -0,0 +1,122 @@
+/**
+ * \file threading.h
+ *
+ * \brief Threading abstraction layer
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_THREADING_H
+#define MBEDTLS_THREADING_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE is deprecated and should not be
+ * used. */
+#define MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE -0x001A /**< The selected feature is not available. */
+
+#define MBEDTLS_ERR_THREADING_BAD_INPUT_DATA -0x001C /**< Bad input parameters to function. */
+#define MBEDTLS_ERR_THREADING_MUTEX_ERROR -0x001E /**< Locking / unlocking / free failed with error code. */
+
+#if defined(MBEDTLS_THREADING_PTHREAD)
+#include
+typedef struct mbedtls_threading_mutex_t
+{
+ pthread_mutex_t mutex;
+ char is_valid;
+} mbedtls_threading_mutex_t;
+#endif
+
+#if defined(MBEDTLS_THREADING_ALT)
+/* You should define the mbedtls_threading_mutex_t type in your header */
+#include "threading_alt.h"
+
+/**
+ * \brief Set your alternate threading implementation function
+ * pointers and initialize global mutexes. If used, this
+ * function must be called once in the main thread before any
+ * other mbed TLS function is called, and
+ * mbedtls_threading_free_alt() must be called once in the main
+ * thread after all other mbed TLS functions.
+ *
+ * \note mutex_init() and mutex_free() don't return a status code.
+ * If mutex_init() fails, it should leave its argument (the
+ * mutex) in a state such that mutex_lock() will fail when
+ * called with this argument.
+ *
+ * \param mutex_init the init function implementation
+ * \param mutex_free the free function implementation
+ * \param mutex_lock the lock function implementation
+ * \param mutex_unlock the unlock function implementation
+ */
+void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ),
+ void (*mutex_free)( mbedtls_threading_mutex_t * ),
+ int (*mutex_lock)( mbedtls_threading_mutex_t * ),
+ int (*mutex_unlock)( mbedtls_threading_mutex_t * ) );
+
+/**
+ * \brief Free global mutexes.
+ */
+void mbedtls_threading_free_alt( void );
+#endif /* MBEDTLS_THREADING_ALT */
+
+#if defined(MBEDTLS_THREADING_C)
+/*
+ * The function pointers for mutex_init, mutex_free, mutex_ and mutex_unlock
+ *
+ * All these functions are expected to work or the result will be undefined.
+ */
+extern void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t *mutex );
+extern void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t *mutex );
+extern int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t *mutex );
+extern int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t *mutex );
+
+/*
+ * Global mutexes
+ */
+#if defined(MBEDTLS_FS_IO)
+extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex;
+#endif
+
+#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
+/* This mutex may or may not be used in the default definition of
+ * mbedtls_platform_gmtime_r(), but in order to determine that,
+ * we need to check POSIX features, hence modify _POSIX_C_SOURCE.
+ * With the current approach, this declaration is orphaned, lacking
+ * an accompanying definition, in case mbedtls_platform_gmtime_r()
+ * doesn't need it, but that's not a problem. */
+extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex;
+#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */
+
+#endif /* MBEDTLS_THREADING_C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* threading.h */
diff --git a/assets/templates/blackpill/Src/utils.c b/templates/blackpill/Src/utils.c
similarity index 100%
rename from assets/templates/blackpill/Src/utils.c
rename to templates/blackpill/Src/utils.c
diff --git a/assets/templates/blackpill/Src/utils.h b/templates/blackpill/Src/utils.h
similarity index 100%
rename from assets/templates/blackpill/Src/utils.h
rename to templates/blackpill/Src/utils.h
diff --git a/templates/blackpill/blackpill.ioc b/templates/blackpill/blackpill.ioc
new file mode 100644
index 0000000..f56e6a5
--- /dev/null
+++ b/templates/blackpill/blackpill.ioc
@@ -0,0 +1,103 @@
+#MicroXplorer Configuration settings - do not modify
+File.Version=6
+KeepUserPlacement=false
+Mcu.Family=STM32F1
+Mcu.IP0=NVIC
+Mcu.IP1=RCC
+Mcu.IP2=SYS
+Mcu.IP3=USART1
+Mcu.IPNb=4
+Mcu.Name=STM32F103C(8-B)Tx
+Mcu.Package=LQFP48
+Mcu.Pin0=PB12
+Mcu.Pin1=PA9
+Mcu.Pin2=PA10
+Mcu.Pin3=PA13
+Mcu.Pin4=PA14
+Mcu.Pin5=VP_SYS_VS_Systick
+Mcu.PinsNb=6
+Mcu.ThirdPartyNb=0
+Mcu.UserConstants=
+Mcu.UserName=STM32F103C8Tx
+MxCube.Version=5.0.1
+MxDb.Version=DB.5.0.1
+NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false
+NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false
+NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false
+NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false
+NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false
+NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false
+NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
+NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false
+NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false
+NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false
+PA10.Mode=Asynchronous
+PA10.Signal=USART1_RX
+PA13.Mode=Serial_Wire
+PA13.Signal=SYS_JTMS-SWDIO
+PA14.Mode=Serial_Wire
+PA14.Signal=SYS_JTCK-SWCLK
+PA9.Mode=Asynchronous
+PA9.Signal=USART1_TX
+PB12.Locked=true
+PB12.Signal=GPIO_Output
+PCC.Checker=false
+PCC.Line=STM32F103
+PCC.MCU=STM32F103C(8-B)Tx
+PCC.PartNumber=STM32F103C8Tx
+PCC.Seq0=0
+PCC.Series=STM32F1
+PCC.Temperature=25
+PCC.Vdd=3.3
+PinOutPanel.RotationAngle=0
+ProjectManager.AskForMigrate=true
+ProjectManager.BackupPrevious=false
+ProjectManager.CompilerOptimize=6
+ProjectManager.ComputerToolchain=false
+ProjectManager.CoupleFile=false
+ProjectManager.CustomerFirmwarePackage=
+ProjectManager.DefaultFWLocation=true
+ProjectManager.DeletePrevious=true
+ProjectManager.DeviceId=STM32F103C8Tx
+ProjectManager.FirmwarePackage=STM32Cube FW_F1 V1.7.0
+ProjectManager.FreePins=true
+ProjectManager.HalAssertFull=false
+ProjectManager.HeapSize=0x200
+ProjectManager.KeepUserCode=false
+ProjectManager.LastFirmware=true
+ProjectManager.LibraryCopy=0
+ProjectManager.MainLocation=Src
+ProjectManager.NoMain=false
+ProjectManager.PreviousToolchain=
+ProjectManager.ProjectBuild=false
+ProjectManager.ProjectFileName=blackpill.ioc
+ProjectManager.ProjectName=blackpill
+ProjectManager.StackSize=0x400
+ProjectManager.TargetToolchain=Makefile
+ProjectManager.ToolChainLocation=
+ProjectManager.UnderRoot=false
+ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-LL-true,2-SystemClock_Config-RCC-false-LL-false,3-MX_USART1_UART_Init-USART1-false-LL-true
+RCC.ADCFreqValue=24000000
+RCC.AHBFreq_Value=48000000
+RCC.APB1CLKDivider=RCC_HCLK_DIV2
+RCC.APB1Freq_Value=24000000
+RCC.APB1TimFreq_Value=48000000
+RCC.APB2Freq_Value=48000000
+RCC.APB2TimFreq_Value=48000000
+RCC.FCLKCortexFreq_Value=48000000
+RCC.FamilyName=M
+RCC.HCLKFreq_Value=48000000
+RCC.IPParameters=ADCFreqValue,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,MCOFreq_Value,PLLCLKFreq_Value,PLLMCOFreq_Value,PLLMUL,SYSCLKFreq_VALUE,SYSCLKSource,TimSysFreq_Value,USBFreq_Value
+RCC.MCOFreq_Value=48000000
+RCC.PLLCLKFreq_Value=48000000
+RCC.PLLMCOFreq_Value=24000000
+RCC.PLLMUL=RCC_PLL_MUL12
+RCC.SYSCLKFreq_VALUE=48000000
+RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
+RCC.TimSysFreq_Value=48000000
+RCC.USBFreq_Value=48000000
+USART1.IPParameters=VirtualMode
+USART1.VirtualMode=VM_ASYNC
+VP_SYS_VS_Systick.Mode=SysTick
+VP_SYS_VS_Systick.Signal=SYS_VS_Systick
+board=custom
diff --git a/assets/crypto_aead.h b/templates/blackpill/crypto_aead.h
similarity index 100%
rename from assets/crypto_aead.h
rename to templates/blackpill/crypto_aead.h
diff --git a/templates/blackpill/startup_stm32f103xb.s b/templates/blackpill/startup_stm32f103xb.s
new file mode 100644
index 0000000..1bdd524
--- /dev/null
+++ b/templates/blackpill/startup_stm32f103xb.s
@@ -0,0 +1,379 @@
+/**
+ *************** (C) COPYRIGHT 2017 STMicroelectronics ************************
+ * @file startup_stm32f103xb.s
+ * @author MCD Application Team
+ * @version V4.2.0
+ * @date 31-March-2017
+ * @brief STM32F103xB Devices vector table for Atollic toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Configure the clock system
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M3 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of STMicroelectronics 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 HOLDER 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.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m3
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+
+.equ BootRAM, 0xF108F85F
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ *
+ * @param None
+ * @retval : None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler
+ .word PVD_IRQHandler
+ .word TAMPER_IRQHandler
+ .word RTC_IRQHandler
+ .word FLASH_IRQHandler
+ .word RCC_IRQHandler
+ .word EXTI0_IRQHandler
+ .word EXTI1_IRQHandler
+ .word EXTI2_IRQHandler
+ .word EXTI3_IRQHandler
+ .word EXTI4_IRQHandler
+ .word DMA1_Channel1_IRQHandler
+ .word DMA1_Channel2_IRQHandler
+ .word DMA1_Channel3_IRQHandler
+ .word DMA1_Channel4_IRQHandler
+ .word DMA1_Channel5_IRQHandler
+ .word DMA1_Channel6_IRQHandler
+ .word DMA1_Channel7_IRQHandler
+ .word ADC1_2_IRQHandler
+ .word USB_HP_CAN1_TX_IRQHandler
+ .word USB_LP_CAN1_RX0_IRQHandler
+ .word CAN1_RX1_IRQHandler
+ .word CAN1_SCE_IRQHandler
+ .word EXTI9_5_IRQHandler
+ .word TIM1_BRK_IRQHandler
+ .word TIM1_UP_IRQHandler
+ .word TIM1_TRG_COM_IRQHandler
+ .word TIM1_CC_IRQHandler
+ .word TIM2_IRQHandler
+ .word TIM3_IRQHandler
+ .word TIM4_IRQHandler
+ .word I2C1_EV_IRQHandler
+ .word I2C1_ER_IRQHandler
+ .word I2C2_EV_IRQHandler
+ .word I2C2_ER_IRQHandler
+ .word SPI1_IRQHandler
+ .word SPI2_IRQHandler
+ .word USART1_IRQHandler
+ .word USART2_IRQHandler
+ .word USART3_IRQHandler
+ .word EXTI15_10_IRQHandler
+ .word RTC_Alarm_IRQHandler
+ .word USBWakeUp_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word BootRAM /* @0x108. This is for boot in RAM mode for
+ STM32F10x Medium Density devices. */
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMPER_IRQHandler
+ .thumb_set TAMPER_IRQHandler,Default_Handler
+
+ .weak RTC_IRQHandler
+ .thumb_set RTC_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_IRQHandler
+ .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel3_IRQHandler
+ .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_IRQHandler
+ .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel5_IRQHandler
+ .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel6_IRQHandler
+ .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel7_IRQHandler
+ .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
+
+ .weak ADC1_2_IRQHandler
+ .thumb_set ADC1_2_IRQHandler,Default_Handler
+
+ .weak USB_HP_CAN1_TX_IRQHandler
+ .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
+
+ .weak USB_LP_CAN1_RX0_IRQHandler
+ .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
+
+ .weak CAN1_RX1_IRQHandler
+ .thumb_set CAN1_RX1_IRQHandler,Default_Handler
+
+ .weak CAN1_SCE_IRQHandler
+ .thumb_set CAN1_SCE_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM1_BRK_IRQHandler
+ .thumb_set TIM1_BRK_IRQHandler,Default_Handler
+
+ .weak TIM1_UP_IRQHandler
+ .thumb_set TIM1_UP_IRQHandler,Default_Handler
+
+ .weak TIM1_TRG_COM_IRQHandler
+ .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
+
+ .weak TIM1_CC_IRQHandler
+ .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak USART3_IRQHandler
+ .thumb_set USART3_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak USBWakeUp_IRQHandler
+ .thumb_set USBWakeUp_IRQHandler,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/templates/linux/Makefile b/templates/linux/Makefile
new file mode 100644
index 0000000..2f01c8b
--- /dev/null
+++ b/templates/linux/Makefile
@@ -0,0 +1,14 @@
+CC=gcc
+NISTGCCFLAGS=-std=c99 -Wall -Wextra -Wshadow -fsanitize=address,undefined -O2
+LFLAGS=-lm
+all: test_1
+
+test_1: test
+
+test: main.c $(SRC_FILES)
+ $(CC) $(NISTGCCFLAGS) -o $@ $^ $(LFLAGS)
+
+.PHONY: clean
+
+clean:
+ -rm test
diff --git a/templates/linux/configure b/templates/linux/configure
new file mode 100755
index 0000000..7a693aa
--- /dev/null
+++ b/templates/linux/configure
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+
diff --git a/templates/linux/crypto_aead.h b/templates/linux/crypto_aead.h
new file mode 100644
index 0000000..eafabff
--- /dev/null
+++ b/templates/linux/crypto_aead.h
@@ -0,0 +1,19 @@
+int crypto_aead_encrypt(
+ unsigned char *c,unsigned long long *clen,
+ const unsigned char *m,unsigned long long mlen,
+ const unsigned char *ad,unsigned long long adlen,
+ const unsigned char *nsec,
+ const unsigned char *npub,
+ const unsigned char *k
+ );
+
+
+int crypto_aead_decrypt(
+ unsigned char *m,unsigned long long *outputmlen,
+ unsigned char *nsec,
+ const unsigned char *c,unsigned long long clen,
+ const unsigned char *ad,unsigned long long adlen,
+ const unsigned char *npub,
+ const unsigned char *k
+ );
+
diff --git a/assets/main.c b/templates/linux/main.c
similarity index 89%
rename from assets/main.c
rename to templates/linux/main.c
index bb43415..01ab177 100644
--- a/assets/main.c
+++ b/templates/linux/main.c
@@ -17,6 +17,8 @@
#define NPUB_LENGTH 0
#endif
+#define FPRINTF_HEX(fd, m, mlen) for (unsigned long long int i = 0; i < mlen; i++) fprintf(fd, "%02x ", m[i]);
+
unsigned char *c = NULL;
unsigned long long clen = 0;
unsigned char *m = NULL;
@@ -41,8 +43,8 @@ static void read_variable(unsigned char **target, unsigned long long *lenp) {
fprintf(stderr, "ERROR: couldn't read length\r\n");
exit(1);
}
-
*lenp = len;
+
if (*lenp == 0) {
*target = NULL;
return;
@@ -65,7 +67,7 @@ static void read_variable(unsigned char **target, unsigned long long *lenp) {
static void write_variable(unsigned char *target, unsigned long long len) {
uint32_t olen = len;
if (1 != fwrite(&olen, sizeof(olen), 1, stdout)) {
- fprintf(stderr, "ERROR: didn't write length\r\n", len);
+ fprintf(stderr, "ERROR: didn't write length\r\n");
exit(1);
}
if (1 != fwrite(target, olen, 1, stdout)) {
@@ -76,8 +78,7 @@ static void write_variable(unsigned char *target, unsigned long long len) {
static bool is_ready() {
- return !(k == NULL || m == NULL || c == NULL
- || ad == NULL || nsec == NULL || npub == NULL);
+ return !(k == NULL || m == NULL || c == NULL || ad == NULL);
}
@@ -112,10 +113,21 @@ int main() {
if (!is_ready()) {
return 3;
}
+ fprintf(stderr, "mlen = %llu\r\n", mlen);
+ fprintf(stderr, "m = "); FPRINTF_HEX(stderr, m, mlen); fprintf(stderr, "\r\n");
+ fprintf(stderr, "adlen = %llu\r\n", adlen);
+ fprintf(stderr, "ad = "); FPRINTF_HEX(stderr, ad, adlen); fprintf(stderr, "\r\n");
+ fprintf(stderr, "nplen = %llu\r\n", nplen);
+ fprintf(stderr, "np = "); FPRINTF_HEX(stderr, npub, nplen); fprintf(stderr, "\r\n");
+ fprintf(stderr, "nslen = %llu\r\n", nslen);
+ fprintf(stderr, "ns = "); FPRINTF_HEX(stderr, nsec, nslen); fprintf(stderr, "\r\n");
+ fprintf(stderr, "klen = %llu\r\n", klen);
+ fprintf(stderr, "k = "); FPRINTF_HEX(stderr, k, klen); fprintf(stderr, "\r\n");
+
fprintf(stderr, "Starting encryption\r\n");
res = crypto_aead_encrypt(c, &clen,
m, mlen, ad, adlen, nsec, npub, k);
- fprintf(stderr, "encryption finished\r\n");
+ fprintf(stderr, "encryption finished %d\r\n", res);
break;
case 'd':
@@ -125,7 +137,7 @@ int main() {
fprintf(stderr, "Starting decryption\r\n");
res = crypto_aead_decrypt(m, &mlen,
nsec, c, clen, ad, adlen, npub, k);
- fprintf(stderr, "decryption finished\r\n");
+ fprintf(stderr, "decryption finished %d\r\n", res);
break;
default:
diff --git a/test.py b/test.py
index 8b3b59f..8e224ef 100755
--- a/test.py
+++ b/test.py
@@ -35,12 +35,12 @@ def main(argv):
if read(14) != b"Hello, World!\n":
raise Exception("Unexpected output")
- submit('c', bytes.fromhex("000102030405060708090A0B0C0D0E0F"))
+ submit('c', b"\0" * 32)
submit('m', bytes.fromhex("000102030405060708090A0B0C0D0E0F"))
submit('a', bytes.fromhex("000102030405060708090A0B0C0D0E0F"))
submit('k', bytes.fromhex("000102030405060708090A0B0C0D0E0F"))
submit('p', bytes.fromhex("000102030405060708090A0B0C0D0E0F"))
- submit('s', bytes.fromhex("000102030405060708090A0B0C0D0E0F"))
+ submit('s', b"")
write(b'e')
write(b'C')
data = obtain()